diff --git a/.editorconfig b/.editorconfig index 8e3084dd3..c70eea97a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,7 +4,7 @@ root = true end_of_line = lf [*.lua] -charset = utf8 +charset = utf-8 indent_style = tab insert_final_newline = true trim_trailing_whitespace = true diff --git a/.gitea/issue_template/bug.md b/.gitea/issue_template/bug.md index be76e6395..db0336182 100644 --- a/.gitea/issue_template/bug.md +++ b/.gitea/issue_template/bug.md @@ -13,18 +13,19 @@ labels: Thanks for taking the time to fill out this bug report! Please follow our contributing guidelines first: -https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests +https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests By submitting this issue, you agree to follow our Code of Conduct: -https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md +https://git.minetest.land/VoxeLibre/VoxeLibre/src/branch/master/CODE_OF_CONDUCT.md --> -MineClone2 version: +VoxeLibre version: ### What happened? Report about the bug! Please send large log snippets as an attachement file. diff --git a/.gitea/issue_template/feature_request.md b/.gitea/issue_template/feature_request.md index 58a7437ab..73d1470ad 100644 --- a/.gitea/issue_template/feature_request.md +++ b/.gitea/issue_template/feature_request.md @@ -1,7 +1,7 @@ --- name: "Feature request" -about: "File a feature request not in Minecraft" +about: "File a feature request" labels: - "non-Minecraft feature" @@ -10,17 +10,17 @@ labels: --- ### Feature -Tell us about your requested feature not in Minecraft! +Tell us about your requested feature! ### Why Tell us why should we implement it! diff --git a/.gitea/issue_template/missing_feature_request.md b/.gitea/issue_template/missing_feature_request.md deleted file mode 100644 index b3e275c9b..000000000 --- a/.gitea/issue_template/missing_feature_request.md +++ /dev/null @@ -1,25 +0,0 @@ ---- - -name: "Missing Feature request" -about: "File a missing feature request in Minecraft but not in MineClone2" -labels: - -- "missing feature" - ---- - - - -### Current feature in Minecraft -Tell us about the feature currently in Minecraft! What is it like on Minecraft? - -### Current feature in MineClone2 -Tell us about the feature currently in MineClone2! What is different? diff --git a/.gitea/pull_request_template.md b/.gitea/pull_request_template.md index ec7207ee4..b77cc1299 100644 --- a/.gitea/pull_request_template.md +++ b/.gitea/pull_request_template.md @@ -8,13 +8,13 @@ labels: -Tell us about your pull request! Reference related issues, if necessary +Tell us about your pull request! Reference related issues, if necessary. ### Testing Tell us how to test your changes! diff --git a/.gitignore b/.gitignore index de181d31a..900629d0f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ *.blend3 /.idea/ *.xcf -.Rproj.user \ No newline at end of file +.Rproj.user +prompt.txt +__pycache__ diff --git a/.luacheckrc b/.luacheckrc index 9d0b8cb2a..69c015665 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -1,10 +1,12 @@ +---@diagnostic disable + unused_args = false allow_defined_top = true max_line_length = false redefined = false globals = { - "minetest", "core", + "minetest", "core", } read_globals = { @@ -40,16 +42,16 @@ read_globals = { "factorial" } }, - ------ - --MODS - ------ + ------ + --MODS + ------ - --GENERAL - "default", + --GENERAL + "default", - --ENTITIES - "cmi", + --ENTITIES + "cmi", - --HUD - "sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus", -} \ No newline at end of file + --HUD + "sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus", +} diff --git a/.luarc.json b/.luarc.json new file mode 100644 index 000000000..7e9e92042 --- /dev/null +++ b/.luarc.json @@ -0,0 +1,22 @@ +{ + "runtime.version": "LuaJIT", + "diagnostics": { "disable": ["lowercase-global"] }, + "diagnostics.globals": [ + "minetest", + "dump", + "dump2", + "Raycast", + "Settings", + "PseudoRandom", + "PerlinNoise", + "VoxelManip", + "SecureRandom", + "VoxelArea", + "PerlinNoiseMap", + "PcgRandom", + "ItemStack", + "AreaStore", + "vector" + ], + "workspace.ignoreDir": [".luacheckrc"] +} diff --git a/API.md b/API.md index 865630c78..cd438e2bf 100644 --- a/API.md +++ b/API.md @@ -1,10 +1,10 @@ # API ## Groups -MineClone 2 makes very extensive use of groups. Making sure your items and objects have the correct group memberships is very important. +VoxeLibre makes very extensive use of groups. Making sure your items and objects have the correct group memberships is very important. Groups are explained in `GROUPS.md`. ## Mod naming convention -Mods mods in MineClone 2 follow a simple naming convention: Mods with the prefix “`mcl_`” are specific to MineClone 2, although they may be based on an existing standalone. Mods which lack this prefix are *usually* verbatim copies of a standalone mod. Some modifications may still have been applied, but the APIs are held compatible. +Mods mods in VoxeLibre follow a simple naming convention: Mods with the prefix "`vl_`" and “`mcl_`” are specific to VoxeLibre (formerly known as MineClone2), although they may be based on an existing standalone. Mods which lack this prefix are *usually* verbatim copies of a standalone mod. Some modifications may still have been applied, but the APIs are held compatible. ## Adding items ### Special fields @@ -31,7 +31,7 @@ All nodes can have these fields: Use the `mcl_sounds` mod for the sounds. ## APIs -A lot of things are possible by using one of the APIs in the mods. Note that not all APIs are documented yet, but it is planned. The following APIs should be more or less stable but keep in mind that MineClone 2 is still unfinished. All directory names are relative to `mods/` +A lot of things are possible by using one of the APIs in the mods. Many of them are documented in `API.md` files located in the directories of the specific mods. Some use `.txt` files or have some documentation in the comments along the code. Note that not all APIs are documented yet, but it is planned. The following APIs should be more or less stable but keep in mind that VoxeLibre is still unfinished. All directory names are relative to `mods/` ### Items * Doors: `ITEMS/mcl_doors` @@ -46,8 +46,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not ### Mobs * Mobs: `ENTITIES/mcl_mobs` -MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short. -This is a fork of Mobs Redo [`mobs`] by TenPlus1. +VoxeLibre uses its own mobs framework, which is a fork of Mobs Redo [`mobs`] by TenPlus1. You can add your own mobs, spawn eggs and spawning rules with this mod. API documnetation is included in `ENTITIES/mcl_mobs/api.txt`. @@ -55,7 +54,7 @@ API documnetation is included in `ENTITIES/mcl_mobs/api.txt`. This mod includes modificiations from the original Mobs Redo. Some items have been removed or moved to other mods. The API is mostly identical, but a few features have been added. Compability is not really a goal, but function and attribute names of Mobs Redo 1.41 are kept. -If you have code for a mod which works fine under Mobs Redo, it should be easy to make it work in MineClone 2, +If you have code for a mod which works fine under Mobs Redo, it should be easy to make it work in VoxeLibre. chances are good that it works out of the box. ### Help @@ -68,6 +67,7 @@ chances are good that it works out of the box. ### Utility APIs * Change player physics: `PLAYER/playerphysics` +* Change player FOV: `PLAYER/mcl_fovapi` * Select random treasures: `CORE/mcl_loot` * Get flowing direction of liquids: `CORE/flowlib` * `on_walk_over` callback for nodes: `CORE/walkover` @@ -77,7 +77,7 @@ chances are good that it works out of the box. * Flowers and flower pots ### Unstable APIs -The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk! +The following APIs may be subject to change in the future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk! * Panes (like glass panes and iron bars): `ITEMS/xpanes` * `_on_ignite` callback: `ITEMS/mcl_fire` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 781b1b85f..cd6eb1801 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,48 +1,47 @@ -# Contributing to MineClone2 -So you want to contribute to MineClone2? +# Contributing to VoxeLibre +So you want to contribute to VoxeLibre? Wow, thank you! :-) -MineClone2 is maintained by AncientMariner and Nicu. If you have any +VoxeLibre is maintained by AncientMariner and Herowl. If you have any problems or questions, contact us on Discord/Matrix (See Links section below). -You can help with MineClone2's development in many different ways, +You can help with VoxeLibre's development in many different ways, whether you're a programmer or not. -## MineClone2's development target is to... -- Create a stable, peformant, moddable, free/libre game based on Minecraft +## VoxeLibre's development target is to... +- Create a stable, peformant, moddable, free/libre game inspired by Minecraft using the Minetest engine, usable in both singleplayer and multiplayer. - Currently, a lot of features are already implemented. Polishing existing features is always welcome. ## Links -* [Mesehub](https://git.minetest.land/MineClone2/MineClone2) +* [Mesehub](https://git.minetest.land/VoxeLibre/VoxeLibre) * [Discord](https://discord.gg/xE4z8EEpDC) * [YouTube](https://www.youtube.com/channel/UClI_YcsXMF3KNeJtoBfnk9A) -* [IRC](https://web.libera.chat/#mineclone2) -* [Matrix](https://app.element.io/#/room/#mc2:matrix.org) -* [Reddit](https://www.reddit.com/r/MineClone2/) +* [Matrix](https://app.element.io/#/room/#voxelibre:matrix.org) +* [Reddit](https://www.reddit.com/r/VoxeLibre/) * [Minetest forums](https://forum.minetest.net/viewtopic.php?f=50&t=16407) * [ContentDB](https://content.minetest.net/packages/wuzzy/mineclone2/) * [OpenCollective](https://opencollective.com/mineclone2) ## Using git -MineClone2 is developed using the version control system +VoxeLibre is developed using the version control system [git](https://git-scm.com/). If you want to contribute code to the project, it is **highly recommended** that you learn the git basics. For non-programmers and people who do not plan to contribute code to -MineClone2, git is not required. However, git is a tool that will be +VoxeLibre, git is not required. However, git is a tool that will be referenced frequently because of its usefulness. As such, it is valuable in learning how git works and its terminology. It can also help you keeping your game updated, and easily test pull requests. Look at our wiki for some concrete guides: -https://git.minetest.land/MineClone2/MineClone2/wiki/ +https://git.minetest.land/VoxeLibre/VoxeLibre/wiki/ ## How you can help as a non-programmer As someone who does not know how to write programs in Lua or does not know how to use the Minetest API, you can still help us out a lot. For example, by opening an issue in the -[Issue tracker](https://git.minetest.land/MineClone2/MineClone2/issues), +[Issue tracker](https://git.minetest.land/VoxeLibre/VoxeLibre/issues), you can report a bug or request a feature. ### Rules about both bugs and feature requests @@ -60,8 +59,7 @@ actually an issue with Minetest itself, and if it is, head to the [Minetest issue tracker](https://github.com/minetest/minetest/issues) instead. * If you need any help regarding creating a Mesehub account or opening -an issue, feel free to ask on the Discord / Matrix server or the IRC -channel. +an issue, feel free to ask on the Discord or Matrix space. The link to the mesehub registration page is: https://git.minetest.land/user/sign_up (It appears to sometimes get lost on the page itsself) @@ -75,7 +73,7 @@ in singleplayer, post a screenshot of the message that Minetest showed when the crash happened (or copy the message into your issue). If you are a server admin, you can find error messages in the log file of the server. -* Tell us which MineClone2 and Minetest versions you are using (from Minetest 5.7 type /ver, for previous versions, check the game.conf or README.md file). +* Tell us which VoxeLibre and Minetest versions you are using (from Minetest 5.7 type /ver, for previous versions, check the game.conf or README.md file). * Tell us how to reproduce the problem: What you were doing to trigger the bug, e.g. before the crash happened or what causes the faulty behavior. @@ -84,14 +82,14 @@ behavior. * Ensure the requested feature fulfills our development targets and goals. * Begging or excessive attention seeking does not help us in the -slightest, and may very well disrupt MineClone2 development. It's better +slightest, and may very well disrupt VoxeLibre development. It's better to put that energy into helping or researching the feature in question. After all, we're just volunteers working on our spare time. -* Ensure the requested feature has not been implemented in MineClone2 +* Ensure the requested feature has not been implemented in VoxeLibre latest or development versions. ### Testing code -If you want to help us with speeding up MineClone2 development and +If you want to help us with speeding up VoxeLibre development and making the game more stable, a great way to do that is by testing out new features from contributors. For most new things that get into the game, a pull request is created. A pull request is essentially a @@ -103,20 +101,21 @@ tell us if the code works as expected without any issues. Ideally, you would report issues will pull requests similar to when you were reporting bugs that are the mainline (See Reporting bugs section). You can find currently open pull requests here: -. Note that pull +. Note that pull requests that start with a `WIP:` are not done yet and therefore could still undergo substantial change. Testing these is still helpful however because that is the reason developers put them up as WIP so other people -can have a look at the PR. +can have a look at the PR. The wiki has an article with instructions +on how to test Pull Requests: +. ### Contributing assets -Due to license problems, MineClone2 cannot use Minecraft's assets, +Due to license problems, VoxeLibre cannot use Minecraft's assets, therefore we are always looking for asset contributions. To contribute assets, it can be useful to learn git basics and read the section for Programmers of this document, however this is not required. -It's also a good idea to join the Discord server -(or alternatively IRC or Matrix). +It's also a good idea to join the Discord server and/or Matrix space. #### Textures For textures we prefer original art, but in the absence of that will accept @@ -128,9 +127,9 @@ If you want to make such contributions, join our Discord server. Demands for textures will be communicated there. #### Sounds -MineClone2 currently does not have a consistent way to handle sounds. +VoxeLibre currently does not have a consistent way to handle sounds. The sounds in the game come from different sources, like the SnowZone -resource pack or minetest_game. Unfortunately, MineClone2 does not play +resource pack or minetest_game. Unfortunately, VoxeLibre does not play a sound in every situation you would get one in Minecraft. Any help with sounds is greatly appreciated, however if you add new sounds you should probably work together with a programmer, to write the code to actually @@ -140,7 +139,7 @@ changes made by the contributor. Use the README files in the mod to communicate this information. #### 3D Models -Most of the 3D Models in MineClone2 come from +Many of the 3D Models in VoxeLibre come from [22i's repository](https://github.com/22i/minecraft-voxel-blender-models). Similar to the textures, we need people that can make 3D Models with Blender on demand. Many of the models have to be patched, some new @@ -154,13 +153,13 @@ also be credited in the Contributors section. ### Contributing Translations #### Workflow -To add/update support for your language to MineClone2, you should take +To add/update support for your language to VoxeLibre, you should take the steps documented in the section for Programmers, add/update the translation files of the mods that you want to update. You can add support for all mods, just some of them or only one mod; you can update the translation file entirely or only partly; basically any effort is valued. If your changes are small, you can also send them to developers -via E-Mail, Discord, IRC or Matrix - they will credit you appropriately. +via E-Mail, Discord or Matrix - they will credit you appropriately. #### Things to note You can use the script at `tools/check_translate_files.py` to compare @@ -178,7 +177,7 @@ If you have commited the results yourself, you will also be credited in the Contributors section. ### Profiling -If you own a server, a great way to help us improve MineClone2's code +If you own a server, a great way to help us improve VoxeLibre's code is by giving us profiler results. Profiler results give us detailed information about the game's performance and let us know places to investigate optimization issues. This way we can make the game faster. @@ -203,18 +202,23 @@ decisions. Also, note that a lot of discussion takes place on the Discord server, so it's definitely worth checking it out. ### Funding -You can help pay for our infrastructure (Mesehub) by donating to our -OpenCollective link (See Links section). +You can help pay for our infrastructure (Mesehub) and other unforeseen +expenses (in the last few years, only payments for Mesehub have been done) +by donating to our OpenCollective link (See Links section). ### Crediting If you opened or have contributed to an issue, you receive the `Community` role on our Discord (after asking for it). +If you have been an author of a PR that got merged or contributed +significantly to art that got merged into the game, you receive the +`Contributor` role on our Discord (after asking for it). +Please note that what counts as "significant" is decided by Maintainers. OpenCollective Funders are credited in their own section in `CREDITS.md` and receive a special role "Funder" on our discord (unless they have made their donation Incognito). ## How you can help as a programmer -(Almost) all the MineClone2 development is done using pull requests. +(Almost) all the VoxeLibre development is done using pull requests. ### Recommended workflow * Fork the repository (in case you have not already) @@ -237,11 +241,11 @@ is no issue on the topic, open one. If there is an issue, tell us that you'd like to take care of it, to avoid duplicate work. ### Don't hesitate to ask for help -We appreciate any contributing effort to MineClone2. If you are a -relatively new programmer, you can reach us on Discord, Matrix or IRC -for questions about git, Lua, Minetest API, MineClone2 codebase or -anything related to MineClone2. We can help you avoid writing code that -would be deemed inadequate, or help you become familiar with MineClone2 +We appreciate any contributing effort to VoxeLibre. If you are a +relatively new programmer, you can reach us on Discord or Matrix +for questions about git, Lua, Minetest API, VoxeLibre codebase or +anything related to VoxeLibre. We can help you avoid writing code that +would be deemed inadequate, or help you become familiar with VoxeLibre better, or assist you use development tools. ### Maintain your own code, even if already got merged @@ -250,40 +254,52 @@ scenarios by testing every time before merging it, but if your merged work causes problems, we ask you fix the issues as soon as possible. ### Changing Gameplay -Pull Requests that change gameplay have to be properly researched and -need to state their sources. These PRs also need the maintainer's approval -before they are merged. -You can use these sources: - -* Testing things inside of Minecraft (Attach screenshots / video footage -of the results) -* Looking at [Minestom](https://github.com/Minestom/Minestom) code. An open source Minecraft Server implementation -* [Official Minecraft Wiki](https://minecraft.fandom.com/wiki/Minecraft_Wiki) -(Include a link to the specific page you used) +Pull Requests that change gameplay are always subject to discussion. +Opinions from the community on such PRs are valued, and Maintainer +should approve the concept (which is usually granted) as well as +the implementation (for which changes are often requested for either +code quality or game design reasons). ### Guidelines #### Git Guidelines -* Pushing to master is disabled - don't even try it. -* Every change is tracked as a PR. -* All but the tiniest changes require at least one approval from a Developer +* Pushing to master is disabled - don't even try it! +* Every change is tracked as a PR +* All changes require at least one approval from a Developer +* Maintainers may merge PRs without formal approval, but should also +take others' opinions and testing into account * To update branches we use rebase not merge (so we don't end up with excessive git bureaucracy commits in master) * We use merge to add the commits from a PR/branch to master +* Smaller PRs may be squashed before merging (especially if the commit history +on them isn't valuable), but when in doubt prefer merging +* Manual merging may be done by a Maintainer if there are technical problems +with the branch, with Gitea, or the PR had been merged to from master and +the author can't fix it for whatever reason +* PR from a fork (usually the author has no contributor/developer privileges) +can be retargeted and merged first into a buffer (normal new) branch on the repo +when adopted by a Developer, and only later into master * Submodules should only be used if a) upstream is highly reliable and -b) it is 100% certain that no mcl2 specific changes to the code will be -needed (this has never been the case before, hence mcl2 is submodule free so far) +b) it is 100% certain that no VL specific changes to the code will be +needed (this has never been the case before, hence VL is submodule free so far) +* Subtrees may be used for including outside mods that don't need changes +in the foreseeable future * Commit messages should be descriptive * Try to group your submissions best as you can: -* Try to keep your PRs small: In some cases things reasonably be can't -split up but in general multiple small PRs are better than a big one. -* Similarly multiple small commits are better than a giant one. (use git commit -p) + * Try to keep your PRs small: In some cases things reasonably be can't +split up but in general multiple small PRs are better than a big one + * Similarly multiple small commits are better than a giant one. (use git commit -p) #### Code Guidelines * Each mod must provide `mod.conf`. -* Mod names are snake case, and newly added mods start with `mcl_`, e.g. -`mcl_core`, `mcl_farming`, `mcl_monster_eggs`. Keep in mind Minetest +* Mod names are snake case, and newly added mods (or substantially changed mods +that are included from the outside) start with `vl_`, e.g. +`vl_hollow_logs`, . Keep in mind Minetest does not support capital letters in mod names. +* In the past mods were prefixed with `mcl_`, e.g. +`mcl_core`, `mcl_farming`, `mcl_monster_eggs`. New mods should **never** use this prefix. +* Mods included from outside with no significant changes to the API +(especially those using git-subtree or such) aren't prefixed. * To export functions, store them inside a global table named like the mod, e.g. @@ -357,17 +373,21 @@ end ### Developer status Active and trusted contributors are often granted write access to the -MineClone2 repository as a contributor. Those that have demonstrated the right -technical skills and behaviours may be granted developer access. These are the -most trusted contributors who will contribute to ensure coding standards and -processes are followed. +VoxeLibre repository as a contributor. This means that they can push +directly to the branches of our repo (except for `master`). +Pushing to others' branches without asking is discouraged, open a PR +targeting that branch instead (PRs can target any branch). + +Those that have demonstrated the right technical skills and behaviour +may be granted developer access. These are the most trusted contributors +who will contribute to ensure coding standards and processes are followed. #### Developer responsibilities - If you have developer/contributor privileges you can just open a new branch -in the mcl2 repository (which is preferred). From that you create a pull request. +in the VL repository (which is preferred). From that you create a pull request. This way other people can review your changes and make sure they work before they get merged. -- If you do not (yet) have developer privs you do your work on a branch +- If you do not (yet) have contributor or developer privs you do your work on a branch on your private repository e.g. using the "fork" function on mesehub. - Any developer is welcome to review, test and approve PRs. A maintainer may prefer to merge the PR especially if it is in a similar area to what has been worked on @@ -390,14 +410,14 @@ merged. - Resolving conflicts and problems within the community #### Current maintainers -* AncientMariner - responsible for gameplay review, publishing releases, +* AncientMariner - responsible for gameplay review, publishing releases +* Herowl - responsible for gameplay review, publishing releases, technical guidelines -* Nicu - responsible for community related issues #### Release process * Run `tools/generate_ingame_credits.lua` to update the ingame credits from `CREDITS.md` and commit the result (if anything changed) -* Launch MineClone2 to make sure it still runs +* Launch VoxeLibre to make sure it still runs * Update the version number in README.md * Use `git tag ` to tag the latest commit with the version number @@ -415,6 +435,5 @@ become part of a free/libre software. ### Crediting Contributors, Developers and Maintainers will be credited in -`CREDITS.md`. If you make your first time contribution, please add -yourself to this file. There are also Discord roles for Contributors, +`CREDITS.md`. There are also Discord roles for Contributors, Developers and Maintainers. diff --git a/CREDITS.md b/CREDITS.md index b3b6d4746..cf54d02bb 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -3,39 +3,42 @@ ## Creator of MineClone * davedevils -## Creator of MineClone2 +## Creator of VoxeLibre * Wuzzy ## Maintainers * AncientMariner -* Nicu +* Herowl ## Previous Maintainers * Fleckenstein * cora +* Nicu ## Developers * AFCMS * epCode * chmodsayshello -* PrairieWind * MrRar -* FossFanatic * SmokeyDope +* Faerraven / Michieal +* rudzik8 +* teknomunk ## Past Developers * jordan4ibanez * iliekprogrammar * kabou * kay27 -* Faerraven / Michieal * MysticTempest * NO11 * SumianVoice +* PrairieWind +* FossFanatic +* Codiac ## Contributors * RandomLegoBrick -* rudzik8 * Code-Sploit * aligator * Rootyjr @@ -112,12 +115,38 @@ * Niterux * appgurueu * seventeenthShulker +* DinoNuggies4665 +* basxto +* Morik666 +* Eliy21 +* mdk +* Alessandra Lozoya +* VanicGame +* ThePython10110 +* Araca +* Montandalar +* mim +* Dark +* Bakawun +* JoseDouglas26 +* Zasco +* PrWalterB +* michaljmalinowski +* nixnoxus +* Potiron +* Tuxilio +* Impulse +* Doods +* SOS-Games +* Bram +* qoheniac +* WillConker ## Music * Jordach for the jukebox music compilation from Big Freaking Dig * Dark Reaven Music (https://soundcloud.com/dark-reaven-music) for the main menu theme (Calmed Cube) and Traitor (horizonchris96), which is licensed under https://creativecommons.org/licenses/by-sa/3.0/ -* Jester for helping to finely tune MineClone2 (https://www.youtube.com/@Jester-8-bit). Songs: Hailing Forest, Gift, 0dd BL0ck, Flock of One (License CC BY-SA 4.0) -* Exhale & Tim Unwin for some wonderful MineClone2 tracks (https://www.youtube.com/channel/UClFo_JDWoG4NGrPQY0JPD_g). Songs: Valley of Ghosts, Lonely Blossom, Farmer (License CC BY-SA 4.0) +* Jester for helping to finely tune VoxeLibre (https://www.youtube.com/@Jester-8-bit). Songs: Hailing Forest, Gift, 0dd BL0ck, Flock of One (License CC BY-SA 4.0) +* Exhale & Tim Unwin for some wonderful VoxeLibre tracks (https://www.youtube.com/channel/UClFo_JDWoG4NGrPQY0JPD_g). Songs: Valley of Ghosts, Lonely Blossom, Farmer (License CC BY-SA 4.0) * Diminixed for 3 fantastic tracks and remastering and leveling volumes. Songs: Afternoon Lullaby (pianowtune02), Spooled (ambientwip02), Never Grow Up (License CC BY-SA 4.0) ## Original Mod Authors @@ -155,6 +184,7 @@ * cora * Faerraven / Michieal * PrairieWind +* ChrisPHP ## 3D Models * 22i @@ -162,6 +192,7 @@ * epCode * Faerraven / Michieal * SumianVoice +* thunder1035 ## Textures * XSSheep @@ -178,8 +209,11 @@ * Faerraven / Michieal * Nicu * Exhale +* Aeonix_Aeon * Wbjitscool * SmokeyDope +* thunder1035 +* Herowl ## Translations * Wuzzy @@ -199,6 +233,10 @@ * Temak * megustanlosfrijoles * kbundg +* Isaac Dennis +* ADLON +* Sab Pyrope +* JoseDouglas26 ## Funders * 40W @@ -208,4 +246,4 @@ ## Special thanks * The Minetest team for making and supporting an engine, and distribution infrastructure that makes this all possible * The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game -* Notch and Jeb for being the major forces behind Minecraft \ No newline at end of file +* Notch and Jeb for being the major forces behind Minecraft diff --git a/GROUPS.md b/GROUPS.md index e6d878990..18510430e 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -25,7 +25,7 @@ The basic digging time groups determine by which tools a node can be dug. * `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess * `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group -Please read to learn how digging times work in Minecraft, as MineClone 2 is based on the same system. +Please read to learn how digging times work in Minecraft, as VoxeLibre is based on the same system. ### Groups for interactions @@ -117,7 +117,7 @@ These groups correspond to the Minecraft materials. They classify the block into * `material_glass=1`: Glass Currently, these groups are used for the note block. -Note that not all Minecraft materials are used so far. More Minecraft materials will lilely only be added when they are needed for a concrete use case. +Note that not all Minecraft materials are used so far. More Minecraft materials will likely only be added when they are needed for a concrete use case. ### Declarative groups These groups are used mostly for informational purposes @@ -170,16 +170,8 @@ These groups are used mostly for informational purposes * `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) * `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=3`: Same as `container=2`, but shulker boxes can not be inserted - * `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 + * `container=1`: Container type, which does not allow hoppers to transfer items + * `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. * `spawn_egg=1`: Spawn egg * `pressure_plate=1`: Pressure plate (off) diff --git a/HOW_TO_PLAY.md b/HOW_TO_PLAY.md index bc6cad1a5..30e279ecc 100644 --- a/HOW_TO_PLAY.md +++ b/HOW_TO_PLAY.md @@ -1,4 +1,4 @@ -Survive, farm, build, explore, play with friends, and do much more. Inspired by a well known block game, pushing beyond. +Survive, farm, build, explore, play with friends, and do much more. Inspired by a well-known block game, pushing beyond. How to play: @@ -6,16 +6,18 @@ How to play: - Navigate to https://www.minetest.net/ to download the client. - Once installed, open and select the "Content" tab -#### Install MineClone2 from ContentDB +#### Install VoxeLibre from ContentDB - Click "Browse Online Content" and filter by Games (select "Games" from the dropdown box) -- Find "MineClone2" (should be first on the list or on the first page) -- Click the [+] button next to MineClone2 and wait for download to finish +- Find "VoxeLibre" (should be first on the list or on the first page) +- Click the [+] button next to VoxeLibre and wait for download to finish - Click "Back to Main Menu" #### Create new world and play - Click "Start Game" tab -- At the bottom click the MineClone2 icon (the 2 dirt with grass blocks) +- At the bottom click the VoxeLibre icon (the stone & sandstone ball with the letters VL) - Click "New", give your world a name - You can leave seed blank or put in a word of your choice +- Pick a mapgen or leave the default (v7, valleys or carpathian mapgens are recommended) +- Pick mapgen options on the right (enabling everything is recommended) - Select your new world -- Click "Play Game" and enjoy! \ No newline at end of file +- Click "Play Game" and enjoy! diff --git a/LEGAL.md b/LEGAL.md index aace346bf..d95f17624 100644 --- a/LEGAL.md +++ b/LEGAL.md @@ -1,14 +1,14 @@ # Legal information -This is a fan game, not developed or endorsed by Mojang AB. +This is a game inspired by Minecraft with unique content. Copying is an act of love. Please copy and share! <3 Here's the detailed legalese for those who need it: ## License of source code -MineClone 2 (by Lizzy Fleckenstein, Wuzzy, davedevils and countless others) -is an imitation of Minecraft. +VoxeLibre (by Lizzy Fleckenstein, Wuzzy, davedevils and countless others) +is inspired by Minecraft. -MineClone 2 is free software: you can redistribute it and/or modify +VoxeLibre is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -22,15 +22,15 @@ details. In the mods you might find in the read-me or license text files a different license. This counts as dual-licensing. You can choose which license applies to you: Either the -license of MineClone 2 (GNU GPLv3) or the mod's license. +license of VoxeLibre (GNU GPLv3) or the mod's license. -MineClone 2 is a direct continuation of the discontinued MineClone +VoxeLibre is a direct continuation of the discontinued MineClone project by davedevils. Mod credits: See `README.txt` or `README.md` in each mod directory for information about other authors. For mods that do not have such a file, the license is the source code license -of MineClone 2 and the author is Wuzzy. +of VoxeLibre and the author is Wuzzy. ## License of media (textures and sounds) No non-free licenses are used anywhere. @@ -38,11 +38,15 @@ No non-free licenses are used anywhere. The textures, unless otherwise noted, are based on the Pixel Perfection resource pack for Minecraft 1.11, authored by XSSheep. Most textures are verbatim copies, while some textures have been changed or redone from scratch. -The glazed terracotta textures have been created by (MysticTempest)[https://github.com/MysticTempest]. +The glazed terracotta textures have been created by [MysticTempest](https://github.com/MysticTempest). Source: License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/) -The main menu images are release under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/) +Armor trim models were created by Aeonix_Aeon +Source: +License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) + +The main menu images are released under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/) All other files, unless mentioned otherwise, fall under: Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) diff --git a/MODELS.md b/MODELS.md index 4b9094c33..60a21c3ce 100644 --- a/MODELS.md +++ b/MODELS.md @@ -1,13 +1,14 @@ -#Models in Minetest/Mineclone2 +# Models in Minetest/VoxeLibre -Models are an important part of all entities & unique nodes in Mineclone2. They provide a 3 dimensional map of an object for which textures are then applied to. This document is for modders, it quickly highlights some important information for the software needed to open models in Mineclone2. +Models are an important part of all entities & unique nodes in VoxeLibre. They provide a 3 dimensional map of an object for which textures are then applied to. This document is for modders, it quickly highlights some important information for the software needed to open models in VoxeLibre. ## Minetest Wiki -For more detailed information on actually using blender to create and modify models for Minetest/Mineclone2, please visit the Minetest wiki's page on using Blender [Here](https://wiki.minetest.net/Using_Blender) -##Recommended software +For more detailed information on actually using blender to create and modify models for Minetest/VoxeLibre, please visit the Minetest wiki's page on using Blender [Here](https://wiki.minetest.net/Using_Blender) -###Blender +## Recommended software + +### Blender Blender is a very popular and free modeling software supported on Windows, MacOS, and most Linux distributions. It is recommended to use Blender to create and modify 3D models within the minetest engine. @@ -19,14 +20,16 @@ Blitz 3D (.b3d) Is one of the main animated model formats used for entities in t The most up to date version of this Blender plugin can be downloaded [Here](https://github.com/GreenXenith/io_scene_b3d/releases/tag/f189786) -##Types of model formats +## Types of model formats + +### Animated, skinned models -###Animated, skinned models * Blitz 3D files (.b3d) * Microsoft DirectX (.x) (binary & text, compression is not supported) -###Static meshes +### Static meshes + * Wavefront OBJ (.obj) Note: The sometimes accompanying .mtl files are not supported and can safely be deleted. @@ -45,16 +48,18 @@ Note: Do not use .b3d and .x files for static meshes at the moment, Minetest cur Note: Any formats not mentioned above but known to work in the past were removed in 5.5.0 and aren't supported anymore. -##Pros & Cons of .b3d vs .x +## Pros & Cons of .b3d vs .x + +### B3D -###B3D * [+] Binary format means a small size * [-] Difficult to postprocess after exporting * [-] Difficult to debug problems -###X (text version) +### X (text version) + * [+] Can be parsed easily with lua scripts * [+] Can be easily generated by scripts diff --git a/README.md b/README.md index 287ded5d9..02f55b4d6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# MineClone2 -An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. -Developed by many people. Not developed or endorsed by Mojang AB. +# VoxeLibre +A game inspired by Minecraft for Minetest. Forked from MineClone by davedevils. +Developed by many people, see CREDITS.md for a complete list. ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore @@ -27,7 +27,7 @@ Or you can play in “creative mode” in which you can build almost anything in ## How to play (quick start) ### Getting started * **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** * **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 @@ -37,15 +37,15 @@ Or you can play in “creative mode” in which you can build almost anything in ### Farming * Find seeds -* Craft hoe -* Rightclick dirt or similar block with hoe to create farmland +* Craft a hoe +* Rightclick dirt or a similar block with a hoe to create farmland * 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 ### Furnace -* Craft furnace -* Furnace allows you to obtain more items +* Craft a furnace +* The furnace allows you to obtain more items * Upper slot must contain a smeltable item (example: iron ore) * Lower slot must contain a fuel item (example: coal) * See tooltips in crafting guide to learn about fuels and smeltable items @@ -64,47 +64,44 @@ Use the `/giveme` chat command to obtain them. See the in-game help for an explanation. ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.4.1 or -later). So you need to install Minetest first. Only stable versions of Minetest -are officially supported. -There is no support for running MineClone2 in development versions of Minetest. +To run the game with the best performance and support, we recommend the latest +stable version of [Minetest](http://minetest.net), be we always make an effort +to support one version behind the latest stable version. In some cases, older +versions might still be good enough but you would be missing out on important +Minetest features that enable important features for our game. -To install MineClone2 (if you haven't already), move this directory into the +There is no support for running VoxeLibre in development versions of Minetest. + +To install VoxeLibre (if you haven't already), move this directory into the “games” directory of your Minetest data directory. Consult the help of Minetest to learn more. ## Useful links -The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there. +The VoxeLibre repository is hosted at Mesehub. To contribute or report issues, head there. -* Mesehub: +* Mesehub: * Discord: * YouTube: * ContentDB: * OpenCollective: -* Mastodon: -* Lemmy: -* Matrix space: +* Mastodon: +* Lemmy: +* Matrix space: * Minetest forums: -* Reddit: +* Reddit: * IRC (barely used): ## Target -- Create a stable, moddable, free/libre game based on Minecraft -on the Minetest engine with polished features, usable in both -singleplayer and multiplayer. Currently, a lot of **Minecraft Java -Edition** features are already implemented and polishing existing -features are prioritized over new feature requests. -- Implement features targetting -**Current Minecraft versions + OptiFine** (OptiFine only as far as supported -by the Minetest Engine). -- Create a performant experience that will run relatively -well on really low spec computers. +- Create a stable, peformant, moddable, free/libre game inspired by Minecraft +using the Minetest engine, usable in both singleplayer and multiplayer. +- Currently, a lot of features are already implemented. +Polishing existing features is always welcome. ## Completion status This game is currently in **beta** stage. It is playable, but not yet feature-complete. Backwards-compability is not entirely guaranteed, updating your world might cause small bugs. -If you want to use the development version of MineClone2 in production, the master branch is usually relatively stable. +If you want to use the development version of VoxeLibre in production, the master branch is usually relatively stable. The following main features are available: @@ -162,7 +159,7 @@ Bonus features (not found in Minecraft): * 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 * 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) * New blocks and items: * Lookup tool, shows you the help for whatever it touches @@ -187,7 +184,7 @@ Technical differences from Minecraft: * Different engine (Minetest) * Different easter eggs -… and finally, MineClone2 is free software (“free” as in “freedom”)! +… and finally, VoxeLibre is free software (“free” as in “freedom”)! ## Other readme files diff --git a/README_locale/README.fr.md b/README_locale/README.fr.md index 9317f09f3..f6bc85eb5 100644 --- a/README_locale/README.fr.md +++ b/README_locale/README.fr.md @@ -1,7 +1,8 @@ -# MineClone2 -Un jeu non-officiel similaire à Minecraft pour Minetest. Forké depuis Mineclone par davedevils. Développé par de nombreuses personnes. Pas développé ni supporté par Mojang AB. +# VoxeLibre +Un jeu inspiré de Minecraft pour Minetest. Forké depuis Mineclone par davedevils. +Développé par de nombreuses personnes, voir CREDITS.md pour une liste complète. -### Gameplay +### Gameplay Vous atterissez dans un monde fait entièrement de cubes et généré aléatoirement. Vous pouvez explorer le monde, miner et construire presque n'importe quel bloc pour créer de nouvelles structures. Vous pouvez choisir de jouer en "mode survie" dans lequel vous devez combattre des monstres et la faim et progresser lentement dans différents aspects du jeu, comme l'extraction de minerai, l'agriculture, la construction de machines et ainsi de suite. Ou alors vous pouvez jouer en "mode créatif" où vous pouvez construire à peu près n'importe quoi instantanément. ### Résumé du Gameplay @@ -21,7 +22,7 @@ Vous atterissez dans un monde fait entièrement de cubes et généré aléatoire ### Commencer * **Frappez un arbre** jusqu'à ce qu'il casse et donne du bois * Placez le **bois dans la grille 2x2** (la "grille de fabrication" de votre menu d'inventaire) et fabriquez 4 planches de bois -* Placer les 4 planches de bois dans la grille 2x2 et **fabriquez un établi** +* Placez les 4 planches de bois dans la grille 2x2 et **fabriquez un établi** * **Faites un clic droit sur l'établi** (icone livre) pour apprendre toutes les recettes possibles * **Fabriquez une pioche de bois** pour miner la pierre * Différents outils minent différentes sortes de blocs. Essayez-les ! @@ -30,10 +31,10 @@ Vous atterissez dans un monde fait entièrement de cubes et généré aléatoire ### Agriculture * Trouvez des graines * Fabriquez une houe -* Faites un clic droit sur la terre ou des blocs similaires avec la houe pour créer des terres agricoles -* Placer des graines sur des terres agricoles et regardez les pousser +* Faites un clic droit sur la terre ou un bloc similaire avec la houe pour créer des terres agricoles +* Placez des graines sur des terres agricoles et regardez les pousser * Récoltez les plantes une fois matûres -* Les terres agricoles proche de l'eau deviennent humides et accélèrent la croissance +* Les terres agricoles proches de l'eau deviennent humides et accélèrent la croissance ### Four * Fabriquez un four @@ -46,7 +47,7 @@ Vous atterissez dans un monde fait entièrement de cubes et généré aléatoire Plus d'aide à propos du jeu, des blocs, objets et plus encore peuvent être trouvés dans le jeu. Vous pouvez accéder à l'aide depuis le menu inventaire. ### Objets spéciaux -Les objets suivants sont intéressants pour le mode Créatif et pour les constructeurs de cartes d'aventure. Ils ne peuvent être obtenus dans le jeu ou dans l'inventaire créatif. +Les objets suivants sont intéressants pour le mode Créatif et pour les constructeurs de cartes d'aventure. Ils ne peuvent être obtenus dans le jeu ou dans l'inventaire créatif. * Barrière : `mcl_core:barrier` @@ -54,33 +55,35 @@ Utilisez la commande de chat `/giveme` pour les obtenir. Voir l'aide interne au ## Installation Ce jeu nécessite [Minetest](http://minetest.net) pour fonctionner (version 5.4.1 ou plus). Vous devez donc installer Minetest d'abord. Seules les versions stables de Minetest sont officielement supportées. -Il n'y a pas de support de MineClone2 dans les versions développement de Minetest. +Il n'y a pas de support de VoxeLibre dans les versions développement de Minetest. -Pour installer MineClone2 (si ce n'est pas déjà fait), déplacez ce dossier dans le dossier “games” de Minetest. Consultez l'aide de Minetest pour en apprendre plus. +Pour installer VoxeLibre (si ce n'est pas déjà fait), déplacez ce dossier dans le dossier “games” de Minetest. Consultez l'aide de Minetest pour en apprendre plus. -## Liens utiles -Le dépôt de MineClone2 est hébergé sur Mesehub. Pour contribuer ou signaler des problèmes, allez là-bas. +## Liens utiles +Le dépôt de VoxeLibre est hébergé sur Mesehub. Pour contribuer ou signaler des problèmes, allez là-bas. -* Mesehub : +* Mesehub : * Discord : * YouTube : -* IRC : -* Matrix : -* Reddit : -* Forums Minetest : * ContentDB : * OpenCollective : +* Mastodon : +* Lemmy : +* Espace Matrix : +* Forums Minetest : +* Reddit : +* IRC (peu utilisé) : ## Objectif -* Essentiellement, créer un clone de Minecraft stable, moddable, libre et gratuit basé sur le moteur de jeu Minetest avec des fonctionnalités abouties, utilisable à la fois en mode solo et multijoueur. Actuellement, beaucoup des fonctionnalités de **Minecraft Java Edition** sont déjà implémentées et leur amélioration est prioritaire sur les nouvelles demandes. -* Avec une priorité moindre, implémenter les fonctionnalités des versions **Minecraft + OptiFine** (OptiFine autant que supporté par le moteur Minetest). Cela signifie que les fonctionnalités présentes dans les versions listées sont priorisées. -* Dans l'idéal, créer une expérience performante qui tourne bien sur des ordinateurs à basse performance. Malheureusement, en raison des mécanismes de Minecraft et des limitations du moteur Minetest ainsi que de la petite taille de la communauté de joueurs sur des ordinateurs à basses performances, les optimisations sont difficiles à explorer. +* Créer un jeu stable, performant, moddable et libre inspiré de Minecraft en utilisant le moteur de jeu Minetest, utilisable à la fois en mode solo et multijoueur. +* Actuellement, un grand nombre de fonctionnalités sont déjà implémentées. +L'amélioration des fonctionnalités existantes est toujours la bienvenue. ## Statut de complétion Ce jeu est actuellement au stade **beta**. Il est jouable mais incomplet en fonctionnalités. La rétro-compatibilité n'est pas entièrement garantie, mettre votre monde à jour peut causer de petits bugs. -Si vous voulez utiliser la version de développement de MineClone2 en production, la branche master est habituellement relativement stable. Les branches de test fusionnent souvent des pull requests expérimentales et doivent être considérées comme moins stable. +Si vous voulez utiliser la version de développement de VoxeLibre en production, la branche master est habituellement relativement stable. Les principales fonctionnalités suivantes sont disponibles : @@ -108,12 +111,12 @@ Les principales fonctionnalités suivantes sont disponibles : * Horloge * Boussole * Éponge -* Bloc de slime +* Bloc de slime * Petites plantes et pousses * Teintures * Bannières * Blocs de décoration : verre, verre teinté, vitres, barres de fer, terre cuites (et couleurs), têtes et plus -* Cadres d'objets +* Cadres d'objets * Juke-boxes * Lits * Menu d'inventaire @@ -122,7 +125,7 @@ Les principales fonctionnalités suivantes sont disponibles : * Livres pour écrire * Commandes * Villages -* L'End +* L'End * et plus ! Les fonctionnalités suivantes sont incomplètes : @@ -137,7 +140,7 @@ Fonctionnalités bonus (absentes de Minecraft) : * 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 * 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) * Nouveaux blocs et objets : * Outil de recherche, montre l'aide de ce qu'il touche @@ -162,7 +165,7 @@ Différences techniques avec Minecraft : * Un moteur de jeu différent (Minetest) * Des bonus cachés différents -...et enfin MineClone2 est un logiciel libre ! +...et enfin VoxeLibre est un logiciel libre ! ## Autres fichiers readme diff --git a/README_locale/README.ru.md b/README_locale/README.ru.md new file mode 100644 index 000000000..b339d9e62 --- /dev/null +++ b/README_locale/README.ru.md @@ -0,0 +1,193 @@ +# VoxeLibre +Неофициальная игра в стиле Minecraft для Minetest. Форк MineClone от davedevils. +Разработана многими людьми. Не разработана и не одобрена Mojang AB. + +### Игровой процесс +Вы начинаете в случайно сгенерированном мире созданном целиком из кубов. Вы можете +исследовать мир, выкопать и поставить почти каждый блок в мире, чтобы создавать новые +структуры. Вы можете играть в “режиме выживания” в котором вам придется бороться с +монстрами и голодом за выживание и медленно проходить через различные аспекты игры, +такие как копание, фермерство, постройка механизмов и так далее. Или вы можете играть +в “творческом режиме” в котором вы сразу можете строить что угодно. + +#### Итоги геймплея + +* Геймплей в стиле песочницы, без целей +* Выживайте: сражайтесь с враждебными монстрами и голодом +* Добывайте руды и прочие ценные предметы +* Магия: получайте опыт и зачаруйте ваше снаряжение +* Создавайте из собранных блоков величественные постройки ограниченные только воображением +* Собирайте цветы и другие красители, чтобы раскрасить ваш мир +* Найдите семена и заведите ферму +* Найдите или создайте один из сотен предметов +* Проложите рельсы и повеселитесь с вагонетками +* Постройте сложные механизмы со схемами из редстоуна +* В творческом режиме вы можете свободно строить всё без лимитов + +## Как играть (быстрый старт) +### Начнем + +* **Бейте по стволу дерева** пока оно не сломается и соберите древесину +* Поставьте **древесину в сетку 2×2** (“сетка крафта” в вашем инвентаре) и скрафтите 4 доски +* Разложите 4 доски в форме 2×2 в сетке крафта, чтобы **сделать верстак** +* **Правым кликом по верстаку**, чтобы открыть сетку крафта 3×3 для более сложных предметов +* Используйте **книгу рецептов** (иконка книги), чтобы узнать все возможные рецепты крафтов +* **Скрафтите деревянную кирку**, чтобы вы могли копать камень +* Разные инструменты добывают разные виды блоков. Опробуйте их все! +* Продолжайте играть как пожелаете. Повеселитесь! + +### Фермерство +* Найдите семена +* Скрафтите мотыгу +* Правой кнопкой мотыгой по земле или похожему блоку, чтобы создать грядку +* Посадите семена на грядку и ждите пока они вырастут +* Соберите растение когда оно полностью созреет +* Рядом с водой грядка становится влажной и растения растут быстрее + +### Переплавка +* Скрафтите печь +* Печь позволит вам получить больше предметов +* Верхний слот должен содержать переплавляемый предмет (например: железную руду) +* Нижний слот должен содержать топливо (например: уголь) +* Смотрите книгу рецептов, чтобы узнать о других переплавляемых предметах и топливе + +### Дополнительная помощь +Больше информации о геймплее, блоках, предметах и многое другое можно найти во +внутриигровой справке. Вы можете перейти в неё через ваш инвентарь. + +### Особые предметы +Следующие предметы интересны для творческого режима и для строителей приключенческих +карт. Их нельзя получить в игре или через творческий инвентарь. + +* Барьер: `mcl_core:barrier` + +Используйте чат-команду `/giveme`, чтобы получить их. +Смотрите справку для дальнейшей информации. + +## Установка +Эта игра требует [Minetest](http://minetest.net) для запуска (версия 5.4.1 или +выше). Вам нужно сперва установить Minetest. Только стабильные версии поддерживаются +официально. Не поддерживается запуск VoxeLibre на разрабатываемых версиях Minetest. + +Чтобы установить VoxeLibre (если вы этого еще не сделали), переместите эту папку в +“games” в папке данных Minetest. Смотрите справку Minetest, чтобы узнать больше. + +## Полезные ссылки +Репозиторий VoxeLibre хранится на Mesehub. Зайдите туда, чтобы оставить запрос или +поучаствовать в разработке. + +* Mesehub: +* Discord: +* YouTube: +* ContentDB: +* OpenCollective: +* Mastodon: +* Lemmy: +* Matrix space: +* Форум Minetest: +* Reddit: +* IRC (едва используется): + +## Цели +- Создать стабильную, модифицируемую, бесплатную и свободную игру основанную на +Minecraft на движке Minetest с проработанными возможностями для одиночной игры и +для мультиплеера. На данный момент множество возможностей **Minecraft Java +Edition** уже реализовано и доработка имеющегося контента в приоритете над +добавлением нового. +- Реализовать возможности на уровне **текущей версии Minecraft + OptiFine** (OptiFine +настолько, насколько это поддерживается движком Minetest). +- Добиться производительности для запуска на действительно слабых компьютерах. + +## Готовность +Игра сейчас на стадии **бета**. Она играбельна, но еще не имеет всех возможностей. +Обратная совместимость целиком не гарантируется, обновление вашего мира может повлечь +за собой небольшие ошибки. Если вы хотите использовать разрабатываемую версию +VoxeLibre, то ветка master обычно относительно стабильна. + +Следущие возможности уже доступны: + +* Инструменты, оружие, броня +* Система крафта: сетка 2×2, верстак (сетка 3×3) и книга рецептов +* Сундуки, большие сундуки, эндер-сундуки, ящики шалкера +* Печи и воронки +* Система голода +* Большинство монстров и животных +* Все руды из Minecraft +* Большинство блоков из Верхнего мира +* Вода и лава +* Погода +* 28 биомов + 5 биомов в Незере +* Незер, пылающий подземный мир в другом измерении +* Схемы из редстоуна (частично) +* Вагонетки (частично) +* Статусные эффекты (частично) +* Опыт +* Зачарование +* Зельеварение, зелья, смоченные стрелы (частично) +* Лодки +* Огонь +* Строительные блоки: ступени, плиты, двери, люки, заборы, калитки, стены +* Часы +* Компас +* Губки +* Блоки слизи +* Растения и саженцы +* Красители +* Флаги +* Декоративные блоки: стекло, окрашенное стекло, стеклянные панели, железные решетки, цветная керамика, головы и многое другое +* Рамки для предметов +* Прогрыватели +* Кровати +* Меню инвентаря +* Творческий инвентарь +* Фермерство +* Книги с пером +* Команды +* Деревни +* Измерение Края +* И многое другое! + +Следующие возможности еще не завершены: + +* Некоторые монстры и животные +* Предметы связанные с редстоуном +* Некоторые вагонетки (с сундуком и с воронкой уже работают) +* Пара нетривиальных блоков и предметов + +Бонусные возможности (нет в Minecraft-е): + +* Встроенный гайд для крафта покажет вам рецепты крафта и переплавки +* Внутриигровая справка содержит всестороннюю информацию об основах игры, блоках, предметах и прочее +* Временные рецепты крафта. Они существуют, чтобы получить доступ к ранее недоступным предметам вне творческого режима. Они будут удалены как только разработка позволит им стать доступными +* Саженцы в сундуках в [mapgen v6](https://wiki.minetest.net/Map_generator#v6) +* Полностью модифицируема (благодаря мощному Lua API в Minetest) +* Новые блоки и предметы: + * Инструмент просмотра покажет справку о том чего коснется + * Больше ступеней и плит + * Калитки и заборы из адских кирпичей +* Замены структур - малые верии структур из Minecraft пока большие структуры не будут сделаны: + * Лесная хижина (Особняк) + * Форт Незера (Крепости) + +Технические отличия от Minecraft: + +* Лимит высоты - 31000 блоков (намного больше чем в Minecraft) +* Горизонтальный размер мира - 62000×62000 блоков (намного меньше чем в Minecraft, но всё еще очень большой) +* Всё еще не завершен и содержит много багов +* Недостающие блоки, предметы, мобы +* Некоторые предметы с другими названиями, чтобы лучше их различать +* Другая музыка для проигрывателей +* Другие текстуры (Pixel Perfection) +* Другие звуки (разные источники) +* Другой движок (Minetest) +* Другие пасхалки + +… и наконец, VoxeLibre это свободное программное обеспечение! + +## Другие readme файлы + +* `LICENSE.txt`: текст лицензии GPLv3 +* `CONTRIBUTING.md`: информация для тех кто хочет поучаствовать в разработке +* `API.md`: для моддеров Minetest кто хочет изменить эту игру +* `LEGAL.md`: юридическая информация +* `CREDITS.md`: список участников проекта diff --git a/README_locale/README.zh_TW.md b/README_locale/README.zh_TW.md index eb7540247..47d29cd59 100644 --- a/README_locale/README.zh_TW.md +++ b/README_locale/README.zh_TW.md @@ -1,4 +1,6 @@ -# MineClone 2 +This file is severely out of date. If you can help updating this translation, please reach out to us (contact in README.md - the English version). + +# VoxeLibre 一個非官方的Minetest遊戲,遊玩方式和Minecraft類似。由davedevils從MineClone分拆。 由許多人開發。並非由Mojang Studios開發。 @@ -83,11 +85,11 @@ Minetest to learn more. The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. * **開發目標:我的世界, Java版, 版本 1.12** -* MineClone2還包括Minetest支持的Optifine功能。 +* VoxeLibre還包括Minetest支持的Optifine功能。 * 後期Minecraft版本的功能可能會偷偷加入,但它們的優先級較低。 * 總的來說,Minecraft的目標是在Minetest目前允許的情況下進行克隆。 * 克隆Minecraft是最優先的。 -* MineClone2將使用不同的圖形和聲音,但風格相似。 +* VoxeLibre將使用不同的圖形和聲音,但風格相似。 * 克隆界面沒有優先權。只會被粗略地模仿。 * 在Minetest中發現的局限性將在開發過程中被記錄和報告。 @@ -173,7 +175,7 @@ The main goal of **MineClone 2** is to be a clone of Minecraft and to be release * 不同的聲音(各種來源) * 不同的引擎(Minetest) -...最後,MineClone2是自由軟件! +...最後,VoxeLibre是自由軟件! ## 錯誤報告 請在此處報告所有錯誤和缺少的功能: @@ -190,7 +192,7 @@ The main goal of **MineClone 2** is to be a clone of Minecraft and to be release * `LICENSE.txt`:GPLv3許可文本 * `CONTRIBUTING.md`: 為那些想參與貢獻的人提供資訊 -* `MISSING_ENGINE_FEATURES.md`: MineClone2需要改进,Minetest中缺失的功能列表。 +* `MISSING_ENGINE_FEATURES.md`: VoxeLibre需要改进,Minetest中缺失的功能列表。 * `API.md`: 關於MineClone2的API ## 參與者 @@ -235,7 +237,7 @@ The main goal of **MineClone 2** is to be a clone of Minecraft and to be release * [kingoscargames](https://github.com/kingoscargames):現有材質的各種編輯和添加 * [leorockway](https://github.com/leorockway):怪物紋理的一些編輯 * [xMrVizzy](https://minecraft.curseforge.com/members/xMrVizzy):釉陶(材質以後會被替換) -* yutyo :MineClone2標志 +* yutyo :VoxeLibre標志 * 其他:GUI圖片 ### 翻譯 @@ -254,7 +256,7 @@ The main goal of **MineClone 2** is to be a clone of Minecraft and to be release ### 特殊感謝 -* Wuzzy,感謝他啟動和維護MineClone2多年。 +* Wuzzy,感謝他啟動和維護VoxeLibre多年。 * celeron55,創建Minetest。 * Minetest的社區提供了大量的mods選擇,其中一些最終被納入MineClone 2。 * Jordach,為《Big Freaking Dig》的唱片機音樂合輯而來 diff --git a/RELEASE.md b/RELEASE.md index 52be92b6c..cf49d98ed 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,83 +1,167 @@ -### Standard Release +## Standard Release -#File to document release steps with a view to evolving into a script +### Before releasing -#Update CREDITS.md -#Update version in game.conf +Make sure all PRs in the release milestone are merged and you are working on a clean branch based on the master branch, up-to-date with the one on the repo. +### Release process + +1. Update CREDITS.md +2. Update version in game.conf +3. Run the script: +``` lua tools/generate_ingame_credits.lua - +``` +4. Make a commit for the above: +``` git add CREDITS.md git add mods/HUD/mcl_credits/people.lua git add game.conf - -#git add RELEASE.md - -git commit -m "Pre-release update credits and set version 0.83.0" - -git tag 0.83.0 - -git push origin 0.83.0 - -#Update version in game.conf to the next version with -SNAPSHOT suffix - -git commit -m "Post-release set version 0.84.0-SNAPSHOT" - -### Hotfix Release - -##### Prepare release branch - -When hotfixing, you should never release new features. Any new code increases risk of new bugs which has additional testing/release concerns. -To mitigate this, you just release the last release, and the relevant bug fix. For this, we do the following: - -* Create release branch from the last release tag, push it: - -git checkout -b release/0.82.1 0.82.0 - -git push origin release/0.82.1 - -##### Prepare feature branch and fix - -* Create feature branch from that release branch (can review it to check only fix is there, nothing else, and use to also merge into master separately) - -git checkout -b hotfix_bug_1_branch - -* Fix crash/serious bug and commit -* Push branch and create pr to the release and also the master branch (Do not rebase, to reduce merge conflict risk. Do not delete after first merge or it needs to be repushed) - -##### Update version and tag the release - -* After all fixes are in release branch, pull it locally (best to avoid a merge conflict as feature branch will need to be merged into master also, which already changed version): - -* Update version in game.conf to hotfix version and commit it. Example: version=0.82.1 - -* Tag it, push tag and branch: - -git tag 0.82.1 - -git push origin 0.82.1 - -git push origin release/0.82.1 - -Note: If you have to do more than 1 hotfix release, can do it on the same release branch. +git commit -m "Updated release credits and set version for v0.87" +``` +5. Add release notes to the `releasenotes` folder, named like +``` +0_87-the_prismatic_release.md +``` +6. Make a commit for the release notes: +``` +git add releasenotes/0_87-the_prismatic_release.md +git commit -m "Add release notes for v0.87" +``` +7. **Tag and push to the tag:** +``` +git tag 0.87.0 +git push origin 0.87.0 +``` +8. Update version in game.conf to the next version with -SNAPSHOT suffix: +``` +git commit -m "Post-release set version 0.88.0-SNAPSHOT" +``` +9. Push the above to a new branch, and make the release PR. Merge to finalize release process. ### Release via ContentDB -* Go to MineClone2 page (https://content.minetest.net/packages/Wuzzy/mineclone2/) -* Click +Release -* Enter the release tag number in the title and Git reference box. For example (without quotes): "0.82.1" -* In the minimum minetest version, put the oldest supported version (as of 14/02/2023 it is 5.5), leave the Maximum minetest version blank -* Click save. Release is now live. +1. Go to VoxeLibre page (https://content.minetest.net/packages/Wuzzy/mineclone2/) +2. Click [+Release] button +3. Enter the release tag number in the title and Git reference box. For example (without quotes): "0.87.0" +4. In the minimum minetest version, put the oldest supported version (as of 19/05/2024 it is 5.6), leave the Maximum minetest version blank +5. Click save. Release is now live. -##### Inform people +### After releasing -* Upload video to YouTube -* Add a comment to the forum post with the release number and change log. Maintainer will update main post with code link. -* Add a Discord announcement post and @everyone with link to video, forum post and release notes. +...inform people. + +* Open a release meta issue on the tracker, unpin and close the issue for the previous release, pin the new one. +* Upload video to YouTube. +* Add a comment to the forum post with the release number and change log. Maintainer will update the main post with code link. +* Add a Discord announcement post and @everyone with link to the release issue, release notes and other content, like video and forum post. +* Add a Matrix announcement post and @room with links like above. * Share the news on reddit + Lemmy. Good subs to share with: - * r/linux_gaming + * r/linux_gaming * r/opensourcegames * r/opensource * r/freesoftware * r/linuxmasterrace - * r/MineClone2 + * r/VoxeLibre + * r/MineClone2 (*for now*) + + +## Hotfix Release + +### Before releasing + +First, determine if the current state of the master branch is fine for the Hotfix. +In general, Hotfixes shouldn't contain new features to minimize the risk of regressions. + +* If it hasn't been long since the release, and the only PRs merged so far are bugfixes and/or documentation changes, +it is certainly fine to use it as a base for the release. +* If there are some features merged, but they are aimed at fixing/alleviating important issues with the last released version, it may still be fine. +* If there are some simple QoL features merged that are irrelevant to the last release, it may still be fine to use it as a base for the Hotfix. +* If there are major features or large overhauls merged, it *most probably* is **not** fine to use as a base for the Hotfix. + +If you decided that the current state of the master branch can be used as the Hotfix version, make sure that all the PRs merged since the last release +are in the Hotfix milestone and you are working on a clean branch based on the master branch, up-to-date with the one on the repo. +In this case, **skip** the following section. + +### Prepare release branch + +If you decided that the current state of the master branch shouldn't be used as the Hotfix version, you must prepare a release branch. + +1. Create release branch from the last release tag, push it: +``` +git checkout -b release/0.82.1 0.82.0 +git push origin release/0.82.1 +``` +2. Cherry-pick the relevant commits from the master branch, or merge them from other (PR) branches. +3. Make sure your local copy of the branch contains all the relevant changes, **do not rebase**. + +### Release process + +1. Update CREDITS.md if it is needed +2. Update version in game.conf +3. If you've changed CREDITS.md, run the script: +``` +lua tools/generate_ingame_credits.lua +``` +4. Make a commit for the above: +``` +git add game.conf +git commit -m "Set version for hotfix v0.87.1" +``` +or, if credits got updated: +``` +git add CREDITS.md +git add mods/HUD/mcl_credits/people.lua +git add game.conf +git commit -m "Updated release credits and set version for hotfix v0.87.1" +``` +5. Add a section in the last releasnotes, like this: +``` +## 0.87.1 hotfix +``` +and describe the changes there + +6. Make a commit for the releasenotes changes: +``` +git add releasenotes/0_87-the_prismatic_release.md +git commit -m "Update release notes for hotfix v0.87.1" +``` +7. **Tag and push to the tag:** +``` +git tag 0.87.1 +git push origin 0.87.1 +``` +8. If you are skipping some changes from the master branch (and thus are using a prepared master branch from the previous section), +push to the remote and skip the next two steps: +``` +git push origin release/0.82.1 +``` +9. If you're releasing master branch, update version in game.conf to the next version with -SNAPSHOT suffix: +``` +git commit -m "Post-hotfix reset version 0.88.0-SNAPSHOT" +``` +10. If you're releasing master branch, push the above to a new branch, and make the release PR. Merge to finalize release process. + +### Release via ContentDB + +1. Go to VoxeLibre page (https://content.minetest.net/packages/Wuzzy/mineclone2/) +2. Click [+Release] button +3. Enter the release tag number in the title and Git reference box. For example (without quotes): "0.87.1" +4. In the minimum minetest version, put the oldest supported version (as of 19/05/2024 it is 5.6), leave the Maximum minetest version blank +5. Click save. Hotfix is now live. + +### After releasing + +...inform people. + +* Add a comment to the forum post with the release number and change log. Maintainer will update the main post with code link. +* Add a Discord announcement post and @everyone with link to the release issue and release notes, and describe briefly what the hotfix does. +* Add a Matrix announcement post and @room with content like above. +* Share the news on reddit + Lemmy. Good subs to share with: + * r/linux_gaming + * r/opensourcegames + * r/opensource + * r/freesoftware + * r/linuxmasterrace + * r/VoxeLibre + * r/MineClone2 (*for now*) diff --git a/TEXTURES.md b/TEXTURES.md index 157965ae6..b29e19ed6 100644 --- a/TEXTURES.md +++ b/TEXTURES.md @@ -1,9 +1,9 @@ -# Making Textures In Mineclone2 +# Making Textures In VoxeLibre -Textures are a crucial asset for all items, nodes, and models in mineclone2. This document is for artist who would like to make and modify textures for mineclone2. While no means comprehensive, this document contains the basic important information for beginners to get started with texture curation and optimization. +Textures are a crucial asset for all items, nodes, and models in VoxeLibre. This document is for artist who would like to make and modify textures for VoxeLibre. While no means comprehensive, this document contains the basic important information for beginners to get started with texture curation and optimization. ## Minetest Wiki -For more detailed information on creating and modifing texture packs for Minetest/Mineclone2, please visit the Minetest wiki's page on creating a texture pack. Click [here](https://wiki.minetest.net/Creating_texture_packs) to view the wiki page on creating texture packs. +For more detailed information on creating and modifing texture packs for Minetest/VoxeLibre, please visit the Minetest wiki's page on creating a texture pack. Click [here](https://wiki.minetest.net/Creating_texture_packs) to view the wiki page on creating texture packs. ## GIMP Tutorials Pixel Art Guide GIMP Tutorials has an excellent guide to making pixel art in GIMP. If you would like further clarification as well as screenshots for what we are about to cover, it is an excellent resource to turn to. Click [here](https://thegimptutorials.com/how-to-make-pixel-art/) to view the guide diff --git a/game.conf b/game.conf index 3ad5a33a5..61cedc596 100644 --- a/game.conf +++ b/game.conf @@ -1,4 +1,4 @@ -title = MineClone 2 +title = VoxeLibre description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more. disallowed_mapgens = v6 -version=0.85.0-SNAPSHOT \ No newline at end of file +version=0.88.0-SNAPSHOT diff --git a/menu/HeaderTemplate.png b/menu/HeaderTemplate.png index ceddaa1f6..69aa42d5b 100644 Binary files a/menu/HeaderTemplate.png and b/menu/HeaderTemplate.png differ diff --git a/menu/header.1.png b/menu/header.1.png index 5204a0d02..55677d4ab 100644 Binary files a/menu/header.1.png and b/menu/header.1.png differ diff --git a/menu/header.2.png b/menu/header.2.png index 8b131302e..af735f03e 100644 Binary files a/menu/header.2.png and b/menu/header.2.png differ diff --git a/menu/header.3.png b/menu/header.3.png index dc618d7c6..a513af8ac 100644 Binary files a/menu/header.3.png and b/menu/header.3.png differ diff --git a/menu/header.png b/menu/header.png index 3c146f3cd..5e6eb5ee0 100644 Binary files a/menu/header.png and b/menu/header.png differ diff --git a/menu/icon.png b/menu/icon.png index 46b7475e3..433532678 100644 Binary files a/menu/icon.png and b/menu/icon.png differ diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index 1a259189b..884508032 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -16,7 +16,7 @@ information. How the mod is used =================== -In MineClone 2, all diggable nodes have the hardness set in the custom field +In VoxeLibre, all diggable nodes have the hardness set in the custom field "_mcl_hardness" (0 by default). These values are used together with digging groups by this mod to create the correct digging times for nodes. Digging groups are registered using the following code: diff --git a/mods/CORE/_mcl_autogroup/mod.conf b/mods/CORE/_mcl_autogroup/mod.conf index eea72c40f..db43aff39 100644 --- a/mods/CORE/_mcl_autogroup/mod.conf +++ b/mods/CORE/_mcl_autogroup/mod.conf @@ -1,3 +1,3 @@ name = _mcl_autogroup author = ryvnf -description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. +description = VoxeLibre core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/controls/init.lua b/mods/CORE/controls/init.lua index ef57281a4..7f308d8e0 100644 --- a/mods/CORE/controls/init.lua +++ b/mods/CORE/controls/init.lua @@ -31,6 +31,7 @@ local known_controls = { aux1 = true, down = true, up = true, + zoom = true, } minetest.register_on_joinplayer(function(player) diff --git a/mods/CORE/mcl_attached/init.lua b/mods/CORE/mcl_attached/init.lua index 2013dbde2..51ea2b0ae 100644 --- a/mods/CORE/mcl_attached/init.lua +++ b/mods/CORE/mcl_attached/init.lua @@ -1,5 +1,5 @@ -- Overrides the builtin minetest.check_single_for_falling. --- We need to do this in order to handle nodes in mineclone specific groups +-- We need to do this in order to handle nodes in VoxeLibre specific groups -- "supported_node" and "attached_node_facedir". -- -- Nodes in group "supported_node" can be placed on any node that does not @@ -94,5 +94,16 @@ function minetest.check_single_for_falling(pos) end end + if get_item_group(node.name, "supported_node_facedir") ~= 0 then + local dir = facedir_to_dir(node.param2) + if dir then + local def = registered_nodes[get_node(vector.add(pos, dir)).name] + if def and def.drawtype == "airlike" then + drop_attached_node(pos) + return true + end + end + end + return false end diff --git a/mods/CORE/mcl_autogroup/mod.conf b/mods/CORE/mcl_autogroup/mod.conf index 45818cd58..7222839aa 100644 --- a/mods/CORE/mcl_autogroup/mod.conf +++ b/mods/CORE/mcl_autogroup/mod.conf @@ -1,3 +1,3 @@ name = mcl_autogroup author = ryvnf -description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. +description = VoxeLibre core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 8804b8561..f6058dbaa 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -96,8 +96,8 @@ function mcl_damage.finish_reason(mcl_reason) end function mcl_damage.from_mt(mt_reason) - if mt_reason._mcl_chached_reason then - return mt_reason._mcl_chached_reason + if mt_reason._mcl_cached_reason then + return mt_reason._mcl_cached_reason end local mcl_reason diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index c6a6d192f..4fbe81860 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -1,8 +1,8 @@ --[[ -Explosion API mod for Minetest (adapted to MineClone 2) +Explosion API mod for Minetest (adapted to VoxeLibre) This mod is based on the Minetest explosion API mod, but has been changed -to have the same explosion mechanics as Minecraft and work with MineClone. +to have the same explosion mechanics as Minecraft and work with VoxeLibre The computation-intensive parts of the mod has been optimized to allow for larger explosions and faster world updating. diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.oc.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.oc.tr new file mode 100644 index 000000000..eac0b501d --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.oc.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1 z-es mòrt dins una explosion diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.pt_BR.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.pt_BR.tr new file mode 100644 index 000000000..d67ea4637 --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1 foi pego(a) em uma explosão. diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr new file mode 100644 index 000000000..0ef0dcd5f --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1 попал(а) под взрыв. \ No newline at end of file diff --git a/mods/CORE/mcl_init/init.lua b/mods/CORE/mcl_init/init.lua index f77b03828..3a0f1c4e5 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -1,6 +1,8 @@ -- Some global variables (don't overwrite them!) mcl_vars = {} +minetest.log("action", "World seed = " .. minetest.get_mapgen_setting("seed")) + mcl_vars.redstone_tick = 0.1 -- GUI / inventory menu settings @@ -36,6 +38,8 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, minetest.MAP_BLOCKSIZE or 16) mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000) mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000) +-- Central chunk is offset from 0,0,0 coordinates by 32 nodes (2 blocks) +-- See more in https://git.minetest.land/VoxeLibre/VoxeLibre/wiki/World-structure%3A-positions%2C-boundaries%2C-blocks%2C-chunks%2C-dimensions%2C-barriers-and-the-void local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2) mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE @@ -181,7 +185,7 @@ mcl_vars.mg_end_exit_portal_pos = vector.new(0, mcl_vars.mg_end_min + 71, 0) mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max mcl_vars.mg_realm_barrier_overworld_end_min = mcl_vars.mg_end_max - 11 --- Use MineClone 2-style dungeons +-- Use VoxeLibre-style dungeons mcl_vars.mg_dungeons = true -- Set default stack sizes diff --git a/mods/CORE/mcl_init/mod.conf b/mods/CORE/mcl_init/mod.conf index a0e810a2f..4ce7b394d 100644 --- a/mods/CORE/mcl_init/mod.conf +++ b/mods/CORE/mcl_init/mod.conf @@ -1,3 +1,3 @@ name = mcl_init author = Wuzzy -description = Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning. +description = Initialization mod of VoxeLibre. Defines some common shared variables and sets up initial default settings which have to be set at the beginning. diff --git a/mods/CORE/mcl_oxidation/README.md b/mods/CORE/mcl_oxidation/README.md index 3f3291b19..0fef8fc3d 100644 --- a/mods/CORE/mcl_oxidation/README.md +++ b/mods/CORE/mcl_oxidation/README.md @@ -1,4 +1,4 @@ -# Oxidization API for MineClone 2 +# Oxidization API for VoxeLibre This mods adds the oxidization api, so that modders can easily use the same features that copper uses. ## API @@ -11,4 +11,4 @@ For example, Copper Blocks have the definition arguement of `_mcl_waxed_variant For waxed nodes, scraping is easy. Start by putting `waxed = 1` into the list of groups of the waxed node. Next put `_mcl_stripped_variant = item string of the unwaxed variant of the node` into the defintion table. -Wxaed Copper Blocks can be scrapped into normal Copper Blocks because of the definition `_mcl_stripped_variant = "mcl_copper:block"`. +Waxed Copper Blocks can be scrapped into normal Copper Blocks because of the definition `_mcl_stripped_variant = "mcl_copper:block"`. diff --git a/mods/CORE/mcl_oxidation/mod.conf b/mods/CORE/mcl_oxidation/mod.conf index 7ab7eeffe..84d5d6828 100644 --- a/mods/CORE/mcl_oxidation/mod.conf +++ b/mods/CORE/mcl_oxidation/mod.conf @@ -1,4 +1,4 @@ name = mcl_oxidation -title = Oxidation API for MineClone 2 +title = Oxidation API for VoxeLibre author = PrairieWind, N011, Michael description = API to allow oxidizing different nodes. diff --git a/mods/CORE/mcl_particles/mod.conf b/mods/CORE/mcl_particles/mod.conf index b8252cbc5..8b02369ea 100644 --- a/mods/CORE/mcl_particles/mod.conf +++ b/mods/CORE/mcl_particles/mod.conf @@ -1,3 +1,2 @@ name = mcl_particles author = Wuzzy -description = Contains particle images of MineClone 2. No code. diff --git a/mods/CORE/mcl_sounds/mod.conf b/mods/CORE/mcl_sounds/mod.conf index 33bcafd9f..947fd1ba7 100644 --- a/mods/CORE/mcl_sounds/mod.conf +++ b/mods/CORE/mcl_sounds/mod.conf @@ -1,3 +1,3 @@ name = mcl_sounds author = Wuzzy -description = This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them. +description = This mod contains the core sounds of VoxeLibre as well as helper function for mods to access them. diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 5872ce742..b6fd71673 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -1,5 +1,7 @@ mcl_util = {} +dofile(minetest.get_modpath(minetest.get_current_modname()).."/roman_numerals.lua") + -- Updates all values in t using values from to*. function table.update(t, ...) for _, to in ipairs {...} do @@ -22,6 +24,30 @@ function table.update_nil(t, ...) return t 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 LOG_MODULE = "[MCL2]" function mcl_util.mcl_log(message, module, bypass_default_logger) @@ -74,10 +100,22 @@ function mcl_util.check_dtime_timer(self, dtime, timer_name, threshold) return false end +-- While we should always favour the new minetest vector functions such as vector.new or vector.offset which validate on +-- creation. There may be cases where state gets corrupted and we may have to check the vector is valid if created the +-- old way. This allows us to do this as a tactical solution until old style vectors are completely removed. +function mcl_util.validate_vector (vect) + if vect then + if tonumber(vect.x) and tonumber(vect.y) and tonumber(vect.z) then + return true + end + end + return false +end + -- Minetest 5.3.0 or less can only measure the light level. This came in at 5.4 -- This function has been known to fail in multiple places so the error handling is added increase safety and improve -- debugging. See: --- https://git.minetest.land/MineClone2/MineClone2/issues/1392 +-- https://git.minetest.land/VoxeLibre/VoxeLibre/issues/1392 function mcl_util.get_natural_light (pos, time) local status, retVal = pcall(minetest.get_natural_light, pos, time) if status then @@ -124,7 +162,7 @@ function mcl_util.rotate_axis_and_place(itemstack, placer, pointed_thing, infini return end local undef = minetest.registered_nodes[unode.name] - if undef and undef.on_rightclick then + if undef and undef.on_rightclick and not invert_wall then undef.on_rightclick(pointed_thing.under, unode, placer, itemstack, pointed_thing) return @@ -162,25 +200,11 @@ function mcl_util.rotate_axis_and_place(itemstack, placer, pointed_thing, infini local p2 if is_y then - if invert_wall then - if fdir == 3 or fdir == 1 then - p2 = 12 - else - p2 = 6 - end - end + p2 = 0 elseif is_x then - if invert_wall then - p2 = 0 - else - p2 = 12 - end + p2 = 12 elseif is_z then - if invert_wall then - p2 = 0 - else - p2 = 6 - end + p2 = 6 end minetest.set_node(pos, {name = wield_name, param2 = p2}) @@ -229,34 +253,34 @@ function mcl_util.get_double_container_neighbor_pos(pos, param2, side) end end --- Iterates through all items in the given inventory and --- returns the slot of the first item which matches a condition. --- Returns nil if no item was found. ---- source_inventory: Inventory to take the item from ---- source_list: List name of the source inventory from which to take the item ---- destination_inventory: Put item into this inventory ---- destination_list: List name of the destination inventory to which to put the item into ---- condition: Function which takes an itemstack and returns true if it matches the desired item condition. ---- If set to nil, the slot of the first item stack will be taken unconditionally. --- 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) +--- Selects item stack to transfer from +---@param src_inventory InvRef Source innentory to pull from +---@param src_list string Name of source inventory list to pull from +---@param dst_inventory InvRef Destination inventory to push to +---@param dst_list string Name of destination inventory list to push to +---@param condition? fun(stack: ItemStack) Condition which items are allowed to be transfered. +---@param count? integer Number of items to try to transfer at once +---@return integer Item stack number to be transfered +function mcl_util.select_stack(src_inventory, src_list, dst_inventory, dst_list, condition, count) + local src_size = src_inventory:get_size(src_list) local stack - for i = 1, size do + for i = 1, src_size do 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 + + -- Allow for partial stack movement + if count and stack:get_count() >= count then + local new_stack = ItemStack(stack) + new_stack:set_count(count) + stack = new_stack + end + + if not stack:is_empty() and dst_inventory:room_for_item(dst_list, stack) and ((condition == nil or condition(stack))) then return i end end return nil 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. --- source_inventory: Inventory to take the item from --- source_list: List name of the source inventory from which to take the item @@ -267,174 +291,91 @@ end -- Returns true on success and false on failure -- 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) - 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 + -- Can't move items we don't have + if source_inventory:is_empty(source_list) then return false end - if not source_inventory:is_empty(source_list) then - local stack = source_inventory:get_stack(source_list, source_stack_id) - if not stack:is_empty() then - local new_stack = ItemStack(stack) - new_stack:set_count(1) - if not destination_inventory:room_for_item(destination_list, new_stack) then - return false - end - stack:take_item() - source_inventory:set_stack(source_list, source_stack_id, stack) - destination_inventory:add_item(destination_list, new_stack) - return true - end - end - return false -end + -- Can't move from an empty stack + local stack = source_inventory:get_stack(source_list, source_stack_id) + if stack:is_empty() then return false end --- Moves a single item from one container node into another. Performs a variety of high-level --- checks to prevent invalid transfers such as shulker boxes into shulker boxes ---- source_pos: Position ({x,y,z}) of the node to take the item from ---- destination_pos: Position ({x,y,z}) of the node to put the item into ---- source_list (optional): List name of the source inventory from which to take the item. Default is normally "main"; "dst" for furnace ---- 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) ---- 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") - local sctype = minetest.get_item_group(snode.name, "container") - - -- Container type 7 does not allow any movement - if sctype == 7 then + local new_stack = ItemStack(stack) + new_stack:set_count(1) + if not destination_inventory:room_for_item(destination_list, new_stack) then return false end - - -- Normalize double container by forcing to always use the left segment first - local function normalize_double_container(pos, node, ctype) - if ctype == 6 then - pos = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - 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 - return pos, node, ctype - end - - 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 - - -- 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 + stack:take_item() + source_inventory:set_stack(source_list, source_stack_id, stack) + destination_inventory:add_item(destination_list, new_stack) + return true end --- Returns the ID of the first non-empty slot in the given inventory list --- or nil, if inventory is empty. -function mcl_util.get_first_occupied_inventory_slot(inventory, listname) - return mcl_util.get_eligible_transfer_item_slot(inventory, listname) +--- Try pushing item from hopper inventory to destination inventory +---@param pos Vector +---@param dst_pos Vector +function mcl_util.hopper_push(pos, dst_pos) + local hop_inv = minetest.get_meta(pos):get_inventory() + local hop_list = 'main' + + -- Get node pos' for item transfer + 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] + + local dst_list = 'main' + local dst_inv, stack_id + + -- Find a inventory stack in the destination + 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, nil, 1) + end + if not stack_id then return false end + + -- Move the item + local ok = mcl_util.move_item(hop_inv, hop_list, stack_id, dst_inv, dst_list) + if dst_def._mcl_hoppers_on_after_push then + dst_def._mcl_hoppers_on_after_push(dst_pos) + end + + return ok +end + +-- Try pulling from source inventory to hopper inventory +---@param pos Vector +---@param src_pos Vector +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, nil, 1) + 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 local function drop_item_stack(pos, stack) @@ -497,10 +438,11 @@ function mcl_util.generate_on_place_plant_function(condition) if not def_under or not def_above then return itemstack end - if def_under.buildable_to then + if def_under.buildable_to and def_under.name ~= itemstack:get_name() then place_pos = pointed_thing.under - elseif def_above.buildable_to then + elseif def_above.buildable_to and def_above.name ~= itemstack:get_name() then place_pos = pointed_thing.above + pointed_thing.under = pointed_thing.above else return itemstack end @@ -595,6 +537,7 @@ end function mcl_util.use_item_durability(itemstack, n) local uses = mcl_util.calculate_durability(itemstack) itemstack:add_wear(65535 / uses * n) + tt.reload_itemstack_description(itemstack) -- update tooltip end function mcl_util.deal_damage(target, damage, mcl_reason) @@ -612,7 +555,7 @@ function mcl_util.deal_damage(target, damage, mcl_reason) end return end - end + elseif not target:is_player() then return end local is_immortal = target:get_armor_groups().immortal or 0 if is_immortal>0 then @@ -1101,3 +1044,62 @@ function mcl_util.get_colorwallmounted_rotation(pos) 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) + mcl_util.mcl_log("item velocity calculated "..vector.to_string(v), "[mcl_util]") + 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 + +function mcl_util.is_it_christmas() + local date = os.date("*t") + if date.month == 12 and date.day >= 24 or date.month == 1 and date.day <= 7 then + return true + else + return false + end +end diff --git a/mods/CORE/mcl_util/mod.conf b/mods/CORE/mcl_util/mod.conf index 82f9137e4..f43663852 100644 --- a/mods/CORE/mcl_util/mod.conf +++ b/mods/CORE/mcl_util/mod.conf @@ -1,4 +1,4 @@ name = mcl_util author = Wuzzy -description = Helper functions for MineClone 2. +description = Helper functions for VoxeLibre. depends = mcl_init diff --git a/mods/CORE/mcl_util/roman_numerals.lua b/mods/CORE/mcl_util/roman_numerals.lua new file mode 100644 index 000000000..a808e43f1 --- /dev/null +++ b/mods/CORE/mcl_util/roman_numerals.lua @@ -0,0 +1,30 @@ +local converter = { + {1000, "M"}, + {900, "CM"}, + {500, "D"}, + {400, "CD"}, + {100, "C"}, + {90, "XC"}, + {50, "L"}, + {40, "XL"}, + {10, "X"}, + {9, "IX"}, + {5, "V"}, + {4, "IV"}, + {1, "I"} +} + +mcl_util.to_roman = function(number) + local r = "" + local a = number + local i = 1 + while a > 0 do + if a >= converter[i][1] then + a = a - converter[i][1] + r = r.. converter[i][2] + else + i = i + 1 + end + end + return r +end diff --git a/mods/CORE/mcl_worlds/API.md b/mods/CORE/mcl_worlds/API.md index 69508e924..6ad7639f4 100644 --- a/mods/CORE/mcl_worlds/API.md +++ b/mods/CORE/mcl_worlds/API.md @@ -31,7 +31,7 @@ This function return the Minecraft dimension of ("overworld", "nether" or * pos: position ## mcl_worlds.layer_to_y(layer, mc_dimension) -Takes a Minecraft layer and a “dimension” name and returns the corresponding Y coordinate for MineClone 2. +Takes a Minecraft layer and a “dimension” name and returns the corresponding Y coordinate for VoxeLibre. mc_dimension can be "overworld", "nether", "end" (default: "overworld"). * layer: int diff --git a/mods/CORE/mcl_worlds/init.lua b/mods/CORE/mcl_worlds/init.lua index 4f8914506..f397ccfd5 100644 --- a/mods/CORE/mcl_worlds/init.lua +++ b/mods/CORE/mcl_worlds/init.lua @@ -58,7 +58,7 @@ local pos_to_dimension = mcl_worlds.pos_to_dimension -- Takes a Minecraft layer and a “dimension” name -- and returns the corresponding Y coordinate for --- MineClone 2. +-- VoxeLibre -- mc_dimension is one of "overworld", "nether", "end" (default: "overworld"). function mcl_worlds.layer_to_y(layer, mc_dimension) if mc_dimension == "overworld" or mc_dimension == nil then diff --git a/mods/CORE/tga_encoder/LICENSE b/mods/CORE/tga_encoder/LICENSE new file mode 100644 index 000000000..f288702d2 --- /dev/null +++ b/mods/CORE/tga_encoder/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/mods/CORE/tga_encoder/README.md b/mods/CORE/tga_encoder/README.md index 9b3293dda..ed7d14538 100644 --- a/mods/CORE/tga_encoder/README.md +++ b/mods/CORE/tga_encoder/README.md @@ -1,4 +1,87 @@ # tga_encoder A TGA Encoder written in Lua without the use of external Libraries. +Created by fleckenstein for VoxeLibre, then improved by erlehmann. + May be used as a Minetest mod. + +See `examples.lua` for example code and usage hints. + +## Use Cases for `tga_encoder` + +### Encoding Textures for Editing + +TGA images of types 1/2/3 consist of header data followed by a pixel array. + +This makes it trivial to parse TGA files – and even edit pixels in-place. + +No checksums need to be updated on any kind of in-place texture editing. + +**Tip**: When storing an editable image in item meta, use zlib compression. + +### Legacy Minetest Texture Encoding + +Minetest 5.4 did not include `minetest.encode_png()` (or any equvivalent). + +Since `tga_encoder` is written in pure Lua, it does not need engine support. + +**Tip:** Look at `examples.lua` and the Minetest mod `mcl_maps` for guidance. + +### Advanced Texture Format Control + +The function `minetest.encode_png()` always encodes images as 32bpp RGBA. + +`tga_encoder` allows saving images as grayscale, 16bpp RGBA and 24bpp RGB. + +For generating maps from terrain, color-mapped formats can be more useful. + +### Encoding Very Small Textures + +Images of size 8×8 or below are often smaller than an equivalent PNG file. + +Note that on many filesystems files use at least 4096 bytes (i.e. 64×64). + +Therefore, saving bytes on files up to a few 100 bytes is often useless. + +### Encoding Reference Textures + +TGA is a simple format, which makes it easy to create reference textures. + +Using a hex editor, one can trivially see how all the pixels are stored. + +## Supported Image Types + +For all types, images are encoded in a fast single pass (i.e. append-only). + +### Color-Mapped Images (Type 1) + +These images contain a palette, followed by pixel data. + +* `A1R5G5B5` (8bpp RGB) +* `B8G8R8` (8bpp RGB) +* `B8G8R8A8` (8bpp RGBA) + +### True-Color Images (Type 2) + +These images contain uncompressed RGB(A) pixel data. + +* `A1R5G5B5` (16bpp RGBA) +* `B8G8R8` (24bpp RGB) +* `B8G8R8A8` (32bpp RGBA) + +### Grayscale Images (Type 3) + +* `Y8` (8bpp grayscale) + +### Run-Length Encoded (RLE), True-Color Images (Type 10) + +These images contain compressed RGB(A) pixel data. + +* `A1R5G5B5` (16bpp RGBA) +* `B8G8R8` (24bpp RGB) +* `B8G8R8A8` (32bpp RGBA) + +## TODO + +* Actually support `R8G8B8A8` input for `A1R5G5B5` output +* Add both zoomable and explorable maps to `mcl_maps`. diff --git a/mods/CORE/tga_encoder/colormap_generator.lua b/mods/CORE/tga_encoder/colormap_generator.lua new file mode 100644 index 000000000..cc6c6a31e --- /dev/null +++ b/mods/CORE/tga_encoder/colormap_generator.lua @@ -0,0 +1,32 @@ +dofile("init.lua") + +-- This generates images necessary to colorize 16 Minetest nodes in 4096 colors. +-- It serves as a demonstration of what you can achieve using colormapped nodes. +-- It is be useful for grass or beam or glass nodes that need to blend smoothly. + +-- Sample depth rescaling is done according to the algorithm presented in: +-- +local max_sample_in = math.pow(2, 4) - 1 +local max_sample_out = math.pow(2, 8) - 1 + +for r = 0,15 do + local pixels = {} + for g = 0,15 do + if nil == pixels[g + 1] then + pixels[g + 1] = {} + end + for b = 0,15 do + local color = { + math.floor((r * max_sample_out / max_sample_in) + 0.5), + math.floor((g * max_sample_out / max_sample_in) + 0.5), + math.floor((b * max_sample_out / max_sample_in) + 0.5), + } + pixels[g + 1][b + 1] = color + end + end + local filename = "colormap_" .. tostring(r) .. ".tga" + tga_encoder.image(pixels):save( + filename, + { color_format="A1R5G5B5" } -- waste less bits + ) +end diff --git a/mods/CORE/tga_encoder/donut.lua b/mods/CORE/tga_encoder/donut.lua new file mode 100644 index 000000000..8567f8aed --- /dev/null +++ b/mods/CORE/tga_encoder/donut.lua @@ -0,0 +1,105 @@ +#!/usr/bin/env lua5.1 +-- -*- coding: utf-8 -*- + +-- 3D “donut” shape rendering using floating-point math +-- see + +-- cargo-culted by erle 2023-09-18 + +local theta_spacing = 0.01 -- 0.07 +local phi_spacing = 0.002 -- 0.02 + +local R1 = 1 +local R2 = 2 +local K2 = 5 + +local screen_height = 256 +local screen_width = 256 + +local K1 = screen_width * K2 * 3 / ( 8 * ( R1 + R2 ) ) + +local output = {} +local zbuffer = {} + +local grey = { 120, 120, 120 } +local gray = { 136, 136, 136 } + +for y = 1,screen_height,1 do + output[y] = {} + zbuffer[y] = {} + for x = 1,screen_width,1 do + local hori = math.floor( ( (y - 1) / 32 ) % 2 ) + local vert = math.floor( ( (x - 1) / 32 ) % 2 ) + output[y][x] = hori ~= vert and grey or gray + zbuffer[y][x] = 0 + end +end + +function render_frame(A, B) + -- precompute sines and cosines of A and B + local cosA = math.cos(A) + local sinA = math.sin(A) + local cosB = math.cos(B) + local sinB = math.sin(B) + + -- theta goas around the cross-sectional circle of a torus + local theta = 0 + while theta <= 2*math.pi do + if ( theta < 2*math.pi * 1/8 ) or ( theta > 2*math.pi * 7/8 ) then + theta = theta + (theta_spacing * 16) + else + theta = theta + theta_spacing + end + -- precompute sines and cosines of theta + local costheta = math.cos(theta) + local sintheta = math.sin(theta) + + -- phi goes around the center of revolution of a torus + local phi = 0 + while phi <= 2*math.pi do + if ( phi > 2*math.pi * 3/8 ) and ( phi < 2*math.pi * 5/8 ) then + phi = phi + (phi_spacing * 128) + else + phi = phi + phi_spacing + end + -- precompute sines and cosines of phi + local cosphi = math.cos(phi) + local sinphi = math.sin(phi) + + -- 2D (x, y) coordinates of the circle, before revolving + local circlex = R2 + R1*costheta + local circley = R1*sintheta + + -- 3D (x, y, z) coordinates after rotation + local x = circlex*(cosB*cosphi + sinA*sinB*sinphi) - circley*cosA*sinB + local y = circlex*(sinB*cosphi - sinA*cosB*sinphi) + circley*cosA*cosB + local z = K2 + cosA*circlex*sinphi + circley*sinA + + local ooz = 1/z + + -- x and y projection + local xp = math.floor(screen_width/2 + K1*ooz*x) + local yp = math.floor(screen_height/2 + K1*ooz*y) + + -- calculate luminance + local L = cosphi*costheta*sinB - cosA*costheta*sinphi - sinA*sintheta + cosB*( cosA*sintheta - costheta*sinA*sinphi ) + -- if (L > 0) then + if (true) then + if (ooz > zbuffer[yp][xp]) then + zbuffer[yp][xp] = ooz + local luminance = math.max( math.ceil( L * 180 ), 0 ) + -- luminance is now in the range 0 to 255 + r = math.ceil( (luminance + xp) / 2 ) + g = math.ceil( (luminance + yp) / 2 ) + b = math.ceil( (luminance + xp + yp) / 3 ) + output[yp][xp] = { r, g, b } + end + end + end + end +end + +dofile('init.lua') + +render_frame(-0.7, 0.7) +tga_encoder.image(output):save("donut.tga") diff --git a/mods/CORE/tga_encoder/examples.lua b/mods/CORE/tga_encoder/examples.lua new file mode 100644 index 000000000..f304998db --- /dev/null +++ b/mods/CORE/tga_encoder/examples.lua @@ -0,0 +1,181 @@ +dofile("init.lua") + +-- encode a bitmap +local _ = { 0, 0, 0 } +local R = { 255, 127, 127 } +local pixels = { + { _, _, _, _, _, _, _ }, + { _, _, _, R, _, _, _ }, + { _, _, R, R, R, _, _ }, + { _, R, R, R, R, R, _ }, + { _, R, R, R, R, R, _ }, + { _, _, R, _, R, _, _ }, + { _, _, _, _, _, _, _ }, +} +tga_encoder.image(pixels):save("bitmap_small.tga") + +-- test that image can be encoded +local bitmap_small_0 = tga_encoder.image(pixels) +bitmap_small_0:encode() +assert(191 == #bitmap_small_0.data) + +-- test that imbage can be encoded with parameters +local bitmap_small_1 = tga_encoder.image(pixels) +bitmap_small_1:encode( + { + colormap = {}, + color_format = "B8G8R8", + compression = "RAW", + } +) +assert(191 == #bitmap_small_1.data) + +-- change a single pixel, then rescale the bitmap +local pixels_orig = pixels +pixels_orig[4][4] = { 255, 255, 255 } +local pixels = {} +for x = 1,56,1 do + local x_orig = math.ceil(x/8) + for z = 1,56,1 do + local z_orig = math.ceil(z/8) + local color = pixels_orig[z_orig][x_orig] + pixels[z] = pixels[z] or {} + pixels[z][x] = color + end +end +tga_encoder.image(pixels):save("bitmap_large.tga") + +-- note that the uncompressed grayscale TGA file written in this +-- example is 80 bytes – but an optimized PNG file is 81 bytes … +local pixels = {} +for x = 1,6,1 do -- left to right + for z = 1,6,1 do -- bottom to top + local color = { math.min(x * z * 4 - 1, 255) } + pixels[z] = pixels[z] or {} + pixels[z][x] = color + end +end +tga_encoder.image(pixels):save("gradient_8bpp_raw.tga", {color_format="Y8", compression="RAW"}) + +local pixels = {} +for x = 1,16,1 do -- left to right + for z = 1,16,1 do -- bottom to top + local r = math.min(x * 32 - 1, 255) + local g = math.min(z * 32 - 1, 255) + local b = 0 + -- blue rectangle in top right corner + if x > 8 and z > 8 then + r = 0 + g = 0 + b = math.min(z * 16 - 1, 255) + end + local color = { r, g, b } + pixels[z] = pixels[z] or {} + pixels[z][x] = color + end +end +local gradients = tga_encoder.image(pixels) +gradients:save("gradients_8bpp_raw.tga", {color_format="Y8", compression="RAW"}) +gradients:save("gradients_16bpp_raw.tga", {color_format="A1R5G5B5", compression="RAW"}) +gradients:save("gradients_16bpp_rle.tga", {color_format="A1R5G5B5", compression="RLE"}) +gradients:save("gradients_24bpp_raw.tga", {color_format="B8G8R8", compression="RAW"}) +gradients:save("gradients_24bpp_rle.tga", {color_format="B8G8R8", compression="RLE"}) + +for x = 1,16,1 do -- left to right + for z = 1,16,1 do -- bottom to top + local color = pixels[z][x] + color[#color+1] = ((x * x) + (z * z)) % 256 + pixels[z][x] = color + end +end +gradients:save("gradients_32bpp_raw.tga", {color_format="B8G8R8A8", compression="RAW"}) +-- the RLE-compressed file is larger than just dumping pixels because +-- the gradients in this picture can not be compressed well using RLE +gradients:save("gradients_32bpp_rle.tga", {color_format="B8G8R8A8", compression="RLE"}) + +local pixels = {} +for x = 1,512,1 do -- left to right + for z = 1,512,1 do -- bottom to top + local oz = (z - 256) / 256 + 0.75 + local ox = (x - 256) / 256 + local px, pz, i = 0, 0, 0 + while (px * px) + (pz * pz) <= 4 and i < 128 do + px = (px * px) - (pz * pz) + oz + pz = (2 * px * pz) + ox + i = i + 1 + end + local color = { + math.max(0, math.min(255, math.floor(px * 64))), + math.max(0, math.min(255, math.floor(pz * 64))), + math.max(0, math.min(255, math.floor(i))), + } + pixels[z] = pixels[z] or {} + pixels[z][x] = color + end +end +tga_encoder.image(pixels):save("fractal_8bpp.tga", {color_format="Y8"}) +tga_encoder.image(pixels):save("fractal_16bpp.tga", {color_format="A1R5G5B5"}) +tga_encoder.image(pixels):save("fractal_24bpp.tga", {color_format="B8G8R8"}) + +-- encode a colormapped bitmap +local K = { 0 } +local B = { 1 } +local R = { 2 } +local G = { 3 } +local W = { 4 } +local colormap = { + { 1, 2, 3 }, -- K + { 0, 0, 255 }, -- B + { 255, 0, 0 }, -- R + { 0, 255, 0 }, -- G + { 253, 254, 255 }, -- W +} +local pixels = { + { W, K, W, K, W, K, W }, + { R, G, B, R, G, B, K }, + { K, W, K, W, K, W, K }, + { G, B, R, G, B, R, W }, + { W, W, W, K, K, K, W }, + { B, R, G, B, R, G, K }, + { B, R, G, B, R, G, W }, +} +-- note that the uncompressed colormapped TGA file written in this +-- example is 108 bytes – but an optimized PNG file is 121 bytes … +tga_encoder.image(pixels):save("colormapped_B8G8R8.tga", {colormap=colormap}) +-- encoding as A1R5G5B5 saves 1 byte per palette entry → 103 bytes +tga_encoder.image(pixels):save("colormapped_A1R5G5B5.tga", {colormap=colormap, color_format="A1R5G5B5"}) + +-- encode a colormapped bitmap with transparency +local _ = { 0 } +local K = { 1 } +local W = { 2 } +local colormap = { + { 0, 0, 0, 0 }, + { 0, 0, 0, 255 }, + { 255, 255, 255, 255 }, +} +local pixels = { + { _, K, K, K, K, K, _ }, + { _, K, W, W, W, K, _ }, + { K, K, W, W, W, K, K }, + { K, W, W, W, W, W, K }, + { _, K, W, W, W, K, _ }, + { _, _, K, W, K, _, _ }, + { _, _, _, K, _, _, _ }, +} +tga_encoder.image(pixels):save("colormapped_B8G8R8A8.tga", {colormap=colormap}) + +-- encoding a colormapped image with illegal colormap indexes should error out +local colormap = { + { 0, 0, 0, 0 }, + { 0, 0, 0, 255 }, +} +local status, message = pcall( + function () + tga_encoder.image(pixels):encode({colormap=colormap}) + end +) +assert( + false == status and + "init.lua:36: colormap index 2 not in colormap of size 2" == message +) diff --git a/mods/CORE/tga_encoder/init.lua b/mods/CORE/tga_encoder/init.lua index 24ec502e1..1a0bd4738 100644 --- a/mods/CORE/tga_encoder/init.lua +++ b/mods/CORE/tga_encoder/init.lua @@ -9,60 +9,566 @@ local image = setmetatable({}, { }) function image:constructor(pixels) - self.data = "" self.pixels = pixels self.width = #pixels[1] self.height = #pixels - - self:encode() end -function image:encode_colormap_spec() - self.data = self.data - .. string.char(0, 0) -- first entry index - .. string.char(0, 0) -- number of entries - .. string.char(0) -- bits per pixel +local pixel_depth_by_color_format = { + ["Y8"] = 8, + ["A1R5G5B5"] = 16, + ["B8G8R8"] = 24, + ["B8G8R8A8"] = 32, +} + +function image:encode_colormap_spec(properties) + local colormap = properties.colormap + local colormap_pixel_depth = 0 + if 0 ~= #colormap then + colormap_pixel_depth = pixel_depth_by_color_format[ + properties.color_format + ] + -- ensure that each pixel references a legal colormap entry + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + local colormap_index = pixel[1] + if colormap_index >= #colormap then + error( + "colormap index " .. colormap_index .. + " not in colormap of size " .. #colormap + ) + end + end + end + end + local colormap_spec = + string.char(0, 0) .. -- first entry index + string.char(#colormap % 256, math.floor(#colormap / 256)) .. -- number of entries + string.char(colormap_pixel_depth) -- bits per pixel + self.data = self.data .. colormap_spec end -function image:encode_image_spec() - self.data = self.data - .. string.char(0, 0) -- X-origin - .. string.char(0, 0) -- Y-origin - .. string.char(self.width % 256, math.floor(self.width / 256)) -- width - .. string.char(self.height % 256, math.floor(self.height / 256)) -- height - .. string.char(24) -- pixel depth (RGB = 3 bytes = 24 bits) - .. string.char(0) -- image descriptor +function image:encode_image_spec(properties) + local color_format = properties.color_format + assert( + "Y8" == color_format or -- (8 bit grayscale = 1 byte = 8 bits) + "A1R5G5B5" == color_format or -- (A1R5G5B5 = 2 bytes = 16 bits) + "B8G8R8" == color_format or -- (B8G8R8 = 3 bytes = 24 bits) + "B8G8R8A8" == color_format -- (B8G8R8A8 = 4 bytes = 32 bits) + ) + local scanline_order = properties.scanline_order + assert ( + "bottom-top" == scanline_order or + "top-bottom" == scanline_order + ) + local pixel_depth + if 0 ~= #properties.colormap then + pixel_depth = self.pixel_depth + else + pixel_depth = pixel_depth_by_color_format[color_format] + end + assert( nil ~= pixel_depth) + -- the origin is the bottom left corner of the image (always) + local x_origin_lo = 0 + local x_origin_hi = 0 + local y_origin_lo = 0 + local y_origin_hi = 0 + local image_descriptor = 0 -- equal to bottom-top scanline order + local width_lo = self.width % 256 + local width_hi = math.floor(self.width / 256) + local height_lo = self.height % 256 + local height_hi = math.floor(self.height / 256) + if "top-bottom" == scanline_order then + image_descriptor = 32 + y_origin_lo = height_lo + y_origin_hi = height_hi + end + self.data = self.data .. string.char ( + x_origin_lo, x_origin_hi, + y_origin_lo, y_origin_hi, + width_lo, width_hi, + height_lo, height_hi, + pixel_depth, + image_descriptor + ) end -function image:encode_header() +function image:encode_colormap(properties) + local colormap = properties.colormap + if 0 == #colormap then + return + end + local color_format = properties.color_format + assert ( + "A1R5G5B5" == color_format or + "B8G8R8" == color_format or + "B8G8R8A8" == color_format + ) + local colors = {} + if "A1R5G5B5" == color_format then + -- Sample depth rescaling is done according to the algorithm presented in: + -- + local max_sample_in = math.pow(2, 8) - 1 + local max_sample_out = math.pow(2, 5) - 1 + for i = 1,#colormap,1 do + local color = colormap[i] + local colorword = 32768 + + ((math.floor((color[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) + + ((math.floor((color[2] * max_sample_out / max_sample_in) + 0.5)) * 32) + + ((math.floor((color[3] * max_sample_out / max_sample_in) + 0.5)) * 1) + local color_bytes = string.char( + colorword % 256, + math.floor(colorword / 256) + ) + colors[#colors + 1] = color_bytes + end + elseif "B8G8R8" == color_format then + for i = 1,#colormap,1 do + local color = colormap[i] + local color_bytes = string.char( + color[3], -- B + color[2], -- G + color[1] -- R + ) + colors[#colors + 1] = color_bytes + end + elseif "B8G8R8A8" == color_format then + for i = 1,#colormap,1 do + local color = colormap[i] + local color_bytes = string.char( + color[3], -- B + color[2], -- G + color[1], -- R + color[4] -- A + ) + colors[#colors + 1] = color_bytes + end + end + assert( 0 ~= #colors ) + self.data = self.data .. table.concat(colors) +end + +function image:encode_header(properties) + local color_format = properties.color_format + local colormap = properties.colormap + local compression = properties.compression + local colormap_type + local image_type + if "Y8" == color_format and "RAW" == compression then + colormap_type = 0 + image_type = 3 -- grayscale + elseif ( + "A1R5G5B5" == color_format or + "B8G8R8" == color_format or + "B8G8R8A8" == color_format + ) then + if "RAW" == compression then + if 0 ~= #colormap then + colormap_type = 1 + image_type = 1 -- colormapped RGB(A) + else + colormap_type = 0 + image_type = 2 -- RAW RGB(A) + end + elseif "RLE" == compression then + colormap_type = 0 + image_type = 10 -- RLE RGB + end + end + assert( nil ~= colormap_type ) + assert( nil ~= image_type ) self.data = self.data .. string.char(0) -- image id - .. string.char(0) -- color map type - .. string.char(10) -- image type (RLE RGB = 10) - self:encode_colormap_spec() -- color map specification - self:encode_image_spec() -- image specification + .. string.char(colormap_type) + .. string.char(image_type) + self:encode_colormap_spec(properties) -- color map specification + self:encode_image_spec(properties) -- image specification + self:encode_colormap(properties) end -function image:encode_data() - local current_pixel = '' - local previous_pixel = '' - local count = 1 - local packets = {} - local rle_packet = '' +function image:encode_data(properties) + local color_format = properties.color_format + local colormap = properties.colormap + local compression = properties.compression + + local data_length_before = #self.data + if "Y8" == color_format and "RAW" == compression then + if 8 == self.pixel_depth then + self:encode_data_Y8_as_Y8_raw() + elseif 24 == self.pixel_depth then + self:encode_data_R8G8B8_as_Y8_raw() + end + elseif "A1R5G5B5" == color_format then + if 0 ~= #colormap then + if "RAW" == compression then + if 8 == self.pixel_depth then + self:encode_data_Y8_as_Y8_raw() + end + end + else + if "RAW" == compression then + self:encode_data_R8G8B8_as_A1R5G5B5_raw() + elseif "RLE" == compression then + self:encode_data_R8G8B8_as_A1R5G5B5_rle() + end + end + elseif "B8G8R8" == color_format then + if 0 ~= #colormap then + if "RAW" == compression then + if 8 == self.pixel_depth then + self:encode_data_Y8_as_Y8_raw() + end + end + else + if "RAW" == compression then + self:encode_data_R8G8B8_as_B8G8R8_raw() + elseif "RLE" == compression then + self:encode_data_R8G8B8_as_B8G8R8_rle() + end + end + elseif "B8G8R8A8" == color_format then + if 0 ~= #colormap then + if "RAW" == compression then + if 8 == self.pixel_depth then + self:encode_data_Y8_as_Y8_raw() + end + end + else + if "RAW" == compression then + self:encode_data_R8G8B8A8_as_B8G8R8A8_raw() + elseif "RLE" == compression then + self:encode_data_R8G8B8A8_as_B8G8R8A8_rle() + end + end + end + local data_length_after = #self.data + assert( + data_length_after ~= data_length_before, + "No data encoded for color format: " .. color_format + ) +end + +function image:encode_data_Y8_as_Y8_raw() + assert(8 == self.pixel_depth) + local raw_pixels = {} for _, row in ipairs(self.pixels) do for _, pixel in ipairs(row) do - current_pixel = string.char(pixel[3], pixel[2], pixel[1]) - if current_pixel ~= previous_pixel or count == 128 then - packets[#packets +1] = rle_packet + local raw_pixel = string.char(pixel[1]) + raw_pixels[#raw_pixels + 1] = raw_pixel + end + end + self.data = self.data .. table.concat(raw_pixels) +end + +function image:encode_data_R8G8B8_as_Y8_raw() + assert(24 == self.pixel_depth) + local raw_pixels = {} + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + -- the HSP RGB to brightness formula is + -- sqrt( 0.299 r² + .587 g² + .114 b² ) + -- see + local gray = math.floor( + math.sqrt( + 0.299 * pixel[1]^2 + + 0.587 * pixel[2]^2 + + 0.114 * pixel[3]^2 + ) + 0.5 + ) + local raw_pixel = string.char(gray) + raw_pixels[#raw_pixels + 1] = raw_pixel + end + end + self.data = self.data .. table.concat(raw_pixels) +end + +function image:encode_data_R8G8B8_as_A1R5G5B5_raw() + assert(24 == self.pixel_depth) + local raw_pixels = {} + -- Sample depth rescaling is done according to the algorithm presented in: + -- + local max_sample_in = math.pow(2, 8) - 1 + local max_sample_out = math.pow(2, 5) - 1 + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + local colorword = 32768 + + ((math.floor((pixel[1] * max_sample_out / max_sample_in) + 0.5)) * 1024) + + ((math.floor((pixel[2] * max_sample_out / max_sample_in) + 0.5)) * 32) + + ((math.floor((pixel[3] * max_sample_out / max_sample_in) + 0.5)) * 1) + local raw_pixel = string.char(colorword % 256, math.floor(colorword / 256)) + raw_pixels[#raw_pixels + 1] = raw_pixel + end + end + self.data = self.data .. table.concat(raw_pixels) +end + +function image:encode_data_R8G8B8_as_A1R5G5B5_rle() + assert(24 == self.pixel_depth) + local colorword = nil + local previous_r = nil + local previous_g = nil + local previous_b = nil + local raw_pixel = '' + local raw_pixels = {} + local count = 1 + local packets = {} + local raw_packet = '' + local rle_packet = '' + -- Sample depth rescaling is done according to the algorithm presented in: + -- + local max_sample_in = math.pow(2, 8) - 1 + local max_sample_out = math.pow(2, 5) - 1 + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + if pixel[1] ~= previous_r or pixel[2] ~= previous_g or pixel[3] ~= previous_b or count == 128 then + if nil ~= previous_r then + colorword = 32768 + + ((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) + + ((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) + + ((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1) + if 1 == count then + -- remember pixel verbatim for raw encoding + raw_pixel = string.char(colorword % 256, math.floor(colorword / 256)) + raw_pixels[#raw_pixels + 1] = raw_pixel + if 128 == #raw_pixels then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, colorword % 256, math.floor(colorword / 256)) + packets[#packets +1] = rle_packet + end + end count = 1 - previous_pixel = current_pixel + previous_r = pixel[1] + previous_g = pixel[2] + previous_b = pixel[3] else count = count + 1 end - rle_packet = string.char(128 + count - 1) .. current_pixel end end - packets[#packets +1] = rle_packet + colorword = 32768 + + ((math.floor((previous_r * max_sample_out / max_sample_in) + 0.5)) * 1024) + + ((math.floor((previous_g * max_sample_out / max_sample_in) + 0.5)) * 32) + + ((math.floor((previous_b * max_sample_out / max_sample_in) + 0.5)) * 1) + if 1 == count then + raw_pixel = string.char(colorword % 256, math.floor(colorword / 256)) + raw_pixels[#raw_pixels + 1] = raw_pixel + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, colorword % 256, math.floor(colorword / 256)) + packets[#packets +1] = rle_packet + end + self.data = self.data .. table.concat(packets) +end + +function image:encode_data_R8G8B8_as_B8G8R8_raw() + assert(24 == self.pixel_depth) + local raw_pixels = {} + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + local raw_pixel = string.char(pixel[3], pixel[2], pixel[1]) + raw_pixels[#raw_pixels + 1] = raw_pixel + end + end + self.data = self.data .. table.concat(raw_pixels) +end + +function image:encode_data_R8G8B8_as_B8G8R8_rle() + assert(24 == self.pixel_depth) + local previous_r = nil + local previous_g = nil + local previous_b = nil + local raw_pixel = '' + local raw_pixels = {} + local count = 1 + local packets = {} + local raw_packet = '' + local rle_packet = '' + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + if pixel[1] ~= previous_r or pixel[2] ~= previous_g or pixel[3] ~= previous_b or count == 128 then + if nil ~= previous_r then + if 1 == count then + -- remember pixel verbatim for raw encoding + raw_pixel = string.char(previous_b, previous_g, previous_r) + raw_pixels[#raw_pixels + 1] = raw_pixel + if 128 == #raw_pixels then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, previous_b, previous_g, previous_r) + packets[#packets +1] = rle_packet + end + end + count = 1 + previous_r = pixel[1] + previous_g = pixel[2] + previous_b = pixel[3] + else + count = count + 1 + end + end + end + if 1 == count then + raw_pixel = string.char(previous_b, previous_g, previous_r) + raw_pixels[#raw_pixels + 1] = raw_pixel + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, previous_b, previous_g, previous_r) + packets[#packets +1] = rle_packet + end + self.data = self.data .. table.concat(packets) +end + +function image:encode_data_R8G8B8A8_as_B8G8R8A8_raw() + assert(32 == self.pixel_depth) + local raw_pixels = {} + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + local raw_pixel = string.char(pixel[3], pixel[2], pixel[1], pixel[4]) + raw_pixels[#raw_pixels + 1] = raw_pixel + end + end + self.data = self.data .. table.concat(raw_pixels) +end + +function image:encode_data_R8G8B8A8_as_B8G8R8A8_rle() + assert(32 == self.pixel_depth) + local previous_r = nil + local previous_g = nil + local previous_b = nil + local previous_a = nil + local raw_pixel = '' + local raw_pixels = {} + local count = 1 + local packets = {} + local raw_packet = '' + local rle_packet = '' + for _, row in ipairs(self.pixels) do + for _, pixel in ipairs(row) do + if pixel[1] ~= previous_r or pixel[2] ~= previous_g or pixel[3] ~= previous_b or pixel[4] ~= previous_a or count == 128 then + if nil ~= previous_r then + if 1 == count then + -- remember pixel verbatim for raw encoding + raw_pixel = string.char(previous_b, previous_g, previous_r, previous_a) + raw_pixels[#raw_pixels + 1] = raw_pixel + if 128 == #raw_pixels then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, previous_b, previous_g, previous_r, previous_a) + packets[#packets +1] = rle_packet + end + end + count = 1 + previous_r = pixel[1] + previous_g = pixel[2] + previous_b = pixel[3] + previous_a = pixel[4] + else + count = count + 1 + end + end + end + if 1 == count then + raw_pixel = string.char(previous_b, previous_g, previous_r, previous_a) + raw_pixels[#raw_pixels + 1] = raw_pixel + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + else + -- encode raw pixels, if any + if #raw_pixels > 0 then + raw_packet = string.char(#raw_pixels - 1) + packets[#packets + 1] = raw_packet + for i=1, #raw_pixels do + packets[#packets +1] = raw_pixels[i] + end + raw_pixels = {} + end + -- RLE encoding + rle_packet = string.char(128 + count - 1, previous_b, previous_g, previous_r, previous_a) + packets[#packets +1] = rle_packet + end self.data = self.data .. table.concat(packets) end @@ -75,15 +581,45 @@ function image:encode_footer() .. string.char(0) end -function image:encode() - self:encode_header() -- header +function image:encode(properties) + local properties = properties or {} + properties.colormap = properties.colormap or {} + properties.compression = properties.compression or "RAW" + properties.scanline_order = properties.scanline_order or "bottom-top" + + self.pixel_depth = #self.pixels[1][1] * 8 + + local color_format_defaults_by_pixel_depth = { + [8] = "Y8", + [24] = "B8G8R8", + [32] = "B8G8R8A8", + } + if nil == properties.color_format then + if 0 ~= #properties.colormap then + properties.color_format = + color_format_defaults_by_pixel_depth[ + #properties.colormap[1] * 8 + ] + else + properties.color_format = + color_format_defaults_by_pixel_depth[ + self.pixel_depth + ] + end + end + assert( nil ~= properties.color_format ) + + self.data = "" + self:encode_header(properties) -- header -- no color map and image id data - self:encode_data() -- encode data + self:encode_data(properties) -- encode data -- no extension or developer area self:encode_footer() -- footer end -function image:save(filename) +function image:save(filename, properties) + self:encode(properties) + local f = assert(io.open(filename, "wb")) f:write(self.data) f:close() diff --git a/mods/CORE/tga_encoder/logo.lua b/mods/CORE/tga_encoder/logo.lua new file mode 100644 index 000000000..49bec0571 --- /dev/null +++ b/mods/CORE/tga_encoder/logo.lua @@ -0,0 +1,51 @@ +dofile("init.lua") + +local colormap = { + { 0, 0, 0 }, -- black + { 255, 255, 255 }, -- white + { 255, 0, 0 }, -- red + { 0, 255, 0 }, -- green + { 0, 0, 255 }, -- blue +} + +local _ = { 0 } +local W = { 1 } +local R = { 2 } +local G = { 3 } +local B = { 4 } + +local pixels_tiny = { + { W, W, W, W, W, W, W, W, W, W, W, W, }, + { W, _, _, _, _, _, _, _, _, _, _, W, }, + { W, _, _, _, _, _, _, B, _, B, _, W, }, + { W, _, _, _, _, _, _, B, B, B, _, W, }, + { W, _, _, _, G, G, G, B, _, B, _, W, }, + { W, _, _, _, G, _, G, B, B, B, _, W, }, + { W, _, _, R, G, _, _, _, _, _, _, W, }, + { W, _, _, R, G, G, G, _, _, _, _, W, }, + { W, _, _, R, _, _, _, _, _, _, _, W, }, + { W, _, R, R, R, _, _, _, _, _, _, W, }, + { W, _, _, _, _, _, _, _, _, _, _, W, }, + { W, W, W, W, W, W, W, W, W, W, W, W, }, +} + +local pixels_huge = {} + +local size_tiny = #pixels_tiny +local size_huge = 1200 +local scale = size_huge / size_tiny + +for x_huge = 1,size_huge,1 do + local x_tiny = math.ceil( x_huge / scale ) + for z_huge = 1,size_huge,1 do + local z_tiny = math.ceil( z_huge / scale ) + if nil == pixels_huge[z_huge] then + pixels_huge[z_huge] = {} + end + pixels_huge[z_huge][x_huge] = pixels_tiny[z_tiny][x_tiny] + end +end + +tga_encoder.image(pixels_tiny):save("logo_tiny.tga", {colormap=colormap}) +tga_encoder.image(pixels_huge):save("logo_huge.tga", {colormap=colormap}) + diff --git a/mods/CORE/tga_encoder/mod.conf b/mods/CORE/tga_encoder/mod.conf index e4bfac898..d65aca884 100644 --- a/mods/CORE/tga_encoder/mod.conf +++ b/mods/CORE/tga_encoder/mod.conf @@ -1,3 +1,2 @@ name = tga_encoder -author = Fleckenstein description = A TGA Encoder written in Lua without the use of external Libraries. diff --git a/mods/CORE/tga_encoder/tools/generate_test_textures.lua b/mods/CORE/tga_encoder/tools/generate_test_textures.lua new file mode 100755 index 000000000..24e4b3278 --- /dev/null +++ b/mods/CORE/tga_encoder/tools/generate_test_textures.lua @@ -0,0 +1,180 @@ +#!/usr/bin/env lua5.1 +dofile("../init.lua") + +local _ = { 0 } +local R = { 1 } +local G = { 2 } +local B = { 3 } + +local pixels_colormapped_bt = { + { _, _, _, _, _, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, G, _, G, B, B, B, }, + { _, R, G, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { R, R, R, _, _, _, _, _, }, +} + +local pixels_colormapped_tb = { + { R, R, R, _, _, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, G, _, _, _, _, _, }, + { _, _, G, _, G, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, _, _, _, B, _, B, }, +} + +image_colormapped_bt = tga_encoder.image(pixels_colormapped_bt) +image_colormapped_tb = tga_encoder.image(pixels_colormapped_tb) + +colormap_32bpp = { + { 0, 0, 0, 128 }, + { 255, 0, 0, 255 }, + { 0, 255, 0, 255 }, + { 0, 0, 255, 255 }, +} +image_colormapped_bt:save( + "type1_32bpp_bt.tga", + { colormap = colormap_32bpp, color_format = "B8G8R8A8", scanline_order = "bottom-top" } +) +image_colormapped_tb:save( + "type1_32bpp_tb.tga", + { colormap = colormap_32bpp, color_format = "B8G8R8A8", scanline_order = "top-bottom" } +) +image_colormapped_bt:save( + "type1_16bpp_bt.tga", + { colormap = colormap_32bpp, color_format = "A1R5G5B5", scanline_order = "bottom-top" } +) +image_colormapped_tb:save( + "type1_16bpp_tb.tga", + { colormap = colormap_32bpp, color_format = "A1R5G5B5", scanline_order = "top-bottom" } +) + +colormap_24bpp = { + { 0, 0, 0 }, + { 255, 0, 0 }, + { 0, 255, 0 }, + { 0, 0, 255 }, +} +image_colormapped_bt:save( + "type1_24bpp_bt.tga", + { colormap = colormap_32bpp, color_format = "B8G8R8", scanline_order = "bottom-top" } +) +image_colormapped_tb:save( + "type1_24bpp_tb.tga", + { colormap = colormap_32bpp, color_format = "B8G8R8", scanline_order = "top-bottom" } +) + +local _ = { 0, 0, 0, 128 } +local R = { 255, 0, 0, 255 } +local G = { 0, 255, 0, 255 } +local B = { 0, 0, 255, 255 } + +local pixels_rgba_bt = { + { _, _, _, _, _, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, G, _, G, B, B, B, }, + { _, R, G, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { R, R, R, _, _, _, _, _, }, +} + +local pixels_rgba_tb = { + { R, R, R, _, _, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, G, _, _, _, _, _, }, + { _, _, G, _, G, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, _, _, _, B, _, B, }, +} + +image_rgba_bt = tga_encoder.image(pixels_rgba_bt) +image_rgba_tb = tga_encoder.image(pixels_rgba_tb) + +image_rgba_bt:save( + "type2_32bpp_bt.tga", + { color_format="B8G8R8A8", compression="RAW", scanline_order = "bottom-top" } +) +image_rgba_tb:save( + "type2_32bpp_tb.tga", + { color_format="B8G8R8A8", compression="RAW", scanline_order = "top-bottom" } +) +image_rgba_bt:save( + "type10_32bpp_bt.tga", + { color_format="B8G8R8A8", compression="RLE", scanline_order = "bottom-top" } +) +image_rgba_tb:save( + "type10_32bpp_tb.tga", + { color_format="B8G8R8A8", compression="RLE", scanline_order = "top-bottom" } +) + +local _ = { 0, 0, 0 } +local R = { 255, 0, 0 } +local G = { 0, 255, 0 } +local B = { 0, 0, 255 } + +local pixels_rgb_bt = { + { _, _, _, _, _, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, G, _, G, B, B, B, }, + { _, R, G, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { R, R, R, _, _, _, _, _, }, +} + +local pixels_rgb_tb = { + { R, R, R, _, _, _, _, _, }, + { _, R, _, _, _, _, _, _, }, + { _, R, G, G, G, _, _, _, }, + { _, R, G, _, _, _, _, _, }, + { _, _, G, _, G, B, B, B, }, + { _, _, G, G, G, B, _, B, }, + { _, _, _, _, _, B, B, B, }, + { _, _, _, _, _, B, _, B, }, +} + +image_rgb_bt = tga_encoder.image(pixels_rgb_bt) +image_rgb_tb = tga_encoder.image(pixels_rgb_tb) + +image_rgb_bt:save( + "type2_24bpp_bt.tga", + { color_format="B8G8R8", compression="RAW", scanline_order = "bottom-top" } +) +image_rgb_tb:save( + "type2_24bpp_tb.tga", + { color_format="B8G8R8", compression="RAW", scanline_order = "top-bottom" } +) +image_rgb_bt:save( + "type10_24bpp_bt.tga", + { color_format="B8G8R8", compression="RLE", scanline_order = "bottom-top" } +) +image_rgb_tb:save( + "type10_24bpp_tb.tga", + { color_format="B8G8R8", compression="RLE", scanline_order = "top-bottom" } +) +image_rgb_bt:save( + "type2_16bpp_bt.tga", + { color_format="A1R5G5B5", compression="RAW", scanline_order = "bottom-top" } +) +image_rgb_tb:save( + "type2_16bpp_tb.tga", + { color_format="A1R5G5B5", compression="RAW", scanline_order = "top-bottom" } +) +image_rgb_bt:save( + "type10_16bpp_bt.tga", + { color_format="A1R5G5B5", compression="RLE", scanline_order = "bottom-top" } +) +image_rgb_tb:save( + "type10_16bpp_tb.tga", + { color_format="A1R5G5B5", compression="RLE", scanline_order = "top-bottom" } +) diff --git a/mods/ENTITIES/mcl_boats/README.txt b/mods/ENTITIES/mcl_boats/README.txt index 0d56aa0e1..12b5d49f2 100644 --- a/mods/ENTITIES/mcl_boats/README.txt +++ b/mods/ENTITIES/mcl_boats/README.txt @@ -10,7 +10,7 @@ License of boat model: GNU GPLv3 ## Textures -See the main MineClone 2 README.md file to learn more. +See the main VoxeLibre README.md file to learn more. ## Code Code based on Minetest Game, licensed under the MIT License (MIT). diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index fabfae91c..fe7b4f7df 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -62,8 +62,13 @@ end local function set_double_attach(boat) boat._driver:set_attach(boat.object, "", {x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0}) - boat._passenger:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) + if boat._passenger:is_player() then + boat._passenger:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -6.2}, {x = 0, y = 0, z = 0}) + else + boat._passenger:set_attach(boat.object, "", + {x = 0, y = 0.42, z = -4.5}, {x = 0, y = 270, z = 0}) + end end local function set_choat_attach(boat) boat._driver:set_attach(boat.object, "", @@ -155,7 +160,7 @@ local boat = { minetest.register_on_respawnplayer(detach_object) function boat.on_rightclick(self, clicker) - if self._passenger or not clicker or clicker:get_attach() then + if self._passenger or not clicker or clicker:get_attach() or (self.name == "mcl_boats:chest_boat" and self._driver) then return end attach_object(self, clicker) @@ -163,7 +168,7 @@ end function boat.on_activate(self, staticdata, dtime_s) - self.object:set_armor_groups({fleshy = 100}) + self.object:set_armor_groups({fleshy = 125}) local data = minetest.deserialize(staticdata) if type(data) == "table" then self._v = data.v diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr index e1ecd9b01..2ea047154 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr @@ -12,6 +12,7 @@ Water vehicle=Véhicule aquatique Sneak to dismount=Se baisser pour descendre Obsidian Boat=Bateau en obsidienne Mangrove Boat=Bateau en palétuvier +Cherry Boat=Bateau en cerisier Oak Chest Boat=Bateau en chêne avec coffre Spruce Chest Boat=Bateau en sapin 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 Dark Oak Chest Boat=Bateau en chêne noir avec coffre Mangrove Chest Boat=Bateau en palétuvier avec coffre +Cherry Chest Boat=Bateau en cerisier avec coffre diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.oc.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.oc.tr new file mode 100644 index 000000000..7ee886712 --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.oc.tr @@ -0,0 +1,21 @@ +# textdomain: mcl_boats +Acacia Boat=Barca de Cacèir +Birch Boat=Barca de Beç +Boat=Barca +Boats are used to travel on the surface of water.=Las barcas son utilizadas per voiatja per aigas. +Dark Oak Boat=Barca de Ròure Nèir +Jungle Boat=Barca d'Acajó +Oak Boat=Barca de Ròure +Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Fasetz un clic dreit sobre una sorça d'aiga per plaça la barca. Fasetz un clic dreit sobre la barca per rintrar. Utilizatz [Gaucha] e [Dreita] per menar, [Davant] per accelerar e [Darrèir] per ralentir o racuolar. Utilizatz [Sneak] per z-o quitar, tustatz la barca per z-o faire tombar coma objècte. +Spruce Boat=Barca de Sap +Water vehicle=Veïcule per aiga +Sneak to dismount=Se baissar per descendre +Obsidian Boat=Barca d'Obsidiana +Mangrove Boat=Barca de Paletuvèir +Oak Chest Boat=Barca de Ròure embei una Mala +Spruce Chest Boat=Barca de Sap embei una Mala +Birch Chest Boat=Barca de Beç embei una Mala +Jungle Chest Boat=Barca d'Acajó embei una Mala +Acacia Chest Boat=Barca de Cacèir embei una Mala +Dark Oak Chest Boat=Barca de Ròure Nèir embei una Mala +Mangrove Chest Boat=Barca de Paletuvèir embei una Mala diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.pt_BR.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.pt_BR.tr new file mode 100644 index 000000000..65a5c3a54 --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.pt_BR.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_boats +Acacia Boat=Barco de Acácia +Birch Boat=Barco de Bétula +Boat=Barco +Boats are used to travel on the surface of water.=Barcos são usados para viajar na superfície da água +Dark Oak Boat=Barco de Carvalho Escuro +Jungle Boat=Barco de Selva +Oak Boat=Barco de Carvalho +Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Clique com o botão direito em uma fonte de água para posicionar o barco. Clique com o botão direito no barco para entrar nele. Use [Esquerda] e [Direita] para fazer curva, [Frente] para acelerar e [Trás] para frear e ir para trás. Use [Agachar] para deixar o barco, soque-o para fazê-lo dropar como um item. +Spruce Boat=Barco de Pinheiro +Water vehicle=Veículo aquático +Sneak to dismount=Agache para desmontar +Obsidian Boat=Barco de Obsidiana +Mangrove Boat=Barco de Mangue +Cherry Boat=Barco de Cerejeira +Oak Chest Boat=Barco de Carvalho com Baú +Spruce Chest Boat=Barco de Pinheiro com Baú +Birch Chest Boat=Barco de Bétula com Baú +Jungle Chest Boat=Barco de Selva com Baú +Acacia Chest Boat=Barco de Acácia com Baú +Dark Oak Chest Boat=Barco de Carvalho Escuro com Baú +Mangrove Chest Boat=Barco de Mangue com Baú +Cherry Chest Boat=Barco de Cerejeira com Baú diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.ru.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ru.tr index 5bd6e4c4d..d1e966976 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.ru.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ru.tr @@ -1,11 +1,23 @@ # textdomain: mcl_boats -Acacia Boat=Лодка из акации +Acacia Boat=Акациевая лодка Birch Boat=Берёзовая лодка Boat=Лодка -Boats are used to travel on the surface of water.=С помощью лодки можно путешествовать по водной поверхности. +Boats are used to travel on the surface of water.=На лодке можно плыть по водной поверхности. Dark Oak Boat=Лодка из тёмного дуба -Jungle Boat=Лодка из дерева джунглей +Jungle Boat=Лодка из тропического дерева Oak Boat=Дубовая лодка -Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Правый клик по воде спустит лодку на воду. Правый клик по лодке разместит вас в ней. [Влево] и [Вправо] - рулить, [Вперед] - разгоняться, [Назад] - тормозить или плыть назад. Правый клик по лодке, когда вы в ней, позволит выйти из неё. Удар по лодке превратит её обратно в предмет. +Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Правый клик на воде, чтобы установить лодку. Правый клик по лодке, чтобы сесть в нее. [Влево] и [Вправо] - рулить, [Вперед] - разгоняться, [Назад] - тормозить или плыть назад. Нажмите [Красться] для высадки, бейте по лодке, чтобы забрать её. Spruce Boat=Еловая лодка Water vehicle=Водный транспорт +Sneak to dismount=Нажмите [Красться] для высадки +Obsidian Boat=Обсидиановая лодка +Mangrove Boat=Мангровая лодка +Cherry Boat=Вишнёвая лодка +Oak Chest Boat=Дубовая лодка с сундуком +Spruce Chest Boat=Еловая лодка с сундуком +Birch Chest Boat=Берёзовая лодка с сундуком +Jungle Chest Boat=Лодка из тропического дерева с сундуком +Acacia Chest Boat=Акациевая лодка с сундуком +Dark Oak Chest Boat=Лодка из тёмного дуба с сундуком +Mangrove Chest Boat=Мангровая лодка с сундуком +Cherry Chest Boat=Вишнёвая лодка с сундуком \ No newline at end of file diff --git a/mods/ENTITIES/mcl_burning/mod.conf b/mods/ENTITIES/mcl_burning/mod.conf index 651698fc7..8a3d6ea00 100644 --- a/mods/ENTITIES/mcl_burning/mod.conf +++ b/mods/ENTITIES/mcl_burning/mod.conf @@ -1,4 +1,4 @@ name = mcl_burning -description = Burning Objects for MineClone2 +description = Burning Objects for VoxeLibre author = Fleckenstein -depends = mcl_weather \ No newline at end of file +depends = mcl_weather diff --git a/mods/ENTITIES/mcl_dripping/README.md b/mods/ENTITIES/mcl_dripping/README.md index d6ff75ff1..37658292c 100644 --- a/mods/ENTITIES/mcl_dripping/README.md +++ b/mods/ENTITIES/mcl_dripping/README.md @@ -1,36 +1,36 @@ -# mcl_dripping - -Dripping Mod by kddekadenz, modified for MineClone 2 by Wuzzy, NO11 and AFCM - -## Manual - -- drops are generated rarely under solid nodes -- they will stay some time at the generated block and than they fall down -- when they collide with the ground, a sound is played and they are destroyed - -Water and Lava have builtin drops registered. - -## License - -code & sounds: CC0 - -## API - -```lua -mcl_dripping.register_drop({ - -- The group the liquid's nodes belong to - liquid = "water", - -- The texture used (particles will take a random 2x2 area of it) - texture = "default_water_source_animated.png", - -- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` - light = 1, - -- The nodes (or node group) the particles will spawn under - nodes = { "group:opaque", "group:leaves" }, - -- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt - sound = "drippingwater_drip", - -- The interval for the ABM to run - interval = 60, - -- The chance of the ABM - chance = 10, -}) -``` +# mcl_dripping + +Dripping Mod by kddekadenz, modified for VoxeLibre by Wuzzy, NO11 and AFCM + +## Manual + +- drops are generated rarely under solid nodes +- they will stay some time at the generated block and than they fall down +- when they collide with the ground, a sound is played and they are destroyed + +Water and Lava have builtin drops registered. + +## License + +code & sounds: CC0 + +## API + +```lua +mcl_dripping.register_drop({ + -- The group the liquid's nodes belong to + liquid = "water", + -- The texture used (particles will take a random 2x2 area of it) + texture = "mcl_core_water_source_animation.png", + -- Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` + light = 1, + -- The nodes (or node group) the particles will spawn under + nodes = { "group:opaque", "group:leaves" }, + -- The sound that will be played then the particle detaches from the roof, see SimpleSoundSpec in lua_api.txt + sound = "drippingwater_drip", + -- The interval for the ABM to run + interval = 60, + -- The chance of the ABM + chance = 10, +}) +``` diff --git a/mods/ENTITIES/mcl_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua index b5a5043b7..5a96e65c4 100644 --- a/mods/ENTITIES/mcl_dripping/init.lua +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -82,7 +82,7 @@ end mcl_dripping.register_drop({ liquid = "water", - texture = "default_water_source_animated.png", + texture = "mcl_core_water_source_animation.png", light = 1, nodes = { "group:opaque", "group:leaves" }, sound = "drippingwater_drip", @@ -92,7 +92,7 @@ mcl_dripping.register_drop({ mcl_dripping.register_drop({ liquid = "lava", - texture = "default_lava_source_animated.png", + texture = "mcl_core_lava_source_animation.png", light = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), nodes = { "group:opaque" }, sound = "drippingwater_lavadrip", diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.oc.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.oc.tr new file mode 100644 index 000000000..0d6da5d05 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.oc.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_falling_nodes +@1 was smashed by a falling anvil.=@1 a estat espotit per un enclutge +@1 was smashed by a falling block.=@1 a estat espotit per un blòc diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pt_BR.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pt_BR.tr new file mode 100644 index 000000000..aaa378ba3 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_falling_nodes +@1 was smashed by a falling anvil.=@1 foi esmagado(a) por uma bigorna em queda. +@1 was smashed by a falling block.=@1 foi esmagado(a) por um bloco em queda. diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.ru.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.ru.tr new file mode 100644 index 000000000..6c4081b50 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_falling_nodes +@1 was smashed by a falling anvil.=@1 был(а) раздавлен(а) падающей наковальней. +@1 was smashed by a falling block.=@1 был(а) раздавлен(а) падающим блоком. diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 149b5ed93..2cb506450 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -6,9 +6,6 @@ local pool = {} local tick = false - - - minetest.register_on_joinplayer(function(player) pool[player:get_player_name()] = 0 end) @@ -113,6 +110,56 @@ local function disable_physics(object, luaentity, ignore_check, reset_movement) end end +local function try_object_pickup(player, inv, object, checkpos) + if not inv then return end + + local le = object:get_luaentity() + + -- Check magnet timer + if not (le._magnet_timer >= 0) then return end + if not (le._magnet_timer < item_drop_settings.magnet_time) then return end + + -- Don't try to collect again + if le._removed then return end + + -- Ignore if itemstring is not set yet + if le.itemstring == "" then return end + + -- Add what we can to the inventory + local itemstack = ItemStack(le.itemstring) + tt.reload_itemstack_description(itemstack) + local leftovers = inv:add_item("main", itemstack ) + + check_pickup_achievements(object, player) + + if leftovers:is_empty() then + -- Destroy entity + -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. + le.target = checkpos + le._removed = true + + -- Stop the object + object:set_velocity(vector.zero()) + object:set_acceleration(vector.zero()) + object:move_to(checkpos) + + -- Update sound pool + local name = player:get_player_name() + pool[name] = ( pool[name] or 0 ) + 1 + + -- Make sure the object gets removed + minetest.after(0.25, function() + --safety check + if object and object:get_luaentity() then + object:remove() + end + end) + else + -- Update entity itemstring + le.itemstring = leftovers:to_string() + end +end + minetest.register_globalstep(function(_) tick = not tick @@ -123,17 +170,17 @@ minetest.register_globalstep(function(_) local pos = player:get_pos() - if tick == true and pool[name] > 0 then + if tick == true and (pool[name] or 0) > 0 then minetest.sound_play("item_drop_pickup", { pos = pos, gain = 0.3, max_hear_distance = 16, pitch = math.random(70, 110) / 100 }) - if pool[name] > 6 then + if (pool[name] or 0) > 6 then pool[name] = 6 else - pool[name] = pool[name] - 1 + pool[name] = (pool[name] or 1) - 1 end end @@ -147,40 +194,7 @@ minetest.register_globalstep(function(_) object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then - if object:get_luaentity()._magnet_timer >= 0 and - object:get_luaentity()._magnet_timer < item_drop_settings.magnet_time and inv and - inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - - -- Collection - if not object:get_luaentity()._removed then - -- Ignore if itemstring is not set yet - if object:get_luaentity().itemstring ~= "" then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - - check_pickup_achievements(object, player) - - -- Destroy entity - -- This just prevents this section to be run again because object:remove() doesn't remove the item immediately. - object:get_luaentity().target = checkpos - object:get_luaentity()._removed = true - - object:set_velocity(vector.zero()) - object:set_acceleration(vector.zero()) - - object:move_to(checkpos) - - pool[name] = pool[name] + 1 - - minetest.after(0.25, function() - --safety check - if object and object:get_luaentity() then - object:remove() - end - end) - end - end - end - + try_object_pickup( player, inv, object, checkpos ) elseif not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mcl_experience:orb" then local entity = object:get_luaentity() entity.collector = player:get_player_name() @@ -362,6 +376,122 @@ function minetest.handle_node_drops(pos, drops, digger) 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 + tt.reload_itemstack_description(wielded) -- update tooltip + 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 function minetest.item_drop(itemstack, dropper, pos) if dropper and dropper:is_player() then diff --git a/mods/ENTITIES/mcl_minecarts/functions.lua b/mods/ENTITIES/mcl_minecarts/functions.lua index 2f0dfe0ae..1792e9252 100644 --- a/mods/ENTITIES/mcl_minecarts/functions.lua +++ b/mods/ENTITIES/mcl_minecarts/functions.lua @@ -134,4 +134,34 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) end end return {x=0, y=0, z=0} -end \ No newline at end of file +end + +local plane_adjacents = { + vector.new(-1,0,0), + vector.new(1,0,0), + vector.new(0,0,-1), + vector.new(0,0,1), +} + +function mcl_minecarts:get_start_direction(pos) + local dir + local i = 0 + while (not dir and i < #plane_adjacents) do + i = i+1 + local node = minetest.get_node_or_nil(vector.add(pos, plane_adjacents[i])) + if node ~= nil + and minetest.get_item_group(node.name, "rail") == 0 + and minetest.get_item_group(node.name, "solid") == 1 + and minetest.get_item_group(node.name, "opaque") == 1 + then + dir = mcl_minecarts:check_front_up_down(pos, vector.multiply(plane_adjacents[i], -1), true) + end + end + return dir +end + +function mcl_minecarts:set_velocity(obj, dir, factor) + obj._velocity = vector.multiply(dir, factor or 3) + obj._old_pos = nil + obj._punched = true +end diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index b87175494..89ae44349 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -241,9 +241,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o if vector.equals(cart_dir, {x=0, y=0, z=0}) then return end - self._velocity = vector.multiply(cart_dir, 3) - self._old_pos = nil - self._punched = true + mcl_minecarts:set_velocity(self, cart_dir) return end @@ -300,9 +298,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval) local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval) - self._velocity = vector.multiply(cart_dir, f) - self._old_pos = nil - self._punched = true + mcl_minecarts:set_velocity(self, cart_dir, f) end cart.on_activate_by_rail = on_activate_by_rail @@ -470,7 +466,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o return end - local dir, last_switch = nil, nil + local dir, last_switch, restart_pos = nil, nil, nil if not pos then pos = self.object:get_pos() end @@ -497,6 +493,9 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o minetest.swap_node(rou_pos, newnode) mesecon.receptor_on(rou_pos) end + if node.name == "mcl_minecarts:golden_rail_on" then + restart_pos = rou_pos + end if node_old.name == "mcl_minecarts:detector_rail_on" then local newnode = {name="mcl_minecarts:detector_rail", param2 = node_old.param2} minetest.swap_node(rou_old, newnode) @@ -647,6 +646,14 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o if update.pos then self.object:set_pos(pos) end + + -- stopped on "mcl_minecarts:golden_rail_on" + if vector.equals(vel, {x=0, y=0, z=0}) and restart_pos then + local dir = mcl_minecarts:get_start_direction(restart_pos) + if dir then + mcl_minecarts:set_velocity(self, dir) + end + end end function cart:get_staticdata() @@ -687,7 +694,15 @@ function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer) if le then le._railtype = railtype end - local cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype) + local cart_dir + if node.name == "mcl_minecarts:golden_rail_on" then + cart_dir = mcl_minecarts:get_start_direction(railpos) + end + if cart_dir then + mcl_minecarts:set_velocity(le, cart_dir) + else + cart_dir = mcl_minecarts:get_rail_direction(railpos, {x=1, y=0, z=0}, nil, nil, railtype) + end cart:set_yaw(minetest.dir_to_yaw(cart_dir)) local pname = "" diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.oc.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.oc.tr new file mode 100644 index 000000000..5b8cfb7a9 --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.oc.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_minecarts +Minecart=Vagonet +Minecarts can be used for a quick transportion on rails.=Los vagonet pòdon èsser utilizats per un transpòrt rapide per ralhs. +Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Los vagonets ròtlon mas per ralhs e seguisson totjorn la pista. A una joncion T embei ren davant, tòrnon a gaucha. +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Podètz plaçar le vagonet per ralhs. Fasetz un clic dreit dessobre per çai rentrar. Tustatz z-o per z-o faire bojar. +To obtain the minecart, punch it while holding down the sneak key.=Per aver le vagonet, tustatz z-o embei la tocha sneak enfonçada. +A minecart with TNT is an explosive vehicle that travels on rail.=Un vagonet embei TNT z-es un vagonet explosiu que voiatja per ralhs. +Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Plaçatz z-o per ralhs. Tustatz z-o per z-o desplaçar. La TNT z-es atubada embei un batifuòc o quand le vagonet z-es per un ralh d'activacion atubat. +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Per obtenèr le vagonet e la TNT, tustatz z-o embei la tocha sneak enfonçada. Podètz pas faire quo si la TNT z-es atubada. +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Un vagonet embei un fornil z-es un veïcule que voiatja per ralhs. Pòt se propulsar embei dau carburant. +Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Plaçatz z-o per ralhs. Si li balhatz dau charbon, le fornil vai començar de borlar lòngtemps e porà rotlar. Tustatz z-o per z-o faire bojar. +To obtain the minecart and furnace, punch them while holding down the sneak key.=Per obtener le vagonet e le fornil, tustatz z-o embei la tocha sneak enfonçada. +Minecart with Chest=Vagonet embei una Mala +Minecart with Furnace=Vagonet embei un Fornil +Minecart with Command Block=Vagonet embei un Blòc de Comandas +Minecart with Hopper=Vagonet embei un Embure +Minecart with TNT=Vagonet embei de la TNT +Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Plaçatz z-o per sòu per construrre vostre chamin de fèrre, los ralhs se conectaron entre ilhs e faron de las corbas, de las junccions en T, en traversadas et en pentas au besonh. +Rail=Ralh +Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Los ralhs pòdon èsser utilizats per construrre los chamins de transpòrt per los vagonets. Los ralhs normaus ralentissons gentament los vagonet per causa de friccion. +Powered Rail=Ralh Atubat +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Los ralhs pòdon èsser utilizats per construrre los chamins de transpòrt per los vagonets. Los ralhs atubats son per faire accelerar o frenar los vagonets. +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Sens energia de pèirotge, le ralh vai frenar los vagonets. Per que le ralh accelera los vagonets, alimentatz z-o embei de l'energia de pèirotge. +Activator Rail=Ralh d'Activacion +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Los ralhs pòdon èsser utilizats per construrre los chamins de transpòrt per los vagonets. Los ralhs d'activacion son utilizats per activar daus vagonets speciaus. +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Per activar le ralh, alimentatz z-o embei de l'energia de pèirotge e fasetz rotlar un vagonet per aqueste ralh. +Detector Rail=Ralh de Deteccion +Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Los ralhs pòdon èsser utilizats per construirre los chamins de transpòrt per los vagonets. Los ralhs de deteccion pòdon detectar un vagonet per ilhs e atubar un mecanisme de pèirotge. +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Per detectar un vagonet e produrre de l'energia de pèirotge, conectatz le ralh a de la pèirotge e fasetz rotlar un vagonet per i-aul. +Track for minecarts=Pista per vagonets +Speed up when powered, slow down when not powered=Acceleratz quand z-es atubat, ralentissetz quand z-es pas atubat. +Activates minecarts when powered=Activa los vagonets quand pas atubat. +Emits redstone power when a minecart is detected=Emeta de l'energia de pèirotge quand un vagonet z-es detectat. +Vehicle for fast travel on rails=Veicule per voiatjar vistament per ralhs. +Can be ignited by tools or powered activator rail=Pòt èsser atubat embei daus otilhs o un ralh d'activacion +Sneak to dismount=Se baissar per descendre diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pt_BR.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pt_BR.tr new file mode 100644 index 000000000..dda35e93f --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pt_BR.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_minecarts +Minecart=Carrinho +Minecarts can be used for a quick transportion on rails.=Carrinhos podem ser usados para transporte rápido em trilhos. +Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Carrinhos viajam somente em trilhos e sempre seguem os traçados. Em uma junção em T sem linha reta à frente, eles viram à esquerda. A velocidade é afetada pelo tipo do trilho. +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Você pode posicionar o carrinho em trilhos. Clique com o botão direito para entrar nele. Soque-o para fazê-lo mover. +To obtain the minecart, punch it while holding down the sneak key.=Para obter o carrinho, soque-o enquanto segura pressionada a tecla de agachar. +A minecart with TNT is an explosive vehicle that travels on rail.=Um carrinho com TNT é um veículo explosivo que viaja nos trilhos. +Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Posicione-o nos trilhos. Soque-o para movê-lo. A TNT é acesa com um isqueiro ou quando o carrinho está sobre um trilho ativador energizado. +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Para obter o carrinho e a TNT, soque-os enquanto segura pressionada a tecla de agachar. Você não consegue fazer isso se a TNT foi acesa. +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Um carrinho com fornalha é um veículo que viaja nos trilhos. Se move por conta própria com combustível. +Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Posicione-o nos trilhos. Se você o der um pouco de carvão, a fornalha vai começar a queimar por um longo tempo e o carrinho será capaz de se mover por conta própria. Soque-o para fazê-lo mover. +To obtain the minecart and furnace, punch them while holding down the sneak key.=Para obter o carrinho e a fornalha, soque-os enquanto segura pressionada a tecla de agachar. +Minecart with Chest=Carrinho com Baú +Minecart with Furnace=Carrinho com Fornalha +Minecart with Command Block=Carrinho com Bloco de Comandos +Minecart with Hopper=Carrinho com Funil +Minecart with TNT=Carrinho com TNT +Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Posicione-os no chão para construir suas linhas férreas, os trilhos vão conectar-se automaticamente uns nos outros e vão se transformar em curvas, junções em T, cruzamentos e rampas quando necessário. +Rail=Trilho +Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Trilhos podem ser usados para construir traçados de transporte para carrinhos. Trilhos normais freiam carrinhos gradativamente devido ao atrito. +Powered Rail=Trilho Energizador +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Trilhos podem ser usados para construir traçados de transporte para carrinhos. Trilhos energizados são capazes de acelerar e frear carrinhos. +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Sem carga de redstone, o trilho vai frear os carrinhos. Para fazer o trilho acelerar os carrinhos, energize-o com uma carga de redstone. +Activator Rail=Trilho Ativador +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Trilhos podem ser usados para construir traçados de transporte para carrinhos. Trilhos ativadores são usados para ativar carrinhos especiais. +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Para fazer esse trilho ativar os carrinhos, energize-o com uma carga de redstone e envie um carrinho sobre esse pedaço de trilho. +Detector Rail=Trilho Detector +Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Trilhos podem ser usados para construir traçados de transporte para carrinhos. Um trilho detector é capaz de detectar um carrinho sobre ele e energizar mecanismos de redstone. +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Para detectar um carrinho e providenciar carga de redstone, conecte-o em trilhas de redstone ou mecanismos de redstone e envie qualquer carrinho sobre esse trilho. +Track for minecarts=Traçado para carrinhos +Speed up when powered, slow down when not powered=Acelera quando energizado, desacelera quando não energizado +Activates minecarts when powered=Ativa carrinhos quando energizado +Emits redstone power when a minecart is detected=Emite carga de redstone quando um carrinho é detectado +Vehicle for fast travel on rails=Veículo para viajar rápido em trilhos +Can be ignited by tools or powered activator rail=Pode ser aceso por ferramentas ou trilho ativador energizado +Sneak to dismount=Agache para desmontar diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr index 6189bac84..89760a0c4 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr @@ -1,36 +1,36 @@ # textdomain: mcl_minecarts Minecart=Вагонетка -Minecarts can be used for a quick transportion on rails.=Вагонетки нужны, чтобы быстро перемещаться по рельсам. -Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Вагонетки едут строго по проложенному железнодорожному пути. На Т-образной развилке они поворачивают налево. Скорость зависит от типа рельсов. -You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Вы ставите вагонетку на рельсы. Правым кликом садитесь в неё. Стукаете, чтобы начать движение. -To obtain the minecart, punch it while holding down the sneak key.=Чтобы взять вагонетку, стукните её, удерживая клавишу [Красться]. -A minecart with TNT is an explosive vehicle that travels on rail.=Вагон тротила это подрывной железнодорожный транспорт. -Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Поместите его на рельсы. Стукните, чтобы он поехал. Тротил воспламеняется, если его поджечь огнивом, либо при попадании на подключенный рельсовый активатор. -To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Чтобы взять вагон тротила, стукните его, удерживая клавишу [Красться]. Если тротил воспламенён, сделать это нельзя. -A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Вагон с печью - это железнодорожный транспорт. Он может двигаться за счёт топлива. -Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Поставьте его на рельсы. Если добавить немного угля, то печь зажжётся на продолжительное время и вагон сможет ехать. Стукните вагон для начала движения. -To obtain the minecart and furnace, punch them while holding down the sneak key.=Чтобы взять вагон с печью, стукните его, удерживая клавишу [Красться]. -Minecart with Chest=Вагон с сундуком -Minecart with Furnace=Вагон с печью -Minecart with Command Block=Вагон с командным блоком -Minecart with Hopper=Вагон с бункером -Minecart with TNT=Вагон тротила -Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Поместите на землю, чтобы сделать железную дорогу, рельсы автоматически соединятся между собой и будут превращаться в плавный повороты, T-образные развилки, перекрёстки и уклоны там, где это потребуется. +Minecarts can be used for a quick transportion on rails.=Вагонетка может быть использована для быстрого перемещения по рельсам. +Minecarts only ride on rails and always follow the tracks. At a T-junction with no straight way ahead, they turn left. The speed is affected by the rail type.=Вагонетки едут только по проложенным рельсам. На Т-образной развилке они поворачивают налево. Скорость зависит от типа рельсов. +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Вы можете поставить вагонетку на рельсы. Правым кликом сядьте в неё. Ударьте по ней, чтобы она поехала. +To obtain the minecart, punch it while holding down the sneak key.=Чтобы забрать вагонетку, ударьте по ней, удерживая клавишу [Красться]. +A minecart with TNT is an explosive vehicle that travels on rail.=Вагонетка с ТНТ это взрывающийся железнодорожный транспорт. +Place it on rails. Punch it to move it. The TNT is ignited with a flint and steel or when the minecart is on an powered activator rail.=Поместите вагонетку на рельсы. Ударьте по ней, чтобы она поехала. ТНТ активируется, если его поджечь огнивом или когда вагонетка проедет через подключенные активирующие рельсы. +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Чтобы забрать вагонетку с ТНТ, ударьте по ней, удерживая клавишу [Красться]. Если ТНТ подожжён, сделать это нельзя. +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Вагонетка с печью это железнодорожный транспорт. Она может ехать сама за счёт топлива. +Place it on rails. If you give it some coal, the furnace will start burning for a long time and the minecart will be able to move itself. Punch it to get it moving.=Поставьте вагонетку на рельсы. Если добавить в неё угля, то печь будет гореть продолжительное время и вагонетка сможет поехать сама. Ударьте по ней, чтобы она поехала. +To obtain the minecart and furnace, punch them while holding down the sneak key.=Чтобы забрать вагонетку с печью, ударьте по ней, удерживая клавишу [Красться]. +Minecart with Chest=Вагонетка с сундуком +Minecart with Furnace=Вагонетка с печью +Minecart with Command Block=Вагонетка с командным блоком +Minecart with Hopper=Вагонетка с воронкой +Minecart with TNT=Вагонетка с ТНТ +Place them on the ground to build your railway, the rails will automatically connect to each other and will turn into curves, T-junctions, crossings and slopes as needed.=Поместите рельсы на землю, чтобы сделать железную дорогу, рельсы автоматически соединятся между собой и будут образовывать повороты, T-образные развилки, перекрёстки и склоны там, где это потребуется. Rail=Рельсы Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Рельсы используются для строительства железной дороги. Обычные рельсы немного замедляют движение вагонеток из-за трения. -Powered Rail=Подключаемые рельсы -Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Рельсы используются для строительства железной дороги. Подключённые рельсы могут разгонять и тормозить вагонетки. -Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Без энергии редстоуна рельсы будут тормозить вагонетки. -Activator Rail=Рельсовый активатор -Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Рельсы используются для строительства железной дороги. Рельсовый активатор активирует особые вагонетки. -To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Чтобы этот блок рельсов активировал вагонетку, подключите его к энергии редстоуна и направьте вагонетку через него. -Detector Rail=Рельсовый детектор -Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Рельсы используются для строительства железной дороги. Рельсовый детектор может обнаруживать вагонетку у себя наверху и подключать механизмы редстоуна. -To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Чтобы обнаруживать вагонетку и подавать энергию редстоуна, подключите его к дорожке редстоуна или механизму редстоуна, после чего направьте любую вагонетку через него. +Powered Rail=Энергорельсы +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Энергорельсы используются для строительства железной дороги. Энергорельсы могут ускорять и тормозить вагонетки. +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Неподключенные энергорельсы замедляют вагонетки. Чтобы энергорельсы ускоряли вагонетки, проведите к ним сигнал редстоуна. +Activator Rail=Активирующие рельсы +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Активирующие рельсы используются для строительства железной дороги. Активирующие рельсы активируют некоторые особые вагонетки. +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Чтобы эти рельсы активировали вагонетки, подключите активирующие рельсы к сигналу редстоуна и направьте вагонетку через них. +Detector Rail=Нажимные рельсы +Rails can be used to build transport tracks for minecarts. A detector rail is able to detect a minecart above it and powers redstone mechanisms.=Нажимные рельсы используются для строительства железной дороги. Нажимные рельсы реагируют на проезжающие по ним вагонетки и выдают сигнал для механизмов из редстоуна. +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Подсоедините к нажимным рельсам редстоун или редстоуновые механизмы, чтобы активировать их когда по рельсам проезжает вагонетка. Track for minecarts=Железная дорога -Speed up when powered, slow down when not powered=Разгоняет, если подключён, тормозит, если не подключён -Activates minecarts when powered=Активирует особые вагонетки, если подключён -Emits redstone power when a minecart is detected=Испускает энергию редстоуна при обнаружении вагонетки -Vehicle for fast travel on rails=Быстрый железнодорожный транспорт -Can be ignited by tools or powered activator rail=Можно воспламенить с помощью инструмента или подключенного рельсового активатора +Speed up when powered, slow down when not powered=Если подключены - ускоряют, если нет - тормозят +Activates minecarts when powered=Активирует особые вагонетки, если подключены +Emits redstone power when a minecart is detected=Подает сигнал редстоуна при обнаружении вагонетки +Vehicle for fast travel on rails=Железнодорожный транспорт +Can be ignited by tools or powered activator rail=Можно поджечь инструментом или активирующими рельсами Sneak to dismount=Нажмите [Красться] для высадки diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index 9c9050341..17c854e68 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -112,6 +112,22 @@ register_rail("mcl_minecarts:golden_rail_on", onstate = "mcl_minecarts:golden_rail_on", rules = rail_rules_long, }, + effector = { + action_on = function(pos, node) + local dir = mcl_minecarts:get_start_direction(pos) + if not dir then return end + local objs = minetest.get_objects_inside_radius(pos, 1) + for _, o in pairs(objs) do + local l = o:get_luaentity() + local v = o:get_velocity() + if l and string.sub(l.name, 1, 14) == "mcl_minecarts:" + and v and vector.equals(v, vector.zero()) + then + mcl_minecarts:set_velocity(l, dir) + end + end +end, + }, }, drop = "mcl_minecarts:golden_rail", }, diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index a9a1a0dad..1e49e8b4f 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -1,7 +1,7 @@ local mob_class = mcl_mobs.mob_class local mob_class_meta = {__index = mcl_mobs.mob_class} local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs --- API for Mobs Redo: MineClone 2 Edition (MRM) +-- API for Mobs Redo: VoxeLibre Edition local PATHFINDING = "gowp" local CRASH_WARN_FREQUENCY = 60 @@ -96,15 +96,23 @@ function mob_class:get_staticdata() local tmp = {} - for _,stat in pairs(self) do + for tag, stat in pairs(self) do local t = type(stat) if t ~= "function" and t ~= "nil" and t ~= "userdata" - and _ ~= "_cmi_components" then - tmp[_] = self[_] + and tag ~= "_cmi_components" then + tmp[tag] = self[tag] + end + end + + tmp._mcl_potions = self._mcl_potions + if tmp._mcl_potions then + for name_raw, data in pairs(tmp._mcl_potions) do + local def = mcl_potions.registered_effects[name_raw:match("^_EF_(.+)$")] + if def and def.on_save_effect then def.on_save_effect(self.object) end end end @@ -142,6 +150,11 @@ function mob_class:mob_activate(staticdata, def, dtime) local tmp = minetest.deserialize(staticdata) if tmp then + -- Patch incorrectly converted mobs + if tmp.base_mesh ~= minetest.registered_entities[self.name].mesh then + mcl_mobs.strip_staticdata(tmp) + end + for _,stat in pairs(tmp) do self[_] = stat end @@ -306,7 +319,10 @@ function mob_class:mob_activate(staticdata, def, dtime) self._run_armor_init = true end - + if not self._mcl_potions then + self._mcl_potions = {} + end + mcl_potions._load_entity_effects(self) if def.after_activate then @@ -473,7 +489,7 @@ local function warn_user_error () if time_since_warning > CRASH_WARN_FREQUENCY then last_crash_warn_time = current_time - minetest.log("A game crashing bug was prevented. Please provide debug.log information to MineClone2 dev team for investigation. (Search for: --- Bug report start)") + minetest.log("A game crashing bug was prevented. Please provide debug.log information to VoxeLibre dev team for investigation. (Search for: --- Bug report start)") end end diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index fe0da4be2..29cdc2c48 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -1,5 +1,5 @@ -Mobs Redo: MineClone 2 Edition +Mobs Redo: VoxeLibre Edition API documentation ============================== @@ -231,7 +231,7 @@ functions needed for the mob to work properly which contains the following: - MineClone 2 extensions: + VoxeLibre extensions: 'spawn_class' Classification of mod for the spawning algorithm: "hostile", "passive", "ambient" or "water" @@ -434,7 +434,7 @@ true the mob will not spawn. 'name' is the name of the animal/monster -MineClone 2 extensions +VoxeLibre extensions ---------------------- mcl_mobs:spawn_child(pos, mob_type) @@ -524,7 +524,7 @@ Does nothing and returns false. This function is provided for compability with Mobs Redo for an attempt to capture a mob. -Mobs cannot be captured in MineClone 2. +Mobs cannot be captured in VoxeLibre. In Mobs Redo, this is generally called inside the on_rightclick section of the mob api code, it provides a chance of capturing the mob. See Mobs Redo documentation @@ -671,6 +671,13 @@ mob will spawn e.g. mobs_animal:sheep_chance 11000 mobs_monster:sand_monster_chance 100 +Registering Mob Conversion +---------------- + +Sometimes you need to completely replace one mob with a different version. To do this, use: + + mcl_mobs.register_conversion(old_name, new_name) + Rideable Horse Example Mob -------------------------- diff --git a/mods/ENTITIES/mcl_mobs/breeding.lua b/mods/ENTITIES/mcl_mobs/breeding.lua index c6d8f92cd..90e625db8 100644 --- a/mods/ENTITIES/mcl_mobs/breeding.lua +++ b/mods/ENTITIES/mcl_mobs/breeding.lua @@ -32,6 +32,9 @@ function mob_class:feed_tame(clicker, feed_count, breed, tame, notake) if not self.follow then return false end + if clicker:get_wielded_item():get_definition()._mcl_not_consumable then + return false + end -- can eat/tame with item in hand if self.nofollow or self:follow_holding(clicker) then local consume_food = false @@ -75,6 +78,7 @@ function mob_class:feed_tame(clicker, feed_count, breed, tame, notake) self.food = 0 self.horny = true self.persistent = true + self._luck = mcl_luck.get_luck(clicker:get_player_name()) end end @@ -270,7 +274,7 @@ function mob_class:check_breeding() return end - mcl_experience.throw_xp(pos, math.random(1, 7)) + mcl_experience.throw_xp(pos, math.random(1, 7) + (parent1._luck or 0) + (parent2._luck or 0)) -- custom breed function if parent1.on_breed then @@ -319,7 +323,7 @@ function mob_class:toggle_sit(clicker,p) particle = "mobs_mc_wolf_icon_roam.png" self.order = "roam" self.state = "stand" - self.walk_chance = default_walk_chance + self.walk_chance = 50 self.jump = true self:set_animation("stand") -- TODO: Add sitting model diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua index 836f53753..608209ee2 100644 --- a/mods/ENTITIES/mcl_mobs/combat.lua +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -33,14 +33,19 @@ function mob_class:day_docile() end end --- attack player/mob -function mob_class:do_attack(player) +-- get this mob to attack the object +function mob_class:do_attack(object) if self.state == "attack" or self.state == "die" then return end - self.attack = player + + if object:is_player() and not minetest.settings:get_bool("enable_damage") then + return + end + + self.attack = object self.state = "attack" -- TODO: Implement war_cry sound without being annoying @@ -382,7 +387,8 @@ function mob_class:monster_attack() -- find specific mob to attack, failing that attack player/npc/animal if specific_attack(self.specific_attack, name) and (type == "player" or ( type == "npc" and self.attack_npcs ) - or (type == "animal" and self.attack_animals == true)) then + or (type == "animal" and self.attack_animals == true) + or (self.extra_hostile and not self.attack_exception(player))) then p = player:get_pos() sp = s @@ -513,6 +519,30 @@ end -- deal damage and effects when mob punched function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) + local is_player = hitter:is_player() + local mob_pos = self.object:get_pos() + local player_pos = hitter:get_pos() + + if is_player then + -- is mob out of reach? + if vector.distance(mob_pos, player_pos) > 3 then + return + end + -- is mob protected? + if self.protected and minetest.is_protected(mob_pos, hitter:get_player_name()) then + return + end + + mcl_potions.update_haste_and_fatigue(hitter) + end + + local time_now = minetest.get_us_time() + 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 -- custom punch function if self.do_punch then @@ -529,20 +559,15 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) return end - local is_player = hitter:is_player() + local time_now = minetest.get_us_time() if is_player then - -- is mob protected? - if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then - return - end - if minetest.is_creative_enabled(hitter:get_player_name()) then self.health = 0 end -- set/update 'drop xp' timestamp if hitted by player - self.xp_timestamp = minetest.get_us_time() + self.xp_timestamp = time_now end @@ -580,6 +605,13 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) * tmp * ((armor[group] or 0) / 100.0) end + -- strength and weakness effects + local strength = mcl_potions.get_effect(hitter, "strength") + local weakness = mcl_potions.get_effect(hitter, "weakness") + local str_fac = strength and strength.factor or 1 + local weak_fac = weakness and weakness.factor or 1 + damage = damage * str_fac * weak_fac + if weapon then local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") if fire_aspect_level > 0 then @@ -621,6 +653,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then local wear = math.floor(65535/tool_capabilities.punch_attack_uses) weapon:add_wear(wear) + tt.reload_itemstack_description(weapon) -- update tooltip hitter:set_wielded_item(weapon) end end, hitter:get_player_name()) @@ -654,6 +687,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) -- do damage self.health = self.health - damage + -- give invulnerability + self.invul_timestamp = time_now + -- skip future functions if dead, except alerting others if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then die = true @@ -669,10 +705,10 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) if not v then return end local r = 1.4 - math.min(punch_interval, 1.4) local kb = r * (math.abs(v.x)+math.abs(v.z)) - local up = 2 + local up = 2.625 if die==true then - kb=kb*2 + kb=kb*1.25 end -- if already in air then dont go up anymore when hit @@ -686,7 +722,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) if tool_capabilities.damage_groups["knockback"] then kb = tool_capabilities.damage_groups["knockback"] else - kb = kb * 1.5 + kb = kb * 1.25 end @@ -696,9 +732,19 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) end if hitter and is_player then local wielditem = hitter:get_wielded_item() - kb = kb + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") - elseif luaentity and luaentity._knockback then + kb = kb + 9 * mcl_enchanting.get_enchantment(wielditem, "knockback") + -- add player velocity to mob knockback + local hv = hitter:get_velocity() + 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)) + 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 + elseif luaentity and luaentity._knockback and die == true then + kb = kb + luaentity._knockback * 0.25 end self._kb_turn = true self._turn_to=self.object:get_yaw()-1.57 @@ -756,34 +802,37 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) end -- alert others to the attack - local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range) - local obj = nil + local alert_pos = hitter:get_pos() + if alert_pos then + local objs = minetest.get_objects_inside_radius(alert_pos, self.view_range) + local obj = nil - for n = 1, #objs do + for n = 1, #objs do - obj = objs[n]:get_luaentity() + obj = objs[n]:get_luaentity() - if obj then - -- only alert members of same mob or friends - if obj.group_attack - and obj.state ~= "attack" - and obj.owner ~= name then - if obj.name == self.name then - obj:do_attack(hitter) - elseif type(obj.group_attack) == "table" then - for i=1, #obj.group_attack do - if obj.group_attack[i] == self.name then - obj._aggro = true - obj:do_attack(hitter) - break + if obj then + -- only alert members of same mob or friends + if obj.group_attack + and obj.state ~= "attack" + and obj.owner ~= name then + if obj.name == self.name then + obj:do_attack(hitter) + elseif type(obj.group_attack) == "table" then + for i=1, #obj.group_attack do + if obj.group_attack[i] == self.name then + obj._aggro = true + obj:do_attack(hitter) + break + end end end end - end - -- have owned mobs attack player threat - if obj.owner == name and obj.owner_loyal then - obj:do_attack(self.object) + -- have owned mobs attack player threat + if obj.owner == name and obj.owner_loyal then + obj:do_attack(self.object) + end end end end @@ -853,7 +902,8 @@ function mob_class:do_states_attack (dtime) return end - local target_line_of_sight = self:line_of_sight(s, p, 2) + local target_line_of_sight = self:target_visible(s) + if not target_line_of_sight then if self.target_time_lost then local time_since_seen = os.time() - self.target_time_lost @@ -918,6 +968,7 @@ function mob_class:do_states_attack (dtime) if self.v_start then self.timer = self.timer + dtime self.blinktimer = (self.blinktimer or 0) + dtime + self:set_animation("fuse") if self.blinktimer > 0.2 then self.blinktimer = 0 @@ -1102,6 +1153,10 @@ function mob_class:do_states_attack (dtime) full_punch_interval = 1.0, damage_groups = {fleshy = self.damage} }, nil) + if self.dealt_effect then + mcl_potions.give_effect_by_level(self.dealt_effect.name, self.attack, + self.dealt_effect.level, self.dealt_effect.dur) + end end else self.custom_attack(self, p) @@ -1192,6 +1247,9 @@ function mob_class:do_states_attack (dtime) -- important for mcl_shields ent._shooter = self.object ent._saved_shooter_pos = self.object:get_pos() + if ent.homing then + ent._target = self.attack + end end local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 @@ -1208,7 +1266,13 @@ function mob_class:do_states_attack (dtime) end end end - else + elseif self.attack_type == "custom" and self.attack_state then + self.attack_state(self, dtime) end + + if self.on_attack then + self.on_attack(self, dtime) + end + end diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua index aa44a67f7..e746fef39 100644 --- a/mods/ENTITIES/mcl_mobs/effects.lua +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -1,5 +1,7 @@ local math, tonumber, vector, minetest, mcl_mobs = math, tonumber, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local validate_vector = mcl_util.validate_vector + local active_particlespawners = {} local disable_blood = minetest.settings:get_bool("mobs_disable_blood") local DEFAULT_FALL_SPEED = -9.81*1.5 @@ -9,16 +11,6 @@ local PATHFINDING = "gowp" local player_transfer_distance = tonumber(minetest.settings:get("player_transfer_distance")) or 128 if player_transfer_distance == 0 then player_transfer_distance = math.huge end - -local function validate_vector (vect) - if vect then - if tonumber(vect.x) and tonumber(vect.y) and tonumber(vect.z) then - return true - end - end - return false -end - -- custom particle effects function mcl_mobs.effect(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down) @@ -418,7 +410,7 @@ function mob_class:check_head_swivel(dtime) --final_rotation = vector.new(0,0,0) end - mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horrizonatal_head_height), final_rotation) + mcl_util.set_bone_position(self.object,self.head_swivel, vector.new(0,self.bone_eye_height,self.horizontal_head_height), final_rotation) end diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index 62100c627..81b5fdfe7 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -147,7 +147,7 @@ function mcl_mobs.register_mob(name, def) head_eye_height = def.head_eye_height or def.bone_eye_height or 0, -- how hight aproximatly the mobs head is fromm the ground to tell the mob how high to look up at the player curiosity = def.curiosity or 1, -- how often mob will look at player on idle head_yaw = def.head_yaw or "y", -- axis to rotate head on - horrizonatal_head_height = def.horrizonatal_head_height or 0, + horizontal_head_height = def.horizontal_head_height or 0, wears_armor = def.wears_armor, -- a number value used to index texture slot for armor stepheight = def.stepheight or 0.6, name = name, @@ -171,6 +171,7 @@ function mcl_mobs.register_mob(name, def) xp_min = def.xp_min or 0, xp_max = def.xp_max or 0, xp_timestamp = 0, + invul_timestamp = 0, breath_max = def.breath_max or 15, breathes_in_water = def.breathes_in_water or false, physical = true, @@ -287,6 +288,7 @@ function mcl_mobs.register_mob(name, def) spawn_in_group_min = def.spawn_in_group_min, noyaw = def.noyaw or false, particlespawners = def.particlespawners, + spawn_check = def.spawn_check, -- End of MCL2 extensions on_spawn = def.on_spawn, on_blast = def.on_blast or function(self,damage) @@ -297,6 +299,7 @@ function mcl_mobs.register_mob(name, def) return false, true, {} end, do_punch = def.do_punch, + deal_damage = def.deal_damage, on_breed = def.on_breed, on_grown = def.on_grown, on_pick_up = def.on_pick_up, @@ -311,18 +314,73 @@ function mcl_mobs.register_mob(name, def) return self:mob_activate(staticdata, def, dtime) end, + after_activate = def.after_activate, + attack_state = def.attack_state, -- custom attack state + on_attack = def.on_attack, -- called after attack, useful with otherwise predefined attack states (not custom) harmed_by_heal = def.harmed_by_heal, - on_lightning_strike = def.on_lightning_strike + is_boss = def.is_boss, + dealt_effect = def.dealt_effect, + on_lightning_strike = def.on_lightning_strike, + extra_hostile = def.extra_hostile, + attack_exception = def.attack_exception or function(p) return false end, + + _spawner = def._spawner, + _mcl_potions = {}, } - minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta)) if minetest.get_modpath("doc_identifier") ~= nil then doc.sub.identifier.register_object(name, "basics", "mobs") + + if def.unused ~= true then + doc.add_entry("mobs", name, { + name = def.description or name, + data = final_def, + }) + end end + minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta)) end -- END mcl_mobs.register_mob function +local STRIP_FIELDS = { "mesh", "base_size", "textures", "base_mesh", "base_texture" } +function mcl_mobs.strip_staticdata(unpacked_staticdata) + -- Strip select fields from the staticdata to prevent conversion issues + for i = 1,#STRIP_FIELDS do + unpacked_staticdata[STRIP_FIELDS[i]] = nil + end +end +function mcl_mobs.register_conversion(old_name, new_name) + minetest.register_entity(old_name, { + on_activate = function(self, staticdata, dtime) + local unpacked_staticdata = minetest.deserialize(staticdata) + mcl_mobs.strip_staticdata(unpacked_staticdata) + staticdata = minetest.serialize(unpacked_staticdata) + + local old_object = self.object + if not old_object then return end + + local pos = old_object:get_pos() + if not pos then return end + old_object:remove() + + local new_object = minetest.add_entity(pos, new_name, staticdata) + if not new_object then return end + + local hook = (new_object:get_luaentity() or {})._on_after_convert + if hook then hook(new_object) end + end, + _convert_to = new_name, + }) +end + +function mcl_mobs.get_arrow_damage_func(damage, typ) + local typ = mcl_damage.types[typ] and typ or "arrow" + return function(projectile, object) + return mcl_util.deal_damage(object, damage, {type = typ}) + end +end + -- register arrow for shoot attack function mcl_mobs.register_arrow(name, def) @@ -339,15 +397,18 @@ function mcl_mobs.register_arrow(name, def) hit_node = def.hit_node, hit_mob = def.hit_mob, hit_object = def.hit_object, + homing = def.homing, drop = def.drop or false, -- drops arrow as registered item when true collisionbox = {0, 0, 0, 0, 0, 0}, -- remove box around arrows timer = 0, switch = 0, + _lifetime = def._lifetime or 7, owner_id = def.owner_id, rotate = def.rotate, - on_punch = function(self) - local vel = self.object:get_velocity() - self.object:set_velocity({x=vel.x * -1, y=vel.y * -1, z=vel.z * -1}) + on_punch = def.on_punch or function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + local vel = self.object:get_velocity():length() + self.object:set_velocity(dir * vel) + self._puncher = puncher end, collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, automatic_face_movement_dir = def.rotate @@ -357,12 +418,12 @@ function mcl_mobs.register_arrow(name, def) on_step = def.on_step or function(self, dtime) - self.timer = self.timer + 1 + self.timer = self.timer + dtime local pos = self.object:get_pos() if self.switch == 0 - or self.timer > 150 + or self.timer > self._lifetime or not within_limits(pos, 0) then mcl_burning.extinguish(self.object) self.object:remove(); @@ -410,26 +471,37 @@ function mcl_mobs.register_arrow(name, def) end end + if self.homing and self._target then + local p = self._target:get_pos() + if p then + if minetest.line_of_sight(self.object:get_pos(), p) then + self.object:set_velocity(vector.direction(self.object:get_pos(), p) * self.velocity) + end + else + self._target = nil + end + end + if self.hit_player or self.hit_mob or self.hit_object then - for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do + for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do if self.hit_player - and player:is_player() then + and object:is_player() then - self.hit_player(self, player) + self.hit_player(self, object) self.object:remove(); return end - local entity = player:get_luaentity() + local entity = object:get_luaentity() if entity and self.hit_mob and entity.is_mob == true - and tostring(player) ~= self.owner_id + and (tostring(object) ~= self.owner_id or self.timer > 2) and entity.name ~= self.object:get_luaentity().name then - self.hit_mob(self, player) + self.hit_mob(self, object) self.object:remove(); return end @@ -437,9 +509,9 @@ function mcl_mobs.register_arrow(name, def) if entity and self.hit_object and (not entity.is_mob) - and tostring(player) ~= self.owner_id + and (tostring(object) ~= self.owner_id or self.timer > 2) and entity.name ~= self.object:get_luaentity().name then - self.hit_object(self, player) + self.hit_object(self, object) self.object:remove(); return end @@ -520,7 +592,12 @@ function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addeg --minetest.log("min light: " .. mob_light_lvl[1]) --minetest.log("max light: " .. mob_light_lvl[2]) - mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name(), mob_light_lvl[1], mob_light_lvl[2]) + -- Handle egg conversion + local mob_name = itemstack:get_name() + local convert_to = (minetest.registered_entities[mob_name] or {})._convert_to + if convert_to then mob_name = convert_to end + + mcl_mobspawners.setup_spawner(pointed_thing.under, mob_name, mob_light_lvl[1], mob_light_lvl[2]) if not minetest.is_creative_enabled(name) then itemstack:take_item() end diff --git a/mods/ENTITIES/mcl_mobs/items.lua b/mods/ENTITIES/mcl_mobs/items.lua index 267dd8595..f2ec4dedd 100644 --- a/mods/ENTITIES/mcl_mobs/items.lua +++ b/mods/ENTITIES/mcl_mobs/items.lua @@ -87,7 +87,8 @@ function mob_class:check_item_pickup() end if self.pick_up then for k,v in pairs(self.pick_up) do - if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then + local itemstack = ItemStack(l.itemstring) + if not player_near(p) and self.on_pick_up and itemstack:get_name():find(v) then local r = self.on_pick_up(self,l) if r and r.is_empty and not r:is_empty() then l.itemstring = r:to_string() diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.oc.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.oc.tr new file mode 100644 index 000000000..a9e775fff --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.oc.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_mobs +Peaceful mode active! No monsters will spawn.=Mòde tranquile actiu! Gis de mostre vai aparèisser. +This allows you to place a single mob.=Quo permet de plaça una creatura. +Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Plaçatz z-o a l'endreit que volètz veire la creatura aparèisser. Las bèstias seron dejà domesticadas, defòra si laissatz la tocha se baissar enfonçada. Si z-o plaçatz sobre un generator de creaturas, chamjatz la creatura generada. +You need the “maphack” privilege to change the mob spawner.=Avètz besonh dau privilègi "maphack" per chamjar le generator de creaturas. +Name Tag=Étiquette de nom +A name tag is an item to name a mob.=Una etiqueta z-es un otilh per chamjar le nom de la creatura. +Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Davant d'utilizar l'etiqueta, vos fau li botar un nom embei una enclutge. Après, podètz utilizar l'etiqueta per nomar una creatura. L'etiqueta pòt èsser utilizada un còp. +Only peaceful mobs allowed!=Mas las creaturas pacificas son autorizadas! +Give names to mobs=Balha daus noms a las creaturas +Set name at anvil=Botar le nom embei l'enclutge +Removes specified mobs except nametagged and tamed ones. For the second parameter, use nametagged/tamed to select only nametagged/tamed mobs, or a range to specify a maximum distance from the player.=Lèva las creaturas specifiadas defòra de las que son nomadas o domesticadas. Per le paramètre segònd, utilizar nomat/domesticat per mas seleccionar las creaturas nomadas/domesticadas, o una distança per specifiar la distança maximum embei li joairi. +Default usage. Clearing hostile mobs. For more options please type: /help clearmobs=Usage par défaut. Lèva las creaturas ostilas. Per mai d'opcions, escriure : /help clearmobs diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.pt_BR.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.pt_BR.tr new file mode 100644 index 000000000..20babe453 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.pt_BR.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_mobs +Peaceful mode active! No monsters will spawn.=Modo pacífico ativado! Nenhum monstro será gerado. +This allows you to place a single mob.=Isso permite você posicionar um único mob. +Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Posicione-o onde você deseja que o mob apareça. Animais serão gerados domesticados, a menos que você segure pressionada a tecla de agachar enquanto posiciona. Se você posicionar em um gerador de mobs, você muda o mob que será gerado. +You need the “maphack” privilege to change the mob spawner.=Você precisa do privilégio "maphack" para mudar o gerador de mobs. +Name Tag=Etiqueta +A name tag is an item to name a mob.=Uma etiqueta é um item para nomear um mob. +Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Antes de você usar a etiqueta, você precisa determinar um nome em uma bigorna. Assim você pode usar a etiqueta para nomear um mob. Isso consumirá a etiqueta. +Only peaceful mobs allowed!=Apenas mobs pacíficos permitidos! +Give names to mobs=Dá nome aos mobs +Set name at anvil=Determine um nome em uma bigorna +Removes specified mobs except nametagged and tamed ones. For the second parameter, use nametagged/tamed to select only nametagged/tamed mobs, or a range to specify a maximum distance from the player.=Remove mobs especifícos exceto os mobs nomeados ou domesticados. Como segundo parâmetro, use nametagged/tamed para selecionar apenas mobs nomeados/domesticados, ou um alcançe para especificar uma distância máxima em relação ao jogador. +Default usage. Clearing hostile mobs. For more options please type: /help clearmobs=Uso padrão. Eliminando mobs hostis. Para mais opções por favor digite: /help clearmobs diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr index 477d3d642..7caa4852d 100644 --- a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr @@ -1,11 +1,13 @@ # textdomain: mcl_mobs -Peaceful mode active! No monsters will spawn.=Мирный режим включён! Чудовища не будут появляться. -This allows you to place a single mob.=Позволяет вам породить одно существо. -Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Просто нажмите на блок, где хотите, чтобы появилось существо. Животные будут появляться уже прирученные, если это не нужно, удерживайте клавишу [Красться] при размещении. Если использовать на порождателе, тогда существо будет изменено. -You need the “maphack” privilege to change the mob spawner.=Вам нужно обладать привилегией «maphack», чтобы изменить порождатель существ. -Name Tag=Именная бирка -A name tag is an item to name a mob.=Именная бирка — это предмет, чтобы дать существу имя. -Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Прежде чем использовать именную бирку, нужно задать имя на наковальне. Тогда вы сможете использовать бирку, чтобы дать имя мобу. -Only peaceful mobs allowed!=Разрешены только мирные существа! -Give names to mobs=Даёт имена существам -Set name at anvil=Задайте имя при помощи наковальни +Peaceful mode active! No monsters will spawn.=Мирный режим включён! Монстры не будут спауниться. +This allows you to place a single mob.=Позволяет вам заспаунить одного моба. +Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Используйте предмет там, где вы хотите, чтобы заспаунился моб. Животные будут спауниться уже прирученные, если только вы не удерживаете клавишу [Красться] при размещении. Если использовать на спаунере мобов, изменится создаваемый им моб. +You need the “maphack” privilege to change the mob spawner.=Вам нужна привилегия “maphack”, чтобы изменить спаунер мобов. +Name Tag=Бирка +A name tag is an item to name a mob.=Бирка это предмет, дающий мобу имя. +Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Прежде чем использовать бирку, нужно задать ей имя на наковальне. Тогда вы сможете использовать бирку, чтобы дать имя мобу. +Only peaceful mobs allowed!=Разрешены только мирные мобы! +Give names to mobs=Даёт имена мобам +Set name at anvil=Задайте имя на наковальне +Removes specified mobs except nametagged and tamed ones. For the second parameter, use nametagged/tamed to select only nametagged/tamed mobs, or a range to specify a maximum distance from the player.=Удаляет указанных мобов кроме именованных и прирученных. Для второго параметра используйте nametagged/tamed, чтобы выбрать именованных/прирученных мобов или радиус указывающий максимальную дистанцию от игрока. +Default usage. Clearing hostile mobs. For more options please type: /help clearmobs=Параметры по умолчанию. Удаляем враждебных мобов. Для дополнительных опций введите: /help clearmobs diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf index 9c10e9a2b..927c1c905 100644 --- a/mods/ENTITIES/mcl_mobs/mod.conf +++ b/mods/ENTITIES/mcl_mobs/mod.conf @@ -1,5 +1,5 @@ name = mcl_mobs author = PilzAdam description = Adds a mob API for mods to add animals or monsters, etc. -depends = mcl_particles +depends = mcl_particles, mcl_luck optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience, mcl_sculk diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua index 317ac9f28..ff9a38f56 100644 --- a/mods/ENTITIES/mcl_mobs/movement.lua +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -76,6 +76,67 @@ function mob_class:is_node_waterhazard(nodename) return false end + +local function raycast_line_of_sight (origin, target) + local raycast = minetest.raycast(origin, target, false, true) + + local los_blocked = false + + for hitpoint in raycast do + if hitpoint.type == "node" then + --TODO type object could block vision, for example chests + local node = minetest.get_node(minetest.get_pointed_thing_position(hitpoint)) + + if node.name ~= "air" then + local nodef = minetest.registered_nodes[node.name] + if nodef and nodef.walkable then + los_blocked = true + break + end + end + end + end + return not los_blocked +end + +function mob_class:target_visible(origin) + if not origin then return end + + if not self.attack then return end + local target_pos = self.attack:get_pos() + + if not target_pos then return end + + local origin_eye_pos = vector.offset(origin, 0, self.head_eye_height, 0) + + --minetest.log("origin: " .. dump(origin)) + --minetest.log("origin_eye_pos: " .. dump(origin_eye_pos)) + + local targ_head_height, targ_feet_height + if self.attack:is_player() then + local cbox = self.object:get_properties().collisionbox + targ_head_height = vector.offset(target_pos, 0, cbox[5], 0) + targ_feet_height = target_pos -- Cbox would put feet under ground which interferes with ray + else + targ_head_height = vector.offset(target_pos, 0, self.collisionbox[5], 0) + targ_feet_height = vector.offset(target_pos, 0, self.collisionbox[2], 0) + end + + --minetest.log("start targ_head_height: " .. dump(targ_head_height)) + if raycast_line_of_sight (origin_eye_pos, targ_head_height) then + return true + end + + --minetest.log("Start targ_feet_height: " .. dump(targ_feet_height)) + if raycast_line_of_sight (origin_eye_pos, targ_feet_height) then + return true + end + + -- TODO mid way between feet and head + + return false +end + -- check line of sight (BrunoMine) function mob_class:line_of_sight(pos1, pos2, stepsize) diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua index e1b23d78a..73aefb509 100644 --- a/mods/ENTITIES/mcl_mobs/physics.lua +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -1,5 +1,6 @@ local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local validate_vector = mcl_util.validate_vector local ENTITY_CRAMMING_MAX = 24 local CRAMMING_DAMAGE = 3 @@ -355,7 +356,7 @@ function mob_class:set_yaw(yaw, delay, dtime) if math.abs(target_shortest_path_nums) > 10 then self.object:set_yaw(self.object:get_yaw()+(target_shortest_path*(3.6*ddtime))) - if self.acc then + if validate_vector(self.acc) then self.acc=vector.rotate_around_axis(self.acc,vector.new(0,1,0), target_shortest_path*(3.6*ddtime)) end end @@ -675,13 +676,20 @@ function mob_class:do_env_damage() self.standing_in = node_ok(pos, "air").name self.standing_on = node_ok(pos2, "air").name + local pos3 = vector.offset(pos, 0, 1, 0) + self.standing_under = node_ok(pos3, "air").name + -- don't fall when on ignore, just stand still if self.standing_in == "ignore" then self.object:set_velocity({x = 0, y = 0, z = 0}) + -- wither rose effect + elseif self.standing_in == "mcl_flowers:wither_rose" then + mcl_potions.give_effect_by_level("withering", self.object, 2, 2) end local nodef = minetest.registered_nodes[self.standing_in] local nodef2 = minetest.registered_nodes[self.standing_on] + local nodef3 = minetest.registered_nodes[self.standing_under] -- rain if self.rain_damage > 0 then @@ -753,6 +761,61 @@ function mob_class:do_env_damage() end end + -- Cactus damage + local near = minetest.find_node_near(pos, 1, "mcl_core:cactus", true) + if not near and near ~= nil then + near = find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus", true) + end + if near then + -- is mob touching the cactus? + local dist = vector.distance(pos, near) + local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near) + local large_mob = false + local medium_mob = false + if self.name == "mobs_mc:ender_dragon" or + self.name == "mobs_mc:ghast" or + self.name == "mobs_mc:guardian_elder" or + self.name == "mobs_mc:slime_big" or + self.name == "mobs_mc:magma_cube_big" or + self.name == "mobs_mc:wither" then + + large_mob = true + elseif self.name == "mobs_mc:hoglin" or + self.name == "mobs_mc:zoglin" or + self.name == "mobs_mc:horse" or + self.name == "mobs_mc:skeleton_horse" or + self.name == "mobs_mc:zombie_horse" or + self.name == "mobs_mc:donkey" or + self.name == "mobs_mc:mule" or + self.name == "mobs_mc:iron_golem" or + self.name == "mobs_mc:polar_bear" or + self.name == "mobs_mc:spider" or + self.name == "mobs_mc:cave_spider" or + self.name == "mobs_mc:strider" then + + medium_mob = true + end + if (not large_mob and not medium_mob and (dist < 1.03 or dist_feet < 1.6)) or (medium_mob and (dist < 1.165 or dist_feet < 1.73)) or (large_mob and (dist < 1.25 or dist_feet < 1.9)) then + if self.health ~= 0 then + self:damage_mob("cactus", 2) + + if self:check_for_death("cactus", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + end + end + -- is mob standing on the cactus? + if self.standing_on == "mcl_core:cactus" or self.standing_in == "mcl_core:cactus" or self.standing_under == "mcl_core:cactus" then + self:damage_mob("cactus", 2) + + if self:check_for_death("cactus", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + -- Drowning damage if self.breath_max ~= -1 then local drowning = false @@ -761,7 +824,7 @@ function mob_class:do_env_damage() if minetest.get_item_group(self.standing_in, "water") == 0 then drowning = true end - elseif nodef.drowning > 0 then + elseif nodef.drowning > 0 and nodef3.drowning > 0 then drowning = true end @@ -939,7 +1002,7 @@ function mob_class:falling(pos) -- in water then float up if registered_node.groups.water then - if acc and self.floats == 1 then + if acc and self.floats == 1 and minetest.registered_nodes[node_ok(vector.offset(pos,0,self.collisionbox[5] -0.25,0)).name].groups.water then self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0)) end else diff --git a/mods/ENTITIES/mcl_mobs/readme.MD b/mods/ENTITIES/mcl_mobs/readme.MD index aa79d909c..df4ecc4c4 100644 --- a/mods/ENTITIES/mcl_mobs/readme.MD +++ b/mods/ENTITIES/mcl_mobs/readme.MD @@ -1,74 +1,74 @@ - -Mobs Redo: MineClone 2 Edition - -Based on Mobs Redo from TenPlus1 -Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel, Zeg9, ExeterDad and AspireMint. - - -This mod contains the API only for adding your own mobs into the world, so please use the additional modpacks to add animals, monsters etc. - - -https://forum.minetest.net/viewtopic.php?f=11&t=9917 - ------------- -Credits: - -mcl_mobs_mob_poof.ogg: -- by Planman (license: Creative Commons Zero) -- Source: - ------------- - -Changelog from original Mobs Redo mod: -- 1.41- Mob pathfinding has been updated thanks to Elkien3 -- 1.40- Updated to use newer functions, requires Minetest 0.4.16+ to work. -- 1.39- Added 'on_breed', 'on_grown' and 'do_punch' custom functions per mob -- 1.38- Better entity checking, nametag setting and on_spawn function added to mob registry, tweaked light damage -- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448 -- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked -- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack -- 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code) -- 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112 -- 1.32- Added new spawn check to count specific mobs AND new minetest.conf setting to chance spawn chance and numbers, added ability to protect tamed mobs -- 1.31- Added 'attack_animals' and 'specific_attack' flags for custom monster attacks, also 'mob_difficulty' .conf setting to make mobs harder. -- 1.30- Added support for invisibility mod (mobs cant attack what they cant see), tweaked and tidied code -- 1.29- Split original Mobs Redo into a modpack to make it easier to disable mob sets (animal, monster, npc) or simply use the Api itself for your own mod -- 1.28- New damage system added with ability for mob to be immune to weapons or healed by them :) -- 1.27- Added new sheep, lava flan and spawn egg textures. New Lava Pick tool smelts what you dig. New atan checking function. -- 1.26- Pathfinding feature added thanks to rnd, when monsters attack they become scary smart in finding you :) also, beehive produces honey now :) -- 1.25- Mobs no longer spawn within 12 blocks of player or despawn within same range, spawners now have player detection, Code tidy and tweak. -- 1.24- Added feature where certain animals run away when punched (runaway = true in mob definition) -- 1.23- Added mob spawner block for admin to setup spawners in-game (place and right click to enter settings) -- 1.22- Added ability to name tamed animals and npc using nametags, also npc will attack anyone who punches them apart from owner -- 1.21- Added some more error checking to reduce serialize.h error and added height checks for falling off cliffs (thanks cmdskp) -- 1.20- Error checking added to remove bad mobs, out of map limit mobs and stop serialize.h error -- 1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick -- 1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first -- 1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added -- 1.16- Mobs follow multiple items now, Npc's can breed -- 1.15- Added Feeding/Taming/Breeding function, right-click to pick up any sheep with X mark on them and replace with new one to fix compatibility. -- 1.14- All .self variables saved in staticdata, Fixed self.health bug -- 1.13- Added capture function (thanks blert2112) chance of picking up mob with hand; net; magic lasso, replaced some .x models with newer .b3d one's -- 1.12- Added animal ownership so that players cannot steal your tamed animals -- 1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy -- 1,10- Footstep removed (use replace), explosion routine added for exploding mobs. -- 1.09- reworked breeding routine, added mob rotation value, added footstep feature, added jumping mobs with sounds feature, added magic lasso for picking up animals -- 1.08- Mob throwing attack has been rehauled so that they can damage one another, also drops and on_die function added -- 1.07- Npc's can now be set to follow player or stand by using self.order and self.owner variables -- beta- Npc mob added, kills monsters, attacks player when punched, right click with food to heal or gold lump for drop -- 1.06- Changed recovery times after breeding, and time taken to grow up (can be sped up by feeding baby animal) -- 1.05- Added ExeterDad's bunny's which can be picked up and tamed with 4 carrots from farming redo or farming_plus, also shears added to get wool from sheep and lastly Jordach/BSD's kitten -- 1.04- Added mating for sheep, cows and hogs... feed animals to make horny and hope for a baby which is half size, will grow up quick though :) -- 1.03- Added mob drop/replace feature so that chickens can drop eggs, cow/sheep can eat grass/wheat etc. -- 1.02- Sheared sheep are remembered and spawn shaven, Warthogs will attack when threatened, Api additions -- 1.01- Mobs that suffer fall damage or die in water/lava/sunlight will now drop items -- 1.0 - more work on Api so that certain mobs can float in water while some sink like a brick :) -- 0.9 - Spawn eggs added for all mobs (admin only, cannot be placed in protected areas)... Api tweaked -- 0.8 - Added sounds to monster mobs (thanks Cyberpangolin for the sfx) and also chicken sound -- 0.7 - mobs.protected switch added to api.lua, when set to 1 mobs no longer spawn in protected areas, also bug fixes -- 0.6 - Api now supports multi-textured mobs, e.g oerkki, dungeon master, rats and chickens have random skins when spawning (sheep fix TODO), also new Honey block -- 0.5 - Mobs now float in water, die from falling, and some code improvements -- 0.4 - Dungeon Masters and Mese Monsters have much better aim due to shoot_offset, also they can both shoot through nodes that aren't walkable (flowers, grass etc) plus new sheep sound :) -- 0.3 - Added LOTT's Spider mob, made Cobwebs, added KPavel's Bee with Honey and Beehives (made texture), Warthogs now have sound and can be tamed, taming of shaved sheep or milked cow with 8 wheat so it will not despawn, many bug fixes :) -- 0.2 - Cooking bucket of milk into cheese now returns empty bucket -- 0.1 - Initial Release + +Mobs Redo: VoxeLibre Edition + +Based on Mobs Redo from TenPlus1 +Built from PilzAdam's original Simple Mobs with additional mobs by KrupnoPavel, Zeg9, ExeterDad and AspireMint. + + +This mod contains the API only for adding your own mobs into the world, so please use the additional modpacks to add animals, monsters etc. + + +https://forum.minetest.net/viewtopic.php?f=11&t=9917 + +------------ +Credits: + +mcl_mobs_mob_poof.ogg: +- by Planman (license: Creative Commons Zero) +- Source: + +------------ + +Changelog from original Mobs Redo mod: +- 1.41- Mob pathfinding has been updated thanks to Elkien3 +- 1.40- Updated to use newer functions, requires Minetest 0.4.16+ to work. +- 1.39- Added 'on_breed', 'on_grown' and 'do_punch' custom functions per mob +- 1.38- Better entity checking, nametag setting and on_spawn function added to mob registry, tweaked light damage +- 1.37- Added support for Raymoo's CMI (common mob interface) mod: https://forum.minetest.net/viewtopic.php?f=9&t=15448 +- 1.36- Death check added, if mob dies in fire/lava/with lava pick then drops are cooked +- 1.35- Added owner_loyal flag for owned mobs to attack player enemies, also fixed group_attack +- 1.34- Added function to fly mob using directional movement (thanks D00Med for flying code) +- 1.33- Added functions to mount ride mobs (mobs.attach, mobs.detach, mobs.drive) many thanks to Blert2112 +- 1.32- Added new spawn check to count specific mobs AND new minetest.conf setting to chance spawn chance and numbers, added ability to protect tamed mobs +- 1.31- Added 'attack_animals' and 'specific_attack' flags for custom monster attacks, also 'mob_difficulty' .conf setting to make mobs harder. +- 1.30- Added support for invisibility mod (mobs cant attack what they cant see), tweaked and tidied code +- 1.29- Split original Mobs Redo into a modpack to make it easier to disable mob sets (animal, monster, npc) or simply use the Api itself for your own mod +- 1.28- New damage system added with ability for mob to be immune to weapons or healed by them :) +- 1.27- Added new sheep, lava flan and spawn egg textures. New Lava Pick tool smelts what you dig. New atan checking function. +- 1.26- Pathfinding feature added thanks to rnd, when monsters attack they become scary smart in finding you :) also, beehive produces honey now :) +- 1.25- Mobs no longer spawn within 12 blocks of player or despawn within same range, spawners now have player detection, Code tidy and tweak. +- 1.24- Added feature where certain animals run away when punched (runaway = true in mob definition) +- 1.23- Added mob spawner block for admin to setup spawners in-game (place and right click to enter settings) +- 1.22- Added ability to name tamed animals and npc using nametags, also npc will attack anyone who punches them apart from owner +- 1.21- Added some more error checking to reduce serialize.h error and added height checks for falling off cliffs (thanks cmdskp) +- 1.20- Error checking added to remove bad mobs, out of map limit mobs and stop serialize.h error +- 1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick +- 1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first +- 1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added +- 1.16- Mobs follow multiple items now, Npc's can breed +- 1.15- Added Feeding/Taming/Breeding function, right-click to pick up any sheep with X mark on them and replace with new one to fix compatibility. +- 1.14- All .self variables saved in staticdata, Fixed self.health bug +- 1.13- Added capture function (thanks blert2112) chance of picking up mob with hand; net; magic lasso, replaced some .x models with newer .b3d one's +- 1.12- Added animal ownership so that players cannot steal your tamed animals +- 1.11- Added flying mobs (and swimming), fly=true and fly_in="air" or "deafult:water_source" for fishy +- 1,10- Footstep removed (use replace), explosion routine added for exploding mobs. +- 1.09- reworked breeding routine, added mob rotation value, added footstep feature, added jumping mobs with sounds feature, added magic lasso for picking up animals +- 1.08- Mob throwing attack has been rehauled so that they can damage one another, also drops and on_die function added +- 1.07- Npc's can now be set to follow player or stand by using self.order and self.owner variables +- beta- Npc mob added, kills monsters, attacks player when punched, right click with food to heal or gold lump for drop +- 1.06- Changed recovery times after breeding, and time taken to grow up (can be sped up by feeding baby animal) +- 1.05- Added ExeterDad's bunny's which can be picked up and tamed with 4 carrots from farming redo or farming_plus, also shears added to get wool from sheep and lastly Jordach/BSD's kitten +- 1.04- Added mating for sheep, cows and hogs... feed animals to make horny and hope for a baby which is half size, will grow up quick though :) +- 1.03- Added mob drop/replace feature so that chickens can drop eggs, cow/sheep can eat grass/wheat etc. +- 1.02- Sheared sheep are remembered and spawn shaven, Warthogs will attack when threatened, Api additions +- 1.01- Mobs that suffer fall damage or die in water/lava/sunlight will now drop items +- 1.0 - more work on Api so that certain mobs can float in water while some sink like a brick :) +- 0.9 - Spawn eggs added for all mobs (admin only, cannot be placed in protected areas)... Api tweaked +- 0.8 - Added sounds to monster mobs (thanks Cyberpangolin for the sfx) and also chicken sound +- 0.7 - mobs.protected switch added to api.lua, when set to 1 mobs no longer spawn in protected areas, also bug fixes +- 0.6 - Api now supports multi-textured mobs, e.g oerkki, dungeon master, rats and chickens have random skins when spawning (sheep fix TODO), also new Honey block +- 0.5 - Mobs now float in water, die from falling, and some code improvements +- 0.4 - Dungeon Masters and Mese Monsters have much better aim due to shoot_offset, also they can both shoot through nodes that aren't walkable (flowers, grass etc) plus new sheep sound :) +- 0.3 - Added LOTT's Spider mob, made Cobwebs, added KPavel's Bee with Honey and Beehives (made texture), Warthogs now have sound and can be tamed, taming of shaved sheep or milked cow with 8 wheat so it will not despawn, many bug fixes :) +- 0.2 - Cooking bucket of milk into cheese now returns empty bucket +- 0.1 - Initial Release diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua index c677aeacf..c0e68e55b 100644 --- a/mods/ENTITIES/mcl_mobs/spawning.lua +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -2,14 +2,20 @@ local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs local mob_class = mcl_mobs.mob_class +local modern_lighting = minetest.settings:get_bool("mcl_mobs_modern_lighting", true) +local nether_threshold = tonumber(minetest.settings:get("mcl_mobs_nether_threshold")) or 11 +local end_threshold = tonumber(minetest.settings:get("mcl_mobs_end_threshold")) or 0 +local overworld_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_threshold")) or 0 +local overworld_sky_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_sky_threshold")) or 7 +local overworld_passive_threshold = tonumber(minetest.settings:get("mcl_mobs_overworld_passive_threshold")) or 7 + local get_node = minetest.get_node local get_item_group = minetest.get_item_group local get_node_light = minetest.get_node_light local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air -local get_biome_name = minetest.get_biome_name +local mt_get_biome_name = minetest.get_biome_name local get_objects_inside_radius = minetest.get_objects_inside_radius local get_connected_players = minetest.get_connected_players -local minetest_get_perlin = minetest.get_perlin local math_random = math.random local math_floor = math.floor @@ -17,6 +23,7 @@ local math_ceil = math.ceil local math_cos = math.cos local math_sin = math.sin local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end +local math_sqrt = math.sqrt local vector_distance = vector.distance local vector_new = vector.new @@ -90,19 +97,6 @@ local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false local logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true) -local noise_params = { - offset = 0, - scale = 3, - spread = { - x = 301, - y = 50, - z = 304, - }, - seed = 100, - octaves = 3, - persistence = 0.5, -} - -- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs -- Also used for missing parameter -- Please update the list when adding new biomes! @@ -439,7 +433,6 @@ WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? local spawn_dictionary = {} --this is where all of the spawning information is kept for mobs that don't naturally spawn local non_spawn_dictionary = {} -local summary_chance = 0 function mcl_mobs:spawn_setup(def) if not mobs_spawn then return end @@ -501,7 +494,6 @@ function mcl_mobs:spawn_setup(def) check_position = check_position, on_spawn = on_spawn, } - summary_chance = summary_chance + chance end function mcl_mobs:mob_light_lvl(mob_name, dimension) @@ -573,6 +565,9 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ return end + assert(min_height) + assert(max_height) + -- chance/spawn number override in minetest.conf for registered mob local numbers = minetest.settings:get(name) @@ -604,27 +599,119 @@ function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_ spawn_dictionary[key]["max_height"] = max_height spawn_dictionary[key]["day_toggle"] = day_toggle spawn_dictionary[key]["check_position"] = check_position - - summary_chance = summary_chance + chance end +-- Calculate the inverse of a piecewise linear function f(x). Line segments are represented as two +-- adjacent points specified as { x, f(x) }. At least 2 points are required. If there are most solutions, +-- the one with a lower x value will be chosen. +local function inverse_pwl(fx, f) + if fx < f[1][2] then + return f[1][1] + end + + for i=2,#f do + local x0,fx0 = unpack(f[i-1]) + local x1,fx1 = unpack(f[i ]) + if fx < fx1 then + return (fx - fx0) * (x1 - x0) / (fx1 - fx0) + x0 + end + end + + return f[#f][1] +end + +local SPAWN_DISTANCE_CDF_PWL = { + {0.000,0.00}, + {0.083,0.40}, + {0.416,0.75}, + {1.000,1.00}, +} local two_pi = 2 * math.pi local function get_next_mob_spawn_pos(pos) - -- TODO We should consider spawning something a little further away sporadically. - -- It would be good for sky farms and variance, rather than all being on the 24 - 32 block away radius - local distance = math_random(MOB_SPAWN_ZONE_INNER, MOB_SPAWN_ZONE_MIDDLE) - local angle = math_random() * two_pi + -- Select a distance such that distances closer to the player are selected much more often than + -- those further away from the player. + local fx = (math_random(1,10000)-1) / 10000 + local x = inverse_pwl(fx, SPAWN_DISTANCE_CDF_PWL) + local distance = x * (MOB_SPAWN_ZONE_OUTER - MOB_SPAWN_ZONE_INNER) + MOB_SPAWN_ZONE_INNER + --print("Using spawn distance of "..tostring(distance).." fx="..tostring(fx)..",x="..tostring(x)) -- TODO Floor xoff and zoff and add 0.5 so it tries to spawn in the middle of the square. Less failed attempts. - local xoff = math_round(distance * math_cos(angle)) - local zoff = math_round(distance * math_sin(angle)) - return vector.offset(pos, xoff, 0, zoff) -end + -- Use spherical coordinates https://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates + local theta = math_random() * two_pi + local phi = math_random() * two_pi + local xoff = math_round(distance * math_sin(theta) * math_cos(phi)) + local yoff = math_round(distance * math_cos(theta)) + local zoff = math_round(distance * math_sin(theta) * math_sin(phi)) + local goal_pos = vector.offset(pos, xoff, yoff, zoff) -local function decypher_limits(posy) - posy = math_floor(posy) - return posy - MOB_SPAWN_ZONE_MIDDLE, posy + MOB_SPAWN_ZONE_MIDDLE + if not ( math.abs(goal_pos.x) <= SPAWN_MAPGEN_LIMIT and math.abs(pos.y) <= SPAWN_MAPGEN_LIMIT and math.abs(goal_pos.z) <= SPAWN_MAPGEN_LIMIT ) then + mcl_log("Pos outside mapgen limits: " .. minetest.pos_to_string(goal_pos)) + return nil + end + + -- Calculate upper/lower y limits + local R1 = MOB_SPAWN_ZONE_OUTER + local d = vector_distance( pos, vector.new( goal_pos.x, pos.y, goal_pos.z ) ) -- distance from player to projected point on horizontal plane + local y1 = math_sqrt( R1*R1 - d*d ) -- absolue value of distance to outer sphere + + local y_min + local y_max + if d >= MOB_SPAWN_ZONE_INNER then + -- Outer region, y range has both ends on the outer sphere + y_min = pos.y - y1 + y_max = pos.y + y1 + else + -- Inner region, y range spans between inner and outer spheres + local R2 = MOB_SPAWN_ZONE_INNER + local y2 = math_sqrt( R2*R2 - d*d ) + if goal_pos.y > pos. y then + -- Upper hemisphere + y_min = pos.y + y2 + y_max = pos.y + y1 + else + -- Lower hemisphere + y_min = pos.y - y1 + y_max = pos.y - y2 + end + end + y_min = math_round(y_min) + y_max = math_round(y_max) + + -- Limit total range of check to 32 nodes (maximum of 3 map blocks) + if y_max > goal_pos.y + 16 then + y_max = goal_pos.y + 16 + end + if y_min < goal_pos.y - 16 then + y_min = goal_pos.y - 16 + end + + -- Ask engine for valid spawn locations + local spawning_position_list = find_nodes_in_area_under_air( + {x = goal_pos.x, y = y_min, z = goal_pos.z}, + {x = goal_pos.x, y = y_max, z = goal_pos.z}, + {"group:solid", "group:water", "group:lava"} + ) or {} + + -- Select only the locations at a valid distance + local valid_positions = {} + for _,check_pos in ipairs(spawning_position_list) do + local dist = vector.distance(pos, check_pos) + if dist >= MOB_SPAWN_ZONE_INNER and dist <= MOB_SPAWN_ZONE_OUTER then + valid_positions[#valid_positions + 1] = check_pos + end + end + spawning_position_list = valid_positions + + -- No valid locations, failed to find a position + if #spawning_position_list == 0 then + mcl_log("Spawning position isn't good. Do not spawn: " .. minetest.pos_to_string(goal_pos)) + return nil + end + + -- Pick a random valid location + mcl_log("Spawning positions available: " .. minetest.pos_to_string(goal_pos)) + return spawning_position_list[math_random(1, #spawning_position_list)] end --a simple helper function for mob_spawn @@ -675,7 +762,29 @@ local function has_room(self,pos) return true end +mcl_mobs.custom_biomecheck = nil +function mcl_mobs.register_custom_biomecheck(custom_biomecheck) + mcl_mobs.custom_biomecheck = custom_biomecheck +end + + +local function get_biome_name(pos) + if mcl_mobs.custom_biomecheck then + return mcl_mobs.custom_biomecheck (pos) + else + local gotten_biome = minetest.get_biome_data(pos) + + if not gotten_biome then + return + end + + gotten_biome = mt_get_biome_name(gotten_biome.biome) + --minetest.log ("biome: " .. dump(gotten_biome)) + + return gotten_biome + end +end local function spawn_check(pos, spawn_def) if not spawn_def or not pos then return end @@ -685,11 +794,10 @@ local function spawn_check(pos, spawn_def) local mob_def = minetest.registered_entities[spawn_def.name] local mob_type = mob_def.type local gotten_node = get_node(pos).name - local gotten_biome = minetest.get_biome_data(pos) + if not gotten_node then return end - if not gotten_node or not gotten_biome then return end - - gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + local biome_name = get_biome_name(pos) + if not biome_name then return end local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0 if not is_ground then @@ -707,11 +815,9 @@ local function spawn_check(pos, spawn_def) if pos.y >= spawn_def.min_height and pos.y <= spawn_def.max_height and spawn_def.dimension == dimension - and biome_check(spawn_def.biomes, gotten_biome) then - - --mcl_log("Level 1 spawn check passed") - --minetest.log("Mob: " .. mob_def.name) + and biome_check(spawn_def.biomes, biome_name) then + mcl_log("Spawn level 1 check - Passed") if (is_ground or spawn_def.type_of_spawning ~= "ground") and (spawn_def.type_of_spawning ~= "ground" or not is_leaf) and (not is_farm_animal(spawn_def.name) or is_grass) @@ -721,20 +827,42 @@ local function spawn_check(pos, spawn_def) and (spawn_def.check_position and spawn_def.check_position(pos) or spawn_def.check_position == nil) and ( not spawn_protected or not minetest.is_protected(pos, "") ) then - --mcl_log("Level 2 spawn check passed") - + mcl_log("Spawn level 2 check - Passed") local gotten_light = get_node_light(pos) - if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then - --mcl_log("Level 3 spawn check passed") - return true + + if modern_lighting then + local my_node = get_node(pos) + local sky_light = minetest.get_natural_light(pos) + local art_light = minetest.get_artificial_light(my_node.param1) + + if mob_def.spawn_check then + return mob_def.spawn_check(pos, gotten_light, art_light, sky_light) + elseif mob_type == "monster" then + if dimension == "nether" then + if art_light <= nether_threshold then + return true + end + elseif dimension == "end" then + if art_light <= end_threshold then + return true + 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 else - --mcl_log("Spawn check level 3 failed") + if gotten_light >= spawn_def.min_light and gotten_light <= spawn_def.max_light then + return true + end end - else - --mcl_log("Spawn check level 2 failed") end - else - --mcl_log("Spawn check level 1 failed") end return false end @@ -850,8 +978,6 @@ minetest.register_chatcommand("spawn_mob",{ if mobs_spawn then - local perlin_noise - -- Get pos to spawn, x and z are randomised, y is range @@ -910,47 +1036,33 @@ if mobs_spawn then local function find_spawning_position(pos, max_times) local spawning_position - - local max_loops = 1 - if max_times then max_loops = max_times end - - local y_min, y_max = decypher_limits(pos.y) + local max_loops = max_times or 1 --mcl_log("mapgen_limit: " .. SPAWN_MAPGEN_LIMIT) - local i = 0 - repeat - local goal_pos = get_next_mob_spawn_pos(pos) + while max_loops > 0 do + local spawning_position = get_next_mob_spawn_pos(pos) + if spawning_position then return spawning_position end + max_loops = max_loops - 1 - if math.abs(goal_pos.x) <= SPAWN_MAPGEN_LIMIT and math.abs(pos.y) <= SPAWN_MAPGEN_LIMIT and math.abs(goal_pos.z) <= SPAWN_MAPGEN_LIMIT then - local spawning_position_list = find_nodes_in_area_under_air( - {x = goal_pos.x, y = y_min, z = goal_pos.z}, - {x = goal_pos.x, y = y_max, z = goal_pos.z}, - {"group:solid", "group:water", "group:lava"} - ) - if #spawning_position_list > 0 then - mcl_log("Spawning positions available: " .. minetest.pos_to_string(goal_pos)) - spawning_position = spawning_position_list[math_random(1, #spawning_position_list)] - else - mcl_log("Spawning position isn't good. Do not spawn: " .. minetest.pos_to_string(goal_pos)) - end + end + return nil + end - else - mcl_log("Pos outside mapgen limits: " .. minetest.pos_to_string(goal_pos)) + local cumulative_chance = nil + local mob_library_worker_table = nil + local function initialize_spawn_data() + if not mob_library_worker_table then + mob_library_worker_table = table_copy(spawn_dictionary) + end + if not cumulative_chance then + cumulative_chance = 0 + for k, v in pairs(mob_library_worker_table) do + cumulative_chance = cumulative_chance + v.chance end - - - i = i + 1 - if i >= max_loops then - mcl_log("Cancel finding spawn positions at: " .. max_loops) - break - end - until spawning_position - return spawning_position + end end local function spawn_a_mob(pos, cap_space_hostile, cap_space_non_hostile) - --create a disconnected clone of the spawn dictionary, prevents memory leak - local mob_library_worker_table = table_copy(spawn_dictionary) local spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES) if not spawning_position then @@ -963,22 +1075,25 @@ if mobs_spawn then --output_mob_stats(mob_counts_wide) --grab mob that fits into the spawning location - --randomly grab a mob, don't exclude any possibilities - perlin_noise = perlin_noise or minetest_get_perlin(noise_params) - local noise = perlin_noise:get_3d(spawning_position) - local current_summary_chance = summary_chance + --use random weighted choice with replacement to grab a mob, don't exclude any possibilities + --shuffle table once every loop to provide equal inclusion probability to all mobs + --repeat grabbing a mob to maintain existing spawn rates + local spawn_loop_counter = #mob_library_worker_table - table.shuffle(mob_library_worker_table) - - while #mob_library_worker_table > 0 do - local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1 + while spawn_loop_counter > 0 do + table.shuffle(mob_library_worker_table) + local mob_chance_offset = math_random(1, cumulative_chance) local mob_index = 1 local mob_chance = mob_library_worker_table[mob_index].chance local step_chance = mob_chance while step_chance < mob_chance_offset do mob_index = mob_index + 1 - mob_chance = mob_library_worker_table[mob_index].chance - step_chance = step_chance + mob_chance + if mob_index <= #mob_library_worker_table then + mob_chance = mob_library_worker_table[mob_index].chance + step_chance = step_chance + mob_chance + else + break + end end --minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance) @@ -1063,8 +1178,7 @@ if mobs_spawn then end end - current_summary_chance = current_summary_chance - mob_chance - table_remove(mob_library_worker_table, mob_index) + spawn_loop_counter = spawn_loop_counter - 1 end end @@ -1076,6 +1190,7 @@ if mobs_spawn then timer = timer + dtime if timer < WAIT_FOR_SPAWN_ATTEMPT then return end + initialize_spawn_data() timer = 0 local players = get_connected_players() @@ -1156,7 +1271,6 @@ function mob_class:check_despawn(pos, dtime) end end - minetest.register_chatcommand("mobstats",{ privs = { debug = true }, func = function(n,param) diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.oc.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.oc.tr new file mode 100644 index 000000000..6f368b3d2 --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.oc.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=Quadre diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pt_BR.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pt_BR.tr new file mode 100644 index 000000000..3c0a840cf --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=Pintura diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ru.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ru.tr index cc2f52778..3cd8ebca7 100644 --- a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ru.tr +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ru.tr @@ -1,2 +1,2 @@ # textdomain:mcl_paintings -Painting=Рисование +Painting=Картина diff --git a/mods/ENTITIES/mcl_wither_spawning/init.lua b/mods/ENTITIES/mcl_wither_spawning/init.lua index 74cd1e6e2..2a7a9c595 100644 --- a/mods/ENTITIES/mcl_wither_spawning/init.lua +++ b/mods/ENTITIES/mcl_wither_spawning/init.lua @@ -2,6 +2,9 @@ local dim = {"x", "z"} local modpath = minetest.get_modpath(minetest.get_current_modname()) +local anti_troll = minetest.settings:get_bool("wither_anti_troll_measures", false) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + local function load_schem(filename) local file = io.open(modpath .. "/schems/" .. filename, "r") local data = minetest.deserialize(file:read()) @@ -9,6 +12,14 @@ local function load_schem(filename) return data end +local wboss_overworld = 0 +local wboss_nether = 0 +local wboss_end = 0 + +local LIM_OVERWORLD = tonumber(minetest.settings:get("wither_cap_overworld")) or 3 +local LIM_NETHER = tonumber(minetest.settings:get("wither_cap_nether")) or 10 +local LIM_END = tonumber(minetest.settings:get("wither_cap_end")) or 5 + local wither_spawn_schems = {} for _, d in pairs(dim) do @@ -16,8 +27,13 @@ for _, d in pairs(dim) do end local function check_schem(pos, schem) + local cn_name for _, n in pairs(schem) do - if minetest.get_node(vector.add(pos, n)).name ~= n.name then + cn_name = minetest.get_node(vector.add(pos, n)).name + if string.find(cn_name, "mcl_heads:wither_skeleton") then + cn_name = "mcl_heads:wither_skeleton" + end + if cn_name ~= n.name then return false end end @@ -30,14 +46,32 @@ local function remove_schem(pos, schem) end end -local function wither_spawn(pos) +local function check_limit(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "overworld" and wboss_overworld >= LIM_OVERWORLD then return false + elseif dim == "end" and wboss_end >= LIM_END then return false + elseif wboss_nether >= LIM_NETHER then return false + else return true end +end + +local function wither_spawn(pos, player) + if peaceful then return end for _, d in pairs(dim) do for i = 0, 2 do local p = vector.add(pos, {x = 0, y = -2, z = 0, [d] = -i}) local schem = wither_spawn_schems[d] - if check_schem(p, schem) then + if check_schem(p, schem) and (not anti_troll or check_limit(pos)) then remove_schem(p, schem) - minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + local wither = minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + if not wither then return end + local wither_ent = wither:get_luaentity() + wither_ent._spawner = player:get_player_name() + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "overworld" then + wboss_overworld = wboss_overworld + 1 + elseif dim == "end" then + wboss_end = wboss_end + 1 + else wboss_nether = wboss_nether + 1 end local objects = minetest.get_objects_inside_radius(pos, 20) for _, players in ipairs(objects) do if players:is_player() then @@ -54,7 +88,19 @@ local old_on_place = wither_head.on_place function wither_head.on_place(itemstack, placer, pointed) local n = minetest.get_node(vector.offset(pointed.above,0,-1,0)) if n and n.name == "mcl_nether:soul_sand" then - minetest.after(0, wither_spawn, pointed.above) + minetest.after(0, wither_spawn, pointed.above, placer) end return old_on_place(itemstack, placer, pointed) end + +if anti_troll then + -- pull wither counts per dimension + minetest.register_globalstep(function(dtime) + wboss_overworld = mobs_mc.wither_count_overworld + wboss_nether = mobs_mc.wither_count_nether + wboss_end = mobs_mc.wither_count_end + mobs_mc.wither_count_overworld = 0 + mobs_mc.wither_count_nether = 0 + mobs_mc.wither_count_end = 0 + end) +end diff --git a/mods/ENTITIES/mcl_wither_spawning/mod.conf b/mods/ENTITIES/mcl_wither_spawning/mod.conf index d144bb1ea..f73ef558e 100644 --- a/mods/ENTITIES/mcl_wither_spawning/mod.conf +++ b/mods/ENTITIES/mcl_wither_spawning/mod.conf @@ -1,4 +1,4 @@ name = mcl_wither_spawning -description = Wither Spawning for MineClone2 +description = Wither Spawning for VoxeLibre author = Fleckenstein depends = mobs_mc, mcl_heads diff --git a/mods/ENTITIES/mobs_mc/LICENSE-media.md b/mods/ENTITIES/mobs_mc/LICENSE-media.md index 4e3de49f1..278148b85 100644 --- a/mods/ENTITIES/mobs_mc/LICENSE-media.md +++ b/mods/ENTITIES/mobs_mc/LICENSE-media.md @@ -191,9 +191,10 @@ Origin of those models: * [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0) * `mcl_totems_totem.ogg` * Source: -* [Baŝto](https://opengameart.org/users/ba%C5%9Dto) +* [Baŝto](https://opengameart.org/users/ba%C5%9Dto) (remixer) and [kantouth](https://freesound.org/people/kantouth/) (original author) * `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0) * Source: + * Based on: * [spookymodem](https://freesound.org/people/spookymodem/) * `mobs_mc_skeleton_death.ogg` (CC0) * @@ -304,7 +305,10 @@ Origin of those models: * `mobs_mc_rabbit_random.*.ogg` (CC0) * Changes were made. * Source: +* [epCode] + * `extra_mobs_hoglin*.ogg` (LGPL 3.0) + * Source: Note: Many of these sounds have been more or less modified to fit the game. -Sounds not mentioned hre are licensed under CC0. +Sounds not mentioned here are licensed under CC0. diff --git a/mods/ENTITIES/mobs_mc/README.md b/mods/ENTITIES/mobs_mc/README.md index bdc561295..db5663abb 100644 --- a/mods/ENTITIES/mobs_mc/README.md +++ b/mods/ENTITIES/mobs_mc/README.md @@ -33,11 +33,11 @@ This mod adds mobs which closely resemble the mobs from the game Minecraft, vers * Husk * Skeleton * Stray -* Creeper +* Stalker * Slime * Spider * Cave Spider -* Enderman +* Rover * Zombie Villager * Zombie Piglin * Wither Skeleton diff --git a/mods/ENTITIES/mobs_mc/axolotl.lua b/mods/ENTITIES/mobs_mc/axolotl.lua index 087f201c7..a30f8ffe1 100644 --- a/mods/ENTITIES/mobs_mc/axolotl.lua +++ b/mods/ENTITIES/mobs_mc/axolotl.lua @@ -1,6 +1,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) local axolotl = { + description = S("Axolotl"), type = "animal", spawn_class = "axolotl", can_despawn = true, @@ -13,7 +14,7 @@ local axolotl = { head_swivel = "head.control", bone_eye_height = -1, head_eye_height = -0.5, - horrizonatal_head_height = 0, + horizontal_head_height = 0, curiosity = 10, head_yaw="z", @@ -78,7 +79,6 @@ local axolotl = { attack_animals = true, specific_attack = { "extra_mobs_cod", - "mobs_mc:sheep", "extra_mobs_glow_squid", "extra_mobs_salmon", "extra_mobs_tropical_fish", @@ -172,7 +172,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -4000, +100, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index b5532e2ee..cc36e3836 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -2,6 +2,18 @@ local S = minetest.get_translator("mobs_mc") +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + local date = os.date("*t") + local maxlight + if (date.month == 10 and date.day >= 20) or (date.month == 11 and date.day <= 3) then + maxlight = 6 + else + maxlight = 3 + end + + return artificial_light <= maxlight +end + mcl_mobs.register_mob("mobs_mc:bat", { description = S("Bat"), type = "animal", @@ -50,6 +62,7 @@ mcl_mobs.register_mob("mobs_mc:bat", { jump = false, fly = true, makes_footstep_sound = false, + spawn_check = spawn_check, }) @@ -137,7 +150,7 @@ mcl_mobs:spawn_specific( 0, maxlight, 20, -5000, +100, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-1) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 6d92de210..bbc47df94 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -11,6 +11,9 @@ local mod_target = minetest.get_modpath("mcl_target") --################### BLAZE --################### +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end mcl_mobs.register_mob("mobs_mc:blaze", { description = S("Blaze"), @@ -137,6 +140,7 @@ mcl_mobs.register_mob("mobs_mc:blaze", { }, }) end, + spawn_check = spawn_check, }) mcl_mobs:spawn_specific( @@ -147,7 +151,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -5000, +1000, 3, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index ca942d355..1adf47569 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -23,7 +23,7 @@ mcl_mobs.register_mob("mobs_mc:chicken", { head_swivel = "head.control", bone_eye_height = 4, head_eye_height = 1.5, - horrizonatal_head_height = -.3, + horizontal_head_height = -.3, curiosity = 10, head_yaw="z", visual_size = {x=1,y=1}, @@ -157,7 +157,7 @@ mcl_mobs:spawn_specific( }, 9, minetest.LIGHT_MAX+1, -30, 17000, +30, 100, 3, mobs_mc.water_level, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/cod.lua b/mods/ENTITIES/mobs_mc/cod.lua index 656b2c14c..a2aa2eadf 100644 --- a/mods/ENTITIES/mobs_mc/cod.lua +++ b/mods/ENTITIES/mobs_mc/cod.lua @@ -30,6 +30,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) --################### local cod = { + description = S("Cod"), type = "animal", spawn_class = "water_ambient", can_despawn = true, @@ -266,7 +267,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -4000, +750, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 64f74c516..4722c157c 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -24,7 +24,7 @@ local cow_def = { head_swivel = "head.control", bone_eye_height = 10, head_eye_height = 1.1, - horrizonatal_head_height=-1.8, + horizontal_head_height=-1.8, curiosity = 2, head_yaw="z", makes_footstep_sound = true, @@ -105,7 +105,7 @@ mooshroom_def.on_rightclick = function(self, clicker) end local item = clicker:get_wielded_item() -- Use shears to get mushrooms and turn mooshroom into cow - if item:get_name() == "mcl_tools:shears" then + if minetest.get_item_group(item:get_name(), "shears") > 0 then local pos = self.object:get_pos() minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) @@ -122,6 +122,7 @@ mooshroom_def.on_rightclick = function(self, clicker) if not minetest.is_creative_enabled(clicker:get_player_name()) then item:add_wear(mobs_mc.shears_wear) + tt.reload_itemstack_description(item) -- update tooltip clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end -- Use bucket to milk @@ -207,7 +208,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -17000, +80, 10, mobs_mc.water_level, mcl_vars.mg_overworld_max) @@ -225,7 +226,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -17000, +80, 5, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/dolphin.lua b/mods/ENTITIES/mobs_mc/dolphin.lua index 153734c39..0db7647b9 100644 --- a/mods/ENTITIES/mobs_mc/dolphin.lua +++ b/mods/ENTITIES/mobs_mc/dolphin.lua @@ -30,6 +30,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) --################### local dolphin = { + description = S("Dolphin"), type = "animal", spawn_class = "water", can_despawn = true, @@ -244,7 +245,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -4000, +70, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index fb92f51c4..d916596dd 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -127,7 +127,7 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", { minetest.set_node(vector.add(self._portal_pos, vector.new(0, 5, 0)), {name = "mcl_end:dragon_egg"}) end end - + -- Free The End Advancement for _,players in pairs(minetest.get_objects_inside_radius(pos,64)) do if players:is_player() then @@ -136,6 +136,7 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", { end end, fire_resistant = true, + is_boss = true, }) diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 1a3d34e1b..81855d0b6 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -20,7 +20,7 @@ mcl_mobs.register_mob("mobs_mc:ghast", { hp_max = 10, xp_min = 5, xp_max = 5, - collisionbox = {-2, 5, -2, 2, 9, 2}, + collisionbox = {-2, 0, -2, 2, 4, 2, rotate=true}, visual = "mesh", mesh = "mobs_mc_ghast.b3d", spawn_in_group = 1, @@ -33,7 +33,7 @@ mcl_mobs.register_mob("mobs_mc:ghast", { death = "mobs_mc_zombie_death", attack = "mobs_fireball", random = "mobs_eerie", - distance = 16, + distance = 80, -- TODO: damage -- TODO: better death }, @@ -50,11 +50,11 @@ mcl_mobs.register_mob("mobs_mc:ghast", { run_start = 0, run_end = 40, }, fall_damage = 0, - view_range = 100, + view_range = 64, attack_type = "dogshoot", arrow = "mobs_mc:fireball", - shoot_interval = 3.5, - shoot_offset = -5, + shoot_interval = 5, + shoot_offset = -0.5, dogshoot_switch = 1, dogshoot_count_max =1, passive = false, @@ -97,7 +97,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -72000, +400, 2, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) @@ -107,8 +107,9 @@ mcl_mobs.register_arrow("mobs_mc:fireball", { visual = "sprite", visual_size = {x = 1, y = 1}, textures = {"mcl_fire_fire_charge.png"}, - velocity = 15, + velocity = 5, collisionbox = {-.5, -.5, -.5, .5, .5, .5}, + _lifetime = 10, _is_fireball = true, hit_player = function(self, player) @@ -125,11 +126,16 @@ mcl_mobs.register_arrow("mobs_mc:fireball", { end, hit_mob = function(self, mob) + local name = mob:get_luaentity().name mob:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, }, nil) mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true) + local ent = mob:get_luaentity() + if (not ent or ent.health <= 0) and self._puncher and name == "mobs_mc:ghast" then + awards.unlock(self._puncher:get_player_name(), "mcl:fireball_redir_serv") + end end, hit_node = function(self, pos, node) diff --git a/mods/ENTITIES/mobs_mc/glow_squid.lua b/mods/ENTITIES/mobs_mc/glow_squid.lua index 2d3f19270..4cf4e5986 100644 --- a/mods/ENTITIES/mobs_mc/glow_squid.lua +++ b/mods/ENTITIES/mobs_mc/glow_squid.lua @@ -30,6 +30,7 @@ for i=1,4 do end mcl_mobs.register_mob("mobs_mc:glow_squid", { + description = S("Glow Squid"), type = "animal", spawn_class = "water_underground", can_despawn = true, @@ -237,7 +238,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX + 1, 30, - 10000, + 100, 3, water - 16, water) diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index f2addbfa0..ab4051626 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -99,9 +99,7 @@ mcl_mobs.register_mob("mobs_mc:guardian", { view_range = 16, }) --- Spawning disabled due to size issues --- TODO: Re-enable spawning ---mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10) +mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10, mobs_mc.water_level) mcl_mobs:non_spawn_specific("mobs_mc:guardian","overworld",0,minetest.LIGHT_MAX+1) -- spawn eggs mcl_mobs.register_egg("mobs_mc:guardian", S("Guardian"), "#5a8272", "#f17d31", 0) diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index 094c0513c..be787216c 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -105,11 +105,14 @@ mcl_mobs.register_mob("mobs_mc:guardian_elder", { fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, jump = false, view_range = 16, + dealt_effect = { + name = "fatigue", + level = 3, + dur = 30, + }, }) --- Spawning disabled due to size issues <- what do you mean? -j4i --- TODO: Re-enable spawning --- mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18) +mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18, mobs_mc.water_level) -- spawn eggs mcl_mobs.register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0) diff --git a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua index 8f8590933..08f9a46ad 100644 --- a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua +++ b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua @@ -31,8 +31,9 @@ local hoglin = { } }, visual_size = {x=3, y=3}, sounds = { - random = "extra_mobs_hoglin", + random = "extra_mobs_hoglin.1", damage = "extra_mobs_hoglin_hurt", + death = "extra_mobs_hoglin_hurt", distance = 16, }, jump = true, @@ -92,6 +93,12 @@ local zoglin = table.copy(hoglin) zoglin.description = S("Zoglin") zoglin.fire_resistant = 1 zoglin.textures = {"extra_mobs_zoglin.png"} +sounds = { + random = "extra_mobs_hoglin.2", + damage = "extra_mobs_hoglin_hurt", + death = "extra_mobs_hoglin_hurt", + distance = 16, + } zoglin.do_custom = function() return end @@ -129,7 +136,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -6000, +200, 3, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 07aa58572..4f2708f2d 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -44,18 +44,6 @@ local function get_drops(self) max = 2, looting = "common", }) - if self._saddle then - table.insert(self.drops,{name = "mcl_mobitems:saddle", - chance = 1, - min = 1, - max = 1,}) - end - if self._chest then - table.insert(self.drops,{name = "mcl_chests:chest", - chance = 1, - min = 1, - max = 1,}) - end end -- Helper functions to determine equipment rules @@ -134,10 +122,10 @@ local horse = { stand_speed = 25, stand_start = 0, stand_end = 0, - walk_speed = 25, + walk_speed = 100, walk_start = 0, walk_end = 40, - run_speed = 60, + run_speed = 200, run_start = 0, run_end = 40, }, @@ -245,10 +233,18 @@ local horse = { on_die = function(self, pos) - -- drop saddle when horse is killed while riding + -- drop saddle when horse is killed if self._saddle then minetest.add_item(pos, "mcl_mobitems:saddle") end + -- drop chest when mule/donkey is killed + if self._chest then + minetest.add_item(pos, "mcl_chests:chest") + end + -- drop armor when horse is killed + if self._wearing_armor then + minetest.add_item(pos, self._horse_armor) + end -- also detach from horse properly if self.driver then mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) @@ -401,6 +397,7 @@ local horse = { -- Put on armor and take armor from player's inventory local armor = minetest.get_item_group(iname, "horse_armor") self._horse_armor = iname + self._wearing_armor = true local w = clicker:get_wielded_item() if not minetest.is_creative_enabled(clicker:get_player_name()) then w:take_item() @@ -546,11 +543,6 @@ donkey.description = S("Donkey") donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}} donkey.spawn_in_group = 3 donkey.spawn_in_group_min = 1 -donkey.animation = { - speed_normal = 25, - stand_start = 0, stand_end = 0, - walk_start = 0, walk_end = 40, -} donkey.sounds = { random = "mobs_mc_donkey_random", damage = "mobs_mc_donkey_hurt", @@ -612,7 +604,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -15000, +40, 4, mobs_mc.water_level+3, mcl_vars.mg_overworld_max) @@ -635,7 +627,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -15000, +10, 4, mobs_mc.water_level+3, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/init.lua b/mods/ENTITIES/mobs_mc/init.lua index 483efdcb4..f22f1ebcf 100644 --- a/mods/ENTITIES/mobs_mc/init.lua +++ b/mods/ENTITIES/mobs_mc/init.lua @@ -124,9 +124,7 @@ dofile(path .. "/witch.lua") -- Mesh and animation by toby109tt / https://githu --Monsters dofile(path .. "/blaze.lua") -- Animation by daufinsyd -dofile(path .. "/creeper.lua") -- Mesh by Morn76 Animation by Pavel_S dofile(path .. "/ender_dragon.lua") -- Mesh and animation by toby109tt / https://github.com/22i -dofile(path .. "/enderman.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/endermite.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_illusioner.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/ghast.lua") -- maikerumine @@ -134,10 +132,12 @@ dofile(path .. "/guardian.lua") -- maikerumine Mesh and animation by toby109tt dofile(path .. "/guardian_elder.lua") -- maikerumine Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/snowman.lua") dofile(path .. "/iron_golem.lua") -- maikerumine Mesh and animation by toby109tt / https://github.com/22i +dofile(path .. "/rover.lua") -- Mesh and Animation by Herowl dofile(path .. "/shulker.lua") -- maikerumine Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/silverfish.lua") -- maikerumine Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/skeleton+stray.lua") -- Mesh by Morn76 Animation by Pavel_S dofile(path .. "/skeleton_wither.lua") -- Mesh by Morn76 Animation by Pavel_S +dofile(path .. "/stalker.lua") -- Mesh and Animation by Herowl dofile(path .. "/zombie.lua") -- Mesh by Morn76 Animation by Pavel_S dofile(path .. "/slime+magma_cube.lua") -- Wuzzy dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture) diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 6b428c6f8..b79971b9b 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -4,12 +4,14 @@ --License for code WTFPL and otherwise stated in readmes local S = minetest.get_translator("mobs_mc") +local allow_nav_hacks = minetest.settings:get_bool("mcl_mob_allow_nav_hacks ",false) --################### --################### IRON GOLEM --################### -local etime = 0 +local walk_dist = 40 +local tele_dist = 80 mcl_mobs.register_mob("mobs_mc:iron_golem", { description = S("Iron Golem"), @@ -85,11 +87,23 @@ mcl_mobs.register_mob("mobs_mc:iron_golem", { punch_start = 40, punch_end = 50, }, jump = true, - on_step = function(self,dtime) - etime = etime + dtime - if etime > 10 then - if self._home and vector.distance(self._home,self.object:get_pos()) > 50 then - self:gopath(self._home) + do_custom = function(self, dtime) + self.home_timer = (self.home_timer or 0) + dtime + + if self.home_timer > 10 then + self.home_timer = 0 + if self._home and self.state ~= "attack" then + local dist = vector.distance(self._home,self.object:get_pos()) + if allow_nav_hacks and dist >= tele_dist then + self.object:set_pos(self._home) + self.state = "stand" + self.order = "follow" + elseif dist >= walk_dist then + self:gopath(self._home, function(self) + self.state = "stand" + self.order = "follow" + end) + end end end end, diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 32bfc97ea..78d190121 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -62,7 +62,7 @@ mcl_mobs.register_mob("mobs_mc:llama", { head_swivel = "head.control", bone_eye_height = 11, head_eye_height = 3, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 60, head_yaw = "z", @@ -291,7 +291,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -15000, +50, 5, mobs_mc.water_level+15, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr index 84aade90e..d807cfa32 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr @@ -5,7 +5,7 @@ Blaze=Lohe Chicken=Huhn Cow=Kuh Mooshroom=Pilzkuh -Creeper=Creeper +Stalker=Stalker Ender Dragon=Enderdrache Enderman=Enderman Endermite=Endermilbe diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr index 5df92f2f8..c125411eb 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr @@ -6,7 +6,7 @@ Blaze=Blaze Chicken=Kylling Cow=Ko Mooshroom=Svamp -Creeper=Creeper +Stalker=Stalker Ender Dragon=Enderdrage Enderman=Enderman Endermite=Endermide @@ -67,4 +67,4 @@ Cod=Torsk Salmon=Laks Dolphin=Delfin Pillager=Plyndrer -Tropical fish=Tropisk fisk \ No newline at end of file +Tropical fish=Tropisk fisk diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr index 47e19cc42..44b6e1ef5 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr @@ -5,7 +5,7 @@ Chicken=Pollo Cod=Bacalao Cow=Vaca Mooshroom=Champivaca -Creeper=Creeper +Stalker=Stalker Dolphin=Delfín Ender Dragon=Ender Dragon Enderman=Enderman diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr index 81c93a33b..94b99bd49 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr @@ -6,7 +6,7 @@ Blaze=Blaze Chicken=Poulet Cow=Vache Mooshroom=Champimeuh -Creeper=Creeper +Stalker=Stalker Ender Dragon=Ender Dragon Enderman=Enderman Endermite=Endermite @@ -21,6 +21,7 @@ Mule=Mule Iron Golem=Golem de fer Llama=Lama Ocelot=Ocelot +Cat=Chat Parrot=Perroquet Pig=Cochon Polar Bear=Ours blanc @@ -48,8 +49,15 @@ Witch=Sorcière Wither=Wither Wolf=Loup Husk=Zombie Momifié +Baby Husk=Bébé Zombie Momifié 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 Fisherman=Pêcheur Fletcher=Archer @@ -69,5 +77,7 @@ Dolphin=Dauphin Pillager=Pilleur Tropical fish=Poisson tropical Hoglin=Hoglin +Baby hoglin=Bébé Hoglin +Zoglin=Zoglin Strider=Arpenteur -Glow Squid=Poulpe Brillant \ No newline at end of file +Glow Squid=Poulpe Brillant diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.oc.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.oc.tr new file mode 100644 index 000000000..aabbe2d63 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.oc.tr @@ -0,0 +1,73 @@ +# textdomain: mobs_mc +Agent=Agent +Axolotl=Axolòtl +Bat=Ratapenada +Blaze=Flamor +Chicken=Polet +Cow=Vacha +Mooshroom=Vachairòla +Stalker=Stalker +Ender Dragon=Dragon de Finuèit +Enderman=Finuèairi +Endermite=Finuèibau +Ghast=Òrra +Elder Guardian=Ancian Gardian +Guardian=Gardian +Horse=Ega +Skeleton Horse=Ega Squeleta +Zombie Horse=Ega Zombia +Donkey=Asne +Mule=Miule +Iron Golem=Golem de Fèrre +Llama=Lamà +Ocelot=Ocelòt +Parrot=Papagai +Pig=Cochon +Polar Bear=Ors Blanc +Rabbit=Lapin +Killer Bunny=Lapin Tuaire +Sheep=Moton +Shulker=Coirafin +Silverfish=Peiçon d'Argent +Skeleton=Squeleta +Stray=Trainabiaça +Wither Skeleton=Squeleta Sechaire +Magma Cube=Cube de Magmà +Slime=Slime +Snow Golem=Golem d'Ivèrn +Spider=Aranha +Cave Spider=Aranha Venimósa +Squid=Pofre +Vex=Vex +Evoker=Invocataire +Illusioner=Fisiciaire +Villager=Vialatgés +Vindicator=Vindicataire +Zombie Villager=Vialatgés Zombia +Witch=Fachinèira +Wither=Le Sechaire +Wolf=Lop +Husk=Zombia Momificat +Zombie=Zombia +Zombie Piglin=Porcadés Zombia +Farmer=Boriaire +Fisherman=Peschaire +Fletcher=Archèir +Shepherd=Bergèir +Librarian=Bibliotecaire +Cartographer=Cartografe +Armorer=Armurèir +Leatherworker=Tanaire +Butcher=Maselèir +Weapon Smith=Farjaire d'Armas +Tool Smith=Farjaire d'Otilhs +Cleric=Clerc +Nitwit=Simple +Cod=Merluça +Salmon=Saumon +Dolphin=Daufin +Pillager=Pilhard +Tropical fish=Peiçon tropicau +Hoglin=Porcard +Strider=Trèva +Glow Squid=Pofre Lusent diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.pt_BR.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.pt_BR.tr new file mode 100644 index 000000000..aa68482c7 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.pt_BR.tr @@ -0,0 +1,83 @@ +# textdomain: mobs_mc +Agent=Agente +Axolotl=Axolote +Bat=Morcego +Blaze=Blaze +Chicken=Galinha +Cow=Vaca +Mooshroom=Coguvaca +Stalker=Stalker +Ender Dragon=Dragão do Fim +Enderman=Enderman +Endermite=Endermite +Ghast=Ghast +Elder Guardian=Guardião Ancião +Guardian=Guardião +Horse=Cavalo +Skeleton Horse=Cavalo Esqueleto +Zombie Horse=Cavalo Zumbi +Donkey=Burro +Mule=Mula +Iron Golem=Golem de Ferro +Llama=Lhama +Ocelot=Jaguatirica +Cat=Gato +Parrot=Papagaio +Pig=Porco +Polar Bear=Urso Polar +Rabbit=Coelho +Killer Bunny=Coelho Assassino +Sheep=Ovelha +Shulker=Shulker +Silverfish=Traça +Skeleton=Esqueleto +Stray=Esqueleto Errante +Wither Skeleton=Esqueleto Wither +Magma Cube=Cubo de Magma +Slime=Slime +Snow Golem=Golem de Neve +Spider=Aranha +Cave Spider=Aranha de Caverna +Squid=Lula +Vex=Vex +Evoker=Invocador +Illusioner=Ilusionista +Villager=Aldeão +Vindicator=Vingador +Zombie Villager=Aldeão Zumbi +Witch=Bruxa +Wither=Wither +Wolf=Lobo +Husk=Zumbi-Múmia +Baby Husk=Zumbi-Múmia Bebê +Zombie=Zumbi +Baby Zombie=Zumbi Bebê +Piglin=Piglin +Baby Piglin=Piglin Bebê +Zombie Piglin=Piglin Zumbi +Baby Zombie Piglin=Piglin Zumbi Bebê +Sword Piglin=Piglin Espadachim +Piglin Brute=Piglin Barbáro +Farmer=Fazendeiro +Fisherman=Pescador +Fletcher=Flecheiro +Shepherd=Pastor +Librarian=Bibliotecário +Cartographer=Cartógrafo +Armorer=Armoreiro +Leatherworker=Coureiro +Butcher=Açougueiro +Weapon Smith=Armeiro +Tool Smith=Ferramenteiro +Cleric=Clérigo +Nitwit=Palerma +Cod=Bacalhau +Salmon=Salmão +Dolphin=Golfinho +Pillager=Saqueador +Tropical fish=Peixe Tropical +Hoglin=Hoglin +Baby hoglin=Hoglin Bebê +Zoglin=Zoglin +Strider=Lavagante +Glow Squid=Lula Brilhante diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr index 62fe69a97..d5ee3b187 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr @@ -1,25 +1,27 @@ # textdomain: mobs_mc Agent=Агент +Axolotl=Аксолотль Bat=Летучая мышь Blaze=Ифрит Chicken=Курица Cow=Корова -Mooshroom=Гриб -Creeper=Крипер -Ender Dragon=Дракон Предела +Mooshroom=Грибная корова +Stalker=Сталкер +Ender Dragon=Дракон Края Enderman=Эндермен Endermite=Эндермит Ghast=Гаст Elder Guardian=Древний страж Guardian=Страж Horse=Лошадь -Skeleton Horse=Скелет лошади -Zombie Horse=Зомби-лошадь +Skeleton Horse=Лошадь-скелет +Zombie Horse=Лошадь-зомби Donkey=Ослик Mule=Мул Iron Golem=Железный голем Llama=Лама Ocelot=Оцелот +Cat=Кошка Parrot=Попугай Pig=Свинья Polar Bear=Полярный медведь @@ -32,13 +34,13 @@ Skeleton=Скелет Stray=Странник Wither Skeleton=Скелет-иссушитель Magma Cube=Лавовый куб -Slime=Слизняк +Slime=Слизень Snow Golem=Снежный голем Spider=Паук Cave Spider=Пещерный паук -Squid=Кальмар +Squid=Спрут Vex=Досаждатель -Evoker=Маг +Evoker=Вызыватель Illusioner=Иллюзор Villager=Житель Vindicator=Поборник @@ -47,8 +49,15 @@ Witch=Ведьма Wither=Иссушитель Wolf=Волк Husk=Кадавр +Baby Husk=Кадавр-ребёнок Zombie=Зомби -Zombie Pigman=Зомби-свиночеловек +Baby Zombie=Зомби-ребёнок +Piglin=Пиглин +Baby Piglin=Пиглин-ребёнок +Zombie Piglin=Зомби-пиглин +Baby Zombie Piglin=Зомби-пиглин-ребёнок +Sword Piglin=Пиглин-мечник +Piglin Brute=Жестокий пиглин Farmer=Фермер Fisherman=Рыбак Fletcher=Лучник @@ -62,3 +71,13 @@ Weapon Smith=Оружейник Tool Smith=Инструментальщик Cleric=Церковник Nitwit=Нищий +Cod=Треска +Salmon=Лосось +Dolphin=Дельфин +Pillager=Разбойник +Tropical fish=Тропическая рыба +Hoglin=Хоглин +Baby hoglin=Детёныш хоглина +Zoglin=Зоглин +Strider=Страйдер +Glow Squid=Светящийся спрут diff --git a/mods/ENTITIES/mobs_mc/locale/template.txt b/mods/ENTITIES/mobs_mc/locale/template.txt index 589a1a3c4..c81e13e41 100644 --- a/mods/ENTITIES/mobs_mc/locale/template.txt +++ b/mods/ENTITIES/mobs_mc/locale/template.txt @@ -6,7 +6,7 @@ Blaze= Chicken= Cow= Mooshroom= -Creeper= +Stalker= Ender Dragon= Enderman= Endermite= @@ -21,6 +21,7 @@ Mule= Iron Golem= Llama= Ocelot= +Cat= Parrot= Pig= Polar Bear= @@ -48,7 +49,9 @@ Witch= Wither= Wolf= Husk= +Baby Husk= Zombie= +Baby Zombie= Piglin= Baby Piglin= Zombie Piglin= @@ -74,5 +77,7 @@ Dolphin= Pillager= Tropical fish= Hoglin= +Baby hoglin= +Zoglin= Strider= -Glow Squid= \ No newline at end of file +Glow Squid= diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index 5b94879b2..ec7446505 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -2,4 +2,4 @@ name = mobs_mc author = maikerumine description = Adds Minecraft-like monsters and animals. depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core, mcl_util -optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items +optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, doc_items, mcl_worlds diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d index cebc037c0..fefc20ecd 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_ghast.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/vl_rover.b3d b/mods/ENTITIES/mobs_mc/models/vl_rover.b3d new file mode 100644 index 000000000..9d9a2809e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/vl_rover.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/vl_stalker.b3d b/mods/ENTITIES/mobs_mc/models/vl_stalker.b3d new file mode 100644 index 000000000..c47edf5b2 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/vl_stalker.b3d differ diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index 65181a581..8f79a589d 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -39,7 +39,7 @@ local ocelot = { head_swivel = "head.control", bone_eye_height = 6.2, head_eye_height = 0.4, - horrizonatal_head_height=-0, + horizontal_head_height=-0, head_yaw="z", curiosity = 4, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3}, @@ -186,7 +186,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -15000, +300, 5, mobs_mc.water_level+15, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index ed2892aca..834ad22ae 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -137,7 +137,7 @@ mcl_mobs.register_mob("mobs_mc:parrot", { xp_max = 3, head_swivel = "head.control", bone_eye_height = 1.1, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 10, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", @@ -235,7 +235,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 7, -30000, +400, 1, mobs_mc.water_level+7, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 9084c5d4d..304c4c800 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -22,7 +22,7 @@ mcl_mobs.register_mob("mobs_mc:pig", { head_swivel = "head.control", bone_eye_height = 7.5, head_eye_height = 0.8, - horrizonatal_head_height=-1, + horizontal_head_height=-1, curiosity = 3, head_yaw="z", makes_footstep_sound = true, @@ -258,7 +258,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -15000, +100, 8, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/piglin.lua b/mods/ENTITIES/mobs_mc/piglin.lua index 4f701b3e9..e81782b1c 100644 --- a/mods/ENTITIES/mobs_mc/piglin.lua +++ b/mods/ENTITIES/mobs_mc/piglin.lua @@ -16,6 +16,13 @@ local trading_items = { { itemstring = "mcl_throwing:ender_pearl", amount_min = 2, amount_max = 6 }, { itemstring = "mcl_potions:fire_resistance", amount_min = 1, amount_max = 1 }, { itemstring = "mcl_potions:fire_resistance_splash", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_enchanting:book_enchanted", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_armor:boots_iron_enchanted", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_blackstone:blackstone", amount_min = 8, amount_max = 16 }, + { itemstring = "mcl_bows:arrow", amount_min = 6, amount_max = 12 }, + { itemstring = "mcl_core:crying_obsidian", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_fire:fire_charge", amount_min = 1, amount_max = 1 }, + --{ itemstring = "FIXME:spectral_arrow", amount_min = 6, amount_max = 12 }, } local S = minetest.get_translator("mobs_mc") @@ -61,8 +68,10 @@ local piglin = { } }, visual_size = {x=1, y=1}, sounds = { - random = "extra_mobs_piglin", - damage = "extra_mobs_piglin_hurt", + random = "mobs_mc_zombiepig_random", + war_cry = "mobs_mc_zombiepig_war_cry", death = "mobs_mc_zombiepig_death", + damage = "mobs_mc_zombiepig_hurt.2", + death = "mobs_mc_zombiepig_death.2", distance = 16, }, jump = true, @@ -140,14 +149,18 @@ local piglin = { local c_pos = self.object:get_pos() if c_pos then self.what_traded = trading_items[math.random(#trading_items)] - for x = 1, math.random(self.what_traded.amount_min, self.what_traded.amount_max) do - local p = c_pos - local nn=minetest.find_nodes_in_area_under_air(vector.offset(c_pos,-1,-1,-1),vector.offset(c_pos,1,1,1),{"group:solid"}) - if nn and #nn > 0 then - p = vector.offset(nn[math.random(#nn)],0,1,0) - end - minetest.add_item(p, self.what_traded.itemstring) + local stack = ItemStack(self.what_traded.itemstring) + stack:set_count(math.random(self.what_traded.amount_min, self.what_traded.amount_max)) + if mcl_enchanting.is_enchanted(self.what_traded.itemstring) then + local enchantment = "soul_speed" + mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(nil, 1, mcl_enchanting.enchantments[enchantment].max_level)) end + local p = c_pos + local nn=minetest.find_nodes_in_area_under_air(vector.offset(c_pos,-1,-1,-1),vector.offset(c_pos,1,1,1),{"group:solid"}) + if nn and #nn > 0 then + p = vector.offset(nn[math.random(#nn)],0,1,0) + end + minetest.add_item(p, stack) end end) end @@ -219,6 +232,10 @@ mcl_mobs.register_mob("mobs_mc:sword_piglin", sword_piglin) -- Zombified Piglin -- +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end + local zombified_piglin = { description = S("Zombie Piglin"), -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked @@ -256,6 +273,7 @@ local zombified_piglin = { }, jump = true, makes_footstep_sound = true, + spawn_check = spawn_check, walk_velocity = .8, run_velocity = 2.6, pathfinding = 1, @@ -325,8 +343,13 @@ mcl_mobs.register_mob("mobs_mc:baby_zombified_piglin", baby_zombified_piglin) -- Compatibility code. These were removed, and now are called zombie piglins. They don't spawn. -- This is only to catch old cases. Maybe could be an alias? -mcl_mobs.register_mob("mobs_mc:pigman", zombified_piglin) -mcl_mobs.register_mob("mobs_mc:baby_pigman", baby_zombified_piglin) +local pigman_unused = table.copy(zombified_piglin) +pigman_unused.unused = true +local baby_pigman_unused = table.copy(baby_zombified_piglin) +baby_pigman_unused.unused = true + +mcl_mobs.register_mob("mobs_mc:pigman", pigman_unused) +mcl_mobs.register_mob("mobs_mc:baby_pigman", baby_pigman_unused) -- Piglin Brute -- @@ -392,7 +415,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -6000, +150, 3, mcl_vars.mg_lava_nether_max, mcl_vars.mg_nether_max) @@ -408,7 +431,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -6000, +150, 3, mcl_vars.mg_lava_nether_max, mcl_vars.mg_nether_max) @@ -424,7 +447,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, - 6000, + 1000, 3, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) @@ -441,7 +464,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, - 100000, + 50, 4, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index d6667a256..aa690bc20 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -27,7 +27,7 @@ mcl_mobs.register_mob("mobs_mc:polar_bear", { head_swivel = "head.control", bone_eye_height = 2.6, head_eye_height = 1, - horrizonatal_head_height = 0, + horizontal_head_height = 0, curiosity = 20, head_yaw="z", visual_size = {x=3.0, y=3.0}, @@ -86,7 +86,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -7000, +50, 3, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 6c4317519..c519e5e7f 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -18,7 +18,7 @@ local rabbit = { head_swivel = "head.control", bone_eye_height = 2, head_eye_height = 0.5, - horrizonatal_head_height = -.3, + horizontal_head_height = -.3, curiosity = 20, head_yaw="z", visual = "mesh", @@ -148,7 +148,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -15000, +40, 8, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/rover.lua similarity index 75% rename from mods/ENTITIES/mobs_mc/enderman.lua rename to mods/ENTITIES/mobs_mc/rover.lua index a57160e4d..d1f21ffd0 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/rover.lua @@ -31,20 +31,9 @@ local place_frequency_min = 235 local place_frequency_max = 245 minetest.register_entity("mobs_mc:ender_eyes", { - visual = "mesh", - mesh = "mobs_mc_spider.b3d", - visual_size = {x=1.01/3, y=1.01/3}, - textures = { - "mobs_mc_enderman_eyes.png", - }, on_step = function(self) - if self and self.object then - if not self.object:get_attach() then - self.object:remove() - end - end + self.object:remove() end, - glow = 50, }) local S = minetest.get_translator("mobs_mc") @@ -66,142 +55,8 @@ end local pr = PseudoRandom(os.time()*(-334)) --- Texuture overrides for enderman block. Required for cactus because it's original is a nodebox --- and the textures have tranparent pixels. -local block_texture_overrides -do - local cbackground = "mobs_mc_enderman_cactus_background.png" - local ctiles = minetest.registered_nodes["mcl_core:cactus"].tiles - - local ctable = {} - local last - for i=1, 6 do - if ctiles[i] then - last = ctiles[i] - end - table.insert(ctable, cbackground .. "^" .. last) - end - - block_texture_overrides = { - ["mcl_core:cactus"] = ctable, - -- FIXME: replace colorize colors with colors from palette - ["mcl_core:dirt_with_grass"] = - { - "mcl_core_grass_block_top.png^[colorize:green:90", - "default_dirt.png", - "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", - "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", - "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)", - "default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)"} - } -end - --- Create the textures table for the enderman, depending on which kind of block --- the enderman holds (if any). -local create_enderman_textures = function(block_type, itemstring) - local base = "mobs_mc_enderman.png^mobs_mc_enderman_eyes.png" - - --[[ Order of the textures in the texture table: - Flower, 90 degrees - Flower, 45 degrees - Held block, backside - Held block, bottom - Held block, front - Held block, left - Held block, right - Held block, top - Enderman texture (base) - ]] - -- Regular cube - if block_type == "cube" then - local tiles = minetest.registered_nodes[itemstring].tiles - local textures = {} - local last - if block_texture_overrides[itemstring] then - -- Texture override available? Use these instead! - textures = block_texture_overrides[itemstring] - else - -- Extract the texture names - for i = 1, 6 do - if type(tiles[i]) == "string" then - last = tiles[i] - elseif type(tiles[i]) == "table" then - if tiles[i].name then - last = tiles[i].name - end - end - table.insert(textures, last) - end - end - return { - "blank.png", - "blank.png", - textures[5], - textures[2], - textures[6], - textures[3], - textures[4], - textures[1], - base, -- Enderman texture - } - -- Node of plantlike drawtype, 45° (recommended) - elseif block_type == "plantlike45" then - local textures = minetest.registered_nodes[itemstring].tiles - return { - "blank.png", - textures[1], - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - base, - } - -- Node of plantlike drawtype, 90° - elseif block_type == "plantlike90" then - local textures = minetest.registered_nodes[itemstring].tiles - return { - textures[1], - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - base, - } - elseif block_type == "unknown" then - return { - "blank.png", - "blank.png", - "unknown_node.png", - "unknown_node.png", - "unknown_node.png", - "unknown_node.png", - "unknown_node.png", - "unknown_node.png", - base, -- Enderman texture - } - -- No block held (for initial texture) - elseif block_type == "nothing" or block_type == nil then - return { - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - "blank.png", - base, -- Enderman texture - } - end -end - -- Select a new animation definition. -local select_enderman_animation = function(animation_type) +local select_rover_animation = function(animation_type) -- Enderman holds a block if animation_type == "block" then return { @@ -254,8 +109,8 @@ local psdefs = {{ texture = "mcl_portals_particle"..math.random(1, 5)..".png", }} -mcl_mobs.register_mob("mobs_mc:enderman", { - description = S("Enderman"), +mcl_mobs.register_mob("mobs_mc:rover", { + description = S("Rover"), type = "monster", spawn_class = "passive", can_despawn = true, @@ -267,23 +122,11 @@ mcl_mobs.register_mob("mobs_mc:enderman", { xp_max = 5, collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3}, visual = "mesh", - mesh = "mobs_mc_enderman.b3d", - textures = create_enderman_textures(), - visual_size = {x=3, y=3}, + mesh = "vl_rover.b3d", + textures = { "vl_mobs_rover.png^vl_mobs_rover_face.png" }, + glow = 100, + visual_size = {x=10, y=10}, makes_footstep_sound = true, - on_spawn = function(self) - local spider_eyes=false - for n = 1, #self.object:get_children() do - local obj = self.object:get_children()[n] - if obj:get_luaentity() and self.object:get_luaentity().name == "mobs_mc:ender_eyes" then - spider_eyes = true - end - end - if not spider_eyes then - minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(0,2.54,-1.99), vector.new(90,0,180)) - minetest.add_entity(self.object:get_pos(), "mobs_mc:ender_eyes"):set_attach(self.object, "head.top", vector.new(1,2.54,-1.99), vector.new(90,0,180)) - end - end, sounds = { -- TODO: Custom war cry sound war_cry = "mobs_sandmonster", @@ -292,8 +135,8 @@ mcl_mobs.register_mob("mobs_mc:enderman", { random = {name="mobs_mc_enderman_random", gain=0.5}, distance = 16, }, - walk_velocity = 0.2, - run_velocity = 3.4, + walk_velocity = 2, + run_velocity = 4, damage = 7, reach = 2, particlespawners = psdefs, @@ -304,7 +147,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", { max = 1, looting = "common"}, }, - animation = select_enderman_animation("normal"), + animation = select_rover_animation("normal"), _taken_node = "", can_spawn = function(pos) return #minetest.find_nodes_in_area(vector.offset(pos,0,1,0),vector.offset(pos,0,3,0),{"air"}) > 2 @@ -348,6 +191,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", { -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. if self.state == "attack" then + self.object:set_properties({textures={"vl_mobs_rover.png^vl_mobs_rover_face_angry.png"}}) if self.attack then local target = self.attack local pos = target:get_pos() @@ -358,6 +202,7 @@ mcl_mobs.register_mob("mobs_mc:enderman", { end end else --if not attacking try to tp to the dark + self.object:set_properties({textures={"vl_mobs_rover.png^vl_mobs_rover_face.png"}}) if dim == 'overworld' then local light = minetest.get_node_light(enderpos) if light and light > minetest.LIGHT_MAX then @@ -489,38 +334,17 @@ mcl_mobs.register_mob("mobs_mc:enderman", { minetest.remove_node(take_pos) local dug = minetest.get_node_or_nil(take_pos) if dug and dug.name == "air" then - self._taken_node = node.name - self.persistent = true - local def = minetest.registered_nodes[self._taken_node] - -- Update animation and texture accordingly (adds visibly carried block) - local block_type - -- Cube-shaped - if def.drawtype == "normal" or - def.drawtype == "nodebox" or - def.drawtype == "liquid" or - def.drawtype == "flowingliquid" or - def.drawtype == "glasslike" or - def.drawtype == "glasslike_framed" or - def.drawtype == "glasslike_framed_optional" or - def.drawtype == "allfaces" or - def.drawtype == "allfaces_optional" or - def.drawtype == nil then - block_type = "cube" - elseif def.drawtype == "plantlike" then - -- Flowers and stuff - block_type = "plantlike45" - elseif def.drawtype == "airlike" then - -- Just air - block_type = nil - else - -- Fallback for complex drawtypes - block_type = "unknown" + local node_obj = vl_held_item.create_item_entity(take_pos, node.name) + if node_obj then + node_obj:set_attach(self.object, "held_node") + self._node_obj = node_obj + self._taken_node = node.name + node_obj:set_properties({visual_size={x=0.02, y=0.02}}) end - self.base_texture = create_enderman_textures(block_type, self._taken_node) - self.object:set_properties({ textures = self.base_texture }) - self.animation = select_enderman_animation("block") + local def = minetest.registered_nodes[self._taken_node] + self.animation = select_rover_animation("block") self:set_animation(self.animation.current) - if def.sounds and def.sounds.dug then + if def and def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true) end end @@ -542,12 +366,14 @@ mcl_mobs.register_mob("mobs_mc:enderman", { local def = minetest.registered_nodes[self._taken_node] -- Update animation accordingly (removes visible block) self.persistent = false - self.animation = select_enderman_animation("normal") + self.animation = select_rover_animation("normal") self:set_animation(self.animation.current) - if def.sounds and def.sounds.place then + if def and def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true) end - self._taken_node = "" + self._node_obj:remove() + self._node_obj = nil + self._taken_node = nil end end end @@ -645,16 +471,41 @@ mcl_mobs.register_mob("mobs_mc:enderman", { --end end end, + after_activate = function(self, staticdata, def, dtime) + if not self._taken_node or self._taken_node == "" then + self.animation = select_rover_animation("normal") + self:set_animation(self.animation.current) + return + end + self.animation = select_rover_animation("block") + self:set_animation(self.animation.current) + local node_obj = vl_held_item.create_item_entity(self.object:get_pos(), self._taken_node) + if node_obj then + node_obj:set_attach(self.object, "held_node") + self._node_obj = node_obj + node_obj:set_properties({visual_size={x=0.02, y=0.02}}) + end + end, armor = { fleshy = 100, water_vulnerable = 100 }, water_damage = 8, view_range = 64, fear_height = 4, attack_type = "dogfight", -}) + _on_after_convert = function(obj) + obj:set_properties({ + mesh = "vl_rover.b3d", + textures = { "vl_mobs_rover.png^vl_mobs_rover_face.png" }, + visual_size = {x=10, y=10}, + }) + end +}) -- END mcl_mobs.register_mob("mobs_mc:rover", { + +-- compat +mcl_mobs.register_conversion("mobs_mc:enderman", "mobs_mc:rover") -- End spawn mcl_mobs:spawn_specific( -"mobs_mc:enderman", +"mobs_mc:rover", "end", "ground", { @@ -668,13 +519,13 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -3000, +100, 12, mcl_vars.mg_end_min, mcl_vars.mg_end_max) -- Overworld spawn mcl_mobs:spawn_specific( -"mobs_mc:enderman", +"mobs_mc:rover", "overworld", "ground", { @@ -816,14 +667,14 @@ mcl_mobs:spawn_specific( 0, 7, 30, -19000, +100, 2, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- Nether spawn (rare) mcl_mobs:spawn_specific( -"mobs_mc:enderman", +"mobs_mc:rover", "nether", "ground", { @@ -833,14 +684,14 @@ mcl_mobs:spawn_specific( 0, 11, 30, -27500, +100, 4, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) -- Warped Forest spawn (common) mcl_mobs:spawn_specific( -"mobs_mc:enderman", +"mobs_mc:rover", "nether", "ground", { @@ -849,10 +700,11 @@ mcl_mobs:spawn_specific( 0, 11, 30, -5000, +100, 4, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) -- spawn eggs -mcl_mobs.register_egg("mobs_mc:enderman", S("Enderman"), "#252525", "#151515", 0) +mcl_mobs.register_egg("mobs_mc:rover", S("Rover"), "#252525", "#151515", 0) +minetest.register_alias("mobs_mc:enderman", "mobs_mc:rover") diff --git a/mods/ENTITIES/mobs_mc/salmon.lua b/mods/ENTITIES/mobs_mc/salmon.lua index f8e0c4e02..47a1a5028 100644 --- a/mods/ENTITIES/mobs_mc/salmon.lua +++ b/mods/ENTITIES/mobs_mc/salmon.lua @@ -10,6 +10,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) --################### local salmon = { + description = S("Salmon"), type = "animal", spawn_class = "water_ambient", can_despawn = true, @@ -220,7 +221,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -4000, +260, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 6eaffa611..e0df5323c 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -67,7 +67,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", { head_swivel = "head.control", bone_eye_height = 3.3, head_eye_height = 1.1, - horrizonatal_head_height=-.7, + horizontal_head_height=-.7, curiosity = 6, head_yaw="z", visual = "mesh", @@ -111,7 +111,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", { run_start = 81, run_end = 121, run_speed = 60, eat_start = 121, eat_start = 161, eat_loop = false, }, - follow = { "mcl_farming:wheat_item" }, + follow = { "mcl_farming:wheat_item", "mcl_shepherd:shepherd_staff" }, view_range = 12, -- Eat grass @@ -234,7 +234,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", { if self:feed_tame(clicker, 1, true, false) then return end if mcl_mobs:protect(self, clicker) then return end - if item:get_name() == "mcl_tools:shears" and not self.gotten and not self.child then + if minetest.get_item_group(item:get_name(), "shears") > 0 and not self.gotten and not self.child then self.gotten = true local pos = self.object:get_pos() minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) @@ -249,6 +249,7 @@ mcl_mobs.register_mob("mobs_mc:sheep", { }) if not minetest.is_creative_enabled(clicker:get_player_name()) then item:add_wear(mobs_mc.shears_wear) + tt.reload_itemstack_description(item) -- update tooltip clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end return @@ -379,7 +380,7 @@ mcl_mobs:spawn_specific( 9, minetest.LIGHT_MAX+1, 30, -15000, +120, 3, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index ecf60debd..78959b717 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -35,7 +35,7 @@ mcl_mobs.register_mob("mobs_mc:shulker", { type = "monster", spawn_class = "hostile", attack_type = "shoot", - shoot_interval = 0.5, + shoot_interval = 6, arrow = "mobs_mc:shulkerbullet", shoot_offset = 0.5, passive = false, @@ -43,7 +43,7 @@ mcl_mobs.register_mob("mobs_mc:shulker", { hp_max = 30, xp_min = 5, xp_max = 5, - armor = 150, + armor = 20, collisionbox = {-0.5, -0.01, -0.5, 0.5, 0.99, 0.5}, visual = "mesh", mesh = "mobs_mc_shulker.b3d", @@ -51,7 +51,7 @@ mcl_mobs.register_mob("mobs_mc:shulker", { -- TODO: sounds -- TODO: Make shulker dye-able visual_size = {x=3, y=3}, - walk_chance = 0, + walk_chance = 10, knock_back = false, jump = false, can_despawn = false, @@ -65,15 +65,19 @@ mcl_mobs.register_mob("mobs_mc:shulker", { looting_factor = 0.0625}, }, animation = { - stand_speed = 25, walk_speed = 0, run_speed = 50, punch_speed = 25, + stand_speed = 25, walk_speed = 25, run_speed = 50, punch_speed = 25, speed_normal = 25, speed_run = 50, stand_start = 0, stand_end = 25, - walk_start = 25, walk_end = 45, - run_start = 45, run_end = 85, + walk_start = 45, walk_end = 65, + walk_loop = false, + run_start = 65, run_end = 85, + run_loop = false, punch_start = 80, punch_end = 100, }, view_range = 16, fear_height = 0, + walk_velocity = 0, + run_velocity = 0, noyaw = true, do_custom = function(self,dtime) local pos = self.object:get_pos() @@ -81,12 +85,13 @@ mcl_mobs.register_mob("mobs_mc:shulker", { self.object:set_yaw(0) mcl_mobs:yaw(self, 0, 0, dtime) end - if self.state == "walk" or self.state == "stand" then - self.state = "stand" - self:set_animation("stand") - end if self.state == "attack" then - self:set_animation("punch") + self:set_animation("run") + self.armor = 0 + elseif self.state == "stand" then + self.armor = 20 + elseif self.state == "walk" or self.state == "run" then + self.armor = 0 end self.path.way = false self.look_at_players = false @@ -149,6 +154,9 @@ mcl_mobs.register_mob("mobs_mc:shulker", { end end end, + on_attack = function(self, dtime) + self.shoot_interval = math.random(1, 6) + end, }) -- bullet arrow (weapon) @@ -156,27 +164,12 @@ mcl_mobs.register_arrow("mobs_mc:shulkerbullet", { visual = "sprite", visual_size = {x = 0.25, y = 0.25}, textures = {"mobs_mc_shulkerbullet.png"}, - velocity = 6, - - hit_player = function(self, player) - player:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = 4}, - }, nil) - end, - - hit_mob = function(self, mob) - mob:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = 4}, - }, nil) - end, - - hit_node = function(self, pos, node) - end + velocity = 5, + homing = true, + hit_player = mcl_mobs.get_arrow_damage_func(4), + hit_mob = mcl_mobs.get_arrow_damage_func(4), }) - mcl_mobs.register_egg("mobs_mc:shulker", S("Shulker"), "#946694", "#4d3852", 0) mcl_mobs:non_spawn_specific("mobs_mc:shulker","overworld",0,minetest.LIGHT_MAX+1) --[[ diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index ab659a2a0..ec8ee19bb 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -4,6 +4,10 @@ local S = minetest.get_translator("mobs_mc") +local function spawn_check(pos, environmental_light, artificial_light, sky_light) + return artificial_light <= 11 +end + mcl_mobs.register_mob("mobs_mc:silverfish", { description = S("Silverfish"), type = "monster", @@ -53,6 +57,7 @@ mcl_mobs.register_mob("mobs_mc:silverfish", { view_range = 16, attack_type = "dogfight", damage = 1, + spawn_check = spawn_check, }) mcl_mobs.register_egg("mobs_mc:silverfish", S("Silverfish"), "#6d6d6d", "#313131", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 215047fdd..8ea4d9ced 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -44,6 +44,13 @@ local skeleton = { "mcl_bows_bow_0.png", -- wielded_item } }, + -- TODO: change random to new api when min minetest version is 5.8 + sounds = { + random = "mobs_mc_skeleton_random.2", + death = "mobs_mc_skeleton_death", + damage = "mobs_mc_skeleton_hurt", + distance = 16, + }, walk_velocity = 1.2, run_velocity = 2.0, damage = 2, @@ -66,7 +73,7 @@ local skeleton = { looting = "common",}, -- Head - -- TODO: Only drop if killed by charged creeper + -- TODO: Only drop if killed by charged stalker {name = "mcl_heads:skeleton", chance = 200, -- 0.5% chance min = 1, @@ -106,7 +113,8 @@ local skeleton = { self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos()))) end local dmg = math.random(2, 4) - mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + local arrow = self.arrow:match("^(.+)_entity$") + mcl_bows.shoot_arrow(arrow, pos, dir, self.object:get_yaw(), self.object, nil, dmg) end end, shoot_interval = 2, @@ -133,10 +141,10 @@ stray.textures = { "mcl_bows_bow_0.png", }, } +stray.arrow = "mcl_potions:frost_arrow_entity" -- TODO: different sound (w/ echo) --- TODO: stray's arrow inflicts slowness status table.insert(stray.drops, { - name = "mcl_potions:slowness_arrow", + name = "mcl_potions:frost_arrow", chance = 2, min = 1, max = 1, @@ -145,13 +153,20 @@ table.insert(stray.drops, { local chance = 0.5 for i = 1, lvl do if chance > 1 then - return 1 + return 1 -- TODO verify this logic, I think this is not how chance works end chance = chance + (1 - chance) / 2 end return chance end, }) +table.insert(stray.drops, { + name = "mcl_mobitems:shiny_ice_crystal", + chance = 3, + min = 1, + max = 2, + looting = "rare", +}) mcl_mobs.register_mob("mobs_mc:stray", stray) @@ -299,7 +314,7 @@ mcl_mobs:spawn_specific( 0, 7, 20, -17000, +800, 2, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) @@ -316,7 +331,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -10000, +800, 3, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) @@ -336,7 +351,7 @@ mcl_mobs:spawn_specific( 0, 7, 20, -19000, +1200, 2, mobs_mc.water_level, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index 314260581..b01fb4b96 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -37,7 +37,7 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", { visual_size = {x=1.2, y=1.2}, makes_footstep_sound = true, sounds = { - random = "mobs_mc_skeleton_random", + random = "mobs_mc_skeleton_random.1", death = "mobs_mc_skeleton_death", damage = "mobs_mc_skeleton_hurt", distance = 16, @@ -96,6 +96,11 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", { fear_height = 4, harmed_by_heal = true, fire_resistant = true, + dealt_effect = { + name = "withering", + level = 1, + dur = 10, + }, }) --spawn @@ -111,7 +116,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -5000, +500, 5, mcl_vars.mg_nether_min, mcl_vars.mg_nether_max) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index c07afb6b1..d56b6e2a2 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -6,6 +6,7 @@ local MAPBLOCK_SIZE = 16 local seed = minetest.get_mapgen_setting("seed") local slime_chunk_match +local slime_chunk_spawn_max = mcl_worlds.layer_to_y(40) local x_modifier local z_modifier @@ -161,9 +162,21 @@ local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed) end end +local swamp_light_max = 7 + +local function slime_spawn_check(pos, environmental_light, artificial_light, sky_light) + local maxlight = swamp_light_max + + if pos.y <= slime_chunk_spawn_max and is_slime_chunk(pos) then + maxlight = minetest.LIGHT_MAX + 1 + end + + return math.max(artificial_light, sky_light) <= maxlight +end + -- Slime local slime_big = { - description = S("Slime"), + description = S("Slime - big"), type = "monster", spawn_class = "hostile", group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" }, @@ -171,7 +184,7 @@ local slime_big = { hp_max = 16, xp_min = 4, xp_max = 4, - collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, + collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02, rotate = true}, visual_size = {x=12.5, y=12.5}, textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}}, visual = "mesh", @@ -185,7 +198,7 @@ local slime_big = { distance = 16, }, damage = 4, - reach = 3, + reach = 2.5, armor = 100, drops = {}, -- TODO: Fix animations @@ -213,19 +226,21 @@ local slime_big = { spawn_small_alternative = "mobs_mc:slime_small", on_die = spawn_children_on_die("mobs_mc:slime_small", 1.0, 1.5), use_texture_alpha = true, + spawn_check = slime_spawn_check, } mcl_mobs.register_mob("mobs_mc:slime_big", slime_big) local slime_small = table.copy(slime_big) +slime_small.description = S("Slime - small") slime_small.sounds.base_pitch = 1.15 slime_small.hp_min = 4 slime_small.hp_max = 4 slime_small.xp_min = 2 slime_small.xp_max = 2 -slime_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51} +slime_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51, rotate = true} slime_small.visual_size = {x=6.25, y=6.25} slime_small.damage = 3 -slime_small.reach = 2.75 +slime_small.reach = 2.25 slime_small.walk_velocity = 1.8 slime_small.run_velocity = 1.8 slime_small.jump_height = 4.3 @@ -234,15 +249,16 @@ slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 0.6, 1.0) mcl_mobs.register_mob("mobs_mc:slime_small", slime_small) local slime_tiny = table.copy(slime_big) +slime_tiny.description = S("Slime - tiny") slime_tiny.sounds.base_pitch = 1.3 slime_tiny.hp_min = 1 slime_tiny.hp_max = 1 slime_tiny.xp_min = 1 slime_tiny.xp_max = 1 -slime_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505} +slime_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505, rotate = true} slime_tiny.visual_size = {x=3.125, y=3.125} -slime_tiny.damage = 0 -slime_tiny.reach = 2.5 +slime_tiny.damage = 1 +slime_tiny.reach = 2 slime_tiny.drops = { -- slimeball {name = "mcl_mobitems:slimeball", @@ -297,7 +313,6 @@ local cave_min = mcl_vars.mg_overworld_min local cave_max = water_level - 23 local swampy_biomes = {"Swampland", "MangroveSwamp"} -local swamp_light_max = 7 local swamp_min = water_level local swamp_max = water_level + 27 @@ -309,7 +324,7 @@ cave_biomes, 0, minetest.LIGHT_MAX+1, 30, -12000, +1000, 4, cave_min, cave_max, @@ -323,7 +338,7 @@ swampy_biomes, 0, swamp_light_max, 30, -12000, +1000, 4, swamp_min, swamp_max) @@ -336,7 +351,7 @@ cave_biomes, 0, minetest.LIGHT_MAX+1, 30, -8500, +1000, 4, cave_min, cave_max, @@ -350,7 +365,7 @@ swampy_biomes, 0, swamp_light_max, 30, -8500, +1000, 4, swamp_min, swamp_max) @@ -363,7 +378,7 @@ cave_biomes, 0, minetest.LIGHT_MAX+1, 30, -10000, +1000, 4, cave_min, cave_max, @@ -377,21 +392,21 @@ swampy_biomes, 0, swamp_light_max, 30, -10000, +1000, 4, swamp_min, swamp_max) -- Magma cube local magma_cube_big = { - description = S("Magma Cube"), + description = S("Magma Cube - big"), type = "monster", spawn_class = "hostile", hp_min = 16, hp_max = 16, xp_min = 4, xp_max = 4, - collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, + collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02, rotate = true}, visual_size = {x=12.5, y=12.5}, textures = {{ "mobs_mc_magmacube.png", "mobs_mc_magmacube.png" }}, visual = "mesh", @@ -406,7 +421,7 @@ local magma_cube_big = { walk_velocity = 2.5, run_velocity = 2.5, damage = 6, - reach = 3, + reach = 2.35, armor = 53, drops = { {name = "mcl_mobitems:magma_cream", @@ -445,16 +460,17 @@ local magma_cube_big = { mcl_mobs.register_mob("mobs_mc:magma_cube_big", magma_cube_big) local magma_cube_small = table.copy(magma_cube_big) +magma_cube_small.description = S("Magma Cube - small") magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small" magma_cube_small.sounds.death = "mobs_mc_magma_cube_small" magma_cube_small.hp_min = 4 magma_cube_small.hp_max = 4 magma_cube_small.xp_min = 2 magma_cube_small.xp_max = 2 -magma_cube_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51} +magma_cube_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51, rotate = true} magma_cube_small.visual_size = {x=6.25, y=6.25} magma_cube_small.damage = 3 -magma_cube_small.reach = 2.75 +magma_cube_small.reach = 2.1 magma_cube_small.walk_velocity = .8 magma_cube_small.run_velocity = 2.0 magma_cube_small.jump_height = 6 @@ -466,6 +482,7 @@ magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 0.6, mcl_mobs.register_mob("mobs_mc:magma_cube_small", magma_cube_small) local magma_cube_tiny = table.copy(magma_cube_big) +magma_cube_tiny.description = S("Magma Cube - tiny") magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small" magma_cube_tiny.sounds.death = "mobs_mc_magma_cube_small" magma_cube_tiny.sounds.base_pitch = 1.25 @@ -473,13 +490,13 @@ magma_cube_tiny.hp_min = 1 magma_cube_tiny.hp_max = 1 magma_cube_tiny.xp_min = 1 magma_cube_tiny.xp_max = 1 -magma_cube_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505} +magma_cube_tiny.collisionbox = {-0.2505, -0.01, -0.2505, 0.2505, 0.50, 0.2505, rotate = true} magma_cube_tiny.visual_size = {x=3.125, y=3.125} magma_cube_tiny.walk_velocity = 1.02 magma_cube_tiny.run_velocity = 1.02 magma_cube_tiny.jump_height = 4 magma_cube_tiny.damage = 3 -magma_cube_tiny.reach = 2.5 +magma_cube_tiny.reach = 2 magma_cube_tiny.armor = 50 magma_cube_tiny.drops = {} magma_cube_tiny.spawn_small_alternative = nil @@ -500,7 +517,7 @@ magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, -15000, +100, 4, nether_min, nether_max) @@ -513,7 +530,7 @@ magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, -15500, +100, 4, nether_min, nether_max) @@ -526,7 +543,7 @@ magma_cube_biomes, 0, minetest.LIGHT_MAX+1, 30, -16000, +100, 4, nether_min, nether_max) diff --git a/mods/ENTITIES/mobs_mc/snowman.lua b/mods/ENTITIES/mobs_mc/snowman.lua index ec2a14675..595c7d63e 100644 --- a/mods/ENTITIES/mobs_mc/snowman.lua +++ b/mods/ENTITIES/mobs_mc/snowman.lua @@ -114,7 +114,7 @@ mcl_mobs.register_mob("mobs_mc:snowman", { -- Remove pumpkin if using shears on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if self.gotten ~= true and item:get_name() == "mcl_tools:shears" then + if self.gotten ~= true and minetest.get_item_group(item:get_name(), "shears") > 0 then -- Remove pumpkin self.gotten = true self.object:set_properties({ @@ -131,6 +131,7 @@ mcl_mobs.register_mob("mobs_mc:snowman", { -- Wear out if not minetest.is_creative_enabled(clicker:get_player_name()) then item:add_wear(mobs_mc.shears_wear) + tt.reload_itemstack_description(item) -- update tooltip clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end end diff --git a/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.1.ogg b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.1.ogg new file mode 100644 index 000000000..5bc9a18ee Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.2.ogg b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.2.ogg new file mode 100644 index 000000000..552d27c5f Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin_hurt.ogg new file mode 100644 index 000000000..7c74f8fb3 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/extra_mobs_hoglin_hurt.ogg differ diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 65d3a2d21..d01c7afbe 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -114,9 +114,7 @@ mcl_mobs.register_mob("mobs_mc:spider", spider) local cave_spider = table.copy(spider) cave_spider.description = S("Cave Spider") cave_spider.textures = { {"mobs_mc_cave_spider.png^(mobs_mc_spider_eyes.png^[makealpha:0,0,0)"} } --- TODO: Poison damage --- TODO: Revert damage to 2 -cave_spider.damage = 3 -- damage increased to undo non-existing poison +cave_spider.damage = 2 cave_spider.hp_min = 1 cave_spider.hp_max = 12 cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.46, 0.35} @@ -138,6 +136,11 @@ cave_spider.walk_velocity = 1.3 cave_spider.run_velocity = 3.2 cave_spider.sounds = table.copy(spider.sounds) cave_spider.sounds.base_pitch = 1.25 +cave_spider.dealt_effect = { + name = "poison", + level = 2, + dur = 7, +} mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider) @@ -284,7 +287,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -17000, +1000, 2, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index a692fd8d4..0cd0c6c5a 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -211,7 +211,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -5500, +80, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/stalker.lua similarity index 70% rename from mods/ENTITIES/mobs_mc/creeper.lua rename to mods/ENTITIES/mobs_mc/stalker.lua index f751b1240..962fbdea9 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/stalker.lua @@ -3,14 +3,60 @@ local S = minetest.get_translator("mobs_mc") --################### ---################### CREEPER +--################### STALKER --################### +local function get_texture(self) + local on_name = self.standing_on + local texture + local texture_suff = "" + if on_name and on_name ~= "air" then + local tiles = minetest.registered_nodes[on_name].tiles + if tiles then + local tile = tiles[1] + local color + if type(tile) == "table" then + texture = tile.name or tile.image + if tile.color then + color = minetest.colorspec_to_colorstring(tile.color) + end + elseif type(tile) == "string" then + texture = tile + end + if not color then + color = minetest.colorspec_to_colorstring(minetest.registered_nodes[on_name].color) + end + if color then + texture_suff = "^[multiply:" .. color .. "^[hsl:0:0:20" + end + end + end + if not texture or texture == "" then + texture = "vl_stalker_default.png" + end + texture = texture:gsub("([\\^:\\[])","\\%1") -- escape texture modifiers + texture = "([combine:16x24:0,0=(" .. texture .. "):0,16=(" .. texture ..")".. texture_suff + if self.attack then + texture = texture .. ")^vl_mobs_stalker_overlay_angry.png" + else + texture = texture .. ")^vl_mobs_stalker_overlay.png" + end + return texture +end + +local AURA = "vl_stalker_overloaded_aura.png" +local function get_overloaded_aura(timer) + local frame = math.floor(timer*16) + local f = tostring(frame) + local nf = tostring(16-f) + return "[combine:16x24:-" .. nf ..",0=" .. AURA .. ":" .. f .. ",0=" .. AURA +end -mcl_mobs.register_mob("mobs_mc:creeper", { - description = S("Creeper"), + +mcl_mobs.register_mob("mobs_mc:stalker", { + description = S("Stalker"), type = "monster", spawn_class = "hostile", spawn_in_group = 1, @@ -21,15 +67,16 @@ mcl_mobs.register_mob("mobs_mc:creeper", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3}, pathfinding = 1, visual = "mesh", - mesh = "mobs_mc_creeper.b3d", - head_swivel = "Head_Control", + mesh = "vl_stalker.b3d", +-- head_swivel = "Head_Control", bone_eye_height = 2.35, + head_eye_height = 1.8; curiosity = 2, textures = { - {"mobs_mc_creeper.png", + {get_texture({}), "mobs_mc_empty.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=2, y=2}, sounds = { attack = "tnt_ignite", death = "mobs_mc_creeper_death", @@ -49,14 +96,14 @@ mcl_mobs.register_mob("mobs_mc:creeper", { explosion_strength = 3, explosion_radius = 3.5, explosion_damage_radius = 3.5, - explosiontimer_reset_radius = 6, + explosiontimer_reset_radius = 3, reach = 3, explosion_timer = 1.5, allow_fuse_reset = true, stop_to_explode = true, - -- Force-ignite creeper with flint and steel and explode after 1.5 seconds. - -- TODO: Make creeper flash after doing this as well. + -- Force-ignite stalker with flint and steel and explode after 1.5 seconds. + -- TODO: Make stalker flash after doing this as well. -- TODO: Test and debug this code. on_rightclick = function(self, clicker) if self._forced_explosion_countdown_timer ~= nil then @@ -85,6 +132,11 @@ mcl_mobs.register_mob("mobs_mc:creeper", { self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) end end + local new_texture = get_texture(self) + if self._stalker_texture ~= new_texture then + self.object:set_properties({textures={new_texture, "mobs_mc_empty.png"}}) + self._stalker_texture = new_texture + end end, on_die = function(self, pos, cmi_cause) -- Drop a random music disc when killed by skeleton or stray @@ -107,35 +159,42 @@ mcl_mobs.register_mob("mobs_mc:creeper", { looting = "common",}, -- Head - -- TODO: Only drop if killed by charged creeper - {name = "mcl_heads:creeper", + -- TODO: Only drop if killed by charged stalker + {name = "mcl_heads:stalker", chance = 200, -- 0.5% min = 1, max = 1,}, }, animation = { - speed_normal = 24, - speed_run = 48, + speed_normal = 30, + speed_run = 60, stand_start = 0, stand_end = 23, walk_start = 24, walk_end = 49, run_start = 24, run_end = 49, - hurt_start = 110, - hurt_end = 139, - death_start = 140, - death_end = 189, - look_start = 50, - look_end = 108, + fuse_start = 49, + fuse_end = 80, }, floats = 1, fear_height = 4, view_range = 16, -}) -mcl_mobs.register_mob("mobs_mc:creeper_charged", { - description = S("Creeper"), + _on_after_convert = function(obj) + obj:set_properties({ + visual_size = {x=2, y=2}, + mesh = "vl_stalker.b3d", + textures = { + {get_texture({}), + "mobs_mc_empty.png"}, + }, + }) + end, +}) -- END mcl_mobs.register_mob("mobs_mc:stalker", { + +mcl_mobs.register_mob("mobs_mc:stalker_overloaded", { + description = S("Overloaded Stalker"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -145,15 +204,16 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3}, pathfinding = 1, visual = "mesh", - mesh = "mobs_mc_creeper.b3d", + mesh = "vl_stalker.b3d", --BOOM textures = { - {"mobs_mc_creeper.png", - "mobs_mc_creeper_charge.png"}, + {get_texture({}), + AURA}, }, - visual_size = {x=3, y=3}, + use_texture_alpha = true, + visual_size = {x=2, y=2}, sounds = { attack = "tnt_ignite", death = "mobs_mc_creeper_death", @@ -171,14 +231,14 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { explosion_strength = 6, explosion_radius = 8, explosion_damage_radius = 8, - explosiontimer_reset_radius = 6, + explosiontimer_reset_radius = 3, reach = 3, explosion_timer = 1.5, allow_fuse_reset = true, stop_to_explode = true, - -- Force-ignite creeper with flint and steel and explode after 1.5 seconds. - -- TODO: Make creeper flash after doing this as well. + -- Force-ignite stalker with flint and steel and explode after 1.5 seconds. + -- TODO: Make stalker flash after doing this as well. -- TODO: Test and debug this code. on_rightclick = function(self, clicker) if self._forced_explosion_countdown_timer ~= nil then @@ -207,6 +267,9 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) end end + if not self._aura_timer or self._aura_timer > 1 then self._aura_timer = 0 end + self._aura_timer = self._aura_timer + dtime + self.object:set_properties({textures={get_texture(self), get_overloaded_aura(self._aura_timer)}}) end, on_die = function(self, pos, cmi_cause) -- Drop a random music disc when killed by skeleton or stray @@ -221,7 +284,7 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { end end, on_lightning_strike = function(self, pos, pos2, objects) - mcl_util.replace_mob(self.object, "mobs_mc:creeper_charged") + mcl_util.replace_mob(self.object, "mobs_mc:stalker_overloaded") return true end, maxdrops = 2, @@ -233,27 +296,23 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { looting = "common",}, -- Head - -- TODO: Only drop if killed by charged creeper - {name = "mcl_heads:creeper", + -- TODO: Only drop if killed by overloaded stalker + {name = "mcl_heads:stalker", chance = 200, -- 0.5% min = 1, max = 1,}, }, animation = { - speed_normal = 24, - speed_run = 48, + speed_normal = 30, + speed_run = 60, stand_start = 0, stand_end = 23, walk_start = 24, walk_end = 49, run_start = 24, run_end = 49, - hurt_start = 110, - hurt_end = 139, - death_start = 140, - death_end = 189, - look_start = 50, - look_end = 108, + fuse_start = 49, + fuse_end = 80, }, floats = 1, fear_height = 4, @@ -261,10 +320,25 @@ mcl_mobs.register_mob("mobs_mc:creeper_charged", { --Having trouble when fire is placed with lightning fire_resistant = true, glow = 3, -}) + + _on_after_convert = function(obj) + obj:set_properties({ + visual_size = {x=2, y=2}, + mesh = "vl_stalker.b3d", + textures = { + {get_texture({}), + AURA}, + }, + }) + end, +}) -- END mcl_mobs.register_mob("mobs_mc:stalker_overloaded", { + +-- compat +mcl_mobs.register_conversion("mobs_mc:creeper", "mobs_mc:stalker") +mcl_mobs.register_conversion("mobs_mc:creeper_charged", "mobs_mc:stalker_overloaded") mcl_mobs:spawn_specific( -"mobs_mc:creeper", +"mobs_mc:stalker", "overworld", "ground", { @@ -406,10 +480,12 @@ mcl_mobs:spawn_specific( 0, 7, 20, -16500, +1000, 2, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mcl_mobs.register_egg("mobs_mc:creeper", S("Creeper"), "#0da70a", "#000000", 0) +mcl_mobs.register_egg("mobs_mc:stalker", S("Stalker"), "#0da70a", "#000000", 0) +minetest.register_alias("mobs_mc:creeper", "mobs_mc:stalker") +mcl_mobs.register_egg("mobs_mc:stalker_overloaded", S("Overloaded Stalker"), "#00a77a", "#000000", 0) diff --git a/mods/ENTITIES/mobs_mc/strider.lua b/mods/ENTITIES/mobs_mc/strider.lua index 142025e06..ea4fc393f 100644 --- a/mods/ENTITIES/mobs_mc/strider.lua +++ b/mods/ENTITIES/mobs_mc/strider.lua @@ -11,6 +11,7 @@ local S = minetest.get_translator("mobs_mc") local strider = { + description = S("Strider"), type = "animal", passive = true, spawn_class = "passive", @@ -30,6 +31,8 @@ local strider = { } }, visual_size = {x=3, y=3}, sounds = { + eat = "mobs_mc_animal_eat_generic", + distance = 16, }, jump = true, makes_footstep_sound = true, @@ -51,6 +54,7 @@ local strider = { walk_start = 1, walk_end = 20, }, + follow = { "mcl_crimson:warped_fungus" }, lava_damage = 0, fire_damage = 0, light_damage = 0, @@ -67,8 +71,13 @@ local strider = { do_custom = function(self, dtime) if minetest.find_node_near(self.object:get_pos(), 2, {"mcl_core:lava_source","mcl_core:lava_flowing","mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) then - self.walk_velocity = 2 - self.run_velocity = 4 + if self.driver then + self.walk_velocity = 4 + self.run_velocity = 8 + else + self.walk_velocity = 2 + self.run_velocity = 4 + end self.base_texture[1] = "extra_mobs_strider.png" self.shaking = false else @@ -122,7 +131,7 @@ local strider = { local wielditem = clicker:get_wielded_item() - if wielditem:get_name() ~= "mcl_crimson:warped_fungus" then + if wielditem:get_name() == "mcl_crimson:warped_fungus" then if self:feed_tame(clicker, 1, true, true) then return end end @@ -197,6 +206,7 @@ mcl_mobs.register_mob("mobs_mc:strider", strider) -- Baby strider. local baby_strider = table.copy(strider) +baby_strider.description = S("Baby Strider") baby_strider.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3} baby_strider.xp_min = 13 baby_strider.xp_max = 13 @@ -206,7 +216,7 @@ textures = { { } } baby_strider.walk_velocity = 1.2 baby_strider.run_velocity = 2.4 -baby_strider.child = 1 +baby_strider.child = true mcl_mobs.register_mob("mobs_mc:baby_strider", baby_strider) @@ -225,7 +235,7 @@ mcl_mobs:spawn_setup({ }, min_height = mcl_vars.mg_nether_min, max_height = mcl_vars.mg_nether_max, - chance = 2000, + chance = 200, }) mcl_mobs:spawn_setup({ @@ -241,7 +251,7 @@ mcl_mobs:spawn_setup({ }, min_height = mcl_vars.mg_nether_min, max_height = mcl_vars.mg_nether_max, - chance = 100, + chance = 20, }) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/tropical_fish.lua b/mods/ENTITIES/mobs_mc/tropical_fish.lua index 79b32bb8b..6f0c4b43b 100644 --- a/mods/ENTITIES/mobs_mc/tropical_fish.lua +++ b/mods/ENTITIES/mobs_mc/tropical_fish.lua @@ -58,6 +58,7 @@ local function set_textures(self) end local tropical_fish = { + description = S("Tropical Fish"), type = "animal", spawn_class = "water_ambient", can_despawn = true, @@ -183,7 +184,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -4000, +750, 3, water-16, water+1) diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua index fbb33804d..cedbc59ad 100644 --- a/mods/ENTITIES/mobs_mc/vex.lua +++ b/mods/ENTITIES/mobs_mc/vex.lua @@ -37,6 +37,7 @@ mcl_mobs.register_mob("mobs_mc:vex", { walk_velocity = 3.2, run_velocity = 5.9, attack_type = "dogfight", + attack_frequency = 2, sounds = { -- TODO: random death = "mobs_mc_vex_death", @@ -63,10 +64,13 @@ mcl_mobs.register_mob("mobs_mc:vex", { self.object:set_properties({textures=self.base_texture}) end else + if self.base_texture[2] == "mobs_mc_vex_charging.png" then + self.base_texture[2] = "mobs_mc_vex.png" + end if self.base_texture[1] ~= "default_tool_steelsword.png" then self.base_texture[1] = "default_tool_steelsword.png" - self.object:set_properties({textures=self.base_texture}) end + self.object:set_properties({textures=self.base_texture}) end -- Take constant damage if the vex' life clock ran out diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 8fc18ccab..b1e291037 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -101,28 +101,32 @@ local professions = { jobsite = "mcl_composters:composter", trades = { { - { { "mcl_farming:wheat_item", 18, 22, }, E1 }, - { { "mcl_farming:potato_item", 15, 19, }, E1 }, - { { "mcl_farming:carrot_item", 15, 19, }, E1 }, - { E1, { "mcl_farming:bread", 2, 4 } }, + { { "mcl_farming:wheat_item", 20, 20, }, E1 }, + { { "mcl_farming:potato_item", 26, 26, }, E1 }, + { { "mcl_farming:carrot_item", 22, 22, }, E1 }, + { { "mcl_farming:beetroot_item", 15, 15 }, E1 }, + { E1, { "mcl_farming:bread", 6, 6 } }, }, { - { { "mcl_farming:pumpkin", 6, 7 }, E1 }, - { E1, { "mcl_farming:pumpkin_pie", 2, 3} }, - { E1, { "mcl_core:apple", 2, 3} }, + { { "mcl_farming:pumpkin", 6, 6 }, E1 }, + { E1, { "mcl_farming:pumpkin_pie", 4, 4 } }, + { E1, { "mcl_core:apple", 4, 4 } }, }, { - { { "mcl_farming:melon", 7, 12 }, E1 }, - { E1, {"mcl_farming:cookie", 5, 7 }, }, + { { "mcl_farming:melon", 4, 4 }, E1 }, + { { "mcl_core:emerald", 3, 3 }, {"mcl_farming:cookie", 18, 18 }, }, }, + { + { E1, { "mcl_cake:cake", 1, 1 } }, { E1, { "mcl_mushrooms:mushroom_stew", 6, 10 } }, --FIXME: expert level farmer is supposed to sell sus stews. }, + { - { E1, { "mcl_farming:carrot_item_gold", 3, 10 } }, - { E1, { "mcl_potions:speckled_melon", 1, 4 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_farming:carrot_item_gold", 3, 3 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_potions:speckled_melon", 3, 3 } }, TRADE_V6_BIRCH_SAPLING, TRADE_V6_DARK_OAK_SAPLING, TRADE_V6_ACACIA_SAPLING, @@ -135,31 +139,36 @@ local professions = { jobsite = "mcl_barrels:barrel_closed", trades = { { - { { "mcl_fishing:fish_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:fish_cooked", 6, 6 } }, - { { "mcl_mobitems:string", 15, 20 }, E1 }, - { { "mcl_core:coal_lump", 10, 15 }, E1 }, - -- FIXME missing: bucket of cod + fish should be cod. + { { "mcl_mobitems:string", 20, 20 }, E1 }, + { { "mcl_core:coal_lump", 10, 10 }, E1 }, + { { "mcl_core:emerald", 1, 1, "mcl_fishing:fish_raw", 6, 6 }, { "mcl_fishing:fish_cooked", 6, 6 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_buckets:bucket_cod", 1, 1 } }, }, - { - { { "mcl_fishing:fish_raw", 6, 15,}, E1 }, - { { "mcl_fishing:salmon_raw", 6, 6, "mcl_core:emerald", 1, 1 },{ "mcl_fishing:salmon_cooked", 6, 6 } }, - { { "mcl_core:emerald", 1, 2 },{"mcl_campfires:campfire_lit",1,1} }, - }, - { - { { "mcl_fishing:salmon_raw", 6, 13,}, E1 }, - { { "mcl_core:emerald", 7, 22 }, { "mcl_fishing:fishing_rod_enchanted", 1, 1} }, - }, - { - { { "mcl_fishing:clownfish_raw", 6, 6,}, E1 }, - }, - { - { { "mcl_fishing:pufferfish_raw", 4, 4,}, E1 }, - { { "mcl_boats:boat", 1, 1,}, E1 }, - { { "mcl_boats:boat_acacia", 1, 1,}, E1 }, - { { "mcl_boats:boat_spruce", 1, 1,}, E1 }, - { { "mcl_boats:boat_dark_oak", 1, 1,}, E1 }, - { { "mcl_boats:boat_birch", 1, 1,}, E1 }, + { + { { "mcl_fishing:fish_raw", 15, 15 }, E1 }, + { { "mcl_core:emerald", 1, 1, "mcl_fishing:salmon_raw", 6, 6 }, { "mcl_fishing:salmon_cooked", 6, 6 } }, + { { "mcl_core:emerald", 2, 2 }, {"mcl_campfires:campfire_lit", 1, 1 } }, + }, + + { + { { "mcl_fishing:salmon_raw", 13, 13 }, E1 }, + { { "mcl_core:emerald", 8, 22 }, { "mcl_fishing:fishing_rod_enchanted", 1, 1 } }, + }, + + { + { { "mcl_fishing:clownfish_raw", 6, 6 }, E1 }, + }, + + { + { { "mcl_fishing:pufferfish_raw", 4, 4 }, E1 }, + + --Boat cherry? + { { "mcl_boats:boat", 1, 1 }, E1 }, + { { "mcl_boats:boat_acacia", 1, 1 }, E1 }, + { { "mcl_boats:boat_spruce", 1, 1 }, E1 }, + { { "mcl_boats:boat_dark_oak", 1, 1 }, E1 }, + { { "mcl_boats:boat_birch", 1, 1 }, E1 }, }, }, }, @@ -169,25 +178,28 @@ local professions = { jobsite = "mcl_fletching_table:fletching_table", trades = { { - { { "mcl_mobitems:string", 15, 20 }, E1 }, - { E1, { "mcl_bows:arrow", 8, 12 } }, - { { "mcl_core:gravel", 10, 10, "mcl_core:emerald", 1, 1 }, { "mcl_core:flint", 6, 10 } }, { { "mcl_core:stick", 32, 32 }, E1 }, + { E1, { "mcl_bows:arrow", 16, 16 } }, + { { "mcl_core:emerald", 1, 1, "mcl_core:gravel", 10, 10 }, { "mcl_core:flint", 10, 10 } }, }, + { { { "mcl_core:flint", 26, 26 }, E1 }, - { { "mcl_core:emerald", 2, 3 }, { "mcl_bows:bow", 1, 1 } }, + { { "mcl_core:emerald", 2, 2 }, { "mcl_bows:bow", 1, 1 } }, }, + { { { "mcl_mobitems:string", 14, 14 }, E1 }, { { "mcl_core:emerald", 3, 3 }, { "mcl_bows:crossbow", 1, 1 } }, }, + { - { { "mcl_mobitems:string", 24, 24 }, E1 }, + { { "mcl_mobitems:feather", 24, 24 }, E1 }, { { "mcl_core:emerald", 7, 21 } , { "mcl_bows:bow_enchanted", 1, 1 } }, }, + { - --FIXME: supposed to be tripwire hook{ { "tripwirehook", 24, 24 }, E1 }, + --FIXME: supposed to be tripwire hook{ { "tripwirehook", 8, 8 }, E1 }, { { "mcl_core:emerald", 8, 22 } , { "mcl_bows:crossbow_enchanted", 1, 1 } }, { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:healing_arrow", 5, 5 } }, { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:harming_arrow", 5, 5 } }, @@ -209,27 +221,108 @@ local professions = { jobsite = "mcl_loom:loom", trades = { { - { { "mcl_wool:white", 16, 22 }, E1 }, - { { "mcl_core:emerald", 3, 4 }, { "mcl_tools:shears", 1, 1 } }, + { { "mcl_wool:white", 18, 18 }, E1 }, + { { "mcl_wool:brown", 18, 18 }, E1 }, + { { "mcl_wool:black", 18, 18 }, E1 }, + { { "mcl_wool:grey", 18, 18 }, E1 }, + { { "mcl_core:emerald", 2, 2 }, { "mcl_tools:shears", 1, 1 } }, }, { - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:white", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:grey", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:silver", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:black", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:yellow", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:orange", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:red", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:magenta", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:purple", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:blue", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:cyan", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:lime", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:green", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:pink", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:light_blue", 1, 1 } }, - { { "mcl_core:emerald", 1, 2 }, { "mcl_wool:brown", 1, 1 } }, + { { "mcl_dye:black", 12, 12 }, E1 }, + { { "mcl_dye:dark_grey", 12, 12 }, E1 }, + { { "mcl_dye:green", 12, 12 }, E1 }, + { { "mcl_dye:lightblue", 12, 12 }, E1 }, + { { "mcl_dye:white", 12, 12 }, E1 }, + + { E1, { "mcl_wool:white", 1, 1 } }, + { E1, { "mcl_wool:grey", 1, 1 } }, + { E1, { "mcl_wool:silver", 1, 1 } }, + { E1, { "mcl_wool:black", 1, 1 } }, + { E1, { "mcl_wool:yellow", 1, 1 } }, + { E1, { "mcl_wool:orange", 1, 1 } }, + { E1, { "mcl_wool:red", 1, 1 } }, + { E1, { "mcl_wool:magenta", 1, 1 } }, + { E1, { "mcl_wool:purple", 1, 1 } }, + { E1, { "mcl_wool:blue", 1, 1 } }, + { E1, { "mcl_wool:cyan", 1, 1 } }, + { E1, { "mcl_wool:lime", 1, 1 } }, + { E1, { "mcl_wool:green", 1, 1 } }, + { E1, { "mcl_wool:pink", 1, 1 } }, + { E1, { "mcl_wool:light_blue", 1, 1 } }, + { E1, { "mcl_wool:brown", 1, 1 } }, + + { E1, { "mcl_wool:white_carpet", 4, 4 } }, + { E1, { "mcl_wool:grey_carpet", 4, 4 } }, + { E1, { "mcl_wool:silver_carpet", 4, 4 } }, + { E1, { "mcl_wool:black_carpet", 4, 4 } }, + { E1, { "mcl_wool:yellow_carpet", 4, 4 } }, + { E1, { "mcl_wool:orange_carpet", 4, 4 } }, + { E1, { "mcl_wool:red_carpet", 4, 4 } }, + { E1, { "mcl_wool:magenta_carpet", 4, 4 } }, + { E1, { "mcl_wool:purple_carpet", 4, 4 } }, + { E1, { "mcl_wool:blue_carpet", 4, 4 } }, + { E1, { "mcl_wool:cyan_carpet", 4, 4 } }, + { E1, { "mcl_wool:lime_carpet", 4, 4 } }, + { E1, { "mcl_wool:green_carpet", 4, 4 } }, + { E1, { "mcl_wool:pink_carpet", 4, 4 } }, + { E1, { "mcl_wool:light_blue_carpet", 4, 4 } }, + { E1, { "mcl_wool:brown_carpet", 4, 4 } }, + }, + + { + { { "mcl_dye:red", 12, 12 }, E1 }, + { { "mcl_dye:grey", 12, 12 }, E1 }, + { { "mcl_dye:pink", 12, 12 }, E1 }, + { { "mcl_dye:yellow", 12, 12 }, E1 }, + { { "mcl_dye:orange", 12, 12 }, E1 }, + + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_red_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_blue_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_cyan_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_grey_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_silver_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_black_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_yellow_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_green_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_magenta_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_orange_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_purple_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_brown_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_pink_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_lime_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_light_blue_bottom", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_beds:bed_white_bottom", 1, 1 } }, + }, + + { + { { "mcl_dye:dark_green", 12, 12 }, E1 }, + { { "mcl_dye:brown", 12, 12 }, E1 }, + { { "mcl_dye:blue", 12, 12 }, E1 }, + { { "mcl_dye:violet", 12, 12 }, E1 }, + { { "mcl_dye:cyan", 12, 12 }, E1 }, + { { "mcl_dye:magenta", 12, 12 }, E1 }, + + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_white", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_grey", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_silver", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_black", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_red", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_yellow", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_green", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_cyan", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_blue", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_magenta", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_orange", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_purple", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_brown", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_pink", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_lime", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_light_blue", 1, 1 } }, + }, + + { + { { "mcl_core:emerald", 2, 2 }, { "mcl_paintings:painting", 3, 3 } }, }, }, }, @@ -239,28 +332,28 @@ local professions = { jobsite = "mcl_lectern:lectern", trades = { { - { { "mcl_core:paper", 24, 36 }, E1 }, - { { "mcl_books:book", 8, 10 }, E1 }, - { { "mcl_core:emerald", 9, 9 }, { "mcl_books:bookshelf", 1 ,1 }}, - { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "mcl_core:paper", 24, 24 }, E1 }, + { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 } }, + { { "mcl_core:emerald", 9, 9 }, { "mcl_books:bookshelf", 1 ,1 } }, }, + { - { { "mcl_books:written_book", 2, 2 }, E1 }, - { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "mcl_books:book", 4, 4 }, E1 }, + { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 } }, { E1, { "mcl_lanterns:lantern_floor", 1, 1 } }, }, { - { { "mcl_dye:black", 5, 5 }, E1 }, - { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "mcl_mobitems:ink_sac", 5, 5 }, E1 }, + { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 } }, { E1, { "mcl_core:glass", 4, 4 } }, }, { - { E1, { "mcl_books:writable_book", 1, 1 } }, - { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, - { { "mcl_core:emerald", 4, 4 }, { "mcl_compass:compass", 1 ,1 }}, + { { "mcl_books:writable_book", 1, 1 }, E1 }, + { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 } }, { { "mcl_core:emerald", 5, 5 }, { "mcl_clock:clock", 1, 1 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_compass:compass", 1 ,1 } }, }, { @@ -275,38 +368,43 @@ local professions = { trades = { { { { "mcl_core:paper", 24, 24 }, E1 }, - { { "mcl_core:emerald", 7, 7}, { "mcl_maps:empty_map", 1, 1 } }, + { { "mcl_core:emerald", 7, 7 }, { "mcl_maps:empty_map", 1, 1 } }, }, + { -- compass subject to special checks { { "xpanes:pane_natural_flat", 11, 11 }, E1 }, - --{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:ocean explorer map" 1, 1} }, + --{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:ocean explorer map" 1, 1 } }, }, + { { { "mcl_compass:compass", 1, 1 }, E1 }, - --{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:woodland explorer map" 1, 1} }, + --{ { "mcl_core:emerald", 14, 14, "mcl_compass:compass", 1, 1 }, { "FIXME:woodland explorer map" 1, 1 } }, }, - { - { { "mcl_core:emerald", 7, 7}, { "mcl_itemframes:item_frame", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_white", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_grey", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_silver", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_black", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_red", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_green", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_cyan", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_blue", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_magenta", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_orange", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_purple", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_brown", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_pink", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_lime", 1, 1 }}, - { { "mcl_core:emerald", 7, 7}, { "mcl_banners:banner_item_light_blue", 1, 1 }}, - }, { - --{ { "mcl_core:emerald", 8, 8}, { "FIXME: globe banner pattern", 1, 1 } }, + { { "mcl_core:emerald", 7, 7 }, { "mcl_itemframes:item_frame", 1, 1 } }, + + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_white", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_grey", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_silver", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_black", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_red", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_yellow", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_green", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_cyan", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_blue", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_magenta", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_orange", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_purple", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_brown", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_pink", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_lime", 1, 1 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_banners:banner_item_light_blue", 1, 1 } }, + }, + + { + --{ { "mcl_core:emerald", 8, 8 }, { "FIXME: globe banner pattern", 1, 1 } }, }, -- TODO: special maps }, @@ -330,6 +428,7 @@ local professions = { { { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_chain", 1, 1 } }, { { "mcl_core:emerald", 1, 1 }, { "mcl_armor:boots_chain", 1, 1 } }, }, + { { { "mcl_buckets:bucket_lava", 1, 1 }, E1 }, { { "mcl_core:diamond", 1, 1 }, E1 }, @@ -342,6 +441,7 @@ local professions = { { { "mcl_core:emerald", 19, 33 }, { "mcl_armor:leggings_diamond_enchanted", 1, 1 } }, { { "mcl_core:emerald", 13, 27 }, { "mcl_armor:boots_diamond_enchanted", 1, 1 } }, }, + { { { "mcl_core:emerald", 13, 27 }, { "mcl_armor:helmet_diamond_enchanted", 1, 1 } }, { { "mcl_core:emerald", 21, 35 }, { "mcl_armor:chestplate_diamond_enchanted", 1, 1 } }, @@ -351,29 +451,34 @@ local professions = { leatherworker = { name = N("Leatherworker"), texture = "mobs_mc_villager_leatherworker.png", - jobsite = "mcl_cauldrons:cauldron", + jobsite = "group:cauldron", trades = { { - { { "mcl_mobitems:leather", 9, 12 }, E1 }, - { { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_leather", 2, 4 } }, - { { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 2, 4 } }, + { { "mcl_mobitems:leather", 6, 6 }, E1 }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_leather", 1, 1 } }, + { { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 1, 1 } }, }, + { { { "mcl_core:flint", 26, 26 }, E1 }, - { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 2, 4 } }, - { { "mcl_core:emerald", 4, 4 }, { "mcl_armor:boots_leather", 2, 4 } }, + { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 1, 1 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_armor:boots_leather", 1, 1 } }, }, + { { { "mcl_mobitems:rabbit_hide", 9, 9 }, E1 }, { { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 1, 1 } }, }, + { --{ { "FIXME: scute", 4, 4 }, E1 }, { { "mcl_core:emerald", 8, 10 }, { "mcl_mobitems:saddle", 1, 1 } }, + --FIXME: { { "mcl_core:emerald", 6, 6 }, { "mcl_mobitems:leather_horse_armor", 1, 1 } }, }, + { { { "mcl_core:emerald", 6, 6 }, { "mcl_mobitems:saddle", 1, 1 } }, - { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 2, 4 } }, + { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 1, 1 } }, }, }, }, @@ -383,8 +488,8 @@ local professions = { jobsite = "mcl_smoker:smoker", trades = { { - { { "mcl_mobitems:beef", 14, 14 }, E1 }, - { { "mcl_mobitems:chicken", 7, 7 }, E1 }, + { { "mcl_mobitems:chicken", 14, 14 }, E1 }, + { { "mcl_mobitems:porkchop", 7, 7 }, E1 }, { { "mcl_mobitems:rabbit", 4, 4 }, E1 }, { E1, { "mcl_mobitems:rabbit_stew", 1, 1 } }, }, @@ -394,16 +499,15 @@ local professions = { { E1, { "mcl_mobitems:cooked_porkchop", 5, 5 } }, { E1, { "mcl_mobitems:cooked_chicken", 8, 8 } }, }, + { { { "mcl_mobitems:mutton", 7, 7 }, E1 }, { { "mcl_mobitems:beef", 10, 10 }, E1 }, }, + { - { { "mcl_mobitems:mutton", 7, 7 }, E1 }, - { { "mcl_mobitems:beef", 10, 10 }, E1 }, - }, - { - --{ { "FIXME: Sweet Berries", 10, 10 }, E1 }, + { { "mcl_ocean:dried_kelp_block", 10, 10 }, E1 }, + { { "mcl_farming:sweet_berry", 10, 10 }, E1 }, }, }, }, @@ -422,11 +526,13 @@ local professions = { { { "mcl_core:iron_ingot", 4, 4 }, E1 }, { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, }, + { - { { "mcl_core:flint", 7, 9 }, E1 }, + { { "mcl_core:flint", 24, 24 }, E1 }, }, + { - { { "mcl_core:diamond", 7, 9 }, E1 }, + { { "mcl_core:diamond", 1, 1 }, E1 }, { { "mcl_core:emerald", 17, 31 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } }, }, @@ -452,6 +558,7 @@ local professions = { { { "mcl_core:iron_ingot", 4, 4 }, E1 }, { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, }, + { { { "mcl_core:flint", 30, 30 }, E1 }, { { "mcl_core:emerald", 6, 20 }, { "mcl_tools:axe_iron_enchanted", 1, 1 } }, @@ -459,11 +566,13 @@ local professions = { { { "mcl_core:emerald", 8, 22 }, { "mcl_tools:pick_iron_enchanted", 1, 1 } }, { { "mcl_core:emerald", 4, 4 }, { "mcl_farming:hoe_diamond", 1, 1 } }, }, + { { { "mcl_core:diamond", 1, 1 }, E1 }, { { "mcl_core:emerald", 17, 31 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } }, { { "mcl_core:emerald", 10, 24 }, { "mcl_tools:shovel_diamond_enchanted", 1, 1 } }, }, + { { { "mcl_core:emerald", 18, 32 }, { "mcl_tools:pick_diamond_enchanted", 1, 1 } }, }, @@ -478,71 +587,98 @@ local professions = { { { "mcl_mobitems:rotten_flesh", 32, 32 }, E1 }, { E1, { "mesecons:redstone", 2, 2 } }, }, + { { { "mcl_core:gold_ingot", 3, 3 }, E1 }, { E1, { "mcl_core:lapis", 1, 1 } }, }, + { { { "mcl_mobitems:rabbit_foot", 2, 2 }, E1 }, - { E1, { "mcl_nether:glowstone", 4, 4 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_nether:glowstone", 1, 1 } }, }, + { --{ { "FIXME: scute", 4, 4 }, E1 }, { { "mcl_potions:glass_bottle", 9, 9 }, E1 }, { { "mcl_core:emerald", 5, 5 }, { "mcl_throwing:ender_pearl", 1, 1 } }, TRADE_V6_RED_SANDSTONE, }, + { - { { "mcl_nether:nether_wart_item", 22, 22 }, E1 }, - { { "mcl_core:emerald", 3, 3 }, { "mcl_experience:bottle", 1, 1 } }, + { { "mcl_nether:nether_wart_item", 22, 22 }, E1 }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_experience:bottle", 1, 1 } }, + { { "mcl_core:emerald", 15, 15 }, { "mcl_mobitems:aery_charge", 1, 1 } }, -- TODO reconsider + { { "mcl_core:emerald", 15, 15 }, { "mcl_mobitems:earthen_ash", 1, 1 } }, -- TODO reconsider }, }, }, mason = { - name = N("Mason"), - texture = "mobs_mc_villager_mason.png", - jobsite = "mcl_stonecutter:stonecutter", - trades = { - { - { { "mcl_core:clay_lump", 10, 10 }, E1 }, - { E1, { "mcl_core:brick", 10, 10 } }, - }, + name = N("Mason"), + texture = "mobs_mc_villager_mason.png", + jobsite = "mcl_stonecutter:stonecutter", + trades = { { - { { "mcl_core:stone", 20, 20 }, E1 }, - { E1, { "mcl_core:stonebrickcarved", 4, 4 } }, - }, - { - { { "mcl_core:granite", 16, 16 }, E1 }, - { { "mcl_core:andesite", 16, 16 }, E1 }, - { { "mcl_core:diorite", 16, 16 }, E1 }, - { E1, { "mcl_core:granite_smooth", 4, 4 } }, - { E1, { "mcl_core:andesite_smooth", 4, 4 } }, - { E1, { "mcl_core:diorite_smooth", 4, 4 } }, - }, - { - { { "mcl_nether:quartz", 12, 12 }, E1 }, - { E1, { "mcl_colorblocks:hardened_clay", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_white", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_grey", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_silver", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_black", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_red", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_yellow", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_green", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_cyan", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_blue", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_magenta", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_orange", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_brown", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_pink", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_light_blue", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_lime", 1, 1} }, - { E1, { "mcl_colorblocks:hardened_clay_purple", 1, 1 } }, - }, - { - { E1, { "mcl_nether:quartz_pillar", 1, 1 } }, - { E1, { "mcl_nether:quartz_block", 1, 1 } }, - }, + { { "mcl_core:clay_lump", 10, 10 }, E1 }, + { E1, { "mcl_core:brick", 10, 10 } }, + }, + + { + { { "mcl_core:stone", 20, 20 }, E1 }, + { E1, { "mcl_core:stonebrickcarved", 4, 4 } }, + }, + + { + { { "mcl_core:granite", 16, 16 }, E1 }, + { { "mcl_core:andesite", 16, 16 }, E1 }, + { { "mcl_core:diorite", 16, 16 }, E1 }, + { E1, { "mcl_core:andesite_smooth", 4, 4 } }, + { E1, { "mcl_core:granite_smooth", 4, 4 } }, + { E1, { "mcl_core:diorite_smooth", 4, 4 } }, + --FIXME: { E1, { "Dripstone Block", 4, 4 } }, + }, + + { + { { "mcl_nether:quartz", 12, 12 }, E1 }, + { E1, { "mcl_colorblocks:hardened_clay_white", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_grey", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_silver", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_black", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_red", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_yellow", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_green", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_cyan", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_blue", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_magenta", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_orange", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_brown", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_pink", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_light_blue", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_lime", 1, 1 } }, + { E1, { "mcl_colorblocks:hardened_clay_purple", 1, 1 } }, + + { E1, { "mcl_colorblocks:glazed_terracotta_white", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_grey", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_silver", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_black", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_red", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_yellow", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_green", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_cyan", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_blue", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_magenta", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_orange", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_brown", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_pink", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_light_blue", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_lime", 1, 1 } }, + { E1, { "mcl_colorblocks:glazed_terracotta_purple", 1, 1 } }, + }, + + { + { E1, { "mcl_nether:quartz_pillar", 1, 1 } }, + { E1, { "mcl_nether:quartz_block", 1, 1 } }, + }, }, }, nitwit = { @@ -1008,7 +1144,15 @@ end ----- JOBSITE LOGIC local function get_profession_by_jobsite(js) for k,v in pairs(professions) do - if v.jobsite == js then return k end + if v.jobsite == js then + return k + -- Catch Nitwit doesn't have a jobsite + elseif v.jobsite and v.jobsite:find("^group:") then + local group = v.jobsite:gsub("^group:", "") + if minetest.get_item_group(js, group) > 0 then + return k + end + end end end @@ -1799,6 +1943,7 @@ local trade_inventory = { if not wanted2:is_empty() then inv:remove_item("input", inv:get_stack("wanted", 2)) end + local name = player:get_player_name() local trader = player_trading_with[name] minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name(),object=trader.object}, true) end @@ -1846,6 +1991,17 @@ local trade_inventory = { -- Otherwise, 20% chance to unlock if used freshly reset trade unlock_stuff = true end + -- calculate xp based on the price + local emeralds = 0 + if wanted1:get_name() == "mcl_core:emerald" then + emeralds = wanted1:get_count() + elseif wanted2:get_name() == "mcl_core:emerald" then + emeralds = wanted2:get_count() + else + local offered = inv:get_stack("offered", 1) + emeralds = offered:get_name() == "mcl_core:emerald" and offered:get_count() or 0 + end + local xp = 2 + math.ceil(emeralds / (64/4)) -- 1..64 emeralds = 3..6 xp local update_formspec = false if unlock_stuff then -- First-time trade unlock all trades and unlock next trade tier @@ -1857,6 +2013,7 @@ local trade_inventory = { set_textures(trader) update_max_tradenum(trader) update_formspec = true + xp = xp + 5 end for t=1, #trades do trades[t].locked = false @@ -1867,6 +2024,7 @@ local trade_inventory = { -- TODO: Replace by Regeneration I trader.health = math.min(trader.hp_max, trader.health + 4) end + mcl_experience.add_xp(player, xp) trade.trade_counter = trade.trade_counter + 1 mcl_log("Trade counter is: ".. trade.trade_counter) -- Semi-randomly lock trade for repeated trade (not if there's only 1 trade) @@ -1904,6 +2062,7 @@ local trade_inventory = { if update_formspec then show_trade_formspec(name, trader, tradenum) end + else minetest.log("error", "[mobs_mc] Player took item from trader output but player_trading_with or player_tradenum is nil!") end @@ -2193,7 +2352,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -20, +2, 4, mobs_mc.water_level+1, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index a34f0ffe9..9d465c25d 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -42,6 +42,7 @@ mcl_mobs.register_mob("mobs_mc:evoker", { run_velocity = 1.4, group_attack = true, attack_type = "dogfight", + attack_frequency = 15, -- Summon vexes custom_attack = function(self, to_attack) if not spawned_vexes[self] then spawned_vexes[self] = {} end @@ -64,7 +65,6 @@ mcl_mobs.register_mob("mobs_mc:evoker", { table.insert(spawned_vexes[self],ent) end end, - shoot_interval = 15, passive = false, drops = { {name = "mcl_core:emerald", @@ -86,6 +86,11 @@ mcl_mobs.register_mob("mobs_mc:evoker", { }, view_range = 16, fear_height = 4, + + on_spawn = function(self) + self.timer = 15 + return true + end, }) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index 5af1fc879..ada456aff 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -225,7 +225,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -4090, +50, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index b00a68116..c9cc3c8ee 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -70,6 +70,11 @@ mcl_mobs.register_mob("mobs_mc:witch", { }, view_range = 16, fear_height = 4, + deal_damage = function(self, damage, mcl_reason) + local factor = 1 + if mcl_reason.type == "magic" then factor = 0.15 end + self.health = self.health - factor*damage + end, }) -- potion projectile (EXPERIMENTAL) diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 6b47d601a..252873629 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -1,14 +1,72 @@ --MCmobs v0.4 --maikerumine +--updated by Herowl --made for MC like Survival game --License for code WTFPL and otherwise stated in readmes local S = minetest.get_translator("mobs_mc") +local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true) +local follow_spawner = minetest.settings:get_bool("wither_follow_spawner", false) +local w_strafes = minetest.settings:get_bool("wither_strafes", true) +local anti_troll = minetest.settings:get_bool("wither_anti_troll_measures", false) + +local WITHER_INIT_BOOM = 7 +local WITHER_MELEE_COOLDOWN = 3 + +local function atan(x) + if not x or x ~= x then + return 0 + else + return math.atan(x) + end +end --################### --################### WITHER --################### +local function wither_unstuck(self) + local pos = self.object:get_pos() + if mobs_griefing then -- destroy blocks very nearby (basically, colliding with) + local col = self.collisionbox + local pos1 = vector.offset(pos, col[1], col[2], col[3]) + local pos2 = vector.offset(pos, col[4], col[5], col[6]) + for z = pos1.z, pos2.z do for y = pos1.y, pos2.y do for x = pos1.x, pos2.x do + local npos = vector.new(x,y,z) + local name = minetest.get_node(npos).name + if name ~= "air" then + local ndef = minetest.registered_nodes[name] + if ndef and ndef._mcl_hardness and ndef._mcl_hardness >= 0 then + local drops = minetest.get_node_drops(name, "") + if minetest.dig_node(npos) then + for _, item in ipairs(drops) do + if type(item) ~= "string" then + item = item:get_name() .. item:get_count() + end + minetest.add_item(npos, item) + end + end + end + end + end end end + end + mcl_mobs.mob_class.safe_boom(self, pos, 2) +end + +local function get_dim_relative_y(pos) + if (pos.y >= mcl_vars.mg_realm_barrier_overworld_end_max) then + return pos.y + elseif (pos.y <= mcl_vars.mg_nether_max + 200) then + return (pos.y - mcl_vars.mg_nether_min - 20) + else + return (pos.y - mcl_vars.mg_end_min - 50) + end +end + +mobs_mc.wither_count_overworld = 0 +mobs_mc.wither_count_nether = 0 +mobs_mc.wither_count_end = 0 + mcl_mobs.register_mob("mobs_mc:wither", { description = S("Wither"), type = "monster", @@ -26,11 +84,11 @@ mcl_mobs.register_mob("mobs_mc:wither", { {"mobs_mc_wither.png"}, }, visual_size = {x=4, y=4}, - makes_footstep_sound = true, - view_range = 16, + view_range = 50, fear_height = 4, walk_velocity = 2, run_velocity = 4, + strafes = w_strafes, sounds = { shoot_attack = "mobs_mc_ender_dragon_shoot", attack = "mobs_mc_ender_dragon_attack", @@ -41,9 +99,8 @@ mcl_mobs.register_mob("mobs_mc:wither", { jump_height = 10, fly = true, makes_footstep_sound = false, - dogshoot_switch = 1, - dogshoot_count_max = 1, - attack_animals = true, + dogshoot_switch = 1, -- unused + dogshoot_count_max = 1, -- unused can_despawn = false, drops = { {name = "mcl_mobitems:nether_star", @@ -53,13 +110,13 @@ mcl_mobs.register_mob("mobs_mc:wither", { }, lava_damage = 0, fire_damage = 0, - attack_type = "dogshoot", + attack_type = "custom", explosion_strength = 8, dogshoot_stop = true, arrow = "mobs_mc:wither_skull", reach = 5, - shoot_interval = 0.5, - shoot_offset = -1, + shoot_interval = 1, + shoot_offset = -0.5, animation = { walk_speed = 12, run_speed = 12, stand_speed = 12, stand_start = 0, stand_end = 20, @@ -67,57 +124,377 @@ mcl_mobs.register_mob("mobs_mc:wither", { run_start = 0, run_end = 20, }, harmed_by_heal = true, - do_custom = function(self) + is_boss = true, + extra_hostile = true, + attack_exception = function(p) + local ent = p:get_luaentity() + if p:is_player() then return false end + if not ent or not ent.is_mob or ent.harmed_by_heal or string.find(ent.name, "ghast") then return true + else return false end + end, + + do_custom = function(self, dtime) + if self._spawning then + -- "loading" bar while spawning + if not self._spw_max then self._spw_max = self._spawning end + self._spawning = self._spawning - dtime + local bardef = { + color = "dark_purple", + text = "Wither spawning", + percentage = math.floor((self._spw_max - self._spawning) / self._spw_max * 100), + } + + local pos = self.object:get_pos() + for _, player in pairs(minetest.get_connected_players()) do + local d = vector.distance(pos, player:get_pos()) + if d <= 80 then + mcl_bossbars.add_bar(player, bardef, true, d) + end + end + + -- turn around and flash while spawning + self.object:set_yaw(self._spawning*10) + local factor = math.floor((math.sin(self._spawning*10)+1.5) * 85) + local str = minetest.colorspec_to_colorstring({r=factor, g=factor, b=factor}) + self.object:set_texture_mod("^[brighten^[multiply:"..str) + + -- when fully spawned, explode + if self._spawning <= 0 then + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, WITHER_INIT_BOOM, { drop_chance = 1.0 }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, WITHER_INIT_BOOM) + end + self.object:set_texture_mod("") + self._spawning = nil + self._spw_max = nil + else + return false + end + end + + -- passive regeneration + self._custom_timer = self._custom_timer + dtime + if self._custom_timer > 1 then + self.health = math.min(self.health + 1, self.hp_max) + self._custom_timer = self._custom_timer - 1 + end + + -- anti-troll measures + if anti_troll then + if self._spawner then + local spawner = minetest.get_player_by_name(self._spawner) + if follow_spawner and spawner then + self._death_timer = 0 + local pos = self.object:get_pos() + local spw = spawner:get_pos() + local dist = vector.distance(pos, spw) + if dist > 60 then -- teleport to the player who spawned the wither + local R = 10 + pos.x = spw.x + math.random(-R, R) + pos.y = spw.y + math.random(-R, R) + pos.z = spw.z + math.random(-R, R) + self.object:set_pos(pos) + end + else -- despawn automatically after set time + -- HP changes impact timer: taking damage sets it back + self._death_timer = self._death_timer + self.health - self._health_old + if self.health == self._health_old then self._death_timer = self._death_timer + dtime end + if self._death_timer > 100 then + self.object:remove() + return false + end + self._health_old = self.health + end + end + -- count withers per dimension + local dim = mcl_worlds.pos_to_dimension(self.object:get_pos()) + if dim == "overworld" then mobs_mc.wither_count_overworld = mobs_mc.wither_count_overworld + 1 + elseif dim == "nether" then mobs_mc.wither_count_nether = mobs_mc.wither_count_nether + 1 + elseif dim == "end" then mobs_mc.wither_count_end = mobs_mc.wither_count_end + 1 end + end + + -- update things dependent on HP + local rand_factor if self.health < (self.hp_max / 2) then self.base_texture = "mobs_mc_wither_half_health.png" self.fly = false - self.object:set_properties({textures={self.base_texture}}) - self.armor = {undead = 80, fleshy = 80} + self._arrow_resistant = true + rand_factor = 3 + else + self.base_texture = "mobs_mc_wither.png" + self.fly = true + self._arrow_resistant = false + rand_factor = 10 end + if not self.attack then + local y = get_dim_relative_y(self.object:get_pos()) + if y > 0 then + self.fly = false + else + self.fly = true + local vel = self.object:get_velocity() + self.object:set_velocity(vector.new(vel.x, self.walk_velocity, vel.z)) + end + end + self.object:set_properties({textures={self.base_texture}}) mcl_bossbars.update_boss(self.object, "Wither", "dark_purple") + if math.random(1, rand_factor) < 2 then + self.arrow = "mobs_mc:wither_skull_strong" + else + self.arrow = "mobs_mc:wither_skull" + end end, + + attack_state = function(self, dtime) + local s = self.object:get_pos() + local p = self.attack:get_pos() or s + + p.y = p.y - .5 + s.y = s.y + .5 + + local dist = vector.distance(p, s) + local vec = { + x = p.x - s.x, + y = p.y - s.y, + z = p.z - s.z + } + + local yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + if p.x > s.x then yaw = yaw +math.pi end + yaw = self:set_yaw( yaw, 0, dtime) + + local stay_away_from_player = vector.zero() + + --strafe back and fourth + + --stay away from player so as to shoot them + if dist < self.avoid_distance and self.shooter_avoid_enemy then + self:set_animation( "shoot") + stay_away_from_player=vector.multiply(vector.direction(p, s), 0.33) + end + + if self.fly then + local vel = self.object:get_velocity() + local diff = s.y - p.y + local FLY_FACTOR = self.walk_velocity + if diff < 10 then + self.object:set_velocity({x=vel.x, y= FLY_FACTOR, z=vel.z}) + elseif diff > 15 then + self.object:set_velocity({x=vel.x, y=-FLY_FACTOR, z=vel.z}) + end + for i=1, 15 do + if minetest.get_node(vector.offset(s, 0, -i, 0)).name ~= "air" then + self.object:set_velocity({x=vel.x, y= FLY_FACTOR, z=vel.z}) + break + elseif minetest.get_node(vector.offset(s, 0, i, 0)).name ~= "air" then + self.object:set_velocity({x=vel.x, y=-FLY_FACTOR/i, z=vel.z}) + break + end + end + end + + if self.strafes then + if not self.strafe_direction then + self.strafe_direction = 1.57 + end + if math.random(40) == 1 then + self.strafe_direction = self.strafe_direction*-1 + end + + local dir = vector.rotate_around_axis(vector.direction(s, p), vector.new(0,1,0), self.strafe_direction) + local dir2 = vector.multiply(dir, 0.3 * self.walk_velocity) + + if dir2 and stay_away_from_player then + self.acc = vector.add(dir2, stay_away_from_player) + end + else + self:set_velocity(0) + end + + if dist > 30 then self.acc = vector.add(self.acc, vector.direction(s, p)*0.01) end + + local side_cor = vector.new(0.7*math.cos(yaw), 0, 0.7*math.sin(yaw)) + local m = self.object:get_pos() -- position of the middle head + local sr = self.object:get_pos() + side_cor -- position of side right head + local sl = self.object:get_pos() - side_cor -- position of side left head + -- height corrections + m.y = m.y + self.collisionbox[5] + sr.y = sr.y + self.collisionbox[5] - 0.3 + sl.y = sl.y + self.collisionbox[5] - 0.3 + local rand_pos = math.random(1,3) + if rand_pos == 1 then m = sr + elseif rand_pos == 2 then m = sl end + + -- melee attack + if not self._melee_timer then + self._melee_timer = 0 + end + if self._melee_timer < WITHER_MELEE_COOLDOWN then + self._melee_timer = self._melee_timer + dtime + else + self._melee_timer = 0 + local pos = table.copy(s) + pos.y = pos.y + 2 + local objs = minetest.get_objects_inside_radius(pos, self.reach) + local obj_pos, dist + local hit_some = false + for n = 1, #objs do + objs[n]:punch(objs[n], 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 4}, + }, pos) + local ent = objs[n]:get_luaentity() + if objs[n]:is_player() or (ent and ent ~= self and (not ent._shooter or ent._shooter ~= self)) then + mcl_util.deal_damage(objs[n], 8, {type = "magic"}) + hit_some = true + end + mcl_potions.give_effect("withering", objs[n], 2, 10) + end + if hit_some then + mcl_mobs.effect(pos, 32, "mcl_particles_soul_fire_flame.png", 5, 10, self.reach, 1, 0) + end + end + + if dist < self.reach then + self.shoot_interval = 3 + else + self.shoot_interval = 1 + end + + if self.shoot_interval + and self.timer > self.shoot_interval + and not minetest.raycast(vector.add(m, vector.new(0,self.shoot_offset,0)), vector.add(self.attack:get_pos(), vector.new(0,1.5,0)), false, false):next() + and math.random(1, 100) <= 60 then + + self.timer = 0 + self:set_animation( "shoot") + + -- play shoot attack sound + self:mob_sound("shoot_attack") + + -- Shoot arrow + if minetest.registered_entities[self.arrow] then + + local arrow, ent + local v = 1 + if not self.shoot_arrow then + self.firing = true + minetest.after(1, function() + self.firing = false + end) + arrow = minetest.add_entity(m, self.arrow) + ent = arrow:get_luaentity() + if ent.velocity then + v = ent.velocity + end + ent.switch = 1 + ent.owner_id = tostring(self.object) -- add unique owner id to arrow + + -- important for mcl_shields + ent._shooter = self.object + ent._saved_shooter_pos = self.object:get_pos() + end + + local amount = (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) ^ 0.5 + -- offset makes shoot aim accurate + vec.y = vec.y + self.shoot_offset + vec.x = vec.x * (v / amount) + vec.y = vec.y * (v / amount) + vec.z = vec.z * (v / amount) + if self.shoot_arrow then + vec = vector.normalize(vec) + self:shoot_arrow(m, vec) + else + arrow:set_velocity(vec) + end + end + end + end, + + do_punch = function(self, hitter, tflp, tool_capabilities, dir) + if self._spawning or hitter == self.object then return false end + local ent = hitter:get_luaentity() + if ent and self._arrow_resistant and (string.find(ent.name, "arrow") or string.find(ent.name, "rocket")) then return false end + wither_unstuck(self) + return true + end, + deal_damage = function(self, damage, mcl_reason) + if self._spawning then return end + if self._arrow_resistant and mcl_reason.type == "magic" then return end + wither_unstuck(self) + self.health = self.health - damage + end, + on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) + self._custom_timer = 0.0 + self._death_timer = 0.0 + self._health_old = self.hp_max + self._spawning = 10 + return true end, }) -local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local wither_rose_soil = { "group:grass_block", "mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_nether:netherrack", "group:soul_block", "mcl_mud:mud", "mcl_moss:moss" } +local function spawn_wither_rose(obj) + local n = minetest.find_node_near(obj:get_pos(),2,wither_rose_soil) + if n then + local p = vector.offset(n,0,1,0) + if minetest.get_node(p).name == "air" then + if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then + minetest.add_item(p,"mcl_flowers:wither_rose") + end + end + end +end mcl_mobs.register_arrow("mobs_mc:wither_skull", { - visual = "sprite", - visual_size = {x = 0.75, y = 0.75}, - -- TODO: 3D projectile, replace tetxture - textures = {"mobs_mc_TEMP_wither_projectile.png"}, - velocity = 6, + visual = "cube", + visual_size = {x = 0.3, y = 0.3}, + textures = { + "mobs_mc_wither_projectile.png^[verticalframe:6:0", -- top + "mobs_mc_wither_projectile.png^[verticalframe:6:1", -- bottom + "mobs_mc_wither_projectile.png^[verticalframe:6:2", -- left + "mobs_mc_wither_projectile.png^[verticalframe:6:3", -- right + "mobs_mc_wither_projectile.png^[verticalframe:6:4", -- back + "mobs_mc_wither_projectile.png^[verticalframe:6:5", -- front + }, + velocity = 7, + rotate = 90, + _lifetime = 15, + on_punch = function(self) end, -- direct hit hit_player = function(self, player) + local pos = vector.new(self.object:get_pos()) + mcl_potions.give_effect("withering", player, 2, 10) player:punch(self.object, 1.0, { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self, pos, 1) + if player:get_hp() <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(player) + end end, hit_mob = function(self, mob) + local pos = vector.new(self.object:get_pos()) + mcl_potions.give_effect("withering", mob, 2, 10) mob:punch(self.object, 1.0, { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self, pos, 1) local l = mob:get_luaentity() if l and l.health - 8 <= 0 then - local n = minetest.find_node_near(mob:get_pos(),2,wither_rose_soil) - if n then - local p = vector.offset(n,0,1,0) - if minetest.get_node(p).name == "air" then - if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then - minetest.add_item(p,"mcl_flowers:wither_rose") - end - end - end + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(mob) end end, @@ -126,10 +503,75 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", { mcl_mobs.mob_class.boom(self,pos, 1) end }) --- TODO: Add blue wither skull +mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", { + visual = "cube", + visual_size = {x = 0.35, y = 0.35}, + textures = { + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:0", -- top + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:1", -- bottom + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:2", -- left + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:3", -- right + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:4", -- back + "mobs_mc_wither_projectile_strong.png^[verticalframe:6:5", -- front + }, + velocity = 4, + rotate = 90, + _lifetime = 25, + on_punch = function(self) end, + + -- direct hit + hit_player = function(self, player) + local pos = vector.new(self.object:get_pos()) + mcl_potions.give_effect("withering", player, 2, 10) + player:punch(self.object, 1.0, { + full_punch_interval = 0.5, + damage_groups = {fleshy = 12}, + }, nil) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + if player:get_hp() <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(player) + end + end, + + hit_mob = function(self, mob) + local pos = vector.new(self.object:get_pos()) + mcl_potions.give_effect("withering", mob, 2, 10) + mob:punch(self.object, 1.0, { + full_punch_interval = 0.5, + damage_groups = {fleshy = 12}, + }, nil) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + local l = mob:get_luaentity() + if l and l.health - 8 <= 0 then + local shooter = self._shooter:get_luaentity() + if shooter then shooter.health = shooter.health + 5 end + spawn_wither_rose(mob) + end + end, + + -- node hit, explode + hit_node = function(self, pos, node) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here + end + end +}) --Spawn egg mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, true) mcl_wip.register_wip_item("mobs_mc:wither") mcl_mobs:non_spawn_specific("mobs_mc:wither","overworld",0,minetest.LIGHT_MAX+1) + diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index 7b142086d..13e76a602 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -29,7 +29,7 @@ local wolf = { head_swivel = "head.control", bone_eye_height = 3.5, head_eye_height = 1.1, - horrizonatal_head_height=0, + horizontal_head_height=0, curiosity = 3, head_yaw="z", sounds = { @@ -135,6 +135,7 @@ end -- Tamed wolf (aka “dog”) local dog = table.copy(wolf) +dog.description = S("Dog") dog.can_despawn = false dog.passive = true dog.hp_min = 20 @@ -224,7 +225,7 @@ mcl_mobs:spawn_specific( 0, minetest.LIGHT_MAX+1, 30, -9000, +80, 7, mobs_mc.water_level+3, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 6a4f5d48a..2f6d7e79f 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -38,7 +38,7 @@ local drops_common = { local drops_zombie = table.copy(drops_common) table.insert(drops_zombie, { -- Zombie Head - -- TODO: Only drop if killed by charged creeper + -- TODO: Only drop if killed by charged stalker name = "mcl_heads:zombie", chance = 200, -- 0.5% min = 1, @@ -243,7 +243,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -6000, +1000, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) @@ -332,7 +332,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -60000, +50, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) @@ -348,7 +348,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -6500, +2400, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) @@ -362,7 +362,7 @@ mcl_mobs:spawn_specific( 0, 7, 30, -65000, +120, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) diff --git a/mods/ENTITIES/modpack.conf b/mods/ENTITIES/modpack.conf index 07731c775..95265a8a0 100644 --- a/mods/ENTITIES/modpack.conf +++ b/mods/ENTITIES/modpack.conf @@ -1,2 +1,2 @@ name = ENTITIES -description = Meta-modpack containing entity-related mods for MineClone 2 +description = Meta-modpack containing entity-related mods for VoxeLibre diff --git a/mods/ENTITIES/vl_held_item/init.lua b/mods/ENTITIES/vl_held_item/init.lua new file mode 100644 index 000000000..f64ad9928 --- /dev/null +++ b/mods/ENTITIES/vl_held_item/init.lua @@ -0,0 +1,40 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +vl_held_item = {} +local mod = vl_held_item + +local held_item_entity = { + initial_properties = { + hp_max = 1, + physical = true, + pointable = false, + collide_with_objects = true, + static_save = false, -- TODO remove/change later when needed to persist + -- WARNING persisting held items not recommended, mob can recreate it after_activate + collision_box = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + }, + visual = "wielditem", + textures = { "mcl_core:dirt_with_grass" }, +} +function held_item_entity:on_activate(staticdata, dtime_unloaded) + local staticdata = minetest.deserialize(staticdata) + self._staticdata = staticdata + + local props = { + visual = "wielditem", + textures = { staticdata.itemname }, + } + self.object:set_properties(props) +end +function held_item_entity:get_staticdata() + return minetest.serialize(self._staticdata) +end +minetest.register_entity("vl_held_item:held_item_entity", held_item_entity) + +function mod.create_item_entity(pos, itemname) + local staticdata = { + itemname = itemname + } + return minetest.add_entity(pos, "vl_held_item:held_item_entity", minetest.serialize(staticdata)) +end + diff --git a/mods/ENTITIES/vl_held_item/mod.conf b/mods/ENTITIES/vl_held_item/mod.conf new file mode 100644 index 000000000..c5068855f --- /dev/null +++ b/mods/ENTITIES/vl_held_item/mod.conf @@ -0,0 +1,4 @@ +name = vl_held_item +author = teknomunk, Herowl +description = An entity that represents an item held by a mob +depends = mcl_core diff --git a/mods/ENVIRONMENT/lightning/API.md b/mods/ENVIRONMENT/lightning/API.md index ad4f0a3b4..d420bd4b3 100644 --- a/mods/ENVIRONMENT/lightning/API.md +++ b/mods/ENVIRONMENT/lightning/API.md @@ -1,5 +1,5 @@ # lightning -Lightning mod for MineClone2 with the following API: +Lightning mod for VoxeLibre with the following API: ## lightning.register_on_strike(function(pos, pos2, objects)) Custom function called when a lightning strikes. @@ -28,4 +28,4 @@ end) minetest.register_on_respawnplayer(function(player) lightning.strike(player:get_pos()) end) -``` \ No newline at end of file +``` diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 59591b061..41d6f458c 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -1,7 +1,7 @@ --[[ Copyright (C) 2016 - Auke Kok -Adapted by MineClone2 contributors +Adapted by VoxeLibre contributors "lightning" is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.es.tr b/mods/ENVIRONMENT/lightning/locale/lightning.es.tr index 5d207a5c6..3b164f530 100644 --- a/mods/ENVIRONMENT/lightning/locale/lightning.es.tr +++ b/mods/ENVIRONMENT/lightning/locale/lightning.es.tr @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.=@ 1 fue alcanzado por un rayo. -Let lightning strike at the specified position or yourself=Deje que un rayo golpee en la posición especificada o sobre usted mismo. +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. No position specified and unknown player=Ninguna posición especificada y jugador desconocido diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.pt_BR.tr b/mods/ENVIRONMENT/lightning/locale/lightning.pt_BR.tr new file mode 100644 index 000000000..f896e3ac1 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: lightning +Let lightning strike at the specified position or player. No parameter will strike yourself.=Deixa o relâmpago acertar a posição ou jogador especificado. Nenhum parâmetro irá acertar você mesmo. +No position specified and unknown player=Nenhuma posição especificada e jogador desconhecido diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.ru.tr b/mods/ENVIRONMENT/lightning/locale/lightning.ru.tr index 68bcf3555..7b535ac81 100644 --- a/mods/ENVIRONMENT/lightning/locale/lightning.ru.tr +++ b/mods/ENVIRONMENT/lightning/locale/lightning.ru.tr @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.=@1 убило молнией. -Let lightning strike at the specified position or yourself=Позволяет молнии бить в заданную позицию или в вас +Let lightning strike at the specified position or player. No parameter will strike yourself.=Бьёт молнией в заданную позицию или в игрока. Без указанного параметра ударит по вам. No position specified and unknown player=Позиция не задана и игрок неизвестен diff --git a/mods/ENVIRONMENT/mcl_raids/init.lua b/mods/ENVIRONMENT/mcl_raids/init.lua index 8e7c644ae..d0c10eb20 100644 --- a/mods/ENVIRONMENT/mcl_raids/init.lua +++ b/mods/ENVIRONMENT/mcl_raids/init.lua @@ -104,11 +104,9 @@ function mcl_raids.promote_to_raidcaptain(c) -- object mcl_raids.drop_obanner(pos) if cmi_cause and cmi_cause.type == "punch" and cmi_cause.puncher:is_player() then awards.unlock(cmi_cause.puncher:get_player_name(), "mcl:voluntary_exile") - local lv = mcl_potions.player_get_effect(cmi_cause.puncher, "bad_omen") - if not lv then lv = 0 - else lv = lv.factor end + local lv = mcl_potions.get_effect_level(cmi_cause.puncher, "bad_omen") lv = math.max(5,lv + 1) - mcl_potions.bad_omen_func(cmi_cause.puncher,lv,6000) + mcl_potions.give_effect_by_level("bad_omen", cmi_cause.puncher, lv, 6000) end end if old_ondie then return old_ondie(self,pos,cmi_cause) end @@ -296,7 +294,7 @@ mcl_events.register_event("raid",{ --minetest.log("Cond start raid") local r = {} for _,p in pairs(minetest.get_connected_players()) do - if mcl_potions.player_has_effect(p,"bad_omen") then + if mcl_potions.has_effect(p,"bad_omen") then local raid_pos = mcl_raids.find_village(p:get_pos()) if raid_pos then --minetest.log("We have a raid position. Start raid") @@ -310,8 +308,8 @@ mcl_events.register_event("raid",{ self.mobs = {} self.health_max = 1 self.health = 0 - local lv = mcl_potions.player_get_effect(minetest.get_player_by_name(self.player), "bad_omen") - if lv and lv.factor and lv.factor > 1 then self.max_stage = 6 end + local lv = mcl_potions.get_effect_level(minetest.get_player_by_name(self.player), "bad_omen") + if lv > 1 then self.max_stage = 6 end end, cond_progress = function(self) if not is_player_near(self) then return false end @@ -331,7 +329,7 @@ mcl_events.register_event("raid",{ end, on_complete = function(self) awards.unlock(self.player,"mcl:hero_of_the_village") - mcl_potions.player_clear_effect(minetest.get_player_by_name(self.player),"bad_omen") + mcl_potions.clear_effect(minetest.get_player_by_name(self.player),"bad_omen") make_firework(self.pos,os.time()) end, }) diff --git a/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.fr.tr b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.fr.tr new file mode 100644 index 000000000..92d40e998 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.fr.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_raids +Ominous Banner=Bannière de mauvais augure diff --git a/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.pt_BR.tr b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.pt_BR.tr new file mode 100644 index 000000000..cd59abb96 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_raids +Ominous Banner=Estandarte Ameaçador diff --git a/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.ru.tr b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.ru.tr new file mode 100644 index 000000000..64ea21aba --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/locale/mcl_raids.ru.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_raids +Ominous Banner=Зловещий флаг diff --git a/mods/ENVIRONMENT/mcl_raids/locale/template.txt b/mods/ENVIRONMENT/mcl_raids/locale/template.txt new file mode 100644 index 000000000..afab805d3 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain: mcl_raids +Ominous Banner= diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pt_BR.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pt_BR.tr new file mode 100644 index 000000000..c4e2152ba --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=O vazio está fora dos limites para você! +@1 fell into the endless void.=@1 caiu em um vazio sem fim. diff --git a/mods/ENVIRONMENT/mcl_weather/README.md b/mods/ENVIRONMENT/mcl_weather/README.md index 08f748dfb..be313cf86 100644 --- a/mods/ENVIRONMENT/mcl_weather/README.md +++ b/mods/ENVIRONMENT/mcl_weather/README.md @@ -1,6 +1,6 @@ `mcl_weather` ======================= -Weather mod for MineClone 2. Forked from the `weather_pack` mod by xeranas. +Weather mod for VoxeLibre. Forked from the `weather_pack` mod by xeranas. Weathers included ----------------------- diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pt_BR.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pt_BR.tr new file mode 100644 index 000000000..3d91979ae --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=Dá a habilidade de controlar o clima +Changes the weather to the specified parameter.=Muda o clima para o parâmetro especificado. +Error: No weather specified.=Erro: Nenhum clima especificado. +Error: Invalid parameters.=Erro: Parâmetros inválidos. +Error: Duration can't be less than 1 second.=Erro: Duração não pode ser menor que 1 segundo. +Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Erro: Clima especificado é inválido. Use "clear", "rain", "snow" ou "thunder". +Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Alterna entre clima limpo e clima com quedas (aleatoriamente chuva, tempestade ou neve) diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ru.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ru.tr index 0c3773b7a..00a9e778e 100644 --- a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ru.tr +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ru.tr @@ -6,4 +6,3 @@ Error: Invalid parameters.=Ошибка: Недопустимые парамет Error: Duration can't be less than 1 second.=Ошибка: длительность не может быть менее 1 секунды. Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Ошибка: Указана неправильная погода. Возможны варианты: “clear” (ясная), “rain” (дождь), “snow” (снег) или “thunder” (гроза). Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Переключает между ясной погодой и осадками (случайно выбирается дождь, грозовой шторм или снег) - diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index aea469760..87952845b 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -120,19 +120,26 @@ mcl_weather.skycolor = { override_day_night_ratio = function(player, ratio) local meta = player:get_meta() local has_night_vision = meta:get_int("night_vision") == 1 + local has_darkness = meta:get_int("darkness") == 1 + local is_visited_shepherd = meta:get_int("mcl_shepherd:special") == 1 local arg - -- Apply night vision only for dark sky - local is_dark = minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none" - local pos = player:get_pos() - local dim = mcl_worlds.pos_to_dimension(pos) - if has_night_vision and is_dark and dim ~= "nether" and dim ~= "end" then - if ratio == nil then - arg = NIGHT_VISION_RATIO - else - arg = math.max(ratio, NIGHT_VISION_RATIO) - end + if has_darkness and not is_visited_shepherd then + if has_night_vision then arg = 0.1 + else arg = 0 end else - arg = ratio + -- Apply night vision only for dark sky + local is_dark = minetest.get_timeofday() > 0.8 or minetest.get_timeofday() < 0.2 or mcl_weather.state ~= "none" + local pos = player:get_pos() + local dim = mcl_worlds.pos_to_dimension(pos) + if (has_night_vision or is_visited_shepherd) and is_dark and dim ~= "nether" and dim ~= "end" then + if ratio == nil then + arg = NIGHT_VISION_RATIO + else + arg = math.max(ratio, NIGHT_VISION_RATIO) + end + else + arg = ratio + end end player:override_day_night_ratio(arg) end, diff --git a/mods/ENVIRONMENT/modpack.conf b/mods/ENVIRONMENT/modpack.conf index 8c40cfab8..8376be988 100644 --- a/mods/ENVIRONMENT/modpack.conf +++ b/mods/ENVIRONMENT/modpack.conf @@ -1,2 +1,2 @@ name = ENVIRONMENT -description = Meta-modpack containing environment and nature-related mods for MineClone 2 +description = Meta-modpack containing environment and nature-related mods for VoxeLibre diff --git a/mods/HELP/doc/README.md b/mods/HELP/doc/README.md index c8fd1407d..37e6e6489 100644 --- a/mods/HELP/doc/README.md +++ b/mods/HELP/doc/README.md @@ -1,5 +1,5 @@ # Help -MineClone 2 uses some of the mods found in the Help modpack by Wuzzy. +VoxeLibre uses some of the mods found in the Help modpack by Wuzzy. The goal of this modpack is to make using Minetest and mods easier for both newcomers and advanced users. @@ -11,7 +11,7 @@ directly into mods (via `doc_items`). More information is given in the respective mods. -Overview of the mods used in MineClone 2: +Overview of the mods used in VoxeLibre: * `doc`: Documentation System. Core API and user interface. Mods can add arbitrary categories and entries * `doc_items`: Item Help. Adds automatically generated help texts for items and an API diff --git a/mods/HELP/doc/doc/init.lua b/mods/HELP/doc/doc/init.lua index 304900753..47b5e18dd 100644 --- a/mods/HELP/doc/doc/init.lua +++ b/mods/HELP/doc/doc/init.lua @@ -53,7 +53,7 @@ doc.data = {} doc.data.categories = {} doc.data.aliases = {} -- Default order (includes categories of other mods from the Docuentation System modpack) -doc.data.category_order = {"basics", "nodes", "tools", "craftitems", "advanced"} +doc.data.category_order = {"basics", "nodes", "tools", "craftitems", "advanced", "mobs"} doc.data.category_count = 0 doc.data.players = {} diff --git a/mods/HELP/doc/doc/locale/doc.ru.tr b/mods/HELP/doc/doc/locale/doc.ru.tr index 105f92b11..74ab5839f 100644 --- a/mods/HELP/doc/doc/locale/doc.ru.tr +++ b/mods/HELP/doc/doc/locale/doc.ru.tr @@ -27,7 +27,7 @@ New help entry unlocked: @1 > @2=Новая подсказка разблоки No categories have been registered, but they are required to provide help.=Для предоставления помощи требуются зарегистрированные категории, но они отсутствуют. The Documentation System [doc] does not come with help contents on its own, it needs additional mods to add help content. Please make sure such mods are enabled on for this world, and try again.=Система документации [doc] не предоставляет помощи сама по себе, нужны дополнительные моды для добавления справочной информации. Пожалуйста, убедитесь, что моды включены для этого мира, после чего попробуйте снова. Number of entries: @1=Количество записей: @1 -OK=О'кей +OK=ОК Open a window providing help entries about Minetest and more=Открыть окно с подсказками о игре Minetest и т. п. Please select a category you wish to learn more about:=Пожалуйста, выберите категорию, о которой хотите узнать больше: Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia.=Рекомендованные моды: doc_basics, doc_items, doc_identifier, doc_encyclopedia. diff --git a/mods/HELP/doc/doc_identifier/init.lua b/mods/HELP/doc/doc_identifier/init.lua index c1c2043d3..483970a5f 100644 --- a/mods/HELP/doc/doc_identifier/init.lua +++ b/mods/HELP/doc/doc_identifier/init.lua @@ -116,7 +116,11 @@ function doc_identifier.identify(itemstack, user, pointed_thing) end -- A known registered object elseif ro then - doc.show_entry(username, ro.category, ro.entry, true) + if doc.entry_exists("mobs", le.name) then + doc.show_entry(username, "mobs", le.name, true) + else + doc.show_entry(username, ro.category, ro.entry, true) + end -- Undefined object (error) elseif minetest.registered_entities[le.name] == nil then show_message(username, "error_unknown", le.name) diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.ru.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ru.tr index 1080a3186..b4e533142 100644 --- a/mods/HELP/doc/doc_identifier/locale/doc_identifier.ru.tr +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ru.tr @@ -1,7 +1,7 @@ # textdomain:doc_identifier Error: This node, item or object is undefined. This is always an error.=Ошибка: Данный узел, предмет или объект не определён. Это всегда вызывает ошибку. This can happen for the following reasons:=Это может произойти по одной из причин: -• The mod which is required for it is not enabled=• Не включён мод, требуемый для этого +• The mod which is required for it is not enabled=• Не включён требуемый мод • The author of the game or a mod has made a mistake=• Автор игры или мода допустил ошибку It appears to originate from the mod “@1”, which is enabled.=Это, вероятно, случилось в моде “@1”, который включён. It appears to originate from the mod “@1”, which is not enabled!=Это, вероятно, случилось в моде “@1”, который не включён! @@ -10,8 +10,8 @@ Lookup Tool=Инструмент просмотра No help entry for this block could be found.=Не удаётся найти справочной записи для этого блока. No help entry for this item could be found.=Не удаётся найти справочной записи для этого предмета. No help entry for this object could be found.=Не удаётся найти справочной записи для этого объекта. -OK=О'кей -Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by using. In liquid mode, this tool points to liquids as well while in solid mode this is not the case.=Стукните любой блок, предмет или другую вещь, про которую хотите узнать больше. Откроется соответствующая справочная запись. Инструмент работает в двух режимах, меняющихся при использовании. В жидком режиме инструмент указывает на жидкости, в твёрдом режиме нет. +OK=ОК +Punch any block, item or other thing about you wish to learn more about. This will open up the appropriate help entry. The tool comes in two modes which are changed by using. In liquid mode, this tool points to liquids as well while in solid mode this is not the case.=Ударьте по любому блоку, предмету и прочим вещам, про который вы хотите узнать больше. Откроется соответствующая справочная запись. Инструмент работает в двух режимах, меняющихся при использовании. В жидкостном режиме инструмент указывает на жидкости, в твёрдом режиме нет. This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds.=Этот блок не может быть идентифицирован, потому что мир не ещё материализовался в этой точке. This is a player.=Это игрок. This useful little helper can be used to quickly learn more about about one's closer environment. It identifies and analyzes blocks, items and other things and it shows extensive information about the thing on which it is used.=Этот маленький помощник выдаст вам быструю справку о чём-то из ближайшего окружения. Он идентифицирует и анализирует блоки, предметы и другие вещи и показывает подробную информацию о вещах, к которым они применимы. diff --git a/mods/HELP/doc/doc_items/init.lua b/mods/HELP/doc/doc_items/init.lua index 325ad9abb..0c3205b04 100644 --- a/mods/HELP/doc/doc_items/init.lua +++ b/mods/HELP/doc/doc_items/init.lua @@ -255,7 +255,7 @@ local function factoid_toolcaps(tool_capabilities, check_uses) formstring = formstring .. miningtimesstr end if useslines > 0 then - formstring = formstring .. S("Mining durability:") .. "\n" + formstring = formstring .. S("Durability:") .. "\n" formstring = formstring .. miningusesstr end if caplines > 0 or useslines > 0 or timelines > 0 then @@ -1136,6 +1136,86 @@ doc.add_category("craftitems", { end }) +doc.add_category("mobs", { + name = S("Mobs"), + description = S("different mobs"), + build_formspec = function(data, playername) + if data then + local datastring = "" + + if data.description then + datastring = datastring .. S("Description: @1", data.description) + datastring = newline2(datastring) + end + + if data.type then + datastring = datastring .. S("Type: @1", data.type) + datastring = newline2(datastring) + end + + if data.spawn_class then + datastring = datastring .. S("spawn class: @1", data.spawn_class) + datastring = newline2(datastring) + end + + if data.jump then + datastring = datastring .. S("Can Jump") + datastring = newline2(datastring) + end + + if data.fly then + datastring = datastring .. S("Can Fly") + datastring = newline2(datastring) + end + + if data.drops then + count = 0 + for _,item in ipairs(data.drops) do + count = count + 1 + end + + if count > 0 then + datastring = datastring .. S("drops: ") + datastring = newline(datastring) + + for _,item in ipairs(data.drops) do + local itemDescription = ItemStack(item.name):get_short_description() + datastring = datastring .. itemDescription + datastring = newline(datastring) + end + + datastring = newline2(datastring) + end + end + + if data.follow then + datastring = datastring .. S("follows player when these items are held:") + datastring = newline(datastring) + + if type(data.follow) == "string" then + datastring = datastring .. data.follow + datastring = newline(datastring) + else + for i=1, #data.follow do + local itemstring = data.follow[i] + local itemDescription = ItemStack(itemstring):get_short_description() + datastring = datastring .. itemDescription + datastring = newline(datastring) + end + end + + datastring = newline2(datastring) + end + + local formstring = doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) + + return formstring + else + return "label[0,1;NO DATA AVALIABLE!]" + end + end +}) + -- Register group definition stuff -- More (user-)friendly group names to replace the rather technical names -- for better understanding diff --git a/mods/HELP/doc/doc_items/locale/doc_items.de.tr b/mods/HELP/doc/doc_items/locale/doc_items.de.tr index f14c99314..c816d6efd 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.de.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.de.tr @@ -134,7 +134,7 @@ Unknown item (@1)=Unbekannter Gegenstand (@1) Itemstring: "@1"=Itemstring: „@1“ Durability: @1 uses=Haltbarkeit: @1 Benutzungen Durability: @1=Haltbarkeit: @1 -Mining durability:=Grabehaltbarkeit: +Durability:=Haltbarkeit: • @1, level @2: @3 uses=• @1, Stufe @2: @3 Benutzungen • @1, level @2: Unlimited=• @1, Stufe @2: Unbegrenzt This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=Die Rotation dieses Blocks hängt davon ab, wie sie ihn platzieren: Platzieren Sie ihn auf den Boden oder an die Decke, um ihn vertikal aufzustellen; platzieren Sie in an der Seite für eine horizontale Ausrichtung. Wenn Sie während des Bauens schleichen, wird der Block stattdessen senkrecht zur üblichen Ausrichtung rotiert. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.dk.tr b/mods/HELP/doc/doc_items/locale/doc_items.dk.tr index 1dd3eff8a..435e98779 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.dk.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.dk.tr @@ -135,7 +135,7 @@ Unknown item (@1)=ukendt genstand (@1) Itemstring: "@1"=Genstandsstreng: "@1" Durability: @1 uses=Holdbarhed: @1 anvendelser Durability: @1=Holdbarhed: @1 -Mining durability:=Udvindingsholdbarhed: +Durability:=Holdbarhed: • @1, level @2: @3 uses=• @1, level @2: @3 anvendelser • @1, level @2: Unlimited=• @1, level @2: Uendelig This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=Denne bloks rotation påvirkes af måden du placerer den på: Placér den på gulvet eller loftet for en lodret orientering; placér den på siden for en horisontal orientering. Hvis du sniger dig mens den placeres den vinkelret i stedet. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.fr.tr b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr index 269c97480..fe3a136c6 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.fr.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr @@ -135,7 +135,7 @@ Unknown item (@1)=Objet inconnu (@1) Itemstring: "@1"=Identifiant d'objet : "@1" Durability: @1 uses=Durabilité : @1 utilisations Durability: @1=Durabilité : @1 -Mining durability:=Durabilité de minage : +Durability:=Durabilité : • @1, level @2: @3 uses=• @1, niveau @2 : @3 utilisations • @1, level @2: Unlimited=• @1, niveau @2 : Illimité This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=La manière dont vous placez ce bloc affecte sa rotation : placez-le au sol ou au plafond pour une orientation verticale ; placez-le sur un coté pour une orientation horizontale. Pour le placer de manière perpendiculaire, utilisez la touche déplacement discrêt en le plaçant. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.ja.tr b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr index a2e1107de..3617081cd 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.ja.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr @@ -135,7 +135,7 @@ Unknown item (@1)=不明なアイテム (@1) Itemstring: "@1"=アイテム文字列:"@1" Durability: @1 uses=耐久度:@1回 使用 Durability: @1=耐久度:@1 -Mining durability:=採掘耐久度: +Durability:=耐久度: • @1, level @2: @3 uses=・@1, レベル @2:@3回 使用 • @1, level @2: Unlimited=・@1, レベル @2:無限 This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=このブロックの回転は、置き方に影響されます:床や天井に置くと垂直方向、横に置くと水平方向になります。スニークしながら置くと、代わって直角の方向に向きます。 diff --git a/mods/HELP/doc/doc_items/locale/doc_items.pl.tr b/mods/HELP/doc/doc_items/locale/doc_items.pl.tr index 8ff945368..efa035429 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.pl.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.pl.tr @@ -135,7 +135,7 @@ Unknown item (@1)=Nieznany przedmiot (@1) Itemstring: "@1"=Id przedmiotu: "@1" Durability: @1 uses=Wytrzymałość: @1 użyć Durability: @1=Wytrzymałość: @1 -Mining durability:=Wytrzymałość kopania: +Durability:=Wytrzymałość: • @1, level @2: @3 uses=• @1, poziom @2: @3 użyć • @1, level @2: Unlimited=• @1, poziom @2: Nielimitowane This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=Na rotację tego bloku wpływa sposób postawienia: Postaw go na podłodze lub suficie aby uzyskać pionową orientację; postaw go na boku by uzyskać poziomą orientację. Skradanie się podczas postawiania sprawia, że zostanie postawiony prostopadle. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.pt.tr b/mods/HELP/doc/doc_items/locale/doc_items.pt.tr index 648e14569..3dcc3c760 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.pt.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.pt.tr @@ -53,8 +53,8 @@ Range: 4=Range: 4 Rating @1=Classificação @1 # @1 is minimal rating, @2 is maximum rating Rating @1-@2=Classificação @1-@2 -The fall damage on this block is increased by @1%.=O dano por queda nesse bloco é aumentado em @ 1%. -The fall damage on this block is reduced by @1%.=O dano por queda nesse bloco é reduzido em @ 1%. +The fall damage on this block is increased by @1%.=O dano por queda nesse bloco é aumentado em @1%. +The fall damage on this block is reduced by @1%.=O dano por queda nesse bloco é reduzido em @1%. This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.=Esse bloco permite que a luz se propague com uma pequena perda de brilho, e a luz solar pode até passar sem perdas. This block allows light to propagate with a small loss of brightness.=Esse bloco permite que a luz se propague com uma pequena perda de brilho. This block allows sunlight to propagate without loss in brightness.=Esse bloco permite que a luz solar se propague sem perda de brilho. @@ -78,7 +78,7 @@ This block connects to this block: @1.=Esse bloco se conecta a esse bloco: @1. This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Esse bloco diminui a sua respiração e causa um dano por afogamento de @1 ponto de vida a cada 2 segundos. This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Esse bloco diminui a sua respiração e causa um dano por afogamento de @1 pontos de vida a cada 2 segundos. This block is a light source with a light level of @1.=Esse bloco é uma fonte de luz com um nível de luz de @1. -This block glows faintly with a light level of @1.=Esse bloco tem um brilho fraco com um nível de luz de @ 1. +This block glows faintly with a light level of @1.=Esse bloco tem um brilho fraco com um nível de luz de @1. This block is a building block for creating various buildings.=Esse bloco é um bloco de construção para criar vários edifícios. This block is a liquid with these properties:=Esse bloco é um líquido com as seguintes propriedades: This block is affected by gravity and can fall.=Esse bloco é afetado pela gravidade e pode cair. @@ -123,7 +123,7 @@ any level=qualquer nível level 0=nível 0 level 0-@1=nivel 0-@1 unknown=desconhecido -Unknown item (@1)=Item desconhecido +Unknown item (@1)=Item desconhecido (@1) • @1: @2= • @1: @2 HP= • @1: @2, @3= @@ -135,7 +135,7 @@ Unknown item (@1)=Item desconhecido Itemstring: "@1"= Durability: @1 uses= Durability: @1= -Mining durability:= +Durability:= • @1, level @2: @3 uses= • @1, level @2: Unlimited= This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.= diff --git a/mods/HELP/doc/doc_items/locale/doc_items.pt_BR.tr b/mods/HELP/doc/doc_items/locale/doc_items.pt_BR.tr index abcf11547..a9c219343 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.pt_BR.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.pt_BR.tr @@ -10,12 +10,12 @@ # Itemname (ca. 25%) @1 (ca. @2%)= # List separator (e.g. “one, two, three”) -, =, +, =, # Final list separator (e.g. “One, two and three”) - and = e + and = e 1 second=1 segundo A transparent block, basically empty space. It is usually left behind after digging something.=Um bloco transparente, basicamente um vazio. Isso geralmente fica no lugar de um bloco removido. -Air=Ár +Air=Ar Blocks=Blocos Building another block at this block will place it inside and replace it.=Construir outro bloco nesse bloco vai subistitui-lo. Building this block is completely silent.=Construir esse bloco é completamente silencioso. @@ -129,13 +129,13 @@ Unknown item (@1)=Item desconhecido (@1) • @1: @2, @3= • Flowing range: @1= • No flowing= -• Not renewable= -• Renewable= -• Viscosity: @1= +• Not renewable=• Não renovável +• Renewable=• Renovável +• Viscosity: @1=• Viscosidade: @1 Itemstring: "@1"= -Durability: @1 uses= -Durability: @1= -Mining durability:= +Durability: @1 uses=Durabilidade: @1 usos +Durability: @1=Durabilidade: @1 +Durability:=Durabilidade: • @1, level @2: @3 uses= • @1, level @2: Unlimited= This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.= diff --git a/mods/HELP/doc/doc_items/locale/doc_items.ru.tr b/mods/HELP/doc/doc_items/locale/doc_items.ru.tr index 08d038592..1a6e5b3df 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.ru.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.ru.tr @@ -1,8 +1,8 @@ # textdomain:doc_items -Using it as fuel turns it into: @1.=Использование в качестве топлива превращает его в: @1. +Using it as fuel turns it into: @1.=Использование в качестве топлива превращает это в: @1. @1 seconds=@1 секунд(ы) # Item count times item name -%@1×@2=%@1×@2 +@1×@2=@1×@2 # Itemname (25%) @1 (@2%)=@1 (@2%) # Itemname (<0.5%) @@ -14,111 +14,111 @@ Using it as fuel turns it into: @1.=Использование в качеств # Final list separator (e.g. “One, two and three”) and = и 1 second=1 секунда -A transparent block, basically empty space. It is usually left behind after digging something.=Один прозрачный блок, основное пустое пространство. Обычно оно остаётся, если выкопать что-то. +A transparent block, basically empty space. It is usually left behind after digging something.=Прозрачный блок, проще говоря, пустое пространство. Обычно оно остаётся, если выкопать что-то. Air=Воздух Blocks=Блоки Building another block at this block will place it inside and replace it.=Возведение другого блока на этом блоке поместит его внутрь и заменит. -Building this block is completely silent.=Строительство этого блока абсолютно бесшумное. +Building this block is completely silent.=Строительство этого блока не издает звука. Collidable: @1=Непроходимый: @1 Description: @1=Описание: @1 Falling blocks can go through this block; they destroy it when doing so.=Падающие блоки могут пройти сквозь этот блок; при этом они уничтожат его. Full punch interval: @1 s=Интервал полного удара: @1 с Hand=Рука -Hold it in your hand, then leftclick to eat it.=Возьмите это в руку и кликните левой, чтобы съесть. -Hold it in your hand, then leftclick to eat it. But why would you want to do this?=Возьмите это в руку и кликните левой, чтобы съесть. Но вам правда этого хочется? +Hold it in your hand, then leftclick to eat it.=Возьмите это в руку и кликните левой кнопкой мыши, чтобы съесть. +Hold it in your hand, then leftclick to eat it. But why would you want to do this?=Возьмите это в руку и кликните левой кнопкой мыши, чтобы съесть. Но зачем вы хотите это сделать? Item reference of all wieldable tools and weapons=Справка по всем носимым инструментам и оружию Item reference of blocks and other things which are capable of occupying space=Справка по всем блокам и другим вещам, способным занимать место -Item reference of items which are neither blocks, tools or weapons (esp. crafting items)=Справка по остальным предметам (не блокам, не инструментам и не оружию) +Item reference of items which are neither blocks, tools or weapons (esp. crafting items)=Справка по остальным предметам - не блокам, не инструментам и не оружию (так называемые материалы для крафта) Liquids can flow into this block and destroy it.=Жидкости могут затекать в этот блок, уничтожая его. -Maximum stack size: @1=Максимальный размер стека: @1 -Mining level: @1=Уровень добываемости: @1 -Mining ratings:=Рейтинг добываемости: +Maximum stack size: @1=Максимальный размер стака: @1 +Mining level: @1=Уровень добывания: @1 +Mining ratings:=Рейтинг добывания: • @1, rating @2: @3 s - @4 s=• @1, рейтинг @2: @3 с - @4 с • @1, rating @2: @3 s=• @1, рейтинг @2: @3 с -Mining times:=Время добывания: -Mining this block is completely silent.=Добывание этого блока происходит абсолютно бесшумно. +Mining times:=Добыто раз: +Mining this block is completely silent.=Добывание этого блока не издает звука. Miscellaneous items=Дополнительные предметы No=Нет -Pointable: No=Ориентируемый: Нет -Pointable: Only by special items=Ориентируемый: Только специальными предметами -Pointable: Yes=Ориентируемый: Да -Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.=Удар этого блока не работает так, как это обычно бывает; рукопашный бой и майнинг либо невозможны, либо работают по-другому. -Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.=Удар этого предмета не работает так, как это обычно бывает; рукопашный бой и майнинг либо невозможны, либо работают по-другому. -Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.=Удар этого инструмента не работает так, как это обычно бывает; рукопашный бой и майнинг либо невозможны, либо работают по-другому. +Pointable: No=Наводимый: нет +Pointable: Only by special items=Наводимый: только специальными предметами +Pointable: Yes=Наводимый: да +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.=Удар этим блоком работает не так, как обычно; ближний бой и копание либо невозможны, либо работают по-другому. +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.=Удар этим предметом работает не так, как обычно; ближний бой и копание либо невозможны, либо работают по-другому. +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.=Удар этим инструментом работает не так, как обычно; ближний бой и копание либо невозможны, либо работают по-другому. Range: @1=Дальность: @1 # Range: () Range: @1 (@2)=Дальность: @1 (@2) Range: 4=Дальность: 4 # Rating used for digging times -Rating @1=Скорость копания @1 +Rating @1=Скорость добывания @1 # @1 is minimal rating, @2 is maximum rating -Rating @1-@2=Скорость копания @1-@2= -The fall damage on this block is increased by @1%.=Повреждение при падении на этот блок увеличивается на @1%. -The fall damage on this block is reduced by @1%.=Повреждение при падении на этот блок уменьшается на @1%. +Rating @1-@2=Скорость добывания @1-@2= +The fall damage on this block is increased by @1%.=При падении на этот блок получаемый урон увеличивается на @1%. +The fall damage on this block is reduced by @1%.=При падении на этот блок получаемый урон уменьшается на @1%. This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.=Этот блок позволяет свету распространяться с небольшой потерей яркости, а солнечный свет может проходить без потерь. This block allows light to propagate with a small loss of brightness.=Этот блок позволяет свету распространяться с небольшой потерей яркости. This block allows sunlight to propagate without loss in brightness.=Этот блок позволяет солнечному свету распространяться без потери яркости. This block belongs to the @1 group.=Этот блок принадлежит группе @1. This block belongs to these groups: @1.=Этот блок принадлежит группам: @1. -This block can be climbed.=На этот блок можно залезть. +This block can be climbed.=По этому блоку можно карабкаться. This block can be destroyed by any mining tool immediately.=Этот блок можно мгновенно уничтожить любым добывающим инструментом. This block can be destroyed by any mining tool in half a second.=Этот блок можно уничтожить любым добывающим инструментом за полсекунды. This block can be mined by any mining tool immediately.=Этот блок можно мгновенно добыть любым добывающим инструментом. This block can be mined by any mining tool in half a second.=Этот блок можно добыть любым добывающим инструментом за полсекунды. -This block can be mined by mining tools which match any of the following mining ratings and its toughness level.=Этот блок можно добыть любым инструментами добычи, соответствующим одному из следующих рейтингов и уровней жёсткости. -This block can not be destroyed by ordinary mining tools.=Этот блок нельзя уничтожить обычным инструментом добычи. -This block can not be mined by ordinary mining tools.=Этот блок нельзя добыть обычным инструментом добычи. -This block can serve as a smelting fuel with a burning time of @1.=Этот блок может служить плавящимся топливом с временем горения @1. -This block causes a damage of @1 hit point per second.=Этот блок вызывает повреждение на @1 HP в секунду. -This block causes a damage of @1 hit points per second.=Этот блок вызывает повреждения на @1 HP в секунду. +This block can be mined by mining tools which match any of the following mining ratings and its toughness level.=Этот блок можно добыть любым добывающим инструментом, соответствующим одному из следующих рейтингов и его уровню твёрдости. +This block can not be destroyed by ordinary mining tools.=Этот блок нельзя уничтожить добывающим инструментом. +This block can not be mined by ordinary mining tools.=Этот блок нельзя добыть обычным добывающим инструментом. +This block can serve as a smelting fuel with a burning time of @1.=Этот блок можно использовать как топливо со временем горения @1. +This block causes a damage of @1 hit point per second.=Этот блок наносит урон в @1 единицу здоровья в секунду. +This block causes a damage of @1 hit points per second.=Этот блок наносит урон в @1 единиц здоровья в секунду. This block connects to blocks of the @1 group.=Этот блок соединяется с блоками группы @1. This block connects to blocks of the following groups: @1.=Этот блок соединяется с блоками групп: @1. This block connects to these blocks: @1.=Этот блок соединяется со следующими блоками: @1. This block connects to this block: @1.=Этот блок соединяется с этим блоком: @1. -This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Этот блок уменьшает ваш кислород и вызывает повреждение от погружения на @1 HP каждые 2 секунды. -This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Этот блок уменьшает ваш кислород и вызывает повреждения от погружения на @1 HP каждые 2 секунды. +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Этот блок уменьшает ваш запас кислорода и наносит урон от утопления в @1 единицу здоровья каждые 2 секунды. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Этот блок уменьшает ваш запас кислорода и наносит урон от утопления в @1 единиц здоровья каждые 2 секунды. This block is a light source with a light level of @1.=Этот блок является источником света уровня @1. This block glows faintly with a light level of @1.=Этот блок мерцает с уровнем света: @1. -This block is a building block for creating various buildings.=Это строительный блок для создания разных конструкций и зданий. -This block is a liquid with these properties:=Это жидкий блок с такими свойствами: +This block is a building block for creating various buildings.=Это строительный блок для создания разных конструкций. +This block is a liquid with these properties:=Это жидкий блок со следующими свойствами: This block is affected by gravity and can fall.=На этот блок действует гравитация, он может падать. -This block is completely silent when mined or built.=Этот блок абсолютно бесшумно добывается и устанавливается при строительстве. -This block is completely silent when walked on, mined or built.=Этот блок абсолютно тихий, он не шумит, если вы идёте по нему, добываете его или строите что-либо из него. +This block is completely silent when mined or built.=Этот блок не издает звуков когда добывается и устанавливается при строительстве. +This block is completely silent when walked on, mined or built.=Этот блок не издает звуков когда вы идёте по нему, добываете его или строите из него. This block is destroyed when a falling block ends up inside it.=Этот блок уничтожается, когда падающий блок попадает в него. This block negates all fall damage.=Этот блок отменяет весь урон от падения. This block points to liquids.=Этот блок указывает на жидкости. This block will drop as an item when a falling block ends up inside it.=Этот блок выпадет как предмет, когда падающий блок попадёт в него. This block will drop as an item when it is not attached to a surrounding block.=Этот блок выпадет как предмет, если он не прикреплён к окружающим блокам. This block will drop as an item when no collidable block is below it.=Этот блок выпадет как предмет, если нет непроходимого блока прямо под ним. -This block will drop the following items when mined: @1.=Этот блок будет выдавать следующие предметы при его добыче: @1. -This block will drop the following when mined: @1×@2.=Этот блок будет выдавать при его добыче: @1×@2. -This block will drop the following when mined: @1.=Этот блок будет выдавать при его добыче: @1. -This block will drop the following when mined: @1.=Этот блок будет выдавать при его добыче: @1. +This block will drop the following items when mined: @1.=При добыче из этого блока выпадут следующие предметы: @1. +This block will drop the following when mined: @1×@2.=При добыче из этого блока выпадет следующее: @1×@2. +This block will drop the following when mined: @1.=При добыче из этого блока выпадет следующее: @1. +This block will drop the following when mined: @1.=При добыче из этого блока выпадет следующее: @1. This block will make you bounce off with an elasticity of @1%.=Этот блок заставит вас отскакивать с упругостью @1%. -This block will randomly drop one of the following when mined: @1.=При добыче этот блок случайным образом выдаёт что-то из списка: @1. -This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=Этот блок случайным образом выдаст до @1 из следующих возможных выдач при добыче: @2. -This block won't drop anything when mined.=Этот блок ничего не выдаст при его добыче. +This block will randomly drop one of the following when mined: @1.=При добыче из этого блока случайным образом выпадает что-то одно из списка: @1. +This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=При добыче из этого блока случайным образом выпадает до @1 из следующих возможных выдач: @2. +This block won't drop anything when mined.=При добыче из этого блока не выпадет ничего. This is a decorational block.=Это декоративный блок. This is a melee weapon which deals damage by punching.=Это орудие ближнего боя, наносящее урон при ударе. Maximum damage per hit:=Максимальный урон за один удар: This item belongs to the @1 group.=Этот предмет относится к группе @1. This item belongs to these groups: @1.=Этот предмет относится к группам: @1. -This item can serve as a smelting fuel with a burning time of @1.=Этот предмет может служить плавящимся топливом с временем горения @1. -This item is primarily used for crafting other items.=Этот предмет в основном используется для создания других предметов. +This item can serve as a smelting fuel with a burning time of @1.=Этот предмет можно использовать как топливо со временем горения @1. +This item is primarily used for crafting other items.=Этот предмет в основном используется для крафта других предметов. This item points to liquids.=Этот предмет указывает на жидкости. This tool belongs to the @1 group.=Этот инструмент относится к группе @1. This tool belongs to these groups: @1.=Этот инструмент относится к группам: @1. -This tool can serve as a smelting fuel with a burning time of @1.=Этот инструмент может служить плавящимся топливом с временем горения @1. +This tool can serve as a smelting fuel with a burning time of @1.=Этот инструмент можно использовать как топливо со временем горения @1. This tool is capable of mining.=Этот инструмент используется для добычи. -Maximum toughness levels:=Максимальный уровень жёсткости: +Maximum toughness levels:=Максимальный уровень твёрдости: This tool points to liquids.=Этот инструмент указывает на жидкости. Tools and weapons=Инструменты и оружие -Unknown Node=Неизвестный узел -Usage help: @1=Использование помощи: @1 -Walking on this block is completely silent.=Хождение по этому блоку абсолютно бесшумное. +Unknown Node=Неизвестный блок +Usage help: @1=Помощь по использованию: @1 +Walking on this block is completely silent.=Хождение по этому блоку не издает звуков. Whenever you are not wielding any item, you use the hand which acts as a tool with its own capabilities. When you are wielding an item which is not a mining tool or a weapon it will behave as if it would be the hand.=Даже если вы не держите никакого предмета, ваша рука - сама по себе инструмент, обладающий определёнными свойствами. Когда в вашей руке предмет, не являющийся инструментом добычи или оружием, он будет иметь свойства вашей пустой руки. Yes=Да -You can not jump while standing on this block.=Вы не можете прыгать, стоя на этом блоке. +You can not jump while standing on this block.=Вы не можете прыгать, пока стоите на этом блоке. any level=любой уровень level 0=уровень 0 level 0-@1=уровень 0-@1 @@ -129,15 +129,15 @@ Unknown item (@1)=Неизвестный предмет (@1) • @1: @2, @3=• @1: @2, @3 • Flowing range: @1=• Дальность потока: @1 • No flowing=• Не текучее -• Not renewable=• Необновляемое -• Renewable=• Обновляемое +• Not renewable=• Невозобновляемое +• Renewable=• Возобновляемое • Viscosity: @1=• Вязкость: @1 -Itemstring: "@1"=Айтемстринг: "@1" -Durability: @1 uses=Долговечность: @1 раз(а) -Durability: @1=Долговечность: @1 -Mining durability:=Долговечность при майнинге: +Itemstring: "@1"=Техническое название: "@1" +Durability: @1 uses=Прочность: @1 использований +Durability: @1=Прочность: @1 +Durability:=Прочность: • @1, level @2: @3 uses=• @1, уровень @2: @3 раз(а) • @1, level @2: Unlimited=• @1, уровень @2: Неограниченно -This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=Вращение этого блока зависит от способа размещения: положите его на пол или потолок для вертикальной ориентации; поместите на стену для горизонтальной ориентации. Удерживайте [Красться] при размещении для перпендикулярной ориентации. -Toughness level: @1=Уровень жёсткости: @1 +This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.=Поворот этого блока зависит от того как вы его ставите: поставьте его на пол или потолок для вертикальной ориентации; поместите на стену для горизонтальной ориентации. Удерживайте [Красться] при размещении для перпендикулярной ориентации. +Toughness level: @1=Уровень твёрдости: @1 This block is slippery.=Этот блок скользкий. diff --git a/mods/HELP/doc/doc_items/locale/template.txt b/mods/HELP/doc/doc_items/locale/template.txt index 77f107863..8ddcc553d 100644 --- a/mods/HELP/doc/doc_items/locale/template.txt +++ b/mods/HELP/doc/doc_items/locale/template.txt @@ -135,7 +135,7 @@ Unknown item (@1)= Itemstring: "@1"= Durability: @1 uses= Durability: @1= -Mining durability:= +Durability:= • @1, level @2: @3 uses= • @1, level @2: Unlimited= This block's rotation is affected by the way you place it: Place it on the floor or ceiling for a vertical orientation; place it at the side for a horizontal orientation. Sneaking while placing it leads to a perpendicular orientation instead.= diff --git a/mods/HELP/mcl_craftguide/README.md b/mods/HELP/mcl_craftguide/README.md index f02ad3462..173e297a8 100644 --- a/mods/HELP/mcl_craftguide/README.md +++ b/mods/HELP/mcl_craftguide/README.md @@ -1,4 +1,4 @@ -# Crafting Guide (MineClone 2 edition) +# Crafting Guide (VoxeLibre edition) #### `mcl_craftguide` is based on, `craftguide` the most comprehensive crafting guide on Minetest. #### Consult the [Minetest Wiki](http://wiki.minetest.net/Crafting_guide) for more details. diff --git a/mods/HELP/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index 5e3686047..2e5e0ea63 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -106,6 +106,31 @@ local item_lists = { "craftpreview", } +local function init_data(name) + player_data[name] = { + filter = "", + pagenum = 1, + iX = sfinv_only and 8 or DEFAULT_SIZE, + items = init_items, + items_raw = init_items, + lang_code = M.get_player_information(name).lang_code or 'en', + } +end +local function get_player_data(name) + -- If the data alrady exists, use it + local data = player_data[name] + if data then return data end + + -- Initialize player data if it doesn't exist + init_data(name) + local player = minetest.get_player_by_name(name) + local meta = player:get_meta() + local data = player_data[name] + + data.inv_items = deserialize(meta:get_string("inv_items")) or {} + return data +end + local function table_merge(t, t2) t, t2 = t or {}, t2 or {} local c = #t @@ -624,7 +649,7 @@ local function get_recipe_fs(data, iY) end local function make_formspec(name) - local data = player_data[name] + local data = get_player_data(name) local iY = sfinv_only and 4 or data.iX - 5 local ipp = data.iX * iY @@ -653,6 +678,7 @@ local function make_formspec(name) image_button[2.4,0.12;0.8,0.8;craftguide_search_icon.png;search;] image_button[3.05,0.12;0.8,0.8;craftguide_clear_icon.png;clear;] field_close_on_enter[filter;false] + field_enter_after_edit[filter;true] ]] fs[#fs + 1] = fmt([[ tooltip[search;%s] @@ -774,7 +800,7 @@ local function search(data) for i = 1, #data.items_raw do local item = data.items_raw[i] local def = reg_items[item] - local desc = lower(def.description) + local desc = string.lower(M.get_translated_string(data.lang_code, def.description)) local search_in = item .. desc local to_add @@ -831,16 +857,6 @@ local function get_inv_items(player) return inv_items end -local function init_data(name) - player_data[name] = { - filter = "", - pagenum = 1, - iX = sfinv_only and 8 or DEFAULT_SIZE, - items = init_items, - items_raw = init_items, - } -end - local function reset_data(data) data.filter = "" data.pagenum = 1 @@ -876,7 +892,7 @@ end local function on_receive_fields(player, fields) local name = player:get_player_name() - local data = player_data[name] + local data = get_player_data(name) for elem_name, def in pairs(formspec_elements) do if fields[elem_name] and def.action then @@ -980,7 +996,7 @@ if sfinv_only then on_enter = function(self, player, context) if next(recipe_filters) then local name = player:get_player_name() - local data = player_data[name] + local data = get_player_data(name) data.items_raw = get_filtered_items(player) search(data) @@ -1004,7 +1020,7 @@ else local name = user:get_player_name() if next(recipe_filters) then - local data = player_data[name] + local data = get_player_data(name) data.items_raw = get_filtered_items(user) search(data) end @@ -1050,7 +1066,7 @@ if progressive_mode then local function progressive_filter(recipes, player) local name = player:get_player_name() - local data = player_data[name] + local data = get_player_data(name) if #data.inv_items == 0 then return {} @@ -1075,7 +1091,7 @@ if progressive_mode then for i = 1, #players do local player = players[i] local name = player:get_player_name() - local data = player_data[name] + local data = get_player_data(name) local inv_items = get_inv_items(player) local diff = table_diff(inv_items, data.inv_items) @@ -1094,12 +1110,7 @@ if progressive_mode then mcl_craftguide.add_recipe_filter("Default progressive filter", progressive_filter) M.register_on_joinplayer(function(player) - local name = player:get_player_name() - init_data(name) - local meta = player:get_meta() - local data = player_data[name] - - data.inv_items = deserialize(meta:get_string("inv_items")) or {} + get_player_data(player:get_player_name()) end) local function save_meta(player) @@ -1144,7 +1155,7 @@ end function mcl_craftguide.show(name) local player = get_player_by_name(name) if next(recipe_filters) then - local data = player_data[name] + local data = get_player_data(name) data.items_raw = get_filtered_items(player) search(data) end diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pt_BR.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pt_BR.tr new file mode 100644 index 000000000..d5bf41235 --- /dev/null +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pt_BR.tr @@ -0,0 +1,37 @@ +# textdomain: craftguide +Any shulker box=Qualquer caixa shulker +Any wool=Qualquer lã +Any wood planks=Quaisquer tábuas de madeira +Any wood=Qualquer madeira +Any sand=Qualquer areia +Any normal sandstone=Qualquer arenito normal +Any red sandstone=Qualquer arenito vermelho +Any carpet=Qualquer carpete +Any dye=Qualquer tintura +Any water bucket=Qualquer balde de água +Any flower=Qualquer flor +Any mushroom=Qualquer cogumelo +Any wooden slab=Qualquer laje de madeira +Any wooden stairs=Quaisquer escadas de madeira +Any coal=Qualquer carvão +Any kind of quartz block=Qualquer tipo de bloco de quartzo +Any kind of purpur block=Qualquer tipo de bloco de purpúra +Any stone bricks=Quaisquer tijolos de pedra +Any stick=Qualquer graveto +Any item belonging to the @1 group=Qualquer item pertencente ao grupo @1 +Any item belonging to the groups: @1=Qualquer item pertencente aos grupos: @1 +Search=Pesquisar +Reset=Resetar +Previous page=Página anterior +Next page=Página posterior +Usage @1 of @2=Uso @1 de @2 +Recipe @1 of @2=Receita @1 de @2 +Burning time: @1=Tempo de queima: @1 +Cooking time: @1=Tempo de cozimento: @1 +Recipe is too big to be displayed (@1×@2)=Receita é muito grande para ser mostrada (@1x@2) +Shapeless=Sem forma +Cooking=Cozimento +Increase window size=Aumentar tamanho da janela +Decrease window size=Diminuir tamanho da janela +No item to show=Nenhum item para mostrar +Collect items to reveal more recipes=Colete itens para revelar mais receitas diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr index ae2f28a9c..58f7cf5a9 100644 --- a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ru.tr @@ -2,29 +2,29 @@ Any shulker box=Любой ящик шалкера Any wool=Любая шерсть Any wood planks=Любые доски -Any wood=Любое дерево +Any wood=Любая древесина Any sand=Любой песок Any normal sandstone=Любой обычный песчаник Any red sandstone=Любой красный песчаник -Any carpet=Любое покрытие +Any carpet=Любой ковёр Any dye=Любой краситель Any water bucket=Любое ведро воды Any flower=Любой цветок Any mushroom=Любой гриб Any wooden slab=Любая деревянная плита -Any wooden stairs=Любые деревянные ступеньки +Any wooden stairs=Любые деревянные ступени Any coal=Любой уголь Any kind of quartz block=Любой кварцевый блок -Any kind of purpur block=Любой фиолетовый блок -Any stone bricks=Любые каменные блоки +Any kind of purpur block=Любой пурпурный блок +Any stone bricks=Любые каменные кирпичи Any stick=Любая палка -Any item belonging to the @1 group=Любой предмет, относящийся к группе @1 -Any item belonging to the groups: @1=Любой предмет, относящийся к группам: @1 +Any item belonging to the @1 group=Любой предмет из группы @1 +Any item belonging to the groups: @1=Любой предмет из группам: @1 Search=Поиск Reset=Сброс Previous page=Предыдущая страница Next page=Следующая страница -Usage @1 of @2=Использование @1 из @2 +Usage @1 of @2=Использование @1 из @2 Recipe @1 of @2=Рецепт @1 из @2 Burning time: @1=Время горения: @1 Cooking time: @1=Время приготовления: @1 @@ -33,5 +33,5 @@ Shapeless=Бесформенный Cooking=Приготовление Increase window size=Увеличить окно Decrease window size=Уменьшить окно -No item to show=Нет элемента для показа -Collect items to reveal more recipes=Для рецептов нужны предметы +No item to show=Нет предмета для показа +Collect items to reveal more recipes=Собирайте предметы, чтобы открыть больше рецептов diff --git a/mods/HELP/mcl_doc/init.lua b/mods/HELP/mcl_doc/init.lua index 4ba387e12..034e7f38c 100644 --- a/mods/HELP/mcl_doc/init.lua +++ b/mods/HELP/mcl_doc/init.lua @@ -374,7 +374,7 @@ doc.sub.items.register_factoid("tools", "misc", function(itemstring, def) capstr = capstr .. S("Mining speed: @1", speedstr) .. "\n" end if miningusesstr ~= "" then - capstr = capstr .. S("Mining durability: @1", miningusesstr) .. "\n" + capstr = capstr .. S("Durability: @1", miningusesstr) .. "\n" end -- Only show one group at max diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.de.tr b/mods/HELP/mcl_doc/locale/mcl_doc.de.tr index e929f9aec..5d64b387e 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.de.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.de.tr @@ -70,7 +70,7 @@ Instantaneous=Unmittelbar @1 uses=@1 Verwendungen Unlimited uses=Unbegrenzte Verwendungen Block breaking strength: @1=Blockbruchstärke: @1 -Mining durability: @1=Grabehaltbarkeit: @1 +Durability: @1=Haltbarkeit: @1 Armor points: @1=Rüstungspunkte: @1 Armor durability: @1=Rüstungshaltbarkeit: @1 It can be worn on the head.=Es kann auf dem Kopf getragen werden. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr b/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr index 7dfc40fdf..d4e45b1fa 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr @@ -70,7 +70,7 @@ Instantaneous=Momentan @1 uses=@1 anvendelser Unlimited uses=Uendelige anvendelser Block breaking strength: @1=Blokkens brudstyrke: @1 -Mining durability: @1=Udvindingsholdbarhed: @1 +Durability: @1=Holdbarhed: @1 Armor points: @1=Rustningspoint: @1 Armor durability: @1=Rustningens holdbarhed: @1 It can be worn on the head.=Den kan bæres på hovedet. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr b/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr index 529615821..9126a08de 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr @@ -6,7 +6,7 @@ This block can be turned into grass path with a shovel.=Ce bloc peut être trans This block acts as a soil for all saplings.=Ce bloc agit comme un sol pour tous les pousses arbres. This block acts as a soil for some saplings.=Ce bloc agit comme un sol pour certains pousses arbres. Sugar canes will grow on this block.=Les cannes à sucre pousseront sur ce bloc. -Nether wart will grow on this block.=La verrue du Néant se développera sur ce bloc. +Nether wart will grow on this block.=La verrue du Nether se développera sur ce bloc. This block quickly decays when there is no wood block of any species within a distance of @1. When decaying, it disappears and may drop one of its regular drops. The block does not decay when the block has been placed by a player.=Ce bloc se désintègre rapidement lorsqu'il n'y a aucun bloc de bois de n'importe quel espèce à une distance de @1. En décomposition, il disparaît et peut lâcher un des ses objets habituels. Le bloc ne se désintègre pas lorsque le bloc a été placé par un joueur. This block quickly decays and disappears when there is no wood block of any species within a distance of @1. The block does not decay when the block has been placed by a player.=Ce bloc se désintègre rapidement et disparaît lorsqu'il n'y a aucun bloc de bois de n'importe quel espèce à une distance de @1. Le bloc ne se désintègre pas lorsque le bloc a été placé par un joueur. This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=Cette plante ne peut pousser que sur des blocs d'herbe et de terre. Pour survivre, il doit avoir une vue dégagée sur le ciel au-dessus ou être exposé à un niveau de lumière de 8 ou plus. @@ -71,7 +71,7 @@ Instantaneous=Instantané @1 uses=@1 utilisations Unlimited uses=Utilisations illimitées Block breaking strength: @1=Résistance de rupture de bloc : @1 -Mining durability: @1=Durabilité de minage : @1 +Durability: @1=Durabilité : @1 Armor points: @1=Point d'armure : @1 Armor durability: @1=Durabilité de l'armure : @1 It can be worn on the head.=Il peut être porté sur la tête. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr index 0cef853c8..0d00f4a3a 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr @@ -70,7 +70,7 @@ Instantaneous=瞬間的 @1 uses=@1 使用 Unlimited uses=無限に使用可能 Block breaking strength: @1=ブロック破壊力:@1 -Mining durability: @1=採掘耐久度:@1 +Durability: @1=耐久性:@1 Armor points: @1=防具値:@1 Armor durability: @1=防具耐久度:@1 It can be worn on the head.=頭に装着することもできます。 diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr b/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr index c451c8c39..015b0c45f 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr @@ -70,7 +70,7 @@ Instantaneous=Natychmiastowe @1 uses=@1 użyć Unlimited uses=Nielimitowane użycia Block breaking strength: @1=Siła niszczenia bloku: @1 -Mining durability: @1=Wytrzymałość kopania: @1 +Durability: @1=Wytrzymałość: @1 Armor points: @1=Punkty zbroi: @1 Armor durability: @1=Wytrzymałość zbroi: @1 It can be worn on the head.=Może być noszony na głowie. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.ru.tr b/mods/HELP/mcl_doc/locale/mcl_doc.ru.tr index 2deeb8e73..ce2da5a5d 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.ru.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.ru.tr @@ -1,33 +1,33 @@ # textdomain: mcl_doc 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 acts as a soil for all saplings.=Этот блок служит почвой для всех саженцев. This block acts as a soil for some saplings.=Этот блок служит почвой для некоторых саженцев. Sugar canes will grow on this block.=На этом блоке будет расти сахарный тростник. -Nether wart will grow on this block.=Адский нарост будет расти на этом блоке. -This block quickly decays when there is no wood block of any species within a distance of @1. When decaying, it disappears and may drop one of its regular drops. The block does not decay when the block has been placed by a player.=Этот блок быстро разрушается, когда на расстоянии @1 нет древесных блоков любого вида. При распаде он исчезает и может уронить одну из своих обычных капель. Блок не разрушается, если он размещен игроком. -This block quickly decays and disappears when there is no wood block of any species within a distance of @1. The block does not decay when the block has been placed by a player.=Этот блок быстро распадается и исчезает, если на расстоянии @1 нет древесных блоков любого типа. Блок не разрушается, если он размещен игроком. -This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=Это растение может расти только на блоках травы и грязи. Чтобы выжить, ему нужно иметь беспрепятственный обзор неба или подвергаться воздействию света уровня 8 или выше. -This plant can grow on grass blocks, podzol, dirt and coarse dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=Это растение может расти на блоках травы, подзола и твёрдой грязи. Чтобы выжить, ему нужно иметь беспрепятственный обзор неба или подвергаться воздействию света уровня 8 или выше. -This block is flammable.=Этот блок легковоспламеним. -This block destroys any item it touches.=Этот блок уничтожает всё, к чему прикасается. -To eat it, wield it, then rightclick.=Чтобы съесть это, возьмите в руки и кликните правой клавишей. +Nether wart will grow on this block.=На этом блоке будет расти адский нарост. +This block quickly decays when there is no wood block of any species within a distance of @1. When decaying, it disappears and may drop one of its regular drops. The block does not decay when the block has been placed by a player.=Этот блок быстро саморазрушается, если на дистанции @1 метров отсутствуют блоки дерева любого типа. При разрушении может выпасть его обычный дроп. Блок не саморазрушается если он был поставлен игроком. +This block quickly decays and disappears when there is no wood block of any species within a distance of @1. The block does not decay when the block has been placed by a player.=Этот блок быстро саморазрушается и исчезает, если на дистанции @1 метров отсутствуют блоки дерева любого типа. Блок не саморазрушается если он был поставлен игроком. +This plant can only grow on grass blocks and dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=Это растение может расти только на блоках дёрна и грязи. Для жизни ему нужно иметь беспрепятственный обзор на небо сверху, либо уровень света 8 и выше. +This plant can grow on grass blocks, podzol, dirt and coarse dirt. To survive, it needs to have an unobstructed view to the sky above or be exposed to a light level of 8 or higher.=Это растение может расти только на блоках дёрна, грязи, подзола и твёрдой земли. Для жизни ему нужно иметь беспрепятственный обзор на небо сверху, либо уровень света 8 и выше. +This block is flammable.=Этот блок воспламеним. +This block destroys any item it touches.=Этот блок уничтожает любой предмет, который его касается. +To eat it, wield it, then rightclick.=Чтобы съесть это, возьмите в руки и кликните правой кнопкой мыши. You can eat this even when your hunger bar is full.=Вы можете есть это, даже когда ваша полоска голода заполнена. You cannot eat this when your hunger bar is full.=Вы не можете есть это, когда ваша полоска голода заполнена. -To drink it, wield it, then rightclick.=Чтобы выпить это, возьмите его в руки и кликните правой клавишей мыши. +To drink it, wield it, then rightclick.=Чтобы выпить это, возьмите его в руки и кликните правой кнопкой мыши. You cannot drink this when your hunger bar is full.=Вы не можете пить это, когда ваша полоска голода заполнена. -To consume it, wield it, then rightclick.=Чтобы употребить это, возьмите в руки и кликните правой клавишей мыши. +To consume it, wield it, then rightclick.=Чтобы употребить это, возьмите в руки и кликните правой кнопкой мыши. You cannot consume this when your hunger bar is full.=Вы не можете употребить это, когда ваша полоска голода заполнена. You have to wait for about 2 seconds before you can eat or drink again.=Вам нужно подождать 2 секунды, прежде чем снова пить или есть. -Hunger points restored: @1=Восстановлено единиц голода: @1 -Saturation points restored: @1%.1f=Восстановлено единиц сытости: @1 +Hunger points restored: @1=Восстанавливает очков голода: @1 +Saturation points restored: @1%.1f=Восстанавливает очков насыщения: @1 This item can be repaired at an anvil with: @1.=Этот предмет можно починить на наковальне при помощи: @1. This item can be repaired at an anvil with any wooden planks.=Этот предмет можно починить на наковальне с помощью любых деревянных досок. This item can be repaired at an anvil with any item in the “@1” group.=Этот предмет можно починить на наковальне с помощью любого предмета из группы “@1”. -This item cannot be renamed at an anvil.=Этот предмет нельзя починить в наковальне. -This block crushes any block it falls into.=Этот блок сокрушает любой блок, на который падает. -When this block falls deeper than 1 block, it causes damage to any player it hits. The damage dealt is B×2−2 hit points with B @= number of blocks fallen. The damage can never be more than 40 HP.=Когда этот блок падает 1 блока, то наносит урон задеваемому игроку. Повреждение составляет B×2–2 единиц удара, где B @= количество упавших блоков. Урон не может превышать 40 HP. +This item cannot be renamed at an anvil.=Этот предмет нельзя переименовать на наковальне. +This block crushes any block it falls into.=Этот блок ломает любой блок, на который падает. +When this block falls deeper than 1 block, it causes damage to any player it hits. The damage dealt is B×2−2 hit points with B @= number of blocks fallen. The damage can never be more than 40 HP.=Когда этот блок падает вниз на 1 блок, он наносит урон игроку, который заденет этот блок. Урон рассчитывается как Z×2–2 единиц здоровья, где Z это высота полета в блоках. Урон не может превышать 40 единиц здоровья. Diamond Pickaxe=Алмазная кирка Iron Pickaxe=Железная кирка Stone Pickaxe=Каменная кирка @@ -45,35 +45,35 @@ Golden Shovel=Золотая лопата Wooden Shovel=Деревянная лопата This block can be mined by any tool instantly.=Этот блок можно мгновенно добыть любым инструментом. This block can be mined by:=Этот блок можно добыть при помощи: -Hardness: ∞=Твердость: ∞ -Hardness: @1=Твердость: @1 -This block will not be destroyed by TNT explosions.=Этот блок не уничтожат взрывы тротила. -This block drops itself when mined by shears.=Этот блок сбрасывается сам при добыче ножницами. +Hardness: ∞=Твёрдость: ∞ +Hardness: @1=Твёрдость: @1 +This block will not be destroyed by TNT explosions.=Этот блок не будет уничтожен при взрыве ТНТ. +This block drops itself when mined by shears.=При добыче этого блока ножницами выпадает этот же блок. @1×@2=@1×@2 -This blocks drops the following when mined by shears: @1=Этот блок при добыче ножницами выбрасывает следующее: @1 +This blocks drops the following when mined by shears: @1=При добыче этого блока ножницами выпадает следующее: @1 , = , • Shears=• Ножницы • Sword=• Меч • Hand=• Рука This is a melee weapon which deals damage by punching.=Это оружие ближнего боя, оно наносит урон при ударе. Maximum damage: @1 HP=Максимальный урон: @1 HP -Full punch interval: @1 s=Интервал полного удара: @1 с +Full punch interval: @1 s=Интервал удара: @1 с This tool is capable of mining.=Этим инструментом можно добывать Mining speed: @1=Скорость добычи: @1 -Painfully slow=Мучительно медленно -Very slow=Очень медленно -Slow=Медленно -Fast=Быстро -Very fast=Очень быстро -Extremely fast=Ужасно быстро -Instantaneous=Мгновенно -@1 uses=@1 раз(а) +Painfully slow=крайне медленно +Very slow=очень медленно +Slow=медленно +Fast=быстро +Very fast=очень быстро +Extremely fast=экстремально быстро +Instantaneous=мгновенно +@1 uses=@1 Unlimited uses=не ограничено -Block breaking strength: @1=Прочность блока на разрыв: @1 -Mining durability: @1=Долговечность при добыче: @1 -Armor points: @1=Эффективность защиты: @1 -Armor durability: @1=Долговечность защиты: @1 +Block breaking strength: @1=Сила добычи: @1 +Durability: @1=Прочность: @1 +Armor points: @1=Очки брони: @1 +Armor durability: @1=Прочность брони: @1 It can be worn on the head.=Это можно носить на голове. -It can be worn on the torso.=Это можно носить на теле. +It can be worn on the torso.=Это можно носить на торсе. It can be worn on the legs.=Это можно носить на ногах. It can be worn on the feet.=Это можно носить на ступнях. diff --git a/mods/HELP/mcl_doc/locale/template.txt b/mods/HELP/mcl_doc/locale/template.txt index ec825644c..2d4e20044 100644 --- a/mods/HELP/mcl_doc/locale/template.txt +++ b/mods/HELP/mcl_doc/locale/template.txt @@ -71,7 +71,7 @@ Instantaneous= @1 uses= Unlimited uses= Block breaking strength: @1= -Mining durability: @1= +Durability: @1= Armor points: @1= Armor durability: @1= It can be worn on the head.= diff --git a/mods/HELP/mcl_doc/mod.conf b/mods/HELP/mcl_doc/mod.conf index d939761d5..080a69252 100644 --- a/mods/HELP/mcl_doc/mod.conf +++ b/mods/HELP/mcl_doc/mod.conf @@ -1,4 +1,4 @@ name = mcl_doc author = Wuzzy -description = This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2. +description = This VoxeLibre mod sets up and configures the Help modpack mods to tailor the help towards VoxeLibre. depends = doc, doc_items diff --git a/mods/HELP/mcl_doc_basics/README.md b/mods/HELP/mcl_doc_basics/README.md index 13ac04e4a..f68ed9724 100644 --- a/mods/HELP/mcl_doc_basics/README.md +++ b/mods/HELP/mcl_doc_basics/README.md @@ -1,4 +1,4 @@ -# Basic help, MineClone 2 edition [`mcl_doc_basics`] +# Basic help, VoxeLibre edition [`mcl_doc_basics`] Adds basic help texts about Minetest, controls, gameplay and other basics. This mod uses the Documentation System [`doc`] as a basis and adds these categories: diff --git a/mods/HELP/mcl_doc_basics/init.lua b/mods/HELP/mcl_doc_basics/init.lua index 45ce75877..29b1fea1c 100644 --- a/mods/HELP/mcl_doc_basics/init.lua +++ b/mods/HELP/mcl_doc_basics/init.lua @@ -126,6 +126,9 @@ S("• I: Show/hide inventory menu").."\n\n".. S("Inventory interaction:").."\n".. S("See the entry “Basics > Inventory”.").."\n\n".. +S("Hunger/Eating:").."\n".. +S("• While holding food, hold the right mouse button (PC) or double-tap and hold the second tap (Android) to eat").."\n\n".. + S("Camera:").."\n".. S("• Z: Zoom").."\n".. S("• F7: Toggle camera mode").."\n\n".. diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.de.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.de.tr index 236d5a6bb..c66bd29b0 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.de.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.de.tr @@ -448,7 +448,7 @@ Pitch movement mode:=Nick-Bewegungsmodus: • No privilege required=• Kein Privileg nötig Creative Mode=Kreativmodus -Enabling Creative Mode in MineClone 2 applies the following changes:=Der Kreativmodus in MineClone 2 nimmt die folgenden Änderungen vor: +Enabling Creative Mode in VoxeLibre applies the following changes:=Der Kreativmodus in VoxeLibre nimmt die folgenden Änderungen vor: • You keep the things you've placed=• Sie behalten die Dinge, die Sie platzieren • Creative inventory is available to obtain most items easily=• Das Kreativinventar ist verfügbar, mit dem Sie die meisten Dinge leicht erhalten • Hand breaks all default blocks instantly=• Hand zerbricht alle Standardblöcke sofort diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.fr.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.fr.tr index 6825e4191..f3e597533 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.fr.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.fr.tr @@ -160,7 +160,7 @@ By holding down [Z], you can zoom the view at your crosshair. You need the “zo • Toggle Cinematic Mode: [F8]=• Basculer le mode cinématique : [F8] • Zoom: [Z]=• Zoom : [Z] Blocks=Blocs -The world of MineClone 2 is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Le monde de MineClone 2 est entièrement constitué de blocs (voxels, pour être précis). Les blocs peuvent être ajoutés ou supprimés avec les bons outils. +The world of VoxeLibre is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Le monde de VoxeLibre est entièrement constitué de blocs (voxels, pour être précis). Les blocs peuvent être ajoutés ou supprimés avec les bons outils. The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Le monde est entièrement fait de blocs (voxels, pour être précis). Les blocs peuvent être ajoutés ou supprimés avec les bons outils. Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:=Les blocs peuvent avoir un large éventail de propriétés différentes qui déterminent les temps d'exploration, le comportement, l'apparence, la forme et bien plus encore. Leurs propriétés comprennent: • Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely=• Collidable : les blocs collidables ne peuvent pas être traversés; les joueurs peuvent marcher dessus. Les blocs non collidables peuvent passer librement @@ -260,15 +260,15 @@ Throwing away: If you hold an item stack and click with it somewhere outside the Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=Transfert rapide : vous pouvez rapidement transférer une pile d'objets vers / depuis l'inventaire du joueur vers / depuis l'emplacement d'inventaire d'un autre objet comme un four, un coffre ou tout autre élément avec un emplacement d'inventaire lorsque l'inventaire de cet article est accessible. L'inventaire cible est généralement l'inventaire le plus pertinent dans ce contexte. • Sneak+Left click: Automatically transfer item stack=• Faufiler+clic gauche : transférer automatiquement la pile d'objets Online help=Aide en ligne -You may want to check out these online resources related to MineClone 2.=Vous voudrez peut-être consulter ces ressources en ligne liées à MineClone 2. -MineClone 2 download and forum discussion: =Téléchargement de MineClone 2 et discussion sur le forum : -Here you find the most recent version of MineClone 2 and can discuss it.=Vous trouverez ici la version la plus récente de MineClone 2 et pouvez en discuter. +You may want to check out these online resources related to VoxeLibre.=Vous voudrez peut-être consulter ces ressources en ligne liées à VoxeLibre. +VoxeLibre download and forum discussion: =Téléchargement de VoxeLibre et discussion sur le forum : +Here you find the most recent version of VoxeLibre and can discuss it.=Vous trouverez ici la version la plus récente de VoxeLibre et pouvez en discuter. Bug tracker: =Suivi des bogues : Report bugs here.=Signalez les bugs ici. Minetest links:=Liens Minetest: You may want to check out these online resources related to Minetest:=Vous voudrez peut-être consulter ces ressources en ligne liées à Minetest: Official homepage of Minetest: =Page d'accueil officielle de Minetest : -The main place to find the most recent version of Minetest, the engine used by MineClone 2.=L'endroit principal pour trouver la version la plus récente de Minetest, le moteur utilisé par MineClone 2. +The main place to find the most recent version of Minetest, the engine used by VoxeLibre.=L'endroit principal pour trouver la version la plus récente de Minetest, le moteur utilisé par VoxeLibre. The main place to find the most recent version of Minetest.=L'endroit principal pour trouver la version la plus récente de Minetest. Community wiki: =Wiki de la communauté : A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Un site Web de documentation communautaire pour Minetest. N'importe qui avec un compte peut le modifier! C'est aussi une documentation pour Minetest. @@ -333,7 +333,7 @@ Online multiplayer:=Multijoueur en ligne: • Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=• Protection : Mécanisme pour posséder des zones du monde, qui permet uniquement aux propriétaires de modifier les blocs à l'intérieur Technical terms:=Termes techniques: • Minetest: This game engine=• Minetest : Ce moteur de jeu -• MineClone 2: What you play right now=• MineClone 2 : Ce à quoi vous jouez en ce moment +• VoxeLibre: What you play right now=• VoxeLibre : Ce à quoi vous jouez en ce moment • Minetest Game: A game for Minetest by the Minetest developers=• Minetest Game : Un jeu pour Minetest par les développeurs de Minetest • Game: A complete playing experience to be used in Minetest; such as a game or sandbox or similar=• Jeu : Une expérience de jeu complète à utiliser dans Minetest; comme un jeu ou un bac à sable ou similaire • Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=• Mod : un sous-système unique qui ajoute ou modifie des fonctionnalités; est le bloc de construction de base des jeux et peut être utilisé pour les améliorer ou les modifier davantage @@ -447,8 +447,8 @@ The values for X, Y and Z work like this:=Les valeurs pour X, Y et Z fonctionnen You can view your current position in the debug screen (open with [F5]).=Vous pouvez afficher votre position actuelle dans l'écran de débogage (ouvrir avec [F5]). # MCL2 extensions -Creative Mode=Mode Creatif -Enabling Creative Mode in MineClone 2 applies the following changes:=L'activation du mode créatif dans MineClone 2 applique les modifications suivantes: +Creative Mode=Mode créatif +Enabling Creative Mode in VoxeLibre applies the following changes:=L'activation du mode créatif dans VoxeLibre applique les modifications suivantes : • You keep the things you've placed=• Vous gardez les choses que vous avez placées • Creative inventory is available to obtain most items easily=• Un inventaire créatif est disponible pour obtenir facilement la plupart des objets • Hand breaks all default blocks instantly=• La main brise instantanément tous les blocs par défaut diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.it.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.it.tr index 694735cac..afe82fd27 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.it.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.it.tr @@ -25,7 +25,7 @@ Minetest is a free software game engine for games based on voxel gameplay, inspi The player is thrown into a huge world made out of cubes or blocks. These cubes usually make the landscape they blocks can be removed and placed almost entirely freely. Using the collected items, new tools and other items can be crafted. Games in Minetest (also called “subgames”) can, however, be much more complex than this.=L'utente è gettat* in un enorme mondo fatto di cubi o blocchi. Questi cubi normalmente compongono il panorama e possono essere tolti o messi quasi completamente liberamente. Usando gli oggetti raccolti, si possono assemblare nuovi strumenti e altri oggetti. I giochi in Minetest (chiamati anche "subgame") possono, comunque, essere molto più complessi. A core feature of Minetest is the built-in modding capability. Mods modify existing gameplay. They can be as simple as adding a few decorational blocks or be very complex by e.g. introducing completely new gameplay concepts, generating a completely different kind of world, and many other things.=Una caratteristica centrale di Minetest è la capacità integrata di usare moduli. I moduli modificano l'esperienza di gioco esistente. Possono essere tanto semplici da aggiungere qualche blocco decorativo o essere molto complessi, per esempio introducendo concetti di gioco totalmente nuovi, generare un tipo di mondo completamente diverso, e molte altre cose. Minetest can be played alone or online together with multiple players. Online play will work out of the box with any mods, with no need for additional software as they are entirely provided by the server.=Minetest può essere giocato localmente o in rete assieme a più utenti. Il gioco in rete funzionerà immediatamente senza nessun modulo, senza bisogno di programmi aggiuntivi perché interamente forniti dal server. -Minetest is usually bundled with a simple default game, named “Minetest Game” (shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .=Minetest generalmente include un gioco predefinito semplice, chiamato "Minetest Game" (mostrato nelle immagini 1 e 2). Probabilmente lo avete già. Altri giochi per Minetest possono essere scaricati dai forum ufficiali di Minetest . +Minetest is usually bundled with a simple default game, named “Minetest Game” (shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .=Minetest generalmente include un gioco predefinito semplice, chiamato "Minetest Game" (mostrato nelle immagini 1 e 2). Probabilmente lo avete già. Altri giochi per Minetest possono essere scaricati dai forum ufficiali di Minetest . Sneaking=Strisciare Sneaking makes you walk slower and prevents you from falling off the edge of a block.=Strisciare vi fa camminare più lentamente e vi impedisce di cadere dal bordo di un blocco. To sneak, hold down the sneak key (default: [Shift]). When you release it, you stop sneaking. Careful: When you release the sneak key at a ledge, you might fall!=Per strisciare, tenete premuto il tasto per strisciare (predefinito [Maiusc]). Quando lo rilasciate, smettete di strisciare. Fate attenzione: quando rilasciate il tasto per strisciare vicino a un orlo, potreste cadere! @@ -396,7 +396,7 @@ Note that “transparency” here only means that the block is able to carry bri Coordinates=Coordinate The Minetest world is a large cube. And because of this, a position in the world can be easily expressed with Cartesian coordinates. That is, for each position in the world, there are 3 values X, Y and Z.=Il mondo di Minetest è un grande cubo. E per questo, una posizione nel mondo può essere facilmente espressa tramite coordinate Cartesiane. Cioè, per ogni posizione nel mondo, esistono tre valori: X, Y e Z. Like this: (5, 45, -12)=Come questi: (5, 45, -12) -This refers to the position where X=5, Y=45 and Z=-12. The 3 letters are called “axes”: Y is for the height. X and Z are for the horizontal position.=Ciò si riferisce alla posizione dove X=5 (si legga “X vale 5”, NdT), Y=45 e Z=-12. Le tre lettere sono chiamate “assi”: Y si riferisce all'altezza. X e Z si riferiscono alla posizione orizzontale. +This refers to the position where X@=5, Y@=45 and Z@=-12. The 3 letters are called “axes”: Y is for the height. X and Z are for the horizontal position.=Ciò si riferisce alla posizione dove X@=5 (si legga “X vale 5”, NdT), Y@=45 e Z@=-12. Le tre lettere sono chiamate “assi”: Y si riferisce all'altezza. X e Z si riferiscono alla posizione orizzontale. The values for X, Y and Z work like this:=I valori di X, Y e Z funzionano così: • If you go up, Y increases=• Se salite, Y aumenta • If you go down, Y decreases=• Se scendete, Y diminuisce diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr index bde6e2152..2fb0596f6 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr @@ -160,7 +160,7 @@ By holding down [Z], you can zoom the view at your crosshair. You need the “zo • Toggle Cinematic Mode: [F8]=・シネマティックモードの切替:[F8] • Zoom: [Z]=・ズーム:[Z] Blocks=ブロック -The world of MineClone 2 is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=MineClone 2のワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 +The world of VoxeLibre is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=VoxeLibreのワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=ワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:=ブロックは幅広く多様なプロパティを持つことができ、採掘時間、動作、外観、形状などが定まります。プロパティは次のとおり: • Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely=・衝突性:衝突性ブロックは通過できず、プレイヤーはその上を歩ける。非衝突性ブロックは、自由に通り抜けられる @@ -260,15 +260,15 @@ Throwing away: If you hold an item stack and click with it somewhere outside the Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=直送する:炉やチェストなどのインベントリスロットに対しては、プレイヤーインベントリからアイテムスタックを直送できます。この場合対象となるのは、一般的に最も関連性の高いインベントリスロットです。 • Sneak+Left click: Automatically transfer item stack=・スニークキー + 左クリック:アイテムスタックの自動転送 Online help=オンラインヘルプ -You may want to check out these online resources related to MineClone 2.=MineClone 2 に関連するオンライン資料もチェックしてみてください。 -MineClone 2 download and forum discussion: =MineClone 2 のダウンロードと掲示板での意見交換: -Here you find the most recent version of MineClone 2 and can discuss it.=ここでは MineClone 2 の最新バージョンを確認し、意見を交換できます。 +You may want to check out these online resources related to VoxeLibre.=VoxeLibre に関連するオンライン資料もチェックしてみてください。 +VoxeLibre download and forum discussion: =VoxeLibre のダウンロードと掲示板での意見交換: +Here you find the most recent version of VoxeLibre and can discuss it.=ここでは VoxeLibre の最新バージョンを確認し、意見を交換できます。 Bug tracker: =バグ追跡: Report bugs here.=バグの報告はこちら。 Minetest links:=Minetest リンク: You may want to check out these online resources related to Minetest:=Minetest に関連するオンライン資料もチェックしてみてください: Official homepage of Minetest: =Minetest の公式ホームページ: -The main place to find the most recent version of Minetest, the engine used by MineClone 2.=MineClone 2 で使用されているエンジン、Minetest の最新版を入手できるメインサイトです。 +The main place to find the most recent version of Minetest, the engine used by VoxeLibre.=VoxeLibre で使用されているエンジン、Minetest の最新版を入手できるメインサイトです。 The main place to find the most recent version of Minetest.=Minetest の最新版を入手できるメインサイトです。 Community wiki: =コミュニティ wiki: A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Minetest のための、コミュニティベースの文書サイトです。アカウントがあれば誰でも編集可能です! また、Minetest Game の資料も掲載されています。 @@ -333,7 +333,7 @@ Online multiplayer:=オンライン マルチプレイヤー • Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=・保護:ワールドの各エリアを所有する仕組み。エリア内部のブロックは、所有者のみが変更可能となる Technical terms:=技術的な用語: • Minetest: This game engine=・Minetest:マインテスト。本ゲームエンジン -• MineClone 2: What you play right now=・MineClone 2:マインクローン2。今、プレイしているもの +• VoxeLibre: What you play right now=・VoxeLibre:マインクローン2。今、プレイしているもの • Minetest Game: A game for Minetest by the Minetest developers=・Minetest Game:Minetest 開発者による、Minetest のためのゲーム • Game: A complete playing experience to be used in Minetest; such as a game or sandbox or similar=・Game:ゲームやサンドボックスなど、Minetest で使用される完全なプレイ体験 • Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=・Mod:モッド。機能を追加または変更する1つのサブシステム。ゲームの基本的な構成要素であり、ゲームをさらに強化または変更するために使用できる @@ -448,7 +448,7 @@ You can view your current position in the debug screen (open with [F5]).=デバ # MCL2 extensions Creative Mode=クリエイティブモード -Enabling Creative Mode in MineClone 2 applies the following changes:=MineClone 2 で Creative Mode を有効にすると、以下の変更が適用されます: +Enabling Creative Mode in VoxeLibre applies the following changes:=VoxeLibre で Creative Mode を有効にすると、以下の変更が適用されます: • You keep the things you've placed=・あなたが置いたものを保つ • Creative inventory is available to obtain most items easily=・ほとんどのアイテムを簡単に入手できるクリエイティブインベントリが利用可能 • Hand breaks all default blocks instantly=・すべてのデフォルトブロックを手で即座に壊せる diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.pl.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.pl.tr index 37fe955ca..44f3cfb1d 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.pl.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.pl.tr @@ -160,7 +160,7 @@ By holding down [Z], you can zoom the view at your crosshair. You need the “zo • Toggle Cinematic Mode: [F8]=• Przełącz tryb kinowy: [F8] • Zoom: [Z]=• Przybliż: [Z] Blocks=Bloki -The world of MineClone 2 is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Świat MineClone 2 jest w całości złożony z bloków (a bardziej precyzyjnie voxeli). Bloki mogą być dodawane lub usuwane przy użyciu odpowiednich narzędzi. +The world of VoxeLibre is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Świat VoxeLibre jest w całości złożony z bloków (a bardziej precyzyjnie voxeli). Bloki mogą być dodawane lub usuwane przy użyciu odpowiednich narzędzi. The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Świat jest w całości złożony z bloków (a bardziej precyzyjnie voxeli). Bloki mogą być dodawane lub usuwane przy użyciu odpowiednich narzędzi. Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:=Bloki mogą mieć wiele różnych właściwości określających czas kopania, zachowanie, wygląd, kształt i wiele więcej. Te własności to między innymi: • Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely=• Zderzalne: Przez bloki z tą własnością nie można przechodzić; gracze mogą po nich chodzić. Przez nie-zderzalne bloki można swobodnie przechodzić. @@ -260,15 +260,15 @@ Throwing away: If you hold an item stack and click with it somewhere outside the Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=Szybki transfer: Możesz szybko przemieszczać grupę przedmiotów z/do ekwipunku gracza do/z ekwipunku innego przedmiotu, takich jak piec, skrzynia czy innego z ekwipunkiem, gdy jego ekwipunek jest otworzony. Docelowy ekwipunek jest najczęściej najbardziej istotnym ekwipunkiem w takim kontekście. • Sneak+Left click: Automatically transfer item stack=• Skradanie+Lewy przycisk: Automatycznie przenieś grupę przedmiotów Online help=Pomoc online -You may want to check out these online resources related to MineClone 2.=Możesz chcieć zobaczyć na te zasoby online powiązane z MineClone 2. -MineClone 2 download and forum discussion: =MineClone 2 pobieranie oraz dyskusja na forum: -Here you find the most recent version of MineClone 2 and can discuss it.=Tutaj możesz znaleźć najnowszą wersję MineClone 2 i porozmawiać o niej +You may want to check out these online resources related to VoxeLibre.=Możesz chcieć zobaczyć na te zasoby online powiązane z VoxeLibre. +VoxeLibre download and forum discussion: =VoxeLibre pobieranie oraz dyskusja na forum: +Here you find the most recent version of VoxeLibre and can discuss it.=Tutaj możesz znaleźć najnowszą wersję VoxeLibre i porozmawiać o niej Bug tracker: =Śledzenie błędów: Report bugs here.=Zgłaszaj tu zauważone błędy. Minetest links:=Linki dotyczące Minetest: You may want to check out these online resources related to Minetest:=Możesz chcieć zobaczyć te zasoby online dotyczące Minetest Official homepage of Minetest: =Oficjalna strona Minetest: -The main place to find the most recent version of Minetest, the engine used by MineClone 2.=Miejsce gdzie można znaleźć najnowszą wersję Minetesta, silnika wykorzystywanego przez MineClone 2. +The main place to find the most recent version of Minetest, the engine used by VoxeLibre.=Miejsce gdzie można znaleźć najnowszą wersję Minetesta, silnika wykorzystywanego przez VoxeLibre. The main place to find the most recent version of Minetest.=Miejsce gdzie można znaleźć najnowszą wersję Minetesta. Community wiki: =Wiki społeczności: A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Utrzymywana przez społeczność dokumentacja na temat Minetest. Każdy z kontem może ją edytować! Znajduje się na niej również dokumentacja Gry Minetest. @@ -333,7 +333,7 @@ Online multiplayer:=Gra wieloosobowa w internecie: • Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=• Ochrona: Mechanizm pozwalający wejść w posiadanie pewnych części świata, co pozwala tylko właścicielom modyfikować bloki wewnątrz Technical terms:=Techniczne terminy: • Minetest: This game engine=• Minetest: Ten silnik gier -• MineClone 2: What you play right now=• MineClone 2: To w co teraz grasz +• VoxeLibre: What you play right now=• VoxeLibre: To w co teraz grasz • Minetest Game: A game for Minetest by the Minetest developers=• Gra Minetest: Gra w Minetest napisana przez jego twórców • Game: A complete playing experience to be used in Minetest; such as a game or sandbox or similar=• Gra: Kompletny doświadczenie do wykorzystania w Minetest; takie jak gry, piaskownice i podobne • Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=• Mod: Pojedynczy system, który dodaje, lub modyfikuje funkcjonalność; jest podstawowym blokiem budowalnym gier i może być wykorzystywany do dalszego urozmaicania i modyfikowania ich @@ -448,7 +448,7 @@ You can view your current position in the debug screen (open with [F5]).=Możesz # MCL2 extensions Creative Mode=Tryb kreatywny -Enabling Creative Mode in MineClone 2 applies the following changes:=Włączenie trybu kreatywnego w MineClone 2 aplikuje następujące zmiany: +Enabling Creative Mode in VoxeLibre applies the following changes:=Włączenie trybu kreatywnego w VoxeLibre aplikuje następujące zmiany: • You keep the things you've placed=• Nie tracisz postawionych rzeczy • Creative inventory is available to obtain most items easily=• Kreatywny ekwipunek jest dostępny, który pozwala łatwo zdobywać przedmioty • Hand breaks all default blocks instantly=• Ręka niszczy wszystkie domyślne bloki natychmiastowo diff --git a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ru.tr b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ru.tr index cf598fb43..2367fbcbd 100644 --- a/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ru.tr +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ru.tr @@ -4,134 +4,134 @@ Everything you need to know to get started with playing=Всё, что вам н Advanced usage=Продвинутое использование Advanced information which may be nice to know, but is not crucial to gameplay=Дополнительная информация, которую хорошо было бы знать, но не критично для хода игры Quick start=Быстрый старт -This is a very brief introduction to the basic gameplay:=Это максимально сжатое введение в основы игрового процесса +This is a very brief introduction to the basic gameplay:=Это краткое введение в основы игрового процесса: Basic controls:=Основное управление: -• Move mouse to look=• Мышь - осматриваться +• Move mouse to look=• [Движение мышью] - осматриваться • [W], [A], [S] and [D] to move=• [W], [A], [S] и [D] - идти • [E] to sprint=• [E] - бежать -• [Space] to jump or move upwards=• [Пробел] - прыгнуть или двигаться вверх -• [Shift] to sneak or move downwards=• [Shift] - красться или двигаться вниз -• Mouse wheel or [1]-[9] to select item=• Колёсико или [1]-[9] - выбор предмета -• Left-click to mine blocks or attack=• Левый клик - добывать блок или атаковать -• Recover from swings to deal full damage=• Бейте без колебаний, чтобы нанести максимальный урон -• Right-click to build blocks and use things=• Правый клик - строить блоки и использовать вещи +• [Space] to jump or move upwards=• [Пробел] - прыгнуть или карабкаться вверх +• [Shift] to sneak or move downwards=• [Shift] - красться или карабкаться вниз +• Mouse wheel or [1]-[9] to select item=• [Колёсико мыши] или [1]-[9] - выбор предмета +• Left-click to mine blocks or attack=• [Левая кнопка мыши] - добывать блок или атаковать +• Recover from swings to deal full damage=• Чтобы нанести максимальный урон, делайте небольшой интервал между ударами +• Right-click to build blocks and use things=• [Правая кнопка мыши] - строить блоки и использовать вещи • [I] for the inventory=• [I] - открыть инвентарь -• First items in inventory appear in hotbar below=• Первые предметы в инвентаре появляются на панели быстрого доступа внизу -• Lowest row in inventory appears in hotbar below=• Нижний ряд в инвентаре появляется на панели быстрого доступа внизу +• First items in inventory appear in hotbar below=• Первые поднятые предметы появляются в хотбаре (9 ячеек инвентаря) внизу экрана +• Lowest row in inventory appears in hotbar below=• Нижний ряд инвентаря это и есть хотбар • [Esc] to close this window=• [Esc] - закрыть это окно How to play:=Как играть: -• 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=• Поместите кусок дерева в решётку 2×2 (вашу личную “крафт-сетку”) в меню инвентаря и скрафтите из него 4 доски +• 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=• Поместите древесину в решётку 2×2 (вашу “сетку крафта”) в меню инвентаря и скрафтите из него 4 доски • Place them in a 2×2 shape in the crafting grid to craft a crafting table=• Разместите их в виде квадрата 2×2 в крафт-сетке, чтобы сделать верстак • Place the crafting table on the ground=• Поставьте верстак на землю -• Rightclick it for a 3×3 crafting grid=• Кликните правой по верстаку для работы с крафт-сеткой 3×3 -• Use the crafting guide (book icon) to learn all the possible crafting recipes=Используйте крафт-гид (значок книги) рецептов для изучения всех доступных рецептов -• Craft a wooden pickaxe so you can dig stone=• Создайте деревянную кирку, чтобы добыть камни +• Rightclick it for a 3×3 crafting grid=• Кликните правой кнопкой мыши по верстаку для работы с сеткой крафта 3×3 +• Use the crafting guide (book icon) to learn all the possible crafting recipes=Используйте книгу рецептов для изучения всех доступных рецептов +• Craft a wooden pickaxe so you can dig stone=• Создайте деревянную кирку, чтобы добыть камень • Different tools break different kinds of blocks. Try them out!=• Разные инструменты могут ломать разные виды блоков. Опробуйте их! -• Read entries in this help to learn the rest=Читайте записи в этой справке, чтобы узнать всё -• Continue playing as you wish. There's no goal. Have fun!=Продолжайте играть, как вам нравится. Игра не имеет конечной цели. Наслаждайтесь! -Minetest=Майнтест -Minetest is a free software game engine for games based on voxel gameplay, inspired by InfiniMiner, Minecraft, and the like. Minetest was originally created by Perttu Ahola (alias “celeron55”).=Майнтест - бесплатный программный движок для игр, основанных на воксельных мирах, источником вдохновения послужили игры InfiniMiner, Minecraft и подобные. Майнтест изначально создан Пертту Ахолой (под псевдонимом “celeron55”). -The player is thrown into a huge world made out of cubes or blocks. These cubes usually make the landscape they blocks can be removed and placed almost entirely freely. Using the collected items, new tools and other items can be crafted. Games in Minetest can, however, be much more complex than this.=Игрок попадает в огромный мир из кубиков-блоков. Из этих кубиков состоит ландшафт, их можно убирать и снова размещать практически свободно. Используя собранные предметы, вы можете создать («скрафтить») новые инструменты и предметы. Игры для Майнтеста могут быть и гораздо сложнее. -A core feature of Minetest is the built-in modding capability. Mods modify existing gameplay. They can be as simple as adding a few decorational blocks or be very complex by e.g. introducing completely new gameplay concepts, generating a completely different kind of world, and many other things.=Основной особенностью Майнтеста является встроенная возможность моддинга. Моды изменяют привычный игровой процесс. Они могут быть очень простыми, например, добавлять нескольких декоративных блоков, или очень сложными - полностью изменяющими игровой процесс, генерирующими новые виды миров и т. д. -Minetest can be played alone or online together with multiple players. Online play will work out of the box with any mods, with no need for additional software as they are entirely provided by the server.=В Майнтест можно играть в одиночку или онлайн вместе с несколькими игроками. Онлайн-игра будет работать «из коробки» с любыми модами без необходимости установки дополнительного программного обеспечения, так как всё необходимое предоставляется сервером. -Minetest is usually bundled with a simple default game, named “Minetest Game” (shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .=Обычно Майнтест поставляется в комплекте с простой игрой по умолчанию, которая называется «Игра Майнтест» (показана на рисунках 1 и 2). У вас она, вероятно, есть. Другие игры для Майнтеста можно скачать с официального форума . -Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly.=Как Майнтест, так и «Игра Майнтест» в данный момент еще не завершены, поэтому, пожалуйста, простите, если что-то не заработает идеально. +• Read entries in this help to learn the rest=Читайте записи в этой справке, чтобы узнать всё остальное +• Continue playing as you wish. There's no goal. Have fun!=Продолжайте играть, как вам захочется. Эта игра не имеет конечной цели. Наслаждайтесь! +Minetest=Minetest +Minetest is a free software game engine for games based on voxel gameplay, inspired by InfiniMiner, Minecraft, and the like. Minetest was originally created by Perttu Ahola (alias “celeron55”).=Minetest - свободный игровой движок для воксельных игр, вдохновлённый играми InfiniMiner, Minecraft и подобным. Minetest изначально создан Пертту Ахолой (под псевдонимом “celeron55”). +The player is thrown into a huge world made out of cubes or blocks. These cubes usually make the landscape they blocks can be removed and placed almost entirely freely. Using the collected items, new tools and other items can be crafted. Games in Minetest can, however, be much more complex than this.=Игрок попадает в огромный мир из кубиков-блоков. Из этих кубиков состоит ландшафт, их можно убирать и снова размещать как угодно. Используя собранные предметы, вы можете создать(скрафтить) новые инструменты и предметы. Игры для Minetest могут быть и гораздо сложнее и комплекснее чем эта. +A core feature of Minetest is the built-in modding capability. Mods modify existing gameplay. They can be as simple as adding a few decorational blocks or be very complex by e.g. introducing completely new gameplay concepts, generating a completely different kind of world, and many other things.=Основной особенностью Minetest является встроенная возможность моддинга. Моды изменяют привычный игровой процесс. Они могут быть очень простыми, например, добавлять нескольких декоративных блоков, или очень сложными - полностью изменяющими игровой процесс, генерирующими новые виды миров и т. д. +Minetest can be played alone or online together with multiple players. Online play will work out of the box with any mods, with no need for additional software as they are entirely provided by the server.=В Minetest можно играть в одиночку или онлайн вместе с другими игроками. Онлайн-игра будет работать “из коробки” с любыми модами без необходимости установки дополнительного программного обеспечения, так как всё необходимое предоставляется сервером. +Minetest is usually bundled with a simple default game, named “Minetest Game” (shown in images 1 and 2). You probably already have it. Other games for Minetest can be downloaded from the official Minetest forums .=Обычно Minetest поставляется в комплекте с простой игрой по умолчанию, которая называется “Minetest Game” ( рис. 1 и 2). У вас она, вероятно, есть. Другие игры для Minetest можно скачать с официального форума . +Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly.=Minetest и “Minetest Game” в данный момент еще не завершены, поэтому, пожалуйста, простите, если что-то работает неидеально. Sneaking=Подкрадывание Sneaking makes you walk slower and prevents you from falling off the edge of a block.=Подкрадывание замедляет ход и предотвращает падение с края блока. To sneak, hold down the sneak key (default: [Shift]). When you release it, you stop sneaking. Careful: When you release the sneak key at a ledge, you might fall!=Чтобы красться, удерживайте нажатой клавишу [Красться] (по умолчанию: [Shift]). Когда вы отпускаете её, то перестаете красться. Будьте осторожны: если отпустить клавишу, стоя на краю выступа, то можете оттуда упасть! -• Sneak: [Shift]=• Красться: [Shift] +• Sneak: [Shift]=• [Shift] - красться Sneaking only works when you stand on solid ground, are not in a liquid and don't climb.=Подкрадывание работает только когда вы стоите на твердой земле, не находитесь в жидкости и не карабкаетесь. If you jump while holding the sneak key, you also jump slightly higher than usual.=Если вы прыгаете, удерживая нажатой клавишу [Красться], вы также прыгаете немного выше, чем обычно. -Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges.=Подкрадывание может быть отключено модами. В этом случае вы все равно идете медленнее, крадясь, но вас больше ничто не останавливает на выступах. +Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges.=Подкрадывание может быть отключено модами. В этом случае, крадясь вы все равно идете медленнее, но вас больше ничто не останавливает на выступах. Controls=Управление These are the default controls:=Вот стандартное управление: Basic movement:=Основное движение: -• Moving the mouse around: Look around=• Движение мыши: осматриваться вокруг -• W: Move forwards=• W: двигаться вперед -• A: Move to the left=• A: двигаться влево -• D: Move to the right=• D: двигаться вправо -• S: Move backwards=• S: двигаться назад -• E: Sprint=• E: Бег +• Moving the mouse around: Look around=• [Движение мышью] - осматриваться вокруг +• W: Move forwards=• [W] - двигаться вперед +• A: Move to the left=• [A] - двигаться влево +• D: Move to the right=• [D] - двигаться вправо +• S: Move backwards=• [S] - двигаться назад +• E: Sprint=• [E] - Бег While standing on solid ground:=Если стоите на твердой земле: -• Space: Jump=• Пробел: прыгать -• Shift: Sneak=• Shift: красться -While on a ladder, swimming in a liquid or fly mode is active=Стоя на лестнице, плывя в режиме жидкости или находясь в режиме полёта -• Space: Move up=• Пробел: двигаться вверх -• Shift: Move down=• Shift: двигаться вниз +• Space: Jump=• [Пробел] - прыгать +• Shift: Sneak=• [Shift] - красться +While on a ladder, swimming in a liquid or fly mode is active=Стоя на лестнице, плывя в жидкости или находясь в режиме полёта: +• Space: Move up=• [Пробел] - двигаться вверх +• Shift: Move down=• [Shift] - двигаться вниз Extended movement (requires privileges):=Расширенное движение (требуются привилегии): -• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=• J: включает/выключает быстрый режим для бега/полёта (требуется привилегия “fast”) -• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=• K: включает/выключает режим полёта, позволяющий свободно перемещаться во всех направлениях (требуется привилегия “fly”) -• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=• H: включает/выключает режим отсутствия препятствий, позволяющий проходить сквозь стены в режиме полёта (требуется привилегия “noclip”) -• E: Move even faster when in fast mode=• E: двигаться даже быстрее, чем в быстром режиме -• E: Walk fast in fast mode=• E: идти быстро в быстром режиме +• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=• [J] - переключает быстрый бег/полёт (требуется привилегия “fast”) +• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=• [K] - переключает режим полёта, позволяющий свободно перемещаться во всех направлениях (требуется привилегия “fly”) +• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=• [H] - переключает режим, позволяющий проходить сквозь стены в режиме полёта (требуется привилегия “noclip”) +• E: Move even faster when in fast mode=• [E] - вы в быстром режиме, ускорит вас еще сильнее +• E: Walk fast in fast mode=• [E] - идти быстрее в быстром режиме World interaction:=Взаимодействие с миром: -• Left mouse button: Punch / mine blocks / take items=• Левая кнопка мыши: Бить / добывать блоки / брать предметы -• Left mouse button: Punch / mine blocks=• Левая кнопка мыши: Бить / добывать блоки -• Right mouse button: Build or use pointed block=• Правая кнопка мыши: Строить или использовать указанный блок -• Shift+Right mouse button: Build=• Shift+Правая кнопка мыши: Строить -• Roll mouse wheel: Select next/previous item in hotbar=• Вращение колёсика мыши: Выбор следующего/предыдущего предмета на панели быстрого доступа -• Roll mouse wheel / B / N: Select next/previous item in hotbar=• Вращение колёсика мыши / B / N: Выбор следующего/предыдущего предмета на панели быстрого доступа -• 1-9: Select item in hotbar directly=• 1-9: Быстрый и прямой выбор предмета на панели быстрого доступа -• Q: Drop item stack=• Q: выбросить всю стопку предметов -• Shift+Q: Drop 1 item=• Shift+Q: выбросить только 1 предмет -• I: Show/hide inventory menu=• I: Показать/скрыть меню вашего инвентаря +• Left mouse button: Punch / mine blocks / take items=• [Левая кнопка мыши] - бить / добывать блоки / брать предметы +• Left mouse button: Punch / mine blocks=• [Левая кнопка мыши] - бить / добывать блоки +• Right mouse button: Build or use pointed block=• [Правая кнопка мыши] - построить или использовать выбранный блок +• Shift+Right mouse button: Build=• [Shift]+[Правая кнопка мыши] - построить +• Roll mouse wheel: Select next/previous item in hotbar=• [Колёсико мыши] - выбор следующего/предыдущего предмета на хотбаре +• Roll mouse wheel / B / N: Select next/previous item in hotbar=• [Колёсико мыши] / [B] / [N] - выбор следующего/предыдущего предмета в хотбаре +• 1-9: Select item in hotbar directly=• [1-9] - выбор предмета в хотбаре +• Q: Drop item stack=• [Q] - выбросить весь стак предметов +• Shift+Q: Drop 1 item=• [Shift]+[Q] - выбросить только 1 предмет +• I: Show/hide inventory menu=• [I] - показать/скрыть ваш инвентарь Inventory interaction:=Взаимодействие с инвентарём: See the entry “Basics > Inventory”.=Смотрите запись “Основы > Инвентарь”. Camera:=Камера: -• Z: Zoom=• Z: Увеличение -• F7: Toggle camera mode=• F7: Смена режима камеры -• F8: Toggle cinematic mode=• F8: Кинематографический режим +• Z: Zoom=• [Z] - приблизить +• F7: Toggle camera mode=• [F7] - смена камеры +• F8: Toggle cinematic mode=• [F8] - кинематографический режим Interface:=Интерфейс: -• Esc: Open menu window (pauses in single-player mode) or close window=• Esc: Открыть/закрыть меню (пауза в режиме одиночной игры) -• F1: Show/hide HUD=• F1: Показать/убрать игровой интерфейс (HUD) -• F2: Show/hide chat=• F2: Показать/убрать чат -• F9: Toggle minimap=• F9: Включить/выключить миникарту -• Shift+F9: Toggle minimap rotation mode=• Shift+F9: Смена режима вращения мини-карты -• F10: Open/close console/chat log=• F10: Открыть/закрыть консоль/историю чата -• F12: Take a screenshot=• F12: Сделать снимок экрана +• Esc: Open menu window (pauses in single-player mode) or close window=• [Esc] - открыть/закрыть меню (ставит на паузу в одиночной игре) +• F1: Show/hide HUD=• [F1] - показать/убрать игровой интерфейс (HUD) +• F2: Show/hide chat=• [F2] - показать/убрать чат +• F9: Toggle minimap=• [F9] - включить/выключить миникарту +• Shift+F9: Toggle minimap rotation mode=• [Shift]+[F9] - смена режима вращения мини-карты +• F10: Open/close console/chat log=• [F10] - открыть/закрыть консоль/историю чата +• F12: Take a screenshot=• [F12] - сделать снимок экрана Server interaction:=Взаимодействие с сервером: -• T: Open chat window (chat requires the “shout” privilege)=• T: Открыть окно чата (чат требует привилегию “shout”) -• /: Start issuing a server command=• /: Начать ввод серверной команды +• T: Open chat window (chat requires the “shout” privilege)=• [T] - открыть окно чата (чтобы писать нужна привилегия “shout”) +• /: Start issuing a server command=• [/] - начать ввод серверной команды Technical:=Технические: -• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=• R: Включить/выключить дальний обзор (отключает туман и позволяет смотреть очень далеко, может замедлять игру) -• +: Increase minimal viewing distance=• +: Увеличить минимальное расстояние просмотра -• -: Decrease minimal viewing distance=• -: Уменьшить минимальное расстояние просмотра -• F3: Enable/disable fog=• F3: Включить/отключить туман -• F5: Enable/disable debug screen which also shows your coordinates=• F5: Включить/отключить экран отладки, который также показывает ваши координаты -• F6: Only useful for developers. Enables/disables profiler=• F6: Полезно только для разработчиков. Включает/отключает профайлер -• P: Only useful for developers. Writes current stack traces=• P: Полезно только для разработчиков. Записывает текущие трассировки стека +• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=• [R] - переключить дальний обзор (отключает туман и позволяет смотреть очень далеко, может замедлять игру) +• +: Increase minimal viewing distance=• [+] - увеличить минимальную дистанцию видимости +• -: Decrease minimal viewing distance=• [-] - уменьшить минимальную дистанцию видимости +• F3: Enable/disable fog=• [F3] - включить/выключить туман +• F5: Enable/disable debug screen which also shows your coordinates=• [F5] - переключить экран отладки, который также показывает ваши координаты +• F6: Only useful for developers. Enables/disables profiler=• [F6] - полезно только для разработчиков. Включает/отключает профайлер +• P: Only useful for developers. Writes current stack traces=• [P] - полезно только для разработчиков. Записывает текущие трассировки стека Players=Игроки -Players (actually: “player characters”) are the characters which users control.=Игроки (на самом деле «персонажи игроков») - персонажи, которыми управляют пользователи. -Players are living beings. They start with a number of health points (HP) and a number of breath points (BP).=Игроки это живые существа. Они появляются с определённым количеством очков здоровья (HP) и дыхания (BP). +Players (actually: “player characters”) are the characters which users control.=Игроки (на самом деле “игровые персонажи”) - персонажи, которыми управляют пользователи. +Players are living beings. They start with a number of health points (HP) and a number of breath points (BP).=Игроки это живые существа. Они начинают с определённым количеством очков здоровья (HP) и дыхания (BP). Players are capable of walking, sneaking, jumping, climbing, swimming, diving, mining, building, fighting and using tools and blocks.=Игроки могут ходить, красться, прыгать, карабкаться, плавать, нырять, добывать, строить, сражаться и использовать инструменты и блоки. Players can take damage for a variety of reasons, here are some:=Игроки могут получить урон по разным причинам, вот некоторые: • Taking fall damage=• Получение урона от падения -• Touching a block which causes direct damage=• Прикосновение к блоку, который наносит прямой ущерб +• Touching a block which causes direct damage=• Прикосновение к блоку, который наносит урон • Drowning=• Утопление -• Being attacked by another player=• Быть атакованным другим игроком -• Being attacked by a computer enemy=• Быть атакованным компьютерным врагом -At a health of 0, the player dies. The player can just respawn in the world.=На отметке здоровья HP@=0 игрок умирает. Но он может возродиться в этом же мире. -Other consequences of death depend on the game. The player could lose all items, or lose the round in a competitive game.=Другие последствия смерти зависят от игры. Игрок может потерять все предметы или проиграть в соревновательной игре. -Some blocks reduce breath. While being with the head in a block which causes drowning, the breath points are reduced by 1 for every 2 seconds. When all breath is gone, the player starts to suffer drowning damage. Breath is quickly restored in any other block.=Некоторые блоки не допускают дыхания. При нахождении с головой в блоке, который вызывает утопление, точки дыхания уменьшаются на 1 каждые 2 секунды. Когда все очки дыхания уходят, игрок начинает получать урон утопающего. Очки дыхания быстро восстановятся в любом другом блоке. -Damage can be disabled on any world. Without damage, players are immortal and health and breath are unimportant.=Урон можно отключить в любом мире. Без повреждений игроки бессмертны, а здоровье и дыхание неважны. +• Being attacked by another player=• Нападение другого игрока +• Being attacked by a computer enemy=• Нападение компьютерного врага +At a health of 0, the player dies. The player can just respawn in the world.=Когда здоровье достигает нуля, игрок умирает. Но он может возродиться в этом же мире. +Other consequences of death depend on the game. The player could lose all items, or lose the round in a competitive game.=Другие последствия смерти зависят от игры-мода. Игрок может потерять все предметы или проиграть в соревновании. +Some blocks reduce breath. While being with the head in a block which causes drowning, the breath points are reduced by 1 for every 2 seconds. When all breath is gone, the player starts to suffer drowning damage. Breath is quickly restored in any other block.=Некоторые блоки уменьшают дыхание. При нахождении с головой в блоке, который вызывает утопление, очки дыхания уменьшаются на 1 каждые 2 секунды. Когда все очки дыхания пропадают, игрок начинает получать урон от утопления. Очки дыхания быстро восстанавливаются в любом другом блоке. +Damage can be disabled on any world. Without damage, players are immortal and health and breath are unimportant.=Урон можно отключить в любом мире. Без включенного урона игроки бессмертны, и здоровье и дыхание для них неважны. In multi-player mode, the name of other players is written above their head.=В многопользовательском режиме имена других игроков написаны над их головами. Items=Предметы -Items are things you can carry along and store in inventories. They can be used for crafting, smelting, building, mining, and more. Types of items include blocks, tools, weapons and items only used for crafting.=Предметы - это вещи, которые вы можете носить с собой и хранить в инвентаре. Их можно использовать для крафтинга (создания чего-либо), плавки, строительства, добычи и многого другого. Типы предметов: блоки, инструменты, оружие, а также предметы, используемые только для крафтинга. -An item stack is a collection of items of the same type which fits into a single item slot. Item stacks can be dropped on the ground. Items which drop into the same coordinates will form an item stack.=Стопка предметов - это набор предметов одного типа, который помещается в один слот. Стопки предметов можно выбрасывать на землю полностью. Предметы, попавшие в одни и те же координаты, образуют стопку. -Dropped item stacks will be collected automatically when you stand close to them.=Стопки брошенных предметов подбираются автоматически, если вы стоите рядом с ними. +Items are things you can carry along and store in inventories. They can be used for crafting, smelting, building, mining, and more. Types of items include blocks, tools, weapons and items only used for crafting.=Предметы это вещи, которые вы можете носить с собой и хранить в инвентаре. Их можно использовать для крафтинга, переплавки, строительства, добычи и многого другого. Предметы включают в себя блоки, инструменты, оружие, а также предметы, используемые только для крафта. +An item stack is a collection of items of the same type which fits into a single item slot. Item stacks can be dropped on the ground. Items which drop into the same coordinates will form an item stack.=Стак предметов это набор предметов одного типа, который помещается в один слот. Стак предметов можно выбрасывать на землю полностью. Предметы, попавшие в одни и те же координаты, образуют стак. +Dropped item stacks will be collected automatically when you stand close to them.=Стаки брошенных предметов подбираются автоматически, если вы стоите рядом с ними. Items have several properties, including the following:=Предметы имеют несколько свойств, в том числе следующие: -• Maximum stack size: Number of items which fit on 1 item stack=• Максимальный размер стопки: количество, которое помещается в 1 стопку предметов +• Maximum stack size: Number of items which fit on 1 item stack=• Максимальный размер стака: количество, которое помещается в 1 стак предметов • Pointing range: How close things must be to be pointed while wielding this item=• Дальность прицела: насколько близко должна находиться цель, чтобы можно было навести на неё этот предмет и использовать • Group memberships: See “Basics > Groups”=• Членство в группах: См. “Основы > Группы” -• May be used for crafting or cooking=• Может быть использовано для крафтинга или приготовления пищи +• May be used for crafting or cooking=• Может быть использовано для крафта или приготовления пищи Tools=Инструменты -Some items may serve as a tool when wielded. Any item which has some special use which can be directly used by its wielder is considered a tool.=Некоторые предметы могут служить вам в качестве инструментов. Любой предмет, которым вы можете напрямую воспользоваться, чтобы сделать какое-то особое действие, считается инструментом. -A common subset of tools is mining tools. These are important to break all kinds of blocks. Weapons are a kind of tool. There are of course many other possible tools. Special actions of tools are usually done by left-click or right-click.=Распространенной разновидностью инструментов являются инструменты майнинга. Они позволяют ломать все виды блоков. Оружие - тоже своего рода инструмент. Есть и много других инструментов. Особое действие инструмента обычно выполняются по нажатию левой или правой кнопки мыши. +Some items may serve as a tool when wielded. Any item which has some special use which can be directly used by its wielder is considered a tool.=Некоторые предметы могут служить вам в качестве инструментов. Любой предмет, который имеет своё специальное назначение и используется напрямую владельцем, считается инструментом. +A common subset of tools is mining tools. These are important to break all kinds of blocks. Weapons are a kind of tool. There are of course many other possible tools. Special actions of tools are usually done by left-click or right-click.=Распространенной разновидностью инструментов являются инструменты для добычи блоков. Они позволяют ломать все виды блоков. Оружие - тоже своего рода инструмент. Есть и много других инструментов. Особое действие инструмента обычно выполняются по нажатию левой или правой кнопки мыши. When nothing is wielded, players use their hand which may act as tool and weapon.=Когда у вас в руке нет никакого предмета, инструментом, либо даже оружием, выступает сама рука. -Mining tools are important to break all kinds of blocks. Weapons are another kind of tool. There are some other more specialized tools. Special actions of tools are usually done by right-click.=Инструменты добычи позволяют ломать все виды блоков. Оружие - тоже своеобразный инструмент, хотя есть и другие, более специализированные. Особое действие инструментов обычно включается правой клавишей мыши. -When nothing is wielded, players use their hand which may act as tool and weapon. The hand is capable of punching and deals minimum damage.=При отсутствии предметов игроки используют свою руку, которая может выступать в качестве инструмента и оружия. Рука способна ударять и даже наносить небольшой урон. -Many tools will wear off when using them and may eventually get destroyed. The damage is displayed in a damage bar below the tool icon. If no damage bar is shown, the tool is in mint condition. Tools may be repairable by crafting, see “Basics > Crafting”.=Многие инструменты изнашиваются при использовании и со временем могут разрушиться. Износ отображается в строке повреждений под значком инструмента. Если полоса повреждений не отображается, значит инструмент находится в отличном состоянии. Инструменты могут быть восстановлены путем крафтинга, см. “Основы > Крафтинг”. +Mining tools are important to break all kinds of blocks. Weapons are another kind of tool. There are some other more specialized tools. Special actions of tools are usually done by right-click.=Инструменты добычи позволяют ломать все виды блоков. Оружие - тоже своеобразный инструмент, хотя есть и другие, более специализированные. Особое действие инструментов обычно используется правой кнопкой мыши. +When nothing is wielded, players use their hand which may act as tool and weapon. The hand is capable of punching and deals minimum damage.=Когда никакой предмет не держится в руках, игроки используют саму руку, которая может выступать в качестве инструмента и оружия. Рукой также можно ломать блоки и даже наносить небольшой урон. +Many tools will wear off when using them and may eventually get destroyed. The damage is displayed in a damage bar below the tool icon. If no damage bar is shown, the tool is in mint condition. Tools may be repairable by crafting, see “Basics > Crafting”.=Многие инструменты изнашиваются при использовании и со временем могут разрушиться. Прочность отображается полоской под иконкой инструмента. Если полоска повреждений не отображается, значит инструмент находится в первоначальном состоянии. Инструменты могут быть восстановлены путем крафтинга, см. “Основы > Крафтинг”. Weapons=Оружие Some items are usable as a melee weapon when wielded. Weapons share most of the properties of tools.=Некоторые предметы можно использовать в качестве оружия ближнего боя. Оружие сохраняет большинство свойств инструментов. Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:=Оружие ближнего боя наносит урон при ударе по игрокам и другим живым объектам. Есть два способа атаковать: @@ -140,11 +140,11 @@ Melee weapons deal damage by punching players and other animate objects. There a There are two core attributes of melee weapons:=Есть два основных атрибута оружия ближнего боя: • Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered=• Максимальный урон: урон, который наносится после удара, когда оружие полностью восстановлено • Full punch interval: Time it takes for fully recovering from a punch=• Интервал полного удара: время, необходимое для полного восстановления после удара -A weapon only deals full damage when it has fully recovered from a previous punch. Otherwise, the weapon will deal only reduced damage. This means, quick punching is very fast, but also deals rather low damage. Note the full punch interval does not limit how fast you can attack.=Оружие наносит полный урон только тогда, когда оно полностью восстановилось после предыдущего удара. В противном случае оружие будет наносить меньший урон. Это означает, что быстрый удар очень быстр, но наносит довольно низкий урон. Обратите внимание, что интервал полного удара не ограничивает скорость атаки. -There is a rule which sometimes makes attacks impossible: Players, animate objects and weapons belong to damage groups. A weapon only deals damage to those who share at least one damage group with it. So if you're using the wrong weapon, you might not deal any damage at all.=Есть правило, иногда делающее атаки невозможными: игроки, живые объекты и оружие принадлежат к некоторым к группам повреждений. Оружие наносит урон только тем, кто имеет хотя бы одну общую группу с ним. Так что, если вы используете «неправильное» оружие, то можете не нанести совсем никакого урона. +A weapon only deals full damage when it has fully recovered from a previous punch. Otherwise, the weapon will deal only reduced damage. This means, quick punching is very fast, but also deals rather low damage. Note the full punch interval does not limit how fast you can attack.=Оружие наносит полный урон только тогда, когда оно полностью восстановилось после предыдущего удара. В противном случае оружие будет наносить меньший урон. Это означает, что быстрые удары наносят довольно низкий урон. Обратите внимание, что интервал полного удара не ограничивает скорость атаки. +There is a rule which sometimes makes attacks impossible: Players, animate objects and weapons belong to damage groups. A weapon only deals damage to those who share at least one damage group with it. So if you're using the wrong weapon, you might not deal any damage at all.=Есть правило, иногда делающее атаки невозможными: игроки, живые объекты и оружие принадлежат к некоторым к группам повреждений. Оружие наносит урон только тем, кто имеет хотя бы одну общую группу с ним. Так что, если вы используете “неправильное” оружие, то можете не нанести совсем никакого урона. Pointing=Прицел -“Pointing” means looking at something in range with the crosshair. Pointing is needed for interaction, like mining, punching, using, etc. Pointable things include blocks, players, computer enemies and objects.=“Прицел” означает, что вы смотрите на цель через область с крестиком. Прицелиться нужно для таких вещей, как добыча, удар, использование и так далее. Нацеливаемыми вещами являются блоки, игроки, компьютерные враги и объекты. -To point something, it must be in the pointing range (also just called “range”) of your wielded item. There's a default range when you are not wielding anything. A pointed thing will be outlined or highlighted (depending on your settings). Pointing is not possible with the 3rd person front camera.=Чтобы прицелиться на что-то, это должно быть в пределах расстояния прицела (по-простому: «дальности») предмета, который вы держите в руках. Существует дальность по умолчанию, когда вы ничего не держите. Вещь под прицелом будет очерчена или подсвечена (в зависимости от настроек). Наведение невозможно выполнить с помощью фронтальной камеры 3-го лица. +“Pointing” means looking at something in range with the crosshair. Pointing is needed for interaction, like mining, punching, using, etc. Pointable things include blocks, players, computer enemies and objects.=“Прицел” означает, что вы смотрите на цель через область с крестиком. Прицеливание нужно для таких вещей, как добыча, удар, использование и так далее. Нацеливаемыми вещами являются блоки, игроки, компьютерные враги и объекты. +To point something, it must be in the pointing range (also just called “range”) of your wielded item. There's a default range when you are not wielding anything. A pointed thing will be outlined or highlighted (depending on your settings). Pointing is not possible with the 3rd person front camera.=Чтобы прицелиться на что-то, это должно быть в пределах расстояния прицела предмета, который вы держите в руках. Существует дальность по умолчанию, когда вы ничего не держите. Вещь под прицелом будет очерчена или подсвечена (в зависимости от настроек). Наведение невозможно выполнить с помощью фронтальной камеры 3-го лица. A few things can not be pointed. Most blocks are pointable. A few blocks, like air, can never be pointed. Other blocks, like liquids can only be pointed by special items.=На некоторые вещи нельзя нацелиться. Большинство блоков нацеливаемые, но некоторые, например, воздух, - нет. На блоки вроде жидкостей можно нацелиться только специальными предметами. Camera=Камера There are 3 different views which determine the way you see the world. The modes are:=Есть 3 различных способа видеть мир: @@ -152,42 +152,42 @@ There are 3 different views which determine the way you see the world. The modes • 2: Third-person view from behind=• 2: вид от третьего лица сзади; • 3: Third-person view from the front=• 3: вид от третьего лица спереди. You can change the camera mode by pressing [F7].=Вы можете изменить режим камеры, нажав клавишу [F7]. -You might be able to zoom with [Z] to zoom the view at the crosshair. This allows you to look further.=Вероятно, вы сможете увеличить масштаб вида в перекрестии с помощью [Z]. Это позволит вам смотреть дальше. +You might be able to zoom with [Z] to zoom the view at the crosshair. This allows you to look further.=Вы можете увеличить масштаб в перекрестии с помощью [Z]. Это позволит вам смотреть дальше. Zooming is a gameplay feature that might be enabled or disabled by the game. By default, zooming is enabled when in Creative Mode but disabled otherwise.=Масштабирование-это функция геймплея, которая может быть включена или отключена игрой. По умолчанию масштабирование включено в творческом режиме, но отключено в обычном. There is also Cinematic Mode which can be toggled with [F8]. With Cinematic Mode enabled, the camera movements become more smooth. Some players don't like it, it is a matter of taste.=Существует также кинематографический режим, который можно переключить с помощью [F8]. При включенном кинематографическом режиме движения камеры становятся более плавными. Некоторым игрокам это не нравится, это дело вкуса. By holding down [Z], you can zoom the view at your crosshair. You need the “zoom” privilege to do this.=Удерживая нажатой клавишу [Z], вы можете увеличить изображение в перекрестии прицела. Для этого вам нужна привилегия “zoom”. -• Switch camera mode: [F7]=• Переключение режима камеры: [F7]; -• Toggle Cinematic Mode: [F8]=• Переключение кинематографического режима: [F8]; -• Zoom: [Z]=• Масштабирование: [Z]. +• Switch camera mode: [F7]=• [F7] - переключение камеры +• Toggle Cinematic Mode: [F8]=• [F8] - переключение кинематографического режима +• Zoom: [Z]=• [Z] - приблизить Blocks=Блоки -The world of MineClone 2 is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Мир MineClone 2 полностью состоит из блоков (вокселей, если быть точными). Блоки могут быть добавлены или удалены с помощью правильно подобранных инструментов. -The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Мир целиком состоит из блоков (точнее, вокселей). Блоки могут быть добавлены или удалены с помощью правильно подобранных инструментов. +The world of VoxeLibre is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Мир VoxeLibre полностью состоит из блоков (вокселей, если быть точнее). Блоки могут быть добавлены или удалены с помощью правильных инструментов. +The world is made entirely out of blocks (voxels, to be precise). Blocks can be added or removed with the correct tools.=Мир целиком состоит из блоков (вокселей, если быть точнее). Блоки могут быть добавлены или удалены с помощью правильных инструментов. Blocks can have a wide range of different properties which determine mining times, behavior, looks, shape, and much more. Their properties include:=Блоки могут иметь широкий спектр различных свойств, которые определяют время добычи, поведение, внешний вид, форму и многое другое. Их свойства включают в себя: • Collidable: Collidable blocks can not be passed through; players can walk on them. Non-collidable blocks can be passed through freely=• Непроходимые: непроходимые блоки не могут быть пройдены насквозь; игроки могут ходить по ним. Проходимые блоки могут свободно пропускать вас сквозь себя • Pointable: Pointable blocks show a wireframe or a halo box when pointed. But you will just point through non-pointable blocks. Liquids are usually non-pointable but they can be pointed at by some special tools=• Нацеливаемые: нацеливаемые блоки демонстрируют свой контур или ореол, когда вы на них нацеливаетесь. Но через ненацеливаемые блоки ваш прицел просто пройдёт насквозь. Жидкости обычно не подлежат нацеливанию, но в них всё-таки можно целиться с помощью некоторых специальных инструментов -• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=• Майнинговые свойства: с помощью каких инструментов можно добывать эти блоки и как быстро инструмент при этом изнашивается -• Climbable: While you are at a climbable block, you won't fall and you can move up and down with the jump and sneak keys=• Карабкательные: пока вы находитесь на блоке, по которому можно карабкаться, вы падаете и можете перемещаться вверх и вниз клавишами [Прыжок] и [Красться] +• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=• Свойства добычи: с помощью каких инструментов можно добывать эти блоки и как быстро инструмент при этом изнашивается +• Climbable: While you are at a climbable block, you won't fall and you can move up and down with the jump and sneak keys=• Карабкательные: пока вы находитесь на блоке, по которому можно карабкаться, вы не упадете и можете перемещаться вверх и вниз клавишами [Прыжок] и [Красться] • Drowning damage: See the entry “Basics > Player”=• Наносящие урон как при утоплении: Смотрите запись “Основы > игрок” • Liquids: See the entry “Basics > Liquids”=• Жидкости: Смотрите запись “Основы > Жидкости” -• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=• Членство в группах: Членство в группах используется для определения майнинговых и крафтинговых свойств, взаимодействий между блоками и другого -Mining=Майнинг (добывание) -Mining (or digging) is the process of breaking blocks to remove them. To mine a block, point it and hold down the left mouse button until it breaks.=Добывание (или копание) - это процесс разрушения блоков для их убирания. Чтобы добыть блок, нацельтесь на него указателем и удерживайте левую кнопку мыши, пока он не сломается. -Blocks require a mining tool to be mined. Different blocks are mined by different mining tools, and some blocks can not be mined by any tool. Blocks vary in hardness and tools vary in strength. Mining tools will wear off over time. The mining time and the tool wear depend on the block and the mining tool. The fastest way to find out how efficient your mining tools are is by just trying them out on various blocks. Any items you gather by mining will drop on the ground, ready to be collected.=Для добычи блоков требуется инструмент майнинга. Разные блоки добываются разными инструментами майнинга, а некоторые блоки не могут быть добыты никаким инструментом. Блоки различаются по твердости, а инструменты - по прочности. Майнинговые инструменты со временем изнашиваются. Время добывания и износ зависят и от блока, и от инструмента майнинга. Самый быстрый способ узнать, насколько эффективны ваши инструменты для майнинга, - это просто попробовать их на различных блоках. Любые предметы, которые вы извлечёте из блоков в качестве добычи, упадут на землю, готовые к сбору. -After mining, a block may leave a “drop” behind. This is a number of items you get after mining. Most commonly, you will get the block itself. There are other possibilities for a drop which depends on the block type. The following drops are possible:=При добыче (майнинге) блок может оставить после себя ”кусочек“. Это предметы, которые вы получаете в результате майнинга. Чаще всего вы получаете сам блок, но в зависимости от его типа блока, может быть следующие варианты: +• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=• Членство в группах: Членство в группах используется для определения свойств крафта и добычи, взаимодействий между блоками и многое другое +Mining=Добывание +Mining (or digging) is the process of breaking blocks to remove them. To mine a block, point it and hold down the left mouse button until it breaks.=Добывание (или копание) это процесс разрушения блоков. Чтобы добыть блок, нацельтесь на него указателем и удерживайте левую кнопку мыши, пока он не сломается. +Blocks require a mining tool to be mined. Different blocks are mined by different mining tools, and some blocks can not be mined by any tool. Blocks vary in hardness and tools vary in strength. Mining tools will wear off over time. The mining time and the tool wear depend on the block and the mining tool. The fastest way to find out how efficient your mining tools are is by just trying them out on various blocks. Any items you gather by mining will drop on the ground, ready to be collected.=Для добычи блоков требуется инструмент для добычи. Разные блоки добываются разными инструментами, а некоторые блоки не могут быть добыты никаким инструментом. Блоки различаются по твёрдости, а инструменты - по силе добычи. Инструменты добычи со временем изнашиваются. Время добывания и износ зависят и от блока, и от инструмента. Самый быстрый способ узнать насколько эффективны ваши инструменты это просто попробовать их на различных блоках. Любые предметы, которые вы извлечёте из блоков в качестве добычи, выпадут на землю и их можно будет забрать. +After mining, a block may leave a “drop” behind. This is a number of items you get after mining. Most commonly, you will get the block itself. There are other possibilities for a drop which depends on the block type. The following drops are possible:=После добычи блок может оставить после себя ”дроп“. Это предметы, которые вы получаете в результате добычи. Чаще всего вы получаете сам блок, но в зависимости от его типа блока, может быть следующие варианты: • Always drops itself (the usual case)=• Всегда выпадает сам блок (обычный случай) • Always drops the same items=• Всегда выпадают одни и те же предметы -• Drops items based on probability=• Выпадающие предметы зависят от вероятности +• Drops items based on probability=• Выпадающие с некоторой вероятностью предметы • Drops nothing=• Ничего не выпадает Building=Строительство -Almost all blocks can be built (or placed). Building is very simple and has no delay.=Почти все блоки можно использовать для строительства (размещая их где-то). Это очень просто и происходит без задержек. -To build your wielded block, point at a block in the world and right-click. If this is not possible because the pointed block has a special right-click action, hold down the sneak key before right-clicking.=Чтобы установить блок, который вы держите в руке, нацельтесь на блок в мире и щелкните правой кнопкой мыши. Если это невозможно из-за того, что указательный блок имеет специальное действие щелчка правой кнопкой мыши, то зажмите клавишу [Красться] перед щелчком правой кнопки. +Almost all blocks can be built (or placed). Building is very simple and has no delay.=Почти все блоки можно использовать для строительства. Блоки строятся очень просто и без задержки. +To build your wielded block, point at a block in the world and right-click. If this is not possible because the pointed block has a special right-click action, hold down the sneak key before right-clicking.=Чтобы построить блок, который вы держите в руке, нацельтесь на блок в мире и щелкните правой кнопкой мыши. Если это невозможно из-за того, что нацеленный блок имеет специальное действие по щелчку правой кнопкой мыши, то зажмите клавишу [Красться] перед щелчком правой кнопки. Blocks can almost always be built at pointable blocks. One exception are blocks attached to the floor; these can only be built on the floor.=Блоки почти всегда могут быть построены на нацеливаемых блоках. Исключение составляют блоки, прикрепляемые к полу - они могут быть установлены только на полу. -Normally, blocks are built in front of the pointed side of the pointed block. A few blocks are different: When you try to build at them, they are replaced.=Обычно блоки строятся прямо перед блоком, в который вы целитесь, прямо перед стороной, на которую вы целитесь. Но несколько блоков ведут себя иначе: когда вы пытаетесь строить на них, они заменяются вашими новыми блоками. +Normally, blocks are built in front of the pointed side of the pointed block. A few blocks are different: When you try to build at them, they are replaced.=Обычно блоки строятся прямо перед блоком, в который вы целитесь, на той стороне, на которую вы целитесь. Но несколько блоков ведут себя иначе: когда вы пытаетесь строить на них, они заменяются вашими новыми блоками. Liquids=Жидкости -Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.=Жидкости - это специальные динамические блоки. Жидкости любят распространяться и стекать по окружающим их блокам. Игроки могут плавать и тонуть в них. +Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.=Жидкости это специальные динамические блоки. Жидкости распространяются и стекают по окружающим их блокам. Игроки могут плавать и тонуть в них. Liquids usually come in two forms: In source form (S) and in flowing form (F).=Жидкости могут быть двух видов: источник (S) и течение (F). -Liquid sources have the shape of a full cube. A liquid source will generate flowing liquids around it from time to time, and, if the liquid is renewable, it also generates liquid sources. A liquid source can sustain itself. As long it is left alone, a liquid source will normally keep its place and does not drain out.=Источники жидкостей имеют форму полного куба. Источник генерирует течение жидкости вокруг себя время от времени, и, если жидкость является возобновляемой, он также генерирует новые источники. Жидкий источник может поддерживать себя сам. Пока вы не трогаете источник, он, как правило, остаётся на месте и никуда не утекает. -Flowing liquids take a sloped form. Flowing liquids spread around the world until they drain. A flowing liquid can not sustain itself and always comes from a liquid source, either directly or indirectly. Without a liquid source, a flowing liquid will eventually drain out and disappear.=Текущие жидкости принимают наклонную форму. Они распространяются по всему миру, пока не пересохнут. Текучая жидкость не может поддерживать себя и всегда поступает из источника жидкости, прямо или непрямо. Без источника течение в конце концов высыхает и исчезает. +Liquid sources have the shape of a full cube. A liquid source will generate flowing liquids around it from time to time, and, if the liquid is renewable, it also generates liquid sources. A liquid source can sustain itself. As long it is left alone, a liquid source will normally keep its place and does not drain out.=Источники жидкостей имеют форму полного куба. Источник генерирует течение жидкости вокруг себя время от времени, и, если жидкость является возобновляемой, он также генерирует новые источники. Жидкий источник может поддерживать себя сам. Пока вы не трогаете источник, он, как правило, остаётся на месте и никуда сам не утекает. +Flowing liquids take a sloped form. Flowing liquids spread around the world until they drain. A flowing liquid can not sustain itself and always comes from a liquid source, either directly or indirectly. Without a liquid source, a flowing liquid will eventually drain out and disappear.=Текущие жидкости принимают наклонную форму. Они распространяются по всему миру, пока не пересохнут. Текучая жидкость не может поддерживать себя и всегда поступает из источника. Без источника течение в конце концов высыхает и исчезает. All liquids share the following properties:=Все жидкости обладают следующими свойствами: • All properties of blocks (including drowning damage)=• Все свойства блоков (включая урон от утопления) • Renewability: Renewable liquids can create new sources=• Возобновляемость: возобновляемые жидкости могут создавать новые источники @@ -196,90 +196,90 @@ All liquids share the following properties:=Все жидкости облада Renewable liquids create new liquid sources at open spaces (image 2). A new liquid source is created when:=Возобновляемые жидкости создают новые источники жидкости на открытых пространствах (рис.2). Новый источник жидкости создается, когда: • Two renewable liquid blocks of the same type touch each other diagonally=• Два возобновляемых жидкостных блока одного типа касаются друг друга по диагонали • These blocks are also on the same height=• При этом данные блоки находятся на одной высоте -• One of the two “corners” is open space which allows liquids to flow in=• Один из двух “углов” - это открытое пространство, которое позволяет жидкостям затекать в него +• One of the two “corners” is open space which allows liquids to flow in=• Один из двух “углов” это открытое пространство, которое позволяет жидкостям затекать в него When those criteria are met, the open space is filled with a new liquid source of the same type (image 3).=Если эти критерии выполнены, открытое пространство заполняется новым источником жидкости того же типа (рис.3). Swimming in a liquid is fairly straightforward: The usual direction keys for basic movement, the jump key for rising and the sneak key for sinking.=Плавать в жидкости довольно просто: обычные клавиши направления для основного движения, клавиша прыжка для подъема и клавиша подкрадывания для погружения. The physics for swimming and diving in a liquid are:=Физика плавания и погружения в жидкость такова: • The higher the viscosity, the slower you move=• Чем выше вязкость, тем медленнее вы двигаетесь -• If you rest, you'll slowly sink=• Если вы отдыхаете, то постепенно тонете -• There is no fall damage for falling into a liquid as such=Падение в жидкость не причиняет вам повреждений напрямую -• If you fall into a liquid, you will be slowed down on impact (but don't stop instantly). Your impact depth is determined by your speed and the liquid viscosity. For a safe high drop into a liquid, make sure there is enough liquid above the ground, otherwise you might hit the ground and take fall damage=• Если вы упадете в жидкость, вы будете замедлены перед ударом (но не остановлены мгновенно). Итоговая сила удара определяется вашей скоростью и вязкостью жидкости. Для безопасного высокого падения в жидкость убедитесь, что над землей достаточно жидкости, иначе вы можете удариться о землю и получить урон от падения +• If you rest, you'll slowly sink=• Если вы ничего не делаете, то постепенно начнёте тонуть +• There is no fall damage for falling into a liquid as such=Падение в жидкость не наносит урон от самого падения +• If you fall into a liquid, you will be slowed down on impact (but don't stop instantly). Your impact depth is determined by your speed and the liquid viscosity. For a safe high drop into a liquid, make sure there is enough liquid above the ground, otherwise you might hit the ground and take fall damage=• Если вы упадете в жидкость, вы будете замедлены перед ударом (но не остановлены мгновенно). Итоговая сила удара определяется вашей скоростью и вязкостью жидкости. Для безопасного падения в жидкость убедитесь, что над землей достаточно жидкости, иначе вы можете удариться о землю и всё-таки получить урон от падения Liquids are often not pointable. But some special items are able to point all liquids.=Жидкости часто ненацеливаемы. Но некоторые специальные предметы способны указывать на все жидкости. -Crafting=Крафтинг -Crafting is the task of combining several items to form a new item.=Крафтинг это комбинирование нескольких предметов для формирования нового предмета. -To craft something, you need one or more items, a crafting grid (C) and a crafting recipe. A crafting grid is like a normal inventory which can also be used for crafting. Items need to be put in a certain pattern into the crafting grid. Next to the crafting grid is an output slot (O). Here the result will appear when you placed items correctly. This is just a preview, not the actual item. Crafting grids can come in different sizes which limits the possible recipes you can craft.=Чтобы скрафтить что-либо, вам понадобятся исходные предметы, крафтинговая решётка (С) и рецепт. Решётка это как будто бы инвентарь, который можно использовать для крафтинга. Предметы должны быть помещены в решётку в определенном порядке. Результат появится сразу, как только вы правильно разместите предметы. Это ещё не сам предмет, а всего лишь предварительный просмотр. Решётки крафтинга могут быть разных размеров, размер ограничивает рецепты, которые вы можете использовать. -To complete the craft, take the result item from the output slot, which will consume items from the crafting grid and creates a new item. It is not possible to place items into the output slot.=Чтобы завершить крафтинг, возьмите результирующий предмет из выходного отсека. Он будет при этом создан, а предметы из решётки будут использованы для его производства. Выходной отсек предназначен только для извлечения предметов, складывать предметы в него нельзя. -A description on how to craft an item is called a “crafting recipe”. You need this knowledge to craft. There are multiple ways to learn crafting recipes. One way is by using a crafting guide, which contains a list of available crafting recipes. Some games provide crafting guides. There are also some mods which you can download online for installing a crafting guide. Another way is by reading the online manual of the game (if one is available).=Описания того, как создавать предметы, называются “рецептами”. Вам понадобятся эти знания для крафтинга различных предметов. Есть много способов узнавать рецепты. Один из них это использование встроенной книги рецептов, доступных вам с теми предметами, которые вы успели собрать. Некоторые игры предоставляют собственные руководства по крафтингу. Существуют моды, скачав и установив которые, вы получите дополнительные руководства. И, наконец, можно узнавать рецепты из онлайн-руководства к игре (если таковое имеется). -Crafting recipes consist of at least one input item and exactly one stack of output items. When performing a single craft, it will consume exactly one item from each stack of the crafting grid, unless the crafting recipe defines replacements.=Рецепты состоят, как минимум, из одного входного элемента и стопки выходных элементов. При выполнении единичного крафтинга будет употреблён ровно один предмет из каждой стопки в отсеках крафтинговой решётки, если только рецепт не предполагает замены. +Crafting=Крафт +Crafting is the task of combining several items to form a new item.=Крафт это комбинирование нескольких предметов для создания нового предмета. +To craft something, you need one or more items, a crafting grid (C) and a crafting recipe. A crafting grid is like a normal inventory which can also be used for crafting. Items need to be put in a certain pattern into the crafting grid. Next to the crafting grid is an output slot (O). Here the result will appear when you placed items correctly. This is just a preview, not the actual item. Crafting grids can come in different sizes which limits the possible recipes you can craft.=Чтобы скрафтить что-либо, вам понадобятся исходные предметы, сетка крафта и рецепт. Сетка крафта действует как инвентарь, который можно использовать для крафта. Предметы должны быть помещены в сетку крафта в определенном порядке. Результат появится сразу, как только вы правильно разместите предметы. Это ещё не сам предмет, а всего лишь предварительный просмотр. Сетки крафта могут быть разных размеров, размер ограничивает рецепты, которые вы можете использовать. +To complete the craft, take the result item from the output slot, which will consume items from the crafting grid and creates a new item. It is not possible to place items into the output slot.=Чтобы завершить крафт, возьмите получившийся предмет из выходного слота. Предмет будет при этом создан, а предметы из сетки будут использованы для его производства. Выходной слот предназначен только для извлечения предметов, складывать предметы в него нельзя. +A description on how to craft an item is called a “crafting recipe”. You need this knowledge to craft. There are multiple ways to learn crafting recipes. One way is by using a crafting guide, which contains a list of available crafting recipes. Some games provide crafting guides. There are also some mods which you can download online for installing a crafting guide. Another way is by reading the online manual of the game (if one is available).=Описание того, как создавать предметы, называются “рецептами”. Вам понадобятся эти знания для крафта различных предметов. Есть много способов узнавать рецепты. Один из них это использование встроенной книги рецептов, доступных вам с теми предметами, которые вы успели собрать. Некоторые игры предоставляют собственные руководства по крафту. Существуют моды, скачав и установив которые, вы получите дополнительные руководства. И, наконец, можно узнавать рецепты из онлайн-руководства к игре (если таковое имеется). +Crafting recipes consist of at least one input item and exactly one stack of output items. When performing a single craft, it will consume exactly one item from each stack of the crafting grid, unless the crafting recipe defines replacements.=Рецепты состоят, как минимум, из одного входного элемента и стака выходных элементов. При выполнении единичного крафта будет употреблён ровно один предмет из каждого стака в слотах сетки крафта, если только рецепт не предполагает замены. There are multiple types of crafting recipes:=Существует несколько типов рецептов: -• Shaped (image 2): Items need to be placed in a particular shape=• Фигурные (рис. 2): предметы должны быть выложены в виде определенной фигуры -• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=• Простые (изображения 3 и 4): предметы помещаются в произвольных отсеках на входе (оба изображения показывают один и тот же рецепт) +• Shaped (image 2): Items need to be placed in a particular shape=• Форменные (рис. 2): предметы должны быть выложены определенной формой +• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=• Бесформенные (изображения 3 и 4): предметы помещаются в произвольных слотах сетки крафта (оба изображения показывают один и тот же рецепт) • Cooking: Explained in “Basics > Cooking”=• Приготовление пищи: описано в разделе “Основы > Приготовление пищи” -• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=• Ремонт (рис. 5): Два поврежденных инструмента помещаются в произвольные отсеки крафт-решётки, и на выходе получается инструмент, отремонтированный на 5% +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=• Ремонт (рис. 5): Два поврежденных инструмента помещаются в произвольные слоты сетки крафта, и на выходе получается инструмент, отремонтированный на 5% In some crafting recipes, some input items do not need to be a concrete item, instead they need to be a member of a group (see “Basics > Groups”). These recipes offer a bit more freedom in the input items. Images 6-8 show the same group-based recipe. Here, 8 items of the “stone” group are required, which is true for all of the shown items.=В некоторых рецептах некоторые предметы должны быть не какими-то конкретными, а просто принадлежать нужной группе предметов (см. “Основы > Группы”). Такие рецепты предлагают немного больше свободы в выборе входных предметов. На рисунках 6-8 показан один и тот же групповой рецепт. Здесь требуется 8 предметов из группы “Камни“, к которой относятся все показанные предметы. -Rarely, crafting recipes have replacements. This means, whenever you perform a craft, some items in the crafting grid will not be consumed, but instead will be replaced by another item.=В редких случаях в рецептах содержатся замены. Это означает, что при каждом крафтинге некоторые предметы из крафтинговой решётки не будут расходоваться, но будут заменяться другими предметами. +Rarely, crafting recipes have replacements. This means, whenever you perform a craft, some items in the crafting grid will not be consumed, but instead will be replaced by another item.=В редких случаях в рецептах содержатся замены. Это означает, что при каждом крафтинге некоторые предметы из сетки крафта не будут расходоваться, а будут заменяться другими предметами. Cooking=Приготовление еды -Cooking (or smelting) is a form of crafting which does not involve a crafting grid. Cooking is done with a special block (like a furnace), an cookable item, a fuel item and time in order to yield a new item.=Приготовление еды (или плавление) это вид крафтинга, для которой не требуется крафтинговая решётка. Приготовление пищи осуществляется с помощью специального блока (например, печи), приготавливаемого предмета, топливного предмета и времени, которое требуется для получения нового предмета. -Each fuel item has a burning time. This is the time a single item of the fuel keeps a furnace burning.=Каждый топливный предмет имеет своё время горения. В течение этого времени печь будет работать. +Cooking (or smelting) is a form of crafting which does not involve a crafting grid. Cooking is done with a special block (like a furnace), an cookable item, a fuel item and time in order to yield a new item.=Приготовление еды (или переплавка) это вид крафта, для которой не требуется сетка крафта. Приготовление пищи осуществляется с помощью специального блока (например, печи), ингредиента, топлива и времени, которое требуется для получения нового предмета. +Each fuel item has a burning time. This is the time a single item of the fuel keeps a furnace burning.=Каждое топливо имеет своё время горения. В течение этого времени печь будет работать. Each cookable item requires time to be cooked. This time is specific to the item type and the item must be “on fire” for the whole cooking time to actually yield the result.=Процесс готовки требует времени. Это время зависит от типа предмета, и продукт должен быть “на огне” в течение всего времени приготовления, чтобы вы получили желаемый результат. -Hotbar=Панель быстрого доступа -At the bottom of the screen you see some squares. This is called the “hotbar”. The hotbar allows you to quickly access the first items from your player inventory.=В нижней части экрана вы видите несколько квадратов. Это так называемая “Панель быстрого доступа“. Она позволяет быстро получать доступ к первым предметам вашего игрового инвентаря. +Hotbar=Хотбар +At the bottom of the screen you see some squares. This is called the “hotbar”. The hotbar allows you to quickly access the first items from your player inventory.=В нижней части экрана вы видите несколько квадратов. Это так называемая “Панель быстрого доступа“ или “Хотбар“. Она позволяет быстро получать доступ к первым предметам вашего инвентаря. You can change the selected item with the mouse wheel or the keyboard.=Вы можете выбирать предмет при помощи колесика мыши или при помощи клавиатуры. -• Select previous item in hotbar: [Mouse wheel up] or [B]=• Выбор предыдущего предмета панели: [Колёсико вверх] или [B] -• Select next item in hotbar: [Mouse wheel down] or [N]=• Выбор следующего предмета панели: [Колёсико вниз] или [N] -• Select item in hotbar directly: [1]-[9]=• Прямой выбор предмета панели: [1] - [9] -The selected item is also your wielded item.=Выбранный предмет на панели быстрого доступа также является вашим носимым предметом, который вы держите в руке. +• Select previous item in hotbar: [Mouse wheel up] or [B]=• [Колёсико вверх] или [B] - выбор предыдущего предмета хотбара +• Select next item in hotbar: [Mouse wheel down] or [N]=• [Колёсико вниз] или [N] - выбор следующего предмета хотбара +• Select item in hotbar directly: [1]-[9]=• [1-9] - прямой выбор предмета хотбара +The selected item is also your wielded item.=Выбранный предмет в хотбаре также является вашим носимым предметом, который вы держите в руке. Minimap=Миникарта -If you have a map item in any of your hotbar slots, you can use the minimap.=Если у вас есть карта (это такой предмет) в любом отсеке панели быстрого доступа, то вы можете пользоваться миникартой. +If you have a map item in any of your hotbar slots, you can use the minimap.=Если у вас есть предмет-карта в любом слоте хотбара, то вы можете пользоваться миникартой. Press [F9] to make a minimap appear on the top right. The minimap helps you to find your way around the world. Press it again to select different minimap modes and zoom levels. The minimap also shows the positions of other players.=Нажмите [F9], чтобы в правом верхнем углу появилась миникарта. Она поможет вам найти свой путь по всему миру. Нажмите его еще раз, чтобы выбирать различные режимы мини-карты и уровни масштабирования. Миникарта также показывает позиции других игроков. There are 2 minimap modes and 3 zoom levels.=Миникарта имеет 2 режима и 3 уровня масштабирования. Surface mode (image 1) is a top-down view of the world, roughly resembling the colors of the blocks this world is made of. It only shows the topmost blocks, everything below is hidden, like a satellite photo. Surface mode is useful if you got lost.=Режим поверхности (рис. 1) это вид на мир сверху с приблизительным воспроизведением цветов блоков из которых этот мир состоит. В этом режиме видны только самые верхние блоки, а всё, что ниже, скрыто, как на спутниковой фотографии. Режим поверхности полезен, если вы заблудились. Radar mode (image 2) is more complicated. It displays the “denseness” of the area around you and changes with your height. Roughly, the more green an area is, the less “dense” it is. Black areas have many blocks. Use the radar to find caverns, hidden areas, walls and more. The rectangular shapes in image 2 clearly expose the position of a dungeon.=Режим радара (рис. 2) более сложный. Он отображает “плотность“ области вокруг вас и изменяется с вашей высотой. Проще говоря, чем больше на карте зелёного цвета, тем данный участок менее “плотный”. Чёрные области содержат много блоков. Используйте радар, чтобы находить пещеры, скрытые области, стены и многое другое. Прямоугольные формы на рисунке 2 ясно показывают местонахождение подземелья. There are also two different rotation modes. In “square mode”, the rotation of the minimap is fixed. If you press [Shift]+[F9] to switch to “circle mode”, the minimap will instead rotate with your looking direction, so “up” is always your looking direction.=Существует также два различных режима вращения. В “квадратном режиме” вращение миникарты фиксируется. Если вы нажмете [Shift]+[F9], чтобы переключиться в “режим круга”, миникарта будет вращаться в соответствии с вашим направлением взгляда, поэтому “вверх” всегда будет вашим направлением взгляда. In some games, the minimap may be disabled.=В некоторых играх миникарта может быть отключена. -• Toggle minimap mode: [F9]=• Переключение режима миникарты: [F9] -• Toggle minimap rotation mode: [Shift]+[F9]=• Переключение режима вращения миникарты: [Shift]+[F9] +• Toggle minimap mode: [F9]=• [F9] - переключение режима миникарты +• Toggle minimap rotation mode: [Shift]+[F9]=• [Shift]+[F9] - Переключение вращения миникарты Inventory=Инвентарь -Inventories are used to store item stacks. There are other uses, such as crafting. An inventory consists of a rectangular grid of item slots. Each item slot can either be empty or hold one item stack. Item stacks can be moved freely between most slots.=Инвентари используются для хранения стопок предметов. Есть и другое их применение, например, крафтинг. Инвентарь состоит из прямоугольной решётки отсеков для предметов. Каждый отсек может быть либо пустым, либо содержать одну стопку предметов. Стопки предметов можно свободно перемещать между большей частью отсеков. -You have your own inventory which is called your “player inventory”, you can open it with the inventory key (default: [I]). The first inventory slots are also used as slots in your hotbar.=У вас есть ваш собственный инвентарь, который называется “инвентарь игрока”, вы можете открыть его нажатием клавиши инвентаря (по умолчанию это [I]). Первый ряд отсеков вашего инвентаря будут отображаться на панели быстрого доступа. +Inventories are used to store item stacks. There are other uses, such as crafting. An inventory consists of a rectangular grid of item slots. Each item slot can either be empty or hold one item stack. Item stacks can be moved freely between most slots.=Инвентари используются для хранения стаков предметов. Есть и другое их применение, например, крафт. Инвентарь состоит из прямоугольной решётки слотов для предметов. Каждый слот может быть либо пустым, либо содержать один стак предметов. Стаки предметов можно свободно перемещать между большей частью слотов. +You have your own inventory which is called your “player inventory”, you can open it with the inventory key (default: [I]). The first inventory slots are also used as slots in your hotbar.=У вас есть ваш собственный инвентарь, который называется “инвентарь игрока”, вы можете открыть его нажатием клавиши инвентаря (по умолчанию это [I]). Первый ряд слотов вашего инвентаря будут отображаться в хотбаре. Blocks can also have their own inventory, e.g. chests and furnaces.=Блоки также могут иметь свой собственный инвентарь, например сундуки и печи. Inventory controls:=Управление инвентарём: -Taking: You can take items from an occupied slot if the cursor holds nothing.=Взятие: вы можете брать предметы из занятого отсека, если не держите предмет курсором в этот момент. -• Left click: take entire item stack=• Клик левой: взятие всей стопки предметов -• Right click: take half from the item stack (rounded up)=• Клик правой: взятие половины стопки предметов (округлённо) -• Middle click: take 10 items from the item stack=• Клик средней: взятие 10 предметов из стопки предметов -• Mouse wheel down: take 1 item from the item stack=• Колесо вниз: взятие 1 предмета из стопки предметов -Putting: You can put items onto a slot if the cursor holds 1 or more items and the slot is either empty or contains an item stack of the same item type.=Выкладывание: вы можете помещать предметы в отсек, если ваш курсор удерживает 1 или более предмет, а отсек пуст, либо содержит стопку таких же предметов. -• Left click: put entire item stack=• Клик левой: положить всю стопку предметов -• Right click: put 1 item of the item stack=• Клик правой: положить только 1 предмет из всей удерживаемой курсором стопки -• Right click or mouse wheel up: put 1 item of the item stack=• Клик правой или колёсико вверх: положить 1 предмет из удерживаемой курсором стопки -• Middle click: put 10 items of the item stack=• Клик средней: положить 10 предметов из удерживаемой курсором стопки -Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=Обмен: Вы можете обменять предметы, если курсор удерживает 1 или более предметов, а целевой отсек занят другими предметами. -• Click: exchange item stacks=• Клик: обмен стопок предметов -Throwing away: If you hold an item stack and click with it somewhere outside the menu, the item stack gets thrown away into the environment.=Выбрасывание: если вы, держа на курсоре стопку предметов, кликнете ей за пределами меню, то вся стопка выбрасывается в окружающую среду. -Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=Быстрая передача: вы можете быстро передавать стопки предметов между вашим личным инвентарём и инвентарём другого предмета (печи, сундука или любого другого, имеющего инвентарный отсек) во время доступа к эту предмету. Обычно это используется для загрузки/выгрузки нужных предметов. -• Sneak+Left click: Automatically transfer item stack=• [Красться]+Клик левой: автоматическая передача стопки предметов +Taking: You can take items from an occupied slot if the cursor holds nothing.=Взятие: вы можете брать предметы из слота, если не держите предмет курсором в этот момент. +• Left click: take entire item stack=• [Левая кнопка мыши] - взять весь стак предметов +• Right click: take half from the item stack (rounded up)=• [Правая кнопка мыши] - взять половину стака предметов (округляется вверх) +• Middle click: take 10 items from the item stack=• [Средняя кнопка мыши] - взять 10 предметов из стака предметов +• Mouse wheel down: take 1 item from the item stack=• [Колёсико вниз] - взять 1 предмет из стака предметов +Putting: You can put items onto a slot if the cursor holds 1 or more items and the slot is either empty or contains an item stack of the same item type.=Выкладывание: вы можете помещать предметы в слот, если ваш курсор удерживает 1 или более предмет, а слот пуст, либо содержит стак таких же предметов. +• Left click: put entire item stack=• [Левая кнопка мыши] - положить весь стак предметов +• Right click: put 1 item of the item stack=• [Правая кнопка мыши] - положить только 1 предмет из всей удерживаемого курсором стака +• Right click or mouse wheel up: put 1 item of the item stack=• [Правая кнопка мыши] или [Колёсико вверх] - положить 1 предмет из удерживаемого курсором стака +• Middle click: put 10 items of the item stack=• [Средняя кнопка мыши] - положить 10 предметов из удерживаемого курсором стака +Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=Обмен: Вы можете обменять предметы, если курсор удерживает 1 или более предметов, а целевой слот занят другими предметами. +• Click: exchange item stacks=• [Левая кнопка мыши] - обменять стаки предметов +Throwing away: If you hold an item stack and click with it somewhere outside the menu, the item stack gets thrown away into the environment.=Выбрасывание: если вы возьмете стак предметов и кликнете им за пределами меню, то весь стак выбрасывается в окружающую среду. +Quick transfer: You can quickly transfer an item stack to/from the player inventory to/from another item's inventory slot like a furnace, chest, or any other item with an inventory slot when that item's inventory is accessed. The target inventory is generally the most relevant inventory in this context.=Быстрая передача: вы можете быстро передавать стаки предметов между вашим личным инвентарём и инвентарём другого предмета (печи, сундука или любого другого, имеющего инвентарный слот) во время доступа к эту предмету. Обычно это используется для загрузки/выгрузки нужных предметов. +• Sneak+Left click: Automatically transfer item stack=• [Красться]+[Левая кнопка] - автоматическая передача стака предметов Online help=Онлайн-помощь -You may want to check out these online resources related to MineClone 2.=Возможно, вы захотите ознакомиться с этими онлайн-ресурсами, связанными с MineClone 2. -MineClone 2 download and forum discussion: =Официальный форум MineClone 2: -Here you find the most recent version of MineClone 2 and can discuss it.=Здесь вы найдете самую последнюю версию MineClone 2 и сможете обсудить её. +You may want to check out these online resources related to VoxeLibre.=Возможно, вы захотите ознакомиться с этими онлайн-ресурсами, связанными с VoxeLibre. +VoxeLibre download and forum discussion: =Официальный форум VoxeLibre: +Here you find the most recent version of VoxeLibre and can discuss it.=Здесь вы найдете самую последнюю версию VoxeLibre и сможете обсудить её. Bug tracker: =Баг-трекер: Report bugs here.=С помощью баг-трекера можно сообщить об ошибке, если вы её обнаружите. Minetest links:=Ссылки Minetest: You may want to check out these online resources related to Minetest:=Возможно, вы захотите посетить эти онлайн-ресурсы, связанные с Minetest: Official homepage of Minetest: =Официальная домашняя страница Minetest: -The main place to find the most recent version of Minetest, the engine used by MineClone 2.=Это основное место для скачивания свежих версий Minetest (Minetest это «движок», используемый MineClone 2). +The main place to find the most recent version of Minetest, the engine used by VoxeLibre.=Это основное место для скачивания свежих версий Minetest, движка, используемого VoxeLibre. The main place to find the most recent version of Minetest.=Это основное место для скачивания свежих версий Minetest. Community wiki: =Wiki сообщества: -A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Веб-сайт документации сообщества. Любой, у кого есть учетная запись, может её редактировать! Там много документации по игре Minetest. +A community-based documentation website for Minetest. Anyone with an account can edit it! It also features a documentation of Minetest Game.=Веб-сайт документации сообщества. Любой, у кого есть учетная запись, может её редактировать! Там много документации по Minetest Game. Minetest forums: =Форумы Minetest: -A web-based discussion platform where you can discuss everything related to Minetest. This is also a place where player-made mods and games are published and discussed. The discussions are mainly in English, but there is also space for discussion in other languages.=Интернет-форумы, где вы можете обсудить все, что связано с Minetest. Это также место, где публикуются и обсуждаются игры и моды, сделанные игроками. Дискуссии ведутся в основном на английском языке, но есть также место для дискуссий и на других языках. +A web-based discussion platform where you can discuss everything related to Minetest. This is also a place where player-made mods and games are published and discussed. The discussions are mainly in English, but there is also space for discussion in other languages.=Интернет-форумы, где вы можете обсудить все, что связано с Minetest. Это также место, где публикуются и обсуждаются игры и моды, сделанные игроками. Дискуссии ведутся в основном на английском языке, но есть также раздел для дискуссий и на других языках. Chat: =Чат: A generic Internet Relay Chat channel for everything related to Minetest where people can meet to discuss in real-time. If you do not understand IRC, see the Community Wiki for help.=Универсальный IRC-чат-канал для всего, связанного с Minetest, где люди могут встретиться для общения в режиме реального времени. Если вы не разбираетесь в IRC, обратитесь за помощью к Wiki. Groups=Группы -Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:=Предметы, игроки и объекты (одушевленные и неодушевленные) могут быть членами любого количества групп. Группы выполняют несколько задач: -• Crafting recipes: Slots in a crafting recipe may not require a specific item, but instead an item which is a member of a particular group, or multiple groups=• Рецепты: один из входных отсеков решётки крафтинга может занять не строго определённый предмет, а один из предметов, принадлежащих одной или нескольким группам -• Digging times: Diggable blocks belong to groups which are used to determine digging times. Mining tools are capable of digging blocks belonging to certain groups=• Время выкапывания: Копаемые блоки принадлежат группам, имеющим определённое время копания. Инструментами майнинга можно добывать блоки, принадлежащие определенным группам +Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:=Предметы, игроки и объекты (живые и нет) могут быть членами любого количества групп. Группы выполняют несколько задач: +• Crafting recipes: Slots in a crafting recipe may not require a specific item, but instead an item which is a member of a particular group, or multiple groups=• Рецепты: один из входных слотов сетки крафта может занять не строго определённый предмет, а один из предметов, принадлежащих одной или нескольким группам +• Digging times: Diggable blocks belong to groups which are used to determine digging times. Mining tools are capable of digging blocks belonging to certain groups=• Время добывания: Копаемые блоки принадлежат группам, имеющим определённое время добычи. Инструментами добычи можно добывать блоки, принадлежащие определенным группам • Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group=• Поведение блоков: блоки могут вести себя необычным образом и взаимодействовать с другими блоками, если принадлежат определенной группе • Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weapons”=• Урон и защита: у объектов и игроков есть группы защиты, а у оружия - группы причиняемого урона. Эти группы позволяют определить урон. Смотри также: “Основы > Оружие” • Other uses=• И прочее @@ -287,110 +287,110 @@ In the item help, many important groups are usually mentioned and explained.=В Glossary=Глоссарий This is a list of commonly used terms:=Это список часто используемых терминов: Controls:=Управление: -• Wielding: Holding an item in hand=• Wielding (Владеть/Держать/Нести/Удерживать): держать предмет в руке -• Pointing: Looking with the crosshair at something in range=• Pointing (Наведение/Нацеливание/Прицел/Взгляд): смотреть через прицел в виде крестика на что-либо в пределах вашей досягаемости -• Dropping: Throwing an item or item stack to the ground=• Dropping (Выпадание): бросание предмета или стопки предметов на землю -• Punching: Attacking with left-click, is also used on blocks=• Punching (Удар/Стуканье): атака с помощью щелчка левой кнопкой мыши, применяется и к блокам -• Sneaking: Walking slowly while (usually) avoiding to fall over edges=• Sneaking (Красться/Подкрадывание): идти медленно, избегая опасности падения с края блока -• Climbing: Moving up or down a climbable block=• Climbing (Карабкаться/Скалолазание): перемещение вверх или вниз по блоку, позволяющему по нему карабкаться +• Wielding: Holding an item in hand=• Владеть/Держать/Нести/Удерживать: держать предмет в руке +• Pointing: Looking with the crosshair at something in range=• Наведение/Нацеливание/Прицел/Взгляд: смотреть через прицел в виде крестика на что-либо в пределах вашей досягаемости +• Dropping: Throwing an item or item stack to the ground=• Выпадание/Дроп: бросание предмета или стака предметов на землю +• Punching: Attacking with left-click, is also used on blocks=• Удар: атака с помощью щелчка левой кнопкой мыши, применяется и к блокам +• Sneaking: Walking slowly while (usually) avoiding to fall over edges=• Подкрадывание: идти медленно, избегая опасности падения с края блока +• Climbing: Moving up or down a climbable block=• Карабкаться: перемещение вверх или вниз по блоку, позволяющему по нему карабкаться Blocks:=Блоки: • Block: Cubes that the worlds are made of=• Блоки: кубики, из которых состоят миры -• Mining/digging: Using a mining tool to break a block=• Майнинг/копание/добывание: использование инструмента майнинга для разрушения блока -• Building/placing: Putting a block somewhere=• Строительство/размещение/установка/укладывание: установка блока где-либо в мире +• Mining/digging: Using a mining tool to break a block=• Добывание/майнинг/копание: использование добывающего инструмента для разрушения блока +• Building/placing: Putting a block somewhere=• Строительство/размещение/установка/укладывание: постройка блока где-либо в мире • Drop: Items you get after mining a block=• Выбрасывание/Выпадание: появление предметов в результате добывания блоков • Using a block: Right-clicking a block to access its special function=• Использование блока: клик правой по блоку для доступа к его специальной функции Items:=Предметы: -• Item: A single thing that players can possess=• Предмет: единственная вещь, которой могут обладать игроки -• Item stack: A collection of items of the same kind=• Стопка предметов: набор одинаковых предметов -• Maximum stack size: Maximum amount of items in an item stack=• Максимальный размер стопки: максимальное количество предметов в стопке -• Slot / inventory slot: Can hold one item stack=• Отсек / отсек инвентаря: может вместить одну стопку предметов -• Inventory: Provides several inventory slots for storage=• Инвентарь: содержит несколько отсеков инвентаря для хранения +• Item: A single thing that players can possess=• Предмет: вещь, которой могут обладать игроки +• Item stack: A collection of items of the same kind=• Стак предметов: набор одинаковых предметов +• Maximum stack size: Maximum amount of items in an item stack=• Максимальный размер стака: максимальное количество предметов в стаке +• Slot / inventory slot: Can hold one item stack=• Слот инвентаря: может вместить один стак предметов +• Inventory: Provides several inventory slots for storage=• Инвентарь: содержит несколько слотов инвентаря для хранения • Player inventory: The main inventory of a player=• Инвентарь игрока: основной инвентарь игрока, который находится непосредственно при нём • Tool: An item which you can use to do special things with when wielding=• Инструмент: предмет, держа который в руке, можно совершать какие-либо специальные действия с блоками • Range: How far away things can be to be pointed by an item=• Диапазон: как далеко могут находиться вещи, на которые нацелен предмет -• Mining tool: A tool which allows to break blocks=• Инструмент майнинга: инструмент, который позволяет разбивать блоки -• Craftitem: An item which is (primarily or only) used for crafting=• Ингредиент: предмет, который преимущественно используется для крафтинга (создания) новых предметов +• Mining tool: A tool which allows to break blocks=• Добывающий инструмент: инструмент, который позволяет разбивать блоки +• Craftitem: An item which is (primarily or only) used for crafting=• Материал: предмет, который преимущественно используется для крафта (создания) новых предметов Gameplay:=Игровой процесс: -• “heart”: A single health symbol, indicates 2 HP=• “сердечко”: часть индикатора здоровья, обозначает 2 HP -• “bubble”: A single breath symbol, indicates 1 BP=• “пузырёк“: часть индикатора дыхания, обозначает 1 BP -• HP: Hit point (equals half 1 “heart”)=• HP: Hit point (половинка сердечка, переводится как “единица удара”) -• BP: Breath point, indicates breath when diving=• BP: Breath point (целый пузырёк, переводится как “единица дыхания”) отображает состояние дыхания при погружении +• “heart”: A single health symbol, indicates 2 HP=• “Сердечко”: часть индикатора здоровья, обозначает 2 очка здоровья (HP) +• “bubble”: A single breath symbol, indicates 1 BP=• “Пузырёк“: часть индикатора дыхания, обозначает 1 очко дыхания (BP) +• HP: Hit point (equals half 1 “heart”)=• HP: очко здоровья (половинка “сердечка”) +• BP: Breath point, indicates breath when diving=• BP: очко дыхания, отображает состояние дыхания при погружении • Mob: Computer-controlled enemy=• Моб: управляемый компьютером враг -• Crafting: Combining multiple items to create new ones=• Крафтинг: комбинирование нескольких предметов для создания новых +• Crafting: Combining multiple items to create new ones=• Крафт: комбинирование нескольких предметов для создания новых • Crafting guide: A helper which shows available crafting recipes=• Книга рецептов: помощник, который показывает доступные рецепты • Spawning: Appearing in the world=• Спаунинг: появление в мире -• Respawning: Appearing again in the world after death=• Возрождение (респаунинг): появление снова в мире после смерти +• Respawning: Appearing again in the world after death=• Возрождение (респаун): появление снова в мире после смерти • Group: Puts similar things together, often affects gameplay=• Группа: объединяет похожие вещи, часто влияет на игровой процесс • noclip: Allows to fly through walls=• noclip (ноуклип): позволяет летать сквозь стены Interface=Интерфейс -• Hotbar: Inventory slots at the bottom=• Панель быстрого доступа: отсеки для инвентаря внизу +• Hotbar: Inventory slots at the bottom=• Панель быстрого доступа/хотбар: слоты инвентаря внизу • Statbar: Indicator made out of half-symbols, used for health and breath=• Панель состояния: индикатор, сделанный из полусимволов, используемый для здоровья и дыхания • Minimap: The map or radar at the top right=• Миникарта: карта или радар в правом верхнем углу • Crosshair: Seen in the middle, used to point at things=• Перекрестие: видно посередине, используется для нацеливания на предметы Online multiplayer:=Сетевая многопользовательская игра: • PvP: Player vs Player. If active, players can deal damage to each other=• PvP: игрок против игрока. Если включено, игроки могут наносить урон друг другу • Griefing: Destroying the buildings of other players against their will=• Грифинг: разрушение зданий других игроков против их воли -• Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=• Защита: механизм присваивания себе некоторых областей мира, позволяющий владельцам запретить изменять блоки внутри этих областей всем, кроме себя, либо ограниченного списка друзей +• Protection: Mechanism to own areas of the world, which only allows the owners to modify blocks inside=• Защита/приват: механизм присваивания себе некоторых областей мира, позволяющий владельцам запретить изменять блоки внутри этих областей всем, кроме себя, либо ограниченного списка друзей Technical terms:=Технические условия: • Minetest: This game engine=• Minetest: движок этой игры -• MineClone 2: What you play right now=• MineClone 2: то, во что вы играете прямо сейчас +• VoxeLibre: What you play right now=• VoxeLibre: то, во что вы играете прямо сейчас • Minetest Game: A game for Minetest by the Minetest developers=• Minetest Game: игра для Minetest от разработчиков Minetest • Game: A complete playing experience to be used in Minetest; such as a game or sandbox or similar=• Игра: весь игровой процесс, принятый в Minetest; например, обычная игра, или песочница, или подобное -• Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=• Мод: отдельная подсистема, которая добавляет или изменяет функциональность; является основным способом конструирования игр и может быть использована для дальнейшего улучшения или изменения их +• Mod: A single subsystem which adds or modifies functionality; is the basic building block of games and can be used to further enhance or modify them=• Мод: отдельная подсистема, которая добавляет или изменяет функциональность; является основным способом конструирования игр и может быть использована для их дальнейшего улучшения или изменения • Privilege: Allows a player to do something=• Привилегия: позволяет игроку что-то делать -• Node: Other word for “block”=• Узел: другое слово для обозначения “блока” +• Node: Other word for “block”=• Узел/нода: другое слово для обозначения “блока” Settings=Настройки There is a large variety of settings to configure Minetest. Pretty much every aspect can be changed that way.=Существует много разнообразных настроек Minetest. Почти каждый аспект игры может быть изменён. These are a few of the most important gameplay settings:=Вот некоторые наиболее важные настройки: • Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal=• Урон (enable_damage): включает здоровье и дыхание для всех игроков. Если он выключен, то все игроки бессмертны • Creative Mode (creative_mode): Enables sandbox-style gameplay focusing on creativity rather than a challenging gameplay. The meaning depends on the game; usual changes are: Reduced dig times, easy access to almost all items, tools never wear off, etc.=• Творческий режим (creative_mode): позволяет играть в стиле песочницы, сосредоточившись на творчестве, а не на сложном игровом процессе. Смысл зависит от конкретной игры. Основные черты: ускоренное время копания, мгновенный доступ почти ко всем предметам, отсутствует износ инструментов и пр. -• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=• PvP (enable_pvp): “Игрок против игрока”. Если этот режим включён, игроки могут наносить урон друг другу +• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=• PvP (enable_pvp): “игрок против игрока”. Если этот режим включён, игроки могут наносить урон друг другу For a full list of all available settings, use the “All Settings” dialog in the main menu.=Для получения полного списка настроек вы можете перейти в ”Настройки - Все настройки“ в главном меню Minetest. Movement modes=Режимы передвижения You can enable some special movement modes that change how you move.=Вы можете включать специальные режимы вашего перемещения. -Pitch movement mode:=Движение под уклоном -• Description: If this mode is activated, the movement keys will move you relative to your current view pitch (vertical look angle) when you're in a liquid or in fly mode.=• Описание: при активации этого режима клавиши будут перемещать вас в соответствии с вашим текущим углом обзора, если вы находитесь в жидкости или в режиме полёта. -• Default key: [L]=• Клавиша по умолчанию: [L] +Pitch movement mode:=Режим движения по направлению взгляда +• Description: If this mode is activated, the movement keys will move you relative to your current view pitch (vertical look angle) when you're in a liquid or in fly mode.=• Описание: при активации этого режима клавиши будут перемещать вас относительно направления взгляда игрока когда вы находитесь в жидкости или в режиме полёта. +• Default key: [L]=• [L] - по умолчанию • No privilege required=• Никаких привилегий не требуется Fast mode:=Быстрый режим -• Description: Allows you to move much faster. Hold down the the “Use” key [E] to move faster. In the client configuration, you can further customize fast mode.=• Описание: позволяет двигаться гораздо быстрее. Удерживайте нажатой клавишу “Use “[E], чтобы двигаться быстрее. В конфигурации клиента вы можете дополнительно настроить быстрый режим. -• Default key: [J]=• Клавиша по умолчанию: [J] +• Description: Allows you to move much faster. Hold down the the “Use” key [E] to move faster. In the client configuration, you can further customize fast mode.=• Описание: позволяет двигаться гораздо быстрее. Удерживайте нажатой клавишу [E], чтобы двигаться быстрее. В конфигурации клиента вы можете дополнительно настроить быстрый режим. +• Default key: [J]=• [J] - по умолчанию • Required privilege: fast=• Требуемые привилегии: fast Fly mode:=Режим полёта: -• Description: Gravity doesn't affect you and you can move freely in all directions. Use the jump key to rise and the sneak key to sink.=• Описание: гравитация не влияет на вас, и вы можете свободно перемещаться во всех направлениях. клавишу прыжка, чтобы подниматься, и клавишу [Красться], чтобы опускаться. -• Default key: [K]=• Клавиша по умолчанию: [K] +• Description: Gravity doesn't affect you and you can move freely in all directions. Use the jump key to rise and the sneak key to sink.=• Описание: гравитация не влияет на вас, и вы можете свободно перемещаться во всех направлениях. [Прыжок], чтобы взлететь выше, и клавишу [Красться], чтобы опуститься. +• Default key: [K]=• [K] - по умолчанию • Required privilege: fly=• Требуемые привилегии: fly Noclip mode:=Режим прохождения сквозь стены (Noclip): • Description: Allows you to move through walls. Only works when fly mode is enabled, too.=• Описание: позволяет перемещаться сквозь стены. Работает только тогда, когда включен режим полета. -• Default key: [H]=• Клавиша по умолчанию: [H] +• Default key: [H]=• [H] - по умолчанию • Required privilege: noclip=• Требуемые привилегии: noclip Console=Консоль With [F10] you can open and close the console. The main use of the console is to show the chat log and enter chat messages or server commands.=С помощью [F10] вы можете открывать и закрывать консоль. Основное назначение консоли - показывать журнал чата и вводить сообщения чата или команды сервера. Using the chat or server command key also opens the console, but it is smaller and will be closed after you sent a message.=Использование чата или клавиши для отправки команд также открывает консоль, но меньшего размера, и будет закрываться сразу после отправки сообщения. Use the chat to communicate with other players. This requires you to have the “shout” privilege.=Используйте чат для общения с другими игроками. Для этого требуется привилегия ”shout“. Just type in the message and hit [Enter]. Public chat messages can not begin with “/”.=Просто введите сообщение и нажмите [Enter]. Сообщения чата не могут начинаться с “/“. -You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=Вы можете отправлять приватные сообщения: скажите “/msg <игрок> <сообщение>” в чате, чтобы отправить “<сообщение>”, который сможет увидеть только <игрок>. +You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=Вы можете отправлять приватные сообщения: напишите “/msg <игрок> <сообщение>” в чате, чтобы отправить “<сообщение>”, который сможет увидеть только <игрок>. There are some special controls for the console:=Клавиши специального управления консолью: -• [F10] Open/close console=• [F10] открыть/закрыть консоль -• [Enter]: Send message or command=• [Enter]: Отправить сообщение или команду -• [Tab]: Try to auto-complete a partially-entered player name=• [Tab]: попытаться автоматически дополнить частично введённое имя игрока -• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=• [Ctrl]+[Left]: переместить курсор в начало предыдущего слова -• [Ctrl]+[Right]: Move cursor to the beginning of the next word=• [Ctrl]+[Right]: переместить курсор в начало следующего слова -• [Ctrl]+[Backspace]: Delete previous word=• [Ctrl]+[Backspace]: удалить предыдущее слово -• [Ctrl]+[Delete]: Delete next word=• [Ctrl]+[Delete]: удалить следующее слово -• [Ctrl]+[U]: Delete all text before the cursor=• [Ctrl]+[U]: удалить весь текст перед курсором -• [Ctrl]+[K]: Delete all text after the cursor=• [Ctrl]+[K]: удалить весь текст после курсора -• [Page up]: Scroll up=• [Page up]: прокрутка вверх -• [Page down]: Scroll down=• [Page down]: прокрутка вниз +• [F10] Open/close console=• [F10] - открыть/закрыть консоль +• [Enter]: Send message or command=• [Enter] - отправить сообщение или команду +• [Tab]: Try to auto-complete a partially-entered player name=• [Tab] - попытаться автоматически дополнить частично введённое имя игрока +• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=• [Ctrl]+[Left] - переместить курсор в начало предыдущего слова +• [Ctrl]+[Right]: Move cursor to the beginning of the next word=• [Ctrl]+[Right] - переместить курсор в начало следующего слова +• [Ctrl]+[Backspace]: Delete previous word=• [Ctrl]+[Backspace] - удалить предыдущее слово +• [Ctrl]+[Delete]: Delete next word=• [Ctrl]+[Delete] - удалить следующее слово +• [Ctrl]+[U]: Delete all text before the cursor=• [Ctrl]+[U] - удалить весь текст перед курсором +• [Ctrl]+[K]: Delete all text after the cursor=• [Ctrl]+[K] - удалить весь текст после курсора +• [Page up]: Scroll up=• [Page up] - прокрутка вверх +• [Page down]: Scroll down=• [Page down] - прокрутка вниз There is also an input history. Minetest saves your previous console inputs which you can quickly access later:=Существует также история ввода данных. Minetest сохраняет весь ваш консольный ввод, и к нему можно быстро получить доступ в дальнейшем: -• [Up]: Go to previous entry in history=• [Вверх]: перейти к предыдущей записи истории ввода -• [Down]: Go to next entry in history=• [Вниз]: переход к следующей записи истории ввода +• [Up]: Go to previous entry in history=• [Вверх] - перейти к предыдущей записи истории ввода +• [Down]: Go to next entry in history=• [Вниз] - переход к следующей записи истории ввода Server commands=Серверные команды -Server commands (also called “chat commands”) are little helpers for advanced users. You don't need to use these commands when playing. But they might come in handy to perform some more technical tasks. Server commands work both in multi-player and single-player mode.=Серверные команды (также известные как “чат-команды”) - это маленькое подспорье для продвинутых пользователей. Нет необходимости использовать их для игры. Но они могут пригодиться для выполнения технических задач. Серверные команды работают как в многопользовательском, так и в однопользовательском режиме. +Server commands (also called “chat commands”) are little helpers for advanced users. You don't need to use these commands when playing. But they might come in handy to perform some more technical tasks. Server commands work both in multi-player and single-player mode.=Серверные команды (также известные как “чат-команды”) это маленькое подспорье для продвинутых пользователей. Нет необходимости использовать их для игры. Но они могут пригодиться для выполнения технических задач. Серверные команды работают как в многопользовательском, так и в однопользовательском режиме. Server commands can be entered by players using the chat to perform a special server action. There are a few commands which can be issued by everyone, but some commands only work if you have certain privileges granted on the server. There is a small set of basic commands which are always available, other commands can be added by mods.=Серверные команды могут выполнять игроки при помощи чата для выполнения специального действия сервера. Есть несколько команд, которые могут быть выданы всеми, но некоторые команды работают только в том случае, если у вас есть определенные привилегии, предоставленные на сервере. Существует небольшой набор базовых команд, которые доступны всегда, дополнительные команды могут добавляться модами. -To issue a command, simply type it like a chat message or press Minetest's command key (default: [/]). All commands have to begin with “/”, for example “/mods”. The Minetest command key does the same as the chat key, except that the slash is already entered.=Чтобы запустить команду, просто введите ее, как вводите сообщения в чате, или нажмите командную клавишу Minetest (по умолчанию: [/]). Все команды должны начинаться с символа “/”, например “/mods”. Клавиша команды Minetest делает то же самое, что и клавиша чата, за исключением того, что символ слэш (косая черта, наклонённая вправо) уже введён. +To issue a command, simply type it like a chat message or press Minetest's command key (default: [/]). All commands have to begin with “/”, for example “/mods”. The Minetest command key does the same as the chat key, except that the slash is already entered.=Чтобы запустить команду просто введите ее как вводите сообщения в чате, или нажмите командную клавишу Minetest (по умолчанию: [/]). Все команды должны начинаться с символа “/”, например “/mods”. Клавиша команды Minetest делает то же самое, что и клавиша чата, за исключением того, что символ слэш (косая черта, наклонённая вправо) уже введён. Commands may or may not give a response in the chat log, but errors will generally be shown in the chat. Try it for yourselves: Close this window and type in the “/mods” command. This will give you the list of available mods on this server.=Команды могут возвращать или не возвращать ответ в журнале чата, но ошибки, как правило, отображаются. Попробуйте сами: закройте это окно и введите команду “/mods”. Она покажет вам список модов, доступных на этом сервере. -“/help all” is a very important command: You get a list of all available commands on the server, a short explanation and the allowed parameters. This command is also important because the available commands often differ per server.=“/help all“ - это очень важная команда: вы получаете список всех доступных серверных команд, их краткое объяснение и разрешённые параметры. Эта команда также важна, потому что доступные команды часто отличаются на каждом сервере. +“/help all” is a very important command: You get a list of all available commands on the server, a short explanation and the allowed parameters. This command is also important because the available commands often differ per server.=“/help all“ это очень важная команда: вы получаете список всех доступных серверных команд, их краткое объяснение и разрешённые параметры. Эта команда также важна, потому что доступные команды часто отличаются на каждом сервере. Commands are followed by zero or more parameters.=За командами прописывается ноль или более параметров. In the command reference, you see some placeholders which you need to replace with an actual value. Here's an explanation:=В справочнике команд отображаются [<(шаблоны)>|], которые нужно заменять реальными значениями. Вот пояснение: • Text in greater-than and lower-than signs (e.g. “”): Placeholder for a parameter=• Текст в знаках больше и меньше (например, “<игрок>”): шаблон параметра @@ -399,14 +399,14 @@ In the command reference, you see some placeholders which you need to replace wi • Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=• Скобки (например, “(слово1 слово2) | слово3”): группируют несколько слов вместе, используется для обозначения возможности выбора • Everything else is to be read as literal text=• Все остальное читается буквально как текст команды Here are some examples to illustrate the command syntax:=Вот несколько примеров, иллюстрирующих синтаксис команды: -• /mods: No parameters. Just enter “/mods”=• /mods: Нет параметров. Просто введите “/mods” +• /mods: No parameters. Just enter “/mods”=• /mods: нет параметров. Просто введите “/mods” • /me : 1 parameter. You have to enter “/me ” followed by any text, e.g. “/me orders pizza”=• /me <действие>: 1 параметр. Вы должны ввести “/me“, а затем любой текст, например “/me orders pizza” -• /give : Two parameters. Example: “/give Player default:apple”=• /give <имя> <Айтемстринг>: два параметра. Пример: “/give Player mcl_core:apple” +• /give : Two parameters. Example: “/give Player default:apple”=• /give <имя> <ТехническоеНазвание>: два параметра. Пример: “/give Player mcl_core:apple” • /help [all|privs|]: Valid inputs are “/help”, “/help all”, “/help privs”, or “/help ” followed by a command name, like “/help time”=• /help [all|privs|<команда>]: допустимыми командами будут являться: “/help”, “/help all”, “/help privs” или “/help ” и имя команды, например: “/help time” • /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=• /spawnentity <ИмяСущности> [<Х>,<У>,]: допустимыми командами будут являться: “/spawnentity mcl_boats:boat” и “/spawnentity mcl_boats:boat 0,0,0” Some final remarks:=Некоторые заключительные замечания: -• For /give and /giveme, you need an itemstring. This is an internally used unique item identifier which you may find in the item help if you have the “give” or “debug” privilege=• Для /give и /giveme вам понадобится значение «Айтемстринг» (ItemString). Это уникальный идентификатор предмета для внутреннего использования, его можно найти в справке по предмету, если у вас есть привилегия “give” (давать) или “debug” (отлаживать) -• For /spawnentity you need an entity name, which is another identifier=• Для /spawnentity вам нужно имя сущности, которое является другим идентификатором +• For /give and /giveme, you need an itemstring. This is an internally used unique item identifier which you may find in the item help if you have the “give” or “debug” privilege=• Для /give и /giveme вам понадобится “техническое название” (ItemString). Это уникальный идентификатор предмета для внутреннего использования, его можно найти в справке по предмету, если у вас есть привилегия “give” или “debug” +• For /spawnentity you need an entity name, which is another identifier=• Для /spawnentity вам нужно имя сущности, которое также является идентификатором Privileges=Привилегии Each player has a set of privileges, which differs from server to server. Your privileges determine what you can and can't do. Privileges can be granted and revoked from other players by any player who has the privilege called “privs”.=Каждый игрок имеет набор привилегий, который отличается от сервера к серверу. Ваши привилегии определяют, что вы можете и чего не можете делать. Привилегии могут быть предоставлены и отозваны у других игроков любым игроком, имеющим привилегию под названием “privs”. On a multiplayer server with the default configuration, new players start with the privileges called “interact” and “shout”. The “interact” privilege is required for the most basic gameplay actions such as building, mining, using, etc. The “shout” privilege allows to chat.=На многопользовательском сервере с конфигурацией по умолчанию новые игроки начинают с привилегиями “interact” (взаимодействовать) и “shout” (кричать). Привилегия “interact” необходима для основных действий игрового процесса, таких как строительство, добыча , использование и т. д. Привилегия “shout” позволяет общаться в чате. @@ -414,14 +414,14 @@ There is a small set of core privileges which you'll find on every server, other To view your own privileges, issue the server command “/privs”.=Чтобы просмотреть свои собственные привилегии, выполните команду сервера “/privs”. Here are a few basic privilege-related commands:=Вот несколько основных команд, связанных с привилегиями: • /privs: Lists your privileges=• /privs: список ваших привилегий -• /privs : Lists the privileges of =• /privs <игрок>: список привилегий игрока с именем <игрок> +• /privs : Lists the privileges of =• /privs <игрок>: список привилегий <игрока> • /help privs: Shows a list and description about all privileges=• /help privs: показывает список и описание всех привилегий Players with the “privs” privilege can modify privileges at will:=Игроки с привилегией “privs” могут предоставлять игрокам привилегии, а также лишать их, по своему усмотрению: • /grant : Grant to =• /grant <игрок> <привилегия>: предоставить <привилегию> <игроку> • /revoke : Revoke from =• /revoke <игрок> <привилегия>: отменить <привилегию> для <игрока> In single-player mode, you can use “/grantme all” to unlock all abilities.=В однопользовательском режиме вы можете использовать “/grantme all“, чтобы сразу разблокировать себе все возможности. Light=Свет -As the world is entirely block-based, so is the light in the world. Each block has its own brightness. The brightness of a block is expressed in a “light level” which ranges from 0 (total darkness) to 15 (as bright as the sun).=Весть мир полностью основан на блоках, и точно так же устроен свет. Каждый блок имеет свою собственную яркость. Яркость блока выражается в “уровне свечения“, который колеблется от 0 (полная темнота) до 15 (такой же яркий, как солнце). +As the world is entirely block-based, so is the light in the world. Each block has its own brightness. The brightness of a block is expressed in a “light level” which ranges from 0 (total darkness) to 15 (as bright as the sun).=Весь мир полностью основан на блоках, и точно так же устроен свет. Каждый блок имеет свою собственную яркость. Яркость блока выражается в “уровне свечения“, который колеблется от 0 (полная темнота) до 15 (такой же яркий, как солнце). There are two types of light: Sunlight and artificial light.=Существует два вида света: солнечный и искусственный. Artificial light is emitted by luminous blocks. Artificial light has a light level from 1-14.=Искусственный свет излучается светящимися блоками. Искусственный свет имеет уровень яркости от 1 до 14. Sunlight is the brightest light and always goes perfectly straight down from the sky at each time of the day. At night, the sunlight will become moonlight instead, which still provides a small amount of light. The light level of sunlight is 15.=Солнечный свет самый яркий и всегда идет совершенно прямо с неба в любое время дня. Ночью свет превращается в лунный, и он тоже даёт небольшое количество света. Уровень яркости солнечного света равен 15. @@ -448,7 +448,7 @@ You can view your current position in the debug screen (open with [F5]).=Вы м # Расширения MCL2 Creative Mode=Творческий режим -Enabling Creative Mode in MineClone 2 applies the following changes:=При включении творческого режима в MineClone 2 применяются следующие изменения: +Enabling Creative Mode in VoxeLibre applies the following changes:=При включении творческого режима в VoxeLibre применяются следующие изменения: • You keep the things you've placed=• У вас сохраняются вещи, которые вы размещаете в мире • Creative inventory is available to obtain most items easily=• Вам доступен творческий инвентарь для легкого получения большинства предметов • Hand breaks all default blocks instantly=• Рука мгновенно разбивает все стандартные блоки @@ -460,8 +460,8 @@ Enabling Creative Mode in MineClone 2 applies the following changes:=При вк • You can always use the minimap (including radar mode)=• Вы всегда можете использовать миникарту (включая режим радара) Damage is not affected by Creative Mode, it needs to be disabled separately.=На урон творческий режим не влияет, его нужно отключать отдельно. Mobs=Мобы -Mobs are the living beings in the world. This includes animals and monsters.=Мобы - это живые существа в мире. Они включают в себя животных и монстров. -Mobs appear randomly throughout the world. This is called “spawning”. Each mob kind appears on particular block types at a given light level. The height also plays a role. Peaceful mobs tend to spawn at daylight while hostile ones prefer darkness. Most mobs can spawn on any solid block but some mobs only spawn on particular blocks (like grass blocks).=Мобы появляются случайным образом по всему миру. Это называется “спаунинг” (“spawning” – появление, рождение, нерест). Каждый вид мобов появляется на определенных типах блоков при заданном уровне освещенности. Высота тоже играет свою роль. Мирные мобы, как правило, появляются при дневном свете, в то время как враждебные предпочитают темноту. Большинство мобов могут появляться на любом твердом блоке, но некоторые мобы появляются только на определённых блоках (например, травяных). +Mobs are the living beings in the world. This includes animals and monsters.=Мобы это живые существа в мире. Они включают в себя животных и монстров. +Mobs appear randomly throughout the world. This is called “spawning”. Each mob kind appears on particular block types at a given light level. The height also plays a role. Peaceful mobs tend to spawn at daylight while hostile ones prefer darkness. Most mobs can spawn on any solid block but some mobs only spawn on particular blocks (like grass blocks).=Мобы появляются случайным образом по всему миру. Это называется “спаун”. Каждый вид мобов спаунится на определенных типах блоков при заданном уровне освещенности. Высота тоже играет свою роль. Мирные мобы, как правило, спаунятся при дневном свете, в то время как враждебные предпочитают темноту. Большинство мобов могут заспаунится на любом твердом блоке, но некоторые мобы только на определённых блоках (например, травяных). Like players, mobs have hit points and sometimes armor points, too (which means you need better weapons to deal any damage at all). Also like players, hostile mobs can attack directly or at a distance. Mobs may drop random items after they die.=Как и игроки, мобы имеют очки здоровья, а иногда и очки защиты (что означает, что вам понадобится оружие получше, чтобы нанести им хоть какой-то урон). Так же, как и игроки, враждебные мобы могут атаковать вплотную или с расстояния. Мобы могут выбрасывать случайные предметы, когда умирают. Most animals roam the world aimlessly while most hostile mobs hunt players. Animals can be fed, tamed and bred.=Большинство животных бесцельно бродят по миру, в то время как большинство враждебных мобов охотятся на игроков. Животных можно кормить, приручать и разводить. Animals=Животные @@ -475,9 +475,9 @@ Taming:=Приручение: A few animals can be tamed. You can generally do more things with tamed animals and use other items on them. For example, tame horses can be saddled and tame wolves fight on your side.=Нескольких животных можно приручать. Как правило, с прирученными животными вы можете делать больше вещей, а также использовать на них другие предметы. Например, прирученных лошадей можно оседлать, а прирученные волки сражаются на вашей стороне. Breeding:=Разведение: When you have fed an animal up to its maximum health, then feed it again, you will activate “Love Mode” and many hearts appear around the animal.=Когда вы кормите животное до его максимального здоровья, а затем кормите его снова, вы активируете “режим любви”, и вокруг животного появляется много сердец. -Two animals of the same species will start to breed if they are in Love Mode and close to each other. Soon a baby animal will pop up.=Два животных одного вида начнут размножаться, если они находятся в режиме любви и близко друг к другу. Скоро появится малыш животного. -Baby animals:=Малыш животного -Baby animals are just like their adult couterparts, but they can't be tamed or bred and don't drop anything when they die. They grow to adults after a short time. When fed, they grow to adults faster.=Малыши животных точно такие же, как и взрослые, но их нельзя приручить или разводить, и они ничего не дают вам, когда умирают. Они вырастают до взрослых через короткое время. Если кормить их, то они вырастут быстрее. +Two animals of the same species will start to breed if they are in Love Mode and close to each other. Soon a baby animal will pop up.=Два животных одного вида начнут размножаться, если они находятся в режиме любви и близко друг к другу. Скоро появится детёныш животного. +Baby animals:=Детёныш животного +Baby animals are just like their adult couterparts, but they can't be tamed or bred and don't drop anything when they die. They grow to adults after a short time. When fed, they grow to adults faster.=Детёнышы животных точно такие же, как и взрослые, но их нельзя приручить или разводить, и они ничего не дают вам, когда умирают. Они вырастают до взрослых через короткое время. Если кормить их, то они вырастут быстрее. Hunger=Голод Hunger affects your health and your ability to sprint. Hunger is not in effect when damage is disabled.=Голод влияет на ваше здоровье и способность бегать. Голод не действует, если урон отключён. Core hunger rules:=Основные правила голода: @@ -485,21 +485,21 @@ Core hunger rules:=Основные правила голода: • Actions like combat, jumping, sprinting, etc. decrease hunger points=• Такие действия, такие как бой, прыжки, бег и тому подобные, уменьшают очки голода • Food restores hunger points=• Еда восстанавливает очки голода • If your hunger bar decreases, you're hungry=• Если ваша индикатор голода уменьшается, вы голодны -• At 18-20 hunger points, you regenerate 1 HP every 4 seconds=• При 18-20 очках голода ваше здоровье восстанавливается со скоростью 1 HP каждые 4 секунды +• At 18-20 hunger points, you regenerate 1 HP every 4 seconds=• При 18-20 очках голода ваше здоровье восстанавливается со скоростью 1 очко каждые 4 секунды • At 6 hunger points or less, you can't sprint=• При 6 очках голода и менее меньше вы не можете бежать -• At 0 hunger points, you lose 1 HP every 4 seconds (down to 1 HP)=• При 0 очках голода вы теряете 1 HP 4 секунды (до уровня 1 HP) -• Poisonous food decreases your health=• Ядовитая пища ухудшает ваше здоровье. +• At 0 hunger points, you lose 1 HP every 4 seconds (down to 1 HP)=• При 0 очках голода вы теряете 1 очко здоровья 4 секунды (до тех пор пока здоровье не понизится до 1 HP) +• Poisonous food decreases your health=• Ядовитая пища умешьшает ваше здоровье. Details:=Подробности: -You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=У вас есть 0-20 очков голода, обозначенных 20 куриными ножками над панелью быстрого доступа. У вас также есть невидимый атрибут: сытость. -Hunger points reflect how full you are while saturation points reflect how long it takes until you're hungry again.=Очки голода отражают, насколько вы сыты, а невидимые очки сытости – через какое время вы снова проголодаетесь. -Each food item increases both your hunger level as well your saturation.=Каждый продукт питания увеличивает как очки голода, так и невидимые очки сытости. +You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=У вас есть 0-20 очков голода, обозначенных 20 куриными ножками над хотбаром. У вас также есть невидимый атрибут: насыщение. +Hunger points reflect how full you are while saturation points reflect how long it takes until you're hungry again.=Очки голода отражают, насколько вы сыты, а невидимые очки насыщения – через какое время вы снова проголодаетесь. +Each food item increases both your hunger level as well your saturation.=Каждый продукт питания увеличивает как очки голода, так и невидимые очки насыщения. Food with a high saturation boost has the advantage that it will take longer until you get hungry again.=Таким образом, еда с высоком насыщаемостью имеет преимущество, которое заключается в том, что пройдёт больше времени, прежде чем вы снова проголодаетесь. -A few food items might induce food poisoning by chance. When you're poisoned, the health and hunger symbols turn sickly green. Food poisoning drains your health by 1 HP per second, down to 1 HP. Food poisoning also drains your saturation. Food poisoning goes away after a while or when you drink milk.=Некоторые продукты питания иногда могут вызвать отравление. Когда вы отравлены, символы здоровья и голода становятся болезненно зелёными. Пищевое отравление истощает здоровье на 1 HP в секунду, до уровня 1 HP. Пищевое отравление также уменьшает невидимые очки сытости. Отравление проходит через некоторое время либо при выпивании молока. -You start with 5 saturation points. The maximum saturation is equal to your current hunger level. So with 20 hunger points your maximum saturation is 20. What this means is that food items which restore many saturation points are more effective the more hunger points you have. This is because at low hunger levels, a lot of the saturation boost will be lost due to the low saturation cap.=Вы начинаете с 5 очками сытости. Максимальная сытость равна вашему текущему уровню голода. Таким образом, с 20 очками голода ваша максимальная сытость 20. Это означает, что продукты питания, которые восстанавливают много очков сытости, тем эффективнее, чем больше у вас очков голода. При низком уровне голода большая часть сытости будет потеряна. -If your saturation reaches 0, you're hungry and start to lose hunger points. Whenever you see the hunger bar decrease, it is a good time to eat.=Если ваши невидимые очки сытости достигают 0, вы начинаете испытывать голод постепенно терять очки голода. Если вы видите, что индикатор голода уменьшается, значит, настало время поесть. -Saturation decreases by doing things which exhaust you (highest exhaustion first):=Сытость уменьшается, если вы делаете вещи, которые истощают вас (от высокого к низкому истощению): -• Regenerating 1 HP=• Восстановление 1 HP (единицы здоровья/удара) -• Suffering food poisoning=• Страдание пищевым отравлением +A few food items might induce food poisoning by chance. When you're poisoned, the health and hunger symbols turn sickly green. Food poisoning drains your health by 1 HP per second, down to 1 HP. Food poisoning also drains your saturation. Food poisoning goes away after a while or when you drink milk.=Некоторая пища иногда может вызвать отравление. Когда вы отравлены, символы здоровья и голода становятся болезненно зелёными. Пищевое отравление истощает здоровье на 1 HP в секунду, до уровня 1 HP. Пищевое отравление также уменьшает невидимые очки насыщения. Отравление проходит через некоторое время либо при выпивании молока. +You start with 5 saturation points. The maximum saturation is equal to your current hunger level. So with 20 hunger points your maximum saturation is 20. What this means is that food items which restore many saturation points are more effective the more hunger points you have. This is because at low hunger levels, a lot of the saturation boost will be lost due to the low saturation cap.=Вы начинаете с 5 очками насыщения. Максимальное насыщение равно вашему текущему уровню голода. Таким образом, с 20 очками голода ваше максимальное насыщение равно 20. Это означает, что пища, которая восстанавливает много очков насыщения, тем эффективнее, чем больше у вас очков голода. При низком уровне голода большая часть насыщения будет потеряна. +If your saturation reaches 0, you're hungry and start to lose hunger points. Whenever you see the hunger bar decrease, it is a good time to eat.=Если ваши невидимые очки насыщения достигает 0, вы начинаете постепенно терять очки голода. Если вы видите, что индикатор голода уменьшается, значит, настало время поесть. +Saturation decreases by doing things which exhaust you (highest exhaustion first):=Насыщение уменьшается, если вы делаете вещи, которые истощают вас (от большего к меньшему): +• Regenerating 1 HP=• Восстановление 1 единицы здоровья +• Suffering food poisoning=• Страдание от пищевого отравления • Sprint-jumping=• Прыжки во время бега • Sprinting=• Бег • Attacking=• Атака @@ -508,4 +508,4 @@ Saturation decreases by doing things which exhaust you (highest exhaustion first • Jumping=• Прыжки • Mining a block=• Добывание блоков Other actions, like walking, do not exaust you.=Другие действия, такие как ходьба, не истощают вас. -If you have a map item in any of your hotbar slots, you can use the minimap.=Если у вас есть карта в любом отсеке на панели быстрого доступа, вы можете использовать миникарту. +If you have a map item in any of your hotbar slots, you can use the minimap.=Если у вас есть карта в любом слоте хотбара, вы можете использовать миникарту. diff --git a/mods/HELP/mcl_doc_basics/locale/template.txt b/mods/HELP/mcl_doc_basics/locale/template.txt index 5abc582e7..0c2dc22f8 100644 --- a/mods/HELP/mcl_doc_basics/locale/template.txt +++ b/mods/HELP/mcl_doc_basics/locale/template.txt @@ -78,6 +78,8 @@ World interaction:= • I: Show/hide inventory menu= Inventory interaction:= See the entry “Basics > Inventory”.= +Hunger/Eating:= +• While holding food, hold the right mouse button (PC) or double-tap and hold the second tap (Android) to eat= Camera:= • Z: Zoom= • F7: Toggle camera mode= diff --git a/mods/HELP/mcl_doc_basics/mcl_extension.lua b/mods/HELP/mcl_doc_basics/mcl_extension.lua index a0f31a2c8..42d93e661 100644 --- a/mods/HELP/mcl_doc_basics/mcl_extension.lua +++ b/mods/HELP/mcl_doc_basics/mcl_extension.lua @@ -3,7 +3,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) doc.add_entry("advanced", "creative", { name = S("Creative Mode"), data = { text = -S("Enabling Creative Mode in MineClone 2 applies the following changes:").."\n\n".. +S("Enabling Creative Mode in VoxeLibre applies the following changes:").."\n\n".. S("• You keep the things you've placed").."\n".. S("• Creative inventory is available to obtain most items easily").."\n".. diff --git a/mods/HELP/mcl_item_id/API.md b/mods/HELP/mcl_item_id/API.md index a2f244e0c..1a499fd38 100644 --- a/mods/HELP/mcl_item_id/API.md +++ b/mods/HELP/mcl_item_id/API.md @@ -1,6 +1,6 @@ # mcl_item_id Show the item ID of an item in the description. -With this API, you can register a different name space than "mineclone" for your mod. +With this API, you can register a different name space than "voxelibre" for your mod. ## mcl_item_id.set_mod_namespace(modname, namespace) Set a name space for all items in a mod. @@ -21,4 +21,4 @@ The name of the mod is "mod" which registered an item called "mod:itemname". * mcl_item_id.set_mod_namespace(minetest.get_current_modname()) will show "mod:itemname" in the description of "mod:itemname" * mcl_item_id.get_mod_namespace(minetest.get_current_modname()) will return "mod" -(If no namespace is set by a mod, mcl_item_id.get_mod_namespace(minetest.get_current_modname()) will return "mineclone") +(If no namespace is set by a mod, mcl_item_id.get_mod_namespace(minetest.get_current_modname()) will return "voxelibre") diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua index 0e029932b..6172e4f67 100644 --- a/mods/HELP/mcl_item_id/init.lua +++ b/mods/HELP/mcl_item_id/init.lua @@ -2,7 +2,7 @@ mcl_item_id = { mod_namespaces = {}, } -local game = "mineclone" +local game = "voxelibre" function mcl_item_id.set_mod_namespace(modname, namespace) local namespace = namespace or modname @@ -21,7 +21,7 @@ end local same_id = { enchanting = { "table" }, experience = { "bottle" }, - heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, + heads = { "skeleton", "zombie", "stalker", "wither_skeleton" }, mobitems = { "rabbit", "chicken" }, walls = { "andesite", "brick", "cobble", "diorite", "endbricks", @@ -42,11 +42,13 @@ tt.register_snippet(function(itemstring) local id_string = itemstring:sub(item_split) local id_modname = itemstring:sub(1, item_split - 1) local new_id = game .. id_string + local alt_id = "mineclone" .. id_string local mod_namespace = mcl_item_id.get_mod_namespace(id_modname) for mod, ids in pairs(same_id) do for _, id in pairs(ids) do if itemstring == "mcl_" .. mod .. ":" .. id then new_id = game .. ":" .. id .. "_" .. mod:gsub("s", "") + alt_id = "mineclone:" .. id .. "_" .. mod:gsub("s", "") end end end @@ -55,8 +57,9 @@ tt.register_snippet(function(itemstring) end if mod_namespace ~= id_modname then minetest.register_alias_force(new_id, itemstring) + minetest.register_alias_force(alt_id, itemstring) end if minetest.settings:get_bool("mcl_item_id_debug", false) then return new_id, "#555555" end -end) \ No newline at end of file +end) diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr index 54c376c3b..5cc402167 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr @@ -14,7 +14,7 @@ Grows on grass blocks, podzol, dirt or coarse dirt=Wächst auf Grasblöcken, Pod Flammable=Entzündlich Zombie view range: -50%=Zombiesichtweite: -50% Skeleton view range: -50%=Skelettsichtweite: -50% -Creeper view range: -50%=Creepersichtweite: -50% +Stalker view range: -50%=Stalkersichtweite: -50% Damage: @1=Schaden: @1 Damage (@1): @2=Schaden (@1): @2 Healing: @1=Heilung: @1 @@ -41,7 +41,6 @@ Fast=Schnell Slow=Langsam Very slow=Sehr langsam Painfully slow=Furchtbar langsam -Mining durability: @1=Grabehaltbarkeit: @1 Block breaking strength: @1=Blockbruchstärke: @1 @1 uses=@1 Verwendungen Unlimited uses=Unbegrenzte Verwendungen diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.es.tr b/mods/HELP/mcl_tt/locale/mcl_tt.es.tr new file mode 100644 index 000000000..b845c4102 --- /dev/null +++ b/mods/HELP/mcl_tt/locale/mcl_tt.es.tr @@ -0,0 +1,47 @@ +# textdomain: mcl_tt +Head armor=Armadura para la cabeza +Torso armor=Armadura para el torso +Legs armor=Armadura para las piernas +Feet armor=Armadura para los pies +Armor points: @1=Puntos de armadura: @1 +Armor durability: @1=Durabilidad de armadura: @1 +Protection: @1%=Protección: @1% +Hunger points: +@1=Puntos de hambre: +@1 +Saturation points: +@1=Puntos de saturación: +@1 +Deals damage when falling=Causa daño al caer +Grows on grass blocks or dirt=Crece sobre bloques de pasto o tierra +Grows on grass blocks, podzol, dirt or coarse dirt=Crece sobre bloques de pasto, podsol, tierra o tierra estéril +Flammable=Inflamable +Zombie view range: -50%=Rango de visión zombie: -50% +Skeleton view range: -50%=Rango de visión de esqueleto: -50% +Stalker view range: -50%=Rango de visión de stalker: -50% +Damage: @1=Daño: @1 +Damage (@1): @2=Daño (@1): @2 +Healing: @1=Curación: @1 +Healing (@1): @2=Curación (@1): @2 +Full punch interval: @1s=Intervalo de golpe completo: @1s +Contact damage: @1 per second=Daño por contacto: @1 por segundo +Contact healing: @1 per second=Curación por contacto: @1 por segundo +Drowning damage: @1=Dañor por ahogamiento: @1 +Bouncy (@1%)=Rebota (@1%) +Luminance: @1=Luminancia: @1 +Slippery=Resbaladizo +Climbable=Escalable +Climbable (only downwards)=Escalable (solo hacia abajo) +No jumping=No saltar +No swimming upwards=No nadar hacia arriba +No rising=No levantar +Fall damage: @1%=Daño por caída: @1% +Fall damage: +@1%=Daño por caída: @1% +No fall damage=Sin daño por caída +Mining speed: @1=Velocidad de minado: @1 +Very fast=Muy rápido +Extremely fast=Extremadamente rápido +Fast=Rápido +Slow=Lento +Very slow=Muy lento +Painfully slow=Dolorosamente lento +Block breaking strength: @1=Fuerza para romper bloques: @1 +@1 uses=@1 usos +Unlimited uses=Usos ilimitados +Durability: @1=Durabilidad: @1 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr index 77e9a35b0..1202581e9 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr @@ -14,7 +14,7 @@ Grows on grass blocks, podzol, dirt or coarse dirt=Pousse sur les blocs de gazon Flammable=Inflammable Zombie view range: -50%=Distance de vue de Zombie : -50% Skeleton view range: -50%=Distance de vue de Squelette : -50% -Creeper view range: -50%=Distance de vue de Creeper : -50% +Stalker view range: -50%=Distance de vue de Stalker : -50% Damage: @1=Dégâts : @1 Damage (@1): @2=Dégâts (@1) : @2 Healing: @1=Guérison : @1 @@ -41,7 +41,6 @@ Fast=Rapide Slow=Lent Very slow=Très lent Painfully slow=Péniblement lent -Mining durability: @1=Durabilité de minage : @1 Block breaking strength: @1=Résistance à la rupture : @1 @1 uses=@1 utilisations Unlimited uses=Utilisations illimitées diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr index 5e5cd5e7a..5bb044f3f 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr @@ -41,7 +41,6 @@ Fast=速い Slow=遅い Very slow=とても遅い Painfully slow=苦痛レベルで遅い -Mining durability: @1=採掘耐久度:@1 Block breaking strength: @1=ブロック破壊力:@1 @1 uses=@1 使用 Unlimited uses=無限に使用可能 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr b/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr index aecc15d1e..912c98ac7 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr @@ -14,7 +14,7 @@ Grows on grass blocks, podzol, dirt or coarse dirt=Rośnie na blokach trawy, bie Flammable=Łatwopalne Zombie view range: -50%=Zasięg widzenia zombie: -50% Skeleton view range: -50%=Zasięg widzenia szkieleta: -50% -Creeper view range: -50%=Zasięg widzenia creepera: -50% +Stalker view range: -50%=Zasięg widzenia stalkera: -50% Damage: @1=Obrażenia: @1 Damage (@1): @2=Obrażenia (@1): @2 Healing: @1=Leczenie: @1 @@ -41,8 +41,8 @@ Fast=Szybkie Slow=Wolne Very slow=Bardzo wolne Painfully slow=Boleśnie wolne -Mining durability: @1=Wytrzymałość kopania: @1 +Durability: @1=Wytrzymałość: @1 Block breaking strength: @1=Siła niszczenia bloku: @1 @1 uses=@1 użyć Unlimited uses=Nielimitowane użycia - +...stacks=...kumuluje się diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.pt_BR.tr b/mods/HELP/mcl_tt/locale/mcl_tt.pt_BR.tr new file mode 100644 index 000000000..c97eb4176 --- /dev/null +++ b/mods/HELP/mcl_tt/locale/mcl_tt.pt_BR.tr @@ -0,0 +1,47 @@ +# textdomain: mcl_tt +Head armor=Armadura de cabeça +Torso armor=Armadura de torso +Legs armor=Armadura de pernas +Feet armor=Armadura de pés +Armor points: @1=Pontos de armadura: @1 +Armor durability: @1=Durabilidade da armadura: @1 +Protection: @1%=Proteção: @1% +Hunger points: +@1=Pontos de fome: +@1 +Saturation points: +@1=Pontos de saturação: +@1 +Deals damage when falling=Dá dano enquanto cai +Grows on grass blocks or dirt=Cresce em blocos de grama ou terra +Grows on grass blocks, podzol, dirt or coarse dirt=Cresce em blocos de grama, podzol, terra ou terra infértil +Flammable=Inflamável +Zombie view range: -50%=Alcançe de visão do zumbi: -50% +Skeleton view range: -50%=Alcançe de visão do esqueleto: -50% +Stalker view range: -50%=Alcançe de visão do stalker: -50% +Damage: @1= Dano: @1 +Damage (@1): @2=Dano (@1): @2 +Healing: @1=Cura: @1 +Healing (@1): @2=Cura (@1): @2 +Full punch interval: @1s=Intervalo completo de batida: @1s +Contact damage: @1 per second=Dano por contaro: @1 por segundo +Contact healing: @1 per second=Cura por contato: @1 por segundo +Drowning damage: @1=Dano de afogamento: @1 +Bouncy (@1%)=Saltitante (@1%) +Luminance: @1=Bliho: @1 +Slippery=Escorregadio +Climbable=Escalável +Climbable (only downwards)=Escalável (apenas em descida) +No jumping=Sem pulo +No swimming upwards=Sem natação em subida +No rising=Sem levantamento +Fall damage: @1%=Dano de queda: @1% +Fall damage: +@1%=Dano de queda: +@1% +No fall damage=Sem dano de queda +Mining speed: @1=Velocidade de mineração: @1 +Very fast=Muito rápido +Extremely fast=Extremamente rápido +Fast=Rápido +Slow=Lento +Very slow=Muito lento +Painfully slow=Dolorosamente lento +Block breaking strength: @1=Força de quebra do bloco: @1 +@1 uses=@1 usos +Unlimited uses=Usos ilimitados +Durability: @1=Durabilidade: @1 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.ru.tr b/mods/HELP/mcl_tt/locale/mcl_tt.ru.tr index 349b6a5fb..9e0487b5a 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.ru.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.ru.tr @@ -1,47 +1,47 @@ # textdomain: mcl_tt -Head armor=Зашита головы -Torso armor=Защита тела -Legs armor=Защита ног -Feet armor=Защита ступней -Armor points: @1=Эффективность защиты: @1 -Armor durability: @1=Долговечность защиты: @1 -Protection: @1%=Уровень защиты: @1% +Head armor=Броня для головы +Torso armor=Броня для торса +Legs armor=Броня для ног +Feet armor=Броня для ступней +Armor points: @1=Очки защиты: @1 +Armor durability: @1=Прочность брони: @1 +Protection: @1%=Защита: @1% Hunger points: +@1=Очки голода: +@1 -Saturation points: +@1=Очки сытости: +@1 +Saturation points: +@1=Насыщение: +@1 Deals damage when falling=Наносит урон при падении -Grows on grass blocks or dirt=Растёт на блоках травы или грязи -Grows on grass blocks, podzol, dirt or coarse dirt=Растёт на блоках травы, подзола, грязи и твёрдой грязи -Flammable=Легковоспламенимо +Grows on grass blocks or dirt=Растёт на дёрне, земле +Grows on grass blocks, podzol, dirt or coarse dirt=Растёт на дёрне, земле, подзоле, каменистой земли +Flammable=Воспламенимо Zombie view range: -50%=Дальность зрения зомби: -50% Skeleton view range: -50%=Дальность зрения скелета: -50% -Creeper view range: -50%=Дальность зрения крипера: -50% +Stalker view range: -50%=Дальность зрения сталкера: -50% Damage: @1=Урон: @1 Damage (@1): @2=Урон (@1): @2 +Durability: @1=Прочность: @1 Healing: @1=Исцеление: @1 Healing (@1): @2=Исцеление (@1): @2 -Full punch interval: @1s=Интервал полного удара: @1 с -Contact damage: @1 per second=Урон при контакте: @1 в секунду -Contact healing: @1 per second=Исцеление при контакте: @1 в секунду -Drowning damage: @1=Урон при падении: @1 -Bouncy (@1%)=Упругость (@1%) +Full punch interval: @1s=Интервал удара: @1 с +Contact damage: @1 per second=Урон при контакте: @1 HP/с +Contact healing: @1 per second=Исцеление при контакте: @1 HP/с +Drowning damage: @1=Урон при утоплении: @1 +Bouncy (@1%)=Упругий: @1% Luminance: @1=Свечение: @1 -Slippery=Скользкость +Slippery=Скользкий Climbable=Можно карабкаться -Climbable (only downwards)=Можно спускаться +Climbable (only downwards)=Можно спускаться вниз No jumping=Нельзя прыгать No swimming upwards=Нельзя плыть вверх No rising=Нельзя подниматься -Fall damage: @1%=Урон при падении: @1% -Fall damage: +@1%=Урон при падении: +@1% +Fall damage: @1%=Урон от падения: @1% +Fall damage: +@1%=Урон от падения: +@1% No fall damage=Нет урона при падении Mining speed: @1=Скорость добычи: @1 -Very fast=очень высокая -Extremely fast=ужасно высокая -Fast=высокая -Slow=низкая -Very slow=очень низкая -Painfully slow=мучительно низкая -Mining durability: @1=Долговечность добычи: @1 -Block breaking strength: @1=Сила разбиения блоков: @1 -@1 uses=@1 раз(а) +Very fast=Очень высокая +Extremely fast=Экстремально высокая +Fast=Высокая +Slow=Низкая +Very slow=Очень низкая +Painfully slow=Крайне низкая +Block breaking strength: @1=Сила добычи: @1 +@1 uses=@1 Unlimited uses=не ограничено diff --git a/mods/HELP/mcl_tt/locale/template.txt b/mods/HELP/mcl_tt/locale/template.txt index 6fb735b13..15076ec24 100644 --- a/mods/HELP/mcl_tt/locale/template.txt +++ b/mods/HELP/mcl_tt/locale/template.txt @@ -14,7 +14,7 @@ Grows on grass blocks, podzol, dirt or coarse dirt= Flammable= Zombie view range: -50%= Skeleton view range: -50%= -Creeper view range: -50%= +Stalker view range: -50%= Damage: @1= Damage (@1): @2= Healing: @1= @@ -41,8 +41,8 @@ Fast= Slow= Very slow= Painfully slow= -Mining durability: @1= Block breaking strength: @1= @1 uses= Unlimited uses= Durability: @1= +...stacks= diff --git a/mods/HELP/mcl_tt/mod.conf b/mods/HELP/mcl_tt/mod.conf index e442e1320..b9ca12379 100644 --- a/mods/HELP/mcl_tt/mod.conf +++ b/mods/HELP/mcl_tt/mod.conf @@ -1,4 +1,4 @@ name = mcl_tt author = Wuzzy description = Add MCL2 tooltips -depends = tt, mcl_enchanting, mcl_colors +depends = tt, mcl_enchanting, mcl_colors, mcl_util diff --git a/mods/HELP/mcl_tt/snippets_base.lua b/mods/HELP/mcl_tt/snippets_base.lua index 4e200d539..f20f3dfe2 100644 --- a/mods/HELP/mcl_tt/snippets_base.lua +++ b/mods/HELP/mcl_tt/snippets_base.lua @@ -35,7 +35,7 @@ local function newline(str) end -- Digging capabilities of tool -tt.register_snippet(function(itemstring, toolcaps) +tt.register_snippet(function(itemstring, toolcaps, itemstack) local def = minetest.registered_items[itemstring] if not toolcaps then return @@ -85,7 +85,12 @@ tt.register_snippet(function(itemstring, toolcaps) if def._doc_items_durability == nil and base_uses > 0 then local real_uses = base_uses * math.pow(3, maxlevel) if real_uses < 65535 then - miningusesstr = S("@1 uses", real_uses) + if itemstack then + local remaining_uses = math.round(real_uses - (itemstack:get_wear() * base_uses) / 65535) + miningusesstr = remaining_uses .. "/" .. real_uses + else + miningusesstr = S("@1 uses", real_uses) + end else miningusesstr = S("Unlimited uses") end @@ -95,7 +100,7 @@ tt.register_snippet(function(itemstring, toolcaps) capstr = capstr .. S("Mining speed: @1", speedstr) .. "\n" end if miningusesstr ~= "" then - capstr = capstr .. S("Mining durability: @1", miningusesstr) .. "\n" + capstr = capstr .. S("Durability: @1", miningusesstr) .. "\n" end -- Only show one group at max diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index 825776f5f..639422295 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -25,6 +25,7 @@ tt.register_snippet(function(itemstring) end return s end) + tt.register_snippet(function(itemstring, _, itemstack) --local def = minetest.registered_items[itemstring] local s = "" @@ -34,13 +35,18 @@ tt.register_snippet(function(itemstring, _, itemstack) s = s .. S("Armor points: @1", pts) s = s .. "\n" end + local remaining_uses = use if itemstack then local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") if unbreaking > 0 then use = math.floor(use / (0.6 + 0.4 / (unbreaking + 1))) end + remaining_uses = math.round(use - (itemstack:get_wear() * use) / 65535) end if use > 0 then + if use ~= remaining_uses then + use = remaining_uses .. "/" .. use -- implicit conversion from number to string + end s = s .. S("Armor durability: @1", use) end if s == "" then @@ -102,13 +108,71 @@ tt.register_snippet(function(itemstring) return S("Zombie view range: -50%") elseif itemstring == "mcl_heads:skeleton" then return S("Skeleton view range: -50%") - elseif itemstring == "mcl_heads:creeper" then - return S("Creeper view range: -50%") + elseif itemstring == "mcl_heads:stalker" then + return S("Stalker view range: -50%") end end) tt.register_snippet(function(itemstring, _, itemstack) if itemstring:sub(1, 23) == "mcl_fishing:fishing_rod" or itemstring:sub(1, 12) == "mcl_bows:bow" then - return S("Durability: @1", S("@1 uses", mcl_util.calculate_durability(itemstack or ItemStack(itemstring)))) + local stack = itemstack or ItemStack(itemstring) + local use = mcl_util.calculate_durability(stack) + local remaining_use = math.round(use - (stack:get_wear() * use) / 65535) + return S("Durability: @1", S("@1 uses", remaining_use .."/".. use)) end end) + + +-- Potions info +tt.register_snippet(function(itemstring, _, itemstack) + if not itemstack then return end + local def = itemstack:get_definition() + if def.groups._mcl_potion ~= 1 then return end + + local s = "" + local meta = itemstack:get_meta() + local potency = meta:get_int("mcl_potions:potion_potent") + local plus = meta:get_int("mcl_potions:potion_plus") + local sl_factor = 1 + if def.groups.splash_potion == 1 then + sl_factor = mcl_potions.SPLASH_FACTOR + elseif def.groups.ling_potion == 1 then + sl_factor = mcl_potions.LINGERING_FACTOR + end + if def._dynamic_tt then s = s.. def._dynamic_tt((potency+1)*sl_factor).. "\n" end + local effects = def._effect_list + if effects then + local effect + local dur + local timestamp + local ef_level + local roman_lvl + local factor + local ef_tt + for name, details in pairs(effects) do + effect = mcl_potions.registered_effects[name] + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) * sl_factor + if potency > 0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency) + end + else + dur = details.dur + end + timestamp = math.floor(dur/60)..string.format(":%02d",math.floor(dur % 60)) + if details.uses_level then + ef_level = details.level + details.level_scaling * (potency) + else + ef_level = details.level + end + if ef_level > 1 then roman_lvl = " ".. mcl_util.to_roman(ef_level) + else roman_lvl = "" end + s = s.. effect.description.. roman_lvl.. " (".. timestamp.. ")\n" + if effect.uses_factor then factor = effect.level_to_factor(ef_level) end + if effect.get_tt then ef_tt = minetest.colorize("grey", effect.get_tt(factor)) else ef_tt = "" end + if ef_tt ~= "" then s = s.. ef_tt.. "\n" end + if details.effect_stacks then s = s.. minetest.colorize("grey", S("...stacks")).. "\n" end + end + end + return s:trim() +end) diff --git a/mods/HELP/tt/init.lua b/mods/HELP/tt/init.lua index f2b83b612..8cc893d47 100644 --- a/mods/HELP/tt/init.lua +++ b/mods/HELP/tt/init.lua @@ -74,8 +74,25 @@ function tt.reload_itemstack_description(itemstack) local orig_desc = def._tt_original_description or def.description if meta:get_string("name") ~= "" then orig_desc = minetest.colorize(tt.NAME_COLOR, meta:get_string("name")) + elseif def.groups._mcl_potion == 1 then + local potency = meta:get_int("mcl_potions:potion_potent") + local plus = meta:get_int("mcl_potions:potion_plus") + if potency > 0 then + local sym_potency = mcl_util.to_roman(potency+1) + orig_desc = orig_desc.. " ".. sym_potency + end + if plus > 0 then + local sym_plus = " " + local i = plus + while i>0 do + i = i - 1 + sym_plus = sym_plus.. "+" + end + orig_desc = orig_desc.. sym_plus + end end local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack) + if desc == def.description and meta:get_string("description") == "" then return end meta:set_string("description", desc) end end diff --git a/mods/HELP/tt/mod.conf b/mods/HELP/tt/mod.conf index 2a260772d..7c4902418 100644 --- a/mods/HELP/tt/mod.conf +++ b/mods/HELP/tt/mod.conf @@ -1,4 +1,4 @@ name = tt author = Wuzzy description = Support for custom tooltip extensions for items -depends = mcl_colors +depends = mcl_colors, mcl_util diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index 6333272bd..ca87a812c 100644 --- a/mods/HUD/awards/api.lua +++ b/mods/HUD/awards/api.lua @@ -217,7 +217,9 @@ function awards.unlock(name, award) -- Get 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 awards.save() diff --git a/mods/HUD/awards/locale/awards.de.tr b/mods/HUD/awards/locale/awards.de.tr index 19db5e0be..1decf81ec 100644 --- a/mods/HUD/awards/locale/awards.de.tr +++ b/mods/HUD/awards/locale/awards.de.tr @@ -1,8 +1,8 @@ # textdomain:awards @1: @2=@1: @2 @1 (got)=@1 (erhalten) -@1’s awards:=Auszeichnungen von @: -(Secret Award)=(Geheime Auszeichnung) +@1’s awards:=Auszeichnungen von @1: +(Secret Advancement)=(Geheime Auszeichnung) Achievement gotten!=Auszeichnung erhalten! Achievement gotten:=Auszeichnung erhalten: Achievement gotten: @1=Auszeichnung erhalten: @1 @@ -61,4 +61,4 @@ Achievement “@1” does not exist.=Auszeichnung »@1« existiert nicht. Write something in chat.=Schreiben Sie etwas in den Chat. Write @1 chat messages.=Schreiben Sie @1 Chatnachrichten. @1/@2 chat messages=@1/@2 Chatnachrichten -Awards are disabled, enable them first by using /awards enable!=Ihre Auszeichnungen sind aktuell deaktiviert, bitte aktivieren Sie diese zuerst indem Sie /awards enable ausführen bevor Sie diesen Befehl erneut verwenden! \ No newline at end of file +Awards are disabled, enable them first by using /awards enable!=Ihre Auszeichnungen sind aktuell deaktiviert, bitte aktivieren Sie diese zuerst indem Sie /awards enable ausführen bevor Sie diesen Befehl erneut verwenden! diff --git a/mods/HUD/awards/locale/awards.es.tr b/mods/HUD/awards/locale/awards.es.tr index 15e8c4670..4058a8b62 100644 --- a/mods/HUD/awards/locale/awards.es.tr +++ b/mods/HUD/awards/locale/awards.es.tr @@ -2,7 +2,7 @@ @1: @2=@1: @2 @1 (got)=@1 (Completado) @1’s awards:=Premios de @1: -(Secret Award)=(Premio secreto) +(Secret Advancement)=(Premio secreto) Achievement gotten!=¡Logro conseguido! Achievement gotten:=Logro conseguido: Achievement gotten: @1=Logro conseguido: @1 diff --git a/mods/HUD/awards/locale/awards.fr.tr b/mods/HUD/awards/locale/awards.fr.tr index 767848a69..7c3fd2a84 100644 --- a/mods/HUD/awards/locale/awards.fr.tr +++ b/mods/HUD/awards/locale/awards.fr.tr @@ -8,7 +8,7 @@ @1 (got)=@1 (obtenu) @1: @2=@1 : @2 @1’s awards:=Récompenses de @1: -(Secret Award)=(Récompense secrète) +(Secret Advancement)=(Récompense secrète) = = Advancement Made!=Progrès réalisé ! @@ -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 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 ! +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 diff --git a/mods/HUD/awards/locale/awards.ja.tr b/mods/HUD/awards/locale/awards.ja.tr index 5a3b73174..fe1dd5f5e 100644 --- a/mods/HUD/awards/locale/awards.ja.tr +++ b/mods/HUD/awards/locale/awards.ja.tr @@ -8,7 +8,7 @@ @1 (got)=@1(入手した) @1: @2=@1: @2 @1’s awards:=@1 のアワード -(Secret Award)=(シークレットアワード) +(Secret Advancement)=(シークレットアワード) =<実績 ID> =<名前> Advancement Made!=進捗 更新! diff --git a/mods/HUD/awards/locale/awards.pl.tr b/mods/HUD/awards/locale/awards.pl.tr index 76d5b9161..2b48d32c3 100644 --- a/mods/HUD/awards/locale/awards.pl.tr +++ b/mods/HUD/awards/locale/awards.pl.tr @@ -8,7 +8,7 @@ @1 (got)=@1 (zdobyto) @1: @2=@1: @2 @1’s awards:=Nagrody @1: -(Secret Award)=(Sekretna nagroda) +(Secret Advancement)=(Sekretna nagroda) = = Achievement gotten!=Zdobyto osiągnięcie! diff --git a/mods/HUD/awards/locale/awards.ru.tr b/mods/HUD/awards/locale/awards.ru.tr index 6f7a6d1bf..c064061e0 100644 --- a/mods/HUD/awards/locale/awards.ru.tr +++ b/mods/HUD/awards/locale/awards.ru.tr @@ -3,19 +3,19 @@ @1/@2 crafted=@1/@2 создано @1/@2 deaths=@1/@2 смертей @1/@2 dug=@1/@2 выкопано -@1/@2 game joins=@1/@2 присоединений к игре +@1/@2 game joins=@1/@2 подключений к игре @1/@2 placed=@1/@2 размещено @1 (got)=@1 (получено) @1: @2=@1: @2 @1’s awards:=Награды @1: -(Secret Award)=(Тайная награда) +(Secret Advancement)=(Секретное достижение) =<идентификатор достижения> =<имя> Advancement Made!=Получено достижение! Advancement Made:=Получено достижение: Advancement: @1=Достижение: @1 Achievement not found.=Достижение не найдено. -All your awards and statistics have been cleared. You can now start again.=Ваши награды удалены вместе со всей статистикой. Теперь можно начать всё сначала. +All your awards and statistics have been cleared. You can now start again.=Ваши награды и статистика удалены. Теперь можно начать всё сначала. Awards=Награды Craft: @1×@2=Создано: @1×@2 Craft: @1=Создано: @1 @@ -25,23 +25,23 @@ Get the achievements statistics for the given player or yourself=Получен Join the game @1 times.=Присоединился(ась) к игре @1 раз(а). Join the game.=Присоединился(ась) к игре. List awards in chat (deprecated)=Вывести список наград в чат (устарело). -Place a block: @1=Разметил(а) блок: @1 -Place blocks: @1×@2=Разместил(а) блоки: @1×@2 -Secret Advancement Made!=Тайное достижение получено! -Secret Advancement Made:=Тайное достижение получено: -Secret Advancement Made: @1=Тайное достижение получено: @1 +Place a block: @1=Поставил(а) блок: @1 +Place blocks: @1×@2=Поставил(а) блоки: @1×@2 +Secret Advancement Made!=Секретное достижение получено! +Secret Advancement Made:=Секретное достижение получено: +Secret Advancement Made: @1=Секретное достижение получено: @1 Show details of an achievement=Показать подробности достижения -Show, clear, disable or enable your advancements.=Отобразить, очистить, запретить или разрешить ваши достижения -Make this advancement to find out what it is.=Получите это достижение, чтобы узнать, что это. +Show, clear, disable or enable your advancements.=Показать, очистить, отключить или включить ваши достижения +Make this advancement to find out what it is.=Получите это достижение, чтобы узнать что это. Write @1 chat messages.=Написано @1 сообщений(е,я) в беседе. -Write something in chat.=Написал(а) что-то в беседе. -You have disabled your advancements.=Вы запретили ваши достижения. -You have enabled your advancements.=Вы разрешили ваши достижения. -You have not gotten any awards.=Вы пока не получали наград. -You've disabled awards. Type /awards enable to reenable.=Вы запретили награды. Выполните /awards enable, чтобы разрешить их обратно. -[c|clear|disable|enable]=[c|clear — очистить|disable — запретить|enable — разрешить] -OK=Ладно -Error: No awards available.=Ошибка: награды недоступны +Write something in chat.=Напишите что-нибудь в чат. +You have disabled your advancements.=Вы отключили ваши достижения. +You have enabled your advancements.=Вы включили ваши достижения. +You have not gotten any awards.=Вы пока не получили никаких наград. +You've disabled awards. Type /awards enable to reenable.=Вы отключили награды. Введите /awards enable, чтобы включить их. +[c|clear|disable|enable]=[c|clear — очистить|disable — отключить|enable — включить] +OK=ОК +Error: No awards available.=Ошибка: Нет доступных наград. Eat: @1×@2=Съедено: @1×@2 Eat: @1=Съедено: @1 @1/@2 eaten=@1/@2 съедено @@ -50,14 +50,14 @@ Dig @1 block(s).=Выкопал(а) @1 блок(а,ов). Eat @1 item(s).=Съел(а) @1 предмет(а,ов). Craft @1 item(s).=Сделал(а) @1 предмет(а,ов). Can give advancements to any player=Может выдавать достижения любому игроку -(grant ( | all)) | list=(grant <игрок> (<достижение> | all — всем)) | список +(grant ( | all)) | list=(grant <игрок> (<достижение> | all — всем)) | list — список Give advancement to player or list all advancements=Выдать достижение игроку или отобразить все достижения @1 (@2)=@1 (@2) -Invalid syntax.=Неверное составление. -Invalid action.=Непредусмотренное действие. -Player is not online.=Игрок не подключён. +Invalid syntax.=Неверный синтаксис. +Invalid action.=Неверное действие. +Player is not online.=Игрок не в сети. Done.=Готово. -Advancement “@1” does not exist.=Достижения «@1» не существует. +Advancement “@1” does not exist.=Достижения “@1” не существует. @1 has made the advancement @2=@1 получил(а) достижение @2 Mine a block: @1=Добыл(а) блок: @1 Mine blocks: @1×@2=Добыл(а) блоки: @1×@2 @@ -65,6 +65,6 @@ Awards are disabled, enable them first by using /awards enable!=Награды Goal Completed:=Цель выполнена: Goal Completed!=Цель выполнена! Goal Completed: @1=Цель выполнена: @1 -Challenge Completed:=Задача выполнена: -Challenge Completed!=Задача выполнена! -Challenge Completed: @1=Задача выполнена: @1 \ No newline at end of file +Challenge Completed:=Испытание выполнено: +Challenge Completed!=Испытание выполнено! +Challenge Completed: @1=Испытание выполнено: @1 \ No newline at end of file diff --git a/mods/HUD/awards/locale/template.txt b/mods/HUD/awards/locale/template.txt index 5312c2ba7..af608863b 100644 --- a/mods/HUD/awards/locale/template.txt +++ b/mods/HUD/awards/locale/template.txt @@ -8,7 +8,7 @@ @1 (got)= @1: @2= @1’s awards:= -(Secret Award)= +(Secret Advancement)= = = Advancement Made!= diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index 505ff403b..7f86a959d 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -521,7 +521,9 @@ end local function update_health(player) local hp_max = player:get_properties().hp_max - hb.change_hudbar(player, "health", player:get_hp(), hp_max) + local hp = player:get_hp() + if hp > hp_max then hp = hp_max end + hb.change_hudbar(player, "health", hp, hp_max) end -- update built-in HUD bars diff --git a/mods/HUD/hudbars/locale/hudbars.pt_BR.tr b/mods/HUD/hudbars/locale/hudbars.pt_BR.tr new file mode 100644 index 000000000..566906452 --- /dev/null +++ b/mods/HUD/hudbars/locale/hudbars.pt_BR.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=Saúde +Breath=Respiração + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20” +@1: @2/@3=@1: @2/@3 diff --git a/mods/HUD/hudbars/locale/hudbars.ru.tr b/mods/HUD/hudbars/locale/hudbars.ru.tr index 2d278e339..0f9ea4ec4 100644 --- a/mods/HUD/hudbars/locale/hudbars.ru.tr +++ b/mods/HUD/hudbars/locale/hudbars.ru.tr @@ -1,4 +1,6 @@ # textdomain: hudbars -Health=HP -Breath=дыхание +Health=Здоровье +Breath=Дыхание + +# Строка форматирования для прогрессбаров, например: “Здоровье: 5/20” @1: @2/@3=@1: @2/@3 diff --git a/mods/HUD/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index 4d272fe86..361a3e659 100644 --- a/mods/HUD/mcl_achievements/init.lua +++ b/mods/HUD/mcl_achievements/init.lua @@ -431,6 +431,27 @@ awards.register_achievement("mcl:wax_off", { group = "Husbandry", }) +-- Triggered in mcl_smithing_table +awards.register_achievement("mcl:trim", { + title = S("Crafting a New Look"), + description = S("Craft a trimmed armor at a Smithing Table"), + icon = "dune_armor_trim_smithing_template.png", + type = "Advancement", + group = "Adventure", +}) + +awards.register_achievement("mcl:lots_of_trimming", { + title = S("Smithing with Style"), + description = S("Apply these smithing templates at least once: Spire, Snout, Rib, Ward, Silence, Vex, Tide, Wayfinder"), + icon = "silence_armor_trim_smithing_template.png", + type = "Advancement", + group = "Adventure", + on_unlock = function(name, awdef) + -- delete json that is no longer needed + minetest.get_player_by_name(name):get_meta():set_string("mcl_smithing_table:achievement_trims", "") + end, +}) + -- NON-PC ACHIEVEMENTS (XBox, Pocket Edition, etc.) if non_pc_achievements then @@ -529,6 +550,13 @@ awards.register_achievement("mcl:obsidian", { type = "Advancement", group = "Overworld", }) +awards.register_achievement("mcl:fireball_redir_serv", { + title = S("Fireball Redirection Service"), + description = S("Defeat a ghast with his own weapon."), + icon = "mcl_fire_fire_charge.png", + type = "Advancement", + group = "Nether", +}) awards.register_achievement("mcl:hero_of_the_village", { title = S("Hero of the Village"), diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr old mode 100644 new mode 100755 index 1c6f668e5..7b73d1887 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr @@ -51,3 +51,7 @@ Bring Home the Beacon=Den Nachbarn heimleuchten Use a beacon.=Benutzen Sie ein Leuchtfeuer. Beaconator=Leuchtturmwärter Use a fully powered beacon.=Benutzen Sie ein vollständiges Leuchtfeuer. +Crafting a New Look=Ein neues Aussehen +Craft a trimmed armor at a Smithing Table=Versieh ein Rüstungsteil an einem Schmiedetisch mit einem Rüstungsbesatz +Smithing with Style=Schmieden mit Stil +Apply these smithing templates at least once: Spire, Snout, Rib, Ward, Silence, Vex, Tide, Wayfinder=Wende jede dieser Schmiedevorlagen mindestens einmal an: Turmspitze, Schnauze, Rippe, Warthof, Stille, Plagegeist, Gezeiten und Wegfinder \ No newline at end of file diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr index 6f00d76b7..19f18703b 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr @@ -108,7 +108,10 @@ Put lava in a bucket.=Pon lava en un cubo. Hero of the Village=Héroe de la aldea Successfully defend a village from a raid=Defiende una aldea de una invasión 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. -Sería mejor alejarte de las aldeas por un tiempo... +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... Tactical Fishing=Pesca táctica 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 diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr index 95800d5e9..3330acddc 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr @@ -15,7 +15,7 @@ Eat a cooked porkchop.=Mangez du porc cuit. Eat a cooked rabbit.=Mangez du lapin cuit. Get really desperate and eat rotten flesh.=Soyez vraiment désespéré et mangez de la chair pourrie. Getting Wood=Obtenir du bois -Getting an Upgrade=Obtenir une augmentation de niveau +Getting an Upgrade=Obtenir une amélioration Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=Frappez un squelette, wither squelette ou stray à l'arc et à la flèche à une distance d'au moins 20 mètres. Hot Topic=Sujet brûlant Into Fire=Dans le feu @@ -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... Tactical Fishing=Pêche tactique 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 \ No newline at end of file diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr index 9a180d89b..2549db4d3 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr @@ -1,113 +1,113 @@ # textdomain:mcl_achievements -Acquire Hardware=Куй Железо -Bake Bread=Хлеб всему голова -Benchmarking=Верстак -Cow Tipper=Кожа да кости -Craft a bookshelf.=Создание книжной полки. -Craft a cake using wheat, sugar, milk and an egg.=Создание торта из пшеницы, сахара, молока и яйца. -Craft a crafting table from 4 wooden planks.=Создание верстака из 4 досок. -Craft a stone pickaxe using sticks and cobblestone.=Создание каменного топора из палок и булыжников. -Craft a wooden sword using wooden planks and sticks on a crafting table.=Изготовление деревянного меча из досок и палок на верстаке. +Acquire Hardware=Куй железо... +Bake Bread=Хлеб насущный +Benchmarking=Рабочий стол +Cow Tipper=Мясник +Craft a bookshelf.=Скрафтите книжную полку. +Craft a cake using wheat, sugar, milk and an egg.=Скрафтите торт из пшеницы, сахара, молока и яйца. +Craft a crafting table from 4 wooden planks.=Скрафтите верстак из 4 досок. +Craft a stone pickaxe using sticks and cobblestone.=Скрафтите каменную кирку из палок и булыжников. +Craft a wooden sword using wooden planks and sticks on a crafting table.=Скрафтите на верстаке деревянный меч из досок и палок. DIAMONDS!=АЛМАЗЫ! -Delicious Fish=Вкусная Рыба -Dispense With This=Раздавай Это -Eat a cooked porkchop.=Употребление в пищу приготовленной свиной отбивной. -Eat a cooked rabbit.=Употребление в пищу приготовленного кролика. -Get really desperate and eat rotten flesh.=Отчаянное и необдуманное употребление в пищу гнилого мяса -Getting Wood=Рубка Леса -Getting an Upgrade=Обновка -Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=Попадание по скелету, скелету-иссушителю либо уклонение от стрелы на расстоянии не менее 20 метров. -Hot Topic=Печник жжёт -Into Fire=В огне +Delicious Fish=Вкусная рыбка +Dispense With This=Раздайте с этим +Eat a cooked porkchop.=Съешьте приготовленную свинину. +Eat a cooked rabbit.=Съешьте приготовленную крольчатину. +Get really desperate and eat rotten flesh.=Отчайтесь и съешьте гнилое мясо. +Getting Wood=Нарубить древесины +Getting an Upgrade=Обновка! +Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=Попадите по скелету, скелету-иссушителю или страннику стрелой из лука на расстоянии не менее 20 метров. +Hot Topic=Жаркая тема +Into Fire=Огненные недра We Need to Go Deeper=В глубь Iron Belly=Железный живот Librarian=Библиотекарь -Mine emerald ore.=Добыча изумрудной руды. -On A Rail=На Рельсах -Pick up a blaze rod from the floor.=Поднятие огненного стержня с пола. -Pick up a diamond from the floor.=Поднятие алмаза с пола. -Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=Поднятие дерева с земли.@nПодсказка: Бейте по стволу, пока он не упадёт на землю, превратившись в предмет. -Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=Поднятие кожи с пола.@nПодсказка: Коровы и некоторые другие животные могут оставлять кожу, если их убивать. -Place a dispenser.=Установка диспенсера. -Place a flower pot.=Установка цветочного горшка. +Mine emerald ore.=Добудьте изумрудную руду. +On A Rail=Стук колёс +Pick up a blaze rod from the floor.=Поднимите огненный стержень. +Pick up a diamond from the floor.=Поднимите алмаз. +Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=Поднимите бревно с земли.@nПодсказка: Бейте по стволу, пока он не выпадёт на землю, превратившись в предмет. +Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=Поднимите кожу.@nПодсказка: Коровы и некоторые другие животные могут оставлять кожу, если их убить. +Place a dispenser.=Поставьте раздатчик. +Place a flower pot.=Поставьте цветочный горшок. Pork Chop=Свиная отбивная -Pot Planter=Сажатель горшков -Rabbit Season=Заячья пора -Sniper Duel=Лучный бой -Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=Приготовление рыбы в печи.@nПодсказка: Ловите рыбу удочкой и готовьте её в печи. -Take an iron ingot from a furnace's output slot.@nHint: To smelt an iron ingot, put a fuel (like coal) and iron ore into a furnace.=Получение слитка железа из печи.@nПодсказка: чтобы переплавить железную руду, нужно положить её в печь и туда же поместить топливо (уголь или другое). -The Haggler=Торговец -The Lie=Тортик -Time to Farm!=Время земледелия! -Time to Mine!=Время добывать! -Time to Strike!=Время сражаться! -Travel by minecart for at least 1000 meters from your starting point in a single ride.=Поездка на вагонетке минимум на 1000 метров от стартовой точки за один раз. -Use 8 cobblestones to craft a furnace.=Создание печи из 8 булыжников. -Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Создание деревянной мотыги из досок и палок на верстаке. -Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Создание деревянной кирки из досок и палок на верстаке. -Use obsidian and a fire starter to construct a Nether portal.=Создание при помощи обсидиана и огнива. -Use wheat to craft a bread.=Использование пшеницы для приготовления хлеба. -Who is Cutting Onions?= -Pick up a crying obsidian from the floor.= -Hidden in the Depths= -Pick up an Ancient Debris from the floor.= -The Nether=Преисподняя -Bring summer clothes.@nHint: Enter the Nether.=Возьмите с собой летнюю одежду.@nПодсказка: войдите в преисподнюю. -Isn't It Iron Pick= -Craft a iron pickaxe using sticks and iron.= -Postmortal= -Use a Totem of Undying to cheat death.= -Sweet Dreams= -Sleep in a bed to change your respawn point.= -Not Quite "Nine" Lives= -Charge a Respawn Anchor to the maximum.= -What A Deal!=Вот так сделка! -Successfully trade with a Villager.=Успешная торговля с жителем. -Withering Heights= -Summon the wither from the dead.= -The Cutest Predator= -Catch an Axolotl with a bucket!= -Fishy Business= -Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.= -Country Lode, Take Me Home= -Use a compass on a Lodestone.= -Serious Dedication= -Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.= -Local Brewery= -Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.= -Enchanter= -Enchant an item using an Enchantment Table.= -Bring Home the Beacon= -Use a beacon.= -Beaconator= -Use a fully powered beacon.= -The Next Generation= -Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.= -The End... Again...= -Respawn the Ender Dragon.= -Sky's the Limit= -Find the elytra and prepare to fly above and beyond!= -Free the End= -Kill the ender dragon. Good Luck!= -Bee Our Guest= -Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.= -Total Beelocation= -Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.= -Wax On= -Apply honeycomb to a copper block to protect it from the elements.= -Wax Off= -Scrape wax off of a copper block.= -The End?= -Or the beginning?@nHint: Enter an end portal.= -Stone Age= -Mine a stone with new pickaxe.= -Ice Bucket Challenge= -Obtain an obsidian block.= -Hot Stuff= -Put lava in a bucket.= -Hero of the Village= -Successfully defend a village from a raid= -Voluntary Exile= -Kill a raid captain. Maybe consider staying away from the local villages for the time being...= -Tactical Fishing= -Catch a fish... without a fishing rod!= \ No newline at end of file +Pot Planter=Садовод +Rabbit Season=Сезон кроликов +Sniper Duel=Снайперская дуэль +Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=Приготовьте рыбу в печи.@nПодсказка: Поймайте рыбу удочкой и приготовьте её в печи. +Take an iron ingot from a furnace's output slot.@nHint: To smelt an iron ingot, put a fuel (like coal) and iron ore into a furnace.=Получите слиток железа из печи.@nПодсказка: чтобы переплавить железную руду, нужно положить в печь руду и топливо (например, уголь). +The Haggler=Торгаш +The Lie=Тортик это ложь +Time to Farm!=Время фермерства! +Time to Mine!=Пора в шахту! +Time to Strike!=К бою готов! +Travel by minecart for at least 1000 meters from your starting point in a single ride.=Прокатитесь на вагонетке минимум на 1000 метров от стартовой точки за один раз. +Use 8 cobblestones to craft a furnace.=Скрафтите печь из 8 булыжников. +Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Скрафтите на верстаке деревянную мотыгу из досок и палок. +Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Скрафтите на верстаке деревянную кирку из досок и палок. +Use obsidian and a fire starter to construct a Nether portal.=Создайте портала в Незер при помощи обсидиана и огнива. +Use wheat to craft a bread.=Скрафтите хлеб из пшеницы. +Who is Cutting Onions?=Обсидиановы слёзы +Pick up a crying obsidian from the floor.=Добудьте плачущий обсидиан. +Hidden in the Depths=Осколки прошлого +Pick up an Ancient Debris from the floor.=Добудьте древние обломки. +The Nether=Незер +Bring summer clothes.@nHint: Enter the Nether.=Захватите летнюю одежду.@nПодсказка: войдите в Незер. +Isn't It Iron Pick=И кирка без дела ржавеет +Craft a iron pickaxe using sticks and iron.=Создайте железную кирку из железный слитков и палок. +Postmortal=Свет в конце тоннеля +Use a Totem of Undying to cheat death.=Воспользуйтесь тотемом бессмертия, чтобы перехитрить смерть. +Sweet Dreams=Спи, моя радость, усни +Sleep in a bed to change your respawn point.=Поспите в кровати, чтобы изменить свою точку возрождения. +Not Quite "Nine" Lives=Ларец Кощея +Charge a Respawn Anchor to the maximum.=Полностью зарядите якорь возрождения. +What A Deal!=Не отходя от кассы! +Successfully trade with a Villager.=Купите что-нибудь у крестьян. +Withering Heights=Чудо-юдо +Summon the wither from the dead.=Призовите визера. +The Cutest Predator=Ласковый и нежный зверь +Catch an Axolotl with a bucket!=Поймайте аксолотля в ведро! +Fishy Business=На крючке +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=Поймайте рыбу.@nПодсказка: Поймайте треску, лосося, тропическую рыбу, или иглобрюха. +Country Lode, Take Me Home=Путеводный камень +Use a compass on a Lodestone.=Настройте компас на магнетит. +Serious Dedication=Заявка на победу +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=Улучшите мотыгу с помощью незеритового слитка, а потом попробуйте переосмыслить свою жизнь. +Local Brewery=Местный зельевар +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=Сварите зелье.@nПодсказка: Заберите зелье или пузырёк из варочной стойки. +Enchanter=Чародей +Enchant an item using an Enchantment Table.=Зачаруйте предмет на столе зачарований. +Bring Home the Beacon=Желанный свет +Use a beacon.=Постройте и установите маяк. +Beaconator=Маяковский +Use a fully powered beacon.=Доведите маяк до полной мощности. +The Next Generation=Новое поколение +Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.=Подберите яйцо дракона.@nПодсказка: Подберите яйцо с земли в инвентарь. +The End... Again...=Дежавю +Respawn the Ender Dragon.=Возродите Дракона Края. +Sky's the Limit=Где твои крылья? +Find the elytra and prepare to fly above and beyond!=Найдите элитры. +Free the End=Освободите Энд +Kill the ender dragon. Good Luck!=Убейте Дракона Края. Удачи! +Bee Our Guest=Пора подкрепиться +Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.=Поставьте костёр под ульем и соберите мёд в бутылочку, не разозлив пчёл. +Total Beelocation=Полосатый груз +Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.=С помощью “шёлкового касания” переместите пчелиное гнездо с 3 пчёлами внутри. +Wax On=Навести воск +Apply honeycomb to a copper block to protect it from the elements.=Нанесите воск на медный блок с помощью пчелиных сот. +Wax Off=Убрать воск +Scrape wax off of a copper block.=Соскребите воск с медного блока. +The End?=Конец? +Or the beginning?@nHint: Enter an end portal.=Или начало?@nПодсказка: Войдите в портал Энда. +Stone Age=Каменный век +Mine a stone with new pickaxe.=Добудьте камень новой киркой. +Ice Bucket Challenge=Две стихии +Obtain an obsidian block.=Получите обсидиан. +Hot Stuff=Горячая штучка +Put lava in a bucket.=Наберите ведро лавы. +Hero of the Village=Герой деревни +Successfully defend a village from a raid=Успешно отразите нападение на деревню. +Voluntary Exile=Добровольное изгнание +Kill a raid captain. Maybe consider staying away from the local villages for the time being...=Убейте главаря разбойников. Может, стоит пока держаться подальше от деревень... +Tactical Fishing=Рыбацкая хитрость +Catch a fish... without a fishing rod!=Поймайте рыбу... без удочки! \ No newline at end of file diff --git a/mods/HUD/mcl_achievements/locale/template.txt b/mods/HUD/mcl_achievements/locale/template.txt old mode 100644 new mode 100755 index d865b1668..89c422a08 --- a/mods/HUD/mcl_achievements/locale/template.txt +++ b/mods/HUD/mcl_achievements/locale/template.txt @@ -111,3 +111,7 @@ Voluntary Exile= Kill a raid captain. Maybe consider staying away from the local villages for the time being...= Tactical Fishing= Catch a fish... without a fishing rod!= +Crafting a New Look= +Craft a trimmed armor at a Smithing Table= +Smithing with Style= +Apply these smithing templates at least once: Spire, Snout, Rib, Ward, Silence, Vex, Tide, Wayfinder= \ No newline at end of file diff --git a/mods/HUD/mcl_base_textures/init.lua b/mods/HUD/mcl_base_textures/init.lua deleted file mode 100644 index 643c51108..000000000 --- a/mods/HUD/mcl_base_textures/init.lua +++ /dev/null @@ -1 +0,0 @@ --- This mod has no code and is only a collection of textures. diff --git a/mods/HUD/mcl_base_textures/mod.conf b/mods/HUD/mcl_base_textures/mod.conf deleted file mode 100644 index b36dccfe4..000000000 --- a/mods/HUD/mcl_base_textures/mod.conf +++ /dev/null @@ -1,3 +0,0 @@ -name = mcl_base_textures -author = Wuzzy -description = Provides core textures needed by Minetest. diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua index db3ac8436..3ab08ab0f 100644 --- a/mods/HUD/mcl_credits/init.lua +++ b/mods/HUD/mcl_credits/init.lua @@ -58,7 +58,7 @@ function mcl_credits.show(player) } add_hud_element({ hud_elem_type = "image", - text = "mineclone2_logo.png", + text = "voxelibre_logo.png", scale = {x = 1, y = 1}, }, huds, 300, 0) add_hud_element({ @@ -89,7 +89,7 @@ function mcl_credits.show(player) end huds.icon = add_hud_element({ hud_elem_type = "image", - text = "mineclone2_icon.png", + text = "voxelibre_icon.png", scale = {x = 1, y = 1}, }, huds, y) mcl_credits.players[name] = huds diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr index fa26f5bc4..73fac3aed 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr @@ -3,7 +3,7 @@ A faithful Open Source clone of Minecraft=Ein treuer Open-Source-Klon von Minecraft Contributors=Mitwirkende Creator of MineClone=Schöpfer von MineClone -Creator of MineClone2=Schöpfer von MineClone2 +Creator of VoxeLibre=Schöpfer von VoxeLibre Developers=Entwickler Jump to speed up (additionally sprint)=Springen, um zu beschleunigen (zusätzlich sprinten) Maintainers=Betreuer diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.es.tr b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr index a8886286e..8dcbe2611 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.es.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr @@ -3,7 +3,7 @@ A faithful Open Source clone of Minecraft= Contributors= Creator of MineClone= -Creator of MineClone2= +Creator of VoxeLibre= Developers= Jump to speed up (additionally sprint)= Maintainers= @@ -11,4 +11,4 @@ MineClone5= Original Mod Authors= Sneak to skip= Textures= -Translations= \ No newline at end of file +Translations= diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr index b34249eff..293dcffe8 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr @@ -3,12 +3,17 @@ A faithful Open Source clone of Minecraft=Un clone open source de Minecraft Contributors=Contributeurs Creator of MineClone=Créateur de MineClone -Creator of MineClone2=Créateur de MineClone2 +Creator of VoxeLibre=Créateur de VoxeLibre Developers=Développeurs +Past Developers=Anciens Développeurs Jump to speed up (additionally sprint)=Saut pour accélérer (peut être combiné avec sprint) Maintainers=Mainteneurs +Previous Maintainers=Anciens Mainteneurs MineClone5=MineClone5 Original Mod Authors=Auteurs des mods originaux Sneak to skip=Shift pour passer Textures=Textures -Translations=Traductions \ No newline at end of file +Translations=Traductions +Music=Musique +Funders=Fondateurs +Special thanks=Remerciements spéciaux diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr index e7bbbbfc2..76bc74a2a 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr @@ -3,7 +3,7 @@ A faithful Open Source clone of Minecraft=オープンソースによるマインクラフトの忠実なクローン Contributors=投稿者 Creator of MineClone=MineClone の創始者 -Creator of MineClone2=MineClone2 の創始者 +Creator of VoxeLibre=VoxeLibre の創始者 Developers=開発者 Jump to speed up (additionally sprint)=ジャンプでスピードアップ(追加で疾走) Maintainers=メンテナンス diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr index a8886286e..8dcbe2611 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr @@ -3,7 +3,7 @@ A faithful Open Source clone of Minecraft= Contributors= Creator of MineClone= -Creator of MineClone2= +Creator of VoxeLibre= Developers= Jump to speed up (additionally sprint)= Maintainers= @@ -11,4 +11,4 @@ MineClone5= Original Mod Authors= Sneak to skip= Textures= -Translations= \ No newline at end of file +Translations= diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.pt_BR.tr b/mods/HUD/mcl_credits/locale/mcl_credits.pt_BR.tr new file mode 100644 index 000000000..1956aa4e3 --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.pt_BR.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_credits +3D Models=Modelos 3D +A faithful Open Source clone of Minecraft=Um clone fiel Open Source do Minecraft +Contributors=Colaboradores +Creator of MineClone=Criador do MineClone +Creator of VoxeLibre=Criador do VoxeLibre +Developers=Desenvolvedores +Past Developers=Desenvolvedores Passados +Jump to speed up (additionally sprint)=Pule para acelerar (arrancada adicional) +Maintainers=Mantedores +Previous Maintainers=Mantedores Anteriores +MineClone5=MineClone5 +Original Mod Authors=Autores Originais do Mod +Sneak to skip=Agache para pular +Textures=Texturas +Translations=Traduções +Music=Músicas +Funders=Financiadores +Special thanks=Agradecimentos especiais diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr index a8886286e..f9b5f3d38 100644 --- a/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr @@ -1,14 +1,19 @@ # textdomain: mcl_credits -3D Models= -A faithful Open Source clone of Minecraft= -Contributors= -Creator of MineClone= -Creator of MineClone2= -Developers= -Jump to speed up (additionally sprint)= -Maintainers= -MineClone5= -Original Mod Authors= -Sneak to skip= -Textures= -Translations= \ No newline at end of file +3D Models=3D модели +A faithful Open Source clone of Minecraft=Верный открытый клон Minecraft +Contributors=Контрибьюторы +Creator of MineClone=Создатель MineClone +Creator of VoxeLibre=Создатель VoxeLibre +Developers=Разработчики +Past Developers=Бывшие разработчики +Jump to speed up (additionally sprint)=[Прыжок] или [Спринт] для промотки вперед +Maintainers=Мейнтейнеры +Previous Maintainers=Бывшие мейнтейнеры +MineClone5=MineClone5 +Original Mod Authors=Авторы оригинальных модов +Sneak to skip=[Красться] для пропуска +Textures=Текстуры +Translations=Перевод +Music=Музыка +Funders=Спонсоры +Special thanks=Особая благодарность diff --git a/mods/HUD/mcl_credits/locale/template.txt b/mods/HUD/mcl_credits/locale/template.txt index 3ee9fa56c..3a6287437 100644 --- a/mods/HUD/mcl_credits/locale/template.txt +++ b/mods/HUD/mcl_credits/locale/template.txt @@ -3,12 +3,17 @@ A faithful Open Source clone of Minecraft= Contributors= Creator of MineClone= -Creator of MineClone2= +Creator of VoxeLibre= Developers= +Past Developers= Jump to speed up (additionally sprint)= Maintainers= +Previous Maintainers= MineClone5= Original Mod Authors= Sneak to skip= Textures= Translations= +Music= +Funders= +Special thanks= diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua index 7421350d0..59ee0f80f 100644 --- a/mods/HUD/mcl_credits/people.lua +++ b/mods/HUD/mcl_credits/people.lua @@ -5,39 +5,42 @@ return { {S("Creator of MineClone"), 0x0A9400, { "davedevils", }}, - {S("Creator of MineClone2"), 0xFBF837, { + {S("Creator of VoxeLibre"), 0xFBF837, { "Wuzzy", }}, {S("Maintainers"), 0xFF51D5, { "AncientMariner", - "Nicu", + "Herowl", }}, {S("Previous Maintainers"), 0xFFFFFF, { "Fleckenstein", "cora", + "Nicu", }}, {S("Developers"), 0xF84355, { "AFCMS", "epCode", "chmodsayshello", - "PrairieWind", "MrRar", - "FossFanatic ", "SmokeyDope", + "Faerraven / Michieal", + "rudzik8", + "teknomunk", }}, {S("Past Developers"), 0xF84355, { "jordan4ibanez", "iliekprogrammar", "kabou", "kay27", - "Faerraven / Michieal", "MysticTempest", "NO11", "SumianVoice", + "PrairieWind", + "FossFanatic", + "Codiac", }}, {S("Contributors"), 0x52FF00, { "RandomLegoBrick", - "rudzik8", "Code-Sploit", "aligator", "Rootyjr", @@ -114,12 +117,38 @@ return { "Niterux", "appgurueu", "seventeenthShulker", + "DinoNuggies4665", + "basxto", + "Morik666", + "Eliy21", + "mdk", + "Alessandra Lozoya", + "VanicGame", + "ThePython10110", + "Araca", + "Montandalar", + "mim", + "Dark", + "Bakawun", + "JoseDouglas26", + "Zasco", + "PrWalterB", + "michaljmalinowski", + "nixnoxus", + "Potiron", + "Tuxilio", + "Impulse", + "Doods", + "SOS-Games", + "Bram", + "qoheniac", + "WillConker", }}, {S("Music"), 0xA60014, { "Jordach for the jukebox music compilation from Big Freaking Dig", "Dark Reaven Music (https://soundcloud.com/dark-reaven-music) for the main menu theme (Calmed Cube) and Traitor (horizonchris96), which is licensed under https://creativecommons.org/licenses/by-sa/3.0/", - "Jester for helping to finely tune MineClone2 (https://www.youtube.com/@Jester-8-bit). Songs: Hailing Forest, Gift, 0dd BL0ck, Flock of One (License CC BY-SA 4.0)", - "Exhale & Tim Unwin for some wonderful MineClone2 tracks (https://www.youtube.com/channel/UClFo_JDWoG4NGrPQY0JPD_g). Songs: Valley of Ghosts, Lonely Blossom, Farmer (License CC BY-SA 4.0)", + "Jester for helping to finely tune VoxeLibre (https://www.youtube.com/@Jester-8-bit). Songs: Hailing Forest, Gift, 0dd BL0ck, Flock of One (License CC BY-SA 4.0)", + "Exhale & Tim Unwin for some wonderful VoxeLibre tracks (https://www.youtube.com/channel/UClFo_JDWoG4NGrPQY0JPD_g). Songs: Valley of Ghosts, Lonely Blossom, Farmer (License CC BY-SA 4.0)", "Diminixed for 3 fantastic tracks and remastering and leveling volumes. Songs: Afternoon Lullaby (pianowtune02), Spooled (ambientwip02), Never Grow Up (License CC BY-SA 4.0)", }}, {S("Original Mod Authors"), 0x343434, { @@ -157,6 +186,7 @@ return { "cora", "Faerraven / Michieal", "PrairieWind", + "ChrisPHP", }}, {S("3D Models"), 0x0019FF, { "22i", @@ -164,6 +194,7 @@ return { "epCode", "Faerraven / Michieal", "SumianVoice", + "thunder1035", }}, {S("Textures"), 0xFF9705, { "XSSheep", @@ -180,8 +211,11 @@ return { "Faerraven / Michieal", "Nicu", "Exhale", + "Aeonix_Aeon", "Wbjitscool", "SmokeyDope", + "thunder1035", + "Herowl", }}, {S("Translations"), 0x00FF60, { "Wuzzy", @@ -201,6 +235,10 @@ return { "Temak", "megustanlosfrijoles", "kbundg", + "Isaac Dennis", + "ADLON", + "Sab Pyrope", + "JoseDouglas26", }}, {S("Funders"), 0xF7FF00, { "40W", diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 6c2040545..82749ca94 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -156,7 +156,6 @@ mcl_death_messages = { plain = "@1 died a sweet death", assist = "@1 was poked to death by a sweet berry bush whilst trying to escape @2", }, - -- Missing snowballs: The Minecraft wiki mentions them but the MC source code does not. }, } diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pt_BR.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pt_BR.tr new file mode 100644 index 000000000..f1f64fa5c --- /dev/null +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pt_BR.tr @@ -0,0 +1,55 @@ +# textdomain: mcl_death_messages +@1 went up in flames=@1 pegou fogo +@1 walked into fire whilst fighting @2=@1 caminhou no fogo enquanto lutava contra @2 +@1 was struck by lightning=@1 foi atingido(a) por um raio +@1 was struck by lightning whilst fighting @2=@1 foi atingido(a) por um raio enquanto lutava contra @2 +@1 burned to death=@1 queimou até a morte +@1 was burnt to a crisp whilst fighting @2=@1 foi queimado até a crocância enquanto lutava contra @2 +@1 tried to swim in lava=@1 tentou nadar em lava +@1 tried to swim in lava to escape @2=@1 tentou nadar em lava para escapar de @2 +@1 discovered the floor was lava=@1 descobriu que o chão era lava +@1 walked into danger zone due to @2=@1 caminhou numa zona perigosa por conta de @2 +@1 suffocated in a wall=@1 sufocou em uma parede +@1 suffocated in a wall whilst fighting @2=@1 sufocou em uma parede enquanto lutava contra @2 +@1 drowned=@1 se afogou +@1 drowned whilst trying to escape @2=@1 se afogou enquanto tentava escapar de @2 +@1 starved to death=@1 morreu de fome +@1 starved to death whilst fighting @2=@1 morreu de fome enquanto lutava contra @2 +@1 was pricked to death=@1 foi espetado até a morte +@1 walked into a cactus whilst trying to escape @2=@1 caminhou até um cacto enquanto tentava escapar de @2 +@1 hit the ground too hard=@1 bateu muito forte no chão +@1 hit the ground too hard whilst trying to escape @2=@1 bateu muito forte no chão enquanto tentava escapar de @2 +@1 experienced kinetic energy=@1 experienciou a energia cinética +@1 experienced kinetic energy whilst trying to escape @2=@1 experienciou a energia cinética enquanto tentava escapar de @2 +@1 fell out of the world=@1 caiu do mundo +@1 didn't want to live in the same world as @2=@1 não queria viver no mesmo mundo que @2 +@1 died=@1 morreu +@1 died because of @2=@1 morreu por conta de @2 +@1 was killed by magic=@1 foi morto(a) por magia +@1 was killed by magic whilst trying to escape @2=@1 foi morto(a) por magia enquanto tentava escapar de @2 +@1 was killed by @2 using magic=@1 foi morto(a) por @2 usando magia +@1 was killed by @2 using @3=@1 foi morto(a) por @2 usando @3 +@1 was roasted in dragon breath=@1 foi assado(a) no bafo do dragão +@1 was roasted in dragon breath by @2=@1 foi assado(a) no bafo do dragão por @2 +@1 withered away=@1 apodreceu +@1 withered away whilst fighting @2=@1 apodreceu enquanto lutava contra @2 +@1 was shot by a skull from @2=@1 foi acertado(a) por um crânio vindo de @2 +@1 was squashed by a falling anvil=@1 foi esmagado(a) por uma bigorna em queda +@1 was squashed by a falling anvil whilst fighting @2=@1 foi esmagado(a) por uma bigorna enquanto lutava contra @2 +@1 was squashed by a falling block=@1 foi esmagado(a) por um bloco em queda +@1 was squashed by a falling block whilst fighting @2=@1 foi esmagado(a) por um bloco em queda enquanto lutava contra @2 +@1 was slain by @2=@1 foi assassinado por @2 +@1 was slain by @2 using @3=@1 foi assassinado por @2 usando @3 +@1 was shot by @2=@1 foi acertado(a) por @2 +@1 was shot by @2 using @3=@1 foi acertado(a) por @2 usando @3 +@1 was fireballed by @2=@1 foi atingido(a) por uma bola de fogo de @2 +@1 was fireballed by @2 using @3=@1 foi atingido(a) por uma bola de fogo de @2 usando @3 +@1 was killed trying to hurt @2=@1 foi morto(a) tentando machucar @2 +@1 tried to hurt @2 and died by @3=@1 tentou machucar @2 e morreu por conta de @3 +@1 blew up=@1 explodiu +@1 was blown up by @2=@1 foi explodido por @2 +@1 was blown up by @2 using @3=@1 foi explodido por @2 usando @3 +@1 was squished too much=@1 foi esmagado(a) demais +@1 was squashed by @2=@1 foi esmagado(a) por @2 +@1 went off with a bang=@1 saiu com um estrondo +@1 went off with a bang due to a firework fired by @2 from @3=@1 saiu com um estrondo por conta de um fogo de artifício disparado por @2 vindo de @3 diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr index 816546e5e..23c90fc05 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ru.tr @@ -1,61 +1,55 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.=@1 застрелил лучник. -@1 has been killed with an arrow.=@1 убило стрелой из лука. -@1 was shot by an arrow from @2.=@1 убило стрелой @2. -@1 was shot by an arrow from a skeleton.=@1 был(а) убит(а) стрелой скелета. -@1 was shot by an arrow from a stray.=@1 был(а) убит(а) стрелой странника. -@1 was shot by an arrow from an illusioner.=@1 был(а) убит(а) стрелой иллюзора. -@1 was shot by an arrow.=@1 был(а) убит(а) стрелой. -@1 forgot to breathe.=@1 забыл(а) подышать. -@1 drowned.=@1 утонул(а). -@1 ran out of oxygen.=У @1 закончился кислород. -@1 was killed by @2.=@1 был(а) убит(а) @2. -@1 was killed.=@1 был(а) убит(а). -@1 was killed by a mob.=@1 был(а) убит(а) мобом. -@1 was burned to death by a blaze's fireball.=@1 до смерти прожарило файерболом ифрита. -@1 was killed by a fireball from a blaze.=@1 был(а) убит(а) файерболом ифрита. -@1 was burned by a fire charge.=@1 сожгло огненным разрядом. -A ghast scared @1 to death.=Гаст напугал @1 до смерти. -@1 has been fireballed by a ghast.=@1 настиг файербол Гаста. -@1 fell from a high cliff.=@1 свалился(ась) с высокого утёса. -@1 took fatal fall damage.=@1 получил(а) смертельный урон от падения. -@1 fell victim to gravity.=@1 стал(а) жертвой гравитации. -@1 died.=@1 умер(ла). -@1 was slain by @2.= -@1 tried to hurt @2 and died by @3=@1 пытался навредить @2 и умер от @3 -@1 went off with a bang due to a firework fired by @2 from @3=@1 взорвался из-за фейерверка, запущенного @2 из @3 -@1 was killed by a zombie.=@1 был(а) убит(а) зомби. -@1 was killed by a baby zombie.=@1 был(а) убит(а) малышом-зомби. -@1 was killed by a blaze.=@1 был(а) убит(а) ифритом. -@1 was killed by a slime.=@1 был(а) убит(а) слизняком. -@1 was killed by a witch.=@1 был(а) убит(а) ведьмой. -@1 was killed by a magma cube.=@1 был(а) убит(а) лавовым кубом. -@1 was killed by a wolf.=@1 был(а) убит(а) волком. -@1 was killed by a cat.=@1 был(а) убит(а) кошкой. -@1 was killed by an ocelot.=@1 был(а) убит(а) оцелотом. -@1 was killed by an ender dragon.=@1 был(а) убит(а) драконом предела. -@1 was killed by a wither.=@1 был(а) убит(а) иссушителем. -@1 was killed by an enderman.=@1 был(а) убит(а) эндерменом. -@1 was killed by an endermite.=@1 был(а) убит(а) эндермитом. -@1 was killed by a ghast.=@1 был(а) убит(а) гастом. -@1 was killed by an elder guardian.=@1 был(а) убит(а) древним стражем. -@1 was killed by a guardian.=@1 был(а) убит(а) стражем. -@1 was killed by an iron golem.=@1 был(а) убит(а) железным големом. -@1 was killed by a polar_bear.=@1 был(а) убит(а) полярным медведем. -@1 was killed by a killer bunny.=@1 был(а) убит(а) кроликом-убийцей. -@1 was killed by a shulker.=@1 был(а) убит(а) шалкером. -@1 was killed by a silverfish.=@1 был(а) убит(а) чешуйницей. -@1 was killed by a skeleton.=@1 был(а) убит(а) скелетом. -@1 was killed by a stray.=@1 был(а) убит(а) странником. -@1 was killed by a slime.=@1 был(а) убит(а) слизняком. -@1 was killed by a spider.=@1 был(а) убит(а) пауком. -@1 was killed by a cave spider.=@1 был(а) убит(а) пещерным пауком. -@1 was killed by a vex.=@1 был(а) убит(а) досаждателем. -@1 was killed by an evoker.=@1 был(а) убит(а) магом. -@1 was killed by an illusioner.=@1 был(а) убит(а) иллюзором. -@1 was killed by a vindicator.=@1 был(а) убит(а) поборником. -@1 was killed by a zombie villager.=@1 был(а) убит(а) зомби-жителем. -@1 was killed by a husk.=@1 был(а) убит(а) кадавром. -@1 was killed by a baby husk.=@1 был(а) убит(а) машылом-кадавром. -@1 was killed by a zombie piglin.=@1 был(а) убит(а) зомби-свиночеловеком. -@1 was killed by a baby zombie piglin.=@1 был(а) убит(а) малышом-зомби-свиночеловеком. +@1 went up in flames=@1 сгорел(а) в языках пламени +@1 walked into fire whilst fighting @2=@1 прошёлся(лась) по огню, сражаясь с @2 +@1 was struck by lightning=@1 был(а) убит(а) молнией +@1 was struck by lightning whilst fighting @2=@1 был(а) убит(а) молнией, сражаясь с @2 +@1 burned to death=@1 сгорел(а) заживо +@1 was burnt to a crisp whilst fighting @2=@1 обгорел(а) до углей, сражаясь с @2 +@1 tried to swim in lava=@1 попытался(ась) поплавать в лаве +@1 tried to swim in lava to escape @2=@1 попытался(ась) переплыть лаву, убегая от @2 +@1 discovered the floor was lava=@1 узнал(а) что пол это лава +@1 walked into danger zone due to @2=@1 прогулялся(лась) в опасной зоне, благодаря @2 +@1 suffocated in a wall=@1 задохнулся(ась) в стене +@1 suffocated in a wall whilst fighting @2=@1 задохнулся(ась) в стене, сражаясь с @2 +@1 drowned=@1 утонул(а) +@1 drowned whilst trying to escape @2=@1 утонул(а), убегая от @2 +@1 starved to death=@1 умер(ла) от голода +@1 starved to death whilst fighting @2=@1 умер(ла) от голода, сражаясь с @2 +@1 was pricked to death=@1 был(а) заколот(а) до смерти +@1 walked into a cactus whilst trying to escape @2=@1 задел(а) кактус, убегая от @2 +@1 hit the ground too hard=@1 слишком сильно ударился(ась) об землю +@1 hit the ground too hard whilst trying to escape @2=@1 слишком сильно ударился(ась) об землю, убегая от @2 +@1 experienced kinetic energy=@1 испытал(а) на себе кинетическую энергию +@1 experienced kinetic energy whilst trying to escape @2=@1 испытал(а) на себе кинетическую энергию, убегая от @2 +@1 fell out of the world=@1 выпал(а) из мира +@1 didn't want to live in the same world as @2=@1 не захотел(а) жить в том же мире, что и @2 +@1 died=@1 погиб(ла) +@1 died because of @2=@1 погиб(ла) из-за @2 +@1 was killed by magic=@1 был(а) убит(а) магией +@1 was killed by magic whilst trying to escape @2=@1 был(а) убит(а) магией, убегая от @2 +@1 was killed by @2 using magic=@1 был(а) убит(а) @2 с помощью магии +@1 was killed by @2 using @3=@1 был(а) убит(а) @2 с помощью @3 +@1 was roasted in dragon breath=@1 поджарился(ась) в драконьем дыхании +@1 was roasted in dragon breath by @2=@1 поджарился(ась) в драконьем дыхании, благодаря @2 +@1 withered away=@1 иссох(ла) +@1 withered away whilst fighting @2=@1 иссох(ла), сражаясь с @2 +@1 was shot by a skull from @2=@1 был(а) застрелен(а) @2 +@1 was squashed by a falling anvil=@1 раздавлен(а) падающей наковальней +@1 was squashed by a falling anvil whilst fighting @2=@1 раздавлен(а) падающей наковальней, сражаясь с @2 +@1 was squashed by a falling block=@1 раздавлен(а) падающим блоком +@1 was squashed by a falling block whilst fighting @2=@1 раздавлен(а) падающим блоком, сражаясь с @2 +@1 was slain by @2=@1 погиб(ла) от @2 +@1 was slain by @2 using @3=@2 убил(а) @1 с помощью своего @3 +@1 was shot by @2=@1 был(а) застрелен @2 +@1 was shot by @2 using @3=@2 застрелил(а) @1 с помощью своего @3 +@1 was fireballed by @2=@1 получил(а) огненным снарядом от @2 +@1 was fireballed by @2 using @3=@1 получил(а) огненным снарядом от @2 из @3 +@1 was killed trying to hurt @2=@1 погиб(ла), пытаясь навредить @2 +@1 tried to hurt @2 and died by @3=@1 убит(а) @3, пытаясь навредить @2 +@1 blew up=@1 взорвался(ась) +@1 was blown up by @2=@1 был(а) взорван(а) @2 +@1 was blown up by @2 using @3=@1 был(а) взорван(а) @2 с помощью @3 +@1 was squished too much=@1 был(а) сдавлен(а) в лепёшку +@1 was squashed by @2=@1 был(а) сдавлен(а) в лепёшку, благодаря @2 +@1 went off with a bang=@1 попал(а) в мир иной под звуки салюта +@1 went off with a bang due to a firework fired by @2 from @3=@1 попал(а) в мир иной под звуки салюта, выпущенного из @3 игроком @2 \ No newline at end of file diff --git a/mods/HUD/mcl_experience/README.md b/mods/HUD/mcl_experience/README.md index f59eab20f..8e37f9b6b 100644 --- a/mods/HUD/mcl_experience/README.md +++ b/mods/HUD/mcl_experience/README.md @@ -1,6 +1,6 @@ -- eXPerience mod -- This mod has adopted from oil_boi's Crafter-minetest -- ( https://www.patreon.com/oil_boi ) by kay27@bk.ru --- for MineClone 2 under GNU General Public License v3.0. +-- for VoxeLibre under GNU General Public License v3.0. -- Copyright (c) Oil_boi, Wuzzy, kay27, -- experience_orb texture by github.com/Gerold55 diff --git a/mods/HUD/mcl_experience/bottle.lua b/mods/HUD/mcl_experience/bottle.lua index 62a3fb9ca..50f96656f 100644 --- a/mods/HUD/mcl_experience/bottle.lua +++ b/mods/HUD/mcl_experience/bottle.lua @@ -14,7 +14,7 @@ minetest.register_entity("mcl_experience:bottle",{ local n = node.name if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_item_group(n, "liquid") == 0 then minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) - mcl_experience.throw_xp(pos, math.random(3, 11)) + mcl_experience.throw_xp(pos, math.random(3, 11) + (self._luck or 0)) minetest.add_particlespawner({ amount = 50, time = 0.1, @@ -40,13 +40,18 @@ minetest.register_entity("mcl_experience:bottle",{ end, }) -local function throw_xp_bottle(pos, dir, velocity) +local function throw_xp_bottle(pos, dir, velocity, user) minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) local obj = minetest.add_entity(pos, "mcl_experience:bottle") obj:set_velocity(vector.multiply(dir, velocity)) local acceleration = vector.multiply(dir, -3) acceleration.y = -9.81 obj:set_acceleration(acceleration) + if user then + local ent = obj:get_luaentity() + local luck = mcl_luck.get_luck(user:get_player_name()) + ent._luck = luck + end end minetest.register_craftitem("mcl_experience:bottle", { @@ -55,7 +60,7 @@ minetest.register_craftitem("mcl_experience:bottle", { wield_image = "mcl_experience_bottle.png", stack_max = 64, on_use = function(itemstack, placer, pointed_thing) - throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10) + throw_xp_bottle(vector.add(placer:get_pos(), vector.new(0, 1.5, 0)), placer:get_look_dir(), 10, placer) if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() end diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index 359e68918..47e48d36c 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -147,13 +147,13 @@ function mcl_experience.throw_xp(pos, total_xp) obj:set_velocity(vector.new( math.random(-2, 2) * math.random(), - math.random( 2, 5), + math.random(2, 5), math.random(-2, 2) * math.random() )) i = i + xp j = j + 1 - table.insert(obs,obj) + table.insert(obs, obj) end return obs end @@ -179,18 +179,18 @@ function mcl_experience.setup_hud(player) if not minetest.is_creative_enabled(player:get_player_name()) then hud_bars[player] = player:hud_add({ hud_elem_type = "image", - position = {x = 0.5, y = 1}, - offset = {x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5)}, - scale = {x = 0.35, y = 0.375}, - alignment = {x = 1, y = 1}, + position = { x = 0.5, y = 1 }, + offset = { x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5) }, + scale = { x = 0.35, y = 0.375 }, + alignment = { x = 1, y = 1 }, z_index = 11, }) hud_levels[player] = player:hud_add({ hud_elem_type = "text", - position = {x = 0.5, y = 1}, + position = { x = 0.5, y = 1 }, number = 0x80FF20, - offset = {x = 0, y = -(48 + 24 + 24)}, + offset = { x = 0, y = -(48 + 24 + 24) }, z_index = 12, }) end @@ -221,7 +221,7 @@ function mcl_experience.update(player) end function mcl_experience.register_on_add_xp(func, priority) - table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0}) + table.insert(mcl_experience.on_add_xp, { func = func, priority = priority or 0 }) end -- callbacks @@ -232,9 +232,9 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_leaveplayer(function(player) - hud_bars[player] = nil - hud_levels[player] = nil - caches[player] = nil + hud_bars[player] = nil + hud_levels[player] = nil + caches[player] = nil end) minetest.register_on_dieplayer(function(player) @@ -247,3 +247,12 @@ end) minetest.register_on_mods_loaded(function() table.sort(mcl_experience.on_add_xp, function(a, b) return a.priority < b.priority end) end) + +mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode) + if new_gamemode == "survival" then + mcl_experience.setup_hud(player) + mcl_experience.update(player) + elseif new_gamemode == "creative" then + mcl_experience.remove_hud(player) + end +end) diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.pt_BR.tr b/mods/HUD/mcl_experience/locale/mcl_experience.pt_BR.tr new file mode 100644 index 000000000..0a7cef5dd --- /dev/null +++ b/mods/HUD/mcl_experience/locale/mcl_experience.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_experience +[[] ]=[[] ] +Gives a player some XP=Dá algum XP a um jogador +Error: Too many parameters!=Erro: Muitos parâmetros +Error: Incorrect value of XP=Erro: Valor incorreto de XP +Error: Player not found=Erro: Jogador não encontrado +Added @1 XP to @2, total: @3, experience level: @4=Adicionado @1 XP para @2, total: @3, nível de experiência: @4 +Bottle o' Enchanting=Frasco de Experiência diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr b/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr index a87840aff..baacbc472 100644 --- a/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr +++ b/mods/HUD/mcl_experience/locale/mcl_experience.ru.tr @@ -2,6 +2,7 @@ [[] ]=[[<игрок>] ] Gives a player some XP=Даёт игроку XP Error: Too many parameters!=Ошибка: слишком много параметров! -Error: Incorrect value of XP=Ошибка: Недопустимое значение XP -Error: Player not found=Ошибка: Игрок не найден -Added @1 XP to @2, total: @3, experience level: @4=Добавляем @1 XP игроку @2, итого: @3, уровень опыта: @4 +Error: Incorrect value of XP=Ошибка: недопустимое значение XP +Error: Player not found=Ошибка: игрок не найден +Added @1 XP to @2, total: @3, experience level: @4=Добавлено @1 XP игроку @2, итого: @3, уровень опыта: @4 +Bottle o' Enchanting=Пузырёк опыта \ No newline at end of file diff --git a/mods/HUD/mcl_experience/mod.conf b/mods/HUD/mcl_experience/mod.conf index 211249b30..1e0c09c31 100644 --- a/mods/HUD/mcl_experience/mod.conf +++ b/mods/HUD/mcl_experience/mod.conf @@ -1,3 +1,4 @@ name = mcl_experience author = oilboi description = eXPerience mod +depends = mcl_gamemode, mcl_luck diff --git a/mods/HUD/mcl_experience/orb.lua b/mods/HUD/mcl_experience/orb.lua index 9aecce00d..9d426a1d7 100644 --- a/mods/HUD/mcl_experience/orb.lua +++ b/mods/HUD/mcl_experience/orb.lua @@ -155,7 +155,7 @@ minetest.register_entity("mcl_experience:orb", { collisionbox = {-0.2, -0.2, -0.2, 0.2, 0.2, 0.2}, visual = "sprite", visual_size = {x = 0.4, y = 0.4}, - textures = {name="mcl_experience_orb.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}, + textures = {"mcl_experience_orb.png"}, spritediv = {x = 1, y = 14}, initial_sprite_basepos = {x = 0, y = 0}, is_visible = true, @@ -177,7 +177,6 @@ minetest.register_entity("mcl_experience:orb", { delete_timer = 0, radius = 4, - on_activate = function(self, staticdata, dtime_s) self.object:set_velocity(vector.new( math.random(-2,2)*math.random(), @@ -187,10 +186,14 @@ minetest.register_entity("mcl_experience:orb", { self.object:set_armor_groups({immortal = 1}) self.object:set_velocity({x = 0, y = 2, z = 0}) self.object:set_acceleration(gravity) - local xp = tonumber(staticdata) + + -- Assign 0 xp in case the entity was persisted even though it should not have been (static_save = false) + -- This was a minetest bug for a while: https://github.com/minetest/minetest/issues/14420 + local xp = tonumber(staticdata) or 0 self._xp = xp - size = xp_to_size(xp) - self.object:set_properties({ + size = xp_to_size(xp) + + self.object:set_properties({ visual_size = {x = size, y = size}, glow = 14, }) diff --git a/mods/HUD/mcl_formspec/API.md b/mods/HUD/mcl_formspec/API.md new file mode 100644 index 000000000..61b328ec5 --- /dev/null +++ b/mods/HUD/mcl_formspec/API.md @@ -0,0 +1,40 @@ +# VoxeLibre Formspec API + +## `mcl_formspec.label_color` + +Contains the color used for formspec labels, currently `#313131`. + +## `mcl_formspec.get_itemslot_bg(x, y, w, h)` + +Get the background of inventory slots (formspec version = 1) + +ex: + +```lua +local formspec = table.concat({ + mcl_formspec.get_itemslot_bg(0, 0, 5, 2), + "list[current_player;super_inventory;0,0;5,2;]", +}) +``` + +## `mcl_formspec.get_itemslot_bg_v4(x, y, w, h, size, texture)` + +Get the background of inventory slots (formspec version > 1) + +Works basically the same as `mcl_formspec.get_itemslot_bg(x, y, w, h)` but have more customisation options: + +- `size`: allow you to customize the size of the slot borders, default is 0.05 +- `texture`: allow you to specify a custom texture tu use instead of the default one + +ex: + +```lua +local formspec = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 0.375, 5, 2, 0.1, "super_slot_background.png"), + "list[current_player;super_inventory;0.375,0.375;5,2;]", +}) +``` + +## `mcl_formspec.itemslot_border_size` + +Contains the default item slot border size used by `mcl_formspec.get_itemslot_bg_v4`, currently 0.05 diff --git a/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md b/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md new file mode 100644 index 000000000..0721d3cce --- /dev/null +++ b/mods/HUD/mcl_formspec/FORMSPEC_GUIDE.md @@ -0,0 +1,21 @@ +# VoxeLibre Formspec Guide + +**_This guide will teach you the rules for creating formspecs for the VoxeLibre game._** + +Formspecs are an important part of game and mod development. + +First of all, VoxeLibre aims to support ONLY last formspec version. Many utility functions will not work with formspec v1 or v2. + +The typical width of an 9 slots width inventory formspec is `0.375 + 9 + ((9-1) * 0.25) + 0.375 = 11.75` + +Margins are 0.375. + +The labels color is `mcl_formspec.label_color` + +Space between 1st inventory line and the rest of inventory is 0.45 + +Labels should have 0.375 space above if there is no other stuff above and 0.45 between content + +- 0.375 under + +According to minetest modding book, table.concat is faster than string concatenation, so this method should be prefered (the code is also more clear) diff --git a/mods/HUD/mcl_formspec/init.lua b/mods/HUD/mcl_formspec/init.lua index 7013fc0ee..d449e937f 100644 --- a/mods/HUD/mcl_formspec/init.lua +++ b/mods/HUD/mcl_formspec/init.lua @@ -1,10 +1,55 @@ mcl_formspec = {} +mcl_formspec.label_color = "#313131" + +---Get the background of inventory slots (formspec version = 1) +---@param x number +---@param y number +---@param w number +---@param h number +---@return string function mcl_formspec.get_itemslot_bg(x, y, w, h) local out = "" for i = 0, w - 1, 1 do for j = 0, h - 1, 1 do - out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]" + out = out .. "image[" .. x + i .. "," .. y + j .. ";1,1;mcl_formspec_itemslot.png]" + end + end + return out +end + +---This function will replace mcl_formspec.get_itemslot_bg then every formspec will be upgrade to version 4 +---@param x number +---@param y number +---@param size number +---@param texture? string +---@return string +---@nodiscard +local function get_slot(x, y, size, texture) + local t = "image[" .. x - size .. "," .. y - size .. ";" .. 1 + (size * 2) .. + "," .. 1 + (size * 2) .. ";" .. (texture and texture or "mcl_formspec_itemslot.png") .. "]" + return t +end + +mcl_formspec.itemslot_border_size = 0.05 + +---Get the background of inventory slots (formspec version > 1) +---@param x number +---@param y number +---@param w integer +---@param h integer +---@param size? number Optional size of the slot border (default: 0.05) +---@param texture? string Optional texture to replace the default one +---@return string +---@nodiscard +function mcl_formspec.get_itemslot_bg_v4(x, y, w, h, size, texture) + if not size then + size = mcl_formspec.itemslot_border_size + end + local out = "" + for i = 0, w - 1, 1 do + for j = 0, h - 1, 1 do + out = out .. get_slot(x + i + (i * 0.25), y + j + (j * 0.25), size, texture) end end return out diff --git a/mods/HUD/mcl_hbarmor/README.md b/mods/HUD/mcl_hbarmor/README.md index 0eccd6916..0b87002b5 100644 --- a/mods/HUD/mcl_hbarmor/README.md +++ b/mods/HUD/mcl_hbarmor/README.md @@ -1,4 +1,4 @@ -# MineClone 2 HUD bar for `mcl_armor` [`mcl_hbarmor`] +# VoxeLibre HUD bar for `mcl_armor` [`mcl_hbarmor`] ## Description This mod adds a simple HUD bar which displays the player's armor points. @@ -14,7 +14,7 @@ License: MIT License (see below) ### Textures -See MineClone 2 license. +See VoxeLibre license. ### MIT License Everything else is under the MIT License: diff --git a/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pt_BR.tr b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pt_BR.tr new file mode 100644 index 000000000..f9529b482 --- /dev/null +++ b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain:hbarmor +Armor=Armadura diff --git a/mods/HUD/mcl_info/locale/mcl_info.fr.tr b/mods/HUD/mcl_info/locale/mcl_info.fr.tr index 96fb2622e..19ff9553d 100644 --- a/mods/HUD/mcl_info/locale/mcl_info.fr.tr +++ b/mods/HUD/mcl_info/locale/mcl_info.fr.tr @@ -1,4 +1,4 @@ # textdomain: mcl_info -Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Régler le masque de bits pour débuguer : 0 @= pour désactiver, 1 @= nom du biome, 2 @= coordonnées, 3 @= tout= +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Régler le masque de bits pour débuguer : 0 @= pour désactiver, 1 @= nom du biome, 2 @= coordonnées, 3 @= tout Error! Possible values are integer numbers from @1 to @2=Erreur ! Les valeurs possibles sont des nombres entiers de @1 à @2 Debug bit mask set to @1=Masque de bits de débuguage réglé à @1 diff --git a/mods/HUD/mcl_info/locale/mcl_info.pt_BR.tr b/mods/HUD/mcl_info/locale/mcl_info.pt_BR.tr new file mode 100644 index 000000000..89ea171e0 --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Defina a máscara de bits de debug: 0 @= desabilitado, 1 @= nome do bioma, 2 @= coordenadas, 3 @= todos +Error! Possible values are integer numbers from @1 to @2=Erro! Valores possíveis são números inteiros de @1 até @2 +Debug bit mask set to @1=Máscara de bits de debug definida como @1 diff --git a/mods/HUD/mcl_inventory/API.md b/mods/HUD/mcl_inventory/API.md new file mode 100644 index 000000000..5fc5a8d6e --- /dev/null +++ b/mods/HUD/mcl_inventory/API.md @@ -0,0 +1,35 @@ +# `mcl_inventory` + +## `mcl_inventory.register_survival_inventory_tab(def)` + +```lua +mcl_inventory.register_survival_inventory_tab({ + -- Page identifier + -- Used to uniquely identify the tab + id = "test", + + -- The tab description, can be translated + description = "Test", + + -- The name of the item that will be used as icon + item_icon = "mcl_core:stone", + + -- If true, the main inventory will be shown at the bottom of the tab + -- Listrings need to be added by hand + show_inventory = true, + + -- This function must return the tab's formspec for the player + build = function(player) + return "label[1,1;Hello hello]button[2,2;2,2;Hello;hey]" + end, + + -- This function will be called in the on_player_receive_fields callback if the tab is currently open + handle = function(player, fields) + print(dump(fields)) + end, + + -- This function will be called to know if a player can see the tab + -- Returns true by default + access = function(player) + end, +``` diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 32bb226f0..4ddbd0823 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -3,19 +3,35 @@ local F = minetest.formspec_escape local C = minetest.colorize -- Prepare player info table +---@type table local players = {} -- Containing all the items for each Creative Mode tab +---@type table local inventory_lists = {} ---local mod_player = minetest.get_modpath("mcl_player") - -- Create tables -local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} +---@type string[] +local builtin_filter_ids = { + "blocks", + "deco", + "redstone", + "rail", + "food", + "tools", + "combat", + "mobs", + "brew", + "matr", + "misc", + "all" +} + for _, f in pairs(builtin_filter_ids) do inventory_lists[f] = {} end +---@param tbl string[] local function replace_enchanted_books(tbl) for k, item in ipairs(tbl) do if item:find("mcl_enchanting:book_enchanted") == 1 then @@ -28,20 +44,32 @@ local function replace_enchanted_books(tbl) end end ---[[ Populate all the item tables. We only do this once. Note this code must be -executed after loading all the other mods in order to work. ]] +-- Populate all the item tables. We only do this once. +-- Note this code must be executed after loading all the other mods in order to work. minetest.register_on_mods_loaded(function() - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and + def.description ~= "" then + ---@param def mt.ItemDef|mt.NodeDef local function is_redstone(def) - return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off + return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or + def.groups.mesecon_effecor_off end + + ---@param def mt.ItemDef|mt.NodeDef local function is_tool(def) return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil) end + + ---@param def mt.ItemDef|mt.NodeDef local function is_weapon_or_armor(def) - return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or ((def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) + return def.groups.weapon or def.groups.weapon_ranged or def.groups.ammo or def.groups.combat_item or + ( + ( + def.groups.armor_head or def.groups.armor_torso or def.groups.armor_legs or def.groups.armor_feet or + def.groups.horse_armor) and def.groups.non_combat_armor ~= 1) end + -- Is set to true if it was added in any category besides misc local nonmisc = false if def.groups.building_block then @@ -77,7 +105,8 @@ minetest.register_on_mods_loaded(function() nonmisc = true end if def.groups.brewitem then - table.insert(inventory_lists["brew"], name) + local str = name + table.insert(inventory_lists["brew"], str) nonmisc = true end if def.groups.craftitem then @@ -89,10 +118,36 @@ minetest.register_on_mods_loaded(function() table.insert(inventory_lists["misc"], name) end + if def.groups._mcl_potion == 1 then + if def.has_potent then + local stack = ItemStack(name) + local potency = def._default_potent_level - 1 + stack:get_meta():set_int("mcl_potions:potion_potent", potency) + table.insert(inventory_lists["brew"], stack:to_string()) + end + if def.has_plus then + local stack = ItemStack(name) + local extend = def._default_extend_level + stack:get_meta():set_int("mcl_potions:potion_plus", extend) + table.insert(inventory_lists["brew"], stack:to_string()) + end + end + table.insert(inventory_lists["all"], name) end end + -- Itemstack descriptions need to be reloaded separately, because tt invalidates minetest.registered_items iterators, somehow + -- (and pairs() uses said iterators internally) + -- TODO investigate the iterator invalidation, where does it happen? + for name, list in pairs(inventory_lists) do + for i=1, #list do + local stack = ItemStack(list[i]) + tt.reload_itemstack_description(stack) + list[i] = stack:to_string() + end + end + for ench, def in pairs(mcl_enchanting.enchantments) do local str = "mcl_enchanting:book_enchanted " .. ench .. " " .. def.max_level if def.inv_tool_tab then @@ -110,6 +165,11 @@ minetest.register_on_mods_loaded(function() end end) +---@param name string +---@param description string +---@param lang mt.LangCode +---@param filter string +---@return integer local function filter_item(name, description, lang, filter) local desc if not lang then @@ -120,13 +180,16 @@ local function filter_item(name, description, lang, filter) return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true) end +---@param filter string +---@param player mt.PlayerObjectRef local function set_inv_search(filter, player) local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) local creative_list = {} local lang = minetest.get_player_information(playername).lang_code - for name,def in pairs(minetest.registered_items) do - if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then + for name, def in pairs(minetest.registered_items) do + if (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and + def.description ~= "" then if filter_item(string.lower(def.name), def.description, lang, filter) then table.insert(creative_list, name) end @@ -147,9 +210,11 @@ local function set_inv_search(filter, player) inv:set_list("main", creative_list) end +---@param page string +---@param player mt.PlayerObjectRef local function set_inv_page(page, player) local playername = player:get_player_name() - local inv = minetest.get_inventory({type="detached", name="creative_"..playername}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) inv:set_size("main", 0) local creative_list = {} if inventory_lists[page] then -- Standard filter @@ -160,11 +225,14 @@ local function set_inv_page(page, player) inv:set_list("main", creative_list) end + +---@param player mt.PlayerObjectRef local function init(player) local playername = player:get_player_name() - minetest.create_detached_inventory("creative_"..playername, { + minetest.create_detached_inventory("creative_" .. playername, { allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - if minetest.is_creative_enabled(playername) then + if minetest.is_creative_enabled(playername) and + from_list ~= to_list then return count else return 0 @@ -197,24 +265,45 @@ local trash = minetest.create_detached_inventory("trash", { inv:set_stack(listname, index, "") end, }) + trash:set_size("main", 1) -local noffset = {} -- numeric tab offset -local offset = {} -- string offset: -local boffset = {} -- -local hoch = {} -local filtername = {} ---local bg = {} +------------------------------ +-- Formspec Precalculations -- +------------------------------ -local noffset_x_start = -0.24 +-- Numeric position of tab background image, indexed by tab name +---@type table +local noffset = {} + +-- String position of tab button background image, indexed by tab name +---@type table +local offset = {} + +-- String position of tab button, indexed by tab name +---@type table +local boffset = {} + +-- Used to determine the tab button background image +---@type table +local button_bg_postfix = {} + +-- Tab caption/tooltip translated string, indexed by tab name +---@type table +local filtername = {} + +local noffset_x_start = 0.2 local noffset_x = noffset_x_start -local noffset_y = -0.25 +local noffset_y = -1.34 + +---@param id string +---@param right? boolean local function next_noffset(id, right) if right then - noffset[id] = { 8.94, noffset_y } + noffset[id] = { 11.3, noffset_y } else noffset[id] = { noffset_x, noffset_y } - noffset_x = noffset_x + 1.25 + noffset_x = noffset_x + 1.6 end end @@ -228,7 +317,7 @@ next_noffset("misc") next_noffset("nix", true) noffset_x = noffset_x_start -noffset_y = 8.12 +noffset_y = 8.64 -- Lower row next_noffset("food") @@ -238,25 +327,25 @@ next_noffset("mobs") next_noffset("matr") next_noffset("inv", true) -for k,v in pairs(noffset) do +for k, v in pairs(noffset) do offset[k] = tostring(v[1]) .. "," .. tostring(v[2]) - boffset[k] = tostring(v[1]+0.19) .. "," .. tostring(v[2]+0.25) + boffset[k] = tostring(v[1] + 0.24) .. "," .. tostring(v[2] + 0.25) end -hoch["blocks"] = "" -hoch["deco"] = "" -hoch["redstone"] = "" -hoch["rail"] = "" -hoch["brew"] = "" -hoch["misc"] = "" -hoch["nix"] = "" -hoch["default"] = "" -hoch["food"] = "_down" -hoch["tools"] = "_down" -hoch["combat"] = "_down" -hoch["mobs"] = "_down" -hoch["matr"] = "_down" -hoch["inv"] = "_down" +button_bg_postfix["blocks"] = "" +button_bg_postfix["deco"] = "" +button_bg_postfix["redstone"] = "" +button_bg_postfix["rail"] = "" +button_bg_postfix["brew"] = "" +button_bg_postfix["misc"] = "" +button_bg_postfix["nix"] = "" +button_bg_postfix["default"] = "" +button_bg_postfix["food"] = "_down" +button_bg_postfix["tools"] = "_down" +button_bg_postfix["combat"] = "_down" +button_bg_postfix["mobs"] = "_down" +button_bg_postfix["matr"] = "_down" +button_bg_postfix["inv"] = "_down" filtername["blocks"] = S("Building Blocks") filtername["deco"] = S("Decoration Blocks") @@ -291,157 +380,223 @@ filtername["inv"] = S("Survival Inventory") bg["default"] = dark_bg end]] +-- Item name representing a tab, indexed by tab name +---@type table +local tab_icon = { + blocks = "mcl_core:brick_block", + deco = "mcl_flowers:peony", + redstone = "mesecons:redstone", + rail = "mcl_minecarts:golden_rail", + misc = "mcl_buckets:bucket_lava", + nix = "mcl_compass:compass", + food = "mcl_core:apple", + tools = "mcl_core:axe_iron", + combat = "mcl_core:sword_gold", + mobs = "mobs_mc:cow", + brew = "mcl_potions:dragon_breath", + matr = "mcl_core:stick", + inv = "mcl_chests:chest", +} + +-- 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_inventory: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_inventory:switch_stack", n) end -minetest.register_on_joinplayer(function (player) +minetest.register_on_joinplayer(function(player) if get_stack_size(player) == 0 then set_stack_size(player, 64) end end) +---@param player mt.PlayerObjectRef function mcl_inventory.set_creative_formspec(player) local playername = player:get_player_name() if not players[playername] then return end local start_i = players[playername].start_i - local pagenum = start_i / (9*5) + 1 - local name = players[playername].page + local pagenum = start_i / (9 * 5) + 1 + local page = players[playername].page local inv_size = players[playername].inv_size local filter = players[playername].filter - local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) + + if not inv_size then + if page == "nix" then + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. playername }) + inv_size = inv:get_size("main") + elseif page and page ~= "inv" then + inv_size = #(inventory_lists[page]) + else + inv_size = 0 + end + end + local pagemax = math.max(1, math.floor((inv_size - 1) / (9 * 5) + 1)) + local name = "nix" local main_list - local listrings = "listring[detached:creative_"..playername..";main]".. - "listring[current_player;main]".. - "listring[detached:trash;main]" + local listrings = table.concat({ + "listring[detached:creative_" .. playername .. ";main]", + "listring[current_player;main]", + "listring[detached:trash;main]", + }) + + if page then + name = page + if players[playername] then + players[playername].page = page + end + end - local inv_bg = "crafting_inventory_creative.png" if name == "inv" then - inv_bg = "crafting_inventory_creative_survival.png" - -- Background images for armor slots (hide if occupied) local armor_slot_imgs = "" local inv = player:get_inventory() if inv:get_stack("armor", 2):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,1.3;1,1;mcl_inventory_empty_armor_slot_helmet.png]" + armor_slot_imgs = armor_slot_imgs .. "image[3.5,0.375;1,1;mcl_inventory_empty_armor_slot_helmet.png]" end if inv:get_stack("armor", 3):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[2.5,2.75;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" + armor_slot_imgs = armor_slot_imgs .. "image[3.5,2.125;1,1;mcl_inventory_empty_armor_slot_chestplate.png]" end if inv:get_stack("armor", 4):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,1.3;1,1;mcl_inventory_empty_armor_slot_leggings.png]" + armor_slot_imgs = armor_slot_imgs .. "image[7.25,0.375;1,1;mcl_inventory_empty_armor_slot_leggings.png]" end if inv:get_stack("armor", 5):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[5.5,2.75;1,1;mcl_inventory_empty_armor_slot_boots.png]" + armor_slot_imgs = armor_slot_imgs .. "image[7.25,2.125;1,1;mcl_inventory_empty_armor_slot_boots.png]" end if inv:get_stack("offhand", 1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[1.5,2.025;1,1;mcl_inventory_empty_armor_slot_shield.png]" + armor_slot_imgs = armor_slot_imgs .. "image[2.25,1.25;1,1;mcl_inventory_empty_armor_slot_shield.png]" end local stack_size = get_stack_size(player) -- Survival inventory slots - main_list = "list[current_player;main;0,3.75;9,3;9]" .. - mcl_formspec.get_itemslot_bg(0, 3.75, 9, 3) .. - + main_list = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 3.375, 9, 3), + "list[current_player;main;0.375,3.375;9,3;9]", + -- Armor - "list[current_player;armor;2.5,1.3;1,1;1]" .. - "list[current_player;armor;2.5,2.75;1,1;2]" .. - "list[current_player;armor;5.5,1.3;1,1;3]" .. - "list[current_player;armor;5.5,2.75;1,1;4]" .. - mcl_formspec.get_itemslot_bg(2.5, 1.3, 1, 1) .. - mcl_formspec.get_itemslot_bg(2.5, 2.75, 1, 1) .. - mcl_formspec.get_itemslot_bg(5.5, 1.3, 1, 1) .. - mcl_formspec.get_itemslot_bg(5.5, 2.75, 1, 1) .. - "list[current_player;offhand;1.5,2.025;1,1]" .. - mcl_formspec.get_itemslot_bg(1.5, 2.025, 1, 1) .. - armor_slot_imgs .. - + mcl_formspec.get_itemslot_bg_v4(3.5, 0.375, 1, 1), + mcl_formspec.get_itemslot_bg_v4(3.5, 2.125, 1, 1), + mcl_formspec.get_itemslot_bg_v4(7.25, 0.375, 1, 1), + mcl_formspec.get_itemslot_bg_v4(7.25, 2.125, 1, 1), + "list[current_player;armor;3.5,0.375;1,1;1]", + "list[current_player;armor;3.5,2.125;1,1;2]", + "list[current_player;armor;7.25,0.375;1,1;3]", + "list[current_player;armor;7.25,2.125;1,1;4]", + + -- Offhand + mcl_formspec.get_itemslot_bg_v4(2.25, 1.25, 1, 1), + "list[current_player;offhand;2.25,1.25;1,1]", + + armor_slot_imgs, + -- Player preview - mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") .. - + "image[4.75,0.33;2.25,2.83;mcl_inventory_background9.png;2]", + mcl_player.get_player_formspec_model(player, 4.75, 0.45, 2.25, 2.75, ""), + -- Crafting guide button - "image_button[9,1;1,1;craftguide_book.png;__mcl_craftguide;]" .. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. - + "image_button[11.575,0.825;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", + -- Help button - "image_button[9,2;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. - "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" .. - - -- Achievements button - "image_button[9,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. - --"style_type[image_button;border=;bgimg=;bgimg_pressed=]" .. - "tooltip[__mcl_achievements;"..F(S("Advancements")) .. "]" .. - + "image_button[11.575,2.075;1.1,1.1;doc_button_icon_lores.png;__mcl_doc;]", + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]", + + -- Advancements button + "image_button[11.575,3.325;1.1,1.1;mcl_achievements_button.png;__mcl_achievements;]", + --"style_type[image_button;border=;bgimg=;bgimg_pressed=]", + "tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]", + -- Switch stack size button - "image_button[9,4;1,1;default_apple.png;__switch_stack;]" .. - "label[9.4,4.4;" .. F(C("#FFFFFF", stack_size ~= 1 and stack_size or "")) .. "]" .. - "tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]" - - -- Skins button - if minetest.global_exists("mcl_skins") then - main_list = main_list .. - "image_button[9,5;1,1;mcl_skins_button.png;__mcl_skins;]" .. - "tooltip[__mcl_skins;"..F(S("Select player skin")) .. "]" - end + "image_button[11.575,4.575;1.1,1.1;default_apple.png;__switch_stack;]", + "label[12.275,5.35;" .. F(C("#FFFFFF", tostring(stack_size ~= 1 and stack_size or ""))) .. "]", + "tooltip[__switch_stack;" .. F(S("Switch stack size")) .. "]", + + -- Skins button + "image_button[11.575,5.825;1.1,1.1;mcl_skins_button.png;__mcl_skins;]", + "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]", + }) -- For shortcuts listrings = listrings .. - "listring[detached:"..playername.."_armor;armor]".. + "listring[detached:" .. playername .. "_armor;armor]" .. "listring[current_player;main]" else + + --local nb_lines = math.ceil(inv_size / 9) -- Creative inventory slots - main_list = "list[detached:creative_"..playername..";main;0,1.75;9,5;"..tostring(start_i).."]".. - mcl_formspec.get_itemslot_bg(0,1.75,9,5).. - -- Page buttons - "label[9.0,5.5;"..F(S("@1/@2", pagenum, pagemax)).."]".. - "image_button[9.0,6.0;0.7,0.7;crafting_creative_prev.png;creative_prev;]".. - "image_button[9.5,6.0;0.7,0.7;crafting_creative_next.png;creative_next;]" + main_list = table.concat({ + mcl_formspec.get_itemslot_bg_v4(0.375, 0.875, 9, 5), + + -- Basic code to replace buttons by scrollbar + -- Require Minetest 5.8 + -- + --"scroll_container[0.375,0.875;11.575,6;scroll;vertical;1.25]", + --"list[detached:creative_" .. playername .. ";main;0,0;9," .. nb_lines .. ";]", + --"scroll_container_end[]", + --"scrollbaroptions[min=0;max=" .. math.max(nb_lines - 5, 0) .. ";smallstep=1;largesteps=1;arrows=hide]", + --"scrollbar[11.75,0.825;0.75,6.1;vertical;scroll;0]", + + "list[detached:creative_" .. playername .. ";main;0.375,0.875;9,5;" .. tostring(start_i) .. "]", + + -- Page buttons + "label[11.65,4.33;" .. F(S("@1 / @2", pagenum, pagemax)) .. "]", + "image_button[11.575,4.58;1.1,1.1;crafting_creative_prev.png^[transformR270;creative_prev;]", + "image_button[11.575,5.83;1.1,1.1;crafting_creative_next.png^[transformR270;creative_next;]", + }) end - local tab_icon = { - blocks = "mcl_core:brick_block", - deco = "mcl_flowers:peony", - redstone = "mesecons:redstone", - rail = "mcl_minecarts:golden_rail", - misc = "mcl_buckets:bucket_lava", - nix = "mcl_compass:compass", - food = "mcl_core:apple", - tools = "mcl_core:axe_iron", - combat = "mcl_core:sword_gold", - mobs = "mobs_mc:cow", - brew = "mcl_potions:dragon_breath", - matr = "mcl_core:stick", - inv = "mcl_chests:chest", - } + ---@param current_tab string + ---@param this_tab string + ---@return string local function tab(current_tab, this_tab) local bg_img if current_tab == this_tab then - bg_img = "crafting_creative_active"..hoch[this_tab]..".png" + bg_img = "crafting_creative_active" .. button_bg_postfix[this_tab] .. ".png" else - bg_img = "crafting_creative_inactive"..hoch[this_tab]..".png" + bg_img = "crafting_creative_inactive" .. button_bg_postfix[this_tab] .. ".png" end - return - "style["..this_tab..";border=false;bgimg=;bgimg_pressed=]".. - "item_image_button[" .. boffset[this_tab] ..";1,1;"..tab_icon[this_tab]..";"..this_tab..";]".. - "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]" - end - local caption = "" - if name ~= "inv" and filtername[name] then - caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" + return table.concat({ + "style[" .. this_tab .. ";border=false;bgimg=;bgimg_pressed=;noclip=true]", + "image[" .. offset[this_tab] .. ";1.5,1.44;" .. bg_img .. "]", + "item_image_button[" .. boffset[this_tab] .. ";1,1;" .. tab_icon[this_tab] .. ";" .. this_tab .. ";]", + }) end - local formspec = "size[10,9.3]".. - "no_prepend[]".. - mcl_vars.gui_nonbg..mcl_vars.gui_bg_color.. - "background[-0.19,-0.25;10.5,9.87;"..inv_bg.."]".. - "label[-5,-5;"..name.."]".. + local caption = "" + if name ~= "inv" and filtername[name] then + caption = "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, filtername[name])) .. "]" + end + + local formspec = table.concat({ + "formspec_version[6]", + "size[13,8.75]", + + "style_type[image;noclip=true]", + + -- Hotbar + mcl_formspec.get_itemslot_bg_v4(0.375, 7.375, 9, 1), + "list[current_player;main;0.375,7.375;9,1;]", + + -- Trash + mcl_formspec.get_itemslot_bg_v4(11.625, 7.375, 1, 1, nil, "crafting_creative_trash.png"), + "list[detached:trash;main;11.625,7.375;1,1;]", + + main_list, + + caption, + + listrings, + tab(name, "blocks") .. "tooltip[blocks;"..F(filtername["blocks"]).."]".. tab(name, "deco") .. @@ -454,10 +609,7 @@ function mcl_inventory.set_creative_formspec(player) "tooltip[misc;"..F(filtername["misc"]).."]".. tab(name, "nix") .. "tooltip[nix;"..F(filtername["nix"]).."]".. - caption.. - "list[current_player;main;0,7;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7,9,1).. - main_list.. + tab(name, "food") .. "tooltip[food;"..F(filtername["food"]).."]".. tab(name, "tools") .. @@ -471,17 +623,22 @@ function mcl_inventory.set_creative_formspec(player) tab(name, "matr") .. "tooltip[matr;"..F(filtername["matr"]).."]".. tab(name, "inv") .. - "tooltip[inv;"..F(filtername["inv"]).."]".. - "list[detached:trash;main;9,7;1,1;]".. - mcl_formspec.get_itemslot_bg(9,7,1,1).. - "image[9,7;1,1;crafting_creative_trash.png]".. - listrings + "tooltip[inv;"..F(filtername["inv"]).."]" + }) if name == "nix" then - formspec = formspec .. "field[5.3,1.34;4,0.75;search;;"..minetest.formspec_escape(filter).."]" - formspec = formspec .. "field_close_on_enter[search;false]" + if filter == nil then + filter = "" + end + + formspec = formspec .. table.concat({ + "field[5.325,0.15;6.1,0.6;search;;" .. minetest.formspec_escape(filter) .. "]", + "field_close_on_enter[search;false]", + "field_enter_after_edit[search;true]", + "set_focus[search;true]", + }) end - if pagenum then formspec = formspec .. "p"..tostring(pagenum) end + if pagenum then formspec = formspec .. "p" .. tostring(pagenum) end player:set_inventory_formspec(formspec) end @@ -500,50 +657,50 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.blocks then if players[name].page == "blocks" then return end - set_inv_page("blocks",player) + set_inv_page("blocks", player) page = "blocks" elseif fields.deco then if players[name].page == "deco" then return end - set_inv_page("deco",player) + set_inv_page("deco", player) page = "deco" elseif fields.redstone then if players[name].page == "redstone" then return end - set_inv_page("redstone",player) + set_inv_page("redstone", player) page = "redstone" elseif fields.rail then if players[name].page == "rail" then return end - set_inv_page("rail",player) + set_inv_page("rail", player) page = "rail" elseif fields.misc then if players[name].page == "misc" then return end - set_inv_page("misc",player) + set_inv_page("misc", player) page = "misc" elseif fields.nix then - set_inv_page("all",player) + set_inv_page("all", player) page = "nix" elseif fields.food then if players[name].page == "food" then return end - set_inv_page("food",player) + set_inv_page("food", player) page = "food" elseif fields.tools then if players[name].page == "tools" then return end - set_inv_page("tools",player) + set_inv_page("tools", player) page = "tools" elseif fields.combat then if players[name].page == "combat" then return end - set_inv_page("combat",player) + set_inv_page("combat", player) page = "combat" elseif fields.mobs then if players[name].page == "mobs" then return end - set_inv_page("mobs",player) + set_inv_page("mobs", player) page = "mobs" elseif fields.brew then if players[name].page == "brew" then return end - set_inv_page("brew",player) + set_inv_page("brew", player) page = "brew" elseif fields.matr then if players[name].page == "matr" then return end - set_inv_page("matr",player) + set_inv_page("matr", player) page = "matr" elseif fields.inv then if players[name].page == "inv" then return end @@ -552,7 +709,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) set_inv_page("all", player) page = "nix" elseif fields.search and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.search),player) + set_inv_search(string.lower(fields.search), player) page = "nix" elseif fields.__switch_stack then local switch = 1 @@ -570,20 +727,20 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local start_i = players[name].start_i if fields.creative_prev then - start_i = start_i - 9*5 + start_i = start_i - 9 * 5 elseif fields.creative_next then - start_i = start_i + 9*5 + start_i = start_i + 9 * 5 else -- Reset scroll bar if not scrolled start_i = 0 end if start_i < 0 then - start_i = start_i + 9*5 + start_i = start_i + 9 * 5 end local inv_size if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) + local inv = minetest.get_inventory({ type = "detached", name = "creative_" .. name }) inv_size = inv:get_size("main") elseif page and page ~= "inv" then inv_size = #(inventory_lists[page]) @@ -593,7 +750,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) players[name].inv_size = inv_size if start_i >= inv_size then - start_i = start_i - 9*5 + start_i = start_i - 9 * 5 end if start_i < 0 or start_i >= inv_size then start_i = 0 @@ -609,11 +766,36 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_inventory.set_creative_formspec(player) end) - minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) return placer and placer:is_player() and minetest.is_creative_enabled(placer:get_player_name()) end) +if minetest.is_creative_enabled("") then + minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack) + -- Place infinite nodes, except for shulker boxes + local group = minetest.get_item_group(itemstack:get_name(), "shulker_box") + return group == 0 or group == nil + end) + + function minetest.handle_node_drops(pos, drops, digger) + if not digger or not digger:is_player() then + for _, item in ipairs(drops) do + minetest.add_item(pos, item) + end + else + -- If there is a player + local inv = digger:get_inventory() + if inv then + for _, item in ipairs(drops) do + if not inv:contains_item("main", item, true) then + inv:add_item("main", item) + end + end + end + end + end +end + minetest.register_on_joinplayer(function(player) -- Initialize variables and inventory local name = player:get_player_name() @@ -629,7 +811,8 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - if minetest.is_creative_enabled(player:get_player_name()) and get_stack_size(player) == 64 and action == "put" and inventory_info.listname == "main" then + if minetest.is_creative_enabled(player:get_player_name()) and get_stack_size(player) == 64 and action == "put" and + inventory_info.listname == "main" then local stack = inventory_info.stack stack:set_count(stack:get_stack_max()) player:get_inventory():set_stack("main", inventory_info.index, stack) diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index 4ca0f2a73..2383295bc 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -1,155 +1,65 @@ -local S = minetest.get_translator(minetest.get_current_modname()) -local F = minetest.formspec_escape - mcl_inventory = {} ---local mod_player = minetest.get_modpath("mcl_player") ---local mod_craftguide = minetest.get_modpath("mcl_craftguide") +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/creative.lua") +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/survival.lua") --- Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left -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 = {x=pos.x, y=pos.y+1.2, z=pos.z} - 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) +local old_is_creative_enabled = minetest.is_creative_enabled + +function minetest.is_creative_enabled(name) + if old_is_creative_enabled(name) then return true end + if not name then return false end + assert(type(name) == "string", "minetest.is_creative_enabled requires a string (the playername) argument.") + local p = minetest.get_player_by_name(name) + if p then + return p:get_meta():get_string("gamemode") == "creative" end - return itemstack + return false end --- Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left -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 - -local function set_inventory(player) +---@param player mt.PlayerObjectRef +---@param armor_change_only? boolean +local function set_inventory(player, armor_change_only) if minetest.is_creative_enabled(player:get_player_name()) then - mcl_inventory.set_creative_formspec(player) + if armor_change_only then + -- Stay on survival inventory plage if only the armor has been changed + mcl_inventory.set_creative_formspec(player, 0, 0, nil, nil, "inv") + else + mcl_inventory.set_creative_formspec(player, 0, 1) + end return end - local inv = player:get_inventory() - inv:set_width("craft", 2) - inv:set_size("craft", 4) - local armor_slots = {"helmet", "chestplate", "leggings", "boots"} - local armor_slot_imgs = "" - for a=1,4 do - if inv:get_stack("armor", a+1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[0,"..(a-1)..";1,1;mcl_inventory_empty_armor_slot_"..armor_slots[a]..".png]" - end - end - - if inv:get_stack("offhand", 1):is_empty() then - armor_slot_imgs = armor_slot_imgs .. "image[3,2;1,1;mcl_inventory_empty_armor_slot_shield.png]" - end - - local form = "size[9,8.75]" .. - "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]" .. - mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") .. - - -- Armor - "list[current_player;armor;0,0;1,1;1]" .. - "list[current_player;armor;0,1;1,1;2]" .. - "list[current_player;armor;0,2;1,1;3]" .. - "list[current_player;armor;0,3;1,1;4]" .. - mcl_formspec.get_itemslot_bg(0,0,1,1) .. - mcl_formspec.get_itemslot_bg(0,1,1,1) .. - mcl_formspec.get_itemslot_bg(0,2,1,1) .. - mcl_formspec.get_itemslot_bg(0,3,1,1) .. - "list[current_player;offhand;3,2;1,1]" .. - mcl_formspec.get_itemslot_bg(3,2,1,1) .. - armor_slot_imgs .. - - -- Craft and inventory - "label[0,4;"..F(minetest.colorize("#313131", S("Inventory"))) .. "]" .. - "list[current_player;main;0,4.5;9,3;9]" .. - "list[current_player;main;0,7.74;9,1;]" .. - "label[4,0.5;"..F(minetest.colorize("#313131", S("Crafting"))) .. "]" .. - "list[current_player;craft;4,1;2,2]" .. - "list[current_player;craftpreview;7,1.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) .. - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) .. - mcl_formspec.get_itemslot_bg(4, 1,2, 2) .. - mcl_formspec.get_itemslot_bg(7, 1.5, 1, 1) .. - - -- Crafting guide button - "image_button[4.5,3;1,1;craftguide_book.png;__mcl_craftguide;]" .. - "tooltip[__mcl_craftguide;"..F(S("Recipe book")) .. "]" .. - - -- Help button - "image_button[8,3;1,1;doc_button_icon_lores.png;__mcl_doc;]" .. - "tooltip[__mcl_doc;" .. F(S("Help")) .. "]" - - -- Skins button - if minetest.global_exists("mcl_skins") then - form = form .. - "image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]" .. - "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]" - end - - form = form .. - -- Achievements button - "image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" .. - "tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]" .. - - -- For shortcuts - "listring[current_player;main]" .. - "listring[current_player;armor]" .. - "listring[current_player;main]" .. - "listring[current_player;craft]" .. - "listring[current_player;main]" - - player:set_inventory_formspec(form) + player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player)) end -- Drop items in craft grid and reset inventory on closing minetest.register_on_player_receive_fields(function(player, formname, fields) if fields.quit then - return_fields(player,"craft") - return_fields(player,"enchanting_lapis") - return_fields(player,"enchanting_item") + mcl_util.move_player_list(player, "craft") + mcl_util.move_player_list(player, "enchanting_lapis") + mcl_util.move_player_list(player, "enchanting_item") if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then set_inventory(player) end end end) -mcl_inventory.update_inventory_formspec = set_inventory + +function mcl_inventory.update_inventory_formspec(player) + set_inventory(player) +end -- Drop crafting grid items on leaving minetest.register_on_leaveplayer(function(player) - return_fields(player, "craft") - return_fields(player, "enchanting_lapis") - return_fields(player, "enchanting_item") + mcl_util.move_player_list(player, "craft") + mcl_util.move_player_list(player, "enchanting_lapis") + mcl_util.move_player_list(player, "enchanting_item") end) minetest.register_on_joinplayer(function(player) --init inventory local inv = player:get_inventory() + inv:set_width("main", 9) inv:set_size("main", 36) inv:set_size("offhand", 1) @@ -169,78 +79,25 @@ minetest.register_on_joinplayer(function(player) 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 inventories. ]] - return_fields(player, "craft") - return_fields(player, "enchanting_item") - return_fields(player, "enchanting_lapis") + mcl_util.move_player_list(player, "craft") + mcl_util.move_player_list(player, "enchanting_lapis") + mcl_util.move_player_list(player, "enchanting_item") end) -dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua") +---@param player mt.PlayerObjectRef +function mcl_inventory.update_inventory(player) + local player_name = player:get_player_name() + local is_gamemode_creative = minetest.is_creative_enabled(player_name) + if is_gamemode_creative then + mcl_inventory.set_creative_formspec(player) + elseif not is_gamemode_creative then + player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player)) + end + mcl_meshhand.update_player(player) +end + +mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode) + set_inventory(player) +end) mcl_player.register_on_visual_change(mcl_inventory.update_inventory_formspec) - -local mt_is_creative_enabled = minetest.is_creative_enabled - -function minetest.is_creative_enabled(name) - if mt_is_creative_enabled(name) then return true end - if not name then return false end - local p = minetest.get_player_by_name(name) - if p then - return p:get_meta():get_string("gamemode") == "creative" - end - return false -end - -local function in_table(n,h) - for k,v in pairs(h) do - if v == n then return true end - end - return false -end - -local gamemodes = { - "survival", - "creative" -} - -function mcl_inventory.player_set_gamemode(p,g) - local m = p:get_meta() - m:set_string("gamemode",g) - if g == "survival" then - mcl_experience.setup_hud(p) - mcl_experience.update(p) - elseif g == "creative" then - mcl_experience.remove_hud(p) - end - mcl_meshhand.update_player(p) - set_inventory(p) -end - -minetest.register_chatcommand("gamemode",{ - params = S("[] []"), - description = S("Change gamemode (survival/creative) for yourself or player"), - privs = { server = true }, - func = function(n,param) - -- Full input validation ( just for @erlehmann <3 ) - local p - local args = param:split(" ") - if args[2] ~= nil then - p = minetest.get_player_by_name(args[2]) - n = args[2] - else - p = minetest.get_player_by_name(n) - end - if not p then - return false, S("Player not online") - end - if args[1] ~= nil and not in_table(args[1],gamemodes) then - return false, S("Gamemode " .. args[1] .. " does not exist.") - elseif args[1] ~= nil then - mcl_inventory.player_set_gamemode(p,args[1]) - end - - --Result message - show effective game mode - local gm = p:get_meta():get_string("gamemode") - if gm == "" then gm = gamemodes[1] end - return true, S("Gamemode for player ")..n..S(": "..gm) - end -}) diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.pt_BR.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.pt_BR.tr new file mode 100644 index 000000000..a24e6afed --- /dev/null +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.pt_BR.tr @@ -0,0 +1,22 @@ +# textdomain: mcl_inventory +Recipe book=Livro de receitas +Help=Ajuda +Select player skin=Selecionar skin do jogador +Advancements=Progressos +Building Blocks=Blocos de construção +Decoration Blocks=Blocos de decoração +Redstone=Redstone +Transportation=Transporte +Brewing=Fermentação +Miscellaneous=Diversos +Search Items=Pesquisar Itens +Foodstuffs=Comida +Tools=Ferramentas +Combat=Combate +Mobs=Mobs +Materials=Materiais +Survival Inventory=Inventário do Sobrevivência +Crafting=Fabricação +Inventory=Inventário +@1/@2=@1/@2 +Switch stack size=Trocar tamanho da pilha diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr index a5c52bc1d..228de6a6d 100644 --- a/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr @@ -1,21 +1,22 @@ # textdomain: mcl_inventory Recipe book=Книга рецептов Help=Справка -Select player skin=Выбор внешности -Achievements=Достижения +Select player skin=Выбор скина +Advancements=Достижения Building Blocks=Строительные блоки -Decoration Blocks=Отделочные блоки -Redstone=Красный камень +Decoration Blocks=Декоративные блоки +Redstone=Механизмы Transportation=Транспорт -Brewing=Зелья -Miscellaneous=Прочее +Brewing=Зельеварение +Miscellaneous=Разное Search Items=Поиск предметов -Foodstuffs=Продовольствие +Foodstuffs=Пища Tools=Инструменты -Combat=Битва +Combat=Оружие и броня Mobs=Сущности Materials=Материалы Survival Inventory=Инвентарь выживания Crafting=Создание Inventory=Инвентарь @1/@2=@1/@2 +Switch stack size=Изменить размер стака \ No newline at end of file diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index e42213d4f..fc10fe32a 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1,5 +1,5 @@ name = mcl_inventory author = BlockMen description = Adds the player inventory and creative inventory. -depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_player -optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide +depends = mcl_init, mcl_formspec, mcl_enchanting, mcl_gamemode +optional_depends = mcl_armor, mcl_brewing, mcl_potions, mcl_enchanting, mcl_craftguide, mcl_player, tt diff --git a/mods/HUD/mcl_inventory/survival.lua b/mods/HUD/mcl_inventory/survival.lua new file mode 100644 index 000000000..253109cb7 --- /dev/null +++ b/mods/HUD/mcl_inventory/survival.lua @@ -0,0 +1,227 @@ +---@diagnostic disable need-check-nil +local S = minetest.get_translator("mcl_inventory") +local F = minetest.formspec_escape + +---@type {id: string, description: string, item_icon: string, build: (fun(player: ObjectRef): string), handle: fun(player: ObjectRef, fields: table), access: (fun(player): boolean), show_inventory: boolean}[] +mcl_inventory.registered_survival_inventory_tabs = {} + + +---@param def {id: string, description: string, item_icon: string, build: (fun(player: ObjectRef): string), handle: fun(player: ObjectRef, fields: table), access: (fun(player): boolean), show_inventory: boolean} +function mcl_inventory.register_survival_inventory_tab(def) + if #mcl_inventory.registered_survival_inventory_tabs == 7 then + error("Too many tabs registered!") + end + + assert(def.id) + assert(def.description) + assert(def.item_icon) + assert(def.build) + assert(def.handle) + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + assert(d.id ~= def.id, "Another tab exists with the same name!") + end + + if not def.access then + function def.access(player) + return true + end + end + + if def.show_inventory == nil then + def.show_inventory = true + end + + table.insert(mcl_inventory.registered_survival_inventory_tabs, def) +end + +local player_current_tab = {} +function get_player_tab(player) + local tab = player_current_tab[player] or "main" + player_current_tab[player] = tab + return tab +end + +minetest.register_on_joinplayer(function(player, last_login) + get_player_tab(player) +end) + +minetest.register_on_leaveplayer(function(player, timed_out) + player_current_tab[player] = nil +end) + +---@param player ObjectRef +---@param content string +---@param inventory boolean +---@param tabname string +local function build_page(player, content, inventory, tabname) + local tab_buttons = "style_type[image;noclip=true]" + + if #mcl_inventory.registered_survival_inventory_tabs ~= 1 then + for i, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + local btn_name = "tab_" .. d.id + + tab_buttons = tab_buttons .. table.concat({ + "style[" .. btn_name .. ";border=false;bgimg=;bgimg_pressed=;noclip=true]", + "image[" .. + (0.2 + (i - 1) * 1.6) .. + ",-1.34;1.5,1.44;" .. (tabname == d.id and "crafting_creative_active.png" or "crafting_creative_inactive.png") .. + "]", + "item_image_button[" .. (0.44 + (i - 1) * 1.6) .. ",-1.1;1,1;" .. d.item_icon .. ";" .. btn_name .. ";]", + "tooltip[" .. btn_name .. ";" .. F(d.description) .. "]" + }) + end + end + + return table.concat({ + "formspec_version[6]", + "size[11.75,10.9]", + + inventory and table.concat({ + --Main inventory + mcl_formspec.get_itemslot_bg_v4(0.375, 5.575, 9, 3), + "list[current_player;main;0.375,5.575;9,3;9]", + + --Hotbar + mcl_formspec.get_itemslot_bg_v4(0.375, 9.525, 9, 1), + "list[current_player;main;0.375,9.525;9,1;]" + }) or "", + + content, + tab_buttons, + }) +end + +local main_page_static = table.concat({ + --Armor slots + mcl_formspec.get_itemslot_bg_v4(0.375, 0.375, 1, 4), + "list[current_player;armor;0.375,0.375;1,1;1]", + "list[current_player;armor;0.375,1.625;1,1;2]", + "list[current_player;armor;0.375,2.875;1,1;3]", + "list[current_player;armor;0.375,4.125;1,1;4]", + + --Player model background + "image[1.57,0.343;3.62,4.85;mcl_inventory_background9.png;2]", + + --Offhand + mcl_formspec.get_itemslot_bg_v4(5.375, 4.125, 1, 1), + "list[current_player;offhand;5.375,4.125;1,1]", + + --Craft grid + "label[6.61,0.5;" .. F(minetest.colorize(mcl_formspec.label_color, S("Crafting"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(6.625, 0.875, 2, 2), + "list[current_player;craft;6.625,0.875;2,2]", + + "image[9.125,1.5;1,1;crafting_formspec_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(10.375, 1.5, 1, 1), + "list[current_player;craftpreview;10.375,1.5;1,1;]", + + --Crafting guide button + "image_button[6.575,4.075;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", + + --Help button + "image_button[7.825,4.075;1.1,1.1;doc_button_icon_lores.png;__mcl_doc;]", + "tooltip[__mcl_doc;" .. F(S("Help")) .. "]", + + --Skins button + "image_button[9.075,4.075;1.1,1.1;mcl_skins_button.png;__mcl_skins;]", + "tooltip[__mcl_skins;" .. F(S("Select player skin")) .. "]", + + --Achievements button + "image_button[10.325,4.075;1.1,1.1;mcl_achievements_button.png;__mcl_achievements;]", + "tooltip[__mcl_achievements;" .. F(S("Achievements")) .. "]", + + --Listring + "listring[current_player;main]", + "listring[current_player;craft]", + "listring[current_player;main]", + "listring[current_player;armor]", + "listring[current_player;main]", +}) + +mcl_inventory.register_survival_inventory_tab({ + id = "main", + description = "Main Inventory", + item_icon = "mcl_crafting_table:crafting_table", + show_inventory = true, + build = function(player) + local inv = player:get_inventory() + + local armor_slots = { "helmet", "chestplate", "leggings", "boots" } + local armor_slot_imgs = "" + + for a = 1, 4 do + if inv:get_stack("armor", a + 1):is_empty() then + armor_slot_imgs = armor_slot_imgs .. + "image[0.375," .. (0.375 + (a - 1) * 1.25) .. ";1,1;mcl_inventory_empty_armor_slot_" .. armor_slots[a] .. ".png]" + end + end + + if inv:get_stack("offhand", 1):is_empty() then + armor_slot_imgs = armor_slot_imgs .. "image[5.375,4.125;1,1;mcl_inventory_empty_armor_slot_shield.png]" + end + return main_page_static .. armor_slot_imgs .. mcl_player.get_player_formspec_model(player, 1.57, 0.4, 3.62, 4.85, "") + end, + handle = function() end, +}) + +--[[ +mcl_inventory.register_survival_inventory_tab({ + id = "test", + description = "Test", + item_icon = "mcl_core:stone", + show_inventory = true, + build = function(player) + return "label[1,1;Hello hello]button[2,2;2,2;Hello;hey]" + end, + handle = function(player, fields) + print(dump(fields)) + end, +})]] + +---@param player ObjectRef +function mcl_inventory.build_survival_formspec(player) + local inv = player:get_inventory() + + inv:set_width("craft", 2) + inv:set_size("craft", 4) + + local tab = get_player_tab(player) + + local tab_def = nil + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if tab == d.id then + tab_def = d + break + end + end + + local form = build_page(player, tab_def.build(player), tab_def.show_inventory, tab) + + return form +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local player_name = player:get_player_name() + if formname == "" and #mcl_inventory.registered_survival_inventory_tabs ~= 1 and + not minetest.is_creative_enabled(player_name) then + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if fields["tab_" .. d.id] and d.access(player) then + player_current_tab[player] = d.id + mcl_inventory.update_inventory(player) + break + end + end + + for _, d in ipairs(mcl_inventory.registered_survival_inventory_tabs) do + if get_player_tab(player) == d.id and d.access(player) then + d.handle(player, fields) + return + end + end + end +end) diff --git a/mods/HUD/mcl_offhand/init.lua b/mods/HUD/mcl_offhand/init.lua index 98954b4f5..e9129e537 100644 --- a/mods/HUD/mcl_offhand/init.lua +++ b/mods/HUD/mcl_offhand/init.lua @@ -16,19 +16,31 @@ local function offhand_get_count(player) return mcl_offhand.get_offhand(player):get_count() end -minetest.register_on_joinplayer(function(player, last_login) - mcl_offhand[player] = { +local function get_offhand(player) + -- Get offhand data if it already exists + local offhand = mcl_offhand[player] + if offhand then return offhand end + + -- Otherwise initialize it + offhand = { hud = {}, last_wear = offhand_get_wear(player), last_count = offhand_get_count(player), } + mcl_offhand[player] = offhand + return offhand +end + +minetest.register_on_joinplayer(function(player, last_login) + get_offhand(player) end) local function remove_hud(player, hud) - local offhand_hud = mcl_offhand[player].hud[hud] + local offhand = get_offhand(player) + local offhand_hud = offhand.hud[hud] if offhand_hud then player:hud_remove(offhand_hud) - mcl_offhand[player].hud[hud] = nil + offhand.hud[hud] = nil end end @@ -48,7 +60,8 @@ local function update_wear_bar(player, itemstack) else color = {255, 511 - wear_i, 0} end - local wear_bar = mcl_offhand[player].hud.wear_bar + local offhand = get_offhand(player) + local wear_bar = offhand.hud.wear_bar player:hud_change(wear_bar, "text", "mcl_wear_bar.png^[colorize:#" .. rgb_to_hex(color[1], color[2], color[3])) player:hud_change(wear_bar, "scale", {x = 40 * wear_bar_percent, y = 3}) player:hud_change(wear_bar, "offset", {x = -320 - (20 - player:hud_get(wear_bar).scale.x / 2), y = -13}) @@ -58,7 +71,8 @@ minetest.register_globalstep(function(dtime) for _, player in pairs(minetest.get_connected_players()) do local itemstack = mcl_offhand.get_offhand(player) local offhand_item = itemstack:get_name() - local offhand_hud = mcl_offhand[player].hud + local offhand = get_offhand(player) + local offhand_hud = offhand.hud local item = minetest.registered_items[offhand_item] if offhand_item ~= "" and item then local item_texture = item.inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px @@ -145,7 +159,8 @@ minetest.register_globalstep(function(dtime) end elseif offhand_hud.slot then - for index, _ in pairs(mcl_offhand[player].hud) do + local offhand = get_offhand(player) + for index, _ in pairs(offhand.hud) do remove_hud(player, index) end end diff --git a/mods/HUD/mcl_ver_info/init.lua b/mods/HUD/mcl_ver_info/init.lua index 632847275..82eb46cfe 100644 --- a/mods/HUD/mcl_ver_info/init.lua +++ b/mods/HUD/mcl_ver_info/init.lua @@ -25,7 +25,7 @@ end -- register normal user access to debug levels 1 and 0. minetest.register_chatcommand("ver", { - description = S("Display Mineclone 2 game version."), + description = S("Display VoxeLibre game version."), func = function(name, params) --[[ get_game_info's table data: { @@ -46,7 +46,7 @@ minetest.register_chatcommand("ver", { local version = conf:get("version") if game_info.title == nil or game_info.title == "" then - game_info.title = "Mineclone 2" + game_info.title = "VoxeLibre" end -- Notes: "game.conf doesn't support id currently, this is planned in the future" - rubenwardy from the github issue. -- TODO: Remove workaround after minetest.get_game_info().id is implemented. diff --git a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.fr.tr b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.fr.tr index 3e6c9af6d..d55fdeb04 100644 --- a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.fr.tr +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.fr.tr @@ -1,2 +1,3 @@ # 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. +Display VoxeLibre game version.=Affiche la version de VoxeLibre. diff --git a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.pt_BR.tr b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.pt_BR.tr new file mode 100644 index 000000000..bb3e372ca --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_ver_info +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=Desculpe, mas sua versão do Minetest não suporta a última API. Por favor atualize seu minetest. +Display VoxeLibre game version.=Mostrar a versão do jogo VoxeLibre. diff --git a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ru.tr b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ru.tr new file mode 100644 index 000000000..5ade98601 --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_ver_info +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=Ваша версия Minetest не поддерживает последнюю версию API. Пожалуйста, обновите ваш Minetest. +Display VoxeLibre game version.=Показать версию VoxeLibre. diff --git a/mods/HUD/mcl_ver_info/locale/template.txt b/mods/HUD/mcl_ver_info/locale/template.txt index 75febe815..92e19c66c 100644 --- a/mods/HUD/mcl_ver_info/locale/template.txt +++ b/mods/HUD/mcl_ver_info/locale/template.txt @@ -1,2 +1,3 @@ # textdomain: mcl_ver_info -Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.= \ No newline at end of file +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.= +Display Mineclone 2 game version.= diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pt_BR.tr b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pt_BR.tr new file mode 100644 index 000000000..2139b73b1 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pt_BR.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_comparators +Redstone comparators are multi-purpose redstone components.=Comparadores de redstone são componentes de redstone multi propósito. +They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.=Eles podem transmitir um sinal de redstone, detectar se um bloco contém alguns itens e compara multíplos sinais. +A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.=Um comparador de redstone tem 1 entrada principal, 2 entradas laterais e 1 saída. A saída é na direção da seta, a entrada principal é na direção oposta. Os outros 2 lados são as entradas laterais. +The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.=A entrada principal pode ser energizada de 2 maneiras: Primeiro, ela pode ser energizada diretamente por carga de redstone como qualquer outro componente. Segundo, é energizada se, e somente se um recipiente (como um baú) é posicionado em frente dele e o recipiente conter pelo menos um item. +The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.=As entradas laterais são energizadas apenas por cargas normais de redstone. O comparador de redstone pode operar em dois modos: Modo de transmissão e modo de subtração. Iniciará em modo de transmissão e o modo pode ser alterado usando o bloco. +Transmission mode:@nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.=Modo de transmissão:@nA tocha frontal é apagada e baixada. A saída é energizada se, e somente se a entrada principal é energizada. As entradas laterais são ignoradas. +Subtraction mode:@nThe front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered.=Modo de subtração:@nA tocha frontal é acesa. A saída é energizada se, e somente se a entrada principal é energizada e nenhuma das entradas laterais estiverem energizadas. +Redstone Comparator=Comparador de Redstone +Redstone Comparator (Subtract)=Comparador de Redstone (Subtração) +Redstone Comparator (Powered)=Comparador de Redstone (Energizado) +Redstone Comparator (Subtract, Powered)=Comparador de Redstone (Subtração, Energizado) diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ru.tr b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ru.tr index 39a845d6e..352526ed6 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ru.tr +++ b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ru.tr @@ -1,12 +1,12 @@ # textdomain: mcl_comparators -Redstone comparators are multi-purpose redstone components.=Компаратор это многофункциональный элемент редстоуна. -They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.=Он может передавать сигнал редстоуна, определять, содержит ли блок какой-либо предмет, и сравнивать сигналы. +Redstone comparators are multi-purpose redstone components.=Компаратор это многофункциональный компонент редстоуна. +They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.=Он может передавать сигнал редстоуна, определять, хранит ли блок предмет, и сравнивать сигналы. A redstone comparator has 1 main input, 2 side inputs and 1 output. The output is in arrow direction, the main input is in the opposite direction. The other 2 sides are the side inputs.=Компаратор имеет 1 основной вход, 2 боковых входа и 1 выход. Выход расположен по направлению стрелки, основной вход в противоположном направлении. Оставшиеся 2 стороны это боковые входы. -The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.=Основной вход можно подключать 2 способами: 1) напрямую к энергии редстоуна, как и любой другой компонент; 2) перед компаратором можно установить контейнер (например, сундук), тогда сигнал будет поступать, если в нём содержится хотя бы один предмет. -The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.=К боковым входам можно подводить только обычную энергию редстоуна. Компаратор может работать в двух режимах: ПЕРЕДАЧА и ВЫЧИТАНИЕ. Он изначально находится в режиме передачи; режим меняется при [Использовании] данного блока. -Transmission mode:@nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.=Режим ПЕРЕДАЧИ:@nПередний индикатор погашен. На выходе появляется энергия редстоуна, только если она подаётся на основной вход. Состояние боковых входов при этом игнорируются. +The main input can powered in 2 ways: First, it can be powered directly by redstone power like any other component. Second, it is powered if, and only if a container (like a chest) is placed in front of it and the container contains at least one item.=Основной вход можно подключать 2 способами: 1) напрямую от сигнала редстоуна, как и любой другой компонент; 2) перед компаратором можно установить контейнер (например, сундук), тогда сигнал будет поступать, если в нём содержится хотя бы один предмет. +The side inputs are only powered by normal redstone power. The redstone comparator can operate in two modes: Transmission mode and subtraction mode. It starts in transmission mode and the mode can be changed by using the block.=К боковым входам можно подводить только сигнал редстоуна. Компаратор может работать в двух режимах: передача и вычитание. Он изначально находится в режиме передачи; режим меняется при использовании данного блока. +Transmission mode:@nThe front torch is unlit and lowered. The output is powered if, and only if the main input is powered. The two side inputs are ignored.=Режим передачи:@nПередний индикатор погашен. На выходе появляется сигнал редстоуна, только если он подаётся на основной вход. Состояние боковых входов при этом игнорируются. Subtraction mode:@nThe front torch is lit. The output is powered if, and only if the main input is powered and none of the side inputs is powered.=Режим ВЫЧИТАНИЯ:@nПередний индикатор светится. На выходе есть сигнал только в том случае, если сигнал есть на основной входе, но при этом его нет ни на одном из боковых входов. Redstone Comparator=Компаратор -Redstone Comparator (Subtract)=Компаратор (ВЫЧИТАНИЕ) -Redstone Comparator (Powered)=Компаратор (ВКЛЮЧЁН) -Redstone Comparator (Subtract, Powered)=Компаратор (ВЫЧИТАНИЕ, ВКЛЮЧЁН) +Redstone Comparator (Subtract)=Компаратор (вычитание) +Redstone Comparator (Powered)=Компаратор (подключён) +Redstone Comparator (Subtract, Powered)=Компаратор (вычитание, подключён) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 17d9385a2..9e5224b15 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -8,23 +8,36 @@ All node definitions share a lot of code, so this is the reason why there are so many weird tables below. ]] local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape --- For after_place_node +local dispenser_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Dispenser"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(4.125, 0.75, 3, 3), + "list[context;main;4.125,0.75;3,3;]", + + "label[0.375,4.7;" .. F(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[context;main]", + "listring[current_player;main]", +}) + +---For after_place_node +---@param pos Vector local function setup_dispenser(pos) -- Set formspec and inventory - local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dispenser"))).."]".. - "list[context;main;3,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[context;main]".. - "listring[current_player;main]" local meta = minetest.get_meta(pos) - meta:set_string("formspec", form) + meta:set_string("formspec", dispenser_formspec) local inv = meta:get_inventory() inv:set_size("main", 9) end @@ -38,9 +51,9 @@ local function orientate_dispenser(pos, placer) local node = minetest.get_node(pos) if pitch > 55 then - minetest.swap_node(pos, {name="mcl_dispensers:dispenser_up", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_dispensers:dispenser_up", param2 = node.param2 }) elseif pitch < -55 then - minetest.swap_node(pos, {name="mcl_dispensers:dispenser_down", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_dispensers:dispenser_down", param2 = node.param2 }) end end @@ -85,11 +98,10 @@ local dispenserdef = { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -107,19 +119,19 @@ local dispenserdef = { dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1) droppos = vector.add(pos, dropdir) elseif node.name == "mcl_dispensers:dispenser_up" then - dropdir = {x=0, y=1, z=0} - droppos = {x=pos.x, y=pos.y+1, z=pos.z} + dropdir = vector.new(0, 1, 0) + droppos = vector.offset(pos, 0, 1, 0) elseif node.name == "mcl_dispensers:dispenser_down" then - dropdir = {x=0, y=-1, z=0} - droppos = {x=pos.x, y=pos.y-1, z=pos.z} + dropdir = vector.new(0, -1, 0) + droppos = vector.offset(pos, 0, -1, 0) end local dropnode = minetest.get_node(droppos) local dropnodedef = minetest.registered_nodes[dropnode.name] local stacks = {} - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - table.insert(stacks, {stack = stack, stackpos = i}) + table.insert(stacks, { stack = stack, stackpos = i }) end end if #stacks >= 1 then @@ -143,9 +155,10 @@ local dispenserdef = { -- Armor, mob heads and pumpkins if igroups.armor then - local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z} + local droppos_below = vector.offset(droppos, 0, -1, 0) - for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do + for _, objs in ipairs({ minetest.get_objects_inside_radius(droppos, 1), + minetest.get_objects_inside_radius(droppos_below, 1) }) do for _, obj in ipairs(objs) do stack = mcl_armor.equip(stack, obj) if stack:is_empty() then @@ -157,11 +170,11 @@ local dispenserdef = { end end - -- Place head or pumpkin as node, if equipping it as armor has failed + -- Place head or pumpkin as node, if equipping it as armor has failed if not stack:is_empty() then if igroups.head or iname == "mcl_farming:pumpkin_face" then if dropnodedef.buildable_to then - minetest.set_node(droppos, {name = iname, param2 = node.param2}) + minetest.set_node(droppos, { name = iname, param2 = node.param2 }) stack:take_item() end end @@ -169,7 +182,7 @@ local dispenserdef = { inv:set_stack("main", stack_id, stack) - -- Use shears on sheeps + -- Use shears on sheeps elseif igroups.shears then for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do local entity = obj:get_luaentity() @@ -214,13 +227,14 @@ local dispenserdef = { entity.gotten = true minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true) stack:add_wear(65535 / stackdef._mcl_diggroups.shearsy.uses) + tt.reload_itemstack_description(stack) -- update tooltip inv:set_stack("main", stack_id, stack) break end end end - -- Spawn Egg + -- Spawn Egg elseif igroups.spawn_egg then -- Spawn mob if not dropnodedef.walkable then @@ -231,7 +245,7 @@ local dispenserdef = { inv:set_stack("main", stack_id, stack) end - -- Generalized dispension + -- Generalized dispension elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then --[[ _on_dispense(stack, pos, droppos, dropnode, dropdir) * stack: Itemstack which is dispense @@ -263,7 +277,7 @@ local dispenserdef = { 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)) + item_entity:set_velocity(vector.multiply(drop_vel, speed)) end else stack:take_item() @@ -280,7 +294,7 @@ local dispenserdef = { 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)) + item_entity:set_velocity(vector.multiply(drop_vel, speed)) stack:take_item() inv:set_stack("main", stack_id, stack) end @@ -299,27 +313,28 @@ local dispenserdef = { local horizontal_def = table.copy(dispenserdef) horizontal_def.description = S("Dispenser") -horizontal_def._tt_help = S("9 inventory slots").."\n"..S("Launches item when powered by redstone power") +horizontal_def._tt_help = S("9 inventory slots") .. "\n" .. S("Launches item when powered by redstone power") horizontal_def._doc_items_longdesc = S("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.") -horizontal_def._doc_items_usagehelp = S("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.").."\n\n".. +horizontal_def._doc_items_usagehelp = S("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.") + .. "\n\n" .. -S("The dispenser will do different things, depending on the dispensed item:").."\n\n".. + S("The dispenser will do different things, depending on the dispensed item:") .. "\n\n" .. -S("• Arrows: Are launched").."\n".. -S("• Eggs and snowballs: Are thrown").."\n".. -S("• Fire charges: Are fired in a straight line").."\n".. -S("• Armor: Will be equipped to players and armor stands").."\n".. -S("• Boats: Are placed on water or are dropped").."\n".. -S("• Minecart: Are placed on rails or are dropped").."\n".. -S("• Bone meal: Is applied on the block it is facing").."\n".. -S("• Empty buckets: Are used to collect a liquid source").."\n".. -S("• Filled buckets: Are used to place a liquid source").."\n".. -S("• Heads, pumpkins: Equipped to players and armor stands, or placed as a block").."\n".. -S("• Shulker boxes: Are placed as a block").."\n".. -S("• TNT: Is placed and ignited").."\n".. -S("• Flint and steel: Is used to ignite a fire in air and to ignite TNT").."\n".. -S("• Spawn eggs: Will summon the mob they contain").."\n".. -S("• Other items: Are simply dropped") + S("• Arrows: Are launched") .. "\n" .. + S("• Eggs and snowballs: Are thrown") .. "\n" .. + S("• Fire charges: Are fired in a straight line") .. "\n" .. + S("• Armor: Will be equipped to players and armor stands") .. "\n" .. + S("• Boats: Are placed on water or are dropped") .. "\n" .. + S("• Minecart: Are placed on rails or are dropped") .. "\n" .. + S("• Bone meal: Is applied on the block it is facing") .. "\n" .. + S("• Empty buckets: Are used to collect a liquid source") .. "\n" .. + S("• Filled buckets: Are used to place a liquid source") .. "\n" .. + S("• Heads, pumpkins: Equipped to players and armor stands, or placed as a block") .. "\n" .. + S("• Shulker boxes: Are placed as a block") .. "\n" .. + S("• TNT: Is placed and ignited") .. "\n" .. + S("• Flint and steel: Is used to ignite a fire in air and to ignite TNT") .. "\n" .. + S("• Spawn eggs: Will summon the mob they contain") .. "\n" .. + S("• Other items: Are simply dropped") function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dispenser(pos) @@ -332,7 +347,7 @@ horizontal_def.tiles = { "default_furnace_side.png", "mcl_dispensers_dispenser_front_horizontal.png" } horizontal_def.paramtype2 = "facedir" -horizontal_def.groups = {pickaxey=1, container=2, material_stone=1} +horizontal_def.groups = { pickaxey = 1, container = 2, material_stone = 1 } minetest.register_node("mcl_dispensers:dispenser", horizontal_def) @@ -345,7 +360,7 @@ down_def.tiles = { "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png" } -down_def.groups = {pickaxey=1, container=2,not_in_creative_inventory=1, material_stone=1} +down_def.groups = { pickaxey = 1, container = 2, not_in_creative_inventory = 1, material_stone = 1 } down_def._doc_items_create_entry = false down_def.drop = "mcl_dispensers:dispenser" minetest.register_node("mcl_dispensers:dispenser_down", down_def) @@ -365,9 +380,9 @@ minetest.register_node("mcl_dispensers:dispenser_up", up_def) minetest.register_craft({ output = "mcl_dispensers:dispenser", recipe = { - {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, - {"mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble",}, - {"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble",}, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble", }, + { "mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble", }, + { "mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble", }, } }) @@ -384,6 +399,6 @@ minetest.register_lbm({ nodenames = { "mcl_dispensers:dispenser", "mcl_dispensers:dispenser_down", "mcl_dispensers:dispenser_up" }, action = function(pos, node) setup_dispenser(pos) - minetest.log("action", "[mcl_dispenser] Node formspec updated at "..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_dispenser] Node formspec updated at " .. minetest.pos_to_string(pos)) end, }) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.es.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.es.tr index cf695307a..1b1481f5c 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.es.tr +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.es.tr @@ -2,12 +2,13 @@ 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. 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 • 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 • 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 -• 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 • 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 @@ -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 Upwards-Facing Dispenser=Dispensador orientado hacia arriba 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 diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pt_BR.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pt_BR.tr new file mode 100644 index 000000000..b21f401ed --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pt_BR.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_dispensers +Dispenser=Ejetor +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.=Um ejetor é um bloco ao qual age como um componente de redstone ao qual, quando energizado com carga de redstone, ejeta um item. Tem um recipiente com 9 slots de inventário. +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.=Posicione o ejetor em uma das 6 direções possíveis. O "buraco" é por onde os itens irão voar para fora do ejetor. Use o ejetor para acessar seu inventário. Insira os itens que você deseja ejetar. Alimente o ejetor com carga de redstone uma vez para ejetar um item aleatório. +The dispenser will do different things, depending on the dispensed item:=O ejetor irá fazer coisas diferentes, dependendo do item ejetado: +• Arrows: Are launched=• Flechas: Serão lançadas +• Eggs and snowballs: Are thrown=• Ovos e bolas de neve: São arremessadas +• Fire charges: Are fired in a straight line=• Bolas de fogo: São atiradas em uma linha reta +• Armor: Will be equipped to players and armor stands=• Armadura: Será equipada em jogadores e suportes de armaduras +• Boats: Are placed on water or are dropped=• Barcos: São posicionados em água ou são liberados +• Minecart: Are placed on rails or are dropped=• Carrinhos: São posicionados em trilhos ou são liberados +• Bone meal: Is applied on the block it is facing=• Farinha de osso: É aplicada no bloco ao qual está encarando +• Empty buckets: Are used to collect a liquid source=• Baldes vazios: São usados para coletar uma fonte de líquido +• Filled buckets: Are used to place a liquid source=• Baldes preenchidos: São usados para posicionar uma fonte de líquido +• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Cabeças, abóboras: São equipadas em jogadores e suportes de armaduras, ou posicionadas como um bloco +• Shulker boxes: Are placed as a block=• Caixas shulker: São posicionadas como um bloco +• TNT: Is placed and ignited=• TNT: É posicionada e acesa +• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Isqueiro: É usado para acender um fogo no ar e para acender uma TNT +• Spawn eggs: Will summon the mob they contain=• Ovos de geração: Vão invocar o mob que eles contém +• Other items: Are simply dropped=• Outros itens: São simplesmente liberados +Downwards-Facing Dispenser=Ejetor Virado Para Baixo +Upwards-Facing Dispenser=Ejetor Virado Para Cima +Inventory=Inventário +9 inventory slots=Inventário de 9 slots +Launches item when powered by redstone power=Lança itens quando energizados por carga de redstone diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ru.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ru.tr index af4d856ec..91438e5f6 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ru.tr +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ru.tr @@ -1,25 +1,25 @@ # textdomain: mcl_dispensers -Dispenser=Диспенсер -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.=Диспенсер это элемент редстоуна, который при подаче энергии редстоуна выбрасывает предмет. В нём есть контейнер из 9 отсеков инвентаря. -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.=Направьте диспенсер в одном из 6 возможных направлений. Предметы будут вылетать из отверстия. [Используйте] диспенсер для доступа к его инвентарю. Загрузите туда предметы, которые должны из него выбрасываться. Подайте однократно на диспенсер энергию редстоуна, чтобы выпал случайный предмет. -The dispenser will do different things, depending on the dispensed item:=Диспенсер будет делать разные вещи, в зависимости от выдаваемых предметов: +Dispenser=Раздатчик +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.=Раздатчик это компонент редстоуна, который при подаче сигнала редстоуна выбрасывает предмет. В нём есть контейнер из 9 слотов инвентаря. +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.=Направьте раздатчик в одном из 6 возможных направлений. Предметы будут вылетать из отверстия. Используйте раздатчик для доступа к его инвентарю. Загрузите туда предметы, которые должны из него выбрасываться. Подайте однократно на раздатчик сигнал редстоуна, чтобы он раздал случайный предмет. +The dispenser will do different things, depending on the dispensed item:=Раздатчик будет делать разные вещи, в зависимости от выдаваемых предметов: • Arrows: Are launched=• Стрелы: выстреливают -• Eggs and snowballs: Are thrown=• Яйца и снежки: происходит бросок +• Eggs and snowballs: Are thrown=• Яйца и снежки: бросаются • Fire charges: Are fired in a straight line=• Огненные шары: стреляют по прямой линии -• Armor: Will be equipped to players and armor stands=• Защита: экипирует игроков или стенд защиты +• Armor: Will be equipped to players and armor stands=• Броня: экипирует игроков или стойку для брони • Boats: Are placed on water or are dropped=• Лодки: спускаются на воду -• Minecart: Are placed on rails or are dropped=• Вагонетка: помещается на рельсы -• Bone meal: Is applied on the block it is facing=• Костная мука: применяется к блоку перед диспенсером +• Minecart: Are placed on rails or are dropped=• Вагонетки: помещаются на рельсы +• Bone meal: Is applied on the block it is facing=• Костная мука: применяется к блоку перед раздатчиком • Empty buckets: Are used to collect a liquid source=• Пустые вёдра: используются для набора источника жидкости • Filled buckets: Are used to place a liquid source=• Полные вёдра: используются для размещения источника жидкости -• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Головы, тыквы: экипирует игроков, или стенд защиты, или устанавливаются как блоки +• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Головы, тыквы: экипирует игроков, стойку для брони, или устанавливаются как блоки • Shulker boxes: Are placed as a block=• Ящик шалкера: устанавливается как блок -• TNT: Is placed and ignited=• Тротил: устанавливается и поджигается -• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Огниво: используется для зажигания огня в воздухе и для подрыва тротила -• Spawn eggs: Will summon the mob they contain=• Порождающие яйца: будут вызывать мобов, содержащихся в них -• Other items: Are simply dropped=• Другие предметы: просто выдаются -Downwards-Facing Dispenser=• Диспенсер, направленный вниз -Upwards-Facing Dispenser=• Диспенсер, направленный вверх +• TNT: Is placed and ignited=• ТНТ: устанавливается и поджигается +• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Огниво: используется для зажигания огня в воздухе и для подрыва ТНТ +• Spawn eggs: Will summon the mob they contain=• Яйца спауна: будут призывать мобов, содержащихся в них +• Other items: Are simply dropped=• Другие предметы: просто выбрасываются +Downwards-Facing Dispenser=• Раздатчик, направленный вниз +Upwards-Facing Dispenser=• Раздатчик, направленный вверх Inventory=Инвентарь -9 inventory slots=9 отсеков инвентаря -Launches item when powered by redstone power=Выбрасывает предметы при подаче энергии редстоуна +9 inventory slots=9 слотов инвентаря +Launches item when powered by redstone power=Выдаёт предметы при подаче сигнала редстоуна diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 5f8f94d84..e47371bc9 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -9,23 +9,36 @@ are so many weird tables below. ]] local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape --- For after_place_node +local dropper_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Dropper"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(4.125, 0.75, 3, 3), + "list[context;main;4.125,0.75;3,3;]", + + "label[0.375,4.7;" .. F(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[context;main]", + "listring[current_player;main]", +}) + +---For after_place_node +---@param pos Vector local function setup_dropper(pos) -- Set formspec and inventory - local form = "size[9,8.75]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. - "list[context;main;3,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[context;main]".. - "listring[current_player;main]" local meta = minetest.get_meta(pos) - meta:set_string("formspec", form) + meta:set_string("formspec", dropper_formspec) local inv = meta:get_inventory() inv:set_size("main", 9) end @@ -38,9 +51,9 @@ local function orientate_dropper(pos, placer) local pitch = placer:get_look_vertical() * (180 / math.pi) if pitch > 55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_up"}) + minetest.swap_node(pos, { name = "mcl_droppers:dropper_up" }) elseif pitch < -55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_down"}) + minetest.swap_node(pos, { name = "mcl_droppers:dropper_down" }) end end @@ -58,11 +71,10 @@ local dropperdef = { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -96,7 +108,7 @@ local dropperdef = { end, _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, - mesecons = {effector = { + mesecons = { effector = { -- Drop random item when triggered action_on = function(pos, node) if not pos then return end @@ -104,23 +116,27 @@ local dropperdef = { local inv = meta:get_inventory() local droppos if node.name == "mcl_droppers:dropper" then - droppos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) + droppos = vector.subtract(pos, minetest.facedir_to_dir(node.param2)) elseif node.name == "mcl_droppers:dropper_up" then - droppos = {x=pos.x, y=pos.y+1, z=pos.z} + droppos = vector.offset(pos, 0, 1, 0) elseif node.name == "mcl_droppers:dropper_down" then - droppos = {x=pos.x, y=pos.y-1, z=pos.z} + droppos = vector.offset(pos, 0, -1, 0) end local dropnode = minetest.get_node(droppos) -- Do not drop into solid nodes, unless they are containers 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 end local stacks = {} - for i=1,inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) if not stack:is_empty() then - table.insert(stacks, {stack = stack, stackpos = i}) + table.insert(stacks, { stack = stack, stackpos = i }) end end if #stacks >= 1 then @@ -129,29 +145,22 @@ local dropperdef = { local dropitem = ItemStack(stack) dropitem:set_count(1) local stack_id = stacks[r].stackpos - - -- If it's a container, attempt to put it into the container - local dropped = mcl_util.move_item_container(pos, droppos, nil, stack_id) - -- No container? - if not dropped and not dropnodedef.groups.container then - -- Drop item normally - local pos_variation = 100 - droppos = { - x = droppos.x + math.random(-pos_variation, pos_variation) / 1000, - y = droppos.y + math.random(-pos_variation, pos_variation) / 1000, - z = droppos.z + math.random(-pos_variation, pos_variation) / 1000, - } - 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 + local pos_variation = 100 + droppos = vector.offset(droppos, + math.random(-pos_variation, pos_variation) / 1000, + math.random(-pos_variation, pos_variation) / 1000, + math.random(-pos_variation, pos_variation) / 1000 + ) + 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, rules = mesecon.rules.alldirs, - }}, + } }, on_rotate = on_rotate, } @@ -159,20 +168,21 @@ local dropperdef = { local horizontal_def = table.copy(dropperdef) horizontal_def.description = S("Dropper") -horizontal_def._tt_help = S("9 inventory slots").."\n"..S("Drops item when powered by redstone power") +horizontal_def._tt_help = S("9 inventory slots") .. "\n" .. S("Drops item when powered by redstone power") horizontal_def._doc_items_longdesc = S("A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.") horizontal_def._doc_items_usagehelp = S("Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.") function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dropper(pos) orientate_dropper(pos, placer) end + horizontal_def.tiles = { "default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "mcl_droppers_dropper_front_horizontal.png" } horizontal_def.paramtype2 = "facedir" -horizontal_def.groups = {pickaxey=1, container=2, material_stone=1} +horizontal_def.groups = { pickaxey = 1, container = 2, material_stone = 1 } minetest.register_node("mcl_droppers:dropper", horizontal_def) @@ -185,7 +195,7 @@ down_def.tiles = { "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png", "default_furnace_side.png" } -down_def.groups = {pickaxey=1, container=2,not_in_creative_inventory=1, material_stone=1} +down_def.groups = { pickaxey = 1, container = 2, not_in_creative_inventory = 1, material_stone = 1 } down_def._doc_items_create_entry = false down_def.drop = "mcl_droppers:dropper" minetest.register_node("mcl_droppers:dropper_down", down_def) @@ -207,9 +217,9 @@ minetest.register_node("mcl_droppers:dropper_up", up_def) minetest.register_craft({ output = "mcl_droppers:dropper", recipe = { - {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, - {"mcl_core:cobble", "", "mcl_core:cobble",}, - {"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble",}, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble", }, + { "mcl_core:cobble", "", "mcl_core:cobble", }, + { "mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble", }, } }) @@ -226,6 +236,6 @@ minetest.register_lbm({ nodenames = { "mcl_droppers:dropper", "mcl_droppers:dropper_down", "mcl_droppers:dropper_up" }, action = function(pos, node) setup_dropper(pos) - minetest.log("action", "[mcl_droppers] Node formspec updated at "..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_droppers] Node formspec updated at " .. minetest.pos_to_string(pos)) end, }) diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pt_BR.tr b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pt_BR.tr new file mode 100644 index 000000000..56917c8f2 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pt_BR.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_droppers +Dropper=Liberador +A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.=Um liberador é um componente de redstone e um recipiente com 9 slots de inventário ao qual, quando alimentado com carga de redstone, libera um item ou coloca-o em um recipiente em sua frente. +Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.=Liberadores podem ser posicionados em 6 direções possíveis, os itens serão liberados pelo buraco. Use o liberador para acessar seu inventário. Alimente-o com carga de redstone uma vez para fazer o liberador liberar ou transferir um item aleatório. +Downwards-Facing Dropper=Liberador Virado Para Baixo +Upwards-Facing Dropper=Liberador Virado Para Cima +Inventory=Inventário +9 inventory slots=Inventário de 9 slots +Drops item when powered by redstone power=Libera itens quando energizados por carga de redstone diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ru.tr b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ru.tr index 22358678a..c4520caf2 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ru.tr +++ b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ru.tr @@ -1,9 +1,9 @@ # textdomain: mcl_droppers Dropper=Выбрасыватель -A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.=Выбрасыватель это элемент редстоуна и контейнер с 9 отсеками инвентаря, срабатывающий по сигналу редстоуна и выбрасывающий предмет, либо выталкивающий его в контейнер, стоящий перед ним. -Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.=Выбрасыватель может быть установлен в 6 возможных направлениях, предметы будут выбрасываться в соответствующем направлении из отверстия. [Используйте] выбрасыватель для доступа к его инвентарю. Подайте на него энергию редстоуна однократно, чтобы заставить его выбросить либо предать один случайный предмет. +A dropper is a redstone component and a container with 9 inventory slots which, when supplied with redstone power, drops an item or puts it into a container in front of it.=Выбрасыватель это компонент редстоуна и контейнер с 9 слотами инвентаря, срабатывающий по сигналу редстоуна и выбрасывающий предмет, либо выталкивающий его в контейнер, стоящий перед ним. +Droppers can be placed in 6 possible directions, items will be dropped out of the hole. Use the dropper to access its inventory. Supply it with redstone energy once to make the dropper drop or transfer a random item.=Выбрасыватель может быть установлен в 6 возможных направлениях, предметы будут выбрасываться в соответствующем направлении из отверстия. Используйте выбрасыватель для доступа к его инвентарю. Подайте на него сигнал редстоуна однократно, чтобы заставить его выбросить либо передать один случайный предмет. Downwards-Facing Dropper=Выбрасыватель, смотрящий вниз Upwards-Facing Dropper=Выбрасыватель, смотрящий вверх Inventory=Инвентарь -9 inventory slots=9 отсеков инвентаря -Drops item when powered by redstone power=Выбрасывает предмет при подаче энергии редстоуна +9 inventory slots=9 слотов инвентаря +Drops item when powered by redstone power=Выбрасывает предмет при подаче сигнала редстоуна diff --git a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pt_BR.tr b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pt_BR.tr new file mode 100644 index 000000000..18e82eb11 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_observers +Observer=Observador +An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes.=Um observador é um componente de redstone o qual observa o bloco a sua frente e envia um pulso de redstone muito curto sempre que esse bloco mudar. +Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here.=Posicione o observador diretamente em frente ao bloco que você deseja observar com a "face" olhando para o bloco. A seta aponta para o lado da saída, a qual está no lado oposto da "face". Você pode posicionar seu pó de redstone ou outros componentes aqui. +Emits redstone pulse when block in front changes=Emite um pulso de redstone quando um bloco muda em sua frente diff --git a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ru.tr b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ru.tr index ac8c658c3..18df6aa72 100644 --- a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ru.tr +++ b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_observers Observer=Наблюдатель -An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes.=Наблюдатель это элемент редстоуна, который следит за блоком перед собой и посылает короткий импульс редстоуна, если этот блок меняется. -Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here.=Поместите наблюдателя прямо перед блоком, за которым хотите наблюдать, так, чтобы “лицо” смотрело на этот блок. Стрелка показывает выходную сторону, находящуюся на противоположной стороне от “лица”. Вы можете разместить там пыль редстоуна или любой другой компонент. -Emits redstone pulse when block in front changes=Генерирует импульс редстоуна при смене блока, находящегося перед ним +An observer is a redstone component which observes the block in front of it and sends a very short redstone pulse whenever this block changes.=Наблюдатель это компонент редстоуна, который следит за блоком перед собой и посылает короткий сигнал редстоуна, если этот блок меняется. +Place the observer directly in front of the block you want to observe with the “face” looking at the block. The arrow points to the side of the output, which is at the opposite side of the “face”. You can place your redstone dust or any other component here.=Поместите наблюдателя прямо перед блоком, за которым хотите наблюдать, так, чтобы “лицо” смотрело на этот блок. Стрелка показывает выход, находящийся на противоположной стороне от “лица”. Вы можете разместить там редстоун или любой другой компонент. +Emits redstone pulse when block in front changes=Генерирует сигнал редстоуна при изменении блока находящегося перед ним diff --git a/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.pt_BR.tr b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.pt_BR.tr new file mode 100644 index 000000000..877e89c82 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_target +Target=Alvo +A target is a block that provides a temporary redstone charge when hit by a projectile.=Um alvo é um bloco que fornece uma carga temporária de redstone quando atingido por um projétil. +Throw a projectile on the target to activate it.=Arremesse um projétil no alvo para ativá-lo. diff --git a/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ru.tr b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ru.tr new file mode 100644 index 000000000..c436211e3 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_target +Target=Мишень +A target is a block that provides a temporary redstone charge when hit by a projectile.=Мишень это блок который генерирует импульс сигнала редстоуна при попадании снаряда. +Throw a projectile on the target to activate it.=Попадите снарядом в мишень, чтобы активировать её. \ No newline at end of file diff --git a/mods/ITEMS/REDSTONE/mesecons/util.lua b/mods/ITEMS/REDSTONE/mesecons/util.lua index b6602526a..12dbc0240 100644 --- a/mods/ITEMS/REDSTONE/mesecons/util.lua +++ b/mods/ITEMS/REDSTONE/mesecons/util.lua @@ -246,6 +246,15 @@ function mesecon.mergetable(source, dest) return rval end +-- +function mesecon.join_table(t1, t2) + local rval = mesecon.tablecopy(t2) + for i, v in ipairs(t1) do + table.insert(rval, mesecon.tablecopy(v)) + end + return rval +end + function mesecon.register_node(name, spec_common, spec_off, spec_on) spec_common.drop = spec_common.drop or name .. "_off" spec_common.on_blast = spec_common.on_blast or mesecon.on_blastnode diff --git a/mods/ITEMS/REDSTONE/mesecons_button/README.md b/mods/ITEMS/REDSTONE/mesecons_button/README.md index 31a1fa9de..80802ec64 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/README.md +++ b/mods/ITEMS/REDSTONE/mesecons_button/README.md @@ -1,5 +1,5 @@ Mesecons button mod. -This mod adds the buttons for MineClone 2. +This mod adds the buttons for VoxeLibre. MEDIA FILE CREDITS: diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua index 275cac2e2..8e2159045 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_button/init.lua @@ -108,7 +108,7 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou 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.") 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 @@ -211,6 +211,11 @@ function mesecon.register_button(basename, description, texture, recipeitem, sou output = "mesecons_button:button_"..basename.."_off", recipe = {{ recipeitem }}, }) + + if minetest.get_modpath("mesecons_mvps") then + mesecon.register_mvps_unsticky("mesecons_button:button_"..basename.."_off") + mesecon.register_mvps_unsticky("mesecons_button:button_"..basename.."_on") + end end mesecon.register_button( diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr index 1d844bd36..7ccc763be 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr @@ -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é Push duration: @1s=Durée de poussée : @1s 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. diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pt_BR.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pt_BR.tr new file mode 100644 index 000000000..f7ec2dd59 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pt_BR.tr @@ -0,0 +1,20 @@ +# textdomain: mesecons_button +Use the button to push it.=Use o botão para pressioná-lo. +Stone Button=Botão de Pedra +A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Um botão de pedra é um componente de redstone feito de pedra ao qual pode ser pressionado para fornecer carga de redstone. Quando pressionado, irá energizar componentes de redstone adjacentes por 1 segundo. +Polished Blackstone Button=Botão de Rocha Negra Polida +A polished blackstone button is a redstone component made out of polished blackstone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Um botão de rocha negra polida é um componente de redstone feito de pedra negra polida ao qual pode ser pressionado para fornecer carga de redstone. Quando pressionado, irá energizar componentes de redstone adjacentes por 1 segundo. +Oak Button=Botão de Carvalho +Acacia Button=Botão de Acácia +Birch Button=Botão de Bétula +Dark Oak Button=Botão de Carvalho Escuro +Spruce Button=Botão de Pinheiro +Jungle Button=Botão da Selva +Mangrove Button=Botão de Mangue +Crimson Button=Botão de Hifas Carmesim +Warped Button=Botão de Hifas Distorcidas +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.=Um botão de madeira é um componente de redstone feito de madeira ao qual pode ser pressionado para fornecer carga de redstone. Quando pressionado, irá energizar componentes de redstone adjacentes por 1.5 segundo. Botões de madeira também podem ser pressionados por flechas. +Provides redstone power when pushed=Fornece carga de redstone quando é pressionado +Push duration: @1s=Duração de pressão: @1s +Pushable by arrow=Pressionável por flecha +A button is a redstone component which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for @1 seconds.=Um botão é um componente de redstone ao qual pode ser pressionado para fornecer carga de redstone. Quando pressionado, irá energizar componentes de redstone adjacentes por @1 segundos. diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ru.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ru.tr index a89c8098a..b66a7e892 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ru.tr @@ -1,14 +1,20 @@ # textdomain: mesecons_button -Use the button to push it.=[Используйте] кнопку, чтобы нажать её. +Use the button to push it.=Используйте кнопку, чтобы нажать её. Stone Button=Каменная кнопка -A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Каменная кнопка это элемент редстоуна, сделанный из камня, её можно нажать, чтобы получить энергию редстоуна. При нажатии она включает соседние элементы редстоуна на 1 секунду. +A stone button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Каменная кнопка это компонент редстоуна, сделанный из камня, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на 1 секунду. +Polished Blackstone Button=Кнопка из полированного чернокамня +A polished blackstone button is a redstone component made out of polished blackstone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Кнопка из полированного чернокамня это компонент редстоуна, сделанный из полированного чернокамня, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на 1 секунду. Oak Button=Дубовая кнопка Acacia Button=Акациевая кнопка Birch Button=Берёзовая кнопка Dark Oak Button=Кнопка из тёмного дуба Spruce Button=Еловая кнопка -Jungle Button=Кнопка из дерева джунглей -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.=Деревянная кнопка это элемент редстоуна, сделанный из дерева, её можно нажать, чтобы получить энергию редстоуна. При нажатии она включает соседние элементы редстоуна на полторы секунды. Деревянные кнопки можно также активировать стрелами. -Provides redstone power when pushed=Выдаёт энергию редстоуна при нажатии +Jungle Button=Кнопка из тропического дерева +Mangrove Button=Мангровая кнопка +Crimson Button=Багровая кнопка +Warped Button=Искажённая кнопка +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.=Деревянная кнопка это компонент редстоуна, сделанный из дерева, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на 1.5 с. Деревянные кнопки нажимаются от попадания стрелы. +Provides redstone power when pushed=Выдаёт сигнал редстоуна при нажатии Push duration: @1s=Длительность нажатия: @1с Pushable by arrow=Нажимается стрелами +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 с. diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt index d42a03741..68d10061a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt @@ -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= Push duration: @1s= 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.= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr index 938c710b9..2933f4fc4 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr @@ -1,7 +1,7 @@ # textdomain: mesecons_commandblock Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands.=Error: el comando "@1" no existe; su bloque de comando no ha sido cambiado. Utilice el comando de chat "help" para obtener una lista de los comandos disponibles. Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.=Error: el comando "@1" no existe; su bloque de comando no ha sido cambiado. Utilice el comando de chat "help" para obtener una lista de los comandos disponibles. Sugerencia: intente eliminar la barra diagonal inicial. -Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.=Error: ¡No tiene suficientes privilegios para usar el comando “@ 1” (faltan privilegios: @ 2)! El bloque de comando no ha sido cambiado. +Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.=Error: ¡No tiene suficientes privilegios para usar el comando “@1” (faltan privilegios: @2)! El bloque de comando no ha sido cambiado. Error: No commander! Block must be replaced.=Error: ¡Sin dueño! El bloque debe ser reemplazado. Commander: @1=Dueño: @1 Submit=Aceptar diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr index 85bed4b95..bbd0a262e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr @@ -1,30 +1,30 @@ # textdomain: mesecons_commandblock -Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands.=Ошибка: Команда “@1” не существует; ваш командный блок не был изменён. Используйте чат-команду “help” для поучения списка доступных команд. -Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.=Ошибка: Команда “@1” не существует; ваш командный блок не был изменён. Используйте чат-команду “help” для поучения списка доступных команд. Подсказка: Попробуйте убрать ведущий слэш. +Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands.=Ошибка: Команда “@1” не существует; ваш командный блок не был изменён. Используйте чат-команду “help” для получения списка доступных команд. +Error: The command “@1” does not exist; your command block has not been changed. Use the “help” chat command for a list of available commands. Hint: Try to remove the leading slash.=Ошибка: Команда “@1” не существует; ваш командный блок не был изменён. Используйте чат-команду “help” для получения списка доступных команд. Подсказка: Попробуйте убрать ведущий слэш. Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.=Ошибка: Вы не имеете привилегий для использования команды “@1” (отсутствует привилегия: @2)! Командный блок не был изменён. Error: No commander! Block must be replaced.=Ошибка: Нет командующего! Блок следует заменить. Commander: @1=Командующий: @1 -Submit=Отправить +Submit=Принять No commands.=Нет команд. Commands:=Команды: Help=Помощь Placement denied. You need the “maphack” privilege to place command blocks.=Установка запрещена. Для установки командных блоков нужно иметь привилегию “maphack”. Command Block=Командный блок -Command blocks are mighty redstone components which are able to alter reality itself. In other words, they cause the server to execute server commands when they are supplied with redstone power.=Командные блоки это мощнейшие компоненты редстоуна, способные изменять реальность сами по себе. Другими словами, они могут заставлять сервер выполнять серверные команды, если подать на них энергию редстоуна. -Everyone can activate a command block and look at its commands, but not everyone can edit and place them.=Каждый может активировать командный блок и увидеть его команды, но не все могут редактировать и устанавливать его. -To view the commands in a command block, use it. To activate the command block, just supply it with redstone power. This will execute the commands once. To execute the commands again, turn the redstone power off and on again.=Чтобы увидеть команды в командном блоке, [используйте] его. Чтобы активировать блок, просто подайте на него энергию редстоуна. При этом команды выполнятся однократно. Чтобы выполнить их вновь, выключите и снова включите энергию редстоуна. -To be able to place a command block and change the commands, you need to be in Creative Mode and must have the “maphack” privilege. A new command block does not have any commands and does nothing. Use the command block (in Creative Mode!) to edit its commands. Read the help entry “Advanced usage > Server Commands” to understand how commands work. Each line contains a single command. You enter them like you would in the console, but without the leading slash. The commands will be executed from top to bottom.=Чтобы иметь возможность устанавливать командные блоки и изменять их команды, вы должны находиться в творческом режиме и иметь привилегию “maphack”. Новый командный блок не содержит команд и ничего не делает. [Используйте] командный блок (в творческом режиме!) для редактирования его команд. Изучите справочную запись “Продвинутое использование > Серверные команды”, чтобы понять, как они работают. Каждая строка содержит одну команду. Вы вводите их так, как вводили бы в консоли, но без ведущих символов слэш. Команды выполняются сверху вниз. +Command blocks are mighty redstone components which are able to alter reality itself. In other words, they cause the server to execute server commands when they are supplied with redstone power.=Командные блоки это мощнейшие компоненты редстоуна, способные изменять саму реальность. Другими словами, они могут заставлять сервер выполнять серверные команды, если подать на них сигнал редстоуна. +Everyone can activate a command block and look at its commands, but not everyone can edit and place them.=Каждый может активировать командный блок и увидеть его команды, но не все могут ставить и редактировать его. +To view the commands in a command block, use it. To activate the command block, just supply it with redstone power. This will execute the commands once. To execute the commands again, turn the redstone power off and on again.=Чтобы просмотреть команды в командном блоке, используйте его. Чтобы активировать блок, просто подайте на него сигнал редстоуна. При этом команды выполнятся однократно. Чтобы выполнить их вновь, выключите и снова включите сигнал редстоуна. +To be able to place a command block and change the commands, you need to be in Creative Mode and must have the “maphack” privilege. A new command block does not have any commands and does nothing. Use the command block (in Creative Mode!) to edit its commands. Read the help entry “Advanced usage > Server Commands” to understand how commands work. Each line contains a single command. You enter them like you would in the console, but without the leading slash. The commands will be executed from top to bottom.=Чтобы иметь возможность устанавливать командные блоки и изменять их команды, вы должны находиться в творческом режиме и иметь привилегию “maphack”. Новый командный блок не содержит команд и ничего не делает. Используйте командный блок (в творческом режиме!) для редактирования его команд. Изучите справочную запись “Продвинутое использование > Серверные команды”, чтобы понять, как они работают. Каждая строка содержит одну команду. Вы вводите их так, как вводили бы в консоли, но без ведущих символов слэш. Команды выполняются сверху вниз. All commands will be executed on behalf of the player who placed the command block, as if the player typed in the commands. This player is said to be the “commander” of the block.=Все команды будут выполняться от имени игрока, разместившего командный блок, как будто если бы игрок сам их набирал. Этот игрок является так называемым “командиром” блока. -Command blocks support placeholders, insert one of these placeholders and they will be replaced by some other text:=Командные блоки поддерживаю шаблоны, вставляйте один из них - и они будут заменены на нужный вам текст: +Command blocks support placeholders, insert one of these placeholders and they will be replaced by some other text:=Командные блоки поддерживают шаблоны, вставляйте один из них - и они будут заменены на нужный вам текст: • “@@c”: commander of this command block=• “@@c”: командир данного командного блока • “@@n” or “@@p”: nearest player from the command block=• “@@n” или “@@p”: игрок, находящийся ближе всего к данному командному блоку • “@@f” farthest player from the command block=• “@@f” игрок, находящийся дальше всего от данного командного блока • “@@r”: random player currently in the world=• “@@r”: случайный игрок, в данный момент присутствующий в мире • “@@@@”: literal “@@” sign=• “@@@@”: если нужно использовать символ “@@” сам по себе -Example 1:@n time 12000@nSets the game clock to 12:00=Пример 1:@n time 12000@nУстанавливает игровые часы на 12:00 +Example 1:@n time 12000@nSets the game clock to 12:00=Пример 1:@n time 12000@nУстанавливает игровое время на 12:00 Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=Пример 2:@n give @@n mcl_core:apple 5@nДаёт ближайшему игроку 5 яблок Access denied. You need the “maphack” privilege to edit command blocks.=Доступ запрещён. Вам нужно иметь привилегию “maphack”, чтобы редактировать командные блоки. -Editing the command block has failed! You can only change the command block in Creative Mode!=Попытка редактирования командного блока потерпела неудачу. Вы можете изменять командные блоки только в творческом режиме! -Editing the command block has failed! The command block is gone.=Попытка редактирования командного блока потерпела неудачу. Командный блок исчез. -Executes server commands when powered by redstone power=При подаче энергии редстоуна выполняет серверные команды -Command blocks are not enabled on this server= +Editing the command block has failed! You can only change the command block in Creative Mode!=Попытка редактирования командного блока неудалась. Вы можете изменять командные блоки только в творческом режиме! +Editing the command block has failed! The command block is gone.=Попытка редактирования командного блока неудалась. Командный блок исчез. +Executes server commands when powered by redstone power=При подаче сигнала редстоуна выполняет серверные команды +Command blocks are not enabled on this server=Командные блоки отключены на этом сервере diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.pt_BR.tr b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.pt_BR.tr new file mode 100644 index 000000000..75af2b8b1 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.pt_BR.tr @@ -0,0 +1,13 @@ +# textdomain: mesecons_delayer +Redstone repeaters are versatile redstone components with multiple purposes: 1. They only allow signals to travel in one direction. 2. They delay the signal. 3. Optionally, they can lock their output in one state.=Repetidores de redstone são componentes de redstone versáteis com multíplos propósitos: 1. Eles apenas permitem que sinais viajem em uma direção. 2. Eles atrasam o sinal. 3. Opcionalmente, eles podem travar suas saídas em um estado. +To power a redstone repeater, send a signal in “arrow” direction (the input). The signal goes out on the opposite side (the output) with a delay. To change the delay, use the redstone repeater. The delay is between 0.1 and 0.4 seconds long and can be changed in steps of 0.1 seconds. It is indicated by the position of the moving redstone torch.=Para energizar um repetidor de redstone, envie um sinal na direção da "seta" (a entrada). O sinal sairá no lado oposto (a saída) com um atraso. Para mudar o atraso, use o repetidor de redstone. O atraso é entre 0.1 e 0.4 segundos de duração e podem ser mudados em passos de 0.1 segundo. É indicado pela posição da tocha tocha de redstone móvel. +To lock a repeater, send a signal from an adjacent repeater into one of its sides. While locked, the moving redstone torch disappears, the output doesn't change and the input signal is ignored.=Para travar um repetidor, envie um sinal de um repetidor adjacente para uma de suas laterais. Enquanto travado, a tocha de redstone móvel desaparece, a saída não muda e o sinal de entrada é ignorado. +Redstone Repeater=Repetidor de Redstone +Redstone Repeater (Powered)=Repetidor de Redstone (Energizado) +Redstone Repeater (Locked)=Repetidor de Redstone (Travado) +Redstone Repeater (Locked, Powered)=Repetidor de Redstone (Travado, Energizado) +Redstone Repeater (Delay @1)=Repetidor de Redstone (Atraso @1) +Redstone Repeater (Delay @1, Powered)=Repetidor de Redstone (Atraso @1, Energizado) +Transmits redstone power only in one direction=Transmite carga de redstone em apenas uma direção +Delays signal=Atrasa o sinal +Output locks when getting active redstone repeater signal from the side=A saída é travada quando estiver recebendo um sinal de um repetidor de redstone ativo pelas laterais diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ru.tr b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ru.tr index f95d3ee8e..3a6570c98 100644 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ru.tr @@ -1,13 +1,13 @@ # textdomain: mesecons_delayer Redstone repeaters are versatile redstone components with multiple purposes: 1. They only allow signals to travel in one direction. 2. They delay the signal. 3. Optionally, they can lock their output in one state.=Повторители это универсальные компоненты, выполняющие много задач: 1. Разрешают сигналам проходить только в одном направлении. 2. Задерживают сигнал. 3. Опционально они могут зафиксировать свой выходной сигнал в одном состоянии. -To power a redstone repeater, send a signal in “arrow” direction (the input). The signal goes out on the opposite side (the output) with a delay. To change the delay, use the redstone repeater. The delay is between 0.1 and 0.4 seconds long and can be changed in steps of 0.1 seconds. It is indicated by the position of the moving redstone torch.=Чтобы подключить повторитель, подайте сигнал в направлении “стрелки” (на вход). Сигнал выйдет с противоположной стороны (с выхода) с задержкой. Чтобы изменить задержку, [используйте] повторитель. Время задержки лежит между 0.1 и 0.4 секунды и может изменяться с шагом 0.1 секунды. Его отражает положение передвигающегося факела редстоуна. +To power a redstone repeater, send a signal in “arrow” direction (the input). The signal goes out on the opposite side (the output) with a delay. To change the delay, use the redstone repeater. The delay is between 0.1 and 0.4 seconds long and can be changed in steps of 0.1 seconds. It is indicated by the position of the moving redstone torch.=Чтобы подключить повторитель, подайте сигнал на вход в направлении “стрелки”. Сигнал выйдет с противоположной стороны с задержкой. Чтобы изменить задержку, используйте повторитель. Время задержки изменяется от 0.1 до 0.4 секунды и может изменяться с шагом 0.1 секунды. Время задержки отражает положение передвигающегося факела редстоуна. To lock a repeater, send a signal from an adjacent repeater into one of its sides. While locked, the moving redstone torch disappears, the output doesn't change and the input signal is ignored.=Чтобы зафиксировать повторитель, подайте сигнал от соседнего повторителя на одну из его сторон. При фиксации передвижной факел редстоуна исчезает, выходной сигнал не меняется, а входной сигнал игнорируется. Redstone Repeater=Повторитель Redstone Repeater (Powered)=Повторитель (подключённый) -Redstone Repeater (Locked)=Повторитель (зафиксированный) -Redstone Repeater (Locked, Powered)=Повторитель (зафиксированный, подключённый) +Redstone Repeater (Locked)=Повторитель (фиксированный) +Redstone Repeater (Locked, Powered)=Повторитель (фиксированный, подключённый) Redstone Repeater (Delay @1)=Повторитель (задержка @1) Redstone Repeater (Delay @1, Powered)=Повторитель (задержка @1, подключённый) -Transmits redstone power only in one direction=Передаёт энергию редстоуна только в одном направлении +Transmits redstone power only in one direction=Передаёт сигнал редстоуна только в одном направлении Delays signal=Задерживает сигнал Output locks when getting active redstone repeater signal from the side=Выход фиксируется при наличии активного сигнала сбоку diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua b/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua index 0e517e4dc..0e0235642 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua @@ -2,7 +2,24 @@ local S = minetest.get_translator(minetest.get_current_modname()) local light = minetest.LIGHT_MAX -minetest.register_node("mesecons_lightstone:lightstone_off", { +local function generate_action_on(color) + local n = "mesecons_lightstone:lightstone_on" + if color then n = n .. "_" .. color end + return function(pos, node) + minetest.swap_node(pos, {name=n, param2 = node.param2}) + end +end + +local function generate_action_off(color) + local n = "mesecons_lightstone:lightstone_off" + if color then n = n .. "_" .. color end + return function(pos, node) + minetest.swap_node(pos, {name=n, param2 = node.param2}) + end +end + +local ls_off_name = "mesecons_lightstone:lightstone_off" +local ls_off_def = { tiles = {"jeija_lightstone_gray_off.png"}, groups = {handy=1, mesecon_effector_off = 1, mesecon = 2}, is_ground_content = false, @@ -11,16 +28,16 @@ minetest.register_node("mesecons_lightstone:lightstone_off", { _doc_items_longdesc = S("Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.", light), sounds = mcl_sounds.node_sound_glass_defaults(), mesecons = {effector = { - action_on = function(pos, node) - minetest.swap_node(pos, {name="mesecons_lightstone:lightstone_on", param2 = node.param2}) - end, + action_on = generate_action_on(), rules = mesecon.rules.alldirs, }}, _mcl_blast_resistance = 0.3, _mcl_hardness = 0.3, -}) +} +minetest.register_node(ls_off_name, ls_off_def) -minetest.register_node("mesecons_lightstone:lightstone_on", { +local ls_on_name = "mesecons_lightstone:lightstone_on" +local ls_on_def = { tiles = {"jeija_lightstone_gray_on.png"}, groups = {handy=1, not_in_creative_inventory=1, mesecon = 2, opaque = 1}, drop = "node mesecons_lightstone:lightstone_off", @@ -29,14 +46,59 @@ minetest.register_node("mesecons_lightstone:lightstone_on", { light_source = light, sounds = mcl_sounds.node_sound_glass_defaults(), mesecons = {effector = { - action_off = function(pos, node) - minetest.swap_node(pos, {name="mesecons_lightstone:lightstone_off", param2 = node.param2}) - end, + action_off = generate_action_off(), rules = mesecon.rules.alldirs, }}, _mcl_blast_resistance = 0.3, _mcl_hardness = 0.3, -}) +} +minetest.register_node(ls_on_name, ls_on_def) + +local colored_lamps = { + {"white", S("White Redstone Lamp"), "white"}, + {"grey", S("Grey Redstone Lamp"), "dark_grey"}, + {"silver", S("Light Grey Redstone Lamp"), "grey"}, + {"black", S("Black Redstone Lamp"), "black"}, + {"red", S("Red Redstone Lamp"), "red"}, + {"yellow", S("Yellow Redstone Lamp"), "yellow"}, + {"green", S("Green Redstone Lamp"), "dark_green"}, + {"cyan", S("Cyan Redstone Lamp"), "cyan"}, + {"blue", S("Blue Redstone Lamp"), "blue"}, + {"magenta", S("Magenta Redstone Lamp"), "magenta"}, + {"orange", S("Orange Redstone Lamp"), "orange"}, + {"purple", S("Purple Redstone Lamp"), "violet"}, + {"brown", S("Brown Redstone Lamp"), "brown"}, + {"pink", S("Pink Redstone Lamp"), "pink"}, + {"lime", S("Lime Redstone Lamp"), "green"}, + {"lightblue", S("Light Blue Redstone Lamp"), "lightblue"}, +} +for _, row in ipairs(colored_lamps) do + local name = row[1] + local desc = row[2] + local dye = row[3] + local mask = "^[hsl:0:-100^(mcl_lightstone_mask.png^[multiply:" .. name .. "^[opacity:100)" + if name == "lightblue" then + mask = "^[hsl:0:-100^(mcl_lightstone_mask.png^[multiply:" .. name .. "^[hsl:0:200^[opacity:100)" + end + local name_off = ls_off_name .. "_" .. name + local def_off = table.copy(ls_off_def) + def_off.description = desc + def_off._doc_items_longdesc = nil + def_off._doc_items_create_entry = false + def_off.mesecons.effector.action_on = generate_action_on(name) + def_off.tiles[1] = def_off.tiles[1] .. mask + local def_on = table.copy(ls_on_def) + def_on.drop = name_off + def_on.tiles[1] = def_on.tiles[1] .. mask + def_on.mesecons.effector.action_off = generate_action_off(name) + minetest.register_node(name_off, def_off) + minetest.register_node(ls_on_name.."_"..name, def_on) + minetest.register_craft({ + type = "shapeless", + output = name_off, + recipe = {ls_off_name, "mcl_dye:" .. dye} + }) +end minetest.register_craft({ output = "mesecons_lightstone:lightstone_off", diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.de.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.de.tr index a0cfc2213..1b0407d1a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.de.tr +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.de.tr @@ -2,3 +2,19 @@ Redstone Lamp=Redstonelampe Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Redstonelampen sind einfache Redstonekomponenten, die hell aufleuchten (Helligkeitspegel von @1), wenn sie Redstoneenergie erhalten. Glows when powered by redstone power=Leuchtet, wenn mit Redstoneenergie versorgt +White Redstone Lamp=Weiße Redstonelampe +Grey Redstone Lamp=Graue Redstonelampe +Light Grey Redstone Lamp=Hellgraue Redstonelampe +Black Redstone Lamp=Schwartze Redstonelampe +Red Redstone Lamp=Rote Redstonelampe +Yellow Redstone Lamp=Gelbe Redstonelampe +Green Redstone Lamp=Grüne Redstonelampe +Cyan Redstone Lamp=Türkise Redstonelampe +Blue Redstone Lamp=Blaue Redstonelampe +Magenta Redstone Lamp=Magenta Redstonelampe +Orange Redstone Lamp=Orange Redstonelampe +Purple Redstone Lamp=Violette Redstonelampe +Brown Redstone Lamp=Braune Redstonelampe +Pink Redstone Lamp=Rosa Redstonelampe +Lime Redstone Lamp=Lindgrüne Redstonelampe +Light Blue Redstone Lamp=Hellblaue Redstonelampe diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.es.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.es.tr index 713f0be5e..f2a47d3ac 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.es.tr @@ -1,3 +1,4 @@ # textdomain: mesecons_lightstone Redstone Lamp=Lámpara de redstone -Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Las lámparas Redstone son componentes simples de redstone que brillan intensamente (nivel de luz @ 1) cuando reciben energía de redstone. +Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Las lámparas de redstone son componentes simples de redstone que brillan intensamente (nivel de luz @1) cuando reciben energía de redstone. +Glows when powered by redstone power=Brilla cuando recibe energía de redstone diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr index cd2f755c9..99d01bb07 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr @@ -2,3 +2,19 @@ Redstone Lamp=Lampa czerwienitowa Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Lampy czerwienitowe to mechanizmy czerwienitowe, które jasno świecą (poziom światła @1), gdy są zasilone energią czerwienitową. Glows when powered by redstone power=Świeci gdy zasilana czerwienitem +White Redstone Lamp=Biała lampa czerwienitowa +Grey Redstone Lamp=Szara lampa czerwienitowa +Light Grey Redstone Lamp=Jasnoszara lampa czerwienitowa +Black Redstone Lamp=Czarna lampa czerwienitowa +Red Redstone Lamp=Czerwona lampa czerwienitowa +Yellow Redstone Lamp=Żółta lampa czerwienitowa +Green Redstone Lamp=Zielona lampa czerwienitowa +Cyan Redstone Lamp=Błękitna lampa czerwienitowa +Blue Redstone Lamp=Niebieska lampa czerwienitowa +Magenta Redstone Lamp=Karmazynowa lampa czerwienitowa +Orange Redstone Lamp=Pomarańczowa lampa czerwienitowa +Purple Redstone Lamp=Fioletowa lampa czerwienitowa +Brown Redstone Lamp=Brązowa lampa czerwienitowa +Pink Redstone Lamp=Różowa lampa czerwienitowa +Lime Redstone Lamp=Jasnozielona lampa czerwienitowa +Light Blue Redstone Lamp=Jasnoniebieska lampa czerwienitowa diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pt_BR.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pt_BR.tr new file mode 100644 index 000000000..8d3c8a0fd --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mesecons_lightstone +Redstone Lamp=Lâmpada de Redstone +Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Lâmpadas de redstone são componentes de redstone simples ao qual brilha intensamente (nível de brilho @1) quando recebe carga de redstone. +Glows when powered by redstone power=Bliha quando energizada com carga de redstone diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ru.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ru.tr index cd1592a28..104b2fc7d 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ru.tr @@ -1,4 +1,4 @@ # textdomain: mesecons_lightstone -Redstone Lamp=Лампа редстоуна -Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Лампа редстоуна это простой компонент редстоуна, который ярко светится (уровень света @1) при подаче на него энергии редстоуна. -Glows when powered by redstone power=Светит при подаче энергии редстоуна +Redstone Lamp=Лампа +Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.=Лампа это простой компонент редстоуна, который ярко светится (уровень света @1) при подаче на него сигнала редстоуна. +Glows when powered by redstone power=Светится при подаче сигнала редстоуна diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/template.txt index 2d2cc419f..0d743daa4 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/template.txt @@ -2,3 +2,19 @@ Redstone Lamp= Redstone lamps are simple redstone components which glow brightly (light level @1) when they receive redstone power.= Glows when powered by redstone power= +White Redstone Lamp= +Grey Redstone Lamp= +Light Grey Redstone Lamp= +Black Redstone Lamp= +Red Redstone Lamp= +Yellow Redstone Lamp= +Green Redstone Lamp= +Cyan Redstone Lamp= +Blue Redstone Lamp= +Magenta Redstone Lamp= +Orange Redstone Lamp= +Purple Redstone Lamp= +Brown Redstone Lamp= +Pink Redstone Lamp= +Lime Redstone Lamp= +Light Blue Redstone Lamp= diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index 663d0f727..1d2e7820d 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -117,7 +117,7 @@ local function is_available(pos) return false, n end if minetest.registered_nodes[name] then - return minetest.registered_nodes[name].buildable_to, n or false, n + return minetest.registered_nodes[name].buildable_to or minetest.get_item_group(name, "dig_by_piston") == 1, n or false, n end return false, n end @@ -126,6 +126,7 @@ end function mesecon.mvps_get_stack(pos, dir, maximum, piston_pos) -- determine the number of nodes to be pushed local nodes = {} + local dig_nodes = {} local frontiers = {pos} while #frontiers > 0 do @@ -140,47 +141,50 @@ function mesecon.mvps_get_stack(pos, dir, maximum, piston_pos) return end - if not node_replaceable(nn.name) then - if #nodes >= maximum then return nil, false end - table.insert(nodes, {node = nn, pos = {x=np.x, y=np.y, z=np.z}}) - - -- add connected nodes to frontiers, connected is a vector list - -- the vectors must be absolute positions - local connected = {} - local has_loop - if minetest.registered_nodes[nn.name] - and minetest.registered_nodes[nn.name].mvps_sticky then - connected, has_loop = minetest.registered_nodes[nn.name].mvps_sticky(np, nn, piston_pos) - if has_loop then - return {}, true - end - end - - table.insert(connected, vector.add(np, dir)) - - -- Make sure there are no duplicates in frontiers / nodes before - -- adding nodes in "connected" to frontiers - for _, cp in ipairs(connected) do - local duplicate = false - for _, rp in ipairs(nodes) do - if vector.equals(cp, rp.pos) then - duplicate = true + if minetest.get_item_group(nn.name, "dig_by_piston") == 1 then + -- if we want the node to drop, e.g. sugar cane, do not count towards push limit + table.insert(dig_nodes, {node = nn, pos = {x=np.x, y=np.y, z=np.z}}) + else + if not node_replaceable(nn.name) then + table.insert(nodes, {node = nn, pos = {x=np.x, y=np.y, z=np.z}}) + if #nodes > maximum then return nil, nil, false, true end + + -- add connected nodes to frontiers, connected is a vector list + -- the vectors must be absolute positions + local connected = {} + local has_loop + if minetest.registered_nodes[nn.name] and minetest.registered_nodes[nn.name].mvps_sticky then + connected, has_loop = minetest.registered_nodes[nn.name].mvps_sticky(np, nn, piston_pos) + if has_loop then + return {}, {}, true, false end end - for _, fp in ipairs(frontiers) do - if vector.equals(cp, fp) then - duplicate = true + table.insert(connected, vector.add(np, dir)) + + -- Make sure there are no duplicates in frontiers / nodes before + -- adding nodes in "connected" to frontiers + for _, cp in ipairs(connected) do + local duplicate = false + for _, rp in ipairs(nodes) do + if vector.equals(cp, rp.pos) then + duplicate = true + end + end + for _, fp in ipairs(frontiers) do + if vector.equals(cp, fp) then + duplicate = true + end + end + if not duplicate and not mesecon.is_mvps_stopper(minetest.get_node(cp)) and minetest.get_item_group(nn.name, "dig_by_piston") == 0 then + table.insert(frontiers, cp) end - end - if not duplicate and not mesecon.is_mvps_stopper(minetest.get_node(cp)) then - table.insert(frontiers, cp) end end end table.remove(frontiers, 1) end - return nodes, false + return nodes, dig_nodes, false, false end function mesecon.mvps_set_owner(pos, placer) @@ -203,6 +207,11 @@ local function are_protected(nodes, player_name) end function mesecon.mvps_push(pos, dir, maximum, player_name, piston_pos) + -- check if the node in front of the piston is protected against player_name (to prevent replacing air) + if minetest.is_protected(pos, player_name) then + return false + end + return mesecon.mvps_push_or_pull(pos, dir, dir, maximum, player_name, piston_pos) end @@ -222,9 +231,9 @@ end -- movedir: direction of actual movement -- maximum: maximum nodes to be pushed function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, piston_pos) - local nodes, has_loop = mesecon.mvps_get_stack(pos, movedir, maximum, piston_pos) + local nodes, dig_nodes, has_loop, too_many = mesecon.mvps_get_stack(pos, movedir, maximum, piston_pos) - if has_loop then + if has_loop or too_many then return false end @@ -237,6 +246,9 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, if (newpos[i].x == piston_pos.x) and (newpos[i].y == piston_pos.y) and (newpos[i].z == piston_pos.z) then return end + if minetest.is_protected(newpos[i], player_name) then + return + end if not is_available(newpos[i]) then local available = false for j in ipairs(nodes) do @@ -253,18 +265,35 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, end end - if are_protected(nodes, player_name) then + local all_nodes = nodes + if dig_nodes and #dig_nodes > 0 then all_nodes = mesecon.join_table(dig_nodes, nodes) end + if are_protected(all_nodes, player_name) then return end local first_dropper = nil -- remove all nodes - for id, n in ipairs(nodes) do + for id, n in ipairs(all_nodes) do n.meta = minetest.get_meta(n.pos):to_table() - local is_dropper = mesecon.is_mvps_dropper(n.node, movedir, nodes, id) + local is_dropper = mesecon.is_mvps_dropper(n.node, movedir, all_nodes, id) if is_dropper then - --local drops = minetest.get_node_drops(n.node.name, "") - minetest.dig_node(n.pos) + -- if current node has already been destroyed (e.g. chain reaction of sugar cane breaking), skip it + if minetest.get_node(n.pos).name == n.node.name then + -- simulate dig_node using handle_node_drops + local drops = minetest.get_node_drops(n.node.name, "") + local counted_drops = {} + minetest.remove_node(n.pos) + for _, callback in pairs(minetest.registered_on_dignodes) do + callback(n.pos, n.node) + end + for _, item in ipairs(drops) do + if type(item) ~= "string" then + item = item:get_name() .. item:get_count() + end + table.insert(counted_drops, item) + end + minetest.handle_node_drops(n.pos, counted_drops) + end else minetest.remove_node(n.pos) local node_timer = minetest.get_node_timer(n.pos) @@ -273,13 +302,13 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, end end if is_dropper then - first_dropper = id - break + -- get id of the first dropper, but we still let everything else drop, so don't break here + if not first_dropper then first_dropper = id end end end -- update mesecons for removed nodes ( has to be done after all nodes have been removed ) - for id, n in ipairs(nodes) do + for id, n in ipairs(all_nodes) do if first_dropper and id >= first_dropper then break end @@ -287,7 +316,7 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, end -- add nodes - for id, n in ipairs(nodes) do + for id, n in ipairs(all_nodes) do if first_dropper and id >= first_dropper then break end @@ -394,6 +423,7 @@ mesecon.register_mvps_stopper("mcl_core:realm_barrier") mesecon.register_mvps_stopper("mcl_core:void") mesecon.register_mvps_stopper("mcl_core:bedrock") mesecon.register_mvps_stopper("mcl_core:obsidian") +mesecon.register_mvps_stopper("mcl_core:crying_obsidian") mesecon.register_mvps_stopper("mcl_chests:ender_chest") mesecon.register_mvps_stopper("mcl_chests:ender_chest_small") mesecon.register_mvps_stopper("mcl_mobspawners:spawner") @@ -411,6 +441,9 @@ mesecon.register_mvps_stopper("mesecons_solarpanel:solar_panel_inverted_on") mesecon.register_mvps_stopper("mesecons_solarpanel:solar_panel_inverted_off") mesecon.register_mvps_stopper("mcl_banners:hanging_banner") mesecon.register_mvps_stopper("mcl_banners:standing_banner") +mesecon.register_mvps_stopper("mcl_beehives:bee_nest") +mesecon.register_mvps_stopper("mcl_beehives:beehive") +mesecon.register_mvps_stopper("mcl_compass:lodestone") -- Unmovable by technical restrictions. -- Open formspec would screw up if node is destroyed (minor problem) @@ -441,13 +474,14 @@ mesecon.register_mvps_stopper("mcl_chests:trapped_chest") mesecon.register_mvps_stopper("mcl_chests:trapped_chest_small") mesecon.register_mvps_stopper("mcl_chests:trapped_chest_left") mesecon.register_mvps_stopper("mcl_chests:trapped_chest_right") -mesecon.register_mvps_stopper("mcl_signs:wall_sign") -mesecon.register_mvps_stopper("mcl_signs:standing_sign") -mesecon.register_mvps_stopper("mcl_signs:standing_sign22_5") -mesecon.register_mvps_stopper("mcl_signs:standing_sign45") -mesecon.register_mvps_stopper("mcl_signs:standing_sign67_5") mesecon.register_mvps_stopper("mcl_barrels:barrel_open") mesecon.register_mvps_stopper("mcl_barrels:barrel_closed") +mesecon.register_mvps_stopper("mcl_campfires:campfire") +mesecon.register_mvps_stopper("mcl_campfires:campfire_lit") +mesecon.register_mvps_stopper("mcl_campfires:soul_campfire") +mesecon.register_mvps_stopper("mcl_campfires:soul_campfire_lit") +mesecon.register_mvps_stopper("mcl_lectern:lectern") +mesecon.register_mvps_stopper("mcl_grindstone:grindstone") -- Unmovable by design: objects @@ -491,8 +525,6 @@ mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_2") mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_3") mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_door") -mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_trapdoor") -mesecon.register_mvps_unsticky("mcl_signs:wall_sign_bamboo") mesecon.register_mvps_unsticky("mcl_bamboo:scaffolding") -- Beds @@ -528,21 +560,6 @@ mesecon.register_mvps_unsticky("mcl_beds:bed_white_top") mesecon.register_mvps_unsticky("mcl_beds:bed_white_bottom") mesecon.register_mvps_unsticky("mcl_beds:bed_yellow_top") mesecon.register_mvps_unsticky("mcl_beds:bed_yellow_bottom") --- Buttons -mesecon.register_mvps_unsticky("mesecons_button:button_stone_off") -mesecon.register_mvps_unsticky("mesecons_button:button_stone_on") -mesecon.register_mvps_unsticky("mesecons_button:button_wood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_wood_on") -mesecon.register_mvps_unsticky("mesecons_button:button_acaciawood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_acaciawood_on") -mesecon.register_mvps_unsticky("mesecons_button:button_birchwood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_birchwood_on") -mesecon.register_mvps_unsticky("mesecons_button:button_darkwood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_darkwood_on") -mesecon.register_mvps_unsticky("mesecons_button:button_sprucewood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_sprucewood_on") -mesecon.register_mvps_unsticky("mesecons_button:button_junglewood_off") -mesecon.register_mvps_unsticky("mesecons_button:button_junglewood_on") -- Cactus, Sugarcane & Vines mesecon.register_mvps_unsticky("mcl_core:cactus") mesecon.register_mvps_unsticky("mcl_core:reeds") @@ -555,23 +572,6 @@ mesecon.register_mvps_unsticky("mcl_cake:cake_4") mesecon.register_mvps_unsticky("mcl_cake:cake_5") mesecon.register_mvps_unsticky("mcl_cake:cake_6") mesecon.register_mvps_unsticky("mcl_cake:cake") --- Carpet -mesecon.register_mvps_unsticky("mcl_wool:black_carpet") -mesecon.register_mvps_unsticky("mcl_wool:blue_carpet") -mesecon.register_mvps_unsticky("mcl_wool:brown_carpet") -mesecon.register_mvps_unsticky("mcl_wool:cyan_carpet") -mesecon.register_mvps_unsticky("mcl_wool:green_carpet") -mesecon.register_mvps_unsticky("mcl_wool:grey_carpet") -mesecon.register_mvps_unsticky("mcl_wool:light_blue_carpet") -mesecon.register_mvps_unsticky("mcl_wool:lime_carpet") -mesecon.register_mvps_unsticky("mcl_wool:orange_carpet") -mesecon.register_mvps_unsticky("mcl_wool:magenta_carpet") -mesecon.register_mvps_unsticky("mcl_wool:pink_carpet") -mesecon.register_mvps_unsticky("mcl_wool:purple_carpet") -mesecon.register_mvps_unsticky("mcl_wool:red_carpet") -mesecon.register_mvps_unsticky("mcl_wool:silver_carpet") -mesecon.register_mvps_unsticky("mcl_wool:white_carpet") -mesecon.register_mvps_unsticky("mcl_wool:yellow_carpet") -- Carved & Jack O'Lantern Pumpkins, Pumpkin & Melon mesecon.register_mvps_unsticky("mcl_farming:pumpkin_face") mesecon.register_mvps_unsticky("mcl_farming:pumpkin_face_light") @@ -661,7 +661,7 @@ mesecon.register_mvps_unsticky("mcl_flowers:tulip_red") mesecon.register_mvps_unsticky("mcl_flowers:tulip_white") mesecon.register_mvps_unsticky("mcl_flowers:waterlily") -- Heads -mesecon.register_mvps_unsticky("mcl_heads:creeper") +mesecon.register_mvps_unsticky("mcl_heads:stalker") mesecon.register_mvps_unsticky("mcl_heads:skeleton") mesecon.register_mvps_unsticky("mcl_heads:steve") mesecon.register_mvps_unsticky("mcl_heads:wither_skeleton") @@ -903,16 +903,16 @@ mesecon.register_mvps_unsticky("mcl_chests:black_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:blue_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:brown_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:cyan_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:dark_green_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:dark_grey_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:lightblue_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:green_shulker_box_small") -mesecon.register_mvps_unsticky("mcl_chests:grey_shulker_box_small") -mesecon.register_mvps_unsticky("mcl_chests:light_blue_shulker_box_small") -mesecon.register_mvps_unsticky("mcl_chests:lime_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:orange_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:magenta_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:pink_shulker_box_small") -mesecon.register_mvps_unsticky("mcl_chests:purple_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:violet_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:red_shulker_box_small") -mesecon.register_mvps_unsticky("mcl_chests:silver_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:grey_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:white_shulker_box_small") mesecon.register_mvps_unsticky("mcl_chests:yellow_shulker_box_small") -- Snow @@ -935,6 +935,11 @@ mesecon.register_mvps_unsticky("mcl_farming:wheat_4") mesecon.register_mvps_unsticky("mcl_farming:wheat_5") mesecon.register_mvps_unsticky("mcl_farming:wheat_6") mesecon.register_mvps_unsticky("mcl_farming:wheat_7") +-- Campfires +mesecon.register_mvps_unsticky("mcl_campfires:campfire") +mesecon.register_mvps_unsticky("mcl_campfires:campfire_lit") +mesecon.register_mvps_unsticky("mcl_campfires:soul_campfire") +mesecon.register_mvps_unsticky("mcl_campfires:soul_campfire_lit") -- Includes node heat when moving them mesecon.register_on_mvps_move(mesecon.move_hot_nodes) diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua b/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua index ac56d8bc5..b841545b3 100644 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua @@ -152,8 +152,6 @@ function mesecon.noteblock_play(pos, param2) soundname="mesecons_noteblock_xylophone_metal" elseif block_below_name == "mcl_nether:soul_sand" then 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 soundname="mesecons_noteblock_squarewave" elseif block_below_name == "mcl_farming:hay_block" then @@ -162,6 +160,8 @@ function mesecon.noteblock_play(pos, param2) soundname="mesecons_noteblock_piano_digital" elseif minetest.get_item_group(block_below_name, "wool") ~= 0 then 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 soundname="mesecons_noteblock_hit" elseif minetest.get_item_group(block_below_name, "material_wood") ~= 0 then diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ru.tr b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ru.tr index fbac4366f..35c44abae 100644 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ru.tr @@ -1,22 +1,22 @@ # textdomain: mesecons_noteblock Note Block=Нотный блок -A note block is a musical block which plays one of many musical notes and different intruments when it is punched or supplied with redstone power.=Нотный блок это музыкальный блок, который при ударе, а также при подаче энергии редстоуна проигрывает одну из множества музыкальных нот различными инструментами. -Use the note block to choose the next musical note (there are 25 semitones, or 2 octaves). The intrument played depends on the material of the block below the note block:=[Используйте] нотный блок, чтобы выбрать следующую ноту (всего предусмотрено 25 полутонов или 2 октавы). Проигрываемый инструмент зависит от материала, который находится непосредственно под нотным блоком. +A note block is a musical block which plays one of many musical notes and different intruments when it is punched or supplied with redstone power.=Нотный блок это музыкальный блок, который при ударе или при подаче сигнала редстоуна проигрывает одну из множества музыкальных нот различными инструментами. +Use the note block to choose the next musical note (there are 25 semitones, or 2 octaves). The intrument played depends on the material of the block below the note block:=Используйте нотный блок, чтобы выбрать следующую ноту (всего предусмотрено 25 полутонов или 2 октавы). Проигрываемый инструмент зависит от материала, который находится непосредственно под нотным блоком. • Glass: Sticks=• Стекло: палочки -• Wood: Bass guitar=• Дерево: бас-гитара -• Stone: Bass drum=• Камень: бочка -• Sand or gravel: Snare drum=• Песок или гравий: барабан +• Wood: Bass guitar=• Древесина: бас-гитара +• Stone: Bass drum=• Камень: большой барабан +• Sand or gravel: Snare drum=• Песок или гравий: малый барабан • Anything else: Piano=• Что-либо другое: фортепиано • Block of Gold: Bell=• Золотой блок: колокол -• Clay: Flute=• Глина: флейта -• Packed Ice: Chime=• Упакованный лёд: звон +• Clay: Flute=• Блок глины: флейта +• Packed Ice: Chime=• Плотный лёд: звон • Wool: Guitar=• Шерсть: гитара • Bone Block: Xylophne=• Костный блок: ксилофон -• Block of Iron: Iron xylophne=• Железный блок: металлофон +• Block of Iron: Iron xylophne=• Железный блок: металлический ксилофон • Soul Sand: Cow bell=• Песок душ: колокольчик • Pumpkin: Didgeridoo=• Тыква: диджериду • Block of Emerald: Square wave=• Изумрудный блок: прямоугольный сигнал • Hay Bale: Banjo=• Стог сена: банджо -• Glowstone: Electric piano=• Электронное фортепиано -The note block will only play a note when it is below air, otherwise, it stays silent.=Нотный блок проигрывает ноту только когда над ним имеется воздух, в противном случае он остаётся тихим. -Plays a musical note when powered by redstone power=Проигрывает ноту при подключении энергии редстоуна +• Glowstone: Electric piano=• Светокамень: электронное фортепиано +The note block will only play a note when it is below air, otherwise, it stays silent.=Нотный блок проигрывает ноту только когда над ним имеется воздух, в противном случае он звука не издает. +Plays a musical note when powered by redstone power=Проигрывает ноту от сигнала редстоуна diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua index 93b8df96d..262ac6eb5 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua @@ -138,14 +138,12 @@ local function piston_off(pos, node) end local function piston_orientate(pos, placer) - mesecon.mvps_set_owner(pos, placer) - -- not placed by player if not placer then return end - + -- placer pitch in degrees local pitch = placer:get_look_vertical() * (180 / math.pi) - + local node = minetest.get_node(pos) local pistonspec = minetest.registered_nodes[node.name].mesecons_piston if pitch > 55 then @@ -153,6 +151,9 @@ local function piston_orientate(pos, placer) elseif pitch < -55 then minetest.add_node(pos, {name=pistonspec.piston_down}) end + + -- set owner meta after setting node, or it will not keep + mesecon.mvps_set_owner(pos, placer) end diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ru.tr b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ru.tr index d69542e79..2f108ac3e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ru.tr @@ -1,8 +1,8 @@ # textdomain: mesecons_pistons -This block can have one of 6 possible orientations.=Этот блок быть ориентирован в одном из 6 возможных направлений. +This block can have one of 6 possible orientations.=Этот блок быть повёрнут в одном из 6 возможных направлений. Piston=Поршень -A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Поршень это компонент редстоуна с толкателем, который толкает блок или блоки перед собой при подаче энергии редстоуна. Следует отметить, что не все блоки могут быть сдвинуты. +A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Поршень это компонент редстоуна с толкателем, который толкает блок или блоки перед собой при подаче сигнала редстоуна. Следует отметить, что не все блоки могут быть сдвинуты. Sticky Piston=Липкий поршень -A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Липкий поршень представляет собой компонент редстоуна с липким толкателем, который можно удлинять и втягивать обратно. Он расширяется, когда на него подается энергия красного камня. Когда толкатель выдвигается, он толкает блок или блоки перед собой. Когда он втягивается, он возвращает обратно один блок перед собой. Следует отметить, что не все блоки могут быть сдвинуты. или втянуты. -Pushes block when powered by redstone power=Толкает блок при подаче энергии редстоуна -Pushes or pulls block when powered by redstone power=Толкает или тянет блок при подаче энергии редстоуна +A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Липкий поршень представляет собой компонент редстоуна с липким толкателем, который можно выдвигать и втягивать обратно. Он выдвигается, когда на него подается сигнал красного камня. Когда толкатель выдвигается, он толкает блок или блоки перед собой. Когда он втягивается, он возвращает обратно один блок перед собой. Следует отметить, что не все блоки могут быть сдвинуты или втянуты. +Pushes block when powered by redstone power=Толкает блок при подаче сигнала редстоуна +Pushes or pulls block when powered by redstone power=Толкает или втягивает блок при подаче сигнала редстоуна diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pt_BR.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pt_BR.tr new file mode 100644 index 000000000..b0abc529c --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pt_BR.tr @@ -0,0 +1,21 @@ +# textdomain: mesecons_pressureplates +A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.=Uma placa de pressão é um componente de redstone ao qual alimenta os blocos ao seu redor com carga de redstone enquanto alguém ou alguma coisa descansa em cima dela. +Oak Pressure Plate=Placa de Pressão de Carvalho +Acacia Pressure Plate=Placa de Pressão de Acácia +Birch Pressure Plate=Placa de Pressão de Bétula +Dark Oak Pressure Plate=Placa de Pressão de Carvalho Escuro +Spruce Pressure Plate=Placa de Pressão de Pinheiro +Jungle Pressure Plate=Placa de Pressão da Selva +Mangrove Pressure Plate=Placa de Pressão de Mangue +Crimson Pressure Plate=Placa de Pressão de Hifas Carmesim +Warped Pressure Plate=Placa de Pressão de Hifas Distorcidas +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Uma placa de pressão de madeira é um componente de redstone ao qual alimenta os blocos ao seu redor com carga de redstone enquanto qualquer objeto móvel (incluindo itens largados, jogadores e mobs) descansarem em cima dela. +Polished Blackstone Pressure Plate=Placa de Pressão de Rocha Negra Polida +A polished blackstone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Uma placa de pressão de pedra negra polida é um componente de redstone ao qual alimenta os blocos ao seu redor com carga de redstone enquanto um jogador ou mob estiver em pé em cima dela. Não é acionada por outras coisas. +Stone Pressure Plate=Placa de Pressão de Pedra +A stone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Uma placa de pressão de pedra é um componente de redstone ao qual alimenta os blocos ao seu redor com carga de redstone enquanto um jogador ou mob estiver em pé em cima dela. Não é acionada por outras coisas. +Provides redstone power when pushed=Fornece carga de redstone quando pressionada +Pushable by players, mobs and objects=Pressionável por jogadores, mobs e objetos +Pushable by players and mobs=Pressionável por jogadores e mobs +Pushable by players=Pressionável por jogadores +Pushable by mobs=Pressionável por mobs diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ru.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ru.tr index fcd81f451..1efeb7805 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ru.tr @@ -1,16 +1,21 @@ # textdomain: mesecons_pressureplates -A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.=Нажимаемая панель это компонент редстоуна, который начинает снабжать энергией редстоуна окружающие его блоки, когда кто-то или что-то находится прямо на нём. -Oak Pressure Plate=Дубовая нажимная панель -Acacia Pressure Plate=Акациевая нажимная панель -Birch Pressure Plate=Берёзовая нажимная панель -Dark Oak Pressure Plate=Нажимная панель из тёмного дуба -Spruce Pressure Plate=Еловая нажимная панель -Jungle Pressure Plate=Нажимная панель из дерева джунглей -A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Деревянная нажимная панель это компонент редстоуна, который начинает снабжать энергией редстоуна окружающие его блоки, когда любой движущийся объект (включая брошенные предметы, игроков и мобов) находится прямо на нём. -Stone Pressure Plate=Каменная нажимная панель -A stone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Каменная нажимная панель это компонент редстоуна, который начинает снабжать энергией редстоуна окружающие его блоки, когда игрок или моб находится прямо на нём. От чего-то другого он не сработает. -Provides redstone power when pushed=Производит энергию редстоуна при нажимании -Pushable by players, mobs and objects=Нажимается игроками, мобами и объектами +A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.=Нажимная плита это компонент редстоуна, который выдает сигнал редстоуна окружающим его блокам, когда кто-то или что-то находится прямо на нём. +Oak Pressure Plate=Дубовая нажимная плита +Acacia Pressure Plate=Акациевая нажимная плита +Birch Pressure Plate=Берёзовая нажимная плита +Dark Oak Pressure Plate=Нажимная плита из тёмного дуба +Spruce Pressure Plate=Еловая нажимная плита +Jungle Pressure Plate=Нажимная плита из тропического дерева +Mangrove Pressure Plate=Мангровая нажимная плита +Crimson Pressure Plate=Багровая нажимная плита +Warped Pressure Plate=Искажённая нажимная плита +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Деревянная нажимная плита это компонент редстоуна, который выдаёт сигнал редстоуна окружающим его блокам, когда любой движущийся объект (включая брошенные предметы, игроков и мобов) находится прямо на нём. +Polished Blackstone Pressure Plate=Нажимная плита из полированного чернокамня +A polished blackstone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Нажимная плита из полированного чернокамня это компонент редстоуна, который выдает сигнал редстоуна окружающим его блокам, когда игрок или моб находится прямо на нём. От чего-то другого она не сработает. +Stone Pressure Plate=Каменная нажимная плита +A stone pressure plate is a redstone component which supplies its surrounding blocks with redstone power while a player or mob stands on top of it. It is not triggered by anything else.=Каменная нажимная плита это компонент редстоуна, который выдает сигнал редстоуна окружающим его блокам, когда игрок или моб находится прямо на нём. От чего-то другого она не сработает. +Provides redstone power when pushed=Производит сигнал редстоуна при нажатии +Pushable by players, mobs and objects=Нажимается игроками, мобами и предметами Pushable by players and mobs=Нажимается игроками и мобами Pushable by players=Нажимается игроками Pushable by mobs=Нажимается мобами diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ru.tr b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ru.tr index 108cb9f75..99859bb89 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ru.tr @@ -1,8 +1,8 @@ # textdomain: mesecons_solarpanel Daylight Sensor=Датчик дневного света -Daylight sensors are redstone components which provide redstone power when they are in sunlight and no power otherwise. They can also be inverted.=Датчик дневного света это компонент редстоуна, который производит энергию редстоуна при нахождении в солнечном свете и не производит в противном случае. Он также может быть инвертирован. -Use the daylight sensor to toggle its state.=[Используйте] датчик дневного света для смены его состояния +Daylight sensors are redstone components which provide redstone power when they are in sunlight and no power otherwise. They can also be inverted.=Датчик дневного света это компонент редстоуна, который производит сигнал редстоуна при солнечном свете и не производит в противном случае. Он также может быть инвертирован. +Use the daylight sensor to toggle its state.=Используйте датчик дневного света для смены его состояния Inverted Daylight Sensor=Инвертированный датчик дневного света -In inverted state, they provide redstone power when they are not in sunlight and no power otherwise.=В инвертированном состоянии он производит энергию редстоуна, когда на него не попадает солнечны свет, а когда попадает - перестаёт производить. -Provides redstone power when in sunlight=Генерирует энергию редстоуна в солнечном свете +In inverted state, they provide redstone power when they are not in sunlight and no power otherwise.=В инвертированном состоянии он производит сигнал редстоуна, когда на него не попадает солнечный свет, а когда попадает - перестаёт производить. +Provides redstone power when in sunlight=Генерирует сигнал редстоуна от солнечного света Can be inverted=Может быть инвертирован diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ru.tr b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ru.tr index 45d0d7667..c3f365f1b 100644 --- a/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ru.tr @@ -1,10 +1,10 @@ # textdomain: mesecons_torch -Redstone Torch=Факел редстоуна -Redstone Torch (off)=Факел редстоуна (выкл) -Redstone Torch (overheated)=Факел редстоуна (перегрелся) -A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything.=Факел редстоуна это компонент, способный инвертировать сигнал редстоуна. Он обеспечивает энергией редстоуна окружающие блоки, за исключением того блока, к которому он присоединён. Факел редстоуна обычно горит, но он также может быть выключен путём подведения энергии редстоуна к тому блоку, к которому он присоединён. Когда он не горит, то не снабжает энергией окружающие блоки. -Redstone torches can be placed at the side and on the top of full solid opaque blocks.=Факелы редстоуна могут быть установлены по краям и на верхней части любого целого плотного твёрдого блока. +Redstone Torch=Красный факел +Redstone Torch (off)=Красный факел (выкл) +Redstone Torch (overheated)=Красный факел (перегорел) +A redstone torch is a redstone component which can be used to invert a redstone signal. It supplies its surrounding blocks with redstone power, except for the block it is attached to. A redstone torch is normally lit, but it can also be turned off by powering the block it is attached to. While unlit, a redstone torch does not power anything.=Красный факел это компонент, способный инвертировать сигнал редстоуна. Он подает сигнал редстоуна на окружающие блоки, за исключением того блока, к которому он присоединён. Красный факел обычно горит, но он также может быть выключен путём подведения сигнала редстоуна к тому блоку, к которому он присоединён. Когда он не горит, то не снабжает сигналом окружающие блоки. +Redstone torches can be placed at the side and on the top of full solid opaque blocks.=Красный факел может быть установлен по краям и сверху любого целого твёрдого непрозрачного блока. Block of Redstone=Блок редстоуна -A block of redstone permanently supplies redstone power to its surrounding blocks.=Блок редстоуна напрямую снабжает энергией окружающие блоки -Provides redstone power when it's not powered itself=Снабжает энергией редстоуна, если не подключён сам -Provides redstone power=Снабжает энергией редстоуна +A block of redstone permanently supplies redstone power to its surrounding blocks.=Блок редстоуна напрямую снабжает сигналом редстоуна окружающие блоки +Provides redstone power when it's not powered itself=Снабжает сигналом редстоуна, если не подключён сам +Provides redstone power=Снабжает сигналом редстоуна diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/README.txt b/mods/ITEMS/REDSTONE/mesecons_walllever/README.txt index 8744b5646..822cc973e 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/README.txt +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/README.txt @@ -8,4 +8,4 @@ Lever meshes created by Gerold55. Jeija and Wuzzy. ## Textures -(See main README file of MineClone 2). +See main README file of VoxeLibre. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pt_BR.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pt_BR.tr new file mode 100644 index 000000000..e2f6b7d45 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mesecons_walllever +Lever=Alavanca +A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Uma alavanca é um componente de redstone ao qual pode ser comutado em ligado ou desligado. Fornecerá carga de redstone para blocos adjacentes enquanto estiver no estado "ligado". +Use the lever to flip it on or off.=Use a alavanca para comutá-la em ligado ou desligado. +Provides redstone power while it's turned on=Fornece carga de redstone enquanto estiver ligada diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr index 00a3e84f1..80aff1e84 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr @@ -1,5 +1,5 @@ # textdomain: mesecons_walllever Lever=Рычаг -A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Рычаг это компонент редстоуна, который можно включать и выключать. Он подаёт энергию редстоуна на соседние блоки, пока он находится во «включённом» состоянии. -Use the lever to flip it on or off.=[Используйте] рычаг, чтобы перещёлкнуть его во включённое или выключенное положение . -Provides redstone power while it's turned on=Снабжает энергией редстоуна, когда включён +A lever is a redstone component which can be flipped on and off. It supplies redstone power to adjacent blocks while it is in the “on” state.=Рычаг это компонент редстоуна, который можно включать и выключать. Он подаёт сигнал редстоуна на соседние блоки, пока он находится во включённом состоянии. +Use the lever to flip it on or off.=Используйте рычаг, чтобы перещёлкнуть его во включённое или выключенное положение. +Provides redstone power while it's turned on=Подаёт сигнал редстоуна когда включён diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ru.tr b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ru.tr index 4316613b0..9c1b05615 100644 --- a/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ru.tr @@ -1,11 +1,11 @@ # textdomain: mesecons_wires -Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on the ground as a trail.=Редстоун является универсальным проводящим минералом, который передает энергию красного камня. Он может размещаться на поверхности как дорожка. -A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.=Дорожка редстоуна может быть в двух состояниях: включена или выключена. Включённая дорожка редстоуна будет снабжать (а значит, активировать) смежные компоненты редстоуна. -Redstone power can be received from various redstone components, such as a block of redstone or a button. Redstone power is used to activate numerous mechanisms, such as redstone lamps or pistons.=Энергию редстоуна можно получать от различных компонентов редстоуна, таких как блок редстоуна или кнопка. Эта энергия используется для активации многочисленных механизмов, таких как лампы редстоуна или поршни. -Place redstone on the ground to build a redstone trail. The trails will connect to each other automatically and it can also go over hills. An easy way to power a redstone trail is by placing a redstone torch.=Поместите редстоун на землю, чтобы создать из него дорожку. Фрагменты дорожек будут соединяться между собой автоматически и могут даже проходить по холмам. Простой способ подать энергию редстоуна к дорожке редстоуна это установка факела редстоуна. +Redstone is a versatile conductive mineral which transmits redstone power. It can be placed on the ground as a trail.=Редстоун является универсальным проводящим минералом, который передает сигнал красного камня. Он может размещаться на поверхности как дорожка. +A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.=Дорожка редстоуна может быть в двух состояниях: подключенная или отключенная. Подключенная дорожка редстоуна будет снабжать (а значит, активировать) рядом стоящие компоненты редстоуна. +Redstone power can be received from various redstone components, such as a block of redstone or a button. Redstone power is used to activate numerous mechanisms, such as redstone lamps or pistons.=Сигнал редстоуна можно получать от различных компонентов редстоуна, таких как блок редстоуна или кнопка. Этот сигнал используется для активации многочисленных механизмов, таких как лампы или поршни. +Place redstone on the ground to build a redstone trail. The trails will connect to each other automatically and it can also go over hills. An easy way to power a redstone trail is by placing a redstone torch.=Поместите редстоун на землю, чтобы создать из него дорожку. Фрагменты дорожек будут соединяться между собой автоматически и могут даже проходить по холмам. Простой способ подать сигнал редстоуна к дорожке редстоуна это установка красного факела. Read the help entries on the other redstone components to learn how redstone components interact.=Смотрите справочные записи к остальным компонентам редстоуна, чтобы узнать больше об их взаимодействии. Redstone=Редстоун -Powered Redstone Spot (@1)=Подключённое пятно редстоуна (@1) +Powered Redstone Spot (@1)=Подключенное пятно редстоуна (@1) Redstone Trail (@1)=Дорожка редстоуна (@1) -Powered Redstone Trail (@1)=Подключённая дорожка редстоуна (@1) -Transmits redstone power, powers mechanisms=Передаёт энергию редстоуна, подключает механизмы +Powered Redstone Trail (@1)=Подключенная дорожка редстоуна (@1) +Transmits redstone power, powers mechanisms=Передаёт сигнал редстоуна, подключает механизмы diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.de.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.de.tr new file mode 100644 index 000000000..29d8d4c0f --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.de.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=Amethysthaufen +Amethyst Cluster is the final growth of amethyst bud.=Der Amethysthaufen ist das endgültige Wachstum der Amethystknospe. +Amethyst Shard=Amethystsplitter +An amethyst shard is a crystalline mineral.=Ein Amethystsplitter ist ein kristallines Mineral. +Block of Amethyst=Amethystblock +Budding Amethyst=Amethystknospe +Calcite=Kalzit +Calcite can be found as part of amethyst geodes.=Kalzit kann als Teil von Amethystgeoden gefunden werden. +Large Amethyst Bud=Große Amethystknospe +Large Amethyst Bud is the third growth of amethyst bud.=Die große Amethystknospe ist die dritte Wachstumsstufe der Amethystknospe. +Medium Amethyst Bud=Mittelgroße Amethystknospe +Medium Amethyst Bud is the second growth of amethyst bud.=Die mittelgroße Amethystknospe ist die zweite Wachstumsstufe der Amethystknospe. +Small Amethyst Bud=Kleine Amethystknospe +Small Amethyst Bud is the first growth of amethyst bud.=Die kleine Amethystknospe ist die erste Wachstumsstufe der Amethystknospe. +The Block of Amethyst is a decoration block crafted from amethyst shards.=Der Amethystblock ist ein aus Amethystsplittern gefertigter Dekorationsblock. +The Budding Amethyst can grow amethyst=Knospender Amethyst kann Amethyst wachsen lassen. +Tinted Glass=Getöntes Glas +Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Getöntes Glas ist eine Art von Glas, das Licht blockiert, während es visuell transparent ist. diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr index 9f1d0f572..3ca786c68 100644 --- a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr @@ -1,8 +1,8 @@ # textdomain: mcl_amethyst Amethyst Cluster=Аметистовая друза -Amethyst Cluster is the final growth of amethyst bud.=Аметистовая друза - это последняя 4-я стадия роста аметистового бутона. -Amethyst Shard=Осколок аметиста -An amethyst shard is a crystalline mineral.=Осколок аметиста - это кристаллический минерал, получаемый в результате разрушения кластеров аметиста. +Amethyst Cluster is the final growth of amethyst bud.=Аметистовая друза это последняя 4-я стадия роста аметистового бутона. +Amethyst Shard=Аметистовый осколок +An amethyst shard is a crystalline mineral.=Осколок аметиста это кристаллический минерал, получаемый в результате разрушения кластеров аметиста. Block of Amethyst=Аметистовый блок Budding Amethyst=Растущий аметист Calcite=Кальцит @@ -13,7 +13,7 @@ Medium Amethyst Bud=Средний росток аметиста Medium Amethyst Bud is the second growth of amethyst bud.=Средний росток - вторая стадия роста аметиста. Small Amethyst Bud=Маленький росток аметиста Small Amethyst Bud is the first growth of amethyst bud.=Маленький росток - первая стадия роста аметиста. -The Block of Amethyst is a decoration block crafted from amethyst shards.=Блок аметиста - декоративный блок, скрафченный из осколков аметиста. +The Block of Amethyst is a decoration block crafted from amethyst shards.=Блок аметиста это декоративный блок, созданный из осколков аметиста. The Budding Amethyst can grow amethyst=Растущий аметист может вырастить аметист Tinted Glass=Тонированное стекло Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Тонированное стекло блокирует свет, но визуально прозрачно. diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index a56299cd9..3db1a7eb9 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -1,4 +1,6 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize local MAX_NAME_LENGTH = 35 local MAX_WEAR = 65535 @@ -10,41 +12,66 @@ local MATERIAL_TOOL_REPAIR_BOOST = { MAX_WEAR, -- 100% } +---@param set_name? string local function get_anvil_formspec(set_name) if not set_name then set_name = "" end - return "size[9,8.75]".. - "background[-0.19,-0.25;9.41,9.49;mcl_anvils_inventory.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "list[context;input;1,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(1,2.5,1,1).. - "list[context;input;4,2.5;1,1;1]".. - mcl_formspec.get_itemslot_bg(4,2.5,1,1).. - "list[context;output;8,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(8,2.5,1,1).. - "label[3,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair and Name"))).."]".. - "field[3.25,1;4,1;name;;"..minetest.formspec_escape(set_name).."]".. - "field_close_on_enter[name;false]".. - "button[7,0.7;2,1;name_button;"..minetest.formspec_escape(S("Set Name")).."]".. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" + + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Repair and Name"))) .. "]", + + "image[0.875,0.375;1.75,1.75;mcl_anvils_inventory_hammer.png]", + + "field[4.125,0.75;7.25,1;name;;" .. F(set_name) .. "]", + "field_close_on_enter[name;false]", + "field_enter_after_edit[name;true]", + "set_focus[name;true]", + + mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1), + "list[context;input;1.625,2.6;1,1;]", + + "image[3.5,2.6;1,1;mcl_anvils_inventory_cross.png]", + + mcl_formspec.get_itemslot_bg_v4(5.375, 2.6, 1, 1), + "list[context;input;5.375,2.6;1,1;1]", + + "image[6.75,2.6;2,1;mcl_anvils_inventory_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(9.125, 2.6, 1, 1), + "list[context;output;9.125,2.6;1,1;]", + + -- Player 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;]", + + -- Listrings + + "listring[context;output]", + "listring[current_player;main]", + "listring[context;input]", + "listring[current_player;main]", + }) end -- Given a tool and material stack, returns how many items of the material stack -- needs to be used up to repair the tool. +---@param tool ItemStack +---@param material ItemStack +---@return integer local function get_consumed_materials(tool, material) local wear = tool:get_wear() --local health = (MAX_WEAR - wear) local matsize = material:get_count() local materials_used = 0 - for m=1, math.min(4, matsize) do + for m = 1, math.min(4, matsize) do materials_used = materials_used + 1 if (wear - MATERIAL_TOOL_REPAIR_BOOST[m]) <= 0 then break @@ -53,27 +80,20 @@ local function get_consumed_materials(tool, material) return materials_used end -local function contains(table, value) - for _, i in pairs(table) do - if i == value then - return true - end - end - return false -end - -- Given 2 input stacks, tells you which is the tool and which is the material. -- Returns ("tool", input1, input2) if input1 is tool and input2 is material. -- Returns ("material", input2, input1) if input1 is material and input2 is tool. -- Returns nil otherwise. +---@param input1 ItemStack +---@param input2 ItemStack local function distinguish_tool_and_material(input1, input2) local def1 = input1:get_definition() local def2 = input2:get_definition() local r1 = def1._repair_material local r2 = def2._repair_material - if def1.type == "tool" and r1 and type(r1) == "table" and contains(r1, input2) then + if def1.type == "tool" and r1 and type(r1) == "table" and table.indexof(r1, input2) ~= -1 then return "tool", input1, input2 - elseif def2.type == "tool" and r2 and type(r2) == "table" and contains(r2, input1) then + elseif def2.type == "tool" and r2 and type(r2) == "table" and table.indexof(r1, input1) ~= -1 then return "material", input2, input1 elseif def1.type == "tool" and r1 then return "tool", input1, input2 @@ -84,7 +104,8 @@ local function distinguish_tool_and_material(input1, input2) end end --- Helper function to make sure update_anvil_slots NEVER overstacks the output slot +---Helper function to make sure update_anvil_slots NEVER overstacks the output slot +---@param stack ItemStack local function fix_stack_size(stack) if not stack or stack == "" then return "" end local count = stack:get_count() @@ -99,6 +120,7 @@ end -- Update the inventory slots of an anvil node. -- meta: Metadata of anvil node +---@param meta NodeMetaRef local function update_anvil_slots(meta) local inv = meta:get_inventory() local new_name = meta:get_string("set_name") @@ -137,7 +159,7 @@ local function update_anvil_slots(meta) name_item = input1 new_output = name_item - -- Tool + repair item + -- Tool + repair item else -- Any tool can have a repair item. This may be defined in the tool's item definition -- as an itemstring in the field `_repair_material`. Only if this field is set, the @@ -159,7 +181,7 @@ local function update_anvil_slots(meta) has_correct_material = true end else - if contains(repair, material_name) then + if table.indexof(repair, material_name) ~= -1 then has_correct_material = true else for _, r in pairs(repair) do @@ -185,7 +207,7 @@ local function update_anvil_slots(meta) new_output = "" end end - -- Exactly 1 input slot occupied + -- Exactly 1 input slot occupied elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then -- Just rename item if input1:is_empty() then @@ -231,28 +253,32 @@ local function update_anvil_slots(meta) end end --- Drop input items of anvil at pos with metadata meta +---Drop input items of anvil at pos with metadata meta +---@param pos Vector +---@param meta NodeMetaRef local function drop_anvil_items(pos, meta) local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do local stack = inv:get_stack("input", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5) minetest.add_item(p, stack) end end end +---@param pos Vector +---@param node node local function damage_particles(pos, node) minetest.add_particlespawner({ amount = 30, time = 0.1, - minpos = vector.add(pos, {x=-0.5, y=-0.5, z=-0.5}), - maxpos = vector.add(pos, {x=0.5, y=-0.25, z=0.5}), - minvel = {x=-0.5, y=0.05, z=-0.5}, - maxvel = {x=0.5, y=0.3, z=0.5}, - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, + minpos = vector.offset(pos, -0.5, -0.5, -0.5), + maxpos = vector.offset(pos, 0.5, -0.25, 0.5), + minvel = vector.new(-0.5, 0.05, -0.5), + maxvel = vector.new(0.5, 0.3, 0.5), + minacc = vector.new(0, -9.81, 0), + maxacc = vector.new(0, -9.81, 0), minexptime = 0.1, maxexptime = 0.5, minsize = 0.4, @@ -267,12 +293,12 @@ local function destroy_particles(pos, node) minetest.add_particlespawner({ amount = math.random(20, 30), time = 0.1, - minpos = vector.add(pos, {x=-0.4, y=-0.4, z=-0.4}), - maxpos = vector.add(pos, {x=0.4, y=0.4, z=0.4}), - minvel = {x=-0.5, y=-0.1, z=-0.5}, - maxvel = {x=0.5, y=0.2, z=0.5}, - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, + minpos = vector.offset(pos, -0.4, -0.4, -0.4), + maxpos = vector.offset(pos, 0.4, 0.4, 0.4), + minvel = vector.new(-0.5, -0.1, -0.5), + maxvel = vector.new(0.5, 0.2, 0.5), + minacc = vector.new(0, -9.81, 0), + maxacc = vector.new(0, -9.81, 0), minexptime = 0.2, maxexptime = 0.65, minsize = 0.8, @@ -289,28 +315,29 @@ end local function damage_anvil(pos) local node = minetest.get_node(pos) if node.name == "mcl_anvils:anvil" then - minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_1", param2=node.param2}) + minetest.swap_node(pos, { name = "mcl_anvils:anvil_damage_1", param2 = node.param2 }) damage_particles(pos, node) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, { pos = pos, max_hear_distance = 16 }, true) return false elseif node.name == "mcl_anvils:anvil_damage_1" then - minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_2", param2=node.param2}) + minetest.swap_node(pos, { name = "mcl_anvils:anvil_damage_2", param2 = node.param2 }) damage_particles(pos, node) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dig, { pos = pos, max_hear_distance = 16 }, true) return false elseif node.name == "mcl_anvils:anvil_damage_2" then -- Destroy anvil local meta = minetest.get_meta(pos) drop_anvil_items(pos, meta) - minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, {pos=pos, max_hear_distance=16}, true) + minetest.sound_play(mcl_sounds.node_sound_metal_defaults().dug, { pos = pos, max_hear_distance = 16 }, true) minetest.remove_node(pos) destroy_particles(pos, node) - minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) + minetest.check_single_for_falling(vector.offset(pos, 0, 1, 0)) return true end end --- Roll a virtual dice and damage anvil at a low chance. +---Roll a virtual dice and damage anvil at a low chance. +---@param pos Vector local function damage_anvil_by_using(pos) local r = math.random(1, 100) -- 12% chance @@ -321,25 +348,30 @@ local function damage_anvil_by_using(pos) end end +---@param pos Vector +---@param distance number local function damage_anvil_by_falling(pos, distance) local r = math.random(1, 100) if distance > 1 then - if r <= (5*distance) then + if r <= (5 * distance) then damage_anvil(pos) end end end +---@type nodebox local anvilbox = { type = "fixed", fixed = { { -8 / 16, -8 / 16, -6 / 16, 8 / 16, 8 / 16, 6 / 16 }, }, } + +---@type node_definition local anvildef = { - groups = {pickaxey=1, falling_node=1, falling_node_damage=1, crush_after_fall=1, deco_block=1, anvil=1}, - tiles = {"mcl_anvils_anvil_top_damaged_0.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + groups = { pickaxey = 1, falling_node = 1, falling_node_damage = 1, crush_after_fall = 1, deco_block = 1, anvil = 1 }, + tiles = { "mcl_anvils_anvil_top_damaged_0.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png" }, + use_texture_alpha = "opaque", _tt_help = S("Repair and rename items"), paramtype = "light", sunlight_propagates = true, @@ -353,7 +385,7 @@ local anvildef = { { -5 / 16, -4 / 16, -4 / 16, 5 / 16, -3 / 16, 4 / 16 }, { -4 / 16, -3 / 16, -2 / 16, 4 / 16, 2 / 16, 2 / 16 }, { -8 / 16, 2 / 16, -5 / 16, 8 / 16, 8 / 16, 5 / 16 }, - } + }, }, selection_box = anvilbox, collision_box = anvilbox, @@ -416,7 +448,7 @@ local anvildef = { local meta = minetest.get_meta(pos) if from_list == "output" and to_list == "input" then local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do if i ~= to_index then local istack = inv:get_stack("input", i) istack:set_count(math.max(0, istack:get_count() - count)) @@ -504,22 +536,20 @@ local anvildef = { minetest.record_protection_violation(pos, sender_name) return end - if fields.name_button or fields.name then - local set_name - if fields.name == nil then - set_name = "" - else - set_name = fields.name - end + + if fields.name then local meta = minetest.get_meta(pos) + -- Limit name length - set_name = string.sub(set_name, 1, MAX_NAME_LENGTH) + local set_name = string.sub(fields.name, 1, MAX_NAME_LENGTH) + meta:set_string("set_name", set_name) update_anvil_slots(meta) meta:set_string("formspec", get_anvil_formspec(set_name)) end end, } + if minetest.get_modpath("screwdriver") then anvildef.on_rotate = screwdriver.rotate_simple end @@ -527,29 +557,34 @@ end local anvildef0 = table.copy(anvildef) anvildef0.description = S("Anvil") anvildef0._doc_items_longdesc = -S("The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!") + S("The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!") anvildef0._doc_items_usagehelp = -S("To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.").."\n".. -S("To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.").."\n".. -S("There are two possibilities to repair tools (and armor):").."\n".. -S("• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.").."\n".. -S("• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.").."\n".. -S("Armor counts as a tool. It is possible to repair and rename a tool in a single step.").."\n\n".. -S("The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.") + S("To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.") .. "\n" .. + S("To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.") + .. "\n" .. + S("There are two possibilities to repair tools (and armor):") .. "\n" .. + S("• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.") + .. "\n" .. + S("• Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.") + .. "\n" .. + S("Armor counts as a tool. It is possible to repair and rename a tool in a single step.") .. "\n\n" .. + S("The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.") local anvildef1 = table.copy(anvildef) anvildef1.description = S("Slightly Damaged Anvil") anvildef1._doc_items_create_entry = false anvildef1.groups.anvil = 2 anvildef1._doc_items_create_entry = false -anvildef1.tiles = {"mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} +anvildef1.tiles = { "mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvils_anvil_base.png", + "mcl_anvils_anvil_side.png" } local anvildef2 = table.copy(anvildef) anvildef2.description = S("Very Damaged Anvil") anvildef2._doc_items_create_entry = false anvildef2.groups.anvil = 3 anvildef2._doc_items_create_entry = false -anvildef2.tiles = {"mcl_anvils_anvil_top_damaged_2.png^[transformR90", "mcl_anvils_anvil_base.png", "mcl_anvils_anvil_side.png"} +anvildef2.tiles = { "mcl_anvils_anvil_top_damaged_2.png^[transformR90", "mcl_anvils_anvil_base.png", + "mcl_anvils_anvil_side.png" } minetest.register_node("mcl_anvils:anvil", anvildef0) minetest.register_node("mcl_anvils:anvil_damage_1", anvildef1) @@ -562,7 +597,7 @@ if minetest.get_modpath("mcl_core") then { "mcl_core:ironblock", "mcl_core:ironblock", "mcl_core:ironblock" }, { "", "mcl_core:iron_ingot", "" }, { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, - } + }, }) end diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ru.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ru.tr index 20281bd6b..e76da3a31 100644 --- a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ru.tr +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ru.tr @@ -3,14 +3,14 @@ Set Name=Дать имя Repair and Name=Починить и дать имя Inventory=Инвентарь Anvil=Наковальня -The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!=Наковальня позволяет ремонтировать инструменты и защиту, а также давать имена предметам. Но она имеет ограниченный срок службы. Не дайте ей упасть вам на голову, это может быть больно! -To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Чтобы воспользоваться наковальней, кликните по ней правой кнопкой. Наковальня имеет два входных отсека (слева) и один выходной. -To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.=Для переименования положите стопку предметов в один отсек, второй оставьте пустым. Наберите имя, нажмите [Enter] или “Дать имя” и заберите переименованные предметы из выходного отсека. -There are two possibilities to repair tools (and armor):=Есть два способа отремонтировать инструменты (и защиту): -• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.=• Инструмент + Инструмент: Положите два инструмента одного типа во входные отсеки. “Здоровье” отремонтированного инструмента будет равно сумме “здоровья” каждого из них, плюс 12% бонус. +The anvil allows you to repair tools and armor, and to give names to items. It has a limited durability, however. Don't let it fall on your head, it could be quite painful!=Наковальня позволяет ремонтировать инструменты и броню, а также давать имена предметам. Но она имеет ограниченную прочность. Не дайте ей упасть вам на голову, это может быть больно! +To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Чтобы воспользоваться наковальней, кликните по ней правой кнопкой. Наковальня имеет два входных слота (слева) и один выходной. +To rename items, put an item stack in one of the item slots while keeping the other input slot empty. Type in a name, hit enter or “Set Name”, then take the renamed item from the output slot.=Для переименования положите стопку предметов в один слот, второй оставьте пустым. Наберите имя, нажмите [Enter] или “Дать имя” и заберите переименованные предметы из выходного слота. +There are two possibilities to repair tools (and armor):=Есть два способа отремонтировать инструменты (и броню): +• Tool + Tool: Place two tools of the same type in the input slots. The “health” of the repaired tool is the sum of the “health” of both input tools, plus a 12% bonus.=• Инструмент + Инструмент: Положите два инструмента одного типа во входные слоты. “Здоровье” отремонтированного инструмента будет равно сумме “здоровья” каждого из них, плюс 12% бонус. • Tool + Material: Some tools can also be repaired by combining them with an item that it's made of. For example, iron pickaxes can be repaired with iron ingots. This repairs the tool by 25%.=• Инструмент + Материал: Некоторые инструменты можно также ремонтировать, добавляя к ним предмет, из которого они сделаны. Например, железные кирки ремонтируются добавлением слитков железа. Таким способом инструмент восстанавливается на 25%. -Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Защиты считается за инструмент. Можно ремонтировать и переименовывать за одно действие. -The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.=Наковальня имеет ограниченный срок службы и 3 уровня износа: новая, немного изношенная, сильно повреждённая. Каждый раз, ремонтируя или переименовывая что-либо, вы имеете 12-процентный шанс повредить наковальню. Наковальни также могут повреждаться, когда они падают с высоте более 1 блока. Если повреждённая наковальня повреждается снова, то она уничтожается. -Slightly Damaged Anvil=Немного изношенная наковальня +Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Броня считается за инструмент. Можно аналогично ремонтировать и переименовывать. +The anvil has limited durability and 3 damage levels: undamaged, slightly damaged and very damaged. Each time you repair or rename something, there is a 12% chance the anvil gets damaged. Anvils also have a chance of being damaged when they fall by more than 1 block. If a very damaged anvil is damaged again, it is destroyed.=Наковальня имеет ограниченный прочность и 3 уровня износа: новая, немного изношенная, сильно повреждённая. Каждый раз, ремонтируя или переименовывая что-либо, вы имеете 12-процентный шанс повредить наковальню. Наковальни также могут повреждаться, когда они падают с высоты более 1 блока. Если повреждённая наковальня повреждается снова, то она уничтожается. +Slightly Damaged Anvil=Повреждённая наковальня Very Damaged Anvil=Сильно повреждённая наковальня Repair and rename items=Ремонтирует и переименовывает предметы diff --git a/mods/ITEMS/mcl_armor/API.md b/mods/ITEMS/mcl_armor/API.md index 06292aab4..507deab39 100644 --- a/mods/ITEMS/mcl_armor/API.md +++ b/mods/ITEMS/mcl_armor/API.md @@ -226,7 +226,7 @@ mcl_armor.update(obj) Armors can be enchanted in most cases. -The enchanting part of MineClone2 is separated from the armor part, but closely linked. +The enchanting part of VoxeLibre is separated from the armor part, but closely linked. Existing armor enchantments in Minecraft improve most of the time how the armor protect the entity from damage. diff --git a/mods/ITEMS/mcl_armor/README.txt b/mods/ITEMS/mcl_armor/README.txt index 5e68b5746..82ff7af39 100644 --- a/mods/ITEMS/mcl_armor/README.txt +++ b/mods/ITEMS/mcl_armor/README.txt @@ -27,4 +27,4 @@ Licensed (CC BY-SA 3.0) by Mito551 All other sounds licensed CC0 by OpenGameArt.org user artisticdude. Source: -Other media files: See MineClone 2 license. +Other media files: See VoxeLibre license. diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua old mode 100644 new mode 100755 index 1b9aa4f73..750bd66c8 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -85,6 +85,31 @@ function mcl_armor.equip_on_use(itemstack, player, pointed_thing) return mcl_armor.equip(itemstack, player) end +local function get_armor_texture(textures, name, modname, itemname, itemstring) + local core_texture = textures[name] or modname .. "_" .. itemname .. ".png" + if type(core_texture) == "function" then return core_texture end + mcl_armor.trims.core_textures[itemstring] = core_texture + local func = function(obj, itemstack) + local overlay = itemstack:get_meta():get_string("mcl_armor:trim_overlay") + local core_armor_texture + local stack_name = mcl_grindstone.remove_enchant_name(itemstack) -- gets original itemstring if enchanted, no need to store (nearly) identical values + local core_armor_texture = mcl_armor.trims.core_textures[stack_name] + + if mcl_enchanting.is_enchanted(itemstack:get_name()) then -- working with the original stack to know wether to apply enchanting overlay or not + -- Far, Far in the future we may no longer _enchanted itemstrings... + -- To fix this code, simply put the unmodified itemstring in stack_name's place + -- DO NOT REMOVE THIS if UNLESS YOU KNOW WHAT YOU'RE TRYING TO ACHIEVE! + core_armor_texture = core_armor_texture .. mcl_enchanting.overlay + end + + if overlay == "" then return core_armor_texture end -- key not present; armor not trimmed + + return core_armor_texture .. overlay + end + + return func +end + function mcl_armor.register_set(def) local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) @@ -104,6 +129,7 @@ function mcl_armor.register_set(def) local groups = table.copy(groups) groups["armor_" .. name] = 1 groups["combat_armor_" .. name] = 1 + groups["armor_" .. def.name] = 1 groups.armor = 1 groups.combat_armor = 1 groups.mcl_armor_points = def.points[name] @@ -136,7 +162,7 @@ function mcl_armor.register_set(def) _on_unequip = on_unequip_callbacks[name] or def.on_unequip, _on_break = on_break_callbacks[name] or def.on_break, _mcl_armor_element = name, - _mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png", + _mcl_armor_texture = get_armor_texture(textures, name, modname, itemname, itemstring), _mcl_upgradable = def._mcl_upgradable, _mcl_upgrade_item = upgrade_item }) @@ -257,3 +283,61 @@ function mcl_armor.update(obj) end end +function mcl_armor.trim(itemstack, overlay, color_string) + local def = itemstack:get_definition() + if not def._mcl_armor_texture and not mcl_armor.trims.blacklisted[itemstack:get_name()] then return end + local meta = itemstack:get_meta() + + local piece_overlay = overlay + local inv_overlay = "" + local piece_type = def._mcl_armor_element + + if piece_type == "head" then --helmet + inv_overlay = "^(helmet_trim.png" + piece_overlay = piece_overlay .. "_helmet" + elseif piece_type == "torso" then --chestplate + inv_overlay = "^(chestplate_trim.png" + piece_overlay = piece_overlay .. "_chestplate" + elseif piece_type == "legs" then --leggings + inv_overlay = "^(leggings_trim.png" + piece_overlay = piece_overlay .. "_leggings" + elseif piece_type == "feet" then --boots + inv_overlay = "^(boots_trim.png" + piece_overlay = piece_overlay .. "_boots" + end + local color = mcl_armor.trims.colors[color_string] + inv_overlay = inv_overlay .. "^[colorize:" .. color .. ":150)" + piece_overlay = piece_overlay .. ".png" + + piece_overlay = "^(" .. piece_overlay .. "^[colorize:" .. color .. ":150)" + + meta:set_string("mcl_armor:trim_overlay" , piece_overlay) -- set textures to render on the player, will work for clients below 5.8 as well + meta:set_string("mcl_armor:inv", inv_overlay) -- make 5.8+ clients display the fancy inv image, older ones will see no change in the *inventory* image + meta:set_string("inventory_image", def.inventory_image .. inv_overlay) -- dont use reload_inv_image as it's a one liner in this enviorment +end + +function mcl_armor.reload_trim_inv_image(itemstack) + local meta = itemstack:get_meta() + local inv_overlay = meta:get_string("mcl_armor:inv") + local def = itemstack:get_definition() + if inv_overlay == "" then return end + meta:set_string("inventory_image", def.inventory_image .. inv_overlay) +end + +tt.register_snippet(function(itemstring, toolcaps, stack) + if not stack then return nil end + local meta = stack:get_meta() + if not mcl_armor.is_trimmed(stack) then return nil end + -- we need to get the part of the overlay image between the overlay begin ( and the trim name end _ + -- we COULD easily store this info in meta, but that would bloat the meta storage, as the same few values would be stored over and over again on every trimmed item + -- this is fine here as this code gets only executed when you put armor and a trim in a smithing table + local full_overlay = meta:get_string("mcl_armor:trim_overlay") + local trim_name = full_overlay:match("%((.-)%_") + return "Upgrade:\n " .. trim_name:gsub("^%l", string.upper) .. " Armor Trim" +end) + +function mcl_armor.is_trimmed(itemstack) + -- this meta value will be there for every trimmed armor piece + -- remember, get_string returns "" if the key doesn't exist + return itemstack:get_meta():get_string("mcl_armor:trim_overlay") ~= "" +end diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index 799bf2e9c..8f592d3ac 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -57,6 +57,12 @@ mcl_armor = { } }, player_view_range_factors = {}, + trims = { + core_textures = {}, + blacklisted = {["mcl_armor:elytra"]=true, ["mcl_armor:elytra_enchanted"]=true}, + overlays = {"sentry","dune","coast","wild","tide","ward","vex","rib","snout","eye","spire","silence","wayfinder"}, + colors = {["amethyst"]="#8246a5",["gold"]="#ce9627",["emerald"]="#1b9958",["copper"]="#c36447",["diamond"]="#5faed8",["iron"]="#938e88",["lapis"]="#1c306b",["netherite"]="#302a26",["quartz"]="#c9bcb9",["redstone"]="#af2c23"}, + }, } local modpath = minetest.get_modpath("mcl_armor") @@ -65,4 +71,6 @@ dofile(modpath .. "/api.lua") dofile(modpath .. "/player.lua") dofile(modpath .. "/damage.lua") dofile(modpath .. "/register.lua") +dofile(modpath .. "/leather.lua") dofile(modpath .. "/alias.lua") +dofile(modpath .. "/trims.lua") diff --git a/mods/ITEMS/mcl_armor/leather.lua b/mods/ITEMS/mcl_armor/leather.lua new file mode 100644 index 000000000..c2366166b --- /dev/null +++ b/mods/ITEMS/mcl_armor/leather.lua @@ -0,0 +1,207 @@ +local C = minetest.colorize + +local colors = { + -- { ID, decription, wool, dye } + { "red", "Red", "mcl_dye:red", "#951d1d" }, + { "blue", "Blue", "mcl_dye:blue", "#2a2c94" }, + { "cyan", "Cyan", "mcl_dye:cyan", "#0d7d8e" }, + { "grey", "Grey", "mcl_dye:dark_grey", "#363a3f" }, + { "silver", "Light Grey", "mcl_dye:grey", "#818177" }, + { "black", "Black", "mcl_dye:black", "#020307" }, + { "yellow", "Yellow", "mcl_dye:yellow", "#f2b410" }, + { "green", "Green", "mcl_dye:dark_green", "#495d20" }, + { "magenta", "Magenta", "mcl_dye:magenta", "#ae2ea4" }, + { "orange", "Orange", "mcl_dye:orange", "#e36501" }, + { "purple", "Purple", "mcl_dye:violet", "#681ba1" }, + { "brown", "Brown", "mcl_dye:brown", "#623b1a" }, + { "pink", "Pink", "mcl_dye:pink", "#d66691" }, + { "lime", "Lime", "mcl_dye:green", "#60ad13" }, + { "light_blue", "Light Blue", "mcl_dye:lightblue", "#1f8eca" }, + { "white", "White", "mcl_dye:white", "#d1d7d8" }, +} + +local function color_string_to_table(colorstring) + return { + r = tonumber(colorstring:sub(2,3), 16), -- 16 as second parameter allows hexadecimal + g = tonumber(colorstring:sub(4,5), 16), + b = tonumber(colorstring:sub(6,7), 16), + } +end + +local function av(a, b) + return (a + b)/2 +end + +local function calculate_color(first, last) + return { + r = av(first.r, last.r), + g = av(first.g, last.g), + b = av(first.b, last.b), + } +end + +local function get_texture_function(texture) + local function get_texture(_, itemstack) + local out + local color = itemstack:get_meta():get_string("mcl_armor:color") + if color == "" or color == nil then + out = texture + else + out = texture.."^[hsl:0:100:50^[multiply:"..color + end + + if mcl_enchanting.is_enchanted(itemstack:get_name()) then + return out..mcl_enchanting.overlay + else + return out + end + end + return get_texture +end + +function mcl_armor.colorize_leather_armor(itemstack, colorstring) + if not itemstack or minetest.get_item_group(itemstack:get_name(), "armor_leather") == 0 then + return + end + local color = color_string_to_table(colorstring) + colorstring = minetest.colorspec_to_colorstring(color) + local meta = itemstack:get_meta() + local old_color = meta:get_string("mcl_armor:color") + if old_color == colorstring then return + elseif old_color ~= "" then + color = calculate_color( + color_string_to_table(minetest.colorspec_to_colorstring(old_color)), + color + ) + colorstring = minetest.colorspec_to_colorstring(color) + end + meta:set_string("mcl_armor:color", colorstring) + meta:set_string("inventory_image", + itemstack:get_definition().inventory_image .. "^[hsl:0:100:50^[multiply:" .. colorstring + ) + tt.reload_itemstack_description(itemstack) + return itemstack +end + +function mcl_armor.wash_leather_armor(itemstack) + if not itemstack or minetest.get_item_group(itemstack:get_name(), "armor_leather") == 0 then + return + end + local meta = itemstack:get_meta() + meta:set_string("mcl_armor:color", "") + meta:set_string("inventory_image", "") + tt.reload_itemstack_description(itemstack) + return itemstack +end + +mcl_armor.register_set({ + name = "leather", + description = "Leather", + descriptions = { + head = "Cap", + torso = "Tunic", + legs = "Pants", + }, + durability = 80, + enchantability = 15, + points = { + head = 1, + torso = 3, + legs = 2, + feet = 1, + }, + textures = { + head = get_texture_function("mcl_armor_helmet_leather.png"), + torso = get_texture_function("mcl_armor_chestplate_leather.png"), + legs = get_texture_function("mcl_armor_leggings_leather.png"), + feet = get_texture_function("mcl_armor_boots_leather.png"), + }, + craft_material = "mcl_mobitems:leather", +}) + +tt.register_priority_snippet(function(_, _, itemstack) + if not itemstack or minetest.get_item_group(itemstack:get_name(), "armor_leather") == 0 then + return + end + local color = itemstack:get_meta():get_string("mcl_armor:color") + if color and color ~= "" then + local text = C(mcl_colors.GRAY, "Dyed: "..color) + return text, false + end +end) + +for name, element in pairs(mcl_armor.elements) do + local modname = minetest.get_current_modname() + local itemname = modname .. ":" .. element.name .. "_leather" + minetest.register_craft({ + type = "shapeless", + output = itemname, + recipe = { + itemname, + "group:dye", + }, + }) + local ench_itemname = itemname .. "_enchanted" + minetest.register_craft({ + type = "shapeless", + output = ench_itemname, + recipe = { + ench_itemname, + "group:dye", + }, + }) +end + +local function colorizing_crafting(itemstack, player, old_craft_grid, craft_inv) + if minetest.get_item_group(itemstack:get_name(), "armor_leather") == 0 then + return + end + + local found_la = nil + local dye_color = nil + for _, item in pairs(old_craft_grid) do + local name = item:get_name() + if name == "" then + -- continue + elseif minetest.get_item_group(name, "armor_leather") > 0 then + if found_la then return end + found_la = item + elseif minetest.get_item_group(name, "dye") > 0 then + if dye_color then return end + for _, row in pairs(colors) do + if row[3] == name then dye_color = row[4] end + end + else return end + end + + return mcl_armor.colorize_leather_armor(found_la, dye_color) or ItemStack() +end + +minetest.register_craft_predict(colorizing_crafting) +minetest.register_on_craft(colorizing_crafting) + + +minetest.register_chatcommand("color_leather", { + params = "", + description = "Colorize a piece of leather armor, or wash it", + privs = {debug = true}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + local item = player:get_wielded_item() + if not item or minetest.get_item_group(item:get_name(), "armor_leather") == 0 then + return false, "Not leather armor." + end + if param == "wash" then + player:set_wielded_item(mcl_armor.wash_leather_armor(item)) + return true, "Washed." + end + local colorstring = minetest.colorspec_to_colorstring(param) + if not colorstring then return false, "Invalid color" end + player:set_wielded_item(mcl_armor.colorize_leather_armor(item, colorstring)) + return true, "Done: " .. colorstring + else + return false, "Player isn't online" + end + end, +}) diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.de.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.de.tr index 09da3a9cc..cd2e9a479 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.de.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.de.tr @@ -1,6 +1,6 @@ # textdomain: mcl_armor This is a piece of equippable armor which reduces the amount of damage you receive.=Dies ist ein Teil einer tragbaren Rüstung, die die Menge an Schaden, den Sie erleiden, reduziert. -To equip it, put it on the corresponding armor slot in your inventory menu.=Um es zu tragen, legen Sie es in den passenden Rüstungsplatz in ihrem Inventarmenü. +To equip it, put it on the corresponding armor slot in your inventory menu.=Um es zu tragen, legen Sie es in den passenden Rüstungsplatz in Ihrem Inventarmenü. Leather Cap=Lederkappe Iron Helmet=Eisenhelm Golden Helmet=Goldhelm @@ -21,3 +21,6 @@ Iron Boots=Eisenstiefel Golden Boots=Goldstiefel Diamond Boots=Diamantstiefel Chain Boots=Kettenstiefel + + +Smithing Template '@1'=Schmiedevorlage '@1' \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr index b3a2c6dbc..09d88f5d4 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr @@ -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. Aqua Affinity=Affinité aquatique - +#Translations for armor trims +Smithing Template '@1'=Modèle à forger '@1' diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr index b12f07026..7c11b26c1 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr @@ -46,3 +46,6 @@ Reduces most types of damage by 4% for each level.=Reduz a maioria dos tipos de Thorns=Espinhos Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflete parte do dano tomado aos custos de reduzir a durabilidade com cada uso. Aqua Affinity=Afinidade Aqua + +#Translations for armor trims +Smithing Template '@1'=Molde de Ferraria '@1' diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.ru.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.ru.tr index 77ed83d10..79b7957b7 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.ru.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.ru.tr @@ -1,23 +1,48 @@ # textdomain: mcl_armor -This is a piece of equippable armor which reduces the amount of damage you receive.=Это часть экипирующей брони, уменьшающая получаемый вами урон. -To equip it, put it on the corresponding armor slot in your inventory menu.=Чтобы надеть, поместите её в соответствующий отсек брони в меню вашего инвентаря. -Leather Cap=Кожаная фуражка +This is a piece of equippable armor which reduces the amount of damage you receive.=Это часть надеваемой брони, уменьшающая получаемый вами урон. +To equip it, put it on the corresponding armor slot in your inventory menu.=Чтобы надеть, поместите в соответствующий слот брони в вашем инвентаря. +Leather Cap=Кожаный шлем Iron Helmet=Железный шлем Golden Helmet=Золотой шлем Diamond Helmet=Алмазный шлем -Chain Helmet=Кольчужный капюшон -Leather Tunic=Кожаная туника -Iron Chestplate=Железные латы -Golden Chestplate=Золотые латы -Diamond Chestplate=Алмазные латы +Chain Helmet=Кольчужный шлем +Netherite Helmet=Незеритовый шлем +Leather Tunic=Кожаная кираса +Iron Chestplate=Железная кираса +Golden Chestplate=Золотая кираса +Diamond Chestplate=Алмазная кираса Chain Chestplate=Кольчуга -Leather Pants=Кожаные штаны -Iron Leggings=Железные штаны -Golden Leggings=Золотые штаны -Diamond Leggings=Алмазные штаны -Chain Leggings=Кольчужные штаны +Netherite Chestplate=Незеритовая кираса +Leather Pants=Кожаные поножи +Iron Leggings=Железные поножи +Golden Leggings=Золотые поножи +Diamond Leggings=Алмазные поножи +Chain Leggings=Кольчужные поножи +Netherite Leggings=Незеритовые поножи Leather Boots=Кожаные ботинки Iron Boots=Железные ботинки Golden Boots=Золотые ботинки Diamond Boots=Алмазные ботинки Chain Boots=Кольчужные ботинки +Netherite Boots=Незеритовые ботинки +Elytra=Элитра + +#Translations of enchantements +Increases underwater mining speed.=Увеличивает скорость добычи под водой. +Blast Protection=Взрывоустойчивость +Reduces explosion damage and knockback.=Уменьшает урон и отбрасывание от взрывов. +Curse of Binding=Проклятие несъёмности +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Броню нельзя снять из слота, кроме как умерев, сломав или в режиме творчества. +Feather Falling=Невесомость +Reduces fall damage.=Уменьшает урон от падения. +Fire Protection=Огнеупорность +Reduces fire damage.=Уменьшает урон от огня. +Shooting consumes no regular arrows.=Для стрельбы не требуются обычные стрелы. +Shoot 3 arrows at the cost of one.=Стреляет за раз 3 стрелами тратя только одну. +Projectile Protection=Защита от снарядов +Reduces projectile damage.=Уменьшает урон от летящих снарядов. +Protection=Защита +Reduces most types of damage by 4% for each level.=Уменьшает большинство типов урона на 4% за каждый уровень. +Thorns=Шипы +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Отражает немного полученного урона при ударе ценой снижения прочности при срабатывании. +Aqua Affinity=Подводник diff --git a/mods/ITEMS/mcl_armor/locale/template.txt b/mods/ITEMS/mcl_armor/locale/template.txt index 4b4ad8385..29d98f6b9 100644 --- a/mods/ITEMS/mcl_armor/locale/template.txt +++ b/mods/ITEMS/mcl_armor/locale/template.txt @@ -31,7 +31,7 @@ Elytra= Increases underwater mining speed.= Blast Protection= Reduces explosion damage and knockback.= -Curse of Binding=Malédiction du lien éternel +Curse of Binding= Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= Feather Falling= Reduces fall damage.= @@ -45,4 +45,7 @@ Protection= Reduces most types of damage by 4% for each level.= Thorns= Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.= -Aqua Affinity= \ No newline at end of file +Aqua Affinity= + +#Translations for armor trims +Smithing Template '@1'= diff --git a/mods/ITEMS/mcl_armor/mod.conf b/mods/ITEMS/mcl_armor/mod.conf index fad2e494c..48e00a30c 100644 --- a/mods/ITEMS/mcl_armor/mod.conf +++ b/mods/ITEMS/mcl_armor/mod.conf @@ -1,5 +1,5 @@ name = mcl_armor author = stu description = Adds craftable armor that is visible to other players. -depends = mcl_core, mcl_player, mcl_enchanting, mcl_damage +depends = mcl_core, mcl_player, mcl_enchanting, mcl_damage, mcl_colors, mcl_grindstone optional_depends = mcl_fire, ethereal, bakedclay diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index c7fa91475..4c4330f3e 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -1,24 +1,5 @@ local S = minetest.get_translator(minetest.get_current_modname()) -mcl_armor.register_set({ - name = "leather", - description = "Leather", - descriptions = { - head = "Cap", - torso = "Tunic", - legs = "Pants", - }, - durability = 80, - enchantability = 15, - points = { - head = 1, - torso = 3, - legs = 2, - feet = 1, - }, - craft_material = "mcl_mobitems:leather", -}) - mcl_armor.register_set({ name = "gold", description = "Golden", @@ -227,5 +208,27 @@ minetest.register_tool("mcl_armor:elytra", { on_place = mcl_armor.equip_on_use, on_secondary_use = mcl_armor.equip_on_use, _mcl_armor_element = "torso", - _mcl_armor_texture = "mcl_armor_elytra.png" + _mcl_armor_texture = function(obj, itemstack) + if obj:is_player() then + local cape = mcl_skins.player_skins[obj].cape + if cape ~= "blank.png" then + return cape:gsub("_body", "_elytra") + end + end + return "mcl_armor_elytra.png" + end, + _on_equip = function(obj, itemstack) + if not obj:is_player() then return end + local cape = mcl_skins.player_skins[obj].cape + if cape ~= "blank.png" then + local skinval = mcl_player.player_get_skin(obj) + skinval = skinval:gsub("%^" .. cape, "") + mcl_player.player_set_skin(obj, skinval) + -- this doesn't mess with the data mcl_skins has, so when mcl_skins reloads (which happens when the elytra is unequipped), the normal cape returns + end + end, + _on_unequip = function(obj, itemstack) + if not obj:is_player() then return end + mcl_skins.update_player_skin(obj) + end }) diff --git a/mods/ITEMS/mcl_armor/trims.lua b/mods/ITEMS/mcl_armor/trims.lua new file mode 100644 index 000000000..76d37deb0 --- /dev/null +++ b/mods/ITEMS/mcl_armor/trims.lua @@ -0,0 +1,64 @@ +local mod_registername = minetest.get_current_modname() .. ":" +local S = minetest.get_translator(minetest.get_current_modname()) + +for _, template_name in pairs(mcl_armor.trims.overlays) do + minetest.register_craftitem(mod_registername .. template_name, { + description = S("Smithing Template '@1'", template_name), + inventory_image = template_name .. "_armor_trim_smithing_template.png", + }) + + minetest.register_craft({ + output = mod_registername .. template_name .. " 2", + recipe = { + {"mcl_core:diamond",mod_registername .. template_name,"mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:cobble","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } + }) +end + +--temp craft recipies, missing structures +minetest.register_craft({ + output = mod_registername .. "eye", + recipe = { + {"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_end:ender_eye","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } +}) + +minetest.register_craft({ + output = mod_registername .. "ward", + recipe = { + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:apple_gold_enchanted","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } +}) + +minetest.register_craft({ + output = mod_registername .. "snout", + recipe = { + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:goldblock","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } +}) + +minetest.register_craft({ + output = mod_registername .. "silence", + recipe = { + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + {"mcl_core:diamond", mod_registername.."ward","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } +}) + +minetest.register_craft({ + output = mod_registername .. "wayfinder", + recipe = { + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + {"mcl_core:diamond", "mcl_maps:empty_map","mcl_core:diamond"}, + {"mcl_core:diamond","mcl_core:diamond","mcl_core:diamond"}, + } +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ru.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ru.tr index 6d05d20fc..12eaab8c1 100644 --- a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ru.tr +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_armor_stand -Armor Stand=Стенд защиты -An armor stand is a decorative object which can display different pieces of armor. Anything which players can wear as armor can also be put on an armor stand.=Стенд защиты - декоративный объект, демонстрирующий различные части защиты. Всё, что игрок может носить на себе в качестве защиты, может быть также помещено на данный стенд. -Just place an armor item on the armor stand. To take the top piece of armor from the armor stand, select your hand and use the place key on the armor stand.=Просто поместите элемент защиты на защитный стенд. Чтобы взять верхнюю часть защиты со стенда, выберите вашу руку и используйте клавишу размещения. -Displays pieces of armor=Демонстрирует части защиты +Armor Stand=Стойка для брони +An armor stand is a decorative object which can display different pieces of armor. Anything which players can wear as armor can also be put on an armor stand.=Стойки для брони - декоративный объект, который может показывать различные части брони. Всё, что игрок может носить на себе в качестве брони, может быть также помещено на стойку. +Just place an armor item on the armor stand. To take the top piece of armor from the armor stand, select your hand and use the place key on the armor stand.=Просто поместите предмет брони на стойку для брони. Чтобы забрать верхнюю часть брони со стойки щелкните по стойке пустой рукой. +Displays pieces of armor=Демонстрирует элементы брони diff --git a/mods/ITEMS/mcl_bamboo/README.md b/mods/ITEMS/mcl_bamboo/README.md index b1f91e641..d5b1e7b97 100644 --- a/mods/ITEMS/mcl_bamboo/README.md +++ b/mods/ITEMS/mcl_bamboo/README.md @@ -1,9 +1,9 @@ mcl_bamboo ========= -This mod adds working, familiar bamboo nodes to your Mineclone 2 world. +This mod adds working, familiar bamboo nodes to your VoxeLibre world. -Code: MineClone2 dev team. Original (basic) bamboo code by: Small Joker. +Code: Michieal. Original (basic, used as inspiration) bamboo code by: Small Joker. Updates to the code: VoxeLibre Dev Team, Michieal. License for code: GPLv3. License for images / textures: CC-BY-SA except where noted. @@ -23,4 +23,4 @@ Nicu - You Rock! Small Joker's bamboo forum topic: Forum topic: https://forum.minetest.net/viewtopic.php?id=8289 -Scaffold inspiration: Cora, because she said that it couldn't be done. \ No newline at end of file +Scaffold inspiration: Cora, because she said that it couldn't be done. diff --git a/mods/ITEMS/mcl_bamboo/bamboo_base.lua b/mods/ITEMS/mcl_bamboo/bamboo_base.lua index 4ccb9bb1b..33e0cebaa 100644 --- a/mods/ITEMS/mcl_bamboo/bamboo_base.lua +++ b/mods/ITEMS/mcl_bamboo/bamboo_base.lua @@ -86,6 +86,11 @@ local bamboo_def = { on_rotate = on_rotate, on_place = function(itemstack, placer, pointed_thing) + + if not pointed_thing then + return itemstack + end + if pointed_thing.type ~= "node" then return itemstack end @@ -201,7 +206,7 @@ local bamboo_def = { local node_above_name = minetest.get_node(pointed_thing.above).name mcl_bamboo.mcl_log("\n\n\nnode_above name: " .. node_above_name) if node_above_name ~= "mcl_core:water_source" and node_above_name ~= "mcl_core:lava_source" - and node_above_name ~= "mcl_nether:nether_lava_source" then + and node_above_name ~= "mcl_nether:nether_lava_source" then local _, position = minetest.item_place(place_item, placer, pointed_thing, fdir) if position then if not minetest.is_creative_enabled(placer:get_player_name()) then @@ -246,7 +251,7 @@ local bamboo_def = { minetest.register_node(BAMBOO, bamboo_def) local bamboo_top = table.copy(bamboo_def) -bamboo_top.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, flammable = 3} +bamboo_top.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3} bamboo_top.tiles = {"mcl_bamboo_endcap.png"} bamboo_top.drawtype = "plantlike_rooted" --"plantlike" --bamboo_top.paramtype2 = "meshoptions" @@ -275,24 +280,7 @@ local bamboo_block_def = { _mcl_blast_resistance = 3, _mcl_hardness = 2, _mcl_stripped_variant = "mcl_bamboo:bamboo_block_stripped", -- this allows us to use the built in Axe's strip block. - on_place = function(itemstack, placer, pointed_thing) - - local pos = pointed_thing.under - - if mcl_bamboo.is_protected(pos, placer) then - return - end - - -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(pointed_thing.under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - return minetest.item_place(itemstack, placer, pointed_thing, minetest.dir_to_facedir(vector.direction(pointed_thing.above, pointed_thing.under))) - end, + on_place = mcl_util.rotate_axis, } minetest.register_node("mcl_bamboo:bamboo_block", bamboo_block_def) @@ -349,7 +337,7 @@ bamboo_one_def.selection_box = { {-0.05, -0.5, 0.285, -0.275, 0.5, 0.06}, } } -bamboo_one_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, flammable = 3} +bamboo_one_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3} mcl_bamboo.mcl_log(dump(mcl_bamboo.bamboo_index)) minetest.register_node(mcl_bamboo.bamboo_index[2], bamboo_one_def) local bamboo_two_def = table.copy(bamboo_def) @@ -373,7 +361,7 @@ bamboo_two_def.selection_box = { {0.25, -0.5, 0.325, 0.025, 0.5, 0.100}, } } -bamboo_two_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, flammable = 3} +bamboo_two_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3} minetest.register_node(mcl_bamboo.bamboo_index[3], bamboo_two_def) local bamboo_three_def = table.copy(bamboo_def) @@ -396,5 +384,5 @@ bamboo_three_def.selection_box = { {-0.125, -0.5, 0.125, -0.3125, 0.5, 0.3125}, } } -bamboo_three_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, flammable = 3} +bamboo_three_def.groups = {not_in_creative_inventory = 1, handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3} minetest.register_node(mcl_bamboo.bamboo_index[4], bamboo_three_def) diff --git a/mods/ITEMS/mcl_bamboo/bamboo_items.lua b/mods/ITEMS/mcl_bamboo/bamboo_items.lua index dbc8e6946..a7a28257e 100644 --- a/mods/ITEMS/mcl_bamboo/bamboo_items.lua +++ b/mods/ITEMS/mcl_bamboo/bamboo_items.lua @@ -179,7 +179,7 @@ if minetest.get_modpath("mcl_signs") then -- Bamboo Signs... mcl_signs.register_sign_custom("mcl_bamboo", "_bamboo", "mcl_bamboo_bamboo_sign.png", "#ffffff", "mcl_bamboo_bamboo_sign_wield.png", "mcl_bamboo_bamboo_sign_wield.png", - "Bamboo Sign") + S("Bamboo Sign")) mcl_signs.register_sign_craft("mcl_bamboo", BAMBOO_PLANK, "_bamboo") minetest.register_alias("bamboo_sign", "mcl_signs:wall_sign_bamboo") end @@ -192,10 +192,23 @@ if minetest.get_modpath("mcl_fences") then local wood_groups = { handy = 1, axey = 1, flammable = 2, fence_wood = 1, fire_encouragement = 5, fire_flammability = 20 } local wood_connect = { "group:fence_wood" } - local fence_id = mcl_fences.register_fence(id, S("Bamboo Fence"), "mcl_bamboo_fence_bamboo.png", wood_groups, - 2, 15, wood_connect, node_sound) - local gate_id = mcl_fences.register_fence_gate(id, S("Bamboo Fence Gate"), "mcl_bamboo_fence_gate_bamboo.png", - wood_groups, 2, 15, node_sound) -- note: about missing params.. will use defaults. + local fence_id = mcl_fences.register_fence( + id, + S("Bamboo Fence"), + "mcl_bamboo_fence_bamboo.png", + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + wood_connect, node_sound) + + local gate_id = mcl_fences.register_fence_gate( + id, + S("Bamboo Fence Gate"), + "mcl_bamboo_fence_gate_bamboo.png", + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + node_sound) -- note: about missing params.. will use defaults. mcl_bamboo.mcl_log(dump(fence_id)) mcl_bamboo.mcl_log(dump(gate_id)) @@ -212,7 +225,7 @@ if minetest.get_modpath("mesecons_button") then { material_wood = 1, handy = 1, pickaxey = 1, flammable = 3, fire_flammability = 20, fire_encouragement = 5, }, 1, false, - S("A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."), + S("A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second."), "mesecons_button_push") end end @@ -303,10 +316,15 @@ minetest.register_node(SCAFFOLDING_NAME, { -- A quick check, that may or may not work, to attempt to prevent placing things on the side of other nodes. local dir = vector.subtract(pointed.under, pointed.above) local wdir = minetest.dir_to_wallmounted(dir) + local anode = minetest.get_node(pointed.above).name if wdir == 1 then - minetest.set_node(pointed.above, { name = SCAFFOLDING_NAME, param2 = 0 }) - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item(1) + if (anode == "air" or minetest.registered_nodes[anode].buildable_to) and not mcl_bamboo.is_protected(pointed.above, placer) then + minetest.set_node(pointed.above, { name = SCAFFOLDING_NAME, param2 = 0 }) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item(1) + end + else + return end return itemstack else diff --git a/mods/ITEMS/mcl_bamboo/globals.lua b/mods/ITEMS/mcl_bamboo/globals.lua index f96395228..37fafc2fd 100644 --- a/mods/ITEMS/mcl_bamboo/globals.lua +++ b/mods/ITEMS/mcl_bamboo/globals.lua @@ -67,7 +67,7 @@ end local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap" --- For when I learn more about the pistons... +-- check if supporting block is broken. pistons now break the bamboo plant. function mcl_bamboo.break_orphaned(pos) mcl_bamboo.mcl_log("Break_Orphaned called.") local node_below = minetest.get_node(vector.offset(pos, 0, -1, 0)) diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr index 5e05302df..a50dbfa70 100644 --- a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr @@ -3,7 +3,7 @@ ### init.lua ### -A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=En bambusknap er en rødstenskomponent lavet af sten som giver rødstensenergi når den aktiveres. Når den aktiveres forsyner den tilstøende rødstenskomponenter i 1 sekund. +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=En bambusknap er en rødstenskomponent lavet af sten som giver rødstensenergi når den aktiveres. Når den aktiveres forsyner den tilstøende rødstenskomponenter i 1 sekund. A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=En trætrykplade er en rødstenskomponent som forsyner omkringliggende blokke med rødstensenergi når et bevægeligt objekt (inklusiv tabte genstande, spillere og monstre) er ovenpå den. diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr index e21beb760..bef0e03f5 100644 --- a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr @@ -8,7 +8,7 @@ Stripped Bamboo Block=Bloque de bambú sin corteza ### bamboo_items.lua ### -A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Un botón de bambú es un componente de redstone hecho de piedra que se puede presionar para proporcionar energía de redstone. Cuando se empuja, alimenta los componentes adyacentes de redstone durante 1 segundo. +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Un botón de bambú es un componente de redstone hecho de piedra que se puede presionar para proporcionar energía de redstone. Cuando se empuja, alimenta los componentes adyacentes de redstone durante 1 segundo. A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Una placa de presión de madera es un componente de redstone que proporciona energía de redstone a sus bloques adyacentes mientras cualquier objeto movible (incluyendo objetos en el suelo, jugadores y mobs) descanse encima suya. diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr index 953d08811..e83f1d87f 100644 --- a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr @@ -10,7 +10,7 @@ Bamboo Block=Bloc de bambou ### bamboo_items.lua ### -A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Un bouton en bambou est un composant redstone fait de bamboo qui peut être poussé pour fournir un signal redstone. Lorsque poussé, il alimente les composants redstone adjacents pendant 1 seconde. +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Un bouton en bambou est un composant redstone fait de bamboo qui peut être poussé pour fournir un signal redstone. Lorsque poussé, il alimente les composants redstone adjacents pendant 1 seconde. A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Une plaque de pression en bois est un composant redstone qui envoie un signal aux blocs alentours lorsque n'importe quel objet mobile (objet jeté, joueurs et mobs) sont dessus. @@ -24,6 +24,7 @@ Bamboo Mosaic Stair=Escalier mosaïque de bambou Bamboo Plank Slab=Dalle de planches de bambou Bamboo Plank Stair=Escalier de planches de bambou Bamboo Pressure Plate=Plaque de pression de bambou +Bamboo Sign=Panneau de bambou Bamboo Slab=Dalle de bambou Bamboo Stair=Escalier de bambou Bamboo Trapdoor=Trappe de bambou diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.pt_BR.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.pt_BR.tr new file mode 100644 index 000000000..8517b0cbe --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.pt_BR.tr @@ -0,0 +1,46 @@ +# textdomain: mcl_bamboo + +### bamboo_base.lua ### + +Bamboo=Bambu +Bamboo Mosaic Plank=Mosaico de Tábuas de Bambu +Bamboo Plank=Tábuas de Bambu +Stripped Bamboo Block=Bloco de Bambu Descascado +Bamboo Block=Bloco de Bambu + +### bamboo_items.lua ### + +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Um botão de bambu é um componente de redstone feito de bambu ao qual pode ser empurrado para providenciar carga de redstone. Quando empurrado, energiza componentes de redstone adjacentes por 1 segundo. + +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Uma placa de pressão de madeira é um componente de redstone ao qual alimenta os blocos ao seu redor com uma carga de redstone enquanto qualquer objeto móvel (incluindo itens largados, jogadores e mobs) parar em cima dela. + +Bamboo=Bambu +Bamboo Button=Botão de Bambu +Bamboo Door=Porta de Bambu +Bamboo Fence=Cerca de Bambu +Bamboo Fence Gate=Portão de Bambu +Bamboo Mosaic Slab=Laje de Mosaico de Bambu +Bamboo Mosaic Stair=Escada de Mosaico de Bambu +Bamboo Plank Slab=Laje de Tábuas de Bambu +Bamboo Plank Stair=Escada de Tábuas de Bambu +Bamboo Pressure Plate=Placa de Pressão de Bambu +Bamboo Sign=Placa de Bambu +Bamboo Slab=Laje de Bambu +Bamboo Stair=Escada de Bambu +Bamboo Trapdoor=Alçapão de Bambu +Double Bamboo Mosaic Slab=Laje Dupla de Mosaico de Bambu +Double Bamboo Plank Slab=Laje Dupla de Tábuas de Bambu +Double Bamboo Slab=Laje Dupla de Bambu +Double Stripped Bamboo Slab=Laje Dupla de Bambu Descascado +Scaffolding=Andaime +Scaffolding (horizontal)=Andaime (horizontal) +Scaffolding block used to climb up or out across areas.=Bloco de andaime é usado para escalar ou cruzar áreas. +Stripped Bamboo Slab=Laje de Bambu Descascado +Stripped Bamboo Stair=Escada de Bambu Descascado + +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Para abrir ou fechar o alçapão, clique com o botão direito ou mande-o um sinal de redstone. + +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Alçapões de madeira são barreiras horizontais as quais podem ser abertas ou fechadas com a mão ou um sinal de redstone. Eles ocupam a parte superior ou inferior de um bloco, dependendo de como eles são posicionados. Quando abertos, eles são escaláveis como uma escada. + +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Portas de madeira são barreiras de 2 blocos de altura as quais podem ser abertas ou fechadas com a mão ou um sinal de redstone. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Para abrir ou fechar uma porta de madeira, clique com o botão direito nela ou alimente sua metade inferior com um sinal de redstone. diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.ru.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.ru.tr index 3ae22d3c6..7ba49317c 100644 --- a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.ru.tr +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.ru.tr @@ -5,14 +5,14 @@ Bamboo=Бамбук Bamboo Mosaic Plank=Бамбуковая мозаика Bamboo Plank=Бамбуковые доски -Stripped Bamboo Block=Блок обтёсанного бамбука -Bamboo Block=Блок бамбука +Stripped Bamboo Block=Обтёсанный бамбуковый блок +Bamboo Block=Бамбуковый блок ### bamboo_items.lua ### -A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Бамбуковая кнопка - это компонент красного камня, который изготовлен из краснокаменной руды. Ее можно нажать, чтобы обеспечить питание красному камню. При нажатии он приводит в действие соседние компоненты красного камня на 1 секунду. +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.=Бамбуковая кнопка это компонент редстоуна, сделанный из бамбука, её можно нажать, чтобы получить сигнал редстоуна. При нажатии она включает соседние компоненты редстоуна на 1 с. -A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Деревянная нажимная пластина - это компонент красного камня, который снабжает окружающие блоки энергией красного камня, в то время как любой подвижный объект (включая выпавшие предметы, игроков и мобов) стоит на ней. +A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.=Нажимная плита это компонент редстоуна, который выдает сигнал редстоуна окружающим его блокам, когда кто-то или что-то находится прямо на нём. Bamboo=Бамбук Bamboo Button=Бамбуковая кнопка @@ -20,26 +20,24 @@ Bamboo Door=Бамбуковая дверь Bamboo Fence=Бамбуковый забор Bamboo Fence Gate=Бамбуковая калитка Bamboo Mosaic Slab=Плита из бамбуковой мозаики -Bamboo Mosaic Stair=Ступеньки из бамбуковой мозаики -Bamboo Plank Slab=Бамбуковая плита из досок -Bamboo Plank Stair=Бамбуковые ступеньки из досок +Bamboo Mosaic Stair=Ступени из бамбуковой мозаики +Bamboo Plank Slab=Плита из бамбуковых досок +Bamboo Plank Stair=Ступени из бамбуковых досок Bamboo Pressure Plate=Бамбуковая нажимная плита +Bamboo Sign=Бамбуковая табличка Bamboo Slab=Бамбуковая плита -Bamboo Stair=Бамбуковые ступеньки +Bamboo Stair=Бамбуковые ступени Bamboo Trapdoor=Бамбуковый люк Double Bamboo Mosaic Slab=Двойная бамбуковая мозаичная плита -Double Bamboo Plank Slab=Двойная бамбуковая дощатая плита +Double Bamboo Plank Slab=Двойная плита из бамбуковых досок Double Bamboo Slab=Двойная бамбуковая плита -Double Stripped Bamboo Slab=Двойная обтесанная бамбуковая плита +Double Stripped Bamboo Slab=Двойная обтёсанная бамбуковая плита Scaffolding=Строительные леса -Scaffolding (horizontal)=Строительные леса (горизонтальный) +Scaffolding (horizontal)=Строительные леса (горизонтальные) Scaffolding block used to climb up or out across areas.=Блок строительных лесов, используемый для подъема вверх или перемещения по другим участкам. -Stripped Bamboo Slab=Обтесанная бамбуковая плита -Stripped Bamboo Stair=Обтесанные бамбуковые ступеньки - -To open or close the trapdoor, rightclick it or send a redstone signal to it.=Чтобы открыть или закрыть люк, щелкните по нему правой кнопкой мыши или отправьте на него сигнал redstone. - -Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Деревянные люки - это горизонтальные барьеры, которые можно открывать и закрывать вручную или по сигналу красного камня. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были размещены. Когда они открыты, по ним можно подниматься, как по лестнице. - -Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери представляют собой барьеры высотой в 2 блока, которые можно открывать или закрывать вручную и по сигналу redstone. -To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Чтобы открыть или закрыть деревянную дверь, щелкните по ней правой кнопкой мыши или снабдите ее нижнюю половину сигналом красного камня. +Stripped Bamboo Slab=Обтёсанная бамбуковая плита +Stripped Bamboo Stair=Обтёсанные бамбуковые ступени +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Чтобы открыть или закрыть деревянный люк, кликните по нему правой кнопкой либо подайте на него сигнал редстоуна. +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Деревянные люки это горизонтальные преграды, которые можно открывать и закрывать вручную и по сигналу редстоуна. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери это преграды высотой в 2 блока, которые можно открывать и закрывать вручную и по сигналу редстоуна. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Чтобы открыть или закрыть деревянную дверь, кликните правой кнопкой или подайте к её нижней части сигнал редстоуна. diff --git a/mods/ITEMS/mcl_bamboo/locale/template.txt b/mods/ITEMS/mcl_bamboo/locale/template.txt index 2d5c69383..0752bf364 100644 --- a/mods/ITEMS/mcl_bamboo/locale/template.txt +++ b/mods/ITEMS/mcl_bamboo/locale/template.txt @@ -10,7 +10,7 @@ Bamboo Block= ### bamboo_items.lua ### -A bamboo button is a redstone component made out of stone which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.= +A bamboo button is a redstone component made out of bamboo which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1 second.= A wooden pressure plate is a redstone component which supplies its surrounding blocks with redstone power while any movable object (including dropped items, players and mobs) rests on top of it.= @@ -24,6 +24,7 @@ Bamboo Mosaic Stair= Bamboo Plank Slab= Bamboo Plank Stair= Bamboo Pressure Plate= +Bamboo Sign= Bamboo Slab= Bamboo Stair= Bamboo Trapdoor= diff --git a/mods/ITEMS/mcl_banners/README.txt b/mods/ITEMS/mcl_banners/README.txt index 4de3ce439..d944c437d 100644 --- a/mods/ITEMS/mcl_banners/README.txt +++ b/mods/ITEMS/mcl_banners/README.txt @@ -1,6 +1,6 @@ License of code: WTFPL -License of textures: See README.md in top directory of MineClone 2. +License of textures: See README.md in top directory of VoxeLibre. License of models: GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) Models author: 22i. diff --git a/mods/ITEMS/mcl_banners/init.lua b/mods/ITEMS/mcl_banners/init.lua index 18b50928a..8c2c1298c 100644 --- a/mods/ITEMS/mcl_banners/init.lua +++ b/mods/ITEMS/mcl_banners/init.lua @@ -22,22 +22,22 @@ mcl_banners = {} mcl_banners.colors = { -- Format: -- [ID] = { banner description, wool, unified dyes color group, overlay color, dye, color name for emblazonings } - ["unicolor_white"] = {"white", S("White Banner"), "mcl_wool:white", "#FFFFFF", "mcl_dye:white", N("White") }, + ["unicolor_white"] = {"white", S("White Banner"), "mcl_wool:white", "#C8C8C8", "mcl_dye:white", N("White") }, ["unicolor_darkgrey"] = {"grey", S("Grey Banner"), "mcl_wool:grey", "#303030", "mcl_dye:dark_grey", N("Grey") }, ["unicolor_grey"] = {"silver", S("Light Grey Banner"), "mcl_wool:silver", "#5B5B5B", "mcl_dye:grey", N("Light Grey") }, ["unicolor_black"] = {"black", S("Black Banner"), "mcl_wool:black", "#000000", "mcl_dye:black", N("Black") }, - ["unicolor_red"] = {"red", S("Red Banner"), "mcl_wool:red", "#BC0000", "mcl_dye:red", N("Red") }, - ["unicolor_yellow"] = {"yellow", S("Yellow Banner"), "mcl_wool:yellow", "#E6CD00", "mcl_dye:yellow", N("Yellow") }, - ["unicolor_dark_green"] = {"green", S("Green Banner"), "mcl_wool:green", "#006000", "mcl_dye:dark_green", N("Green") }, - ["unicolor_cyan"] = {"cyan", S("Cyan Banner"), "mcl_wool:cyan", "#00ACAC", "mcl_dye:cyan", N("Cyan") }, - ["unicolor_blue"] = {"blue", S("Blue Banner"), "mcl_wool:blue", "#0000AC", "mcl_dye:blue", N("Blue") }, - ["unicolor_red_violet"] = {"magenta", S("Magenta Banner"), "mcl_wool:magenta", "#AC007C", "mcl_dye:magenta", N("Magenta")}, - ["unicolor_orange"] = {"orange", S("Orange Banner"), "mcl_wool:orange", "#E67300", "mcl_dye:orange", N("Orange") }, - ["unicolor_violet"] = {"purple", S("Purple Banner"), "mcl_wool:purple", "#6400AC", "mcl_dye:violet", N("Violet") }, - ["unicolor_brown"] = {"brown", S("Brown Banner"), "mcl_wool:brown", "#603000", "mcl_dye:brown", N("Brown") }, - ["unicolor_pink"] = {"pink", S("Pink Banner"), "mcl_wool:pink", "#DE557C", "mcl_dye:pink", N("Pink") }, - ["unicolor_lime"] = {"lime", S("Lime Banner"), "mcl_wool:lime", "#30AC00", "mcl_dye:green", N("Lime") }, - ["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#4040CF", "mcl_dye:lightblue", N("Light Blue") }, + ["unicolor_red"] = {"red", S("Red Banner"), "mcl_wool:red", "#760F15", "mcl_dye:red", N("Red") }, + ["unicolor_yellow"] = {"yellow", S("Yellow Banner"), "mcl_wool:yellow", "#E2b43E", "mcl_dye:yellow", N("Yellow") }, + ["unicolor_dark_green"] = {"green", S("Green Banner"), "mcl_wool:green", "#385833", "mcl_dye:dark_green", N("Green") }, + ["unicolor_cyan"] = {"cyan", S("Cyan Banner"), "mcl_wool:cyan", "#114C56", "mcl_dye:cyan", N("Cyan") }, + ["unicolor_blue"] = {"blue", S("Blue Banner"), "mcl_wool:blue", "#20336B", "mcl_dye:blue", N("Blue") }, + ["unicolor_red_violet"] = {"magenta", S("Magenta Banner"), "mcl_wool:magenta", "#B36897", "mcl_dye:magenta", N("Magenta")}, + ["unicolor_orange"] = {"orange", S("Orange Banner"), "mcl_wool:orange", "#B35E2E", "mcl_dye:orange", N("Orange") }, + ["unicolor_violet"] = {"purple", S("Purple Banner"), "mcl_wool:purple", "#764F91", "mcl_dye:violet", N("Violet") }, + ["unicolor_brown"] = {"brown", S("Brown Banner"), "mcl_wool:brown", "#46251A", "mcl_dye:brown", N("Brown") }, + ["unicolor_pink"] = {"pink", S("Pink Banner"), "mcl_wool:pink", "#C98196", "mcl_dye:pink", N("Pink") }, + ["unicolor_lime"] = {"lime", S("Lime Banner"), "mcl_wool:lime", "#7DA553", "mcl_dye:green", N("Lime") }, + ["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#5176B2", "mcl_dye:lightblue", N("Light Blue") }, } @@ -96,8 +96,8 @@ end dofile(modpath.."/patterncraft.lua") -- Overlay ratios (0-255) -local base_color_ratio = 224 -local layer_ratio = 255 +local base_color_ratio = 225 +local layer_ratio = 225 local standing_banner_entity_offset = { x=0, y=-0.499, z=0 } local hanging_banner_entity_offset = { x=0, y=-1.7, z=0 } @@ -181,7 +181,7 @@ function mcl_banners.make_banner_texture(base_color, layers) local color = mcl_banners.colors[layerinfo.color][4] -- Generate layer texture - local layer = "(("..pattern.."^[colorize:"..color..":"..layer_ratio..")^[mask:"..pattern..")" + local layer = "((mcl_banners_banner_base.png^[colorize:"..color..":"..layer_ratio..")^[mask:"..pattern..")" finished_banner = finished_banner .. "^" .. layer end diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr index 78095a4a7..016abb6e7 100644 --- a/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr @@ -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 @1 additional layers=Et @1 couches supplémentaires Paintable decoration=Décoration à peindre +Preview Banner=Aperçu de la bannière diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr index a6cee5a67..4f2659e50 100644 --- a/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr @@ -13,65 +13,67 @@ Yellow Banner=Жёлтый флаг Yellow=Жёлтый Green Banner=Зелёный флаг Green=Зелёный -Cyan Banner=Голубой флаг +Cyan Banner=Бирюзовый флаг Cyan=Голубой Blue Banner=Синий флаг Blue=Синий -Magenta Banner=Фиолетовый флаг -Magenta=Фиолетовый +Magenta Banner=Сиреневый флаг +Magenta=Сиреневый Orange Banner=Оранжевый флаг Orange=Оранжевый -Purple Banner=Пурпурный флаг -Violet=Пурпурный +Purple Banner=Фиолетовый флаг +Violet=Фиолетовый Brown Banner=Коричневый флаг Brown=Коричневый Pink Banner=Розовый флаг Pink=Розовый -Lime Banner=Зелёный лаймовый флаг +Lime Banner=Лаймовый флаг Lime=Зелёный лаймовый -Light Blue Banner=Светло-голубой флаг -Light Blue=Светло-голубой -Banners are tall colorful decorative blocks. They can be placed on the floor and at walls. Banners can be emblazoned with a variety of patterns using a lot of dye in crafting.=Баннеры - высокие цветные декоративные блоки. Их можно размещать на полу и на стенах. Флаги можно украшать разнообразными узорами при помощью красителей во время создания. -Use crafting to draw a pattern on top of the banner. Emblazoned banners can be emblazoned again to combine various patterns. You can draw up to 12 layers on a banner that way. If the banner includes a gradient, only 3 layers are possible.=Используйте крафтинг, чтобы нарисовать узор поверх флага. Украшенные флаги можно украсить повторно, чтобы сочетать разные узоры. Таким способом вы можете нарисовать до 12 слоев на одном флаге. Если флаг содержит градиент, возможно только 3 слоя. -You can copy the pattern of a banner by placing two banners of the same color in the crafting grid—one needs to be emblazoned, the other one must be clean. Finally, you can use a banner on a cauldron with water to wash off its top-most layer.=Вы можете скопировать рисунок флага, поместив два флага одного цвета в крафтинговую решётку - один должен быть украшенный, другой - чистый. Наконец, вы можете [использовать] флаг на котле с водой для смывания верхнего слоя. -@1 Bordure=@1 Кайма -@1 Bricks=@1 Кирпичи -@1 Roundel=@1 Рондо -@1 Creeper Charge=@1 Атака крипера -@1 Saltire=@1 Андреевский крест -@1 Bordure Indented=@1 Кайма с отступом -@1 Per Bend Inverted=@1 Повторяющийся изгиб поворотом -@1 Per Bend Sinister Inverted=@1 Повторяющийся зловещий изгиб с поворотом -@1 Per Bend=@1 Повторяющийся изгиб -@1 Per Bend Sinister=@1 Зловещий изгиб -@1 Flower Charge=@1 Забота о цветке -@1 Gradient=@1 Градиент -@1 Base Gradient=@1 Основной градиент -@1 Per Fess Inverted=@1 Обратное деление щита -@1 Per Fess=@1 Деление щита -@1 Per Pale=@1 Вертикальное деление щита -@1 Per Pale Inverted=@1 Вертикальное обратное деление -@1 Thing Charge=@1 Атака существа -@1 Lozenge=@1 Ромб -@1 Skull Charge=@1 Атака черепа -@1 Paly=@1 Бледный -@1 Base Dexter Canton=@1 Основной правый кант -@1 Base Sinister Canton=@1 Основной зловещий кант -@1 Chief Dexter Canton=@1 Главный правый кант -@1 Chief Sinister Canton=@1 Главный зловещий кант -@1 Cross=@1 Крест -@1 Base=@1 Основа -@1 Pale=@1 Черта -@1 Bend Sinister=@1 Зловещий изгиб -@1 Bend=@1 Изгиб -@1 Pale Dexter=@1 Черты справа +Light Blue Banner=Голубой флаг +Light Blue=Голубой +Banner=Флаг +Banners are tall colorful decorative blocks. They can be placed on the floor and at walls. Banners can be emblazoned with a variety of patterns using a lot of dye in crafting.=Флаги - высокие цветные декоративные блоки. Их можно размещать на полу и на стенах. Флаги можно украшать разнообразными узорами при помощью красителей во время создания. +Use crafting to draw a pattern on top of the banner. Emblazoned banners can be emblazoned again to combine various patterns. You can draw up to 12 layers on a banner that way. If the banner includes a gradient, only 3 layers are possible.=Используйте сетку крафта, чтобы нарисовать узор поверх флага. Украшенные флаги можно украсить повторно, чтобы сочетать разные узоры. Таким способом вы можете нарисовать до 12 слоев на одном флаге. Если флаг содержит градиент, возможно только 3 слоя. +You can copy the pattern of a banner by placing two banners of the same color in the crafting grid—one needs to be emblazoned, the other one must be clean. Finally, you can use a banner on a cauldron with water to wash off its top-most layer.=Вы можете скопировать рисунок флага, поместив два флага одного цвета в сетку крафта - один должен быть украшенный, другой - чистый. Вы можете использовать флаг на котле с водой, чтобы смыть верхний слой. +@1 Bordure=@1 простая кайма +@1 Bricks=@1 кирпичный фон +@1 Roundel=@1 круг в центре +@1 Creeper Charge=@1 лицо крипера +@1 Saltire=@1 диагональный крест +@1 Bordure Indented=@1 рельефная кайма +@1 Per Bend Inverted=@1 нижняя левая половина +@1 Per Bend Sinister Inverted=@1 нижняя правая половина +@1 Per Bend=@1 верхняя правая половина +@1 Per Bend Sinister=@1 верхняя левая половина +@1 Flower Charge=@1 цветок +@1 Gradient=@1 верхний градиент +@1 Base Gradient=@1 нижний градиент +@1 Per Fess Inverted=@1 нижняя половина +@1 Per Fess=@1 верхняя половина +@1 Per Pale=@1 левая половина +@1 Per Pale Inverted=@1 правая половина +@1 Thing Charge=@1 нечто +@1 Lozenge=@1 Ромб в центре +@1 Skull Charge=@1 Весёлый Роджер +@1 Paly=@1 продольные полосы +@1 Base Dexter Canton=@1 нижний левый угол +@1 Base Sinister Canton=@1 нижний правый угол +@1 Chief Dexter Canton=@1 верхний левый угол +@1 Chief Sinister Canton=@1 верхний правый угол +@1 Cross=@1 крест +@1 Base=@1 треть снизу +@1 Pale=@1 вертикальная центральная линия +@1 Bend Sinister=@1 диагональная линия сверху справа +@1 Bend=@1 диагональная линия сверху слева +@1 Pale Dexter=@1 треть слева @1 Fess=@1 Разделение -@1 Pale Sinister=@1 Бледный зловещий -@1 Chief=@1 Главный -@1 Chevron=@1 Шеврон -@1 Chevron Inverted=@1 Инвертированный шеврон -@1 Base Indented=@1 Инвертированный основной -@1 Chief Indented=@1 Инвертированный главный -And one additional layer=И один индивидуальный слой -And @1 additional layers=И @1 дополнительныйх слойёв -Paintable decoration=Художественное украшение +@1 Pale Sinister=@1 треть справа +@1 Chief=@1 треть сверху +@1 Chevron=@1 треугольник снизу +@1 Chevron Inverted=@1 треугольник сверху +@1 Base Indented=@1 гребешки снизу +@1 Chief Indented=@1 гребешки сверху +And one additional layer=И один дополнительный слой +And @1 additional layers=И @1 дополнительных слоёв +Paintable decoration=Раскрашиваемая декорация +Preview Banner=Предпросмотр баннера diff --git a/mods/ITEMS/mcl_banners/locale/template.txt b/mods/ITEMS/mcl_banners/locale/template.txt index 357ff6b08..1c10dbeeb 100644 --- a/mods/ITEMS/mcl_banners/locale/template.txt +++ b/mods/ITEMS/mcl_banners/locale/template.txt @@ -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= And @1 additional layers= Paintable decoration= +Preview Banner= diff --git a/mods/ITEMS/mcl_banners/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index 767235b1e..3beb9550d 100644 --- a/mods/ITEMS/mcl_banners/patterncraft.lua +++ b/mods/ITEMS/mcl_banners/patterncraft.lua @@ -36,7 +36,7 @@ local patterns = { ["creeper"] = { name = N("@1 Creeper Charge"), type = "shapeless", - { e, "mcl_heads:creeper", d }, + { e, "mcl_heads:stalker", d }, }, ["cross"] = { name = N("@1 Saltire"), diff --git a/mods/ITEMS/mcl_barrels/init.lua b/mods/ITEMS/mcl_barrels/init.lua index 714a80f09..face52d6d 100644 --- a/mods/ITEMS/mcl_barrels/init.lua +++ b/mods/ITEMS/mcl_barrels/init.lua @@ -8,6 +8,7 @@ local open_barrels = {} local drop_content = mcl_util.drop_items_from_meta_container("main") +---@param pos Vector local function on_blast(pos) local node = minetest.get_node(pos) drop_content(pos, node) @@ -45,30 +46,37 @@ local function barrel_open(pos, node, clicker) local playername = clicker:get_player_name() minetest.show_formspec(playername, - "mcl_barrels:barrel_"..pos.x.."_"..pos.y.."_"..pos.z, + "mcl_barrels:barrel_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, table.concat({ - "size[9,8.75]", - "label[0,0;"..F(C("#313131", name)).."]", - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]", - mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3), - "label[0,4.0;"..F(C("#313131", S("Inventory"))).."]", - "list[current_player;main;0,4.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3), - "list[current_player;main;0,7.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1), - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]", + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(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[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main]", "listring[current_player;main]", }) ) - minetest.swap_node(pos, { name = "mcl_barrels:barrel_open", param2 = node.param2 }) + minetest.swap_node(pos, { name = "mcl_barrels:barrel_open", param2 = node.param2 }) open_barrels[playername] = pos - minetest.sound_play({name="mcl_barrels_default_barrel_open", pos=pos, gain=0.5, max_hear_distance=16}, true) + minetest.sound_play({name="mcl_barrels_default_barrel_open", gain=0.5}, { + pos = pos, + max_hear_distance = 16, + }, true) end +---@param pos Vector local function close_forms(pos) local players = minetest.get_connected_players() - local formname = "mcl_barrels:barrel_"..pos.x.."_"..pos.y.."_"..pos.z + local formname = "mcl_barrels:barrel_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then minetest.close_formspec(players[p]:get_player_name(), formname) @@ -76,15 +84,21 @@ local function close_forms(pos) end end +---@param pos Vector local function update_after_close(pos) local node = minetest.get_node_or_nil(pos) if not node then return end if node.name == "mcl_barrels:barrel_open" then - minetest.swap_node(pos, {name = "mcl_barrels:barrel_closed", param2 = node.param2}) - minetest.sound_play({name="mcl_barrels_default_barrel_close", pos=pos, gain=0.5, max_hear_distance=16}, true) + minetest.swap_node(pos, { name = "mcl_barrels:barrel_closed", param2 = node.param2 }) + minetest.sound_play({name="mcl_barrels_default_barrel_close", gain=0.5}, { + pos = pos, + max_hear_distance = 16, + }, true) + end end +---@param player ObjectRef local function close_barrel(player) local name = player:get_player_name() local open = open_barrels[name] @@ -102,20 +116,22 @@ minetest.register_node("mcl_barrels:barrel_closed", { _tt_help = S("27 inventory slots"), _doc_items_longdesc = S("Barrels are containers which provide 27 inventory slots."), _doc_items_usagehelp = S("To access its inventory, rightclick it. When broken, the items will drop out."), - tiles = {"mcl_barrels_barrel_top.png^[transformR270", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png"}, + tiles = { "mcl_barrels_barrel_top.png^[transformR270", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png" }, paramtype = "light", paramtype2 = "facedir", on_place = function(itemstack, placer, pointed_thing) - minetest.rotate_and_place(itemstack, placer, pointed_thing, minetest.is_creative_enabled(placer:get_player_name()), {}, false) + minetest.rotate_and_place(itemstack, placer, pointed_thing, + minetest.is_creative_enabled(placer:get_player_name()), {} + , false) return itemstack end, stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1}, + groups = { handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1 }, on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) end, after_place_node = function(pos, placer, itemstack, pointed_thing) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) @@ -124,16 +140,16 @@ minetest.register_node("mcl_barrels:barrel_closed", { allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from barrel at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, @@ -149,27 +165,35 @@ minetest.register_node("mcl_barrels:barrel_open", { _doc_items_longdesc = S("Barrels are containers which provide 27 inventory slots."), _doc_items_usagehelp = S("To access its inventory, rightclick it. When broken, the items will drop out."), _doc_items_create_entry = false, - tiles = {"mcl_barrels_barrel_top_open.png", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png"}, + tiles = { "mcl_barrels_barrel_top_open.png", "mcl_barrels_barrel_bottom.png", "mcl_barrels_barrel_side.png" }, paramtype = "light", paramtype2 = "facedir", drop = "mcl_barrels:barrel_closed", stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {handy = 1, axey = 1, container = 2, material_wood = 1, flammable = -1, deco_block = 1, not_in_creative_inventory = 1}, + groups = { + handy = 1, + axey = 1, + container = 2, + material_wood = 1, + flammable = -1, + deco_block = 1, + not_in_creative_inventory = 1 + }, allow_metadata_inventory_move = protection_check_move, allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to barrel at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from barrel at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from barrel at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, @@ -193,10 +217,10 @@ end) minetest.register_craft({ output = "mcl_barrels:barrel_closed", recipe = { - {"group:wood", "group:wood_slab", "group:wood"}, - {"group:wood", "", "group:wood"}, - {"group:wood", "group:wood_slab", "group:wood"}, - } + { "group:wood", "group:wood_slab", "group:wood" }, + { "group:wood", "", "group:wood" }, + { "group:wood", "group:wood_slab", "group:wood" }, + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr index 2d860c532..680d6874d 100644 --- a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_barrels Barrel=Бочка -Barrels are containers which provide 27 inventory slots.=Бочки — это хранилища, у которых 27 ячеек хранения. -To access its inventory, rightclick it. When broken, the items will drop out.=Чтобы получить доступ к хранилищу, нажмите по нему правой кнопкой мыши. Если его сломать, тогда выпадут предметы. -27 inventory slots=27 ячеек хранения \ No newline at end of file +Barrels are containers which provide 27 inventory slots.=Бочки — это хранилища, у которых 27 слотов инвентаря. +To access its inventory, rightclick it. When broken, the items will drop out.=Чтобы получить доступ к хранилищу, нажмите по нему правой кнопкой мыши. Если его сломать предметы выпадут. +27 inventory slots=27 слотов инвентаря \ No newline at end of file diff --git a/mods/ITEMS/mcl_beacons/init.lua b/mods/ITEMS/mcl_beacons/init.lua index 9941e9e50..e17de8a0e 100644 --- a/mods/ITEMS/mcl_beacons/init.lua +++ b/mods/ITEMS/mcl_beacons/init.lua @@ -4,8 +4,12 @@ there are strings in meta, which are being used to see which effect will be give Valid strings: swiftness leaping - strenght + strength regeneration + haste + resistance + slow_falling + absorption ]]-- mcl_beacons = { @@ -80,6 +84,9 @@ local pallete_order = { pane_magenta_flat = 16, pane_magenta = 16 } +local EFFECT_CONVERSIONS = { + strenght = "strength" +} local function get_beacon_beam(glass_nodename) if glass_nodename == "air" then return 0 end @@ -122,10 +129,17 @@ local formspec_string= "image[1,4.5;1,1;custom_beacom_symbol_2.png]".. "image[1,6;1,1;custom_beacom_symbol_1.png]".. - "image_button[5.2,1.5;1,1;mcl_potions_effect_swift.png;swiftness;]".. + "image_button[5.2,1.5;1,1;mcl_potions_effect_swiftness.png;swiftness;]".. + "image_button[8.5,1.5;1,1;mcl_potions_effect_haste.png;haste;]".. + "image_button[5.2,3;1,1;mcl_potions_effect_leaping.png;leaping;]".. - "image_button[5.2,4.5;1,1;mcl_potions_effect_strong.png;strenght;]".. - "image_button[5.2,6;1,1;mcl_potions_effect_regenerating.png;regeneration;]".. + "image_button[8.5,3;1,1;mcl_potions_effect_resistance.png;resistance;]".. + + "image_button[5.2,4.5;1,1;mcl_potions_effect_strength.png;strength;]".. + "image_button[8.5,4.5;1,1;mcl_potions_effect_absorption.png;absorption;]".. + + "image_button[5.2,6;1,1;mcl_potions_effect_regeneration.png;regeneration;]".. + "image_button[8.5,6;1,1;mcl_potions_effect_slow_falling.png;slow_falling;]".. "item_image[1,7;1,1;mcl_core:diamond]".. "item_image[2.2,7;1,1;mcl_core:emerald]".. @@ -148,7 +162,7 @@ local function remove_beacon_beam(pos) minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z}) node = minetest.get_node({x=pos.x,y=y,z=pos.z}) end - + if node.name == "mcl_beacons:beacon_beam" then minetest.remove_node({x=pos.x,y=y,z=pos.z}) end @@ -197,36 +211,34 @@ end local function effect_player(effect,pos,power_level, effect_level,player) local distance = vector.distance(player:get_pos(), pos) if distance > (power_level+1)*10 then return end - if effect == "swiftness" then - mcl_potions.swiftness_func(player,effect_level,16) - elseif effect == "leaping" then - mcl_potions.leaping_func(player, effect_level, 16) - elseif effect == "strenght" then - mcl_potions.strength_func(player, effect_level, 16) - elseif effect == "regeneration" then - mcl_potions.regeneration_func(player, effect_level, 16) - end + mcl_potions.give_effect_by_level(effect, player, effect_level, 16) end local function apply_effects_to_all_players(pos) - local meta = minetest.get_meta(pos) + local meta = minetest.get_meta(pos) local effect_string = meta:get_string("effect") - local effect_level = meta:get_int("effect_level") + local effect_level = meta:get_int("effect_level") - local power_level = beacon_blockcheck(pos) + local power_level = beacon_blockcheck(pos) - if effect_level == 2 and power_level < 4 then --no need to run loops when beacon is in an invalid setup :P + local new_effect_string = EFFECT_CONVERSIONS[effect_string] + if new_effect_string then + effect_string = new_effect_string + meta:set_string("effect", effect_string) + end + + if effect_string == "" or ( effect_level == 2 and power_level < 4 ) then --no need to run loops when beacon is in an invalid setup :P return end - local beacon_distance = (power_level + 1) * 10 + local beacon_distance = (power_level + 1) * 10 for _, player in pairs(minetest.get_connected_players()) do - if vector.distance(pos, player:get_pos()) <= beacon_distance then - if not clear_obstructed_beam(pos) then - effect_player(effect_string, pos, power_level, effect_level, player) - end - end + if vector.distance(pos, player:get_pos()) <= beacon_distance then + if not clear_obstructed_beam(pos) then + effect_player(effect_string, pos, power_level, effect_level, player) + end + end end end @@ -241,8 +253,7 @@ minetest.register_node("mcl_beacons:beacon", { local meta = minetest.get_meta(pos) local inv = meta:get_inventory() inv:set_size("input", 1) - local form = formspec_string - meta:set_string("formspec", form) + meta:set_string("formspec", formspec_string) end, on_destruct = function(pos) local meta = minetest.get_meta(pos) @@ -254,7 +265,8 @@ minetest.register_node("mcl_beacons:beacon", { remove_beacon_beam(pos) end, on_receive_fields = function(pos, formname, fields, sender) - if fields.swiftness or fields.regeneration or fields.leaping or fields.strenght then + if fields.swiftness or fields.regeneration or fields.leaping or fields.strength + or fields.haste or fields.resistance or fields.absorption or fields.slow_falling then local sender_name = sender:get_player_name() local power_level = beacon_blockcheck(pos) if minetest.is_protected(pos, sender_name) then @@ -267,7 +279,7 @@ minetest.register_node("mcl_beacons:beacon", { local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local input = inv:get_stack("input",1) - + if input:is_empty() then return end @@ -293,6 +305,14 @@ minetest.register_node("mcl_beacons:beacon", { end minetest.get_meta(pos):set_string("effect","swiftness") successful = true + elseif fields.haste then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","haste") + successful = true elseif fields.leaping and power_level >= 2 then if power_level == 4 then minetest.get_meta(pos):set_int("effect_level",2) @@ -301,18 +321,38 @@ minetest.register_node("mcl_beacons:beacon", { end minetest.get_meta(pos):set_string("effect","leaping") successful = true - elseif fields.strenght and power_level >= 3 then + elseif fields.resistance and power_level >= 2 then if power_level == 4 then minetest.get_meta(pos):set_int("effect_level",2) else minetest.get_meta(pos):set_int("effect_level",1) end - minetest.get_meta(pos):set_string("effect","strenght") + minetest.get_meta(pos):set_string("effect","resistance") + successful = true + elseif fields.strength and power_level >= 3 then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","strength") + successful = true + elseif fields.absorption and power_level >= 3 then + if power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + else + minetest.get_meta(pos):set_int("effect_level",1) + end + minetest.get_meta(pos):set_string("effect","absorption") successful = true elseif fields.regeneration and power_level == 4 then minetest.get_meta(pos):set_int("effect_level",2) minetest.get_meta(pos):set_string("effect","regeneration") successful = true + elseif fields.slow_falling and power_level == 4 then + minetest.get_meta(pos):set_int("effect_level",2) + minetest.get_meta(pos):set_string("effect","slow_falling") + successful = true end if successful then if power_level == 4 then @@ -321,7 +361,7 @@ minetest.register_node("mcl_beacons:beacon", { awards.unlock(sender:get_player_name(),"mcl:beacon") input:take_item() inv:set_stack("input",1,input) - + local beam_palette_index = 0 remove_beacon_beam(pos) for y = pos.y +1, pos.y + 201 do @@ -330,7 +370,6 @@ minetest.register_node("mcl_beacons:beacon", { minetest.get_voxel_manip():read_from_map({x=pos.x,y=y,z=pos.z}, {x=pos.x,y=y,z=pos.z}) node = minetest.get_node({x=pos.x,y=y,z=pos.z}) end - if minetest.get_item_group(node.name, "glass") ~= 0 or minetest.get_item_group(node.name,"material_glass") ~= 0 then beam_palette_index = get_beacon_beam(node.name) @@ -394,10 +433,19 @@ minetest.register_abm{ apply_effects_to_all_players(pos) end, } +minetest.register_lbm({ + label = "Update beacon formspecs (0.87.1)", + name = "mcl_beacons:update_beacon_formspecs_0_87_1", + nodenames = { "mcl_beacons:beacon" }, + action = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", formspec_string) + end +}) minetest.register_craft({ output = "mcl_beacons:beacon", - recipe = { + recipe = { {"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"}, {"mcl_core:glass", "mcl_mobitems:nether_star", "mcl_core:glass"}, {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"} diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index 9d46eca39..b1f1ebec9 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -77,16 +77,31 @@ local function rotate(pos, node, user, mode, new_param2) end +local creative_dig = {} local function destruct_bed(pos, oldnode) local node = oldnode or minetest_get_node_or_nil(pos) if not node then return end local pos2, node2, bottom = get_bed_next_node(pos, oldnode) + -- Check creative dig flags and don't drop an item if the bed was dug by a player in + -- creative mode + local pos_hash = minetest.hash_node_position(pos) + local pos2_hash = minetest.hash_node_position(pos2) + local creative_mode = creative_dig[pos_hash] or creative_dig[pos2_hash] + if bottom then if node2 and string.sub(node2.name, -4) == "_top" then minetest_remove_node(pos2) end + + -- Drop the bed only when removing the top to prevent duplication and only if + -- it wasn't dug by a player in creative mode + local bed_node_def = minetest.registered_nodes[node.name] + if bed_node_def and bed_node_def._mcl_beds_drop and not creative_mode then + local stack = ItemStack(bed_node_def._mcl_beds_drop) + minetest.add_item(pos2, stack) + end else if node2 and string.sub(node2.name, -7) == "_bottom" then minetest_remove_node(pos2) @@ -94,6 +109,29 @@ local function destruct_bed(pos, oldnode) end end +local function dig_bed(pos, node, digger) + local pos_hash = minetest.hash_node_position(pos) + + if digger then + local name = digger:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return + end + + -- Set creative dig flags to stop dropping items + if minetest.is_creative_enabled(name) then + creative_dig[pos_hash] = true + end + end + + -- Trigger the destruct_bed function + minetest.remove_node(pos) + + -- Clean up creative dig flag + creative_dig[pos_hash] = nil +end + local function kick_player_after_destruct(destruct_pos) for name, player_bed_pos in pairs(mcl_beds.bed_pos) do if vector.distance(destruct_pos, player_bed_pos) < 0.1 then @@ -126,6 +164,26 @@ if minetest.get_modpath("mcl_sounds") then }) end +local function place_bed(name, placer, pos, dir) + local botpos = vector_add(pos, minetest_facedir_to_dir(dir)) + + if minetest.is_protected(botpos, placer:get_player_name()) and + not minetest.check_player_privs(placer, "protection_bypass") then + minetest.record_protection_violation(botpos, placer:get_player_name()) + return false + end + + local botdef = minetest.registered_nodes[minetest_get_node(botpos).name] + if not botdef or not botdef.buildable_to then + return false + end + + minetest.set_node(pos, {name = name .. "_bottom", param2 = dir}) + minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) + + return true +end + function mcl_beds.register_bed(name, def) local common_box = { type = "fixed", @@ -156,7 +214,8 @@ function mcl_beds.register_bed(name, def) sounds = def.sounds or default_sounds, selection_box = common_box, collision_box = common_box, - drop = def.recipe and name or "", + _mcl_beds_drop = def.recipe and name or "", + drop = "", node_placement_prediction = "", on_place = function(itemstack, placer, pointed_thing) @@ -189,30 +248,23 @@ function mcl_beds.register_bed(name, def) return itemstack end + -- Try to place in three directions: inline with the view and rotated to + -- the right and left local dir = minetest.dir_to_facedir(placer:get_look_dir()) - local botpos = vector_add(pos, minetest_facedir_to_dir(dir)) - - if minetest.is_protected(botpos, placer:get_player_name()) and - not minetest.check_player_privs(placer, "protection_bypass") then - minetest.record_protection_violation(botpos, placer:get_player_name()) - return itemstack - end - - local botdef = minetest.registered_nodes[minetest_get_node(botpos).name] - if not botdef or not botdef.buildable_to then - return itemstack - end - - minetest.set_node(pos, {name = name .. "_bottom", param2 = dir}) - minetest.set_node(botpos, {name = name .. "_top", param2 = dir}) - - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() + if place_bed(name, placer, pos, dir) or + place_bed(name, placer, pos, (dir+1)%4) or + place_bed(name, placer, pos, (dir+3)%4) or + place_bed(name, placer, pos, (dir+2)%4) then + -- Bed was places + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end end return itemstack end, after_destruct = destruct_bed, + on_dig = dig_bed, on_destruct = kick_player_after_destruct, @@ -239,7 +291,7 @@ function mcl_beds.register_bed(name, def) _mcl_hardness = 0.2, _mcl_blast_resistance = 1, sounds = def.sounds or default_sounds, - drop = def.recipe and name or "", + drop = "", selection_box = common_box, collision_box = common_box, @@ -250,6 +302,7 @@ function mcl_beds.register_bed(name, def) on_rotate = rotate, after_destruct = destruct_bed, + on_dig = dig_bed, }) minetest.register_alias(name, name .. "_bottom") diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index fdb4f8f41..b1c3f0830 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -8,7 +8,7 @@ local is_sp = minetest.is_singleplayer() local weather_mod = minetest.get_modpath("mcl_weather") local explosions_mod = minetest.get_modpath("mcl_explosions") local spawn_mod = minetest.get_modpath("mcl_spawn") -local worlds_mod = minetest.get_modpath("mcl_worlds") +local pos_to_dim = minetest.get_modpath("mcl_worlds") and mcl_worlds.pos_to_dimension or function(pos) return "overworld" end local function mcl_log (message) mcl_util.mcl_log (message, "[Beds]") @@ -38,6 +38,16 @@ local function is_night_skip_enabled() return players_in_bed_setting() <= 100 end +local function players_in_overworld(players) + local count = 0 + for _, player in pairs(players) do + if player and pos_to_dim(player:get_pos()) == "overworld" then + count = count +1 + end + end + return count +end + local function check_in_beds(players) if not players then players = minetest.get_connected_players() @@ -45,7 +55,7 @@ local function check_in_beds(players) if player_in_bed <= 0 then return false end - return players_in_bed_setting() <= (player_in_bed * 100) / #players + return players_in_bed_setting() <= (player_in_bed * 100) / players_in_overworld(players) end -- These monsters do not prevent sleep @@ -206,20 +216,18 @@ local function lay_down(player, pos, bed_pos, state, skip) return true end -local function update_formspecs(finished, ges) - local ges = ges or #minetest.get_connected_players() +local function update_formspecs(finished, players) + local ges = players_in_overworld(players or minetest.get_connected_players()) local form_n = "size[12,5;true]" - local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges + local all_in_bed = ges and players_in_bed_setting() <= (player_in_bed * 100) / ges or 0 local night_skip = is_night_skip_enabled() local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]" local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]" local bg_presleep = "bgcolor[#00000080;true]" local bg_sleep = "bgcolor[#000000FF;true]" - local chatbox = "field[0.2,4.5;9,1;chatmessage;"..F(S("Chat:"))..";]" - local chatsubmit = "button[9.2,3.75;1,2;chatsubmit;"..F(S("send!")).."]" - local defaultmessagebutton = "button[10.2,3.75;1,2;defaultmessage;zzZzzZ]" - - form_n = form_n .. chatbox .. chatsubmit --because these should be in the formspec in ANY case, they might as well be added here already + local chatbox = "field[0.3,4.5;10,1;chatmessage;"..F(S("Chat:"))..";]" + local chatsubmit = "button[10,3.73;2,2;chatsubmit;"..F(S("Send")).."]" + local defaultmessagebutton = "button[10.98,2.93;1,2;defaultmessage;zzZ]" if finished then for name,_ in pairs(mcl_beds.player) do @@ -227,6 +235,7 @@ local function update_formspecs(finished, ges) end return elseif not is_sp then + form_n = form_n .. chatbox .. chatsubmit --because these should be in the formspec in ANY case, they might as well be added here already local text = S("Players in bed: @1/@2", player_in_bed, ges) if not night_skip then text = text .. "\n" .. S("Note: Night skip is disabled.") @@ -349,25 +358,36 @@ function mcl_beds.get_bed_bottom (pos) return bed_bottom end +local function recheck_in_beds() + if check_in_beds() then + update_formspecs(is_night_skip_enabled()) + mcl_beds.sleep() + end + + -- check again (a player can change the dimension) + if player_in_bed > 0 then + update_formspecs(false) + minetest.after(5, recheck_in_beds) + end +end + function mcl_beds.on_rightclick(pos, player, is_top) -- Anti-Inception: Don't allow to sleep while you're sleeping if player:get_meta():get_string("mcl_beds:sleeping") == "true" then return end - if worlds_mod then - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" or dim == "end" then - -- Bed goes BOOM in the Nether or End. - local node = minetest.get_node(pos) - local dir = minetest.facedir_to_dir(node.param2) + local dim = pos_to_dim(pos) + if dim == "nether" or dim == "end" then + -- Bed goes BOOM in the Nether or End. + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) - minetest.remove_node(pos) - minetest.remove_node(string.sub(node.name, -4) == "_top" and vector.subtract(pos, dir) or vector.add(pos, dir)) - if explosions_mod then - mcl_explosions.explode(pos, 5, {drop_chance = 1.0, fire = true}) - end - return + minetest.remove_node(pos) + minetest.remove_node(string.sub(node.name, -4) == "_top" and vector.subtract(pos, dir) or vector.add(pos, dir)) + if explosions_mod then + mcl_explosions.explode(pos, 5, {drop_chance = 1.0, fire = true}) end + return end local name = player:get_player_name() local ppos = player:get_pos() @@ -383,6 +403,18 @@ function mcl_beds.on_rightclick(pos, player, is_top) end if message then 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 ges = players_in_overworld(connected_players) + local sleep_hud_message = S("@1/@2 players currently in bed.", player_in_bed, math.ceil(players_in_bed_setting() * ges / 100)) + for _, player in pairs(connected_players) do + -- only send message to players not sleeping and in the "overworld" + if not mcl_beds.player[player:get_player_name()] and pos_to_dim(player:get_pos()) == "overworld" then + -- clear, old message is still being displayed + if mcl_title.params_get(player) then mcl_title.clear(player) end + mcl_title.set(player, "actionbar", {text=sleep_hud_message, color="white", stay=60}) + end + end end else lay_down(player, nil, nil, false) @@ -391,13 +423,8 @@ function mcl_beds.on_rightclick(pos, player, is_top) update_formspecs(false) -- skip the night and let all players stand up - if check_in_beds() then - minetest.after(5, function() - if check_in_beds() then - update_formspecs(is_night_skip_enabled()) - mcl_beds.sleep() - end - end) + if player_in_bed > 0 then + minetest.after(5, recheck_in_beds) end end @@ -424,15 +451,10 @@ minetest.register_on_leaveplayer(function(player) break end end - if check_in_beds(players) then - minetest.after(5, function() - if check_in_beds() then - update_formspecs(is_night_skip_enabled()) - mcl_beds.sleep() - end - end) + if player_in_bed > 0 then + minetest.after(5, recheck_in_beds) end - update_formspecs(false, #players) + update_formspecs(false, players) end) local message_rate_limit = tonumber(minetest.settings:get("chat_message_limit_per_10sec")) or 8 --NEVER change this! if this was java, i would've declared it as final diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr index 97867b44b..6771596a5 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr @@ -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 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? -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! \ No newline at end of file +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. \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr index cc69db33b..ab4917c95 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr @@ -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. Allows you to sleep=Vous permet de dormir 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 ! diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.ru.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.ru.tr index 8093e95fb..cf9e285d1 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.ru.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.ru.tr @@ -1,28 +1,28 @@ # textdomain: mcl_beds -Beds allow you to sleep at night and make the time pass faster.=На кровати можно спать по ночам и заставлять ночи проходить быстрее. -To use a bed, stand close to it and right-click the bed to sleep in it. Sleeping only works when the sun sets, at night or during a thunderstorm. The bed must also be clear of any danger.=Чтобы использовать кровать, встаньте рядом и кликните по ней правой кнопкой. Вы сможете уснуть, только если солнце в закате, либо уже наступила ночь, либо идёт гроза. Кровать при этом должна в месте, свободном от любых опасностей. +Beds allow you to sleep at night and make the time pass faster.=На кровати можно спать по ночам и заставлять ночь проходить быстрее. +To use a bed, stand close to it and right-click the bed to sleep in it. Sleeping only works when the sun sets, at night or during a thunderstorm. The bed must also be clear of any danger.=Чтобы использовать кровать, встаньте рядом и кликните по ней правой кнопкой. Вы сможете уснуть, только если солнце в закате, либо уже наступила ночь, либо идёт гроза. Кровать при этом должна в безопасном месте. You have heard of other worlds in which a bed would set the start point for your next life. But this world is not one of them.=Вы слышали о других мирах, где кровать становится стартовой точкой для вашей следующей жизни. Но этот мир не такой. By using a bed, you set the starting point for your next life. If you die, you will start your next life at this bed, unless it is obstructed or destroyed.=Воспользовавшись кроватью, вы устанавливаете стартовую точку для вашей следующей жизни. Если вы умрёте, ваша новая жизнь начнётся в этой кровати, если она не уничтожена и не загромождена. -In this world, going to bed won't skip the night, but it will skip thunderstorms.=В этом мире использование кровати не заставит ночь пройти скорее, но может сократить время грозового шторма. -Sleeping allows you to skip the night. The night is skipped when all players in this world went to sleep. The night is skipped after sleeping for a few seconds. Thunderstorms can be skipped in the same manner.=Сон позволяет вам пропустить ночь. Если все игроки в этом мире лягут спать, ночь будет пропущена. Она закончится буквально через несколько секунд. Таким же способом можно пропускать грозы. +In this world, going to bed won't skip the night, but it will skip thunderstorms.=В этом мире использование кровати не заставит ночь пройти быстрее, но может сократить время грозового шторма. +Sleeping allows you to skip the night. The night is skipped when all players in this world went to sleep. The night is skipped after sleeping for a few seconds. Thunderstorms can be skipped in the same manner.=Сон позволяет вам пропустить ночь. Если все игроки в этом мире лягут спать, ночь будет пропущена. Она пропустится через несколько секунд после сна. Таким же способом можно пропускать грозу. Bed=Кровать Red Bed=Красная кровать Blue Bed=Синяя кровать -Cyan Bed=Голубая кровать +Cyan Bed=Бирюзовая кровать Grey Bed=Серая кровать Light Grey Bed=Светло-серая кровать Black Bed=Чёрная кровать Yellow Bed=Жёлтая кровать Green Bed=Зелёная кровать -Magenta Bed=Фиолетовая кровать +Magenta Bed=Сиреневая кровать Orange Bed=Оранжевая кровать -Purple Bed=Пурпурная кровать +Purple Bed=Фиолетовая кровать Brown Bed=Коричневая кровать Pink Bed=Розовая кровать -Lime Bed=Зелёная лаймовая кровать -Light Blue Bed=Светло-голубая кровать +Lime Bed=Лаймовая кровать +Light Blue Bed=Голубая кровать White Bed=Белая кровать -You can't sleep, the bed's too far away!=Не удаётся лечь, кровать слишком далеко! +You can't sleep, the bed's too far away!=Вы не можете спать, кровать слишком далеко! This bed is already occupied!=Эта кровать уже занята! You have to stop moving before going to bed!=Вам нужно перестать двигаться, чтобы лечь! You can't sleep now, monsters are nearby!=Вы не можете спать, монстры слишком близко! @@ -31,11 +31,19 @@ It's too dangerous to sleep here!=Спать здесь слишком опас New respawn position set! But you can only sleep at night or during a thunderstorm.=Новая точка возрождения успешно задана! Но спать вы можете только ночью или во время грозы. You can only sleep at night or during a thunderstorm.=Вы можете спать только ночью или во время грозы. New respawn position set!=Задана новая точка возрождения! -Leave bed=Покинуть кровать -Abort sleep=Прервать сон +Leave bed=Встать с кровати +Abort sleep=Проснуться Players in bed: @1/@2=Игроков в кроватях: @1/@2 -Note: Night skip is disabled.=Предупреждение: Пропускание ночи отключено. -You're sleeping.=Вы спите... -You will fall asleep when all players are in bed.=Вы уснёте, когда лягут все игроки. +Note: Night skip is disabled.=Предупреждение: Пропуск ночи отключен. +You're sleeping.=Вы засыпаете... +You will fall asleep when all players are in bed.=Вы уснёте когда все игроки лягут в кровати. +You will fall asleep when @1% of all players are in bed.=Вы уснёте когда @1% игроков лягут в кровати. You're in bed.=Вы в кровати. -Allows you to sleep=Позволяет вам спать +Allows you to sleep=Можно спать +Respawn Anchor=Якорь возрождения +Chat:=Чат: +send!=Отправить +You are missing the 'shout' privilege! It's required in order to talk in chat...=Вам нужна привилегия “shout”, чтобы писать в чат. +You exceeded the maximum number of messages per 10 seconds!=Вы превысили максимальный лимит сообщений в 10 секунд! +Hey! Would you guys mind sleeping?=Эй, ребята, не хотите поспать? +Sorry, but you have to wait @1 seconds until you may use this button again!=Вам нужно подождать еще @1 с. прежде чем вы сможете нажать эту кнопку снова! \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/locale/template.txt b/mods/ITEMS/mcl_beds/locale/template.txt index 42e59509e..e604299e0 100644 --- a/mods/ITEMS/mcl_beds/locale/template.txt +++ b/mods/ITEMS/mcl_beds/locale/template.txt @@ -46,4 +46,5 @@ send!= 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!= Hey! Would you guys mind sleeping?= -Sorry, but you have to wait @1 seconds until you may use this button again!= \ No newline at end of file +Sorry, but you have to wait @1 seconds until you may use this button again!= +@1/@2 players currently in bed.= \ No newline at end of file diff --git a/mods/ITEMS/mcl_beehives/init.lua b/mods/ITEMS/mcl_beehives/init.lua index 82b3cae5f..548c9b150 100644 --- a/mods/ITEMS/mcl_beehives/init.lua +++ b/mods/ITEMS/mcl_beehives/init.lua @@ -8,36 +8,60 @@ local S = minetest.get_translator(minetest.get_current_modname()) -- Function to allow harvesting honey and honeycomb from the beehive and bee nest. local honey_harvest = function(pos, node, player, itemstack, pointed_thing) local inv = player:get_inventory() - local shears = player:get_wielded_item():get_name() == "mcl_tools:shears" - local bottle = player:get_wielded_item():get_name() == "mcl_potions:glass_bottle" - local beehive = "mcl_beehives:beehive" + local item = player:get_wielded_item() local is_creative = minetest.is_creative_enabled(player:get_player_name()) + -- Determine the node name to replace the beehive with if harvest is successful + local beehive = "mcl_beehives:beehive" if node.name == "mcl_beehives:beehive_5" then beehive = "mcl_beehives:beehive" elseif node.name == "mcl_beehives:bee_nest_5" then beehive = "mcl_beehives:bee_nest" end + -- Check for a campfire within 5 blocks below the beehive local campfire_area = vector.offset(pos, 0, -5, 0) local campfire = minetest.find_nodes_in_area(pos, campfire_area, "group:lit_campfire") - if bottle then + -- Player used a bottle + if item:get_name() == "mcl_potions:glass_bottle" then local honey = "mcl_honey:honey_bottle" if inv:room_for_item("main", honey) then + -- Replace the beehive with the version without honey or comb node.name = beehive minetest.set_node(pos, node) + + -- Give honey bottle and take the empty bottle if survival mode inv:add_item("main", "mcl_honey:honey_bottle") if not is_creative then itemstack:take_item() end - if not campfire[1] then mcl_util.deal_damage(player, 10) else awards.unlock(player:get_player_name(), "mcl:bee_our_guest") end + + -- Hurt the player if there was no campfire, or give award if there was + if not campfire[1] then + mcl_util.deal_damage(player, 10) + else + awards.unlock(player:get_player_name(), "mcl:bee_our_guest") + end end - elseif shears then + + -- Player used shears + elseif minetest.get_item_group(item:get_name(), "shears") > 0 then + -- Give honeycomb minetest.add_item(pos, "mcl_honey:honeycomb 3") + + -- Replace the beehive with the version without honey or comb node.name = beehive minetest.set_node(pos, node) + + -- Hurt the player if there was no campfire if not campfire[1] then mcl_util.deal_damage(player, 10) end + + -- Add wear to the shears + if not is_creative then + mcl_util.use_item_durability(item, 1) + return item + end end end @@ -191,6 +215,18 @@ minetest.register_craft({ }, }) +minetest.register_craft({ + type = "fuel", + recipe = "group:bee_nest", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:beehive", + burntime = 15, +}) + -- Temporary ABM to update honey levels minetest.register_abm({ label = "Update Beehive Honey Levels", diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr index 61510cbc1..a0596338a 100644 --- a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr @@ -1,4 +1,5 @@ +# textdomain: mcl_beehives Beehive=Bistade Artificial bee nest.=Kunstigt bibo. Bee Nest=Bibo -A naturally generating block that houses bees and a tasty treat...if you can get it.=En naturligt genereret blok som indeholde bier og velsmagende godter... hvis du kan få fat i dem. \ No newline at end of file +A naturally generating block that houses bees and a tasty treat...if you can get it.=En naturligt genereret blok som indeholde bier og velsmagende godter... hvis du kan få fat i dem. diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.pt_BR.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.pt_BR.tr new file mode 100644 index 000000000..cf4923a83 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beehives +Beehive=Colméia Artificial +Artificial bee nest.=Colméia artificial. +Bee Nest=Colméia +A naturally generating block that houses bees and a tasty treat...if you can get it.=Um bloco naturalmente gerado que abriga abelhas e um regalo saboroso...se você conseguir pegá-lo. diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ru.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ru.tr new file mode 100644 index 000000000..b956967a9 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ru.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beehives +Beehive=Улей +Artificial bee nest.=Искусственное пчелиное гнездо. +Bee Nest=Пчелиное гнездо +A naturally generating block that houses bees and a tasty treat...if you can get it.=Естественное генерирующийся блок служащий домом пчёлам и вкусному угощению... если вы сможете достать его. diff --git a/mods/ITEMS/mcl_bells/README.md b/mods/ITEMS/mcl_bells/README.md index 53cba890c..a865aa449 100644 --- a/mods/ITEMS/mcl_bells/README.md +++ b/mods/ITEMS/mcl_bells/README.md @@ -1,6 +1,6 @@ mcl_bells --------- -Village bells for MineClone2, originally imported from mcl5, heavily modified by cora. +Village bells for VoxeLibre, originally imported from mcl5, heavily modified by cora. License of media files ---------------------- diff --git a/mods/ITEMS/mcl_bells/init.lua b/mods/ITEMS/mcl_bells/init.lua index 32bdfe3d7..46b8b9f89 100644 --- a/mods/ITEMS/mcl_bells/init.lua +++ b/mods/ITEMS/mcl_bells/init.lua @@ -33,7 +33,7 @@ minetest.register_node("mcl_bells:bell", { "mcl_bells_bell_side.png", }, is_ground_content = false, - groups = {pickaxey=2, deco_block=1 }, + groups = {pickaxey=2, deco_block=1, dig_by_piston=1 }, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 5, _mcl_hardness = 5, diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.ru.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.ru.tr new file mode 100644 index 000000000..eb2df707f --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.ru.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=Колокол diff --git a/mods/ITEMS/mcl_blackstone/init.lua b/mods/ITEMS/mcl_blackstone/init.lua index fd05465d3..63d085877 100644 --- a/mods/ITEMS/mcl_blackstone/init.lua +++ b/mods/ITEMS/mcl_blackstone/init.lua @@ -193,13 +193,51 @@ minetest.registered_nodes["mcl_fire:fire"].on_construct=function(pos) end --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_simple("blackstone_polished", "mcl_blackstone:blackstone_polished", S("Polished Blackstone Stair"), S("Polished Blackstone Slab"), S("Polished Double Blackstone Slab")) -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_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")) +mcl_stairs.register_stair_and_slab("blackstone", "mcl_blackstone:blackstone", + {cracky=3, pickaxey=1, material_stone=1}, + {"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"}, + S("Blackstone Stair"), + 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 Stair"), + 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 Stair"), + 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"), + S("Polished Blackstone Brick Slab"), + mcl_sounds.node_sound_stone_defaults(), 6, 2, + S("Double Polished Blackstone Brick Slab"), nil) --Wall -mcl_walls.register_wall("mcl_blackstone:wall", S("Blackstone Wall"), "mcl_blackstone:blackstone") +mcl_walls.register_wall( + "mcl_blackstone:wall", + S("Blackstone Wall"), + "mcl_blackstone:blackstone", + { + "mcl_blackstone_top.png", + "mcl_blackstone_top.png", + "mcl_blackstone_side.png" + }, + "", + { cracky=3, pickaxey=1, material_stone=1 } +) --lavacooling @@ -362,3 +400,10 @@ minetest.register_craft({ { "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") diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr index 11cf26fcd..80cb8384d 100644 --- a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr @@ -9,10 +9,10 @@ Blackstone Slab=Schwarzstein Stufe Polished Blackstone Slab=Polierte Schwarzstein Stufe Chiseled Polished Blackstone Slab=Gemeißelte Polierte Schwarzstein Stufe Polished Blackstone Brick Slab=Polierte Schwarzsteinziegel Stufe -Blackstone Stairs=Schwarzstein Treppe -Polished Blackstone Stairs=Polierte Schwarzstein Treppe -Chiseled Polished Blackstone Stairs=Gemeißelte Polierte Schwarzstein Treppe -Polished Blackstone Brick Stairs=Polierte Schwarzsteinziegel Treppe +Blackstone Stair=Schwarzstein Treppe +Polished Blackstone Stair=Polierte Schwarzstein Treppe +Chiseled Polished Blackstone Stair=Gemeißelte Polierte Schwarzstein Treppe +Polished Blackstone Brick Stair=Polierte Schwarzsteinziegel Treppe Quartz Bricks=Quartz Ziegel Soul Torch=Seelenfakel Soul Lantern=Seelenlaterne diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ru.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ru.tr index 8e27983ea..3375586a2 100644 --- a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ru.tr +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ru.tr @@ -1,29 +1,29 @@ # textdomain: mcl_blackstone -Blackstone=Чернит -Polished Blackstone=Полированный чернит -Chiseled Polished Blackstone=Резной полированный чернит -Polished Blackstone Bricks=Полированный чернокаменный кирпич +Blackstone=Чернокамень +Polished Blackstone=Полированный чернокамень +Chiseled Polished Blackstone=Резной полированный чернокамень +Polished Blackstone Bricks=Полированные чернокаменные кирпичи Basalt=Базальт Polished Basalt=Полированный базальт -Blackstone Slab=Чернитная плита -Polished Blackstone Slab=Плита из полированного чернита -Chiseled Polished Blackstone Slab=Резная полированная чернитная плита -Polished Blackstone Brick Slab=Плита из полированно-чернитного кирпича -Blackstone Stair=Чернитные ступеньки -Polished Blackstone Stair=Ступеньки из полированно-чернитного кирпича -Chiseled Polished Blackstone Stair=Резные полированные чернитные ступеньки -Polished Blackstone Brick Stair=Ступеньки из полированно-чернитного кирпича +Blackstone Slab=Чернокаменная плита +Polished Blackstone Slab=Полированная чернокаменная плита +Chiseled Polished Blackstone Slab=Плита из резного полированного чернокамня +Polished Blackstone Brick Slab=Плита из полированных чернокаменных кирпичей +Blackstone Stair=Чернокаменные ступени +Polished Blackstone Stair=Полированные чернокаменные ступени +Chiseled Polished Blackstone Stair=Резные полированные чернокаменные ступени +Polished Blackstone Brick Stair=Ступени из полированных чернокаменных кирпичей Quartz Bricks=Кварцевые кирпичи Soul Torch=Факел душ -Torches are light sources which can be placed at the side or on the top of most blocks.=Факелы - это источники света, которые могут быть размещены сбоку или сверху большинства блоков. -Soul Lantern=Фонарь душ -Soul Soil=Почва душ -Eternal Soul Fire=Пламя душ -Gilded Blackstone=Золочёный чернит -Nether Gold Ore=Незерская золотая руда +Torches are light sources which can be placed at the side or on the top of most blocks.=Факелы это источники света, которые могут быть размещены сбоку или сверху большинства блоков. +Soul Lantern=Лампа душ +Soul Soil=Песок душ +Eternal Soul Fire=Вечный огонь душ +Gilded Blackstone=Позолоченный чернокамень +Nether Gold Ore=Золотая руда Незера Smooth Basalt=Гладкий базальт -Blackstone Wall=Чернитная стена -Double Blackstone Slab=Двойная чернитная плита -Polished Double Blackstone Slab=Полированная двойная чернитная плита -Double Chiseled Polished Blackstone Slab=Двойная резная полированная чернитная плита -Double Polished Blackstone Brick Slab=Двойная плита из полированно-чернитного кирпича +Blackstone Wall=Стена из чернокамня +Double Blackstone Slab=Двойная чернокаменная плита +Polished Double Blackstone Slab=Полированная двойная чернокаменная плита +Double Chiseled Polished Blackstone Slab=Двойная резная полированная чернокаменная плита +Double Polished Blackstone Brick Slab=Двойная плита из полированных чернокаменных кирпичей diff --git a/mods/ITEMS/mcl_blackstone/mod.conf b/mods/ITEMS/mcl_blackstone/mod.conf index 8728f5b01..14a482067 100644 --- a/mods/ITEMS/mcl_blackstone/mod.conf +++ b/mods/ITEMS/mcl_blackstone/mod.conf @@ -1,3 +1,3 @@ name = mcl_blackstone 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 diff --git a/mods/ITEMS/mcl_blast_furnace/README.md b/mods/ITEMS/mcl_blast_furnace/README.md index e96c21942..f61230fb8 100644 --- a/mods/ITEMS/mcl_blast_furnace/README.md +++ b/mods/ITEMS/mcl_blast_furnace/README.md @@ -1,5 +1,5 @@ -Blast Furnaces for MineClone 2. -Heavily based on Minetest Game (default/furnace.lua) and the MineClone 2 Furnaces. +Blast Furnaces for VoxeLibre. +Heavily based on Minetest Game (default/furnace.lua) and the VoxeLibre Furnaces. License of source code ---------------------- @@ -10,4 +10,4 @@ MCl 2 Furances modified by PrairieWind. License of media ---------------- -See the main MineClone 2 README.md file. +See the main VoxeLibre README.md file. diff --git a/mods/ITEMS/mcl_blast_furnace/init.lua b/mods/ITEMS/mcl_blast_furnace/init.lua index e8e6e81c8..7d0f091d9 100644 --- a/mods/ITEMS/mcl_blast_furnace/init.lua +++ b/mods/ITEMS/mcl_blast_furnace/init.lua @@ -1,5 +1,6 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 @@ -8,60 +9,82 @@ local LIGHT_ACTIVE_FURNACE = 13 -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Blast Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Blast Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Blast Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Blast Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +94,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -99,7 +122,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -160,17 +183,17 @@ local function spawn_flames(pos, param2) local minrelpos, maxrelpos local dir = minetest.facedir_to_dir(param2) if dir.x > 0 then - minrelpos = { x = -0.6, y = -0.05, z = -0.25 } - maxrelpos = { x = -0.55, y = -0.45, z = 0.25 } + minrelpos = vector.new(-0.6, -0.05, -0.25) + maxrelpos = vector.new(-0.55, -0.45, 0.25) elseif dir.x < 0 then - minrelpos = { x = 0.55, y = -0.05, z = -0.25 } - maxrelpos = { x = 0.6, y = -0.45, z = 0.25 } + minrelpos = vector.new(0.55, -0.05, -0.25) + maxrelpos = vector.new(0.6, -0.45, 0.25) elseif dir.z > 0 then - minrelpos = { x = -0.25, y = -0.05, z = -0.6 } - maxrelpos = { x = 0.25, y = -0.45, z = -0.55 } + minrelpos = vector.new(-0.25, -0.05, -0.6) + maxrelpos = vector.new(0.25, 0.45, -0.55) elseif dir.z < 0 then - minrelpos = { x = -0.25, y = -0.05, z = 0.55 } - maxrelpos = { x = 0.25, y = -0.45, z = 0.6 } + minrelpos = vector.new(-0.25, -0.05, 0.55) + maxrelpos = vector.new(0.25, -0.45, 0.6) else return end @@ -179,8 +202,8 @@ local function spawn_flames(pos, param2) time = 0, minpos = vector.add(pos, minrelpos), maxpos = vector.add(pos, maxrelpos), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minvel = vector.new(-0.01, 0, -0.01), + maxvel = vector.new(0.01, 0.1, 0.01), minexptime = 0.3, maxexptime = 0.6, minsize = 0.4, @@ -293,7 +316,7 @@ local function blast_furnace_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "blast_furnace_smeltable") == 1 if cookable then -- Successful cooking requires space in dst slot and time @@ -311,7 +334,7 @@ local function blast_furnace_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -343,7 +366,7 @@ local function blast_furnace_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -390,9 +413,9 @@ local function blast_furnace_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) @@ -415,13 +438,14 @@ end minetest.register_node("mcl_blast_furnace:blast_furnace", { description = S("Blast Furnace"), _tt_help = S("Smelts ores faster than furnace"), - _doc_items_longdesc = S("Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace."), + _doc_items_longdesc = S( + "Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace."), _doc_items_usagehelp = - S("Use the blast furnace to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The blast furnace will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn."), + S("Use the blast furnace to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The blast furnace will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "blast_furnace_top.png", "blast_furnace_top.png", @@ -429,7 +453,7 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", { "blast_furnace_side.png", "blast_furnace_front.png" }, 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, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -439,11 +463,10 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} - minetest.add_item(p, stack) + minetest.add_item(vector.offset(pos, math.random(0, 10) / 10 - 0.5, 0, math.random(0, 10) / 10 - 0.5), stack) end end meta:from_table(meta2) @@ -491,6 +514,11 @@ minetest.register_node("mcl_blast_furnace:blast_furnace", { _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, 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", { @@ -499,14 +527,16 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { tiles = { "blast_furnace_top.png", "blast_furnace_top.png", "blast_furnace_side.png", "blast_furnace_side.png", - "blast_furnace_side.png", {name = "blast_furnace_front_on.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48}}, + "blast_furnace_side.png", { + name = "blast_furnace_front_on.png", + animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48 } + }, }, paramtype2 = "facedir", paramtype = "light", light_source = LIGHT_ACTIVE_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, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = blast_furnace_node_timer, @@ -516,10 +546,14 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = vector.new( + pos.x + math.random(0, 10) / 10 - 0.5, + pos.y, + pos.z + math.random(0, 10) / 10 - 0.5 + ) minetest.add_item(p, stack) end end @@ -545,13 +579,15 @@ minetest.register_node("mcl_blast_furnace:blast_furnace_active", { _mcl_hardness = 3.5, on_rotate = on_rotate, 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({ output = "mcl_blast_furnace:blast_furnace", recipe = { - { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, - { "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" }, + { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" }, + { "mcl_core:iron_ingot", "mcl_furnaces:furnace", "mcl_core:iron_ingot" }, { "mcl_core:stone_smooth", "mcl_core:stone_smooth", "mcl_core:stone_smooth" }, } }) @@ -564,10 +600,9 @@ end minetest.register_lbm({ label = "Active blast_furnace flame particles", name = "mcl_blast_furnace:flames", - nodenames = {"mcl_blast_furnace:blast_furnace_active"}, + nodenames = { "mcl_blast_furnace:blast_furnace_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) end, }) - diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ru.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ru.tr new file mode 100644 index 000000000..c4d4ce8ad --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ru.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_blast_furnace +Inventory=Инвентарь +Blast Furnace=Плавильная печь +Smelts ores faster than furnace=Переплавляет руды быстрее чем обычная печь +Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn.=Используйте книгу рецептов, чтобы увидеть какие руды можно переплавить, что можно использовать как топливо и как долго оно будет гореть. +Use the blast furnace to open the furnace menu.=Используйте плавильную печь, чтобы открыть меню печи. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Положите топливо в нижний слот и материал в верхний. +The blast furnace will slowly use its fuel to smelt the item.=Плавильная печь будет медленно использовать топливо для переплавки предмета. +The result will be placed into the output slot at the right side.=Результат будет помещен в выходной слот с правой стороны. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace.=Плавильная печь плавит некоторые предметы, в основном руды и броню используя топливо, но в два раза быстрее чем обычная печь. +Active Blast Furnace=Горящая плавильная печь diff --git a/mods/ITEMS/mcl_blast_furnace/locale/template.txt b/mods/ITEMS/mcl_blast_furnace/locale/template.txt index 46841046d..7b2b35c21 100644 --- a/mods/ITEMS/mcl_blast_furnace/locale/template.txt +++ b/mods/ITEMS/mcl_blast_furnace/locale/template.txt @@ -6,6 +6,6 @@ Use the recipe book to see what ores you can smelt, what you can use as fuel and Use the blast furnace to open the furnace menu.= Place a furnace fuel in the lower slot and the source material in the upper slot.= The blast furnace will slowly use its fuel to smelt the item.= -The result will be placed into the output slot at the right side.= +The result will be placed into the output slot at the right side.= Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace.= Active Blast Furnace= diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index af84feb66..9e9a800cf 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -5,7 +5,7 @@ local C = minetest.colorize local max_text_length = 4500 -- TODO: Increase to 12800 when scroll bar was added to written book local max_title_length = 64 -local bookshelf_inv = minetest.settings:get_bool("mcl_bookshelf_inventories",true) +local bookshelf_inv = minetest.settings:get_bool("mcl_bookshelf_inventories", true) local header = "" if minetest.get_modpath("mcl_init") then @@ -19,7 +19,7 @@ minetest.register_craftitem("mcl_books:book", { _doc_items_longdesc = S("Books are used to make bookshelves and book and quills."), inventory_image = "default_book.png", stack_max = 64, - groups = { book=1, craftitem = 1, enchantability = 1 }, + groups = { book = 1, craftitem = 1, enchantability = 1 }, _mcl_enchanting_enchanted_tool = "mcl_enchanting:book_enchanted", }) @@ -85,18 +85,19 @@ local function write(itemstack, user, pointed_thing) local node = minetest.get_node(pointed_thing.under) if user and not user:get_player_control().sneak then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or + itemstack end end end local text = get_text(itemstack) - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "textarea[0.75,0.1;7.25,9;text;;"..minetest.formspec_escape(text).."]".. - "button[0.75,7.95;3,1;sign;"..minetest.formspec_escape(S("Sign")).."]".. - "button_exit[4.25,7.95;3,1;ok;"..minetest.formspec_escape(S("Done")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "textarea[0.75,0.1;7.25,9;text;;" .. minetest.formspec_escape(text) .. "]" .. + "button[0.75,7.95;3,1;sign;" .. minetest.formspec_escape(S("Sign")) .. "]" .. + "button_exit[4.25,7.95;3,1;ok;" .. minetest.formspec_escape(S("Done")) .. "]" minetest.show_formspec(user:get_player_name(), "mcl_books:writable_book", formspec) end @@ -106,17 +107,18 @@ local function read(itemstack, user, pointed_thing) local node = minetest.get_node(pointed_thing.under) if user and not user:get_player_control().sneak then if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or + itemstack end end end local text = get_text(itemstack) - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "textarea[0.75,0.1;7.25,9;;"..minetest.formspec_escape(text)..";]".. - "button_exit[2.25,7.95;3,1;ok;"..minetest.formspec_escape(S("Done")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "textarea[0.75,0.1;7.25,9;;" .. minetest.formspec_escape(text) .. ";]" .. + "button_exit[2.25,7.95;3,1;ok;" .. minetest.formspec_escape(S("Done")) .. "]" minetest.show_formspec(user:get_player_name(), "mcl_books:written_book", formspec) end @@ -125,16 +127,18 @@ minetest.register_craftitem("mcl_books:writable_book", { description = S("Book and Quill"), _tt_help = S("Write down some notes"), _doc_items_longdesc = S("This item can be used to write down some notes."), - _doc_items_usagehelp = S("Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.").."\n".. - S("A book can hold up to 4500 characters. The title length is limited to 64 characters."), + _doc_items_usagehelp = S( + "Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.") + .. "\n" .. + S("A book can hold up to 4500 characters. The title length is limited to 64 characters."), inventory_image = "mcl_books_book_writable.png", - groups = { book=1 }, + groups = { book = 1 }, stack_max = 1, on_place = write, on_secondary_use = write, }) -minetest.register_on_player_receive_fields(function ( player, formname, fields ) +minetest.register_on_player_receive_fields(function(player, formname, fields) if ((formname == "mcl_books:writable_book") and fields and fields.text) then local stack = player:get_wielded_item() if (stack:get_name() and (stack:get_name() == "mcl_books:writable_book")) then @@ -148,14 +152,17 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields ) player:set_wielded_item(stack) local name = player:get_player_name() - local formspec = "size[8,9]".. - header.. - "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]".. - "field[0.75,1;7.25,1;title;"..minetest.formspec_escape(minetest.colorize("#000000", S("Enter book title:")))..";]".. - "label[0.75,1.5;"..minetest.formspec_escape(minetest.colorize("#404040", S("by @1", name))).."]".. - "button_exit[0.75,7.95;3,1;sign;"..minetest.formspec_escape(S("Sign and Close")).."]".. - "tooltip[sign;"..minetest.formspec_escape(S("Note: The book will no longer be editable after signing")).."]".. - "button[4.25,7.95;3,1;cancel;"..minetest.formspec_escape(S("Cancel")).."]" + local formspec = "size[8,9]" .. + header .. + "background[-0.5,-0.5;9,10;mcl_books_book_bg.png]" .. + "field[0.75,1;7.25,1;title;" .. + minetest.formspec_escape(minetest.colorize("#000000", S("Enter book title:"))) .. ";]" .. + "label[0.75,1.5;" .. + minetest.formspec_escape(minetest.colorize("#404040", S("by @1", name))) .. "]" .. + "button_exit[0.75,7.95;3,1;sign;" .. minetest.formspec_escape(S("Sign and Close")) .. "]" .. + "tooltip[sign;" .. + minetest.formspec_escape(S("Note: The book will no longer be editable after signing")) .. "]" .. + "button[4.25,7.95;3,1;cancel;" .. minetest.formspec_escape(S("Cancel")) .. "]" minetest.show_formspec(player:get_player_name(), "mcl_books:signing", formspec) end end @@ -181,7 +188,7 @@ minetest.register_on_player_receive_fields(function ( player, formname, fields ) player:set_wielded_item(newbook) else - minetest.log("error", "[mcl_books] "..name.." failed to sign a book!") + minetest.log("error", "[mcl_books] " .. name .. " failed to sign a book!") end elseif ((formname == "mcl_books:signing") and fields and fields.cancel) then local book = player:get_wielded_item() @@ -202,12 +209,16 @@ end -- Written Book minetest.register_craftitem("mcl_books:written_book", { description = S("Written Book"), - _doc_items_longdesc = S("Written books contain some text written by someone. They can be read and copied, but not edited."), - _doc_items_usagehelp = S("Hold it in your hand, then rightclick to read the book.").."\n\n".. - -S("To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied."), + _doc_items_longdesc = S( + "Written books contain some text written by someone. They can be read and copied, but not edited." + ), + _doc_items_usagehelp = S("Hold it in your hand, then rightclick to read the book.") .. + "\n\n" .. + S( + "To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied." + ), inventory_image = "mcl_books_book_written.png", - groups = { not_in_creative_inventory=1, book=1, no_rename=1 }, + groups = { not_in_creative_inventory = 1, book = 1, no_rename = 1 }, stack_max = 16, on_place = read, on_secondary_use = read @@ -219,19 +230,19 @@ S("To copy the text of the written book, place it into the crafting grid togethe local baq = "mcl_books:writable_book" local wb = "mcl_books:written_book" local recipes = { - {wb, baq}, - {baq, baq, wb}, - {baq, baq, wb, baq}, - {baq, baq, baq, baq, wb}, - {baq, baq, baq, baq, wb, baq}, - {baq, baq, baq, baq, wb, baq, baq}, - {baq, baq, baq, baq, wb, baq, baq, baq}, - {baq, baq, baq, baq, wb, baq, baq, baq, baq}, + { wb, baq }, + { baq, baq, wb }, + { baq, baq, wb, baq }, + { baq, baq, baq, baq, wb }, + { baq, baq, baq, baq, wb, baq }, + { baq, baq, baq, baq, wb, baq, baq }, + { baq, baq, baq, baq, wb, baq, baq, baq }, + { baq, baq, baq, baq, wb, baq, baq, baq, baq }, } -for r=#recipes, 1, -1 do +for r = #recipes, 1, -1 do minetest.register_craft({ type = "shapeless", - output = "mcl_books:written_book "..r, + output = "mcl_books:written_book " .. r, recipe = recipes[r], }) end @@ -367,6 +378,9 @@ local function protection_check_put_take(pos, listname, index, stack, player) end end +---@param pos Vector +---@param node node +---@param clicker ObjectRef local function bookshelf_gui(pos, node, clicker) if not bookshelf_inv then return end local name = minetest.get_meta(pos):get_string("name") @@ -378,18 +392,22 @@ local function bookshelf_gui(pos, node, clicker) local playername = clicker:get_player_name() minetest.show_formspec(playername, - "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z, + "mcl_books:bookshelf_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, table.concat({ - "size[9,8.75]", - "label[0,0;"..F(C("#313131", name)).."]", - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]", - mcl_formspec.get_itemslot_bg(0, 0.5, 9, 3), - "label[0,4.0;"..F(C("#313131", S("Inventory"))).."]", - "list[current_player;main;0,4.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3), - "list[current_player;main;0,7.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1), - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]", + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3, 0, "mcl_book_book_empty_slot.png"), + "list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(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[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";main]", "listring[current_player;main]", }) ) @@ -397,7 +415,7 @@ end local function close_forms(pos) local players = minetest.get_connected_players() - local formname = "mcl_books:bookshelf_"..pos.x.."_"..pos.y.."_"..pos.z + local formname = "mcl_books:bookshelf_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then minetest.close_formspec(players[p]:get_player_name(), formname) @@ -409,12 +427,18 @@ end minetest.register_node("mcl_books:bookshelf", { description = S("Bookshelf"), _doc_items_longdesc = S("Bookshelves are used for decoration."), - tiles = {"mcl_books_bookshelf_top.png", "mcl_books_bookshelf_top.png", "default_bookshelf.png"}, + tiles = { "mcl_books_bookshelf_top.png", "mcl_books_bookshelf_top.png", "default_bookshelf.png" }, stack_max = 64, is_ground_content = false, groups = { - handy=1, axey=1, deco_block=1, material_wood=1, - flammable=3, fire_encouragement=30, fire_flammability=20, container=1 + handy = 1, + axey = 1, + deco_block = 1, + material_wood = 1, + flammable = 3, + fire_encouragement = 30, + fire_flammability = 20, + container = 2 }, drop = "mcl_books:book 3", sounds = wood_sound, @@ -424,7 +448,7 @@ minetest.register_node("mcl_books:bookshelf", { on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) end, after_place_node = function(pos, placer, itemstack, pointed_thing) minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) @@ -433,29 +457,38 @@ minetest.register_node("mcl_books:bookshelf", { allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in bookshelf at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to bookshelf at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from bookshelf at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from bookshelf at " .. minetest.pos_to_string(pos)) end, after_dig_node = drop_content, on_blast = on_blast, on_rightclick = bookshelf_gui, 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() + local function filter(stack) + return minetest.get_item_group(stack:get_name(), "book") == 1 or + stack:get_name() == "mcl_enchanting:book_enchanted" + end + return inv, "main", mcl_util.select_stack(hop_inv, hop_list, inv, "main", filter, 1) + end, }) minetest.register_craft({ output = "mcl_books:bookshelf", recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"mcl_books:book", "mcl_books:book", "mcl_books:book"}, - {"group:wood", "group:wood", "group:wood"}, + { "group:wood", "group:wood", "group:wood" }, + { "mcl_books:book", "mcl_books:book", "mcl_books:book" }, + { "group:wood", "group:wood", "group:wood" }, } }) @@ -464,4 +497,3 @@ minetest.register_craft({ recipe = "mcl_books:bookshelf", burntime = 15, }) - diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr b/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr index fbbb543fd..ed84cf067 100644 --- a/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr +++ b/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr @@ -2,7 +2,7 @@ Book=Livro Books are used to make bookshelves and book and quills.=Livros são utilizados para fazer prateleiras de livros e livro e pena. “@1”= -Copy of “@1”=Copia de "@1" +Copy of “@1”=Cópia de "@1" Copy of Copy of “@1”=Cópia da Cópia de "@1" Tattered Book=Livro Esfarrapado by @1=por @1 diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.ru.tr b/mods/ITEMS/mcl_books/locale/mcl_books.ru.tr index a4cc9804c..4eedf3b57 100644 --- a/mods/ITEMS/mcl_books/locale/mcl_books.ru.tr +++ b/mods/ITEMS/mcl_books/locale/mcl_books.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_books -Book=Книги +Book=Книга Books are used to make bookshelves and book and quills.=Из книг можно создавать книжные полки и книги с перьями. “@1”=“@1” Copy of “@1”=Копия “@1” @@ -10,7 +10,7 @@ by @1=игрока @1 Sign=Подписать Done=Готово This item can be used to write down some notes.=Этот предмет можно использовать для записи заметок. -Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=Удерживая его в руке, кликните правой, чтобы прочитать текущие записи и отредактировать. Вы можете редактировать текст, сколько захотите. Вы также можете подписать книгу, что превратит её в подписанную книгу, её можно будет уложить в стопку с другими такими же, но больше нельзя будет редактировать. +Hold it in the hand, then rightclick to read the current notes and edit then. You can edit the text as often as you like. You can also sign the book which turns it into a written book which you can stack, but it can't be edited anymore.=Удерживая книгу в руке, кликните правой кнопкой мыши, чтобы прочитать текущие записи и отредактировать их. Вы можете редактировать текст сколько угодно. Вы также можете подписать книгу, что превратит её в подписанную книгу, её можно будет уложить в стопку с другими такими же, но больше нельзя будет редактировать. A book can hold up to 4500 characters. The title length is limited to 64 characters.=Книга может содержать до 4500 символов. Длина названия ограничена 64 символами. Enter book title:=Введите название книги by @1=игрока @1 @@ -20,9 +20,9 @@ Cancel=Отмена Nameless Book=Безымянная книга Written Book=Подписанная книга Written books contain some text written by someone. They can be read and copied, but not edited.=Подписанная книга содержит текст, написанный кем-то. Она может быть прочитана и скопирована, но её нельзя редактировать. -Hold it in your hand, then rightclick to read the book.=Удерживая в руке, кликните правой, чтобы прочитать книгу. -To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=Чтобы скопировать текст подписанной книги, поместите её в крафтинговую решётку вместе с книгой с пером (или сразу несколькими) и скрафтите. Подписанная книга не израсходуется. Не могут быть скопированы копии копий. +Hold it in your hand, then rightclick to read the book.=Удерживая в руке, кликните правой кнопкой мыши, чтобы прочитать книгу. +To copy the text of the written book, place it into the crafting grid together with a book and quill (or multiple of those) and craft. The written book will not be consumed. Copies of copies can not be copied.=Чтобы скопировать текст подписанной книги, поместите её в сетку крафта вместе с книгой с пером (или сразу несколькими) и скрафтите. Подписанная книга не израсходуется. Копии копий нельзя скопировать. Bookshelf=Книжная полка -Bookshelves are used for decoration.=Книжные полки используют в качестве украшений +Bookshelves are used for decoration.=Книжные полки используют в качестве декораций Book and Quill=Книга с пером -Write down some notes=Сделайте какие-нибудь записи +Write down some notes=Сделайте записи diff --git a/mods/ITEMS/mcl_bows/README.txt b/mods/ITEMS/mcl_bows/README.txt index fe879c95c..8d25ad905 100644 --- a/mods/ITEMS/mcl_bows/README.txt +++ b/mods/ITEMS/mcl_bows/README.txt @@ -1,11 +1,11 @@ -This mod adds bows and arrows for MineClone 2. +This mod adds bows and arrows for VoxeLibre. License: * Source code: LGPL 3.0 * Incorporates code from the [bow] mod by Arcelmi. https://github.com/Arcelmi/minetest-bows -* Textures: See MineClone 2 license notes. +* Textures: See VoxeLibre license notes. * Sounds: * mcl_bows_bow_shoot.ogg: CC0 by Freesound.org user JoeDinesSound https://freesound.org/people/JoeDinesSound/sounds/534942/ diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index 2181d7b98..652819aa6 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -1,6 +1,7 @@ local S = minetest.get_translator(minetest.get_current_modname()) local mod_target = minetest.get_modpath("mcl_target") +local mod_campfire = minetest.get_modpath("mcl_campfires") local enable_pvp = minetest.settings:get_bool("enable_pvp") local math = math @@ -248,7 +249,7 @@ function ARROW_ENTITY.on_step(self, dtime) end -- Punch target object but avoid hurting enderman. - if not lua or lua.name ~= "mobs_mc:enderman" then + if not lua or lua.name ~= "mobs_mc:rover" then if not self._in_player then damage_particles(vector.add(pos, vector.multiply(self.object:get_velocity(), 0.1)), self._is_critical) end @@ -395,6 +396,11 @@ function ARROW_ENTITY.on_step(self, dtime) tnt.ignite(self._stuckin) end + -- Ignite Campfires + if mod_campfire and mcl_burning.is_burning(self.object) and minetest.get_item_group(snode.name, "campfire") ~= 0 then + mcl_campfires.light_campfire(self._stuckin) + end + -- Activate target if mod_target and snode.name == "mcl_target:target_off" then mcl_target.hit(self._stuckin, 1) --10 redstone ticks diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 23b6b4310..9f381f501 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -33,6 +33,15 @@ local bow_load = {} -- Another player table, this one stores the wield index of the bow being charged local bow_index = {} +-- define FOV modifier(s) +mcl_fovapi.register_modifier({ + name = "bowcomplete", + fov_factor = 0.8, + time = 1, + reset_time = 0.3, + is_multiplier = true, +}) + function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical, bow_stack, collectable) local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity") if power == nil then @@ -48,7 +57,9 @@ function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage, damage = damage + (enchantments.power + 1) / 4 end if enchantments.punch then - knockback = enchantments.punch * 3 + knockback = enchantments.punch * 24 + else + knockback = 4.875 end if enchantments.flame then mcl_burning.set_on_fire(obj, math.huge) @@ -131,7 +142,7 @@ minetest.register_tool("mcl_bows:bow", { _tt_help = S("Launches arrows"), _doc_items_longdesc = S("Bows are ranged weapons to shoot arrows at your foes.").."\n".. S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), - _doc_items_usagehelp = S("To use the bow, 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."), + _doc_items_usagehelp = S("To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Hold down the right mouse button (or the zoom key) to charge, release to shoot."), _doc_items_durability = BOW_DURABILITY, inventory_image = "mcl_bows_bow.png", wield_scale = mcl_vars.tool_wield_scale, @@ -183,6 +194,9 @@ end -- Resets the bow charging state and player speed. To be used when the player is no longer charging the bow local function reset_bow_state(player, also_reset_bows) + -- clear the FOV change from the player. + mcl_fovapi.remove_modifier(player, "bowcomplete") -- for the complete zoom in FOV Modifier. + bow_load[player:get_player_name()] = nil bow_index[player:get_player_name()] = nil if minetest.get_modpath("playerphysics") then @@ -227,7 +241,7 @@ end controls.register_on_release(function(player, key, time) - if key~="RMB" then return end + if key~="RMB" and key~="zoom" then return end --local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) local wielditem = player:get_wielded_item() if (wielditem:get_name()=="mcl_bows:bow_0" or wielditem:get_name()=="mcl_bows:bow_1" or wielditem:get_name()=="mcl_bows:bow_2" or @@ -256,10 +270,10 @@ controls.register_on_release(function(player, key, time) local is_critical = false if charge >= BOW_CHARGE_TIME_FULL then speed = BOW_MAX_SPEED - local r = math.random(1,5) - if r == 1 then - -- 20% chance for critical hit - damage = 10 + local r = math.random(1,5) + mcl_luck.get_luck(player:get_player_name()) + if r > 4 then + -- 20% chance for critical hit (by default) + damage = 10 + math.floor((r-5)/5) -- mega crit (over crit) with high luck is_critical = true else damage = 9 @@ -286,6 +300,7 @@ controls.register_on_release(function(player, key, time) durability = durability * (unbreaking + 1) end wielditem:add_wear(65535/durability) + tt.reload_itemstack_description(wielditem) -- update tooltip end player:set_wielded_item(wielditem) reset_bow_state(player, true) @@ -295,25 +310,30 @@ end) controls.register_on_hold(function(player, key, time) local name = player:get_player_name() local creative = minetest.is_creative_enabled(name) - if key ~= "RMB" or not (creative or get_arrow(player)) then + if (key ~= "RMB" and key ~= "zoom") or not (creative or get_arrow(player)) then return end --local inv = minetest.get_inventory({type="player", name=name}) local wielditem = player:get_wielded_item() - if bow_load[name] == nil and (wielditem:get_name()=="mcl_bows:bow" or wielditem:get_name()=="mcl_bows:bow_enchanted") and wielditem:get_meta():get("active") and (creative or get_arrow(player)) then - local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) - if enchanted then - wielditem:set_name("mcl_bows:bow_0_enchanted") - else - wielditem:set_name("mcl_bows:bow_0") - end - player:set_wielded_item(wielditem) - if minetest.get_modpath("playerphysics") then - -- Slow player down when using bow - playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_bow", PLAYER_USE_BOW_SPEED) - end - bow_load[name] = minetest.get_us_time() - bow_index[name] = player:get_wield_index() + if bow_load[name] == nil + and (wielditem:get_name()=="mcl_bows:bow" or wielditem:get_name()=="mcl_bows:bow_enchanted") + and (wielditem:get_meta():get("active") or key == "zoom") and (creative or get_arrow(player)) then + local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) + if enchanted then + wielditem:set_name("mcl_bows:bow_0_enchanted") + else + wielditem:set_name("mcl_bows:bow_0") + end + player:set_wielded_item(wielditem) + if minetest.get_modpath("playerphysics") then + -- Slow player down when using bow + playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_bow", PLAYER_USE_BOW_SPEED) + end + bow_load[name] = minetest.get_us_time() + bow_index[name] = player:get_wield_index() + + -- begin Bow Zoom. + mcl_fovapi.apply_modifier(player, "bowcomplete") else if player:get_wield_index() == bow_index[name] then if type(bow_load[name]) == "number" then diff --git a/mods/ITEMS/mcl_bows/crossbow.lua b/mods/ITEMS/mcl_bows/crossbow.lua index 752ccdc54..c1cb7f8be 100644 --- a/mods/ITEMS/mcl_bows/crossbow.lua +++ b/mods/ITEMS/mcl_bows/crossbow.lua @@ -48,7 +48,7 @@ function mcl_bows_s.shoot_arrow_crossbow(arrow_item, pos, dir, yaw, shooter, pow if damage == nil then damage = 3 end - local knockback + local knockback = 4.875 if crossbow_stack then local enchantments = mcl_enchanting.get_enchantments(crossbow_stack) if enchantments.piercing then @@ -132,7 +132,7 @@ minetest.register_tool("mcl_bows:crossbow", { _tt_help = S("Launches arrows"), _doc_items_longdesc = S("Crossbows are ranged weapons to shoot arrows at your foes.").."\n".. S("The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead."), - _doc_items_usagehelp = S("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."), + _doc_items_usagehelp = S("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 (or zoom key) to charge, release to load an arrow into the chamber, then to shoot press left mouse."), _doc_items_durability = BOW_DURABILITY, inventory_image = "mcl_bows_crossbow.png", wield_scale = mcl_vars.tool_wield_scale, @@ -263,7 +263,7 @@ end controls.register_on_release(function(player, key, time) - if key~="RMB" then return end + if key~="RMB" and key~="zoom" then return end --local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) local wielditem = player:get_wielded_item() if wielditem:get_name()=="mcl_bows:crossbow_2" and get_arrow(player) or wielditem:get_name()=="mcl_bows:crossbow_2" and minetest.is_creative_enabled(player:get_player_name()) or wielditem:get_name()=="mcl_bows:crossbow_2_enchanted" and get_arrow(player) or wielditem:get_name()=="mcl_bows:crossbow_2_enchanted" and minetest.is_creative_enabled(player:get_player_name()) then @@ -322,10 +322,10 @@ controls.register_on_press(function(player, key, time) -- Fully charged local is_critical = false speed = BOW_MAX_SPEED - local r = math.random(1,5) - if r == 1 then - -- 20% chance for critical hit - damage = 10 + local r = math.random(1,5) + mcl_luck.get_luck(player:get_player_name()) + if r > 4 then + -- 20% chance for critical hit (by default) + damage = 10 + math.floor((r-5)/5) -- mega crit (over crit) with high luck is_critical = true else damage = 9 @@ -350,6 +350,7 @@ controls.register_on_press(function(player, key, time) durability = durability / 3 end wielditem:add_wear(65535/durability) + tt.reload_itemstack_description(wielditem) -- update tooltip end player:set_wielded_item(wielditem) reset_bow_state(player, true) @@ -359,7 +360,7 @@ end) controls.register_on_hold(function(player, key, time) local name = player:get_player_name() local creative = minetest.is_creative_enabled(name) - if key ~= "RMB" then + if key ~= "RMB" and key ~= "zoom" then return end --local inv = minetest.get_inventory({type="player", name=name}) @@ -373,22 +374,24 @@ controls.register_on_hold(function(player, key, time) BOW_CHARGE_TIME_FULL = _BOW_CHARGE_TIME_FULL end - if bow_load[name] == nil and (wielditem:get_name()=="mcl_bows:crossbow" or wielditem:get_name()=="mcl_bows:crossbow_enchanted") and wielditem:get_meta():get("active") and (creative or get_arrow(player)) then - local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) - if enchanted then - wielditem:set_name("mcl_bows:crossbow_0_enchanted") - play_load_sound(0, player:get_pos()) - else - wielditem:set_name("mcl_bows:crossbow_0") - play_load_sound(0, player:get_pos()) - end - player:set_wielded_item(wielditem) - if minetest.get_modpath("playerphysics") then - -- Slow player down when using bow - playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_crossbow", PLAYER_USE_CROSSBOW_SPEED) - end - bow_load[name] = minetest.get_us_time() - bow_index[name] = player:get_wield_index() + if bow_load[name] == nil + and (wielditem:get_name()=="mcl_bows:crossbow" or wielditem:get_name()=="mcl_bows:crossbow_enchanted") + and (wielditem:get_meta():get("active") or key=="zoom") and (creative or get_arrow(player)) then + local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) + if enchanted then + wielditem:set_name("mcl_bows:crossbow_0_enchanted") + play_load_sound(0, player:get_pos()) + else + wielditem:set_name("mcl_bows:crossbow_0") + play_load_sound(0, player:get_pos()) + end + player:set_wielded_item(wielditem) + if minetest.get_modpath("playerphysics") then + -- Slow player down when using bow + playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_crossbow", PLAYER_USE_CROSSBOW_SPEED) + end + bow_load[name] = minetest.get_us_time() + bow_index[name] = player:get_wield_index() else if player:get_wield_index() == bow_index[name] then if type(bow_load[name]) == "number" then diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr index 4ed4d8640..0375eb320 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr @@ -11,7 +11,7 @@ To use the bow, you first need to have at least one arrow anywhere in your inven Bow=Arco Ammunition=Munición Damage from bow: 1-10=Daño con arco: 1-10 -Damage from dispenser: 3=Daño por dispendsador: 3 +Damage from dispenser: 3=Daño por dispensador: 3 Launches arrows=Lanza flechas Crossbow=Ballesta Crossbows are ranged weapons to shoot arrows at your foes.=Las ballestas son armas a distancia para disparar flechas a tus enemigos. diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr index 901be04df..6f91cd986 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr @@ -15,4 +15,4 @@ Damage from dispenser: 3=Dégâts du distributeur : 3 Launches arrows=Lance des flèches 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. -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. diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr index 66044f8a0..ebb9e407c 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr @@ -9,7 +9,7 @@ Bows are ranged weapons to shoot arrows at your foes.=Arcos são armas de longo The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead.=A velocidade e o dano da flecha aumenta quanto mais você puxar o arco. O dano regular de uma flecha varia entre 1 e 9. Quando puxado no máximo, há também uma chance de 20% de causar acerto crítico, efetuando 10 de dano. To use the bow, 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.=Para usar o arco, você primeiro precisa possuir pelo menos uma flecha em qualquer lugar do seu inventário (a não ser no Modo Criativo). Segure o botão direito do mouse para puxar o arco, solte-o para disparar. Bow=Arco -Ammunition=munição +Ammunition=Munição Damage from bow: 1-10=Dano provocado pelo arco: 1-10 Damage from dispenser: 3=Dano provocado pelo dispensor: 3 Launches arrows=Dispara flechas diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.ru.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.ru.tr index 6a1b7ed31..87e41fe95 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.ru.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.ru.tr @@ -1,15 +1,18 @@ # textdomain: mcl_bows Arrow=Стрела -Arrows are ammunition for bows and dispensers.=Стрелы - это боеприпасы для луков и диспенсеров. -An arrow fired from a bow has a regular damage of 1-9. At full charge, there's a 20% chance of a critical hit dealing 10 damage instead. An arrow fired from a dispenser always deals 3 damage.=Стрела, выпущенная из лука, обычно наносит урон 1-9. При полном натяжении есть 20-процентный шанс критического удара с уроном 10. Стрела из диспенсера всегда наносит урон уровня 3. -Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=Стрелы могут застревать в твёрдых блоках, их можно подбирать для повторного использования. Они также способны нажимать деревянные кнопки. -To use arrows as ammunition for a bow, just put them anywhere in your inventory, they will be used up automatically. To use arrows as ammunition for a dispenser, place them in the dispenser's inventory. To retrieve an arrow that sticks in a block, simply walk close to it.=Чтобы использовать стрелы в качестве боеприпасов для лука, просто положите их в любую ячейку вашего инвентаря, и они будут использоваться автоматически. Чтобы использовать стрелы в качестве боеприпасов для диспенсера, поместите их в инвентарь диспенсера. Чтобы взять стрелу, застрявшую в блоке, просто пройдите рядом с ней. +Arrows are ammunition for bows and dispensers.=Стрелы это боеприпасы для луков и раздатчиков. +An arrow fired from a bow has a regular damage of 1-9. At full charge, there's a 20% chance of a critical hit dealing 10 damage instead. An arrow fired from a dispenser always deals 3 damage.=Стрела, выпущенная из лука, обычно наносит урон 1-9. При полном натяжении есть шанс в 20% для критического удара с уроном 10. Стрела из раздатчика всегда наносит урон 3. +Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=Стрелы могут застревать в твёрдых блоках, тогда их можно снова подобрать. Стрелы также способны нажимать деревянные кнопки. +To use arrows as ammunition for a bow, just put them anywhere in your inventory, they will be used up automatically. To use arrows as ammunition for a dispenser, place them in the dispenser's inventory. To retrieve an arrow that sticks in a block, simply walk close to it.=Чтобы использовать стрелы в качестве боеприпасов для лука, просто положите их в любую ячейку вашего инвентаря, и они будут использоваться автоматически. Чтобы использовать стрелы в качестве боеприпасов для раздатчика, поместите их в инвентарь раздатчика. Чтобы взять стрелу, застрявшую в блоке, просто пройдите рядом с ней. Bow=Лук -Bows are ranged weapons to shoot arrows at your foes.=Лук - это оружие дальнего боя, чтобы стрелять стрелами по вашим врагам. +Bows are ranged weapons to shoot arrows at your foes.=Лук это оружие дальнего боя, позволяющее стрелять стрелами в ваших врагов. The speed and damage of the arrow increases the longer you charge. The regular damage of the arrow is between 1 and 9. At full charge, there's also a 20% of a critical hit, dealing 10 damage instead.=Скорость и урон стрелы увеличиваются, пока вы её натягиваете. Обычный урон стрелы находится между 1 и 9. При полном натяжении есть 20-процентный шанс критического удара с уроном 10. To use the bow, 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.=Чтобы использовать лук, нужно иметь хотя бы одну стрелу в вашем инвентаре (за исключением творческого режима). Удерживайте правую клавишу мыши, чтобы натягивать тетиву, затем отпустите, чтобы выстрелить. Bow=Лук Ammunition=Боеприпасы -Damage from bow: 1-10=Урон от лука: 1-10 -Damage from dispenser: 3=Урон от диспенсера: 3 -Launches arrows=Пускает стрелы +Damage from bow: 1-10=Урон из лука: 1-10 +Damage from dispenser: 3=Урон из раздатчика: 3 +Launches arrows=Выпускает стрелы +Crossbow=Арбалет +Crossbows are ranged weapons to shoot arrows at your foes.=Арбалет это оружие дальнего боя, позволяющее стрелять стрелами в ваших врагов. +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.=Чтобы использовать арбалет, нужно иметь хотя бы одну стрелу в вашем инвентаре (за исключением творческого режима). Удерживайте правую клавишу мыши, чтобы зарядить стрелу, затем нажмите левую кнопку мыши, чтобы выстрелить. diff --git a/mods/ITEMS/mcl_bows/locale/template.txt b/mods/ITEMS/mcl_bows/locale/template.txt index ebdea9525..0c5565725 100644 --- a/mods/ITEMS/mcl_bows/locale/template.txt +++ b/mods/ITEMS/mcl_bows/locale/template.txt @@ -15,4 +15,4 @@ Damage from dispenser: 3= Launches arrows= Crossbow= Crossbows are ranged weapons to shoot arrows at your foes.= -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.= \ No newline at end of file +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.= diff --git a/mods/ITEMS/mcl_bows/mod.conf b/mods/ITEMS/mcl_bows/mod.conf index 7b174826a..61fb52ddb 100644 --- a/mods/ITEMS/mcl_bows/mod.conf +++ b/mods/ITEMS/mcl_bows/mod.conf @@ -1,6 +1,6 @@ name = mcl_bows author = Arcelmi description = This mod adds bows and arrows for MineClone 2. -depends = controls, mcl_particles, mcl_enchanting, mcl_init, mcl_util, mcl_shields +depends = controls, mcl_particles, mcl_enchanting, mcl_init, mcl_util, mcl_shields, mcl_fovapi, mcl_luck optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua index e71c0c122..8cd690171 100644 --- a/mods/ITEMS/mcl_bows/rocket.lua +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -27,11 +27,11 @@ local function damage_explosion(self, damagemulitplier) for _,obj in pairs(objects) do if obj:is_player() then mcl_util.deal_damage(obj, damagemulitplier - vector.distance(p, obj:get_pos()), {type = "explosion"}) - elseif obj:get_luaentity().is_mob then + elseif obj:get_luaentity() and obj:get_luaentity().is_mob then obj:punch(self.object, 1.0, { full_punch_interval=1.0, damage_groups={fleshy=damagemulitplier - vector.distance(p, obj:get_pos())}, - }, self.object:get_velocity()) + }, self.object:get_velocity()) -- TODO possibly change the punch dir to be outwards instead of rocket velocity end end end @@ -470,7 +470,7 @@ function ARROW_ENTITY.on_step(self, dtime) end -- Punch target object but avoid hurting enderman. - if not lua or lua.name ~= "mobs_mc:enderman" then + if not lua or lua.name ~= "mobs_mc:rover" then if self._in_player == false then damage_particles(self.object:get_pos(), self._is_critical) end diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua index 9c6879430..937d9089c 100644 --- a/mods/ITEMS/mcl_brewing/init.lua +++ b/mods/ITEMS/mcl_brewing/init.lua @@ -82,7 +82,7 @@ local function brewable(inv) for i=1,stand_size do - bottle = inv:get_stack("stand", i):get_name() + bottle = inv:get_stack("stand", i) alchemy = mcl_potions.get_alchemy(ingredient, bottle) if alchemy then @@ -340,6 +340,7 @@ local function on_put(pos, listname, index, stack, player) local inv = meta:get_inventory() local str = "" local stack + local oldparam2 = minetest.get_node(pos).param2 for i=1, inv:get_size("stand") do stack = inv:get_stack("stand", i) if not stack:is_empty() then @@ -347,7 +348,7 @@ local function on_put(pos, listname, index, stack, player) else str = str.."0" end end - minetest.swap_node(pos, {name = "mcl_brewing:stand_"..str}) + minetest.swap_node(pos, {name = "mcl_brewing:stand_"..str, param2 = oldparam2}) minetest.get_node_timer(pos):start(1.0) --some code here to enforce only potions getting placed on stands end @@ -376,13 +377,52 @@ local function allow_take(pos, listname, index, stack, player) 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 + local function filter(stack) + return minetest.get_item_group(stack:get_name(), "brewitem") == 1 and + minetest.get_item_group(stack:get_name(), "bottle") == 0 + end + + return inv, "input", mcl_util.select_stack(hop_inv, hop_list, inv, "input", filter, 1) + else + local filter = function(stack) + return stack:get_name() == "mcl_mobitems:blaze_powder" + end + local stack = mcl_util.select_stack(hop_inv, hop_list, inv, "fuel", filter, 1 ) + if stack then + return inv, "fuel", stack + else + local function filter(stack) + return minetest.get_item_group(stack:get_name(), "bottle") == 1 + end + return inv, "stand", mcl_util.select_stack(hop_inv, hop_list, inv, "stand", filter, 1) + 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", { description = S("Brewing Stand"), _doc_items_longdesc = S("The stand allows you to brew potions!"), _doc_items_usagehelp = doc_string, _tt_help = S("Brew Potions"), - groups = {pickaxey=1, brewitem=1 }, + groups = {pickaxey=1, container = 2, brewitem=1 }, tiles = tiles, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -444,12 +484,20 @@ minetest.register_node("mcl_brewing:stand_000", { on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -514,13 +562,21 @@ minetest.register_node("mcl_brewing:stand_100", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -586,13 +642,21 @@ minetest.register_node("mcl_brewing:stand_010", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -653,13 +717,21 @@ minetest.register_node("mcl_brewing:stand_001", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -730,13 +802,21 @@ minetest.register_node("mcl_brewing:stand_110", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -803,13 +883,21 @@ minetest.register_node("mcl_brewing:stand_101", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -876,13 +964,21 @@ minetest.register_node("mcl_brewing:stand_011", { end, on_timer = brewing_stand_timer, 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", { description = S("Brewing Stand"), _doc_items_create_entry = false, _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, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", @@ -956,6 +1052,14 @@ minetest.register_node("mcl_brewing:stand_111", { end, on_timer = brewing_stand_timer, 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({ diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ru.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ru.tr index 37b96819d..ca0169a08 100644 --- a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ru.tr +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ru.tr @@ -1,10 +1,10 @@ # textdomain: mcl_brewing -Brewing Stand=Варочный стенд +Brewing Stand=Варочная стойка Inventory=Инвентарь -To use a brewing stand, rightclick it.=Кликните правой, чтобы использовать варочный стенд. -To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Для приготовления зелья вам понадобится огненный порошок в качестве топлива, исходный материал и как минимум 1 стеклянная бутылка, наполненная жидкостью. -Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Поместите огненный порошок в левый отсек, исходный материал в средний отсек и 1-3 бутылки в оставшиеся отсеки. -When you have found a good combination, the brewing will commence automatically and steam starts to appear, using up the fuel and brewing material. The potions will soon be ready.=Когда вы подберёте хорошее сочетание, приготовление зелья начнётся автоматически — появится пар и начнётся расход топлива и исходного материала. Зелья вскоре будут готовы. +To use a brewing stand, rightclick it.=Кликните правой кнопкой мыши, чтобы использовать варочную стойку. +To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Для приготовления зелья вам понадобится огненный порошок в качестве топлива, варочный материал и как минимум 1 стеклянный пузырёк, наполненный жидкостью. +Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Поместите огненный порошок в левый слот, варочный материал в средний слот и 1-3 пузырька в оставшиеся слоты. +When you have found a good combination, the brewing will commence automatically and steam starts to appear, using up the fuel and brewing material. The potions will soon be ready.=Когда вы подберёте хорошую комбинацию, варка зелья начнётся автоматически — появится пар и начнётся расход топлива и материала. Зелья вскоре будут готовы. Different combinations of brewing materials and liquids will give different results. Try to experiment!=Разные сочетания варочных материалов и жидкостей будут давать разные результаты. Поэкспериментируйте! -The stand allows you to brew potions!=Стенд позволяет вам варить зелья! +The stand allows you to brew potions!=Стойка позволяет вам варить зелья! Brew Potions=Зельеварение diff --git a/mods/ITEMS/mcl_buckets/README.md b/mods/ITEMS/mcl_buckets/README.md index b783cc133..be186fc31 100644 --- a/mods/ITEMS/mcl_buckets/README.md +++ b/mods/ITEMS/mcl_buckets/README.md @@ -1,5 +1,5 @@ -# MineClone2 Bucket (`mcl_bucket`) -Originally taken from Minetest Game, adapted for MineClone2. +# VoxeLibre Bucket (`mcl_bucket`) +Originally taken from Minetest Game, adapted for VoxeLibre. This mod add buckets to the game, including an API to register your own (see `API.md`). diff --git a/mods/ITEMS/mcl_buckets/fishbuckets.lua b/mods/ITEMS/mcl_buckets/fishbuckets.lua index 185f72486..bc93654da 100644 --- a/mods/ITEMS/mcl_buckets/fishbuckets.lua +++ b/mods/ITEMS/mcl_buckets/fishbuckets.lua @@ -18,13 +18,21 @@ local function on_place_fish(itemstack, placer, pointed_thing) return new_stack end - local pos = pointed_thing.above or pointed_thing.under - if not pos then return end - local n = minetest.get_node_or_nil(pos) - if n.name and minetest.registered_nodes[n.name].buildable_to or n.name == "mcl_portals:portal" then - local fish = itemstack:get_name():gsub(fishbucket_prefix,"") - if fish_names[fish] then - local o = minetest.add_entity(pos, "mobs_mc:" .. fish) + if pointed_thing.type ~= "node" then return end + + local pos = pointed_thing.above + local n = minetest.get_node(pointed_thing.above) + local def = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + + if ( def and def.buildable_to ) or n.name == "mcl_portals:portal" then + pos = pointed_thing.under + n = minetest.get_node(pointed_thing.under) + end + + local fish = itemstack:get_definition()._mcl_buckets_fish + if fish_names[fish] then + local o = minetest.add_entity(pos, "mobs_mc:" .. fish) + if o and o:get_pos() then local props = itemstack:get_meta():get_string("properties") if props ~= "" then o:set_properties(minetest.deserialize(props)) @@ -60,6 +68,7 @@ for techname, fishname in pairs(fish_names) do stack_max = 1, groups = {bucket = 1, fish_bucket = 1}, liquids_pointable = false, + _mcl_buckets_fish = techname, on_place = on_place_fish, on_secondary_use = on_place_fish, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ru.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ru.tr index 9c8cd0539..0fadbd06f 100644 --- a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ru.tr +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ru.tr @@ -1,17 +1,25 @@ # textdomain: mcl_buckets Empty Bucket=Пустое ведро A bucket can be used to collect and release liquids.=Ведро может быть использовано для набора и выливания жидкостей. -Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Ударьте источник жидкости, чтобы зачерпнуть его. После этого вы можете в ведре перенести жидкость в другое место. +Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Ударьте ведром источник жидкости, чтобы зачерпнуть его. После этого вы можете в ведре перенести жидкость в другое место. Lava Bucket=Ведро лавы A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Ведро может быть использовано для набора и выливания жидкостей. Это ведро наполнено лавой, которая безопасно хранится внутри. Используйте с осторожностью. -Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Стоя на безопасном расстоянии, поместите ведро в пустоту, чтобы создать источник лавы на этом участке. +Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Стоя на безопасном расстоянии, используйте ведро на пустом месте, чтобы создать источник лавы на этом участке. Water Bucket=Ведро воды A bucket can be used to collect and release liquids. This one is filled with water.=Ведро может быть использовано для набора и выливания жидкостей. Это ведро наполнено водой. -Place it to empty the bucket and create a water source.=Поместите ведро на пустой участок для создания водного источника. +Place it to empty the bucket and create a water source.=Используйте ведро на пустом месте для создания источника воды. River Water Bucket=Ведро речной воды A bucket can be used to collect and release liquids. This one is filled with river water.=Ведро может быть использовано для набора и выливания жидкостей. Это ведро наполнено речной водой. -Place it to empty the bucket and create a river water source.=Поместите ведро на пустой участок для создания источника речной воды. +Place it to empty the bucket and create a river water source.=Используйте ведро на пустом месте для создания источника речной воды. Collects liquids=Набирает жидкости Places a lava source=Переносит источник лавы Places a water source=Переносит источник воды Places a river water source=Переносит источник речной воды +Axolotl=аксолотлем +Cod=треской +Salmon=лососем +Tropical Fish=тропической рыбой +Bucket of @1=Ведро с @1 +This bucket is filled with water and @1.=Это ведро с водой и @1. +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.=Используйте, чтобы опустошить ведро с @1. Можно получить использовав ведро с водой на мобе. +Places a water source and a @1.=Переносит воду с @1 diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.ru.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.ru.tr index 50a5b34c1..9cb85d84c 100644 --- a/mods/ITEMS/mcl_cake/locale/mcl_cake.ru.tr +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.ru.tr @@ -1,12 +1,12 @@ # textdomain: mcl_cake Cake=Торт -Cakes can be placed and eaten to restore hunger points. A cake has 7 slices. Each slice restores 2 hunger points and 0.4 saturation points. Cakes will be destroyed when dug or when the block below them is broken.=Торты можно есть, восстанавливая очки голода, а также размещать на других блоках. Торт состоит из 7 кусочков. Каждый кусочек восстанавливает 2 очка голода и 0.4 очка сытости. Торты уничтожаются при выкапывании или разрушении нижестоящего блока. -Place the cake anywhere, then rightclick it to eat a single slice. You can't eat from the cake when your hunger bar is full.=Поместите торт куда-нибудь, затем кликните правой, чтобы съесть кусочек. +Cakes can be placed and eaten to restore hunger points. A cake has 7 slices. Each slice restores 2 hunger points and 0.4 saturation points. Cakes will be destroyed when dug or when the block below them is broken.=Торты можно разместить на блоке и съесть, чтобы восстановить очки голода. Торт состоит из 7 кусочков. Каждый кусочек восстанавливает 2 очка голода и 0.4 очка насыщения. Торты уничтожаются при выкапывании или разрушении нижестоящего блока. +Place the cake anywhere, then rightclick it to eat a single slice. You can't eat from the cake when your hunger bar is full.=Поместите торт куда-нибудь, затем кликните правой кнопкой мыши, чтобы съесть кусочек. Cake (6 Slices Left)=Торт (осталось 6 кусочков) Cake (5 Slices Left)=Торт (осталось 5 кусочков) Cake (4 Slices Left)=Торт (осталось 4 кусочка) Cake (3 Slices Left)=Торт (осталось 3 кусочка) Cake (2 Slices Left)=Торт (осталось 2 кусочка) Cake (1 Slice Left)=Торт (остался 1 кусочек) -With 7 tasty slices!=Из 7 вкусных кусочков -Hunger points: +@1 per slice=Очки голода: +@1 с каждым куском +With 7 tasty slices!=Из 7 вкусных кусочков! +Hunger points: +@1 per slice=Очки голода: +@1 на каждый кусочек diff --git a/mods/ITEMS/mcl_campfires/API.md b/mods/ITEMS/mcl_campfires/API.md index abf61c6f1..db97366f8 100644 --- a/mods/ITEMS/mcl_campfires/API.md +++ b/mods/ITEMS/mcl_campfires/API.md @@ -1,7 +1,5 @@ -MineClone 2 Campfire API -======================== -`mcl_campfires.register_campfire` ---------------------------------- +# VoxeLibre Campfire API +## `mcl_campfires.register_campfire` Used to register campfires. **Example Usage** @@ -23,4 +21,7 @@ mcl_campfires.register_campfire("mcl_campfires:campfire", { * lit_logs_texture - texture for the logs of the lit campfire. if not changed, specify mcl_campfires_log.png. * drops - what items drop when the campfire is mined. * lightlevel - the level of light the campfire emits. -* damage - amount of damage the campfire deals when the player stands on it. \ No newline at end of file +* damage - amount of damage the campfire deals when the player stands on it. + +## Cooking Items +To allow an item to be cooked on the campfire, it must first have a registered cooked variant. To allow placing the item on the campfire to be cooked, add `campfire_cookable = 1` into the item groups list. diff --git a/mods/ITEMS/mcl_campfires/README.md b/mods/ITEMS/mcl_campfires/README.md index 8747aa7e3..3ccd8becf 100644 --- a/mods/ITEMS/mcl_campfires/README.md +++ b/mods/ITEMS/mcl_campfires/README.md @@ -4,15 +4,19 @@ Adds the campfire and its soul variant. License of code --------------- -See the main MineClone 2 README.md file. +See the main VoxeLibre README.md file. Authors: Gerold55 - Code Start + Models? PrairieWind - Improved and Cleaned Up Code, and added the soul campfire and crafting recipes. cora - Added burning damage. +DinoNuggies4665 - Cooking logic implemented. +thunder1035 - Redesigned model and texture tweaks. +AncientMariner - Changed smoke to particle spawner and tweaked particle configuration. +Michieal - Fixed misc. errors. License of media ---------------- -See the main MineClone 2 README.md file for license on most of the textures. +See the main VoxeLibre README.md file for license on most of the textures. For the following textures: mcl_campfires_campfire_inv.png diff --git a/mods/ITEMS/mcl_campfires/api.lua b/mods/ITEMS/mcl_campfires/api.lua index 8b0aff85e..98318f3f1 100644 --- a/mods/ITEMS/mcl_campfires/api.lua +++ b/mods/ITEMS/mcl_campfires/api.lua @@ -1,6 +1,235 @@ local S = minetest.get_translator(minetest.get_current_modname()) mcl_campfires = {} +local COOK_TIME = 30 -- Time it takes to cook food on a campfire. + +local food_entity = {nil, nil, nil, nil} +local campfire_spots = { + vector.new(-0.25, -0.04, -0.25), + vector.new( 0.25, -0.04, -0.25), + vector.new( 0.25, -0.04, 0.25), + vector.new(-0.25, -0.04, 0.25), +} + +local drop_inventory = mcl_util.drop_items_from_meta_container("main") + +local function campfire_drops(pos, digger, drops, nodename) + local wield_item = digger:get_wielded_item() + local silk_touch = mcl_enchanting.has_enchantment(wield_item, "silk_touch") + local is_creative = minetest.is_creative_enabled(digger:get_player_name()) + local inv = digger:get_inventory() + if not is_creative then + if silk_touch then + minetest.add_item(pos, nodename) + else + minetest.add_item(pos, drops) + end + elseif is_creative and inv:room_for_item("main", nodename) and not inv:contains_item("main", nodename) then + inv:add_item("main", nodename) + end +end + +local function drop_items(pos, node, oldmeta) + local meta = minetest.get_meta(pos) + drop_inventory(pos, node, oldmeta) + local entites = minetest.get_objects_inside_radius(pos, 0.5) + if entites then + for _, food_entity in ipairs(entites) do + if food_entity then + if food_entity:get_luaentity().name == "mcl_campfires:food_entity" then + food_entity:remove() + for i = 1, 4 do + meta:set_string("food_x_"..tostring(i), nil) + meta:set_string("food_y_"..tostring(i), nil) + meta:set_string("food_z_"..tostring(i), nil) + end + end + end + end + end +end + +local function on_blast(pos) + local node = minetest.get_node(pos) + drop_items(pos, node) + minetest.remove_node(pos) +end + +function mcl_campfires.light_campfire(pos) + local campfire = minetest.get_node(pos) + local name = campfire.name .. "_lit" + minetest.set_node(pos, {name = name, param2 = campfire.param2}) +end + +-- on_rightclick function to take items that are cookable in a campfire, and put them in the campfire inventory +function mcl_campfires.take_item(pos, node, player, itemstack) + local food_entity = {nil,nil,nil,nil} + local is_creative = minetest.is_creative_enabled(player:get_player_name()) + local inv = player:get_inventory() + local campfire_meta = minetest.get_meta(pos) + local campfire_inv = campfire_meta:get_inventory() + local timer = minetest.get_node_timer(pos) + local stack = itemstack:peek_item(1) + if minetest.get_item_group(itemstack:get_name(), "campfire_cookable") ~= 0 then + local cookable = minetest.get_craft_result({method = "cooking", width = 1, items = {itemstack}}) + if cookable then + for space = 1, 4 do -- Cycle through spots + local spot = campfire_inv:get_stack("main", space) + if not spot or spot == (ItemStack("") or ItemStack("nil")) then -- Check if the spot is empty or not + if not is_creative then itemstack:take_item(1) end -- Take the item if in creative + campfire_inv:set_stack("main", space, stack) -- Set the inventory itemstack at the empty spot + campfire_meta:set_int("cooktime_"..tostring(space), COOK_TIME) -- Set the cook time meta + food_entity[space] = minetest.add_entity(pos + campfire_spots[space], "mcl_campfires:food_entity") -- Spawn food item on the campfire + local food_luaentity = food_entity[space]:get_luaentity() + food_luaentity.wield_item = campfire_inv:get_stack("main", space):get_name() -- Set the wielditem of the food item to the food on the campfire + food_luaentity.wield_image = "mcl_mobitems_"..string.sub(campfire_inv:get_stack("main", space):get_name(), 14).."_raw.png" -- Set the wield_image to the food item on the campfire + food_entity[space]:set_properties(food_luaentity) -- Apply changes to the food entity + campfire_meta:set_string("food_x_"..tostring(space), tostring(food_entity[space]:get_pos().x)) + campfire_meta:set_string("food_y_"..tostring(space), tostring(food_entity[space]:get_pos().y)) + campfire_meta:set_string("food_z_"..tostring(space), tostring(food_entity[space]:get_pos().z)) + break + end + end + end + timer:start(1) -- Start cook timer + end +end + +-- on_timer function to run the cook timer and cook items. +function mcl_campfires.cook_item(pos, elapsed) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local continue = 0 + -- Cycle through slots to cook them. + for i = 1, 4 do + local time_r = meta:get_int("cooktime_"..tostring(i)) + local item = inv:get_stack("main", i) + local food_entity = nil + local food_x = tonumber(meta:get_string("food_x_"..tostring(i))) + local food_y = tonumber(meta:get_string("food_y_"..tostring(i))) + local food_z = tonumber(meta:get_string("food_z_"..tostring(i))) + if food_x and food_y and food_z then + local entites = minetest.get_objects_inside_radius(vector.new(food_x, food_y, food_z), 0) + if entites then + for _, entity in ipairs(entites) do + if entity then + local luaentity = entity:get_luaentity() + if luaentity then + local name = luaentity.name + if name == "mcl_campfires:food_entity" then + food_entity = entity + food_entity:set_properties({wield_item = inv:get_stack("main", i):get_name()}) + end + end + end + end + end + end + if item ~= (ItemStack("") or ItemStack("nil")) then + -- Item hasn't been cooked completely, continue cook timer countdown. + if time_r > 0 then + meta:set_int("cooktime_"..tostring(i), time_r - 1) + -- Item cook timer is up, finish cooking process and drop cooked item. + elseif time_r <= 0 then + local cooked = minetest.get_craft_result({method = "cooking", width = 1, items = {item}}) + if cooked then + if food_entity then + food_entity:remove() -- Remove visual food entity + meta:set_string("food_x_"..tostring(i), nil) + meta:set_string("food_y_"..tostring(i), nil) + meta:set_string("food_z_"..tostring(i), nil) + minetest.add_item(pos, cooked.item) -- Drop Cooked Item + -- Throw some Experience Points because why not? + -- Food is cooked, xp is deserved for using this unique cooking method. Take that Minecraft ;) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + mcl_experience.throw_xp(vector.add(pos, dir), 1) + inv:set_stack("main", i, "") -- Clear Inventory + continue = continue + 1 -- Indicate that the slot is clear. + end + end + end + else + continue = continue + 1 + end + end + -- Not all slots are empty, continue timer. + if continue ~= 4 then + return true + -- Slots are empty, stop node timer. + else + return false + end +end + +local function destroy_particle_spawner (pos) + local meta = minetest.get_meta(pos) + local part_spawn_id = meta:get_int("particle_spawner_id") + if part_spawn_id and part_spawn_id > 0 then + minetest.delete_particlespawner(part_spawn_id) + end +end + + +local function create_smoke_partspawner (pos, constructor) + if not constructor then + destroy_particle_spawner (pos) + end + + local haybale = false + + local node_below = vector.offset(pos, 0, -1, 0) + if minetest.get_node(node_below).name == "mcl_farming:hay_block" then + haybale = true + end + + local smoke_timer + + if haybale then + smoke_timer = 4 + else + smoke_timer = 2.4 + end + + local spawner_id = minetest.add_particlespawner({ + amount = 3, + time = 0, + minpos = vector.add(pos, vector.new(-0.25, 0, -0.25)), + maxpos = vector.add(pos, vector.new( 0.25, 0, 0.25)), + minvel = vector.new(-0.2, 0.5, -0.2), + maxvel = vector.new(0.2, 1, 0.2), + minacc = vector.new(0, 0.5, 0), + maxacc = vector.new(0, 0.5, 0), + minexptime = smoke_timer, + maxexptime = smoke_timer * 2, + minsize = 6, + maxsize = 8, + collisiondetection = true, + vertical = false, + texture = "mcl_campfires_particle_1.png", + texpool = { + "mcl_campfires_particle_1.png"; + { name = "mcl_campfires_particle_1.png", fade = "out" }, + { name = "mcl_campfires_particle_2.png", fade = "out" }, + { name = "mcl_campfires_particle_3.png", fade = "out" }, + { name = "mcl_campfires_particle_4.png", fade = "out" }, + { name = "mcl_campfires_particle_5.png", fade = "out" }, + { name = "mcl_campfires_particle_6.png", fade = "out" }, + { name = "mcl_campfires_particle_7.png", fade = "out" }, + { name = "mcl_campfires_particle_8.png", fade = "out" }, + { name = "mcl_campfires_particle_9.png", fade = "out" }, + { name = "mcl_campfires_particle_10.png", fade = "out" }, + { name = "mcl_campfires_particle_11.png", fade = "out" }, + { name = "mcl_campfires_particle_11.png", fade = "out" }, + { name = "mcl_campfires_particle_12.png", fade = "out" }, + } + }) + + local meta = minetest.get_meta(pos) + meta:set_int("particle_spawner_id", spawner_id) +end + + + function mcl_campfires.register_campfire(name, def) -- Define Campfire minetest.register_node(name, { @@ -15,16 +244,13 @@ function mcl_campfires.register_campfire(name, def) use_texture_alpha = "clip", groups = { handy=1, axey=1, material_wood=1, not_in_creative_inventory=1, campfire=1, }, paramtype = "light", - paramtype2 = "facedir", - on_rightclick = function (pos, node, player, itemstack, pointed_thing) - if player:get_wielded_item():get_name() == "mcl_fire:flint_and_steel" then - node.name = name.."_lit" - minetest.set_node(pos, node) - end + paramtype2 = "4dir", + _on_ignite = function(player, node) + mcl_campfires.light_campfire(node.under) + return true end, - drop = def.drops, - _mcl_silk_touch_drop = {name}, - mcl_sounds.node_sound_wood_defaults(), + drop = "", + sounds = mcl_sounds.node_sound_wood_defaults(), selection_box = { type = 'fixed', fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top @@ -35,6 +261,9 @@ function mcl_campfires.register_campfire(name, def) }, _mcl_blast_resistance = 2, _mcl_hardness = 2, + after_dig_node = function(pos, node, oldmeta, digger) + campfire_drops(pos, digger, def.drops, name.."_lit") + end, }) --Define Lit Campfire @@ -45,38 +274,75 @@ function mcl_campfires.register_campfire(name, def) inventory_image = def.inv_texture, wield_image = def.inv_texture, drawtype = "mesh", - mesh = "mcl_campfires_campfire_lit.obj", - tiles = {{ - name=def.fire_texture, - animation={ - type="vertical_frames", - aspect_w=16, - aspect_h=16, - length=2.0 - }}, - {name=def.lit_logs_texture, - animation={ - type="vertical_frames", - aspect_w=16, - aspect_h=16, - length=2.0 - }} + mesh = "mcl_campfires_campfire.obj", + tiles = { + { + name=def.fire_texture, + animation={ + type="vertical_frames", + aspect_w=32, + aspect_h=16, + length=0.8 + }} + }, + overlay_tiles = { + { + name=def.lit_logs_texture, + animation = { + type = "vertical_frames", + aspect_w = 32, + aspect_h = 16, + length = 2.0, + } + }, }, use_texture_alpha = "clip", - groups = { handy=1, axey=1, material_wood=1, campfire=1, lit_campfire=1 }, + groups = { handy=1, axey=1, material_wood=1, lit_campfire=1 }, paramtype = "light", - paramtype2 = "facedir", + paramtype2 = "4dir", + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 4) + create_smoke_partspawner (pos, true) + end, + on_destruct = function(pos) + destroy_particle_spawner (pos) + end, on_rightclick = function (pos, node, player, itemstack, pointed_thing) - if player:get_wielded_item():get_name():find("shovel") then - node.name = name - minetest.set_node(pos, node) - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if not inv then inv:set_size("main", 4) end + + if minetest.get_item_group(itemstack:get_name(), "shovel") ~= 0 then + local protected = mcl_util.check_position_protection(pos, player) + if not protected then + if not minetest.is_creative_enabled(player:get_player_name()) then + -- Add wear (as if digging a shovely node) + local toolname = itemstack:get_name() + local wear = mcl_autogroup.get_wear(toolname, "shovely") + if wear then + itemstack:add_wear(wear) + tt.reload_itemstack_description(itemstack) -- update tooltip + end + end + node.name = name + minetest.set_node(pos, node) + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + elseif minetest.get_item_group(itemstack:get_name(), "campfire_cookable") ~= 0 then + mcl_campfires.take_item(pos, node, player, itemstack) + else + if not pointed_thing then + return itemstack + end + minetest.item_place_node(itemstack, player, pointed_thing) end end, - drop = def.drops, - _mcl_silk_touch_drop = {name.."_lit"}, + on_timer = mcl_campfires.cook_item, + drop = "", light_source = def.lightlevel, - mcl_sounds.node_sound_wood_defaults(), + sounds = mcl_sounds.node_sound_wood_defaults(), selection_box = { type = "fixed", fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top @@ -87,7 +353,13 @@ function mcl_campfires.register_campfire(name, def) }, _mcl_blast_resistance = 2, _mcl_hardness = 2, - damage_per_second = def.damage, + damage_per_second = def.damage, -- FIXME: Once entity burning is fixed, this needs to be removed. + on_blast = on_blast, + after_dig_node = function(pos, node, oldmeta, digger) + drop_items(pos, node, oldmeta) + campfire_drops(pos, digger, def.drops, name.."_lit") + end, + _mcl_campfires_smothered_form = name, }) end @@ -107,11 +379,25 @@ minetest.register_globalstep(function(dtime) if etime < 0.5 then return end etime = 0 for _,pl in pairs(minetest.get_connected_players()) do + local armor_feet = pl:get_inventory():get_stack("armor", 5) + if pl and pl:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.has_effect(pl, "fire_resistance")) then + return + end burn_in_campfire(pl) end for _,ent in pairs(minetest.luaentities) do if ent.is_mob then - burn_in_campfire(ent.object) + burn_in_campfire(ent.object) -- FIXME: Mobs don't seem to burn properly anymore. end end end) + +minetest.register_lbm({ + label = "Campfire Smoke", + name = "mcl_campfires:campfire_smoke", + nodenames = {"group:lit_campfire"}, + run_at_every_load = true, + action = function(pos, node) + create_smoke_partspawner (pos) + end, +}) diff --git a/mods/ITEMS/mcl_campfires/init.lua b/mods/ITEMS/mcl_campfires/init.lua index 058ba50ed..701fd6095 100644 --- a/mods/ITEMS/mcl_campfires/init.lua +++ b/mods/ITEMS/mcl_campfires/init.lua @@ -1,8 +1,8 @@ -- TO-DO: --- * Add Smoke Particles -- * Add Spark Particles --- * Add Cooking Meat -- * Add Working Sounds +-- * Waterlogging (needs engine change) +-- * Fix the mob damage when mobs go back to burning again local modname = minetest.get_modpath(minetest.get_current_modname()) dofile(modname.."/api.lua") -- Load API File diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ru.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ru.tr new file mode 100644 index 000000000..f63e18d68 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ru.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=Костёр +Soul Campfire=Костёр душ +Cooks food and keeps bees happy.=Готовит еду и выкуривает пчёл +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Костры имеют несколько применений, включая выкуривание пчёл, готовка сырого мяса и рыбы, и как ловушка. \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/mod.conf b/mods/ITEMS/mcl_campfires/mod.conf index 5c4b77dda..cb87a0c93 100644 --- a/mods/ITEMS/mcl_campfires/mod.conf +++ b/mods/ITEMS/mcl_campfires/mod.conf @@ -1,3 +1,3 @@ name = mcl_campfires -depends = mcl_sounds -author = PrairieWind, Gerold55 \ No newline at end of file +depends = mcl_sounds, mcl_util +author = PrairieWind, Gerold55, DinoNuggies4665 \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj index a559fdd4f..30ead4079 100644 --- a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj @@ -1,224 +1,5158 @@ -# Blender v2.78 (sub 0) OBJ File: '' +# Blender 3.5.1 # www.blender.org -mtllib campfire.mtl -o nodebox4 -v 0.500000 -0.312500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v 0.500000 -0.062500 0.250000 -v -0.500000 -0.312500 0.250000 -v -0.500000 -0.312500 0.500000 -v -0.500000 -0.062500 0.500000 -v -0.500000 -0.062500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v -0.500000 -0.062500 0.500000 -v -0.500000 -0.312500 0.500000 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vn -1.0000 0.0000 0.0000 -vn 0.0000 -0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -usemtl none -s 1 -f 1/1/1 2/2/1 3/3/1 4/4/1 -f 5/5/1 6/6/1 7/7/1 8/8/1 -f 1/9/2 4/10/2 8/11/2 5/5/2 -f 1/9/3 2/12/3 6/13/3 5/5/3 -f 4/14/3 3/15/3 7/16/3 8/17/3 -f 9/18/2 10/19/2 11/20/2 12/21/2 -o nodebox4.001 -v 0.500000 -0.312500 -0.498288 -v 0.500000 -0.312500 -0.248288 -v 0.500000 -0.062500 -0.248288 -v 0.500000 -0.062500 -0.498288 -v -0.500000 -0.312500 -0.498288 -v -0.500000 -0.312500 -0.248288 -v -0.500000 -0.062500 -0.248288 -v -0.500000 -0.062500 -0.498288 -v 0.500000 -0.312500 -0.248288 -v 0.500000 -0.062500 -0.248288 -v -0.500000 -0.062500 -0.248288 -v -0.500000 -0.312500 -0.248288 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vn -1.0000 0.0000 0.0000 -vn 0.0000 -0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -usemtl none -s 1 -f 13/22/4 14/23/4 15/24/4 16/25/4 -f 17/26/4 18/27/4 19/28/4 20/29/4 -f 13/30/5 16/31/5 20/32/5 17/26/5 -f 13/30/6 14/33/6 18/34/6 17/26/6 -f 16/35/6 15/36/6 19/37/6 20/38/6 -f 21/39/5 22/40/5 23/41/5 24/42/5 -o nodebox3 -v 0.250000 -0.500000 -0.500000 -v 0.250000 -0.437500 -0.500000 -v -0.250000 -0.437500 -0.500000 -v -0.250000 -0.500000 -0.500000 -v 0.250000 -0.500000 0.500000 -v 0.250000 -0.437500 0.500000 -v -0.250000 -0.437500 0.500000 -v -0.250000 -0.500000 0.500000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 1.0000 0.0000 -vt 1.0000 0.1250 -vt 0.0000 0.1250 -vt 1.0000 0.0000 -vt 1.0000 0.1250 -vt 0.0000 0.1250 -vt 1.0000 0.5000 -vt 0.0000 0.5000 -vt 0.0001 0.0001 -vt 1.0000 0.0000 -vt 1.0000 0.5000 -vt 0.0000 0.5000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -usemtl none_NONE -s 1 -f 25/43/7 29/44/7 30/45/7 26/46/7 -f 28/47/7 32/48/7 31/49/7 27/50/7 -usemtl none -f 25/51/8 26/52/8 27/53/8 28/47/8 -f 29/54/8 30/55/8 31/56/8 32/48/8 -f 25/51/9 29/57/9 32/58/9 28/59/9 -f 26/46/9 30/60/9 31/61/9 27/62/9 -o nodebox4.003 -v -0.248335 -0.500045 0.508619 -v -0.498333 -0.500045 0.509533 -v -0.498334 -0.250045 0.509533 -v -0.248335 -0.250045 0.508619 -v -0.251992 -0.500045 -0.491375 -v -0.501991 -0.500045 -0.490460 -v -0.501991 -0.250045 -0.490460 -v -0.251992 -0.250045 -0.491375 -v -0.498333 -0.500045 0.509533 -v -0.498334 -0.250045 0.509533 -v -0.501991 -0.250045 -0.490460 -v -0.501991 -0.500045 -0.490460 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vn -0.0037 -0.0000 -1.0000 -vn -1.0000 0.0000 0.0037 +mtllib campfire_4.mtl +o campfire_(lit) +v 0.519165 -0.498991 0.454269 +v -0.519165 -0.498991 0.454270 +v 0.519165 -0.498991 0.389374 +v 0.519165 -0.498991 0.324478 +v 0.519165 -0.498991 0.259582 +v 0.519165 -0.498991 0.194687 +v -0.519165 -0.498991 0.194687 +v -0.519165 -0.498991 0.259583 +v -0.519165 -0.498991 0.324478 +v -0.519165 -0.498991 0.389374 +v -0.454270 -0.498991 0.454270 +v -0.389374 -0.498991 0.454270 +v -0.324478 -0.498991 0.454270 +v -0.259583 -0.498991 0.454270 +v -0.194687 -0.498991 0.454270 +v -0.129791 -0.498991 0.454270 +v -0.064896 -0.498991 0.454270 +v 0.000000 -0.498991 0.454270 +v 0.064896 -0.498991 0.454270 +v 0.129791 -0.498991 0.454270 +v 0.194687 -0.498991 0.454269 +v 0.259583 -0.498991 0.454269 +v 0.324478 -0.498991 0.454269 +v 0.389374 -0.498991 0.454269 +v 0.454270 -0.498991 0.454269 +v 0.454270 -0.498991 0.194687 +v 0.454270 -0.498991 0.259582 +v 0.454270 -0.498991 0.324478 +v 0.454270 -0.498991 0.389374 +v 0.389374 -0.498991 0.194687 +v 0.389374 -0.498991 0.259582 +v 0.389374 -0.498991 0.324478 +v 0.389374 -0.498991 0.389374 +v 0.324478 -0.498991 0.194687 +v 0.324478 -0.498991 0.259582 +v 0.324478 -0.498991 0.324478 +v 0.324478 -0.498991 0.389374 +v 0.259583 -0.498991 0.194687 +v 0.259583 -0.498991 0.259582 +v 0.259583 -0.498991 0.324478 +v 0.259583 -0.498991 0.389374 +v 0.194687 -0.498991 0.194687 +v 0.194687 -0.498991 0.259583 +v 0.194687 -0.498991 0.324478 +v 0.194687 -0.498991 0.389374 +v 0.129791 -0.498991 0.194687 +v 0.129791 -0.498991 0.259583 +v 0.129791 -0.498991 0.324478 +v 0.129791 -0.498991 0.389374 +v 0.064896 -0.498991 0.194687 +v 0.064896 -0.498991 0.259583 +v 0.064896 -0.498991 0.324478 +v 0.064896 -0.498991 0.389374 +v -0.000000 -0.498991 0.194687 +v -0.000000 -0.498991 0.259583 +v -0.000000 -0.498991 0.324478 +v 0.000000 -0.498991 0.389374 +v -0.064896 -0.498991 0.194687 +v -0.064896 -0.498991 0.259583 +v -0.064896 -0.498991 0.324478 +v -0.064896 -0.498991 0.389374 +v -0.129791 -0.498991 0.194687 +v -0.129791 -0.498991 0.259583 +v -0.129791 -0.498991 0.324478 +v -0.129791 -0.498991 0.389374 +v -0.194687 -0.498991 0.194687 +v -0.194687 -0.498991 0.259583 +v -0.194687 -0.498991 0.324478 +v -0.194687 -0.498991 0.389374 +v -0.259583 -0.498991 0.194687 +v -0.259583 -0.498991 0.259583 +v -0.259583 -0.498991 0.324478 +v -0.259583 -0.498991 0.389374 +v -0.324478 -0.498991 0.194687 +v -0.324478 -0.498991 0.259583 +v -0.324478 -0.498991 0.324478 +v -0.324478 -0.498991 0.389374 +v -0.389374 -0.498991 0.194687 +v -0.389374 -0.498991 0.259583 +v -0.389374 -0.498991 0.324478 +v -0.389374 -0.498991 0.389374 +v -0.454270 -0.498991 0.194687 +v -0.454270 -0.498991 0.259583 +v -0.454270 -0.498991 0.324478 +v -0.454270 -0.498991 0.389374 +v -0.519165 -0.434095 0.389374 +v -0.519165 -0.434095 0.454270 +v 0.454270 -0.434095 0.454269 +v 0.519165 -0.434095 0.454269 +v 0.519165 -0.434095 0.389374 +v 0.519165 -0.434095 0.324478 +v 0.519165 -0.434095 0.259582 +v 0.519165 -0.434095 0.194687 +v -0.519165 -0.434095 0.194687 +v -0.519165 -0.434095 0.259583 +v -0.519165 -0.434095 0.324478 +v -0.454270 -0.434095 0.454270 +v -0.389374 -0.434095 0.454270 +v -0.324478 -0.434095 0.454270 +v -0.259583 -0.434095 0.454270 +v -0.194687 -0.434095 0.454270 +v -0.129791 -0.434095 0.454270 +v -0.064896 -0.434095 0.454270 +v 0.000000 -0.434095 0.454270 +v 0.064896 -0.434095 0.454270 +v 0.129791 -0.434095 0.454270 +v 0.194687 -0.434095 0.454269 +v 0.259583 -0.434095 0.454269 +v 0.324478 -0.434095 0.454269 +v 0.389374 -0.434095 0.454269 +v 0.454270 -0.434095 0.194687 +v 0.194687 -0.304304 0.194687 +v 0.389374 -0.434095 0.194687 +v 0.259583 -0.304304 0.194687 +v 0.324478 -0.434095 0.194687 +v 0.259583 -0.434095 0.194687 +v 0.324478 -0.304304 0.194687 +v 0.194687 -0.434095 0.194687 +v 0.389374 -0.304304 0.194687 +v 0.129791 -0.434095 0.194687 +v 0.454270 -0.304304 0.194687 +v 0.064896 -0.434095 0.194687 +v 0.389374 -0.304304 0.454269 +v 0.324478 -0.304304 0.454269 +v -0.000000 -0.434095 0.194687 +v 0.259583 -0.304304 0.454269 +v 0.194687 -0.304304 0.454269 +v 0.129791 -0.304304 0.454270 +v -0.064896 -0.434095 0.194687 +v 0.064896 -0.304304 0.454270 +v 0.000000 -0.304304 0.454270 +v -0.064896 -0.304304 0.454270 +v -0.129791 -0.434095 0.194687 +v -0.129791 -0.304304 0.454270 +v -0.194687 -0.304304 0.454270 +v -0.259583 -0.304304 0.454270 +v -0.194687 -0.434095 0.194687 +v -0.324478 -0.304304 0.454270 +v -0.389374 -0.304304 0.454270 +v -0.454270 -0.304304 0.454270 +v -0.259583 -0.434095 0.194687 +v -0.519165 -0.304304 0.324478 +v -0.519165 -0.304304 0.259583 +v -0.519165 -0.304304 0.194687 +v -0.324478 -0.434095 0.194687 +v 0.519165 -0.304304 0.194687 +v 0.519165 -0.304304 0.259582 +v 0.519165 -0.304304 0.324478 +v -0.389374 -0.434095 0.194687 +v 0.519165 -0.304304 0.389374 +v 0.519165 -0.304304 0.454269 +v 0.454270 -0.304304 0.454269 +v -0.454270 -0.434095 0.194687 +v -0.519165 -0.304304 0.454270 +v -0.519165 -0.304304 0.389374 +v -0.519165 -0.369199 0.389374 +v -0.519165 -0.369199 0.454270 +v 0.454270 -0.369199 0.454269 +v 0.519165 -0.369199 0.454269 +v 0.519165 -0.369199 0.389374 +v 0.519165 -0.369199 0.324478 +v 0.519165 -0.369199 0.259582 +v 0.519165 -0.369199 0.194687 +v -0.519165 -0.369199 0.194687 +v -0.519165 -0.369199 0.259583 +v -0.519165 -0.369199 0.324478 +v -0.454270 -0.369199 0.454270 +v -0.389374 -0.369199 0.454270 +v -0.324478 -0.369199 0.454270 +v -0.259583 -0.369199 0.454270 +v -0.194687 -0.369199 0.454270 +v -0.129791 -0.369199 0.454270 +v -0.064896 -0.369199 0.454270 +v 0.000000 -0.369199 0.454270 +v 0.064896 -0.369199 0.454270 +v 0.129791 -0.369199 0.454270 +v 0.194687 -0.369199 0.454269 +v 0.259583 -0.369199 0.454269 +v 0.324478 -0.369199 0.454269 +v 0.389374 -0.369199 0.454269 +v 0.324478 -0.239408 0.454269 +v 0.454270 -0.369199 0.194687 +v 0.324478 -0.239408 0.194687 +v 0.324478 -0.239408 0.259582 +v 0.324478 -0.239408 0.389374 +v 0.389374 -0.369199 0.194687 +v 0.324478 -0.239408 0.324478 +v 0.259583 -0.239408 0.454269 +v 0.259583 -0.239408 0.194687 +v 0.324478 -0.369199 0.194687 +v 0.259583 -0.239408 0.259582 +v 0.259583 -0.239408 0.389374 +v 0.259583 -0.239408 0.324478 +v 0.259583 -0.369199 0.194687 +v 0.194687 -0.239408 0.454269 +v 0.194687 -0.239408 0.194687 +v 0.194687 -0.239408 0.259583 +v 0.194687 -0.369199 0.194687 +v 0.194687 -0.239408 0.389374 +v 0.194687 -0.239408 0.324478 +v 0.129791 -0.239408 0.454270 +v 0.129791 -0.369199 0.194687 +v 0.129791 -0.239408 0.194687 +v 0.129791 -0.239408 0.259583 +v 0.129791 -0.239408 0.389374 +v 0.064896 -0.369199 0.194687 +v 0.129791 -0.239408 0.324478 +v 0.064896 -0.239408 0.454270 +v 0.064896 -0.239408 0.194687 +v -0.000000 -0.369199 0.194687 +v 0.064896 -0.239408 0.259583 +v 0.064896 -0.239408 0.389374 +v 0.064896 -0.239408 0.324478 +v -0.064896 -0.369199 0.194687 +v 0.000000 -0.239408 0.454270 +v -0.000000 -0.239408 0.194687 +v -0.000000 -0.239408 0.259583 +v -0.129791 -0.369199 0.194687 +v 0.000000 -0.239408 0.389374 +v -0.000000 -0.239408 0.324478 +v -0.064896 -0.239408 0.454270 +v -0.194687 -0.369199 0.194687 +v -0.064896 -0.239408 0.194687 +v -0.064896 -0.239408 0.259583 +v -0.064896 -0.239408 0.389374 +v -0.259583 -0.369199 0.194687 +v -0.064896 -0.239408 0.324478 +v -0.129791 -0.239408 0.454270 +v -0.129791 -0.239408 0.194687 +v -0.324478 -0.369199 0.194687 +v -0.129791 -0.239408 0.259583 +v -0.129791 -0.239408 0.389374 +v -0.129791 -0.239408 0.324478 +v -0.389374 -0.369199 0.194687 +v -0.194687 -0.239408 0.454270 +v -0.194687 -0.239408 0.194687 +v -0.194687 -0.239408 0.259583 +v -0.454270 -0.369199 0.194687 +v -0.194687 -0.239408 0.389374 +v -0.194687 -0.239408 0.324478 +v 0.129791 -0.304304 0.194687 +v 0.064896 -0.304304 0.194687 +v -0.000000 -0.304304 0.194687 +v -0.064896 -0.304304 0.194687 +v -0.129791 -0.304304 0.194687 +v -0.194687 -0.304304 0.194687 +v -0.259583 -0.304304 0.194687 +v -0.324478 -0.304304 0.194687 +v -0.389374 -0.304304 0.194687 +v -0.454270 -0.304304 0.194687 +v 0.389374 -0.239408 0.324478 +v 0.389374 -0.239408 0.389374 +v 0.389374 -0.239408 0.259582 +v 0.389374 -0.239408 0.194687 +v 0.389374 -0.239408 0.454269 +v 0.454270 -0.239408 0.324478 +v 0.454270 -0.239408 0.389374 +v 0.454270 -0.239408 0.259582 +v 0.454270 -0.239408 0.194687 +v 0.454270 -0.239408 0.454269 +v -0.259583 -0.239408 0.454270 +v -0.324478 -0.239408 0.454270 +v -0.389374 -0.239408 0.454270 +v -0.454270 -0.239408 0.454270 +v -0.519165 -0.239408 0.454270 +v -0.519165 -0.239408 0.324478 +v -0.519165 -0.239408 0.389374 +v -0.519165 -0.239408 0.259583 +v -0.519165 -0.239408 0.194687 +v 0.519165 -0.239408 0.259582 +v 0.519165 -0.239408 0.194687 +v 0.519165 -0.239408 0.324478 +v 0.519165 -0.239408 0.389374 +v 0.519165 -0.239408 0.454269 +v -0.259583 -0.239408 0.389374 +v -0.259583 -0.239408 0.194687 +v -0.259583 -0.239408 0.259583 +v -0.259583 -0.239408 0.324478 +v -0.324478 -0.239408 0.389374 +v -0.324478 -0.239408 0.194687 +v -0.324478 -0.239408 0.259583 +v -0.324478 -0.239408 0.324478 +v -0.389374 -0.239408 0.389374 +v -0.389374 -0.239408 0.194687 +v -0.389374 -0.239408 0.259583 +v -0.389374 -0.239408 0.324478 +v -0.454270 -0.239408 0.389374 +v -0.454270 -0.239408 0.194687 +v -0.454270 -0.239408 0.259583 +v -0.454270 -0.239408 0.324478 +v 0.324478 -0.434095 0.000000 +v 0.324478 -0.434095 0.064896 +v 0.324478 -0.434095 0.129791 +v 0.324478 -0.434095 0.194687 +v 0.259583 -0.434095 -0.194687 +v 0.259583 -0.434095 -0.129791 +v 0.259583 -0.434095 -0.064896 +v -0.519165 -0.498991 -0.194687 +v -0.519165 -0.498991 -0.129791 +v -0.519165 -0.498991 -0.064896 +v -0.519165 -0.498991 0.000000 +v -0.519165 -0.498991 0.064896 +v -0.519165 -0.498991 0.129791 +v -0.519165 -0.498991 0.194687 +v 0.259583 -0.434095 0.000000 +v 0.259583 -0.434095 0.064896 +v 0.259583 -0.434095 0.129791 +v 0.259583 -0.434095 0.194687 +v 0.194687 -0.434095 -0.194687 +v 0.194687 -0.434095 -0.129791 +v 0.194687 -0.434095 -0.064896 +v 0.194687 -0.434095 0.000000 +v 0.194687 -0.434095 0.064896 +v 0.194687 -0.434095 0.129791 +v 0.194687 -0.434095 0.194687 +v 0.129791 -0.434095 -0.194687 +v 0.129791 -0.434095 -0.129791 +v 0.129791 -0.434095 -0.064896 +v 0.129791 -0.434095 0.000000 +v 0.519165 -0.498991 0.194687 +v 0.519165 -0.498991 0.129791 +v 0.519165 -0.498991 0.064896 +v 0.519165 -0.498991 0.000000 +v 0.519165 -0.498991 -0.064896 +v 0.519165 -0.498991 -0.129791 +v 0.519165 -0.498991 -0.194687 +v 0.129791 -0.434095 0.064896 +v 0.129791 -0.434095 0.129791 +v 0.129791 -0.434095 0.194687 +v 0.064896 -0.434095 -0.194687 +v 0.064896 -0.434095 -0.129791 +v -0.454270 -0.498991 0.194687 +v -0.454270 -0.498991 0.129791 +v -0.454270 -0.498991 0.064896 +v -0.454270 -0.498991 0.000000 +v -0.454270 -0.498991 -0.064896 +v -0.454270 -0.498991 -0.129791 +v -0.454270 -0.498991 -0.194687 +v 0.064896 -0.434095 -0.064896 +v 0.064896 -0.434095 0.000000 +v 0.064896 -0.434095 0.064896 +v 0.064896 -0.434095 0.129791 +v 0.064896 -0.434095 0.194687 +v -0.389374 -0.498991 0.194687 +v -0.389374 -0.498991 0.129791 +v -0.389374 -0.498991 0.064896 +v -0.389374 -0.498991 0.000000 +v -0.389374 -0.498991 -0.064896 +v -0.389374 -0.498991 -0.129791 +v -0.389374 -0.498991 -0.194687 +v -0.000000 -0.434095 -0.194687 +v -0.000000 -0.434095 -0.129791 +v -0.000000 -0.434095 -0.064896 +v -0.000000 -0.434095 0.000000 +v -0.000000 -0.434095 0.064896 +v -0.324478 -0.498991 0.194687 +v -0.324478 -0.498991 0.129791 +v -0.324478 -0.498991 0.064896 +v -0.324478 -0.498991 0.000000 +v -0.324478 -0.498991 -0.064896 +v -0.324478 -0.498991 -0.129791 +v -0.324478 -0.498991 -0.194687 +v -0.000000 -0.434095 0.129791 +v -0.000000 -0.434095 0.194687 +v -0.064896 -0.434095 -0.194687 +v -0.064896 -0.434095 -0.129791 +v -0.064896 -0.434095 -0.064896 +v -0.259583 -0.498991 0.194687 +v -0.259583 -0.498991 0.129791 +v -0.259583 -0.498991 0.064896 +v -0.259583 -0.498991 0.000000 +v -0.259583 -0.498991 -0.064896 +v -0.259583 -0.498991 -0.129791 +v -0.259583 -0.498991 -0.194687 +v -0.064896 -0.434095 0.000000 +v -0.064896 -0.434095 0.064896 +v -0.064896 -0.434095 0.129791 +v -0.064896 -0.434095 0.194687 +v -0.129791 -0.434095 -0.194687 +v -0.194687 -0.498991 0.194687 +v -0.194687 -0.498991 0.129791 +v -0.194687 -0.498991 0.064896 +v -0.194687 -0.498991 0.000000 +v -0.194687 -0.498991 -0.064896 +v -0.194687 -0.498991 -0.129791 +v -0.194687 -0.498991 -0.194687 +v -0.129791 -0.434095 -0.129791 +v -0.129791 -0.434095 -0.064896 +v -0.129791 -0.434095 0.000000 +v -0.129791 -0.434095 0.064896 +v -0.129791 -0.434095 0.129791 +v -0.129791 -0.498991 0.194687 +v -0.129791 -0.498991 0.129791 +v -0.129791 -0.498991 0.064896 +v -0.129791 -0.498991 0.000000 +v -0.129791 -0.498991 -0.064896 +v -0.129791 -0.498991 -0.129791 +v -0.129791 -0.498991 -0.194687 +v -0.129791 -0.434095 0.194687 +v -0.194687 -0.434095 -0.194687 +v -0.194687 -0.434095 -0.129791 +v -0.194687 -0.434095 -0.064896 +v -0.194687 -0.434095 0.000000 +v -0.064896 -0.498991 0.194687 +v -0.064896 -0.498991 0.129791 +v -0.064896 -0.498991 0.064896 +v -0.064896 -0.498991 0.000000 +v -0.064896 -0.498991 -0.064896 +v -0.064896 -0.498991 -0.129791 +v -0.064896 -0.498991 -0.194687 +v -0.194687 -0.434095 0.064896 +v -0.194687 -0.434095 0.129791 +v -0.194687 -0.434095 0.194687 +v -0.259583 -0.434095 -0.194687 +v -0.259583 -0.434095 -0.129791 +v -0.000000 -0.498991 0.194687 +v -0.000000 -0.498991 0.129791 +v -0.000000 -0.498991 0.064896 +v -0.000000 -0.498991 0.000000 +v -0.000000 -0.498991 -0.064896 +v -0.000000 -0.498991 -0.129791 +v -0.000000 -0.498991 -0.194687 +v -0.259583 -0.434095 -0.064896 +v -0.259583 -0.434095 0.000000 +v -0.259583 -0.434095 0.064896 +v -0.259583 -0.434095 0.129791 +v -0.259583 -0.434095 0.194687 +v 0.064896 -0.498991 0.194687 +v 0.064896 -0.498991 0.129791 +v 0.064896 -0.498991 0.064896 +v 0.064896 -0.498991 0.000000 +v 0.064896 -0.498991 -0.064896 +v 0.064896 -0.498991 -0.129791 +v 0.064896 -0.498991 -0.194687 +v -0.324478 -0.434095 -0.194687 +v -0.324478 -0.434095 -0.129791 +v -0.324478 -0.434095 -0.064896 +v -0.324478 -0.434095 0.000000 +v -0.324478 -0.434095 0.064896 +v 0.129791 -0.498991 0.194687 +v 0.129791 -0.498991 0.129791 +v 0.129791 -0.498991 0.064896 +v 0.129791 -0.498991 0.000000 +v 0.129791 -0.498991 -0.064896 +v 0.129791 -0.498991 -0.129791 +v 0.129791 -0.498991 -0.194687 +v -0.324478 -0.434095 0.129791 +v -0.324478 -0.434095 0.194687 +v -0.389374 -0.434095 -0.194687 +v -0.389374 -0.434095 -0.129791 +v -0.389374 -0.434095 -0.064896 +v 0.194687 -0.498991 0.194687 +v 0.194687 -0.498991 0.129791 +v 0.194687 -0.498991 0.064896 +v 0.194687 -0.498991 0.000000 +v 0.194687 -0.498991 -0.064896 +v 0.194687 -0.498991 -0.129791 +v 0.194687 -0.498991 -0.194687 +v -0.389374 -0.434095 0.000000 +v -0.389374 -0.434095 0.064896 +v -0.389374 -0.434095 0.129791 +v -0.389374 -0.434095 0.194687 +v -0.454270 -0.434095 -0.194687 +v 0.259583 -0.498991 0.194687 +v 0.259583 -0.498991 0.129791 +v 0.259583 -0.498991 0.064896 +v 0.259583 -0.498991 0.000000 +v 0.259583 -0.498991 -0.064896 +v 0.259583 -0.498991 -0.129791 +v 0.259583 -0.498991 -0.194687 +v -0.454270 -0.434095 -0.129791 +v -0.454270 -0.434095 -0.064896 +v -0.454270 -0.434095 0.000000 +v -0.454270 -0.434095 0.064896 +v -0.454270 -0.434095 0.129791 +v 0.324478 -0.498991 0.194687 +v 0.324478 -0.498991 0.129791 +v 0.324478 -0.498991 0.064896 +v 0.324478 -0.498991 0.000000 +v 0.324478 -0.498991 -0.064896 +v 0.324478 -0.498991 -0.129791 +v 0.324478 -0.498991 -0.194687 +v -0.454270 -0.434095 0.194687 +v 0.519165 -0.434095 -0.194687 +v 0.519165 -0.434095 -0.129791 +v 0.519165 -0.434095 -0.064896 +v 0.519165 -0.434095 0.000000 +v 0.389374 -0.498991 0.194687 +v 0.389374 -0.498991 0.129791 +v 0.389374 -0.498991 0.064896 +v 0.389374 -0.498991 0.000000 +v 0.389374 -0.498991 -0.064896 +v 0.389374 -0.498991 -0.129791 +v 0.389374 -0.498991 -0.194687 +v 0.519165 -0.434095 0.064896 +v 0.519165 -0.434095 0.129791 +v 0.519165 -0.434095 0.194687 +v -0.519165 -0.434095 0.194687 +v -0.519165 -0.434095 0.129791 +v 0.454270 -0.498991 0.194687 +v 0.454270 -0.498991 0.129791 +v 0.454270 -0.498991 0.064896 +v 0.454270 -0.498991 0.000000 +v 0.454270 -0.498991 -0.064896 +v 0.454270 -0.498991 -0.129791 +v 0.454270 -0.498991 -0.194687 +v -0.519165 -0.434095 0.064896 +v -0.519165 -0.434095 0.000000 +v -0.519165 -0.434095 -0.064896 +v -0.519165 -0.434095 -0.129791 +v -0.519165 -0.434095 -0.194687 +v 0.324478 -0.434095 -0.064896 +v 0.324478 -0.434095 -0.129791 +v 0.324478 -0.434095 -0.194687 +v 0.389374 -0.434095 0.194687 +v 0.389374 -0.434095 0.129791 +v 0.389374 -0.434095 0.064896 +v 0.389374 -0.434095 0.000000 +v 0.389374 -0.434095 -0.064896 +v 0.389374 -0.434095 -0.129791 +v 0.389374 -0.434095 -0.194687 +v 0.454270 -0.434095 0.194687 +v 0.454270 -0.434095 0.129791 +v 0.454270 -0.434095 0.064896 +v 0.454270 -0.434095 0.000000 +v 0.454270 -0.434095 -0.064896 +v 0.454270 -0.434095 -0.129791 +v 0.454270 -0.434095 -0.194687 +v 0.454269 -0.304304 -0.519165 +v 0.454270 -0.304304 0.519165 +v 0.389374 -0.304304 -0.519165 +v 0.324478 -0.304304 -0.519165 +v 0.259582 -0.304304 -0.519165 +v 0.194687 -0.304304 -0.519165 +v 0.194687 -0.304304 0.519165 +v 0.259583 -0.304304 0.519165 +v 0.324478 -0.304304 0.519165 +v 0.389374 -0.304304 0.519165 +v 0.454270 -0.304304 0.454270 +v 0.454270 -0.304304 0.389374 +v 0.454270 -0.304304 0.324478 +v 0.454270 -0.304304 0.259583 +v 0.454270 -0.304304 0.194687 +v 0.454270 -0.304304 0.129791 +v 0.454270 -0.304304 0.064896 +v 0.454270 -0.304304 -0.000000 +v 0.454270 -0.304304 -0.064896 +v 0.454269 -0.304304 -0.129791 +v 0.454269 -0.304304 -0.194687 +v 0.454269 -0.304304 -0.259583 +v 0.454269 -0.304304 -0.324478 +v 0.454269 -0.304304 -0.389374 +v 0.454269 -0.304304 -0.454270 +v 0.194687 -0.304304 -0.454270 +v 0.259582 -0.304304 -0.454270 +v 0.324478 -0.304304 -0.454270 +v 0.389374 -0.304304 -0.454270 +v 0.194687 -0.304304 -0.389374 +v 0.259582 -0.304304 -0.389374 +v 0.324478 -0.304304 -0.389374 +v 0.389374 -0.304304 -0.389374 +v 0.194687 -0.304304 -0.324478 +v 0.259582 -0.304304 -0.324478 +v 0.324478 -0.304304 -0.324478 +v 0.389374 -0.304304 -0.324478 +v 0.194687 -0.304304 -0.259583 +v 0.259582 -0.304304 -0.259583 +v 0.324478 -0.304304 -0.259583 +v 0.389374 -0.304304 -0.259583 +v 0.194687 -0.304304 -0.194687 +v 0.259583 -0.304304 -0.194687 +v 0.324478 -0.304304 -0.194687 +v 0.389374 -0.304304 -0.194687 +v 0.194687 -0.304304 -0.129791 +v 0.259583 -0.304304 -0.129791 +v 0.324478 -0.304304 -0.129791 +v 0.389374 -0.304304 -0.129791 +v 0.194687 -0.304304 -0.064896 +v 0.259583 -0.304304 -0.064896 +v 0.324478 -0.304304 -0.064896 +v 0.389374 -0.304304 -0.064896 +v 0.194687 -0.304304 0.000000 +v 0.259583 -0.304304 0.000000 +v 0.324478 -0.304304 0.000000 +v 0.389374 -0.304304 -0.000000 +v 0.194687 -0.304304 0.064896 +v 0.259583 -0.304304 0.064896 +v 0.324478 -0.304304 0.064896 +v 0.389374 -0.304304 0.064896 +v 0.194687 -0.304304 0.129791 +v 0.259583 -0.304304 0.129791 +v 0.324478 -0.304304 0.129791 +v 0.389374 -0.304304 0.129791 +v 0.194687 -0.304304 0.194687 +v 0.259583 -0.304304 0.194687 +v 0.324478 -0.304304 0.194687 +v 0.389374 -0.304304 0.194687 +v 0.194687 -0.304304 0.259583 +v 0.259583 -0.304304 0.259583 +v 0.324478 -0.304304 0.259583 +v 0.389374 -0.304304 0.259583 +v 0.194687 -0.304304 0.324478 +v 0.259583 -0.304304 0.324478 +v 0.324478 -0.304304 0.324478 +v 0.389374 -0.304304 0.324478 +v 0.194687 -0.304304 0.389374 +v 0.259583 -0.304304 0.389374 +v 0.324478 -0.304304 0.389374 +v 0.389374 -0.304304 0.389374 +v 0.194687 -0.304304 0.454270 +v 0.259583 -0.304304 0.454270 +v 0.324478 -0.304304 0.454270 +v 0.389374 -0.304304 0.454270 +v 0.389374 -0.239408 0.519165 +v 0.454270 -0.239408 0.519165 +v 0.454269 -0.239408 -0.454270 +v 0.454269 -0.239408 -0.519165 +v 0.389374 -0.239408 -0.519165 +v 0.324478 -0.239408 -0.519165 +v 0.259582 -0.239408 -0.519165 +v 0.194687 -0.239408 -0.519165 +v 0.194687 -0.239408 0.519165 +v 0.259583 -0.239408 0.519165 +v 0.324478 -0.239408 0.519165 +v 0.454270 -0.239408 0.454270 +v 0.454270 -0.239408 0.389374 +v 0.454270 -0.239408 0.324478 +v 0.454270 -0.239408 0.259583 +v 0.454270 -0.239408 0.194687 +v 0.454270 -0.239408 0.129791 +v 0.454270 -0.239408 0.064896 +v 0.454270 -0.239408 -0.000000 +v 0.454270 -0.239408 -0.064896 +v 0.454269 -0.239408 -0.129791 +v 0.454269 -0.239408 -0.194687 +v 0.454269 -0.239408 -0.259583 +v 0.454269 -0.239408 -0.324478 +v 0.454269 -0.239408 -0.389374 +v 0.194687 -0.239408 -0.454270 +v 0.194687 -0.109617 -0.194687 +v 0.194687 -0.239408 -0.389374 +v 0.194687 -0.109617 -0.259583 +v 0.194687 -0.239408 -0.324478 +v 0.194687 -0.239408 -0.259583 +v 0.194687 -0.109617 -0.324478 +v 0.194687 -0.239408 -0.194687 +v 0.194687 -0.109617 -0.389374 +v 0.194687 -0.239408 -0.129791 +v 0.194687 -0.109617 -0.454270 +v 0.194687 -0.239408 -0.064896 +v 0.454269 -0.109617 -0.389374 +v 0.454269 -0.109617 -0.324478 +v 0.194687 -0.239408 0.000000 +v 0.454269 -0.109617 -0.259583 +v 0.454269 -0.109617 -0.194687 +v 0.454269 -0.109617 -0.129791 +v 0.194687 -0.239408 0.064896 +v 0.454270 -0.109617 -0.064896 +v 0.454270 -0.109617 -0.000000 +v 0.454270 -0.109617 0.064896 +v 0.194687 -0.239408 0.129791 +v 0.454270 -0.109617 0.129791 +v 0.454270 -0.109617 0.194687 +v 0.454270 -0.109617 0.259583 +v 0.194687 -0.239408 0.194687 +v 0.454270 -0.109617 0.324478 +v 0.454270 -0.109617 0.389374 +v 0.454270 -0.109617 0.454270 +v 0.194687 -0.239408 0.259583 +v 0.324478 -0.109617 0.519165 +v 0.259583 -0.109617 0.519165 +v 0.194687 -0.109617 0.519165 +v 0.194687 -0.239408 0.324478 +v 0.194687 -0.109617 -0.519165 +v 0.259582 -0.109617 -0.519165 +v 0.324478 -0.109617 -0.519165 +v 0.194687 -0.239408 0.389374 +v 0.389374 -0.109617 -0.519165 +v 0.454269 -0.109617 -0.519165 +v 0.454269 -0.109617 -0.454270 +v 0.194687 -0.239408 0.454270 +v 0.454270 -0.109617 0.519165 +v 0.389374 -0.109617 0.519165 +v 0.389374 -0.174512 0.519165 +v 0.454270 -0.174512 0.519165 +v 0.454269 -0.174512 -0.454270 +v 0.454269 -0.174512 -0.519165 +v 0.389374 -0.174512 -0.519165 +v 0.324478 -0.174512 -0.519165 +v 0.259582 -0.174512 -0.519165 +v 0.194687 -0.174512 -0.519165 +v 0.194687 -0.174512 0.519165 +v 0.259583 -0.174512 0.519165 +v 0.324478 -0.174512 0.519165 +v 0.454270 -0.174512 0.454270 +v 0.454270 -0.174512 0.389374 +v 0.454270 -0.174512 0.324478 +v 0.454270 -0.174512 0.259583 +v 0.454270 -0.174512 0.194687 +v 0.454270 -0.174512 0.129791 +v 0.454270 -0.174512 0.064896 +v 0.454270 -0.174512 -0.000000 +v 0.454270 -0.174512 -0.064896 +v 0.454269 -0.174512 -0.129791 +v 0.454269 -0.174512 -0.194687 +v 0.454269 -0.174512 -0.259583 +v 0.454269 -0.174512 -0.324478 +v 0.454269 -0.174512 -0.389374 +v 0.454269 -0.044721 -0.324478 +v 0.194687 -0.174512 -0.454270 +v 0.194687 -0.044721 -0.324478 +v 0.259582 -0.044721 -0.324478 +v 0.389374 -0.044721 -0.324478 +v 0.194687 -0.174512 -0.389374 +v 0.324478 -0.044721 -0.324478 +v 0.454269 -0.044721 -0.259583 +v 0.194687 -0.044721 -0.259583 +v 0.194687 -0.174512 -0.324478 +v 0.259582 -0.044721 -0.259583 +v 0.389374 -0.044721 -0.259583 +v 0.324478 -0.044721 -0.259583 +v 0.194687 -0.174512 -0.259583 +v 0.454269 -0.044721 -0.194687 +v 0.194687 -0.044721 -0.194687 +v 0.259583 -0.044721 -0.194687 +v 0.194687 -0.174512 -0.194687 +v 0.389374 -0.044721 -0.194687 +v 0.324478 -0.044721 -0.194687 +v 0.454269 -0.044721 -0.129791 +v 0.194687 -0.174512 -0.129791 +v 0.194687 -0.044721 -0.129791 +v 0.259583 -0.044721 -0.129791 +v 0.389374 -0.044721 -0.129791 +v 0.194687 -0.174512 -0.064896 +v 0.324478 -0.044721 -0.129791 +v 0.454270 -0.044721 -0.064896 +v 0.194687 -0.044721 -0.064896 +v 0.194687 -0.174512 0.000000 +v 0.259583 -0.044721 -0.064896 +v 0.389374 -0.044721 -0.064896 +v 0.324478 -0.044721 -0.064896 +v 0.194687 -0.174512 0.064896 +v 0.454270 -0.044721 -0.000000 +v 0.194687 -0.044721 0.000000 +v 0.259583 -0.044721 0.000000 +v 0.194687 -0.174512 0.129791 +v 0.389374 -0.044721 -0.000000 +v 0.324478 -0.044721 0.000000 +v 0.454270 -0.044721 0.064896 +v 0.194687 -0.174512 0.194687 +v 0.194687 -0.044721 0.064896 +v 0.259583 -0.044721 0.064896 +v 0.389374 -0.044721 0.064896 +v 0.194687 -0.174512 0.259583 +v 0.324478 -0.044721 0.064896 +v 0.454270 -0.044721 0.129791 +v 0.194687 -0.044721 0.129791 +v 0.194687 -0.174512 0.324478 +v 0.259583 -0.044721 0.129791 +v 0.389374 -0.044721 0.129791 +v 0.324478 -0.044721 0.129791 +v 0.194687 -0.174512 0.389374 +v 0.454270 -0.044721 0.194687 +v 0.194687 -0.044721 0.194687 +v 0.259583 -0.044721 0.194687 +v 0.194687 -0.174512 0.454270 +v 0.389374 -0.044721 0.194687 +v 0.324478 -0.044721 0.194687 +v 0.194687 -0.109617 -0.129791 +v 0.194687 -0.109617 -0.064896 +v 0.194687 -0.109617 0.000000 +v 0.194687 -0.109617 0.064896 +v 0.194687 -0.109617 0.129791 +v 0.194687 -0.109617 0.194687 +v 0.194687 -0.109617 0.259583 +v 0.194687 -0.109617 0.324478 +v 0.194687 -0.109617 0.389374 +v 0.194687 -0.109617 0.454270 +v 0.324478 -0.044721 -0.389374 +v 0.389374 -0.044721 -0.389374 +v 0.259582 -0.044721 -0.389374 +v 0.194687 -0.044721 -0.389374 +v 0.454269 -0.044721 -0.389374 +v 0.324478 -0.044721 -0.454270 +v 0.389374 -0.044721 -0.454270 +v 0.259582 -0.044721 -0.454270 +v 0.194687 -0.044721 -0.454270 +v 0.454269 -0.044721 -0.454270 +v 0.454270 -0.044721 0.259583 +v 0.454270 -0.044721 0.324478 +v 0.454270 -0.044721 0.389374 +v 0.454270 -0.044721 0.454270 +v 0.454270 -0.044721 0.519165 +v 0.324478 -0.044721 0.519165 +v 0.389374 -0.044721 0.519165 +v 0.259583 -0.044721 0.519165 +v 0.194687 -0.044721 0.519165 +v 0.259582 -0.044721 -0.519165 +v 0.194687 -0.044721 -0.519165 +v 0.324478 -0.044721 -0.519165 +v 0.389374 -0.044721 -0.519165 +v 0.454269 -0.044721 -0.519165 +v 0.389374 -0.044721 0.259583 +v 0.194687 -0.044721 0.259583 +v 0.259583 -0.044721 0.259583 +v 0.324478 -0.044721 0.259583 +v 0.389374 -0.044721 0.324478 +v 0.194687 -0.044721 0.324478 +v 0.259583 -0.044721 0.324478 +v 0.324478 -0.044721 0.324478 +v 0.389374 -0.044721 0.389374 +v 0.194687 -0.044721 0.389374 +v 0.259583 -0.044721 0.389374 +v 0.324478 -0.044721 0.389374 +v 0.389374 -0.044721 0.454270 +v 0.194687 -0.044721 0.454270 +v 0.259583 -0.044721 0.454270 +v 0.324478 -0.044721 0.454270 +v 0.519165 -0.498991 -0.194687 +v -0.519165 -0.498991 -0.194687 +v 0.519165 -0.498991 -0.259583 +v 0.519165 -0.498991 -0.324478 +v 0.519165 -0.498991 -0.389374 +v 0.519165 -0.498991 -0.454270 +v -0.519165 -0.498991 -0.454269 +v -0.519165 -0.498991 -0.389374 +v -0.519165 -0.498991 -0.324478 +v -0.519165 -0.498991 -0.259582 +v -0.454270 -0.498991 -0.194687 +v -0.389374 -0.498991 -0.194687 +v -0.324478 -0.498991 -0.194687 +v -0.259583 -0.498991 -0.194687 +v -0.194687 -0.498991 -0.194687 +v -0.129791 -0.498991 -0.194687 +v -0.064896 -0.498991 -0.194687 +v 0.000000 -0.498991 -0.194687 +v 0.064896 -0.498991 -0.194687 +v 0.129791 -0.498991 -0.194687 +v 0.194687 -0.498991 -0.194687 +v 0.259583 -0.498991 -0.194687 +v 0.324478 -0.498991 -0.194687 +v 0.389374 -0.498991 -0.194687 +v 0.454270 -0.498991 -0.194687 +v 0.454270 -0.498991 -0.454270 +v 0.454270 -0.498991 -0.389374 +v 0.454270 -0.498991 -0.324478 +v 0.454270 -0.498991 -0.259583 +v 0.389374 -0.498991 -0.454270 +v 0.389374 -0.498991 -0.389374 +v 0.389374 -0.498991 -0.324478 +v 0.389374 -0.498991 -0.259583 +v 0.324478 -0.498991 -0.454270 +v 0.324478 -0.498991 -0.389374 +v 0.324478 -0.498991 -0.324478 +v 0.324478 -0.498991 -0.259583 +v 0.259583 -0.498991 -0.454270 +v 0.259583 -0.498991 -0.389374 +v 0.259583 -0.498991 -0.324478 +v 0.259583 -0.498991 -0.259583 +v 0.194687 -0.498991 -0.454270 +v 0.194687 -0.498991 -0.389374 +v 0.194687 -0.498991 -0.324478 +v 0.194687 -0.498991 -0.259583 +v 0.129791 -0.498991 -0.454270 +v 0.129791 -0.498991 -0.389374 +v 0.129791 -0.498991 -0.324478 +v 0.129791 -0.498991 -0.259583 +v 0.064896 -0.498991 -0.454270 +v 0.064896 -0.498991 -0.389374 +v 0.064896 -0.498991 -0.324478 +v 0.064896 -0.498991 -0.259583 +v -0.000000 -0.498991 -0.454270 +v -0.000000 -0.498991 -0.389374 +v -0.000000 -0.498991 -0.324478 +v 0.000000 -0.498991 -0.259583 +v -0.064896 -0.498991 -0.454270 +v -0.064896 -0.498991 -0.389374 +v -0.064896 -0.498991 -0.324478 +v -0.064896 -0.498991 -0.259583 +v -0.129791 -0.498991 -0.454269 +v -0.129791 -0.498991 -0.389374 +v -0.129791 -0.498991 -0.324478 +v -0.129791 -0.498991 -0.259583 +v -0.194687 -0.498991 -0.454269 +v -0.194687 -0.498991 -0.389374 +v -0.194687 -0.498991 -0.324478 +v -0.194687 -0.498991 -0.259583 +v -0.259583 -0.498991 -0.454269 +v -0.259583 -0.498991 -0.389374 +v -0.259583 -0.498991 -0.324478 +v -0.259583 -0.498991 -0.259583 +v -0.324478 -0.498991 -0.454269 +v -0.324478 -0.498991 -0.389374 +v -0.324478 -0.498991 -0.324478 +v -0.324478 -0.498991 -0.259582 +v -0.389374 -0.498991 -0.454269 +v -0.389374 -0.498991 -0.389374 +v -0.389374 -0.498991 -0.324478 +v -0.389374 -0.498991 -0.259582 +v -0.454270 -0.498991 -0.454269 +v -0.454270 -0.498991 -0.389374 +v -0.454270 -0.498991 -0.324478 +v -0.454270 -0.498991 -0.259582 +v -0.519165 -0.434095 -0.259582 +v -0.519165 -0.434095 -0.194687 +v 0.454270 -0.434095 -0.194687 +v 0.519165 -0.434095 -0.194687 +v 0.519165 -0.434095 -0.259583 +v 0.519165 -0.434095 -0.324478 +v 0.519165 -0.434095 -0.389374 +v 0.519165 -0.434095 -0.454270 +v -0.519165 -0.434095 -0.454269 +v -0.519165 -0.434095 -0.389374 +v -0.519165 -0.434095 -0.324478 +v -0.454270 -0.434095 -0.194687 +v -0.389374 -0.434095 -0.194687 +v -0.324478 -0.434095 -0.194687 +v -0.259583 -0.434095 -0.194687 +v -0.194687 -0.434095 -0.194687 +v -0.129791 -0.434095 -0.194687 +v -0.064896 -0.434095 -0.194687 +v 0.000000 -0.434095 -0.194687 +v 0.064896 -0.434095 -0.194687 +v 0.129791 -0.434095 -0.194687 +v 0.194687 -0.434095 -0.194687 +v 0.259583 -0.434095 -0.194687 +v 0.324478 -0.434095 -0.194687 +v 0.389374 -0.434095 -0.194687 +v 0.454270 -0.434095 -0.454270 +v 0.194687 -0.304304 -0.454270 +v 0.389374 -0.434095 -0.454270 +v 0.259583 -0.304304 -0.454270 +v 0.324478 -0.434095 -0.454270 +v 0.259583 -0.434095 -0.454270 +v 0.324478 -0.304304 -0.454270 +v 0.194687 -0.434095 -0.454270 +v 0.389374 -0.304304 -0.454270 +v 0.129791 -0.434095 -0.454270 +v 0.454270 -0.304304 -0.454270 +v 0.064896 -0.434095 -0.454270 +v 0.389374 -0.304304 -0.194687 +v 0.324478 -0.304304 -0.194687 +v -0.000000 -0.434095 -0.454270 +v 0.259583 -0.304304 -0.194687 +v 0.194687 -0.304304 -0.194687 +v 0.129791 -0.304304 -0.194687 +v -0.064896 -0.434095 -0.454270 +v 0.064896 -0.304304 -0.194687 +v 0.000000 -0.304304 -0.194687 +v -0.064896 -0.304304 -0.194687 +v -0.129791 -0.434095 -0.454269 +v -0.129791 -0.304304 -0.194687 +v -0.194687 -0.304304 -0.194687 +v -0.259583 -0.304304 -0.194687 +v -0.194687 -0.434095 -0.454269 +v -0.324478 -0.304304 -0.194687 +v -0.389374 -0.304304 -0.194687 +v -0.454270 -0.304304 -0.194687 +v -0.259583 -0.434095 -0.454269 +v -0.519165 -0.304304 -0.324478 +v -0.519165 -0.304304 -0.389374 +v -0.519165 -0.304304 -0.454269 +v -0.324478 -0.434095 -0.454269 +v 0.519165 -0.304304 -0.454270 +v 0.519165 -0.304304 -0.389374 +v 0.519165 -0.304304 -0.324478 +v -0.389374 -0.434095 -0.454269 +v 0.519165 -0.304304 -0.259583 +v 0.519165 -0.304304 -0.194687 +v 0.454270 -0.304304 -0.194687 +v -0.454270 -0.434095 -0.454269 +v -0.519165 -0.304304 -0.194687 +v -0.519165 -0.304304 -0.259582 +v -0.519165 -0.369199 -0.259582 +v -0.519165 -0.369199 -0.194687 +v 0.454270 -0.369199 -0.194687 +v 0.519165 -0.369199 -0.194687 +v 0.519165 -0.369199 -0.259583 +v 0.519165 -0.369199 -0.324478 +v 0.519165 -0.369199 -0.389374 +v 0.519165 -0.369199 -0.454270 +v -0.519165 -0.369199 -0.454269 +v -0.519165 -0.369199 -0.389374 +v -0.519165 -0.369199 -0.324478 +v -0.454270 -0.369199 -0.194687 +v -0.389374 -0.369199 -0.194687 +v -0.324478 -0.369199 -0.194687 +v -0.259583 -0.369199 -0.194687 +v -0.194687 -0.369199 -0.194687 +v -0.129791 -0.369199 -0.194687 +v -0.064896 -0.369199 -0.194687 +v 0.000000 -0.369199 -0.194687 +v 0.064896 -0.369199 -0.194687 +v 0.129791 -0.369199 -0.194687 +v 0.194687 -0.369199 -0.194687 +v 0.259583 -0.369199 -0.194687 +v 0.324478 -0.369199 -0.194687 +v 0.389374 -0.369199 -0.194687 +v 0.324478 -0.239408 -0.194687 +v 0.454270 -0.369199 -0.454270 +v 0.324478 -0.239408 -0.454270 +v 0.324478 -0.239408 -0.389374 +v 0.324478 -0.239408 -0.259583 +v 0.389374 -0.369199 -0.454270 +v 0.324478 -0.239408 -0.324478 +v 0.259583 -0.239408 -0.194687 +v 0.259583 -0.239408 -0.454270 +v 0.324478 -0.369199 -0.454270 +v 0.259583 -0.239408 -0.389374 +v 0.259583 -0.239408 -0.259583 +v 0.259583 -0.239408 -0.324478 +v 0.259583 -0.369199 -0.454270 +v 0.194687 -0.239408 -0.194687 +v 0.194687 -0.239408 -0.454270 +v 0.194687 -0.239408 -0.389374 +v 0.194687 -0.369199 -0.454270 +v 0.194687 -0.239408 -0.259583 +v 0.194687 -0.239408 -0.324478 +v 0.129791 -0.239408 -0.194687 +v 0.129791 -0.369199 -0.454270 +v 0.129791 -0.239408 -0.454270 +v 0.129791 -0.239408 -0.389374 +v 0.129791 -0.239408 -0.259583 +v 0.064896 -0.369199 -0.454270 +v 0.129791 -0.239408 -0.324478 +v 0.064896 -0.239408 -0.194687 +v 0.064896 -0.239408 -0.454270 +v -0.000000 -0.369199 -0.454270 +v 0.064896 -0.239408 -0.389374 +v 0.064896 -0.239408 -0.259583 +v 0.064896 -0.239408 -0.324478 +v -0.064896 -0.369199 -0.454270 +v 0.000000 -0.239408 -0.194687 +v -0.000000 -0.239408 -0.454270 +v -0.000000 -0.239408 -0.389374 +v -0.129791 -0.369199 -0.454269 +v 0.000000 -0.239408 -0.259583 +v -0.000000 -0.239408 -0.324478 +v -0.064896 -0.239408 -0.194687 +v -0.194687 -0.369199 -0.454269 +v -0.064896 -0.239408 -0.454270 +v -0.064896 -0.239408 -0.389374 +v -0.064896 -0.239408 -0.259583 +v -0.259583 -0.369199 -0.454269 +v -0.064896 -0.239408 -0.324478 +v -0.129791 -0.239408 -0.194687 +v -0.129791 -0.239408 -0.454269 +v -0.324478 -0.369199 -0.454269 +v -0.129791 -0.239408 -0.389374 +v -0.129791 -0.239408 -0.259583 +v -0.129791 -0.239408 -0.324478 +v -0.389374 -0.369199 -0.454269 +v -0.194687 -0.239408 -0.194687 +v -0.194687 -0.239408 -0.454269 +v -0.194687 -0.239408 -0.389374 +v -0.454270 -0.369199 -0.454269 +v -0.194687 -0.239408 -0.259583 +v -0.194687 -0.239408 -0.324478 +v 0.129791 -0.304304 -0.454270 +v 0.064896 -0.304304 -0.454270 +v -0.000000 -0.304304 -0.454270 +v -0.064896 -0.304304 -0.454270 +v -0.129791 -0.304304 -0.454269 +v -0.194687 -0.304304 -0.454269 +v -0.259583 -0.304304 -0.454269 +v -0.324478 -0.304304 -0.454269 +v -0.389374 -0.304304 -0.454269 +v -0.454270 -0.304304 -0.454269 +v 0.389374 -0.239408 -0.324478 +v 0.389374 -0.239408 -0.259583 +v 0.389374 -0.239408 -0.389374 +v 0.389374 -0.239408 -0.454270 +v 0.389374 -0.239408 -0.194687 +v 0.454270 -0.239408 -0.324478 +v 0.454270 -0.239408 -0.259583 +v 0.454270 -0.239408 -0.389374 +v 0.454270 -0.239408 -0.454270 +v 0.454270 -0.239408 -0.194687 +v -0.259583 -0.239408 -0.194687 +v -0.324478 -0.239408 -0.194687 +v -0.389374 -0.239408 -0.194687 +v -0.454270 -0.239408 -0.194687 +v -0.519165 -0.239408 -0.194687 +v -0.519165 -0.239408 -0.324478 +v -0.519165 -0.239408 -0.259582 +v -0.519165 -0.239408 -0.389374 +v -0.519165 -0.239408 -0.454269 +v 0.519165 -0.239408 -0.389374 +v 0.519165 -0.239408 -0.454270 +v 0.519165 -0.239408 -0.324478 +v 0.519165 -0.239408 -0.259583 +v 0.519165 -0.239408 -0.194687 +v -0.259583 -0.239408 -0.259583 +v -0.259583 -0.239408 -0.454269 +v -0.259583 -0.239408 -0.389374 +v -0.259583 -0.239408 -0.324478 +v -0.324478 -0.239408 -0.259582 +v -0.324478 -0.239408 -0.454269 +v -0.324478 -0.239408 -0.389374 +v -0.324478 -0.239408 -0.324478 +v -0.389374 -0.239408 -0.259582 +v -0.389374 -0.239408 -0.454269 +v -0.389374 -0.239408 -0.389374 +v -0.389374 -0.239408 -0.324478 +v -0.454270 -0.239408 -0.259582 +v -0.454270 -0.239408 -0.454269 +v -0.454270 -0.239408 -0.389374 +v -0.454270 -0.239408 -0.324478 +v -0.194687 -0.304304 -0.519165 +v -0.194687 -0.304304 0.519165 +v -0.259583 -0.304304 -0.519165 +v -0.324478 -0.304304 -0.519165 +v -0.389374 -0.304304 -0.519165 +v -0.454270 -0.304304 -0.519165 +v -0.454269 -0.304304 0.519165 +v -0.389374 -0.304304 0.519165 +v -0.324478 -0.304304 0.519165 +v -0.259582 -0.304304 0.519165 +v -0.194687 -0.304304 0.454270 +v -0.194687 -0.304304 0.389374 +v -0.194687 -0.304304 0.324478 +v -0.194687 -0.304304 0.259583 +v -0.194687 -0.304304 0.194687 +v -0.194687 -0.304304 0.129791 +v -0.194687 -0.304304 0.064896 +v -0.194687 -0.304304 -0.000000 +v -0.194687 -0.304304 -0.064896 +v -0.194687 -0.304304 -0.129791 +v -0.194687 -0.304304 -0.194687 +v -0.194687 -0.304304 -0.259583 +v -0.194687 -0.304304 -0.324478 +v -0.194687 -0.304304 -0.389374 +v -0.194687 -0.304304 -0.454270 +v -0.454270 -0.304304 -0.454270 +v -0.389374 -0.304304 -0.454270 +v -0.324478 -0.304304 -0.454270 +v -0.259583 -0.304304 -0.454270 +v -0.454270 -0.304304 -0.389374 +v -0.389374 -0.304304 -0.389374 +v -0.324478 -0.304304 -0.389374 +v -0.259583 -0.304304 -0.389374 +v -0.454270 -0.304304 -0.324478 +v -0.389374 -0.304304 -0.324478 +v -0.324478 -0.304304 -0.324478 +v -0.259583 -0.304304 -0.324478 +v -0.454270 -0.304304 -0.259583 +v -0.389374 -0.304304 -0.259583 +v -0.324478 -0.304304 -0.259583 +v -0.259583 -0.304304 -0.259583 +v -0.454270 -0.304304 -0.194687 +v -0.389374 -0.304304 -0.194687 +v -0.324478 -0.304304 -0.194687 +v -0.259583 -0.304304 -0.194687 +v -0.454270 -0.304304 -0.129791 +v -0.389374 -0.304304 -0.129791 +v -0.324478 -0.304304 -0.129791 +v -0.259583 -0.304304 -0.129791 +v -0.454270 -0.304304 -0.064896 +v -0.389374 -0.304304 -0.064896 +v -0.324478 -0.304304 -0.064896 +v -0.259583 -0.304304 -0.064896 +v -0.454270 -0.304304 0.000000 +v -0.389374 -0.304304 0.000000 +v -0.324478 -0.304304 0.000000 +v -0.259583 -0.304304 -0.000000 +v -0.454270 -0.304304 0.064896 +v -0.389374 -0.304304 0.064896 +v -0.324478 -0.304304 0.064896 +v -0.259583 -0.304304 0.064896 +v -0.454269 -0.304304 0.129791 +v -0.389374 -0.304304 0.129791 +v -0.324478 -0.304304 0.129791 +v -0.259583 -0.304304 0.129791 +v -0.454269 -0.304304 0.194687 +v -0.389374 -0.304304 0.194687 +v -0.324478 -0.304304 0.194687 +v -0.259583 -0.304304 0.194687 +v -0.454269 -0.304304 0.259583 +v -0.389374 -0.304304 0.259583 +v -0.324478 -0.304304 0.259583 +v -0.259582 -0.304304 0.259583 +v -0.454269 -0.304304 0.324478 +v -0.389374 -0.304304 0.324478 +v -0.324478 -0.304304 0.324478 +v -0.259582 -0.304304 0.324478 +v -0.454269 -0.304304 0.389374 +v -0.389374 -0.304304 0.389374 +v -0.324478 -0.304304 0.389374 +v -0.259582 -0.304304 0.389374 +v -0.454269 -0.304304 0.454270 +v -0.389374 -0.304304 0.454270 +v -0.324478 -0.304304 0.454270 +v -0.259582 -0.304304 0.454270 +v -0.259582 -0.239408 0.519165 +v -0.194687 -0.239408 0.519165 +v -0.194687 -0.239408 -0.454270 +v -0.194687 -0.239408 -0.519165 +v -0.259583 -0.239408 -0.519165 +v -0.324478 -0.239408 -0.519165 +v -0.389374 -0.239408 -0.519165 +v -0.454270 -0.239408 -0.519165 +v -0.454269 -0.239408 0.519165 +v -0.389374 -0.239408 0.519165 +v -0.324478 -0.239408 0.519165 +v -0.194687 -0.239408 0.454270 +v -0.194687 -0.239408 0.389374 +v -0.194687 -0.239408 0.324478 +v -0.194687 -0.239408 0.259583 +v -0.194687 -0.239408 0.194687 +v -0.194687 -0.239408 0.129791 +v -0.194687 -0.239408 0.064896 +v -0.194687 -0.239408 -0.000000 +v -0.194687 -0.239408 -0.064896 +v -0.194687 -0.239408 -0.129791 +v -0.194687 -0.239408 -0.194687 +v -0.194687 -0.239408 -0.259583 +v -0.194687 -0.239408 -0.324478 +v -0.194687 -0.239408 -0.389374 +v -0.454270 -0.239408 -0.454270 +v -0.454270 -0.109617 -0.194687 +v -0.454270 -0.239408 -0.389374 +v -0.454270 -0.109617 -0.259583 +v -0.454270 -0.239408 -0.324478 +v -0.454270 -0.239408 -0.259583 +v -0.454270 -0.109617 -0.324478 +v -0.454270 -0.239408 -0.194687 +v -0.454270 -0.109617 -0.389374 +v -0.454270 -0.239408 -0.129791 +v -0.454270 -0.109617 -0.454270 +v -0.454270 -0.239408 -0.064896 +v -0.194687 -0.109617 -0.389374 +v -0.194687 -0.109617 -0.324478 +v -0.454270 -0.239408 0.000000 +v -0.194687 -0.109617 -0.259583 +v -0.194687 -0.109617 -0.194687 +v -0.194687 -0.109617 -0.129791 +v -0.454270 -0.239408 0.064896 +v -0.194687 -0.109617 -0.064896 +v -0.194687 -0.109617 -0.000000 +v -0.194687 -0.109617 0.064896 +v -0.454269 -0.239408 0.129791 +v -0.194687 -0.109617 0.129791 +v -0.194687 -0.109617 0.194687 +v -0.194687 -0.109617 0.259583 +v -0.454269 -0.239408 0.194687 +v -0.194687 -0.109617 0.324478 +v -0.194687 -0.109617 0.389374 +v -0.194687 -0.109617 0.454270 +v -0.454269 -0.239408 0.259583 +v -0.324478 -0.109617 0.519165 +v -0.389374 -0.109617 0.519165 +v -0.454269 -0.109617 0.519165 +v -0.454269 -0.239408 0.324478 +v -0.454270 -0.109617 -0.519165 +v -0.389374 -0.109617 -0.519165 +v -0.324478 -0.109617 -0.519165 +v -0.454269 -0.239408 0.389374 +v -0.259583 -0.109617 -0.519165 +v -0.194687 -0.109617 -0.519165 +v -0.194687 -0.109617 -0.454270 +v -0.454269 -0.239408 0.454270 +v -0.194687 -0.109617 0.519165 +v -0.259582 -0.109617 0.519165 +v -0.259582 -0.174512 0.519165 +v -0.194687 -0.174512 0.519165 +v -0.194687 -0.174512 -0.454270 +v -0.194687 -0.174512 -0.519165 +v -0.259583 -0.174512 -0.519165 +v -0.324478 -0.174512 -0.519165 +v -0.389374 -0.174512 -0.519165 +v -0.454270 -0.174512 -0.519165 +v -0.454269 -0.174512 0.519165 +v -0.389374 -0.174512 0.519165 +v -0.324478 -0.174512 0.519165 +v -0.194687 -0.174512 0.454270 +v -0.194687 -0.174512 0.389374 +v -0.194687 -0.174512 0.324478 +v -0.194687 -0.174512 0.259583 +v -0.194687 -0.174512 0.194687 +v -0.194687 -0.174512 0.129791 +v -0.194687 -0.174512 0.064896 +v -0.194687 -0.174512 -0.000000 +v -0.194687 -0.174512 -0.064896 +v -0.194687 -0.174512 -0.129791 +v -0.194687 -0.174512 -0.194687 +v -0.194687 -0.174512 -0.259583 +v -0.194687 -0.174512 -0.324478 +v -0.194687 -0.174512 -0.389374 +v -0.194687 -0.044721 -0.324478 +v -0.454270 -0.174512 -0.454270 +v -0.454270 -0.044721 -0.324478 +v -0.389374 -0.044721 -0.324478 +v -0.259583 -0.044721 -0.324478 +v -0.454270 -0.174512 -0.389374 +v -0.324478 -0.044721 -0.324478 +v -0.194687 -0.044721 -0.259583 +v -0.454270 -0.044721 -0.259583 +v -0.454270 -0.174512 -0.324478 +v -0.389374 -0.044721 -0.259583 +v -0.259583 -0.044721 -0.259583 +v -0.324478 -0.044721 -0.259583 +v -0.454270 -0.174512 -0.259583 +v -0.194687 -0.044721 -0.194687 +v -0.454270 -0.044721 -0.194687 +v -0.389374 -0.044721 -0.194687 +v -0.454270 -0.174512 -0.194687 +v -0.259583 -0.044721 -0.194687 +v -0.324478 -0.044721 -0.194687 +v -0.194687 -0.044721 -0.129791 +v -0.454270 -0.174512 -0.129791 +v -0.454270 -0.044721 -0.129791 +v -0.389374 -0.044721 -0.129791 +v -0.259583 -0.044721 -0.129791 +v -0.454270 -0.174512 -0.064896 +v -0.324478 -0.044721 -0.129791 +v -0.194687 -0.044721 -0.064896 +v -0.454270 -0.044721 -0.064896 +v -0.454270 -0.174512 0.000000 +v -0.389374 -0.044721 -0.064896 +v -0.259583 -0.044721 -0.064896 +v -0.324478 -0.044721 -0.064896 +v -0.454270 -0.174512 0.064896 +v -0.194687 -0.044721 -0.000000 +v -0.454270 -0.044721 0.000000 +v -0.389374 -0.044721 0.000000 +v -0.454269 -0.174512 0.129791 +v -0.259583 -0.044721 -0.000000 +v -0.324478 -0.044721 0.000000 +v -0.194687 -0.044721 0.064896 +v -0.454269 -0.174512 0.194687 +v -0.454270 -0.044721 0.064896 +v -0.389374 -0.044721 0.064896 +v -0.259583 -0.044721 0.064896 +v -0.454269 -0.174512 0.259583 +v -0.324478 -0.044721 0.064896 +v -0.194687 -0.044721 0.129791 +v -0.454269 -0.044721 0.129791 +v -0.454269 -0.174512 0.324478 +v -0.389374 -0.044721 0.129791 +v -0.259583 -0.044721 0.129791 +v -0.324478 -0.044721 0.129791 +v -0.454269 -0.174512 0.389374 +v -0.194687 -0.044721 0.194687 +v -0.454269 -0.044721 0.194687 +v -0.389374 -0.044721 0.194687 +v -0.454269 -0.174512 0.454270 +v -0.259583 -0.044721 0.194687 +v -0.324478 -0.044721 0.194687 +v -0.454270 -0.109617 -0.129791 +v -0.454270 -0.109617 -0.064896 +v -0.454270 -0.109617 0.000000 +v -0.454270 -0.109617 0.064896 +v -0.454269 -0.109617 0.129791 +v -0.454269 -0.109617 0.194687 +v -0.454269 -0.109617 0.259583 +v -0.454269 -0.109617 0.324478 +v -0.454269 -0.109617 0.389374 +v -0.454269 -0.109617 0.454270 +v -0.324478 -0.044721 -0.389374 +v -0.259583 -0.044721 -0.389374 +v -0.389374 -0.044721 -0.389374 +v -0.454270 -0.044721 -0.389374 +v -0.194687 -0.044721 -0.389374 +v -0.324478 -0.044721 -0.454270 +v -0.259583 -0.044721 -0.454270 +v -0.389374 -0.044721 -0.454270 +v -0.454270 -0.044721 -0.454270 +v -0.194687 -0.044721 -0.454270 +v -0.194687 -0.044721 0.259583 +v -0.194687 -0.044721 0.324478 +v -0.194687 -0.044721 0.389374 +v -0.194687 -0.044721 0.454270 +v -0.194687 -0.044721 0.519165 +v -0.324478 -0.044721 0.519165 +v -0.259582 -0.044721 0.519165 +v -0.389374 -0.044721 0.519165 +v -0.454269 -0.044721 0.519165 +v -0.389374 -0.044721 -0.519165 +v -0.454270 -0.044721 -0.519165 +v -0.324478 -0.044721 -0.519165 +v -0.259583 -0.044721 -0.519165 +v -0.194687 -0.044721 -0.519165 +v -0.259582 -0.044721 0.259583 +v -0.454269 -0.044721 0.259583 +v -0.389374 -0.044721 0.259583 +v -0.324478 -0.044721 0.259583 +v -0.259582 -0.044721 0.324478 +v -0.454269 -0.044721 0.324478 +v -0.389374 -0.044721 0.324478 +v -0.324478 -0.044721 0.324478 +v -0.259582 -0.044721 0.389374 +v -0.454269 -0.044721 0.389374 +v -0.389374 -0.044721 0.389374 +v -0.324478 -0.044721 0.389374 +v -0.259582 -0.044721 0.454270 +v -0.454269 -0.044721 0.454270 +v -0.389374 -0.044721 0.454270 +v -0.324478 -0.044721 0.454270 vn -0.0000 -1.0000 -0.0000 -usemtl none -s 1 -f 33/63/10 34/64/10 35/65/10 36/66/10 -f 37/67/10 38/68/10 39/69/10 40/70/10 -f 33/71/11 36/72/11 40/73/11 37/67/11 -f 33/71/12 34/74/12 38/75/12 37/67/12 -f 36/76/12 35/77/12 39/78/12 40/79/12 -f 41/80/11 42/81/11 43/82/11 44/83/11 -o nodebox4.002 -v 0.499948 -0.500045 0.505882 -v 0.249950 -0.500045 0.506796 -v 0.249950 -0.250045 0.506796 -v 0.499948 -0.250045 0.505882 -v 0.496291 -0.500045 -0.494111 -v 0.246293 -0.500045 -0.493197 -v 0.246293 -0.250045 -0.493197 -v 0.496291 -0.250045 -0.494111 -v 0.249950 -0.500045 0.506796 -v 0.249950 -0.250045 0.506796 -v 0.246293 -0.250045 -0.493197 -v 0.246293 -0.500045 -0.493197 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vn -0.0037 0.0000 -1.0000 -vn -1.0000 -0.0000 0.0037 -vn -0.0000 -1.0000 -0.0000 -usemtl none -s 1 -f 45/84/13 46/85/13 47/86/13 48/87/13 -f 49/88/13 50/89/13 51/90/13 52/91/13 -f 45/92/14 48/93/14 52/94/14 49/88/14 -f 45/92/15 46/95/15 50/96/15 49/88/15 -f 48/97/15 47/98/15 51/99/15 52/100/15 -f 53/101/14 54/102/14 55/103/14 56/104/14 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -0.0000 -1.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vt 0.000050 0.999900 +vt 0.000025 0.812526 +vt 0.000000 0.500000 +vt 0.499950 0.999900 +vt 0.499975 0.812525 +vt 0.125000 0.500000 +vt 0.000050 0.937413 +vt 0.031250 0.500000 +vt 0.000050 0.874925 +vt 0.062500 0.500000 +vt 0.000050 0.812438 +vt 0.093750 0.500000 +vt 0.000050 0.749950 +vt 0.499978 1.000027 +vt 0.125000 0.500000 +vt 0.499950 0.749950 +vt 0.000022 1.000027 +vt 0.000000 0.500000 +vt 0.499950 0.812438 +vt 0.031250 0.500000 +vt 0.499950 0.874925 +vt 0.062500 0.500000 +vt 0.499950 0.937413 +vt 0.093750 0.500000 +vt 0.468706 0.999900 +vt 0.468728 0.812525 +vt 0.437463 0.999900 +vt 0.437481 0.812525 +vt 0.406219 0.999900 +vt 0.406234 0.812525 +vt 0.374975 0.999900 +vt 0.374988 0.812525 +vt 0.343731 0.999900 +vt 0.343741 0.812525 +vt 0.312488 0.999900 +vt 0.312494 0.812525 +vt 0.281244 0.999900 +vt 0.281247 0.812525 +vt 0.250000 0.999900 +vt 0.250000 0.812525 +vt 0.218756 0.999900 +vt 0.218753 0.812525 +vt 0.187513 0.999900 +vt 0.187506 0.812526 +vt 0.156269 0.999900 +vt 0.156259 0.812526 +vt 0.125025 0.999900 +vt 0.125013 0.812526 +vt 0.093781 0.999900 +vt 0.093766 0.812526 +vt 0.062537 0.999900 +vt 0.062519 0.812526 +vt 0.031294 0.999900 +vt 0.031272 0.812526 +vt 0.031294 0.749950 +vt 0.468731 1.000027 +vt 0.031294 0.812438 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.062538 0.749950 +vt 0.062500 0.921875 +vt 0.437484 1.000027 +vt 0.062538 0.812438 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.093781 0.749950 +vt 0.093750 0.921875 +vt 0.093781 0.812438 +vt 0.093781 0.874925 +vt 0.093781 0.937413 +vt 0.125025 0.749950 +vt 0.125000 0.921875 +vt 0.125025 0.812438 +vt 0.125025 0.874925 +vt 0.125025 0.937413 +vt 0.156269 0.749950 +vt 0.156250 0.921875 +vt 0.156269 0.812438 +vt 0.156269 0.874925 +vt 0.156269 0.937413 +vt 0.187513 0.749950 +vt 0.187500 0.921875 +vt 0.187513 0.812438 +vt 0.187513 0.874925 +vt 0.187513 0.937413 +vt 0.218756 0.749950 +vt 0.218750 0.921875 +vt 0.218756 0.812438 +vt 0.218756 0.874925 +vt 0.218756 0.937413 +vt 0.250000 0.749950 +vt 0.250000 0.921875 +vt 0.250000 0.812438 +vt 0.250000 0.874925 +vt 0.250000 0.937413 +vt 0.281244 0.749950 +vt 0.281250 0.921875 +vt 0.281244 0.812438 +vt 0.281244 0.874925 +vt 0.281244 0.937413 +vt 0.312488 0.749950 +vt 0.312500 0.921875 +vt 0.312488 0.812438 +vt 0.312488 0.874925 +vt 0.312488 0.937413 +vt 0.343731 0.749950 +vt 0.343750 0.921875 +vt 0.343731 0.812438 +vt 0.343731 0.874925 +vt 0.343731 0.937413 +vt 0.374975 0.749950 +vt 0.375000 0.921875 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.374975 0.937413 +vt 0.406219 0.749950 +vt 0.406250 0.921875 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.406219 0.937413 +vt 0.437463 0.749950 +vt 0.437500 0.921875 +vt 0.062516 1.000027 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.437463 0.937413 +vt 0.468706 0.749950 +vt 0.031269 1.000027 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +vt 0.468706 0.937413 +vt 0.093750 0.562500 +vt 0.499975 0.875031 +vt 0.499975 0.750031 +vt 0.125000 0.562500 +vt 0.031272 0.875032 +vt 0.031272 0.750032 +vt 0.000025 0.875032 +vt 0.000025 0.750032 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.093750 0.562500 +vt 0.499978 0.937533 +vt 0.125000 0.562500 +vt 0.000022 0.937533 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.468728 0.875031 +vt 0.468728 0.750031 +vt 0.437481 0.875031 +vt 0.437481 0.750031 +vt 0.406234 0.875031 +vt 0.406234 0.750031 +vt 0.374988 0.875031 +vt 0.374988 0.750031 +vt 0.343741 0.875031 +vt 0.343741 0.750031 +vt 0.312494 0.875031 +vt 0.312494 0.750031 +vt 0.281247 0.875031 +vt 0.281247 0.750031 +vt 0.250000 0.875032 +vt 0.250000 0.750032 +vt 0.218753 0.875032 +vt 0.218753 0.750032 +vt 0.187506 0.875032 +vt 0.187506 0.750032 +vt 0.156259 0.875032 +vt 0.156259 0.750032 +vt 0.125013 0.875032 +vt 0.125013 0.750032 +vt 0.093766 0.875032 +vt 0.093766 0.750032 +vt 0.062519 0.875032 +vt 0.062519 0.750032 +vt 0.468731 0.937533 +vt 0.156250 0.968750 +vt 0.156250 0.937500 +vt 0.062500 0.937500 +vt 0.437484 0.937533 +vt 0.125000 0.968750 +vt 0.374989 0.812543 +vt 0.125000 0.937500 +vt 0.406236 0.937533 +vt 0.093750 0.937500 +vt 0.374989 0.937533 +vt 0.125000 0.937500 +vt 0.406236 0.812543 +vt 0.093750 0.937500 +vt 0.156250 0.937500 +vt 0.437484 0.812543 +vt 0.062500 0.937500 +vt 0.187500 0.937500 +vt 0.468731 0.812543 +vt 0.031250 0.937500 +vt 0.218750 0.937500 +vt 0.062519 0.875044 +vt 0.062519 1.000044 +vt 0.093766 0.875044 +vt 0.093766 1.000044 +vt 0.250000 0.937500 +vt 0.125012 0.875044 +vt 0.125012 1.000044 +vt 0.156259 0.875044 +vt 0.156259 1.000044 +vt 0.187506 0.875044 +vt 0.187506 1.000044 +vt 0.281250 0.937500 +vt 0.218753 0.875044 +vt 0.218753 1.000044 +vt 0.250000 0.875044 +vt 0.250000 1.000044 +vt 0.281247 0.875044 +vt 0.281247 1.000044 +vt 0.312500 0.937500 +vt 0.312494 0.875044 +vt 0.312494 1.000044 +vt 0.343741 0.875044 +vt 0.343741 1.000044 +vt 0.374987 0.875044 +vt 0.374987 1.000044 +vt 0.343750 0.937500 +vt 0.406234 0.875044 +vt 0.406234 1.000044 +vt 0.437481 0.875044 +vt 0.437481 1.000044 +vt 0.468728 0.875044 +vt 0.468728 1.000044 +vt 0.375000 0.937500 +vt 0.062500 0.687500 +vt 0.031250 0.687500 +vt 0.000022 0.812544 +vt 0.000000 0.687500 +vt 0.500000 0.937500 +vt 0.093764 0.937533 +vt 0.406250 0.937500 +vt 0.499978 0.812543 +vt 0.125000 0.687500 +vt 0.000000 0.937500 +vt 0.093750 0.687500 +vt 0.062500 0.687500 +vt 0.437500 0.937500 +vt 0.062516 0.937533 +vt 0.031250 0.687500 +vt 0.000025 0.875044 +vt 0.000025 1.000044 +vt 0.000000 0.687500 +vt 0.031272 0.875044 +vt 0.031272 1.000044 +vt 0.031269 0.937533 +vt 0.499975 0.875044 +vt 0.499975 1.000044 +vt 0.125000 0.687500 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.499975 0.812538 +vt 0.125000 0.625000 +vt 0.499975 0.937538 +vt 0.031272 0.812538 +vt 0.031272 0.937538 +vt 0.000025 0.812538 +vt 0.000000 0.625000 +vt 0.000025 0.937538 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.093750 0.625000 +vt 0.125000 0.625000 +vt 0.499978 0.875038 +vt 0.000000 0.625000 +vt 0.000022 0.875038 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.468728 0.812538 +vt 0.468728 0.937538 +vt 0.437481 0.812538 +vt 0.437481 0.937538 +vt 0.406234 0.812538 +vt 0.406234 0.937538 +vt 0.374988 0.812538 +vt 0.374988 0.937538 +vt 0.343741 0.812538 +vt 0.343741 0.937538 +vt 0.312494 0.812538 +vt 0.312494 0.937538 +vt 0.281247 0.812538 +vt 0.281247 0.937538 +vt 0.250000 0.812538 +vt 0.250000 0.937538 +vt 0.218753 0.812538 +vt 0.218753 0.937538 +vt 0.187506 0.812538 +vt 0.187506 0.937538 +vt 0.156259 0.812538 +vt 0.156259 0.937538 +vt 0.125013 0.812538 +vt 0.125013 0.937538 +vt 0.093766 0.812538 +vt 0.093766 0.937538 +vt 0.062519 0.812538 +vt 0.062519 0.937538 +vt 0.093781 0.999900 +vt 0.093766 0.937550 +vt 0.468731 0.875038 +vt 0.093750 1.000000 +vt 0.093781 0.749950 +vt 0.093781 0.812438 +vt 0.093781 0.937413 +vt 0.437484 0.875038 +vt 0.093781 0.874925 +vt 0.125025 0.999900 +vt 0.125012 0.937550 +vt 0.125000 1.000000 +vt 0.125025 0.749950 +vt 0.406236 0.875038 +vt 0.125025 0.812438 +vt 0.125025 0.937413 +vt 0.125025 0.874925 +vt 0.125000 0.953125 +vt 0.374989 0.875038 +vt 0.156269 0.999900 +vt 0.156259 0.937550 +vt 0.156250 1.000000 +vt 0.156269 0.749950 +vt 0.156269 0.812438 +vt 0.156250 0.953125 +vt 0.156269 0.937413 +vt 0.156269 0.874925 +vt 0.187513 0.999900 +vt 0.187506 0.937550 +vt 0.312495 0.875038 +vt 0.187500 0.953125 +vt 0.187500 1.000000 +vt 0.187513 0.749950 +vt 0.187513 0.812438 +vt 0.187513 0.937413 +vt 0.218750 0.953125 +vt 0.281247 0.875038 +vt 0.187513 0.874925 +vt 0.218756 0.999900 +vt 0.218753 0.937550 +vt 0.218750 1.000000 +vt 0.218756 0.749950 +vt 0.250000 0.875038 +vt 0.250000 0.953125 +vt 0.218756 0.812438 +vt 0.218756 0.937413 +vt 0.218756 0.874925 +vt 0.281250 0.953125 +vt 0.250000 0.999900 +vt 0.250000 0.937550 +vt 0.250000 1.000000 +vt 0.250000 0.749950 +vt 0.250000 0.812438 +vt 0.312500 0.953125 +vt 0.250000 0.937413 +vt 0.250000 0.874925 +vt 0.281244 0.999900 +vt 0.281247 0.937550 +vt 0.343750 0.953125 +vt 0.156258 0.875038 +vt 0.281250 1.000000 +vt 0.281244 0.749950 +vt 0.281244 0.812438 +vt 0.281244 0.937413 +vt 0.375000 0.953125 +vt 0.125011 0.875038 +vt 0.281244 0.874925 +vt 0.312488 0.999900 +vt 0.312494 0.937550 +vt 0.312500 1.000000 +vt 0.312488 0.749950 +vt 0.406250 0.953125 +vt 0.093764 0.875038 +vt 0.312488 0.812438 +vt 0.312488 0.937413 +vt 0.312488 0.874925 +vt 0.062516 0.875038 +vt 0.343731 0.999900 +vt 0.343741 0.937550 +vt 0.343750 1.000000 +vt 0.343731 0.749950 +vt 0.343731 0.812438 +vt 0.031269 0.875038 +vt 0.343731 0.937413 +vt 0.343731 0.874925 +vt 0.312495 0.812543 +vt 0.187500 0.968750 +vt 0.187500 0.937500 +vt 0.281247 0.812543 +vt 0.218750 0.937500 +vt 0.250000 0.812543 +vt 0.250000 0.968750 +vt 0.250000 0.937500 +vt 0.281250 0.968750 +vt 0.281250 0.937500 +vt 0.312500 0.968750 +vt 0.312500 0.937500 +vt 0.343750 0.968750 +vt 0.156258 0.812543 +vt 0.343750 0.937500 +vt 0.125011 0.812543 +vt 0.375000 0.937500 +vt 0.093764 0.812544 +vt 0.406250 0.937500 +vt 0.062516 0.812544 +vt 0.437500 0.937500 +vt 0.031269 0.812544 +vt 0.468750 0.937500 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.062538 0.812438 +vt 0.062538 0.749950 +vt 0.062500 1.000000 +vt 0.062537 0.999900 +vt 0.062519 0.937551 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.031294 0.812438 +vt 0.031294 0.749950 +vt 0.031250 1.000000 +vt 0.031294 0.999900 +vt 0.031272 0.937551 +vt 0.374975 0.999900 +vt 0.374987 0.937550 +vt 0.406219 0.999900 +vt 0.406234 0.937550 +vt 0.437463 0.999900 +vt 0.437481 0.937550 +vt 0.468706 0.999900 +vt 0.468728 0.937550 +vt 0.499950 0.999900 +vt 0.499975 0.937550 +vt 0.125000 0.750000 +vt 0.062500 0.750000 +vt 0.499950 0.874925 +vt 0.093750 0.750000 +vt 0.499950 0.937413 +vt 0.031250 0.750000 +vt 0.499950 0.812438 +vt 0.000000 0.750000 +vt 0.500000 1.000000 +vt 0.499950 0.749950 +vt 0.000050 0.812438 +vt 0.093750 0.750000 +vt 0.000050 0.749950 +vt 0.125000 0.750000 +vt 0.000000 1.000000 +vt 0.000050 0.874925 +vt 0.062500 0.750000 +vt 0.000050 0.937413 +vt 0.031250 0.750000 +vt 0.000050 0.999900 +vt 0.000025 0.937551 +vt 0.000000 0.750000 +vt 0.374975 0.937413 +vt 0.375000 1.000000 +vt 0.374975 0.749950 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.406219 0.937413 +vt 0.406250 1.000000 +vt 0.406219 0.749950 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.437463 0.937413 +vt 0.437500 1.000000 +vt 0.437463 0.749950 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.468706 0.937413 +vt 0.468750 1.000000 +vt 0.468706 0.749950 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +vt 0.406250 0.828125 +vt 0.406250 0.312500 +vt 0.406250 0.250000 +vt 0.406250 0.812500 +vt 0.406250 0.796875 +vt 0.406250 0.781250 +vt 0.406219 0.031584 +vt 0.375000 0.875000 +vt 0.374975 0.465416 +vt 0.375000 0.859375 +vt 0.375000 0.437500 +vt 0.375000 0.375000 +vt 0.375000 0.843750 +vt 0.000050 0.465416 +vt 0.000050 0.437513 +vt 0.000050 0.375025 +vt 0.000050 0.312538 +vt 0.000050 0.250050 +vt 0.000050 0.187562 +vt 0.000050 0.125075 +vt 0.000050 0.062587 +vt 0.000050 0.031584 +vt 0.375000 0.312500 +vt 0.375000 0.828125 +vt 0.375000 0.250000 +vt 0.375000 0.812500 +vt 0.375000 0.796875 +vt 0.375000 0.187500 +vt 0.375000 0.781250 +vt 0.375000 0.125000 +vt 0.374975 0.031584 +vt 0.343750 0.875000 +vt 0.343731 0.465416 +vt 0.343750 0.859375 +vt 0.343750 0.437500 +vt 0.343750 0.375000 +vt 0.343750 0.843750 +vt 0.343750 0.828125 +vt 0.343750 0.812500 +vt 0.343750 0.187500 +vt 0.343750 0.796875 +vt 0.343750 0.125000 +vt 0.343750 0.781250 +vt 0.343731 0.031584 +vt 0.312500 0.875000 +vt 0.312488 0.465416 +vt 0.312500 0.437500 +vt 0.312500 0.859375 +vt 0.312500 0.375000 +vt 0.312500 0.843750 +vt 0.312500 0.828125 +vt 0.499950 0.031584 +vt 0.499950 0.062587 +vt 0.499950 0.125075 +vt 0.499950 0.187562 +vt 0.499950 0.250050 +vt 0.499950 0.312538 +vt 0.499950 0.375025 +vt 0.499950 0.465416 +vt 0.499950 0.437513 +vt 0.312500 0.812500 +vt 0.312500 0.796875 +vt 0.312500 0.781250 +vt 0.312488 0.031584 +vt 0.281250 0.875000 +vt 0.281244 0.465416 +vt 0.281250 0.859375 +vt 0.031294 0.062587 +vt 0.031294 0.031584 +vt 0.031294 0.125075 +vt 0.031294 0.187562 +vt 0.031294 0.250050 +vt 0.031294 0.312537 +vt 0.031294 0.375025 +vt 0.031294 0.437512 +vt 0.031294 0.465416 +vt 0.281250 0.843750 +vt 0.281250 0.828125 +vt 0.281250 0.812500 +vt 0.281250 0.796875 +vt 0.281250 0.781250 +vt 0.281244 0.031584 +vt 0.062538 0.062587 +vt 0.062538 0.031584 +vt 0.062538 0.125075 +vt 0.062538 0.187562 +vt 0.062538 0.250050 +vt 0.062538 0.312537 +vt 0.062538 0.375025 +vt 0.062538 0.437512 +vt 0.062538 0.465416 +vt 0.250000 0.875000 +vt 0.250000 0.465416 +vt 0.250000 0.859375 +vt 0.250000 0.843750 +vt 0.250000 0.828125 +vt 0.250000 0.812500 +vt 0.093781 0.062587 +vt 0.093781 0.031584 +vt 0.093781 0.125075 +vt 0.093781 0.187562 +vt 0.093781 0.250050 +vt 0.093781 0.312538 +vt 0.093781 0.375025 +vt 0.093781 0.437513 +vt 0.093781 0.465416 +vt 0.250000 0.796875 +vt 0.250000 0.781250 +vt 0.250000 0.031584 +vt 0.218750 0.875000 +vt 0.218750 0.500000 +vt 0.218756 0.465416 +vt 0.218750 0.437500 +vt 0.218750 0.859375 +vt 0.218750 0.843750 +vt 0.125025 0.062587 +vt 0.125025 0.031584 +vt 0.125025 0.125075 +vt 0.125025 0.187562 +vt 0.125025 0.250050 +vt 0.125025 0.312538 +vt 0.125025 0.375025 +vt 0.125025 0.437513 +vt 0.125025 0.465416 +vt 0.218750 0.828125 +vt 0.218750 0.812500 +vt 0.218750 0.250000 +vt 0.218750 0.187500 +vt 0.218750 0.796875 +vt 0.218750 0.781250 +vt 0.218756 0.031584 +vt 0.187500 0.500000 +vt 0.187513 0.465416 +vt 0.156269 0.062587 +vt 0.156269 0.031584 +vt 0.156269 0.125075 +vt 0.156269 0.187562 +vt 0.156269 0.250050 +vt 0.156269 0.312538 +vt 0.156269 0.375025 +vt 0.156269 0.437513 +vt 0.156269 0.465416 +vt 0.187500 0.437500 +vt 0.187500 0.859375 +vt 0.187500 0.843750 +vt 0.187500 0.828125 +vt 0.187500 0.812500 +vt 0.187500 0.250000 +vt 0.187500 0.187500 +vt 0.187500 0.796875 +vt 0.187513 0.062587 +vt 0.187513 0.031584 +vt 0.187513 0.125075 +vt 0.187513 0.187562 +vt 0.187513 0.250050 +vt 0.187513 0.312538 +vt 0.187513 0.375025 +vt 0.187513 0.437513 +vt 0.187513 0.465416 +vt 0.187500 0.781250 +vt 0.187513 0.031584 +vt 0.156250 0.500000 +vt 0.156250 0.875000 +vt 0.156269 0.465416 +vt 0.156250 0.437500 +vt 0.156250 0.859375 +vt 0.156250 0.843750 +vt 0.156250 0.375000 +vt 0.156250 0.312500 +vt 0.156250 0.828125 +vt 0.218756 0.062587 +vt 0.218756 0.031584 +vt 0.218756 0.125075 +vt 0.218756 0.187562 +vt 0.218756 0.250050 +vt 0.218756 0.312538 +vt 0.218756 0.375025 +vt 0.218756 0.437513 +vt 0.218756 0.465416 +vt 0.156250 0.250000 +vt 0.156250 0.812500 +vt 0.156250 0.796875 +vt 0.156250 0.187500 +vt 0.156250 0.781250 +vt 0.156250 0.125000 +vt 0.156269 0.031584 +vt 0.125000 0.875000 +vt 0.125025 0.465416 +vt 0.125000 0.859375 +vt 0.250000 0.062587 +vt 0.250000 0.031584 +vt 0.250000 0.125075 +vt 0.250000 0.187562 +vt 0.250000 0.250050 +vt 0.250000 0.312538 +vt 0.250000 0.375025 +vt 0.250000 0.437513 +vt 0.250000 0.465416 +vt 0.125000 0.843750 +vt 0.125000 0.375000 +vt 0.125000 0.312500 +vt 0.125000 0.828125 +vt 0.125000 0.812500 +vt 0.125000 0.187500 +vt 0.125000 0.796875 +vt 0.125000 0.125000 +vt 0.125000 0.781250 +vt 0.125025 0.031584 +vt 0.281244 0.062587 +vt 0.281244 0.031584 +vt 0.281244 0.125075 +vt 0.281244 0.187562 +vt 0.281244 0.250050 +vt 0.281244 0.312538 +vt 0.281244 0.375025 +vt 0.281244 0.437513 +vt 0.281244 0.465416 +vt 0.093750 0.875000 +vt 0.093750 0.500000 +vt 0.093781 0.465416 +vt 0.093750 0.437500 +vt 0.093750 0.859375 +vt 0.093750 0.375000 +vt 0.093750 0.843750 +vt 0.093750 0.312500 +vt 0.093750 0.828125 +vt 0.093750 0.812500 +vt 0.312488 0.062587 +vt 0.312488 0.031584 +vt 0.312488 0.125075 +vt 0.312488 0.187562 +vt 0.312488 0.250050 +vt 0.312488 0.312538 +vt 0.312488 0.375025 +vt 0.312488 0.437513 +vt 0.312488 0.465416 +vt 0.093750 0.796875 +vt 0.093750 0.187500 +vt 0.093750 0.781250 +vt 0.093750 0.125000 +vt 0.093781 0.031584 +vt 0.062500 0.500000 +vt 0.062538 0.465416 +vt 0.062500 0.859375 +vt 0.062500 0.437500 +vt 0.062500 0.843750 +vt 0.062500 0.375000 +vt 0.343731 0.062587 +vt 0.343731 0.031584 +vt 0.343731 0.125075 +vt 0.343731 0.187562 +vt 0.343731 0.250050 +vt 0.343731 0.312538 +vt 0.343731 0.375025 +vt 0.343731 0.437513 +vt 0.343731 0.465416 +vt 0.062500 0.828125 +vt 0.062500 0.312500 +vt 0.062500 0.812500 +vt 0.062500 0.250000 +vt 0.062500 0.796875 +vt 0.062500 0.187500 +vt 0.062500 0.125000 +vt 0.062538 0.031584 +vt 0.031250 0.500000 +vt 0.031294 0.465416 +vt 0.374975 0.062587 +vt 0.374975 0.031584 +vt 0.374975 0.125075 +vt 0.374975 0.187562 +vt 0.374975 0.250050 +vt 0.374975 0.312538 +vt 0.374975 0.375025 +vt 0.374975 0.437513 +vt 0.374975 0.465416 +vt 0.031250 0.437500 +vt 0.031250 0.375000 +vt 0.031250 0.312500 +vt 0.031250 0.250000 +vt 0.031250 0.187500 +vt 0.406219 0.062587 +vt 0.406219 0.031584 +vt 0.406219 0.125075 +vt 0.406219 0.187562 +vt 0.406219 0.250050 +vt 0.406219 0.312538 +vt 0.406219 0.375025 +vt 0.406219 0.437513 +vt 0.406219 0.465416 +vt 0.031250 0.125000 +vt 0.031294 0.031584 +vt 0.500000 0.500000 +vt 0.499950 0.465416 +vt 0.499950 0.437513 +vt 0.500000 0.437500 +vt 0.499950 0.375025 +vt 0.500000 0.375000 +vt 0.499950 0.312538 +vt 0.500000 0.312500 +vt 0.499950 0.250050 +vt 0.437463 0.062587 +vt 0.437463 0.031584 +vt 0.437463 0.125075 +vt 0.437462 0.187562 +vt 0.437462 0.250050 +vt 0.437463 0.312538 +vt 0.437463 0.375025 +vt 0.437463 0.437513 +vt 0.437463 0.465416 +vt 0.500000 0.250000 +vt 0.499950 0.187562 +vt 0.500000 0.187500 +vt 0.499950 0.125075 +vt 0.500000 0.125000 +vt 0.499950 0.031584 +vt 0.499950 0.062587 +vt 0.000000 0.125000 +vt 0.000050 0.062587 +vt 0.000050 0.031584 +vt 0.000000 0.187500 +vt 0.000050 0.125075 +vt 0.468706 0.062587 +vt 0.468706 0.031584 +vt 0.468706 0.125075 +vt 0.468706 0.187562 +vt 0.468706 0.250050 +vt 0.468706 0.312538 +vt 0.468706 0.375025 +vt 0.468706 0.437513 +vt 0.468706 0.465416 +vt 0.000000 0.250000 +vt 0.000050 0.187562 +vt 0.000000 0.312500 +vt 0.000050 0.250050 +vt 0.000000 0.375000 +vt 0.000050 0.312538 +vt 0.000000 0.437500 +vt 0.000050 0.375025 +vt 0.000000 0.500000 +vt 0.000050 0.465416 +vt 0.000050 0.437513 +vt 0.406250 0.843750 +vt 0.406250 0.437500 +vt 0.406250 0.859375 +vt 0.406250 0.500000 +vt 0.406250 0.875000 +vt 0.406219 0.465416 +vt 0.437500 0.125000 +vt 0.437500 0.781250 +vt 0.437463 0.031584 +vt 0.437500 0.187500 +vt 0.437500 0.796875 +vt 0.437500 0.250000 +vt 0.437500 0.812500 +vt 0.437500 0.828125 +vt 0.437500 0.312500 +vt 0.437500 0.375000 +vt 0.437500 0.843750 +vt 0.437500 0.437500 +vt 0.437500 0.859375 +vt 0.437500 0.500000 +vt 0.437463 0.465416 +vt 0.468750 0.125000 +vt 0.468706 0.031584 +vt 0.468750 0.796875 +vt 0.468750 0.187500 +vt 0.468750 0.250000 +vt 0.468750 0.812500 +vt 0.468750 0.312500 +vt 0.468750 0.828125 +vt 0.468750 0.375000 +vt 0.468750 0.843750 +vt 0.468750 0.437500 +vt 0.468750 0.500000 +vt 0.468706 0.465416 +vt 0.000050 0.812438 +vt 0.499975 0.750031 +vt 0.000000 0.500000 +vt 0.500000 0.890625 +vt 0.000025 0.750032 +vt 0.125000 0.500000 +vt 0.000050 0.749950 +vt 0.000050 0.874925 +vt 0.031250 0.500000 +vt 0.000050 0.937413 +vt 0.000050 0.812438 +vt 0.062500 0.500000 +vt 0.000050 0.999900 +vt 0.000050 0.874925 +vt 0.093750 0.500000 +vt 0.000050 0.937413 +vt 0.500000 0.812500 +vt 0.125000 0.500000 +vt 0.500000 0.937500 +vt 0.000000 0.812500 +vt 0.000000 0.500000 +vt 0.500000 1.000000 +vt 0.468750 0.937500 +vt 0.031250 0.500000 +vt 0.468750 0.875000 +vt 0.500000 0.812500 +vt 0.062500 0.500000 +vt 0.500000 0.875000 +vt 0.093750 0.500000 +vt 0.468750 0.890625 +vt 0.031272 0.750032 +vt 0.437500 0.890625 +vt 0.062519 0.750032 +vt 0.406250 0.890625 +vt 0.093766 0.750032 +vt 0.375000 0.890625 +vt 0.125012 0.750032 +vt 0.125000 0.937500 +vt 0.343750 0.890625 +vt 0.156250 0.937500 +vt 0.312500 0.890625 +vt 0.187500 0.937500 +vt 0.281250 0.890625 +vt 0.218750 0.937500 +vt 0.250000 0.890625 +vt 0.250000 0.937500 +vt 0.218750 0.890625 +vt 0.281250 0.937500 +vt 0.187500 0.890625 +vt 0.312500 0.937500 +vt 0.156250 0.890625 +vt 0.343750 0.937500 +vt 0.125000 0.890625 +vt 0.375000 0.937500 +vt 0.093750 0.890625 +vt 0.406234 0.750031 +vt 0.406250 0.937500 +vt 0.062500 0.890625 +vt 0.437481 0.750031 +vt 0.031294 0.812437 +vt 0.031250 0.890625 +vt 0.468728 0.750031 +vt 0.031294 0.937413 +vt 0.468750 0.812500 +vt 0.031294 0.874925 +vt 0.031294 0.999900 +vt 0.031250 0.906250 +vt 0.031294 0.937412 +vt 0.031294 0.812437 +vt 0.031250 0.921875 +vt 0.031250 0.890625 +vt 0.031294 0.749950 +vt 0.031294 0.874925 +vt 0.031250 0.906250 +vt 0.062537 0.937413 +vt 0.062500 0.921875 +vt 0.437500 0.812500 +vt 0.062537 0.999900 +vt 0.062500 0.937500 +vt 0.062500 0.906250 +vt 0.062500 0.921875 +vt 0.062500 0.890625 +vt 0.062500 0.875000 +vt 0.062500 0.906250 +vt 0.093750 0.921875 +vt 0.406250 0.812500 +vt 0.406250 0.953125 +vt 0.093750 0.937500 +vt 0.093750 0.906250 +vt 0.093750 0.921875 +vt 0.093750 0.890625 +vt 0.093750 0.875000 +vt 0.093750 0.906250 +vt 0.125000 0.921875 +vt 0.375000 0.953125 +vt 0.125000 0.937500 +vt 0.125000 0.906250 +vt 0.125000 0.921875 +vt 0.125000 0.890625 +vt 0.125000 0.875000 +vt 0.125000 0.906250 +vt 0.156250 0.921875 +vt 0.343750 0.953125 +vt 0.156250 0.937500 +vt 0.156250 0.906250 +vt 0.156250 0.921875 +vt 0.156250 0.890625 +vt 0.156250 0.875000 +vt 0.156250 0.906250 +vt 0.187500 0.921875 +vt 0.312500 0.953125 +vt 0.187500 0.937500 +vt 0.187500 0.906250 +vt 0.187500 0.921875 +vt 0.187500 0.890625 +vt 0.187500 0.875000 +vt 0.187500 0.906250 +vt 0.218750 0.921875 +vt 0.281250 0.953125 +vt 0.218750 0.937500 +vt 0.218750 0.906250 +vt 0.218750 0.921875 +vt 0.218750 0.890625 +vt 0.218750 0.875000 +vt 0.218750 0.906250 +vt 0.250000 0.921875 +vt 0.250000 0.953125 +vt 0.250000 0.937500 +vt 0.250000 0.906250 +vt 0.250000 0.921875 +vt 0.250000 0.890625 +vt 0.250000 0.875000 +vt 0.250000 0.906250 +vt 0.281250 0.921875 +vt 0.218750 0.953125 +vt 0.281250 0.937500 +vt 0.281250 0.906250 +vt 0.281250 0.921875 +vt 0.281250 0.890625 +vt 0.281250 0.875000 +vt 0.281250 0.906250 +vt 0.312500 0.921875 +vt 0.187500 0.953125 +vt 0.312500 0.937500 +vt 0.312500 0.906250 +vt 0.312500 0.921875 +vt 0.312500 0.890625 +vt 0.312500 0.875000 +vt 0.312500 0.906250 +vt 0.343750 0.921875 +vt 0.156250 0.953125 +vt 0.343750 0.937500 +vt 0.343750 0.906250 +vt 0.343750 0.921875 +vt 0.343750 0.890625 +vt 0.343750 0.875000 +vt 0.343750 0.906250 +vt 0.375000 0.921875 +vt 0.125000 0.812500 +vt 0.125000 0.953125 +vt 0.375000 0.937500 +vt 0.375000 0.906250 +vt 0.375000 0.921875 +vt 0.375000 0.890625 +vt 0.375000 0.875000 +vt 0.375000 0.906250 +vt 0.406250 0.921875 +vt 0.093750 0.812500 +vt 0.406250 0.937500 +vt 0.406250 0.906250 +vt 0.406250 0.921875 +vt 0.406250 0.890625 +vt 0.406250 0.875000 +vt 0.406250 0.906250 +vt 0.437500 0.921875 +vt 0.437500 0.937500 +vt 0.062500 0.812500 +vt 0.437500 0.937500 +vt 0.437500 1.000000 +vt 0.437500 0.906250 +vt 0.437500 0.921875 +vt 0.437500 0.890625 +vt 0.437500 0.875000 +vt 0.437500 0.906250 +vt 0.468750 0.937500 +vt 0.031250 0.812500 +vt 0.468750 0.906250 +vt 0.468750 1.000000 +vt 0.500000 0.937500 +vt 0.468750 0.921875 +vt 0.468750 0.890625 +vt 0.500000 0.875000 +vt 0.468750 0.812500 +vt 0.468750 0.906250 +vt 0.468750 0.875000 +vt 0.093750 0.562500 +vt 0.000025 0.812526 +vt 0.125000 0.562500 +vt 0.468728 0.812525 +vt 0.499975 0.812525 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.093750 0.562500 +vt 0.500000 0.875000 +vt 0.500000 0.750000 +vt 0.125000 0.562500 +vt 0.000000 0.875000 +vt 0.000000 0.750000 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.031272 0.812526 +vt 0.062519 0.812526 +vt 0.093766 0.812526 +vt 0.125012 0.812526 +vt 0.125000 0.953125 +vt 0.156250 0.953125 +vt 0.187506 0.812538 +vt 0.187500 0.953125 +vt 0.218753 0.812538 +vt 0.218750 0.953125 +vt 0.250000 0.812538 +vt 0.250000 0.953125 +vt 0.281250 0.953125 +vt 0.312494 0.812538 +vt 0.312500 0.953125 +vt 0.343741 0.812538 +vt 0.343750 0.953125 +vt 0.374987 0.812538 +vt 0.375000 0.953125 +vt 0.406234 0.812525 +vt 0.406250 0.953125 +vt 0.437481 0.812525 +vt 0.468750 0.875000 +vt 0.468750 0.750000 +vt 0.343750 0.875000 +vt 0.343750 1.000000 +vt 0.437500 0.875000 +vt 0.437500 0.750000 +vt 0.375000 0.875000 +vt 0.375000 1.000000 +vt 0.406250 0.875000 +vt 0.406250 0.750000 +vt 0.406250 0.937500 +vt 0.375000 0.875000 +vt 0.375000 0.937500 +vt 0.406250 0.875000 +vt 0.406250 1.000000 +vt 0.343750 0.875000 +vt 0.343750 0.968750 +vt 0.343750 0.937500 +vt 0.437500 0.875000 +vt 0.437500 1.000000 +vt 0.312500 0.968750 +vt 0.312500 0.937500 +vt 0.468750 0.875000 +vt 0.468750 1.000000 +vt 0.281250 0.968750 +vt 0.281250 0.937500 +vt 0.437481 0.937550 +vt 0.406234 0.937550 +vt 0.250000 0.968750 +vt 0.250000 0.875000 +vt 0.250000 0.937500 +vt 0.374987 0.937550 +vt 0.343741 0.937550 +vt 0.312494 0.937551 +vt 0.218750 0.875000 +vt 0.218750 0.937500 +vt 0.281247 0.937551 +vt 0.250000 0.937551 +vt 0.218753 0.937551 +vt 0.187500 0.968750 +vt 0.187500 0.875000 +vt 0.187500 0.937500 +vt 0.187506 0.937551 +vt 0.156259 0.937551 +vt 0.125012 0.937551 +vt 0.156250 0.968750 +vt 0.156250 0.937500 +vt 0.093766 0.937551 +vt 0.062519 0.937551 +vt 0.031272 0.937551 +vt 0.125000 0.875000 +vt 0.125000 0.968750 +vt 0.125000 0.750000 +vt 0.125000 0.937500 +vt 0.062500 0.687500 +vt 0.031250 0.687500 +vt 0.000000 0.875000 +vt 0.000000 0.687500 +vt 0.000000 1.000000 +vt 0.093750 0.875000 +vt 0.093750 0.750000 +vt 0.500000 0.875000 +vt 0.125000 0.687500 +vt 0.500000 1.000000 +vt 0.093750 0.687500 +vt 0.062500 0.687500 +vt 0.062500 0.875000 +vt 0.062500 0.750000 +vt 0.031250 0.687500 +vt 0.499975 0.937550 +vt 0.000000 0.687500 +vt 0.468728 0.937550 +vt 0.031250 0.875000 +vt 0.031250 0.750000 +vt 0.000025 0.937551 +vt 0.125000 0.687500 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.125000 0.625000 +vt 0.000025 0.875044 +vt 0.468728 0.875044 +vt 0.000000 0.625000 +vt 0.499975 0.875044 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.093750 0.625000 +vt 0.500000 0.812500 +vt 0.125000 0.625000 +vt 0.500000 0.937500 +vt 0.000000 0.812500 +vt 0.000000 0.625000 +vt 0.000000 0.937500 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.031272 0.875044 +vt 0.062519 0.875044 +vt 0.093766 0.875044 +vt 0.125000 0.968750 +vt 0.125012 0.875044 +vt 0.156250 0.968750 +vt 0.156259 0.875044 +vt 0.187500 0.968750 +vt 0.187506 0.875044 +vt 0.218753 0.875044 +vt 0.250000 0.968750 +vt 0.250000 0.875044 +vt 0.281250 0.968750 +vt 0.281247 0.875044 +vt 0.312500 0.968750 +vt 0.312494 0.875044 +vt 0.343741 0.875044 +vt 0.374987 0.875044 +vt 0.406234 0.875044 +vt 0.437481 0.875044 +vt 0.093781 0.999900 +vt 0.406234 1.000044 +vt 0.468750 0.812500 +vt 0.468750 0.937500 +vt 0.406250 0.937500 +vt 0.093781 0.749950 +vt 0.093781 0.812438 +vt 0.093781 0.937413 +vt 0.437500 0.812500 +vt 0.437500 0.937500 +vt 0.093781 0.874925 +vt 0.125025 0.999900 +vt 0.374988 1.000044 +vt 0.375000 0.937500 +vt 0.125025 0.749950 +vt 0.406250 0.812500 +vt 0.406250 0.937500 +vt 0.125025 0.812438 +vt 0.125025 0.937413 +vt 0.125025 0.874925 +vt 0.375000 0.812500 +vt 0.375000 0.937500 +vt 0.156269 0.999900 +vt 0.343741 1.000044 +vt 0.343750 0.937500 +vt 0.156269 0.749950 +vt 0.156269 0.812438 +vt 0.343750 0.812500 +vt 0.343750 0.953125 +vt 0.343750 0.937500 +vt 0.156269 0.937413 +vt 0.156269 0.874925 +vt 0.187513 0.999900 +vt 0.312494 1.000044 +vt 0.312500 0.953125 +vt 0.312500 0.937500 +vt 0.312500 0.937500 +vt 0.187513 0.749950 +vt 0.187513 0.812438 +vt 0.187513 0.937413 +vt 0.281250 0.953125 +vt 0.281250 0.937500 +vt 0.187513 0.874925 +vt 0.218756 0.999900 +vt 0.281247 1.000044 +vt 0.281250 0.937500 +vt 0.218756 0.749950 +vt 0.250000 0.953125 +vt 0.250000 0.812500 +vt 0.250000 0.937500 +vt 0.218756 0.812438 +vt 0.218756 0.937413 +vt 0.218756 0.874925 +vt 0.218750 0.812500 +vt 0.218750 0.937500 +vt 0.250000 0.999900 +vt 0.250000 1.000044 +vt 0.250000 0.937500 +vt 0.250000 0.749950 +vt 0.250000 0.812438 +vt 0.187500 0.953125 +vt 0.187500 0.812500 +vt 0.187500 0.937500 +vt 0.250000 0.937413 +vt 0.250000 0.874925 +vt 0.281244 0.999900 +vt 0.218753 1.000044 +vt 0.156250 0.953125 +vt 0.156250 0.937500 +vt 0.218750 0.937500 +vt 0.281244 0.749950 +vt 0.281244 0.812438 +vt 0.281244 0.937413 +vt 0.125000 0.812500 +vt 0.125000 0.953125 +vt 0.125000 0.937500 +vt 0.281244 0.874925 +vt 0.312488 0.999900 +vt 0.187506 1.000044 +vt 0.187500 0.937500 +vt 0.312488 0.749950 +vt 0.093750 0.812500 +vt 0.093750 0.937500 +vt 0.312488 0.812438 +vt 0.312488 0.937413 +vt 0.312488 0.874925 +vt 0.062500 0.812500 +vt 0.062500 0.937500 +vt 0.343731 0.999900 +vt 0.156259 1.000044 +vt 0.156250 0.937500 +vt 0.343731 0.749950 +vt 0.343731 0.812438 +vt 0.031250 0.812500 +vt 0.031250 0.937500 +vt 0.343731 0.937413 +vt 0.343731 0.874925 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.281250 0.875000 +vt 0.281250 1.000000 +vt 0.250000 0.875000 +vt 0.250000 1.000000 +vt 0.218750 0.875000 +vt 0.218750 1.000000 +vt 0.187500 0.875000 +vt 0.187500 1.000000 +vt 0.156250 0.875000 +vt 0.156250 1.000000 +vt 0.125000 0.875000 +vt 0.125000 1.000000 +vt 0.093750 0.875000 +vt 0.093750 1.000000 +vt 0.062500 0.875000 +vt 0.062500 1.000000 +vt 0.031250 0.875000 +vt 0.031250 1.000000 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.062538 0.812438 +vt 0.062538 0.749950 +vt 0.437500 0.937500 +vt 0.062537 0.999900 +vt 0.437481 1.000044 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.031294 0.812438 +vt 0.031294 0.749950 +vt 0.468750 0.937500 +vt 0.031294 0.999900 +vt 0.468728 1.000044 +vt 0.374975 0.999900 +vt 0.125012 1.000045 +vt 0.406219 0.999900 +vt 0.093766 1.000045 +vt 0.437463 0.999900 +vt 0.062519 1.000045 +vt 0.468706 0.999900 +vt 0.031272 1.000044 +vt 0.499950 0.999900 +vt 0.000025 1.000044 +vt 0.125000 0.750000 +vt 0.062500 0.750000 +vt 0.499950 0.874925 +vt 0.093750 0.750000 +vt 0.499950 0.937413 +vt 0.031250 0.750000 +vt 0.499950 0.812438 +vt 0.000000 0.750000 +vt 0.000000 0.937500 +vt 0.499950 0.749950 +vt 0.000050 0.812438 +vt 0.093750 0.750000 +vt 0.000050 0.749950 +vt 0.125000 0.750000 +vt 0.500000 0.937500 +vt 0.000050 0.874925 +vt 0.062500 0.750000 +vt 0.000050 0.937413 +vt 0.031250 0.750000 +vt 0.000050 0.999900 +vt 0.499975 1.000044 +vt 0.000000 0.750000 +vt 0.374975 0.937413 +vt 0.125000 0.937500 +vt 0.374975 0.749950 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.406219 0.937413 +vt 0.093750 0.937500 +vt 0.406219 0.749950 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.437463 0.937413 +vt 0.062500 0.937500 +vt 0.437463 0.749950 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.468706 0.937413 +vt 0.031250 0.937500 +vt 0.468706 0.749950 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +vt 0.000050 0.999900 +vt 0.000025 0.812526 +vt 0.000000 0.500000 +vt 0.499950 0.999900 +vt 0.499975 0.812525 +vt 0.125000 0.500000 +vt 0.000050 0.937413 +vt 0.031250 0.500000 +vt 0.000050 0.874925 +vt 0.062500 0.500000 +vt 0.000050 0.812438 +vt 0.093750 0.500000 +vt 0.000000 0.750000 +vt 0.125000 0.500000 +vt 0.500000 0.750000 +vt 0.000000 0.500000 +vt 0.499950 0.812438 +vt 0.031250 0.500000 +vt 0.499950 0.874925 +vt 0.062500 0.500000 +vt 0.499950 0.937413 +vt 0.093750 0.500000 +vt 0.468706 0.999900 +vt 0.468728 0.812525 +vt 0.437463 0.999900 +vt 0.437481 0.812525 +vt 0.062500 0.921875 +vt 0.406219 0.999900 +vt 0.093750 0.921875 +vt 0.374975 0.999900 +vt 0.125000 0.921875 +vt 0.343731 0.999900 +vt 0.156250 0.921875 +vt 0.312488 0.999900 +vt 0.187500 0.921875 +vt 0.281244 0.999900 +vt 0.218750 0.921875 +vt 0.250000 0.999900 +vt 0.250000 0.921875 +vt 0.218756 0.999900 +vt 0.281250 0.921875 +vt 0.187513 0.999900 +vt 0.312500 0.921875 +vt 0.156269 0.999900 +vt 0.343750 0.921875 +vt 0.125025 0.999900 +vt 0.375000 0.921875 +vt 0.093781 0.999900 +vt 0.406250 0.921875 +vt 0.062537 0.999900 +vt 0.437500 0.921875 +vt 0.062519 0.812526 +vt 0.031294 0.999900 +vt 0.031272 0.812526 +vt 0.031250 0.750000 +vt 0.031294 0.812438 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.062500 0.750000 +vt 0.062538 0.812438 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.093750 0.750000 +vt 0.093781 0.812438 +vt 0.093781 0.874925 +vt 0.093781 0.937413 +vt 0.125000 0.750000 +vt 0.125025 0.812438 +vt 0.125025 0.874925 +vt 0.125025 0.937413 +vt 0.156250 0.750000 +vt 0.156269 0.812438 +vt 0.156269 0.874925 +vt 0.156269 0.937413 +vt 0.187500 0.750000 +vt 0.187513 0.812438 +vt 0.187513 0.874925 +vt 0.187513 0.937413 +vt 0.218750 0.750000 +vt 0.218756 0.812438 +vt 0.218756 0.874925 +vt 0.218756 0.937413 +vt 0.250000 0.750000 +vt 0.250000 0.812438 +vt 0.250000 0.874925 +vt 0.250000 0.937413 +vt 0.281250 0.750000 +vt 0.281244 0.812438 +vt 0.281244 0.874925 +vt 0.281244 0.937413 +vt 0.312500 0.750000 +vt 0.312488 0.812438 +vt 0.312488 0.874925 +vt 0.312488 0.937413 +vt 0.343750 0.750000 +vt 0.343731 0.812438 +vt 0.343731 0.874925 +vt 0.343731 0.937413 +vt 0.375000 0.750000 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.374975 0.937413 +vt 0.406250 0.750000 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.406219 0.937413 +vt 0.437500 0.750000 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.437463 0.937413 +vt 0.468750 0.750000 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +vt 0.468706 0.937413 +vt 0.093750 0.562500 +vt 0.499975 0.875031 +vt 0.499975 0.750031 +vt 0.125000 0.562500 +vt 0.031272 0.875032 +vt 0.031272 0.750032 +vt 0.000025 0.875032 +vt 0.000025 0.750032 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.093750 0.562500 +vt 0.000000 0.812500 +vt 0.125000 0.562500 +vt 0.500000 0.812500 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.468728 0.875031 +vt 0.468728 0.750031 +vt 0.437481 0.875031 +vt 0.437481 0.750031 +vt 0.062500 0.937500 +vt 0.406234 0.875031 +vt 0.093750 0.937500 +vt 0.374988 0.875031 +vt 0.125000 0.937500 +vt 0.156250 0.937500 +vt 0.187500 0.937500 +vt 0.218750 0.937500 +vt 0.250000 0.937500 +vt 0.281250 0.937500 +vt 0.312500 0.937500 +vt 0.343750 0.937500 +vt 0.375000 0.937500 +vt 0.093766 0.875032 +vt 0.406250 0.937500 +vt 0.062519 0.875032 +vt 0.437500 0.937500 +vt 0.062519 0.750032 +vt 0.031250 0.812500 +vt 0.156250 0.937500 +vt 0.062500 0.812500 +vt 0.125000 0.937500 +vt 0.093750 0.812500 +vt 0.125000 0.812500 +vt 0.093750 0.937500 +vt 0.156250 0.812500 +vt 0.062500 0.937500 +vt 0.187500 0.812500 +vt 0.031250 0.937500 +vt 0.218750 0.812500 +vt 0.062519 0.875044 +vt 0.062519 1.000044 +vt 0.093766 0.875044 +vt 0.093766 1.000044 +vt 0.250000 0.812500 +vt 0.125012 0.875044 +vt 0.125012 1.000044 +vt 0.156259 0.875044 +vt 0.343750 0.968750 +vt 0.156259 1.000044 +vt 0.312500 0.968750 +vt 0.187506 1.000044 +vt 0.281250 0.812500 +vt 0.281250 0.968750 +vt 0.218753 1.000044 +vt 0.250000 0.968750 +vt 0.250000 0.875044 +vt 0.250000 1.000044 +vt 0.281247 0.875044 +vt 0.281247 1.000044 +vt 0.312500 0.812500 +vt 0.312494 0.875044 +vt 0.187500 0.968750 +vt 0.312494 1.000044 +vt 0.156250 0.968750 +vt 0.343741 1.000044 +vt 0.125000 0.968750 +vt 0.374987 0.875044 +vt 0.374987 1.000044 +vt 0.343750 0.812500 +vt 0.406234 0.875044 +vt 0.406234 1.000044 +vt 0.437481 0.875044 +vt 0.437481 1.000044 +vt 0.468728 0.875044 +vt 0.468728 1.000044 +vt 0.375000 0.812500 +vt 0.062500 0.687500 +vt 0.031250 0.687500 +vt 0.000000 0.687500 +vt 0.500000 0.937500 +vt 0.406250 0.812500 +vt 0.125000 0.687500 +vt 0.000000 0.937500 +vt 0.093750 0.687500 +vt 0.062500 0.687500 +vt 0.437500 0.812500 +vt 0.031250 0.687500 +vt 0.000025 0.875045 +vt 0.000025 1.000044 +vt 0.000000 0.687500 +vt 0.031272 0.875045 +vt 0.031272 1.000044 +vt 0.468750 0.812500 +vt 0.499975 0.875044 +vt 0.499975 1.000044 +vt 0.125000 0.687500 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.499975 0.812537 +vt 0.125000 0.625000 +vt 0.499975 0.937537 +vt 0.031272 0.812538 +vt 0.031272 0.937538 +vt 0.000025 0.812538 +vt 0.000000 0.625000 +vt 0.000025 0.937538 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.093750 0.625000 +vt 0.125000 0.625000 +vt 0.000000 0.875000 +vt 0.000000 0.625000 +vt 0.500000 0.875000 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.468728 0.812537 +vt 0.468728 0.937537 +vt 0.437481 0.812538 +vt 0.437481 0.937538 +vt 0.406234 0.812538 +vt 0.406234 0.937538 +vt 0.374988 0.812538 +vt 0.125000 0.953125 +vt 0.374988 0.937538 +vt 0.156250 0.953125 +vt 0.312494 0.937538 +vt 0.187500 0.953125 +vt 0.218750 0.953125 +vt 0.281247 0.937538 +vt 0.250000 0.953125 +vt 0.250000 0.937538 +vt 0.281250 0.953125 +vt 0.312500 0.953125 +vt 0.156259 0.937538 +vt 0.343750 0.953125 +vt 0.375000 0.953125 +vt 0.125013 0.937538 +vt 0.093766 0.812538 +vt 0.406250 0.953125 +vt 0.093766 0.937538 +vt 0.062519 0.812538 +vt 0.062519 0.937538 +vt 0.093781 0.999900 +vt 0.093766 0.937550 +vt 0.031250 0.875000 +vt 0.093750 1.000000 +vt 0.093781 0.749950 +vt 0.093781 0.812438 +vt 0.093781 0.937413 +vt 0.062500 0.875000 +vt 0.093781 0.874925 +vt 0.125025 0.999900 +vt 0.125012 0.937550 +vt 0.125000 1.000000 +vt 0.125025 0.749950 +vt 0.093750 0.875000 +vt 0.125025 0.812438 +vt 0.125025 0.937413 +vt 0.125025 0.874925 +vt 0.125000 0.875000 +vt 0.156269 0.999900 +vt 0.156259 0.937550 +vt 0.156250 1.000000 +vt 0.156269 0.749950 +vt 0.156269 0.812438 +vt 0.156250 0.875000 +vt 0.156269 0.937413 +vt 0.156269 0.874925 +vt 0.187513 0.999900 +vt 0.187506 0.937550 +vt 0.187500 0.875000 +vt 0.187500 1.000000 +vt 0.187513 0.749950 +vt 0.187513 0.812438 +vt 0.187513 0.937413 +vt 0.218750 0.875000 +vt 0.187513 0.874925 +vt 0.218756 0.999900 +vt 0.218753 0.937550 +vt 0.218750 1.000000 +vt 0.218756 0.749950 +vt 0.250000 0.875000 +vt 0.218756 0.812438 +vt 0.218756 0.937413 +vt 0.218756 0.874925 +vt 0.281250 0.875000 +vt 0.250000 0.999900 +vt 0.250000 0.937550 +vt 0.250000 1.000000 +vt 0.250000 0.749950 +vt 0.250000 0.812438 +vt 0.312500 0.875000 +vt 0.250000 0.937413 +vt 0.250000 0.874925 +vt 0.281244 0.999900 +vt 0.281247 0.937550 +vt 0.343750 0.875000 +vt 0.281250 1.000000 +vt 0.281244 0.749950 +vt 0.281244 0.812438 +vt 0.281244 0.937413 +vt 0.375000 0.875000 +vt 0.281244 0.874925 +vt 0.312488 0.999900 +vt 0.312494 0.937550 +vt 0.312500 1.000000 +vt 0.312488 0.749950 +vt 0.406250 0.875000 +vt 0.312488 0.812438 +vt 0.312488 0.937413 +vt 0.312488 0.874925 +vt 0.437500 0.875000 +vt 0.343731 0.999900 +vt 0.343741 0.937550 +vt 0.343750 1.000000 +vt 0.343731 0.749950 +vt 0.343731 0.812438 +vt 0.468750 0.875000 +vt 0.343731 0.937413 +vt 0.343731 0.874925 +vt 0.187500 0.937500 +vt 0.218750 0.937500 +vt 0.250000 0.937500 +vt 0.281250 0.937500 +vt 0.312500 0.937500 +vt 0.343750 0.937500 +vt 0.375000 0.937500 +vt 0.406250 0.937500 +vt 0.437500 0.937500 +vt 0.468750 0.937500 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.062538 0.812438 +vt 0.062538 0.749950 +vt 0.062500 1.000000 +vt 0.062537 0.999900 +vt 0.062519 0.937551 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.031294 0.812438 +vt 0.031294 0.749950 +vt 0.031250 1.000000 +vt 0.031294 0.999900 +vt 0.031272 0.937551 +vt 0.374975 0.999900 +vt 0.374987 0.937550 +vt 0.406219 0.999900 +vt 0.406234 0.937550 +vt 0.437463 0.999900 +vt 0.437481 0.937550 +vt 0.468706 0.999900 +vt 0.468728 0.937550 +vt 0.499950 0.999900 +vt 0.499975 0.937550 +vt 0.125000 0.750000 +vt 0.062500 0.750000 +vt 0.499950 0.874925 +vt 0.093750 0.750000 +vt 0.499950 0.937413 +vt 0.031250 0.750000 +vt 0.499950 0.812438 +vt 0.000000 0.750000 +vt 0.500000 1.000000 +vt 0.499950 0.749950 +vt 0.000050 0.812438 +vt 0.093750 0.750000 +vt 0.000050 0.749950 +vt 0.125000 0.750000 +vt 0.000000 1.000000 +vt 0.000050 0.874925 +vt 0.062500 0.750000 +vt 0.000050 0.937413 +vt 0.031250 0.750000 +vt 0.000050 0.999900 +vt 0.000025 0.937551 +vt 0.000000 0.750000 +vt 0.374975 0.937413 +vt 0.375000 1.000000 +vt 0.374975 0.749950 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.406219 0.937413 +vt 0.406250 1.000000 +vt 0.406219 0.749950 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.437463 0.937413 +vt 0.437500 1.000000 +vt 0.437463 0.749950 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.468706 0.937413 +vt 0.468750 1.000000 +vt 0.468706 0.749950 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +vt 0.000050 0.812400 +vt 0.000025 0.812526 +vt 0.000000 0.500000 +vt 0.500000 0.890625 +vt 0.499975 0.812525 +vt 0.125000 0.500000 +vt 0.000050 0.749913 +vt 0.000050 0.874913 +vt 0.031250 0.500000 +vt 0.000050 0.937425 +vt 0.000050 0.812425 +vt 0.062500 0.500000 +vt 0.000050 0.999938 +vt 0.000050 0.874938 +vt 0.093750 0.500000 +vt 0.000050 0.937450 +vt 0.000000 0.750000 +vt 0.125000 0.500000 +vt 0.500000 0.984375 +vt 0.500000 0.750000 +vt 0.000000 0.500000 +vt 0.500000 1.000000 +vt 0.499950 0.874938 +vt 0.031250 0.500000 +vt 0.499950 0.937425 +vt 0.499950 0.812425 +vt 0.062500 0.500000 +vt 0.499950 0.874913 +vt 0.093750 0.500000 +vt 0.468750 0.890625 +vt 0.468728 0.812525 +vt 0.437500 0.890625 +vt 0.437481 0.812525 +vt 0.406250 0.890625 +vt 0.406234 0.812525 +vt 0.406250 0.953125 +vt 0.375000 0.890625 +vt 0.375000 0.953125 +vt 0.343750 0.890625 +vt 0.343750 0.953125 +vt 0.312500 0.890625 +vt 0.312500 0.953125 +vt 0.281250 0.890625 +vt 0.281250 0.953125 +vt 0.250000 0.890625 +vt 0.250000 0.953125 +vt 0.218750 0.890625 +vt 0.218750 0.953125 +vt 0.187500 0.890625 +vt 0.187500 0.953125 +vt 0.156250 0.890625 +vt 0.156250 0.953125 +vt 0.125000 0.890625 +vt 0.125000 0.953125 +vt 0.125013 0.812526 +vt 0.093750 0.890625 +vt 0.093766 0.812526 +vt 0.062500 0.890625 +vt 0.062519 0.812526 +vt 0.031294 0.812400 +vt 0.031250 0.890625 +vt 0.031272 0.812526 +vt 0.031294 0.937450 +vt 0.031250 0.750000 +vt 0.031294 0.874938 +vt 0.031294 0.999938 +vt 0.031250 0.906250 +vt 0.031294 0.937425 +vt 0.031294 0.812425 +vt 0.031250 0.921875 +vt 0.031250 0.890625 +vt 0.031294 0.749913 +vt 0.031294 0.874913 +vt 0.031250 0.906250 +vt 0.062538 0.937450 +vt 0.062500 0.921875 +vt 0.062500 0.750000 +vt 0.062538 0.999938 +vt 0.062500 0.937500 +vt 0.062500 0.906250 +vt 0.062500 0.921875 +vt 0.062500 0.890625 +vt 0.062500 0.875000 +vt 0.062500 0.906250 +vt 0.093750 0.921875 +vt 0.093750 0.750000 +vt 0.093750 0.937500 +vt 0.093750 0.906250 +vt 0.093750 0.921875 +vt 0.093750 0.890625 +vt 0.093750 0.875000 +vt 0.093750 0.906250 +vt 0.125000 0.921875 +vt 0.125000 0.750000 +vt 0.125000 0.937500 +vt 0.125000 0.937500 +vt 0.125000 0.906250 +vt 0.125000 0.921875 +vt 0.125000 0.890625 +vt 0.125000 0.875000 +vt 0.125000 0.906250 +vt 0.156250 0.921875 +vt 0.156250 0.937500 +vt 0.156250 0.937500 +vt 0.156250 0.906250 +vt 0.156250 0.921875 +vt 0.156250 0.890625 +vt 0.156250 0.875000 +vt 0.156250 0.906250 +vt 0.187500 0.921875 +vt 0.187500 0.937500 +vt 0.187500 0.937500 +vt 0.187500 0.906250 +vt 0.187500 0.921875 +vt 0.187500 0.890625 +vt 0.187500 0.875000 +vt 0.187500 0.906250 +vt 0.218750 0.921875 +vt 0.218750 0.937500 +vt 0.218750 0.937500 +vt 0.218750 0.906250 +vt 0.218750 0.921875 +vt 0.218750 0.890625 +vt 0.218750 0.875000 +vt 0.218750 0.906250 +vt 0.250000 0.921875 +vt 0.250000 0.937500 +vt 0.250000 0.937500 +vt 0.250000 0.906250 +vt 0.250000 0.921875 +vt 0.250000 0.890625 +vt 0.250000 0.875000 +vt 0.250000 0.906250 +vt 0.281250 0.921875 +vt 0.281250 0.937500 +vt 0.281250 0.937500 +vt 0.281250 0.906250 +vt 0.281250 0.921875 +vt 0.281250 0.890625 +vt 0.281250 0.875000 +vt 0.281250 0.906250 +vt 0.312500 0.921875 +vt 0.312500 0.937500 +vt 0.312500 0.937500 +vt 0.312500 0.906250 +vt 0.312500 0.921875 +vt 0.312500 0.890625 +vt 0.312500 0.875000 +vt 0.312500 0.906250 +vt 0.343750 0.921875 +vt 0.343750 0.937500 +vt 0.343750 0.937500 +vt 0.343750 0.906250 +vt 0.343750 0.921875 +vt 0.343750 0.890625 +vt 0.343750 0.875000 +vt 0.343750 0.906250 +vt 0.375000 0.921875 +vt 0.375000 0.937500 +vt 0.375000 0.937500 +vt 0.375000 0.906250 +vt 0.375000 0.921875 +vt 0.375000 0.890625 +vt 0.375000 0.875000 +vt 0.375000 0.906250 +vt 0.406250 0.921875 +vt 0.406250 0.937500 +vt 0.406250 0.750000 +vt 0.406250 0.937500 +vt 0.406250 0.906250 +vt 0.406250 0.921875 +vt 0.406250 0.890625 +vt 0.406250 0.875000 +vt 0.406250 0.906250 +vt 0.437500 0.921875 +vt 0.437463 0.937450 +vt 0.437500 0.750000 +vt 0.437500 0.937500 +vt 0.437463 0.999938 +vt 0.437500 0.906250 +vt 0.437500 0.921875 +vt 0.437500 0.890625 +vt 0.437500 0.875000 +vt 0.437500 0.906250 +vt 0.468706 0.937450 +vt 0.468750 0.984375 +vt 0.468750 0.750000 +vt 0.468750 0.906250 +vt 0.468750 1.000000 +vt 0.468706 0.874938 +vt 0.468750 0.921875 +vt 0.468750 0.890625 +vt 0.468706 0.937425 +vt 0.468706 0.812425 +vt 0.468750 0.906250 +vt 0.468706 0.874913 +vt 0.093750 0.562500 +vt 0.499975 0.875031 +vt 0.499975 0.750031 +vt 0.125000 0.562500 +vt 0.031272 0.875032 +vt 0.031272 0.750032 +vt 0.000025 0.875032 +vt 0.000025 0.750032 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.093750 0.562500 +vt 0.000000 0.812500 +vt 0.125000 0.562500 +vt 0.500000 0.812500 +vt 0.000000 0.562500 +vt 0.031250 0.562500 +vt 0.062500 0.562500 +vt 0.468728 0.875031 +vt 0.468728 0.750031 +vt 0.437481 0.875031 +vt 0.437481 0.750031 +vt 0.406234 0.875031 +vt 0.406234 0.750031 +vt 0.406250 0.937500 +vt 0.374988 0.875031 +vt 0.375000 0.937500 +vt 0.343750 0.968750 +vt 0.343741 0.875031 +vt 0.343750 0.937500 +vt 0.312500 0.968750 +vt 0.312500 0.937500 +vt 0.281250 0.968750 +vt 0.281250 0.937500 +vt 0.250000 0.875032 +vt 0.250000 0.968750 +vt 0.250000 0.937500 +vt 0.218753 0.875032 +vt 0.218750 0.937500 +vt 0.187500 0.968750 +vt 0.187506 0.875032 +vt 0.187500 0.937500 +vt 0.156250 0.968750 +vt 0.156250 0.937500 +vt 0.125000 0.968750 +vt 0.125013 0.875032 +vt 0.125000 0.937500 +vt 0.125013 0.750032 +vt 0.093766 0.875032 +vt 0.093766 0.750032 +vt 0.062519 0.875032 +vt 0.062519 0.750032 +vt 0.031250 0.812500 +vt 0.156250 0.937500 +vt 0.062500 0.812500 +vt 0.125000 0.937500 +vt 0.093750 0.812500 +vt 0.125000 0.812500 +vt 0.125000 0.953125 +vt 0.093750 0.937500 +vt 0.156250 0.953125 +vt 0.062500 0.937500 +vt 0.187500 0.812500 +vt 0.187500 0.953125 +vt 0.031250 0.937500 +vt 0.218750 0.812500 +vt 0.218750 0.953125 +vt 0.062519 0.875044 +vt 0.062519 1.000044 +vt 0.093766 0.875044 +vt 0.093766 1.000044 +vt 0.250000 0.812500 +vt 0.250000 0.953125 +vt 0.125012 0.875044 +vt 0.125012 1.000044 +vt 0.156259 0.875044 +vt 0.156259 1.000044 +vt 0.187506 0.875044 +vt 0.187506 1.000044 +vt 0.281250 0.953125 +vt 0.218753 0.875044 +vt 0.218753 1.000044 +vt 0.250000 0.875044 +vt 0.250000 1.000044 +vt 0.281247 0.875044 +vt 0.281247 1.000044 +vt 0.312500 0.953125 +vt 0.312494 0.875044 +vt 0.312494 1.000044 +vt 0.343741 0.875044 +vt 0.343741 1.000044 +vt 0.374987 0.875044 +vt 0.374987 1.000044 +vt 0.343750 0.812500 +vt 0.343750 0.953125 +vt 0.406234 0.875044 +vt 0.406234 1.000044 +vt 0.437481 0.875044 +vt 0.437481 1.000044 +vt 0.468728 0.875044 +vt 0.468728 1.000044 +vt 0.375000 0.812500 +vt 0.375000 0.953125 +vt 0.062500 0.687500 +vt 0.031250 0.687500 +vt 0.000000 0.687500 +vt 0.500000 0.937500 +vt 0.406250 0.953125 +vt 0.406250 0.812500 +vt 0.125000 0.687500 +vt 0.000000 0.937500 +vt 0.093750 0.687500 +vt 0.062500 0.687500 +vt 0.437500 0.812500 +vt 0.031250 0.687500 +vt 0.000025 0.875044 +vt 0.000025 1.000044 +vt 0.000000 0.687500 +vt 0.031272 0.875044 +vt 0.031272 1.000044 +vt 0.468750 0.812500 +vt 0.499975 0.875044 +vt 0.499975 1.000044 +vt 0.125000 0.687500 +vt 0.093750 0.687500 +vt 0.093750 0.625000 +vt 0.499975 0.812538 +vt 0.125000 0.625000 +vt 0.499975 0.937538 +vt 0.031272 0.812538 +vt 0.031272 0.937538 +vt 0.000025 0.812538 +vt 0.000000 0.625000 +vt 0.000025 0.937538 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.093750 0.625000 +vt 0.125000 0.625000 +vt 0.000000 0.875000 +vt 0.000000 0.625000 +vt 0.500000 0.875000 +vt 0.031250 0.625000 +vt 0.062500 0.625000 +vt 0.468728 0.812538 +vt 0.468728 0.937538 +vt 0.437481 0.812538 +vt 0.437481 0.937538 +vt 0.406234 0.812538 +vt 0.406234 0.937538 +vt 0.374988 0.812538 +vt 0.374988 0.937538 +vt 0.343750 0.953125 +vt 0.343741 0.812538 +vt 0.343741 0.937538 +vt 0.312500 0.953125 +vt 0.312494 0.937538 +vt 0.281250 0.953125 +vt 0.281247 0.937538 +vt 0.250000 0.812538 +vt 0.250000 0.953125 +vt 0.250000 0.937538 +vt 0.218753 0.812538 +vt 0.218753 0.937538 +vt 0.187500 0.953125 +vt 0.187506 0.812538 +vt 0.187506 0.937538 +vt 0.156250 0.953125 +vt 0.156259 0.937538 +vt 0.125000 0.953125 +vt 0.125013 0.812538 +vt 0.125013 0.937538 +vt 0.093766 0.812538 +vt 0.093766 0.937538 +vt 0.062519 0.812538 +vt 0.062519 0.937538 +vt 0.093781 0.999900 +vt 0.093766 0.937550 +vt 0.031250 0.875000 +vt 0.093750 1.000000 +vt 0.093781 0.749950 +vt 0.093781 0.812438 +vt 0.093781 0.937413 +vt 0.062500 0.875000 +vt 0.093781 0.874925 +vt 0.125025 0.999900 +vt 0.125012 0.937550 +vt 0.125000 1.000000 +vt 0.125025 0.749950 +vt 0.093750 0.875000 +vt 0.125025 0.812438 +vt 0.125025 0.937413 +vt 0.125025 0.874925 +vt 0.125000 0.968750 +vt 0.125000 0.875000 +vt 0.156269 0.999900 +vt 0.156259 0.937550 +vt 0.156250 1.000000 +vt 0.156269 0.749950 +vt 0.156269 0.812438 +vt 0.156250 0.968750 +vt 0.156250 0.875000 +vt 0.156269 0.937413 +vt 0.156269 0.874925 +vt 0.187513 0.999900 +vt 0.187506 0.937550 +vt 0.187500 0.968750 +vt 0.187500 0.875000 +vt 0.187500 1.000000 +vt 0.187513 0.749950 +vt 0.187513 0.812438 +vt 0.187513 0.937413 +vt 0.218750 0.875000 +vt 0.187513 0.874925 +vt 0.218756 0.999900 +vt 0.218753 0.937550 +vt 0.218750 1.000000 +vt 0.218756 0.749950 +vt 0.250000 0.968750 +vt 0.250000 0.875000 +vt 0.218756 0.812438 +vt 0.218756 0.937413 +vt 0.218756 0.874925 +vt 0.281250 0.968750 +vt 0.281250 0.875000 +vt 0.250000 0.999900 +vt 0.250000 0.937550 +vt 0.250000 1.000000 +vt 0.250000 0.749950 +vt 0.250000 0.812438 +vt 0.312500 0.968750 +vt 0.312500 0.875000 +vt 0.250000 0.937413 +vt 0.250000 0.874925 +vt 0.281244 0.999900 +vt 0.281247 0.937550 +vt 0.343750 0.968750 +vt 0.343750 0.875000 +vt 0.281250 1.000000 +vt 0.281244 0.749950 +vt 0.281244 0.812438 +vt 0.281244 0.937413 +vt 0.375000 0.875000 +vt 0.281244 0.874925 +vt 0.312488 0.999900 +vt 0.312494 0.937550 +vt 0.312500 1.000000 +vt 0.312488 0.749950 +vt 0.406250 0.875000 +vt 0.312488 0.812438 +vt 0.312488 0.937413 +vt 0.312488 0.874925 +vt 0.437500 0.875000 +vt 0.343731 0.999900 +vt 0.343741 0.937550 +vt 0.343750 1.000000 +vt 0.343731 0.749950 +vt 0.343731 0.812438 +vt 0.468750 0.875000 +vt 0.343731 0.937413 +vt 0.343731 0.874925 +vt 0.187500 0.937500 +vt 0.218750 0.937500 +vt 0.250000 0.937500 +vt 0.281250 0.937500 +vt 0.312500 0.937500 +vt 0.343750 0.937500 +vt 0.375000 0.937500 +vt 0.406250 0.937500 +vt 0.437500 0.937500 +vt 0.468750 0.937500 +vt 0.062537 0.874925 +vt 0.062537 0.937413 +vt 0.062538 0.812438 +vt 0.062538 0.749950 +vt 0.062500 1.000000 +vt 0.062537 0.999900 +vt 0.062519 0.937551 +vt 0.031294 0.874925 +vt 0.031294 0.937413 +vt 0.031294 0.812438 +vt 0.031294 0.749950 +vt 0.031250 1.000000 +vt 0.031294 0.999900 +vt 0.031272 0.937551 +vt 0.374975 0.999900 +vt 0.374987 0.937550 +vt 0.406219 0.999900 +vt 0.406234 0.937550 +vt 0.437463 0.999900 +vt 0.437481 0.937550 +vt 0.468706 0.999900 +vt 0.468728 0.937550 +vt 0.499950 0.999900 +vt 0.499975 0.937550 +vt 0.125000 0.750000 +vt 0.062500 0.750000 +vt 0.499950 0.874925 +vt 0.093750 0.750000 +vt 0.499950 0.937413 +vt 0.031250 0.750000 +vt 0.499950 0.812438 +vt 0.000000 0.750000 +vt 0.500000 1.000000 +vt 0.499950 0.749950 +vt 0.000050 0.812438 +vt 0.093750 0.750000 +vt 0.000050 0.749950 +vt 0.125000 0.750000 +vt 0.000000 1.000000 +vt 0.000050 0.874925 +vt 0.062500 0.750000 +vt 0.000050 0.937413 +vt 0.031250 0.750000 +vt 0.000050 0.999900 +vt 0.000025 0.937551 +vt 0.000000 0.750000 +vt 0.374975 0.937413 +vt 0.375000 1.000000 +vt 0.374975 0.749950 +vt 0.374975 0.812438 +vt 0.374975 0.874925 +vt 0.406219 0.937413 +vt 0.406250 1.000000 +vt 0.406219 0.749950 +vt 0.406219 0.812438 +vt 0.406219 0.874925 +vt 0.437463 0.937413 +vt 0.437500 1.000000 +vt 0.437463 0.749950 +vt 0.437463 0.812438 +vt 0.437463 0.874925 +vt 0.468706 0.937413 +vt 0.468750 1.000000 +vt 0.468706 0.749950 +vt 0.468706 0.812438 +vt 0.468706 0.874925 +s 0 +usemtl campfire_log +f 85/131/1 11/25/1 2/4/1 10/23/1 +f 3/7/1 1/1/1 25/53/1 29/59/1 +f 29/59/1 25/53/1 24/51/1 33/65/1 +f 33/65/1 24/51/1 23/49/1 37/70/1 +f 37/70/1 23/49/1 22/47/1 41/75/1 +f 41/75/1 22/47/1 21/45/1 45/80/1 +f 45/80/1 21/45/1 20/43/1 49/85/1 +f 49/85/1 20/43/1 19/41/1 53/90/1 +f 53/90/1 19/41/1 18/39/1 57/95/1 +f 57/95/1 18/39/1 17/37/1 61/100/1 +f 61/100/1 17/37/1 16/35/1 65/105/1 +f 65/105/1 16/35/1 15/33/1 69/110/1 +f 69/110/1 15/33/1 14/31/1 73/115/1 +f 73/115/1 14/31/1 13/29/1 77/120/1 +f 77/120/1 13/29/1 12/27/1 81/126/1 +f 81/126/1 12/27/1 11/25/1 85/131/1 +f 6/13/1 5/11/1 27/57/1 26/55/1 +f 5/11/1 4/9/1 28/58/1 27/57/1 +f 4/9/1 3/7/1 29/59/1 28/58/1 +f 26/55/1 27/57/1 31/63/1 30/60/1 +f 27/57/1 28/58/1 32/64/1 31/63/1 +f 28/58/1 29/59/1 33/65/1 32/64/1 +f 30/60/1 31/63/1 35/68/1 34/66/1 +f 31/63/1 32/64/1 36/69/1 35/68/1 +f 32/64/1 33/65/1 37/70/1 36/69/1 +f 34/66/1 35/68/1 39/73/1 38/71/1 +f 35/68/1 36/69/1 40/74/1 39/73/1 +f 36/69/1 37/70/1 41/75/1 40/74/1 +f 38/71/1 39/73/1 43/78/1 42/76/1 +f 39/73/1 40/74/1 44/79/1 43/78/1 +f 40/74/1 41/75/1 45/80/1 44/79/1 +f 42/76/1 43/78/1 47/83/1 46/81/1 +f 43/78/1 44/79/1 48/84/1 47/83/1 +f 44/79/1 45/80/1 49/85/1 48/84/1 +f 46/81/1 47/83/1 51/88/1 50/86/1 +f 47/83/1 48/84/1 52/89/1 51/88/1 +f 48/84/1 49/85/1 53/90/1 52/89/1 +f 50/86/1 51/88/1 55/93/1 54/91/1 +f 51/88/1 52/89/1 56/94/1 55/93/1 +f 52/89/1 53/90/1 57/95/1 56/94/1 +f 54/91/1 55/93/1 59/98/1 58/96/1 +f 55/93/1 56/94/1 60/99/1 59/98/1 +f 56/94/1 57/95/1 61/100/1 60/99/1 +f 58/96/1 59/98/1 63/103/1 62/101/1 +f 59/98/1 60/99/1 64/104/1 63/103/1 +f 60/99/1 61/100/1 65/105/1 64/104/1 +f 62/101/1 63/103/1 67/108/1 66/106/1 +f 63/103/1 64/104/1 68/109/1 67/108/1 +f 64/104/1 65/105/1 69/110/1 68/109/1 +f 66/106/1 67/108/1 71/113/1 70/111/1 +f 67/108/1 68/109/1 72/114/1 71/113/1 +f 68/109/1 69/110/1 73/115/1 72/114/1 +f 70/111/1 71/113/1 75/118/1 74/116/1 +f 71/113/1 72/114/1 76/119/1 75/118/1 +f 72/114/1 73/115/1 77/120/1 76/119/1 +f 74/116/1 75/118/1 79/124/1 78/121/1 +f 75/118/1 76/119/1 80/125/1 79/124/1 +f 76/119/1 77/120/1 81/126/1 80/125/1 +f 78/121/1 79/124/1 83/129/1 82/127/1 +f 79/124/1 80/125/1 84/130/1 83/129/1 +f 80/125/1 81/126/1 85/131/1 84/130/1 +f 82/127/1 83/129/1 8/19/1 7/16/1 +f 83/129/1 84/130/1 9/21/1 8/19/1 +f 84/130/1 85/131/1 10/23/1 9/21/1 +f 95/148/2 96/149/2 166/274/2 165/273/2 +f 107/170/3 108/172/3 178/297/3 177/295/3 +f 116/189/4 118/192/4 198/327/4 194/320/4 +f 94/147/2 95/148/2 165/273/2 164/271/2 +f 149/245/4 153/252/4 238/385/4 234/379/4 +f 106/168/3 107/170/3 177/295/3 176/293/3 +f 92/143/5 93/145/5 163/269/5 162/268/5 +f 122/198/4 125/203/4 210/346/4 206/338/4 +f 105/166/3 106/168/3 176/293/3 175/291/3 +f 91/142/5 92/143/5 162/268/5 161/267/5 +f 104/164/3 105/166/3 175/291/3 174/289/3 +f 93/144/4 111/178/4 182/305/4 163/270/4 +f 133/217/4 137/224/4 222/361/4 218/356/4 +f 90/141/5 91/142/5 161/267/5 160/266/5 +f 103/162/3 104/164/3 174/289/3 173/287/3 +f 115/186/4 116/188/4 194/321/4 190/316/4 +f 89/140/5 90/141/5 160/266/5 159/264/5 +f 145/237/4 149/245/4 234/379/4 230/375/4 +f 102/160/3 103/162/3 173/287/3 172/285/3 +f 88/136/3 89/138/3 159/263/3 158/261/3 +f 120/195/4 122/198/4 206/338/4 202/333/4 +f 101/158/3 102/160/3 172/285/3 171/283/3 +f 86/132/2 87/135/2 157/259/2 156/257/2 +f 100/156/3 101/158/3 171/283/3 170/281/3 +f 129/210/4 133/217/4 218/356/4 214/350/4 +f 99/154/3 100/156/3 170/281/3 169/279/3 +f 113/182/4 115/186/4 190/316/4 186/310/4 +f 141/231/4 145/238/4 230/374/4 226/367/4 +f 98/152/3 99/154/3 169/279/3 168/277/3 +f 118/192/4 120/195/4 202/333/4 198/327/4 +f 97/150/3 98/152/3 168/277/3 167/275/3 +f 153/252/4 94/146/4 164/272/4 238/385/4 +f 110/176/3 88/136/3 158/261/3 180/301/3 +f 87/133/3 97/150/3 167/275/3 157/258/3 +f 125/203/4 129/210/4 214/350/4 210/346/4 +f 109/174/3 110/176/3 180/301/3 179/299/3 +f 96/149/2 86/132/2 156/257/2 166/274/2 +f 108/172/3 109/174/3 179/299/3 178/297/3 +f 111/178/4 113/182/4 186/310/4 182/305/4 +f 137/224/4 141/231/4 226/367/4 222/361/4 +f 9/22/2 10/24/2 86/132/2 96/149/2 +f 23/50/3 24/52/3 110/177/3 109/175/3 +f 54/92/4 58/97/4 129/210/4 125/203/4 +f 2/5/3 11/26/3 97/151/3 87/134/3 +f 24/52/3 25/54/3 88/137/3 110/177/3 +f 82/128/4 7/17/4 94/146/4 153/252/4 +f 11/26/3 12/28/3 98/153/3 97/151/3 +f 42/77/4 46/82/4 120/195/4 118/192/4 +f 12/28/3 13/30/3 99/155/3 98/153/3 +f 70/112/4 74/117/4 145/238/4 141/231/4 +f 30/61/4 34/67/4 115/187/4 113/181/4 +f 13/30/3 14/32/3 100/157/3 99/155/3 +f 58/97/4 62/102/4 133/217/4 129/210/4 +f 14/32/3 15/34/3 101/159/3 100/157/3 +f 10/24/2 2/6/2 87/135/2 86/132/2 +f 15/34/3 16/36/3 102/161/3 101/159/3 +f 46/82/4 50/87/4 122/198/4 120/195/4 +f 25/54/3 1/2/3 89/139/3 88/137/3 +f 16/36/3 17/38/3 103/163/3 102/161/3 +f 74/117/4 78/122/4 149/244/4 145/238/4 +f 1/3/5 3/8/5 90/141/5 89/140/5 +f 34/67/4 38/72/4 116/189/4 115/187/4 +f 17/38/3 18/40/3 104/165/3 103/163/3 +f 3/8/5 4/10/5 91/142/5 90/141/5 +f 62/102/4 66/107/4 137/224/4 133/217/4 +f 6/14/4 26/56/4 111/178/4 93/144/4 +f 18/40/3 19/42/3 105/167/3 104/165/3 +f 4/10/5 5/12/5 92/143/5 91/142/5 +f 19/42/3 20/44/3 106/169/3 105/167/3 +f 50/87/4 54/92/4 125/203/4 122/198/4 +f 5/12/5 6/15/5 93/145/5 92/143/5 +f 20/44/3 21/46/3 107/171/3 106/169/3 +f 78/123/4 82/128/4 153/252/4 149/245/4 +f 7/18/2 8/20/2 95/148/2 94/147/2 +f 38/72/4 42/77/4 118/192/4 116/189/4 +f 21/46/3 22/48/3 108/173/3 107/171/3 +f 8/20/2 9/22/2 96/149/2 95/148/2 +f 66/107/4 70/112/4 141/231/4 137/224/4 +f 26/56/4 30/62/4 113/182/4 111/178/4 +f 22/48/3 23/50/3 109/175/3 108/173/3 +f 287/472/6 267/439/6 265/433/6 264/431/6 +f 273/452/6 257/419/6 260/423/6 274/454/6 +f 257/419/6 252/412/6 255/416/6 260/423/6 +f 252/412/6 185/309/6 181/303/6 255/416/6 +f 185/309/6 192/318/6 188/312/6 181/303/6 +f 192/318/6 199/328/6 195/322/6 188/312/6 +f 199/328/6 205/337/6 201/330/6 195/322/6 +f 205/337/6 212/348/6 208/341/6 201/330/6 +f 212/348/6 219/357/6 215/351/6 208/341/6 +f 219/357/6 225/366/6 221/359/6 215/351/6 +f 225/366/6 232/377/6 228/370/6 221/359/6 +f 232/377/6 239/386/6 235/380/6 228/370/6 +f 239/386/6 275/457/6 261/425/6 235/380/6 +f 275/457/6 279/462/6 262/427/6 261/425/6 +f 279/462/6 283/467/6 263/429/6 262/427/6 +f 283/467/6 287/472/6 264/431/6 263/429/6 +f 271/447/6 259/421/6 258/420/6 270/445/6 +f 270/445/6 258/420/6 256/418/6 272/450/6 +f 272/450/6 256/418/6 257/419/6 273/452/6 +f 259/421/6 254/414/6 253/413/6 258/420/6 +f 258/420/6 253/413/6 251/411/6 256/418/6 +f 256/418/6 251/411/6 252/412/6 257/419/6 +f 254/414/6 183/307/6 184/308/6 253/413/6 +f 253/413/6 184/308/6 187/311/6 251/411/6 +f 177/296/3 178/298/3 126/204/3 127/206/3 +f 194/320/4 198/327/4 112/179/4 114/183/4 +f 164/271/2 165/273/2 143/233/2 144/235/2 +f 234/379/4 238/385/4 250/409/4 249/407/4 +f 176/294/3 177/296/3 127/206/3 128/208/3 +f 162/268/5 163/269/5 146/240/5 147/242/5 +f 206/339/4 210/345/4 243/393/4 242/391/4 +f 175/292/3 176/294/3 128/208/3 130/211/3 +f 161/267/5 162/268/5 147/242/5 148/243/5 +f 174/290/3 175/292/3 130/211/3 131/213/3 +f 163/270/4 182/305/4 121/196/4 146/239/4 +f 218/356/4 222/361/4 246/400/4 245/398/4 +f 160/266/5 161/267/5 148/243/5 150/246/5 +f 173/288/3 174/290/3 131/213/3 132/215/3 +f 190/316/4 194/321/4 114/184/4 117/190/4 +f 159/264/5 160/266/5 150/246/5 151/249/5 +f 230/375/4 234/379/4 249/407/4 248/405/4 +f 172/286/3 173/288/3 132/215/3 134/218/3 +f 158/262/3 159/265/3 151/247/3 152/250/3 +f 202/332/4 206/339/4 242/391/4 241/388/4 +f 171/284/3 172/286/3 134/218/3 135/220/3 +f 156/257/2 157/259/2 154/255/2 155/256/2 +f 170/282/3 171/284/3 135/220/3 136/222/3 +f 214/350/4 218/356/4 245/398/4 244/396/4 +f 169/280/3 170/282/3 136/222/3 138/225/3 +f 186/310/4 190/316/4 117/190/4 119/193/4 +f 226/368/4 230/375/4 248/405/4 247/403/4 +f 168/278/3 169/280/3 138/225/3 139/227/3 +f 198/327/4 202/333/4 241/389/4 112/179/4 +f 167/276/3 168/278/3 139/227/3 140/229/3 +f 238/385/4 164/272/4 144/234/4 250/409/4 +f 180/302/3 158/262/3 152/250/3 123/199/3 +f 157/260/3 167/276/3 140/229/3 154/253/3 +f 210/346/4 214/350/4 244/396/4 243/394/4 +f 179/300/3 180/302/3 123/199/3 124/201/3 +f 166/274/2 156/257/2 155/256/2 142/232/2 +f 182/305/4 186/310/4 119/193/4 121/196/4 +f 178/298/3 179/300/3 124/201/3 126/204/3 +f 222/362/4 226/368/4 247/403/4 246/401/4 +f 165/273/2 166/274/2 142/232/2 143/233/2 +f 131/214/3 130/212/3 208/342/3 215/352/3 +f 147/242/5 146/240/5 271/448/5 270/446/5 +f 114/185/4 112/180/4 196/324/4 189/314/4 +f 130/212/3 128/209/3 201/331/3 208/342/3 +f 249/408/4 250/410/4 288/473/4 284/468/4 +f 144/235/2 143/233/2 268/440/2 269/442/2 +f 128/209/3 127/207/3 195/323/3 201/331/3 +f 242/392/4 243/395/4 216/353/4 209/343/4 +f 143/233/2 142/232/2 266/436/2 268/440/2 +f 127/207/3 126/205/3 188/313/3 195/323/3 +f 146/241/4 121/197/4 259/422/4 271/449/4 +f 245/399/4 246/402/4 236/382/4 229/372/4 +f 126/205/3 124/202/3 181/304/3 188/313/3 +f 142/232/2 155/256/2 267/438/2 266/436/2 +f 117/191/4 114/185/4 189/314/4 183/306/4 +f 124/202/3 123/200/3 255/417/3 181/304/3 +f 248/406/4 249/408/4 284/468/4 280/463/4 +f 154/254/3 140/230/3 264/432/3 265/434/3 +f 123/200/3 152/251/3 260/424/3 255/417/3 +f 241/390/4 242/392/4 209/343/4 203/334/4 +f 140/230/3 139/228/3 263/430/3 264/432/3 +f 155/256/2 154/255/2 265/435/2 267/438/2 +f 139/228/3 138/226/3 262/428/3 263/430/3 +f 244/397/4 245/399/4 229/372/4 223/363/4 +f 152/251/3 151/248/3 274/455/3 260/424/3 +f 138/226/3 136/223/3 261/426/3 262/428/3 +f 119/194/4 117/191/4 183/306/4 254/415/4 +f 247/404/4 248/406/4 280/463/4 276/458/4 +f 136/223/3 135/221/3 235/381/3 261/426/3 +f 151/249/5 150/246/5 273/453/5 274/456/5 +f 112/180/4 241/390/4 203/334/4 196/324/4 +f 135/221/3 134/219/3 228/371/3 235/381/3 +f 250/410/4 144/236/4 269/443/4 288/473/4 +f 150/246/5 148/243/5 272/451/5 273/453/5 +f 134/219/3 132/216/3 221/360/3 228/371/3 +f 243/395/4 244/397/4 223/363/4 216/353/4 +f 148/243/5 147/242/5 270/446/5 272/451/5 +f 132/216/3 131/214/3 215/352/3 221/360/3 +f 121/197/4 119/194/4 254/415/4 259/422/4 +f 246/402/4 247/404/4 276/458/4 236/382/4 +f 251/411/6 187/311/6 185/309/6 252/412/6 +f 183/307/6 189/315/6 191/317/6 184/308/6 +f 184/308/6 191/317/6 193/319/6 187/311/6 +f 187/311/6 193/319/6 192/318/6 185/309/6 +f 189/315/6 196/325/6 197/326/6 191/317/6 +f 191/317/6 197/326/6 200/329/6 193/319/6 +f 193/319/6 200/329/6 199/328/6 192/318/6 +f 196/325/6 203/335/6 204/336/6 197/326/6 +f 197/326/6 204/336/6 207/340/6 200/329/6 +f 200/329/6 207/340/6 205/337/6 199/328/6 +f 203/335/6 209/344/6 211/347/6 204/336/6 +f 204/336/6 211/347/6 213/349/6 207/340/6 +f 207/340/6 213/349/6 212/348/6 205/337/6 +f 209/344/6 216/354/6 217/355/6 211/347/6 +f 211/347/6 217/355/6 220/358/6 213/349/6 +f 213/349/6 220/358/6 219/357/6 212/348/6 +f 216/354/6 223/364/6 224/365/6 217/355/6 +f 217/355/6 224/365/6 227/369/6 220/358/6 +f 220/358/6 227/369/6 225/366/6 219/357/6 +f 223/364/6 229/373/6 231/376/6 224/365/6 +f 224/365/6 231/376/6 233/378/6 227/369/6 +f 227/369/6 233/378/6 232/377/6 225/366/6 +f 229/373/6 236/383/6 237/384/6 231/376/6 +f 231/376/6 237/384/6 240/387/6 233/378/6 +f 233/378/6 240/387/6 239/386/6 232/377/6 +f 236/383/6 276/459/6 277/460/6 237/384/6 +f 237/384/6 277/460/6 278/461/6 240/387/6 +f 240/387/6 278/461/6 275/457/6 239/386/6 +f 276/459/6 280/464/6 281/465/6 277/460/6 +f 277/460/6 281/465/6 282/466/6 278/461/6 +f 278/461/6 282/466/6 279/462/6 275/457/6 +f 280/464/6 284/469/6 285/470/6 281/465/6 +f 281/465/6 285/470/6 286/471/6 282/466/6 +f 282/466/6 286/471/6 283/467/6 279/462/6 +f 284/469/6 288/474/6 289/475/6 285/470/6 +f 285/470/6 289/475/6 290/476/6 286/471/6 +f 286/471/6 290/476/6 287/472/6 283/467/6 +f 288/474/6 269/444/6 268/441/6 289/475/6 +f 289/475/6 268/441/6 266/437/6 290/476/6 +f 290/476/6 266/437/6 267/439/6 287/472/6 +f 527/849/6 485/771/6 484/768/6 528/850/6 +f 304/497/1 303/496/1 333/546/1 332/544/1 +f 303/496/1 302/495/1 334/547/1 333/546/1 +f 302/495/1 301/494/1 335/548/1 334/547/1 +f 301/494/1 300/493/1 336/549/1 335/548/1 +f 300/493/1 299/492/1 337/550/1 336/549/1 +f 299/492/1 298/491/1 338/551/1 337/550/1 +f 526/847/6 486/773/6 485/771/6 527/849/6 +f 525/845/6 487/775/6 486/773/6 526/847/6 +f 524/843/6 495/786/6 487/775/6 525/845/6 +f 523/842/6 496/788/6 495/786/6 524/843/6 +f 522/839/6 497/790/6 496/788/6 523/842/6 +f 520/835/6 527/849/6 528/850/6 521/837/6 +f 332/544/1 333/546/1 345/561/1 344/559/1 +f 333/546/1 334/547/1 346/562/1 345/561/1 +f 334/547/1 335/548/1 347/563/1 346/562/1 +f 335/548/1 336/549/1 348/564/1 347/563/1 +f 336/549/1 337/550/1 349/565/1 348/564/1 +f 337/550/1 338/551/1 350/566/1 349/565/1 +f 519/833/6 526/847/6 527/849/6 520/835/6 +f 518/831/6 525/846/6 526/848/6 519/834/6 +f 517/830/6 524/844/6 525/846/6 518/831/6 +f 516/828/6 523/841/6 524/844/6 517/830/6 +f 515/824/6 522/839/6 523/842/6 516/827/6 +f 513/819/6 520/835/6 521/837/6 514/821/6 +f 344/559/1 345/561/1 357/576/1 356/574/1 +f 345/561/1 346/562/1 358/577/1 357/576/1 +f 346/562/1 347/563/1 359/578/1 358/577/1 +f 347/563/1 348/564/1 360/579/1 359/578/1 +f 348/564/1 349/565/1 361/580/1 360/579/1 +f 349/565/1 350/566/1 362/581/1 361/580/1 +f 512/818/6 519/834/6 520/836/6 513/820/6 +f 291/477/6 518/831/6 519/834/6 512/818/6 +f 292/479/6 517/829/6 518/832/6 291/478/6 +f 293/481/6 516/828/6 517/830/6 292/480/6 +f 294/482/6 515/825/6 516/828/6 293/481/6 +f 296/486/6 513/820/6 514/822/6 295/484/6 +f 356/574/1 357/576/1 369/594/1 368/592/1 +f 357/576/1 358/577/1 370/595/1 369/594/1 +f 358/577/1 359/578/1 371/596/1 370/595/1 +f 359/578/1 360/579/1 372/597/1 371/596/1 +f 360/579/1 361/580/1 373/598/1 372/597/1 +f 361/580/1 362/581/1 374/599/1 373/598/1 +f 297/489/6 512/818/6 513/820/6 296/486/6 +f 305/500/6 291/477/6 512/818/6 297/489/6 +f 306/501/6 292/479/6 291/478/6 305/499/6 +f 307/503/6 293/481/6 292/480/6 306/502/6 +f 308/505/6 294/482/6 293/481/6 307/503/6 +f 310/510/6 296/486/6 295/484/6 309/508/6 +f 368/592/1 369/594/1 381/612/1 380/610/1 +f 369/594/1 370/595/1 382/613/1 381/612/1 +f 370/595/1 371/596/1 383/614/1 382/613/1 +f 371/596/1 372/597/1 384/615/1 383/614/1 +f 372/597/1 373/598/1 385/616/1 384/615/1 +f 373/598/1 374/599/1 386/617/1 385/616/1 +f 311/512/6 297/488/6 296/487/6 310/511/6 +f 312/514/6 305/500/6 297/489/6 311/513/6 +f 313/515/6 306/502/6 305/500/6 312/514/6 +f 314/517/6 307/503/6 306/502/6 313/515/6 +f 315/518/6 308/506/6 307/504/6 314/516/6 +f 317/524/6 310/510/6 309/508/6 316/521/6 +f 380/610/1 381/612/1 393/629/1 392/627/1 +f 381/612/1 382/613/1 394/630/1 393/629/1 +f 382/613/1 383/614/1 395/631/1 394/630/1 +f 383/614/1 384/615/1 396/632/1 395/631/1 +f 384/615/1 385/616/1 397/633/1 396/632/1 +f 385/616/1 386/617/1 398/634/1 397/633/1 +f 318/525/6 311/512/6 310/511/6 317/523/6 +f 319/527/6 312/514/6 311/513/6 318/526/6 +f 327/537/6 313/515/6 312/514/6 319/527/6 +f 328/538/6 314/517/6 313/515/6 327/537/6 +f 329/539/6 315/519/6 314/517/6 328/538/6 +f 331/543/6 317/524/6 316/521/6 330/541/6 +f 392/627/1 393/629/1 405/649/1 404/647/1 +f 393/629/1 394/630/1 406/650/1 405/649/1 +f 394/630/1 395/631/1 407/651/1 406/650/1 +f 395/631/1 396/632/1 408/652/1 407/651/1 +f 396/632/1 397/633/1 409/653/1 408/652/1 +f 397/633/1 398/634/1 410/654/1 409/653/1 +f 339/553/6 318/526/6 317/524/6 331/543/6 +f 340/554/6 319/527/6 318/526/6 339/553/6 +f 341/555/6 327/537/6 319/527/6 340/554/6 +f 342/556/6 328/538/6 327/537/6 341/555/6 +f 343/557/6 329/539/6 328/538/6 342/556/6 +f 352/570/6 331/543/6 330/541/6 351/568/6 +f 404/647/1 405/649/1 417/668/1 416/666/1 +f 405/649/1 406/650/1 418/669/1 417/668/1 +f 406/650/1 407/651/1 419/670/1 418/669/1 +f 407/651/1 408/652/1 420/671/1 419/670/1 +f 408/652/1 409/653/1 421/672/1 420/671/1 +f 409/653/1 410/654/1 422/673/1 421/672/1 +f 353/571/6 339/553/6 331/543/6 352/570/6 +f 354/572/6 340/554/6 339/553/6 353/571/6 +f 355/573/6 341/555/6 340/554/6 354/572/6 +f 363/583/6 342/556/6 341/555/6 355/573/6 +f 364/584/6 343/557/6 342/556/6 363/583/6 +f 366/590/6 352/570/6 351/568/6 365/586/6 +f 416/666/1 417/668/1 429/687/1 428/685/1 +f 417/668/1 418/669/1 430/688/1 429/687/1 +f 418/669/1 419/670/1 431/689/1 430/688/1 +f 419/670/1 420/671/1 432/690/1 431/689/1 +f 420/671/1 421/672/1 433/691/1 432/690/1 +f 421/672/1 422/673/1 434/692/1 433/691/1 +f 367/591/6 353/571/6 352/570/6 366/590/6 +f 375/601/6 354/572/6 353/571/6 367/591/6 +f 376/602/6 355/573/6 354/572/6 375/601/6 +f 377/605/6 363/583/6 355/573/6 376/602/6 +f 378/606/6 364/584/6 363/583/6 377/605/6 +f 387/619/6 366/589/6 365/587/6 379/608/6 +f 428/685/1 429/687/1 441/706/1 440/704/1 +f 429/687/1 430/688/1 442/707/1 441/706/1 +f 430/688/1 431/689/1 443/708/1 442/707/1 +f 431/689/1 432/690/1 444/709/1 443/708/1 +f 432/690/1 433/691/1 445/710/1 444/709/1 +f 433/691/1 434/692/1 446/711/1 445/710/1 +f 388/621/6 367/591/6 366/590/6 387/620/6 +f 389/622/6 375/601/6 367/591/6 388/621/6 +f 390/623/6 376/602/6 375/601/6 389/622/6 +f 391/625/6 377/604/6 376/603/6 390/624/6 +f 399/636/6 378/606/6 377/605/6 391/626/6 +f 401/641/6 387/619/6 379/608/6 400/638/6 +f 440/704/1 441/706/1 453/726/1 452/724/1 +f 441/706/1 442/707/1 454/727/1 453/726/1 +f 442/707/1 443/708/1 455/728/1 454/727/1 +f 443/708/1 444/709/1 456/729/1 455/728/1 +f 444/709/1 445/710/1 457/730/1 456/729/1 +f 445/710/1 446/711/1 458/731/1 457/730/1 +f 402/643/6 388/621/6 387/620/6 401/642/6 +f 403/646/6 389/622/6 388/621/6 402/643/6 +f 411/657/6 390/623/6 389/622/6 403/646/6 +f 412/659/6 391/625/6 390/624/6 411/656/6 +f 413/660/6 399/636/6 391/626/6 412/658/6 +f 415/665/6 401/642/6 400/639/6 414/663/6 +f 452/724/1 453/726/1 465/745/1 464/743/1 +f 453/726/1 454/727/1 466/746/1 465/745/1 +f 454/727/1 455/728/1 467/747/1 466/746/1 +f 455/728/1 456/729/1 468/748/1 467/747/1 +f 456/729/1 457/730/1 469/749/1 468/748/1 +f 457/730/1 458/731/1 470/750/1 469/749/1 +f 423/675/6 402/643/6 401/642/6 415/665/6 +f 424/677/6 403/645/6 402/644/6 423/676/6 +f 425/679/6 411/657/6 403/646/6 424/678/6 +f 426/681/6 412/658/6 411/657/6 425/679/6 +f 427/682/6 413/661/6 412/659/6 426/680/6 +f 436/698/6 415/665/6 414/663/6 435/694/6 +f 464/743/1 465/745/1 477/759/1 476/757/1 +f 465/745/1 466/746/1 478/760/1 477/759/1 +f 466/746/1 467/747/1 479/761/1 478/760/1 +f 467/747/1 468/748/1 480/762/1 479/761/1 +f 468/748/1 469/749/1 481/763/1 480/762/1 +f 469/749/1 470/750/1 482/764/1 481/763/1 +f 437/700/6 423/675/6 415/665/6 436/698/6 +f 438/701/6 424/677/6 423/676/6 437/699/6 +f 439/703/6 425/679/6 424/678/6 438/702/6 +f 447/713/6 426/681/6 425/679/6 439/703/6 +f 448/715/6 427/683/6 426/681/6 447/713/6 +f 450/721/6 436/697/6 435/695/6 449/718/6 +f 476/757/1 477/759/1 489/779/1 488/777/1 +f 477/759/1 478/760/1 490/780/1 489/779/1 +f 478/760/1 479/761/1 491/781/1 490/780/1 +f 479/761/1 480/762/1 492/782/1 491/781/1 +f 480/762/1 481/763/1 493/783/1 492/782/1 +f 481/763/1 482/764/1 494/784/1 493/783/1 +f 451/722/6 437/700/6 436/698/6 450/720/6 +f 459/733/6 438/702/6 437/700/6 451/722/6 +f 460/735/6 439/703/6 438/702/6 459/733/6 +f 461/737/6 447/713/6 439/703/6 460/735/6 +f 462/739/6 448/716/6 447/714/6 461/738/6 +f 471/752/6 450/721/6 449/718/6 463/741/6 +f 488/777/1 489/779/1 501/800/1 500/798/1 +f 489/779/1 490/780/1 502/801/1 501/800/1 +f 490/780/1 491/781/1 503/802/1 502/801/1 +f 491/781/1 492/782/1 504/803/1 503/802/1 +f 492/782/1 493/783/1 505/804/1 504/803/1 +f 493/783/1 494/784/1 506/805/1 505/804/1 +f 472/753/6 451/723/6 450/721/6 471/752/6 +f 473/754/6 459/734/6 451/723/6 472/753/6 +f 474/755/6 460/736/6 459/734/6 473/754/6 +f 475/756/6 461/738/6 460/736/6 474/755/6 +f 483/766/6 462/739/6 461/738/6 475/756/6 +f 510/813/6 471/752/6 463/741/6 511/815/6 +f 500/798/1 501/800/1 321/530/1 320/529/1 +f 501/800/1 502/801/1 322/531/1 321/530/1 +f 502/801/1 503/802/1 323/532/1 322/531/1 +f 503/802/1 504/803/1 324/533/1 323/532/1 +f 504/803/1 505/804/1 325/534/1 324/533/1 +f 505/804/1 506/805/1 326/536/1 325/534/1 +f 509/811/6 472/753/6 471/752/6 510/813/6 +f 508/809/6 473/754/6 472/753/6 509/811/6 +f 507/807/6 474/755/6 473/754/6 508/809/6 +f 499/796/6 475/756/6 474/755/6 507/807/6 +f 498/793/6 483/766/6 475/756/6 499/796/6 +f 299/492/2 300/493/2 509/812/2 510/814/2 +f 482/765/4 470/751/4 295/485/4 514/823/4 +f 362/582/4 350/567/4 449/719/4 435/696/4 +f 300/493/2 301/494/2 508/810/2 509/812/2 +f 404/648/3 416/667/3 364/585/3 378/607/3 +f 470/751/4 458/732/4 309/509/4 295/485/4 +f 301/494/2 302/495/2 507/808/2 508/810/2 +f 350/567/4 338/552/4 463/742/4 449/719/4 +f 392/628/3 404/648/3 378/607/3 399/637/3 +f 458/732/4 446/712/4 316/522/4 309/509/4 +f 302/495/2 303/496/2 499/797/2 507/808/2 +f 500/799/3 320/528/3 497/791/3 522/840/3 +f 338/552/4 298/490/4 511/816/4 463/742/4 +f 380/611/3 392/628/3 399/637/3 413/662/3 +f 303/496/2 304/497/2 498/794/2 499/797/2 +f 446/712/4 434/693/4 330/542/4 316/522/4 +f 488/778/3 500/799/3 522/840/3 515/826/3 +f 368/593/3 380/611/3 413/662/3 427/684/3 +f 434/693/4 422/674/4 351/569/4 330/542/4 +f 476/758/3 488/778/3 515/826/3 294/483/3 +f 356/575/3 368/593/3 427/684/3 448/717/3 +f 422/674/4 410/655/4 365/588/4 351/569/4 +f 464/744/3 476/758/3 294/483/3 308/507/3 +f 320/529/5 321/530/5 496/789/5 497/792/5 +f 344/560/3 356/575/3 448/717/3 462/740/3 +f 321/530/5 322/531/5 495/787/5 496/789/5 +f 410/655/4 398/635/4 379/609/4 365/588/4 +f 452/725/3 464/744/3 308/507/3 315/520/3 +f 326/535/4 506/806/4 528/851/4 484/769/4 +f 322/531/5 323/532/5 487/776/5 495/787/5 +f 332/545/3 344/560/3 462/740/3 483/767/3 +f 398/635/4 386/618/4 400/640/4 379/609/4 +f 440/705/3 452/725/3 315/520/3 329/540/3 +f 323/532/5 324/533/5 486/774/5 487/776/5 +f 506/806/4 494/785/4 521/838/4 528/851/4 +f 304/498/3 332/545/3 483/767/3 498/795/3 +f 386/618/4 374/600/4 414/664/4 400/640/4 +f 324/533/5 325/534/5 485/772/5 486/774/5 +f 428/686/3 440/705/3 329/540/3 343/558/3 +f 494/785/4 482/765/4 514/823/4 521/838/4 +f 298/491/2 299/492/2 510/814/2 511/817/2 +f 325/534/5 326/536/5 484/770/5 485/772/5 +f 374/600/4 362/582/4 435/696/4 414/664/4 +f 416/667/3 428/686/3 343/558/3 364/585/3 +f 613/1046/1 539/881/1 530/855/1 538/879/1 +f 531/858/1 529/852/1 553/911/1 557/923/1 +f 557/924/1 553/912/1 552/909/1 561/934/1 +f 561/934/1 552/909/1 551/906/1 565/943/1 +f 565/943/1 551/906/1 550/904/1 569/951/1 +f 569/951/1 550/904/1 549/902/1 573/959/1 +f 573/959/1 549/902/1 548/900/1 577/967/1 +f 577/967/1 548/900/1 547/898/1 581/975/1 +f 581/975/1 547/898/1 546/896/1 585/983/1 +f 585/983/1 546/896/1 545/894/1 589/991/1 +f 589/991/1 545/894/1 544/892/1 593/999/1 +f 593/999/1 544/892/1 543/890/1 597/1007/1 +f 597/1007/1 543/890/1 542/887/1 601/1016/1 +f 601/1016/1 542/887/1 541/885/1 605/1024/1 +f 605/1024/1 541/885/1 540/883/1 609/1034/1 +f 609/1034/1 540/883/1 539/881/1 613/1046/1 +f 534/867/1 533/864/1 555/917/1 554/914/1 +f 533/865/1 532/861/1 556/919/1 555/916/1 +f 532/862/1 531/859/1 557/924/1 556/920/1 +f 554/914/1 555/917/1 559/929/1 558/926/1 +f 555/918/1 556/921/1 560/932/1 559/931/1 +f 556/922/1 557/925/1 561/935/1 560/933/1 +f 558/927/1 559/930/1 563/939/1 562/936/1 +f 559/931/1 560/932/1 564/941/1 563/940/1 +f 560/933/1 561/935/1 565/944/1 564/942/1 +f 562/936/1 563/939/1 567/947/1 566/945/1 +f 563/940/1 564/941/1 568/949/1 567/948/1 +f 564/942/1 565/944/1 569/952/1 568/950/1 +f 566/945/1 567/947/1 571/955/1 570/953/1 +f 567/948/1 568/949/1 572/957/1 571/956/1 +f 568/950/1 569/952/1 573/960/1 572/958/1 +f 570/953/1 571/955/1 575/963/1 574/961/1 +f 571/956/1 572/957/1 576/965/1 575/964/1 +f 572/958/1 573/960/1 577/968/1 576/966/1 +f 574/961/1 575/963/1 579/971/1 578/969/1 +f 575/964/1 576/965/1 580/973/1 579/972/1 +f 576/966/1 577/968/1 581/976/1 580/974/1 +f 578/969/1 579/971/1 583/979/1 582/977/1 +f 579/972/1 580/973/1 584/981/1 583/980/1 +f 580/974/1 581/976/1 585/984/1 584/982/1 +f 582/977/1 583/979/1 587/987/1 586/985/1 +f 583/980/1 584/981/1 588/989/1 587/988/1 +f 584/982/1 585/984/1 589/992/1 588/990/1 +f 586/985/1 587/987/1 591/995/1 590/993/1 +f 587/988/1 588/989/1 592/997/1 591/996/1 +f 588/990/1 589/992/1 593/1000/1 592/998/1 +f 590/993/1 591/995/1 595/1003/1 594/1001/1 +f 591/996/1 592/997/1 596/1005/1 595/1004/1 +f 592/998/1 593/1000/1 597/1008/1 596/1006/1 +f 594/1001/1 595/1003/1 599/1012/1 598/1009/1 +f 595/1004/1 596/1005/1 600/1014/1 599/1013/1 +f 596/1006/1 597/1008/1 601/1017/1 600/1015/1 +f 598/1009/1 599/1012/1 603/1020/1 602/1018/1 +f 599/1013/1 600/1014/1 604/1022/1 603/1021/1 +f 600/1015/1 601/1017/1 605/1025/1 604/1023/1 +f 602/1018/1 603/1020/1 607/1029/1 606/1026/1 +f 603/1021/1 604/1022/1 608/1032/1 607/1031/1 +f 604/1023/1 605/1025/1 609/1035/1 608/1033/1 +f 606/1027/1 607/1030/1 611/1039/1 610/1036/1 +f 607/1031/1 608/1032/1 612/1041/1 611/1038/1 +f 608/1033/1 609/1035/1 613/1045/1 612/1042/1 +f 610/1036/1 611/1039/1 536/873/1 535/870/1 +f 611/1040/1 612/1043/1 537/876/1 536/874/1 +f 612/1044/1 613/1046/1 538/879/1 537/877/1 +f 623/1062/3 624/1063/3 694/1179/3 693/1178/3 +f 635/1079/5 636/1081/5 706/1197/5 705/1196/5 +f 644/1097/2 646/1101/2 726/1227/2 722/1220/2 +f 622/1061/3 623/1062/3 693/1178/3 692/1176/3 +f 677/1152/2 681/1158/2 766/1293/2 762/1286/2 +f 634/1077/5 635/1079/5 705/1196/5 704/1195/5 +f 620/1055/4 621/1058/4 691/1173/4 690/1171/4 +f 650/1110/2 653/1114/2 738/1247/2 734/1240/2 +f 633/1076/5 634/1078/5 704/1194/5 703/1192/5 +f 619/1054/4 620/1055/4 690/1171/4 689/1170/4 +f 632/1075/5 633/1076/5 703/1192/5 702/1190/5 +f 621/1056/2 639/1086/2 710/1202/2 691/1172/2 +f 661/1125/2 665/1131/2 750/1267/2 746/1260/2 +f 618/1053/4 619/1054/4 689/1170/4 688/1169/4 +f 631/1072/5 632/1074/5 702/1191/5 701/1189/5 +f 643/1094/2 644/1097/2 722/1220/2 718/1215/2 +f 617/1052/4 618/1053/4 688/1169/4 687/1167/4 +f 673/1145/2 677/1152/2 762/1286/2 758/1281/2 +f 630/1070/5 631/1072/5 701/1189/5 700/1188/5 +f 616/1050/5 617/1051/5 687/1168/5 686/1166/5 +f 648/1106/2 650/1110/2 734/1240/2 730/1234/2 +f 629/1069/5 630/1071/5 700/1187/5 699/1185/5 +f 614/1047/3 615/1049/3 685/1164/3 684/1163/3 +f 628/1068/5 629/1069/5 699/1185/5 698/1183/5 +f 657/1120/2 661/1126/2 746/1261/2 742/1253/2 +f 627/1066/5 628/1067/5 698/1184/5 697/1182/5 +f 641/1090/2 643/1094/2 718/1215/2 714/1208/2 +f 669/1136/2 673/1145/2 758/1281/2 754/1273/2 +f 626/1065/5 627/1066/5 697/1182/5 696/1181/5 +f 646/1102/2 648/1106/2 730/1234/2 726/1228/2 +f 625/1064/5 626/1065/5 696/1181/5 695/1180/5 +f 681/1158/2 622/1059/2 692/1175/2 766/1293/2 +f 638/1085/5 616/1050/5 686/1166/5 708/1199/5 +f 615/1048/5 625/1064/5 695/1180/5 685/1165/5 +f 653/1115/2 657/1120/2 742/1253/2 738/1248/2 +f 637/1083/5 638/1085/5 708/1199/5 707/1198/5 +f 624/1063/3 614/1047/3 684/1163/3 694/1179/3 +f 636/1081/5 637/1083/5 707/1198/5 706/1197/5 +f 639/1086/2 641/1090/2 714/1208/2 710/1202/2 +f 665/1131/2 669/1137/2 754/1274/2 750/1267/2 +f 537/878/3 538/880/3 614/1047/3 624/1063/3 +f 551/907/5 552/910/5 638/1085/5 637/1083/5 +f 582/978/2 586/986/2 657/1121/2 653/1116/2 +f 530/856/5 539/882/5 625/1064/5 615/1048/5 +f 552/910/5 553/913/5 616/1050/5 638/1085/5 +f 610/1037/2 535/871/2 622/1060/2 681/1159/2 +f 539/882/5 540/884/5 626/1065/5 625/1064/5 +f 570/954/2 574/962/2 648/1107/2 646/1103/2 +f 540/884/5 541/886/5 627/1066/5 626/1065/5 +f 598/1010/2 602/1019/2 673/1146/2 669/1138/2 +f 558/928/2 562/937/2 643/1095/2 641/1091/2 +f 541/886/5 542/888/5 628/1067/5 627/1066/5 +f 586/986/2 590/994/2 661/1127/2 657/1121/2 +f 542/889/5 543/891/5 629/1069/5 628/1068/5 +f 538/880/3 530/857/3 615/1049/3 614/1047/3 +f 543/891/5 544/893/5 630/1071/5 629/1069/5 +f 574/962/2 578/970/2 650/1111/2 648/1107/2 +f 553/913/5 529/853/5 617/1051/5 616/1050/5 +f 544/893/5 545/895/5 631/1073/5 630/1071/5 +f 602/1019/2 606/1028/2 677/1153/2 673/1146/2 +f 529/854/4 531/860/4 618/1053/4 617/1052/4 +f 562/938/2 566/946/2 644/1098/2 643/1096/2 +f 545/895/5 546/897/5 632/1075/5 631/1073/5 +f 531/860/4 532/863/4 619/1054/4 618/1053/4 +f 590/994/2 594/1002/2 665/1132/2 661/1127/2 +f 534/868/2 554/915/2 639/1087/2 621/1057/2 +f 546/897/5 547/899/5 633/1076/5 632/1075/5 +f 532/863/4 533/866/4 620/1055/4 619/1054/4 +f 547/899/5 548/901/5 634/1078/5 633/1076/5 +f 578/970/2 582/978/2 653/1116/2 650/1111/2 +f 533/866/4 534/869/4 621/1058/4 620/1055/4 +f 548/901/5 549/903/5 635/1080/5 634/1078/5 +f 606/1028/2 610/1037/2 681/1159/2 677/1153/2 +f 535/872/3 536/875/3 623/1062/3 622/1061/3 +f 566/946/2 570/954/2 646/1103/2 644/1098/2 +f 549/903/5 550/905/5 636/1082/5 635/1080/5 +f 536/875/3 537/878/3 624/1063/3 623/1062/3 +f 594/1002/2 598/1011/2 669/1139/2 665/1132/2 +f 554/915/2 558/928/2 641/1091/2 639/1087/2 +f 550/905/5 551/908/5 637/1084/5 636/1082/5 +f 815/1378/6 795/1345/6 793/1339/6 792/1337/6 +f 801/1358/6 785/1325/6 788/1329/6 802/1360/6 +f 785/1325/6 780/1318/6 783/1322/6 788/1329/6 +f 780/1318/6 713/1207/6 709/1200/6 783/1322/6 +f 713/1207/6 720/1218/6 716/1211/6 709/1200/6 +f 720/1218/6 727/1230/6 723/1222/6 716/1211/6 +f 727/1230/6 733/1239/6 729/1232/6 723/1222/6 +f 733/1239/6 740/1251/6 736/1243/6 729/1232/6 +f 740/1251/6 747/1263/6 743/1255/6 736/1243/6 +f 747/1263/6 753/1272/6 749/1265/6 743/1255/6 +f 753/1272/6 760/1284/6 756/1277/6 749/1265/6 +f 760/1284/6 767/1295/6 763/1288/6 756/1277/6 +f 767/1295/6 803/1363/6 789/1331/6 763/1288/6 +f 803/1363/6 807/1368/6 790/1333/6 789/1331/6 +f 807/1368/6 811/1373/6 791/1335/6 790/1333/6 +f 811/1373/6 815/1378/6 792/1337/6 791/1335/6 +f 799/1353/6 787/1327/6 786/1326/6 798/1351/6 +f 798/1351/6 786/1326/6 784/1324/6 800/1356/6 +f 800/1356/6 784/1324/6 785/1325/6 801/1358/6 +f 787/1327/6 782/1320/6 781/1319/6 786/1326/6 +f 786/1326/6 781/1319/6 779/1317/6 784/1324/6 +f 784/1324/6 779/1317/6 780/1318/6 785/1325/6 +f 782/1320/6 711/1205/6 712/1206/6 781/1319/6 +f 781/1319/6 712/1206/6 715/1210/6 779/1317/6 +f 705/1196/5 706/1197/5 654/1117/5 655/1118/5 +f 722/1221/2 726/1229/2 640/1088/2 642/1092/2 +f 692/1176/3 693/1178/3 671/1141/3 672/1143/3 +f 762/1287/2 766/1294/2 778/1315/2 777/1313/2 +f 704/1195/5 705/1196/5 655/1118/5 656/1119/5 +f 690/1171/4 691/1173/4 674/1148/4 675/1150/4 +f 734/1241/2 738/1249/2 771/1301/2 770/1299/2 +f 703/1193/5 704/1195/5 656/1119/5 658/1122/5 +f 689/1170/4 690/1171/4 675/1150/4 676/1151/4 +f 702/1191/5 703/1193/5 658/1122/5 659/1123/5 +f 691/1174/2 710/1203/2 649/1108/2 674/1147/2 +f 746/1262/2 750/1268/2 774/1307/2 773/1305/2 +f 688/1169/4 689/1170/4 676/1151/4 678/1154/4 +f 701/1189/5 702/1191/5 659/1123/5 660/1124/5 +f 718/1216/2 722/1221/2 642/1092/2 645/1099/2 +f 687/1167/4 688/1169/4 678/1154/4 679/1156/4 +f 758/1282/2 762/1287/2 777/1313/2 776/1311/2 +f 700/1188/5 701/1189/5 660/1124/5 662/1128/5 +f 686/1166/5 687/1168/5 679/1155/5 680/1157/5 +f 730/1235/2 734/1241/2 770/1299/2 769/1297/2 +f 699/1186/5 700/1188/5 662/1128/5 663/1129/5 +f 684/1163/3 685/1164/3 682/1161/3 683/1162/3 +f 698/1184/5 699/1186/5 663/1129/5 664/1130/5 +f 742/1254/2 746/1262/2 773/1305/2 772/1303/2 +f 697/1182/5 698/1184/5 664/1130/5 666/1133/5 +f 714/1209/2 718/1216/2 645/1099/2 647/1104/2 +f 754/1275/2 758/1282/2 776/1311/2 775/1309/2 +f 696/1181/5 697/1182/5 666/1133/5 667/1134/5 +f 726/1229/2 730/1235/2 769/1297/2 640/1088/2 +f 695/1180/5 696/1181/5 667/1134/5 668/1135/5 +f 766/1294/2 692/1177/2 672/1142/2 778/1315/2 +f 708/1199/5 686/1166/5 680/1157/5 651/1112/5 +f 685/1165/5 695/1180/5 668/1135/5 682/1160/5 +f 738/1249/2 742/1254/2 772/1303/2 771/1301/2 +f 707/1198/5 708/1199/5 651/1112/5 652/1113/5 +f 694/1179/3 684/1163/3 683/1162/3 670/1140/3 +f 710/1203/2 714/1209/2 647/1104/2 649/1108/2 +f 706/1197/5 707/1198/5 652/1113/5 654/1117/5 +f 750/1268/2 754/1275/2 775/1309/2 774/1307/2 +f 693/1178/3 694/1179/3 670/1140/3 671/1141/3 +f 659/1123/5 658/1122/5 736/1244/5 743/1256/5 +f 675/1150/4 674/1148/4 799/1354/4 798/1352/4 +f 642/1093/2 640/1089/2 724/1224/2 717/1213/2 +f 658/1122/5 656/1119/5 729/1233/5 736/1244/5 +f 777/1314/2 778/1316/2 816/1379/2 812/1374/2 +f 672/1143/3 671/1141/3 796/1346/3 797/1348/3 +f 656/1119/5 655/1118/5 723/1223/5 729/1233/5 +f 770/1300/2 771/1302/2 744/1257/2 737/1245/2 +f 671/1141/3 670/1140/3 794/1342/3 796/1346/3 +f 655/1118/5 654/1117/5 716/1212/5 723/1223/5 +f 674/1149/2 649/1109/2 787/1328/2 799/1355/2 +f 773/1306/2 774/1308/2 764/1290/2 757/1279/2 +f 654/1117/5 652/1113/5 709/1201/5 716/1212/5 +f 670/1140/3 683/1162/3 795/1344/3 794/1342/3 +f 645/1100/2 642/1093/2 717/1213/2 711/1204/2 +f 652/1113/5 651/1112/5 783/1323/5 709/1201/5 +f 776/1312/2 777/1314/2 812/1374/2 808/1369/2 +f 682/1160/5 668/1135/5 792/1338/5 793/1340/5 +f 651/1112/5 680/1157/5 788/1330/5 783/1323/5 +f 769/1298/2 770/1300/2 737/1245/2 731/1236/2 +f 668/1135/5 667/1134/5 791/1336/5 792/1338/5 +f 683/1162/3 682/1161/3 793/1341/3 795/1344/3 +f 667/1134/5 666/1133/5 790/1334/5 791/1336/5 +f 772/1304/2 773/1306/2 757/1279/2 751/1269/2 +f 680/1157/5 679/1155/5 802/1361/5 788/1330/5 +f 666/1133/5 664/1130/5 789/1332/5 790/1334/5 +f 647/1105/2 645/1100/2 711/1204/2 782/1321/2 +f 775/1310/2 776/1312/2 808/1369/2 804/1364/2 +f 664/1130/5 663/1129/5 763/1289/5 789/1332/5 +f 679/1156/4 678/1154/4 801/1359/4 802/1362/4 +f 640/1089/2 769/1298/2 731/1236/2 724/1224/2 +f 663/1129/5 662/1128/5 756/1278/5 763/1289/5 +f 778/1316/2 672/1144/2 797/1349/2 816/1379/2 +f 678/1154/4 676/1151/4 800/1357/4 801/1359/4 +f 662/1128/5 660/1124/5 749/1266/5 756/1278/5 +f 771/1302/2 772/1304/2 751/1269/2 744/1257/2 +f 676/1151/4 675/1150/4 798/1352/4 800/1357/4 +f 660/1124/5 659/1123/5 743/1256/5 749/1266/5 +f 649/1109/2 647/1105/2 782/1321/2 787/1328/2 +f 774/1308/2 775/1310/2 804/1364/2 764/1290/2 +f 779/1317/6 715/1210/6 713/1207/6 780/1318/6 +f 711/1205/6 717/1214/6 719/1217/6 712/1206/6 +f 712/1206/6 719/1217/6 721/1219/6 715/1210/6 +f 715/1210/6 721/1219/6 720/1218/6 713/1207/6 +f 717/1214/6 724/1225/6 725/1226/6 719/1217/6 +f 719/1217/6 725/1226/6 728/1231/6 721/1219/6 +f 721/1219/6 728/1231/6 727/1230/6 720/1218/6 +f 724/1225/6 731/1237/6 732/1238/6 725/1226/6 +f 725/1226/6 732/1238/6 735/1242/6 728/1231/6 +f 728/1231/6 735/1242/6 733/1239/6 727/1230/6 +f 731/1237/6 737/1246/6 739/1250/6 732/1238/6 +f 732/1238/6 739/1250/6 741/1252/6 735/1242/6 +f 735/1242/6 741/1252/6 740/1251/6 733/1239/6 +f 737/1246/6 744/1258/6 745/1259/6 739/1250/6 +f 739/1250/6 745/1259/6 748/1264/6 741/1252/6 +f 741/1252/6 748/1264/6 747/1263/6 740/1251/6 +f 744/1258/6 751/1270/6 752/1271/6 745/1259/6 +f 745/1259/6 752/1271/6 755/1276/6 748/1264/6 +f 748/1264/6 755/1276/6 753/1272/6 747/1263/6 +f 751/1270/6 757/1280/6 759/1283/6 752/1271/6 +f 752/1271/6 759/1283/6 761/1285/6 755/1276/6 +f 755/1276/6 761/1285/6 760/1284/6 753/1272/6 +f 757/1280/6 764/1291/6 765/1292/6 759/1283/6 +f 759/1283/6 765/1292/6 768/1296/6 761/1285/6 +f 761/1285/6 768/1296/6 767/1295/6 760/1284/6 +f 764/1291/6 804/1365/6 805/1366/6 765/1292/6 +f 765/1292/6 805/1366/6 806/1367/6 768/1296/6 +f 768/1296/6 806/1367/6 803/1363/6 767/1295/6 +f 804/1365/6 808/1370/6 809/1371/6 805/1366/6 +f 805/1366/6 809/1371/6 810/1372/6 806/1367/6 +f 806/1367/6 810/1372/6 807/1368/6 803/1363/6 +f 808/1370/6 812/1375/6 813/1376/6 809/1371/6 +f 809/1371/6 813/1376/6 814/1377/6 810/1372/6 +f 810/1372/6 814/1377/6 811/1373/6 807/1368/6 +f 812/1375/6 816/1380/6 817/1381/6 813/1376/6 +f 813/1376/6 817/1381/6 818/1382/6 814/1377/6 +f 814/1377/6 818/1382/6 815/1378/6 811/1373/6 +f 816/1380/6 797/1350/6 796/1347/6 817/1381/6 +f 817/1381/6 796/1347/6 794/1343/6 818/1382/6 +f 818/1382/6 794/1343/6 795/1345/6 815/1378/6 +f 903/1496/1 829/1405/1 820/1386/1 828/1403/1 +f 821/1389/1 819/1383/1 843/1435/1 847/1440/1 +f 847/1440/1 843/1435/1 842/1432/1 851/1444/1 +f 851/1444/1 842/1432/1 841/1430/1 855/1448/1 +f 855/1448/1 841/1430/1 840/1428/1 859/1452/1 +f 859/1452/1 840/1428/1 839/1426/1 863/1456/1 +f 863/1456/1 839/1426/1 838/1424/1 867/1460/1 +f 867/1460/1 838/1424/1 837/1422/1 871/1464/1 +f 871/1464/1 837/1422/1 836/1420/1 875/1468/1 +f 875/1468/1 836/1420/1 835/1418/1 879/1472/1 +f 879/1472/1 835/1418/1 834/1416/1 883/1476/1 +f 883/1476/1 834/1416/1 833/1414/1 887/1480/1 +f 887/1480/1 833/1414/1 832/1412/1 891/1484/1 +f 891/1484/1 832/1412/1 831/1410/1 895/1488/1 +f 895/1488/1 831/1410/1 830/1407/1 899/1492/1 +f 899/1492/1 830/1407/1 829/1405/1 903/1496/1 +f 824/1395/1 823/1393/1 845/1438/1 844/1437/1 +f 823/1393/1 822/1391/1 846/1439/1 845/1438/1 +f 822/1391/1 821/1389/1 847/1440/1 846/1439/1 +f 844/1437/1 845/1438/1 849/1442/1 848/1441/1 +f 845/1438/1 846/1439/1 850/1443/1 849/1442/1 +f 846/1439/1 847/1440/1 851/1444/1 850/1443/1 +f 848/1441/1 849/1442/1 853/1446/1 852/1445/1 +f 849/1442/1 850/1443/1 854/1447/1 853/1446/1 +f 850/1443/1 851/1444/1 855/1448/1 854/1447/1 +f 852/1445/1 853/1446/1 857/1450/1 856/1449/1 +f 853/1446/1 854/1447/1 858/1451/1 857/1450/1 +f 854/1447/1 855/1448/1 859/1452/1 858/1451/1 +f 856/1449/1 857/1450/1 861/1454/1 860/1453/1 +f 857/1450/1 858/1451/1 862/1455/1 861/1454/1 +f 858/1451/1 859/1452/1 863/1456/1 862/1455/1 +f 860/1453/1 861/1454/1 865/1458/1 864/1457/1 +f 861/1454/1 862/1455/1 866/1459/1 865/1458/1 +f 862/1455/1 863/1456/1 867/1460/1 866/1459/1 +f 864/1457/1 865/1458/1 869/1462/1 868/1461/1 +f 865/1458/1 866/1459/1 870/1463/1 869/1462/1 +f 866/1459/1 867/1460/1 871/1464/1 870/1463/1 +f 868/1461/1 869/1462/1 873/1466/1 872/1465/1 +f 869/1462/1 870/1463/1 874/1467/1 873/1466/1 +f 870/1463/1 871/1464/1 875/1468/1 874/1467/1 +f 872/1465/1 873/1466/1 877/1470/1 876/1469/1 +f 873/1466/1 874/1467/1 878/1471/1 877/1470/1 +f 874/1467/1 875/1468/1 879/1472/1 878/1471/1 +f 876/1469/1 877/1470/1 881/1474/1 880/1473/1 +f 877/1470/1 878/1471/1 882/1475/1 881/1474/1 +f 878/1471/1 879/1472/1 883/1476/1 882/1475/1 +f 880/1473/1 881/1474/1 885/1478/1 884/1477/1 +f 881/1474/1 882/1475/1 886/1479/1 885/1478/1 +f 882/1475/1 883/1476/1 887/1480/1 886/1479/1 +f 884/1477/1 885/1478/1 889/1482/1 888/1481/1 +f 885/1478/1 886/1479/1 890/1483/1 889/1482/1 +f 886/1479/1 887/1480/1 891/1484/1 890/1483/1 +f 888/1481/1 889/1482/1 893/1486/1 892/1485/1 +f 889/1482/1 890/1483/1 894/1487/1 893/1486/1 +f 890/1483/1 891/1484/1 895/1488/1 894/1487/1 +f 892/1485/1 893/1486/1 897/1490/1 896/1489/1 +f 893/1486/1 894/1487/1 898/1491/1 897/1490/1 +f 894/1487/1 895/1488/1 899/1492/1 898/1491/1 +f 896/1489/1 897/1490/1 901/1494/1 900/1493/1 +f 897/1490/1 898/1491/1 902/1495/1 901/1494/1 +f 898/1491/1 899/1492/1 903/1496/1 902/1495/1 +f 900/1493/1 901/1494/1 826/1399/1 825/1397/1 +f 901/1494/1 902/1495/1 827/1401/1 826/1399/1 +f 902/1495/1 903/1496/1 828/1403/1 827/1401/1 +f 913/1513/2 914/1514/2 984/1624/2 983/1623/2 +f 925/1530/3 926/1531/3 996/1645/3 995/1644/3 +f 934/1542/4 936/1544/4 1016/1675/4 1012/1669/4 +f 912/1512/2 913/1513/2 983/1623/2 982/1621/2 +f 967/1595/4 971/1602/4 1056/1727/4 1052/1721/4 +f 924/1529/3 925/1530/3 995/1644/3 994/1642/3 +f 910/1508/5 911/1510/5 981/1619/5 980/1618/5 +f 940/1548/4 943/1553/4 1028/1691/4 1024/1685/4 +f 923/1528/3 924/1529/3 994/1642/3 993/1641/3 +f 909/1507/5 910/1508/5 980/1618/5 979/1617/5 +f 922/1527/3 923/1528/3 993/1641/3 992/1639/3 +f 911/1509/4 929/1537/4 1000/1654/4 981/1620/4 +f 951/1569/4 955/1578/4 1040/1706/4 1036/1701/4 +f 908/1506/5 909/1507/5 979/1617/5 978/1616/5 +f 921/1526/3 922/1527/3 992/1639/3 991/1637/3 +f 933/1541/4 934/1542/4 1012/1669/4 1008/1665/4 +f 907/1505/5 908/1506/5 978/1616/5 977/1614/5 +f 963/1590/4 967/1595/4 1052/1721/4 1048/1717/4 +f 920/1525/3 921/1526/3 991/1637/3 990/1636/3 +f 906/1501/3 907/1503/3 977/1613/3 976/1611/3 +f 938/1546/4 940/1548/4 1024/1685/4 1020/1680/4 +f 919/1524/3 920/1525/3 990/1636/3 989/1634/3 +f 904/1497/2 905/1500/2 975/1609/2 974/1607/2 +f 918/1523/3 919/1524/3 989/1634/3 988/1632/3 +f 947/1561/4 951/1569/4 1036/1701/4 1032/1695/4 +f 917/1520/3 918/1522/3 988/1631/3 987/1629/3 +f 931/1539/4 933/1541/4 1008/1665/4 1004/1659/4 +f 959/1585/4 963/1590/4 1048/1717/4 1044/1711/4 +f 916/1517/3 917/1520/3 987/1629/3 986/1627/3 +f 936/1544/4 938/1546/4 1020/1680/4 1016/1675/4 +f 915/1515/3 916/1517/3 986/1627/3 985/1625/3 +f 971/1602/4 912/1511/4 982/1622/4 1056/1727/4 +f 928/1534/3 906/1501/3 976/1611/3 998/1650/3 +f 905/1498/3 915/1515/3 985/1625/3 975/1608/3 +f 943/1553/4 947/1561/4 1032/1695/4 1028/1691/4 +f 927/1532/3 928/1534/3 998/1650/3 997/1647/3 +f 914/1514/2 904/1497/2 974/1607/2 984/1624/2 +f 926/1531/3 927/1533/3 997/1648/3 996/1645/3 +f 929/1537/4 931/1539/4 1004/1659/4 1000/1654/4 +f 955/1578/4 959/1585/4 1044/1711/4 1040/1706/4 +f 827/1402/2 828/1404/2 904/1497/2 914/1514/2 +f 841/1431/3 842/1433/3 928/1535/3 927/1533/3 +f 872/1465/4 876/1469/4 947/1561/4 943/1553/4 +f 820/1387/3 829/1406/3 915/1516/3 905/1499/3 +f 842/1434/3 843/1436/3 906/1502/3 928/1536/3 +f 900/1493/4 825/1397/4 912/1511/4 971/1602/4 +f 829/1406/3 830/1408/3 916/1518/3 915/1516/3 +f 860/1453/4 864/1457/4 938/1546/4 936/1544/4 +f 830/1409/3 831/1411/3 917/1521/3 916/1519/3 +f 888/1481/4 892/1485/4 963/1590/4 959/1585/4 +f 848/1441/4 852/1445/4 933/1541/4 931/1539/4 +f 831/1411/3 832/1413/3 918/1523/3 917/1521/3 +f 876/1469/4 880/1473/4 951/1569/4 947/1561/4 +f 832/1413/3 833/1415/3 919/1524/3 918/1523/3 +f 828/1404/2 820/1388/2 905/1500/2 904/1497/2 +f 833/1415/3 834/1417/3 920/1525/3 919/1524/3 +f 864/1457/4 868/1461/4 940/1548/4 938/1546/4 +f 843/1436/3 819/1384/3 907/1504/3 906/1502/3 +f 834/1417/3 835/1419/3 921/1526/3 920/1525/3 +f 892/1485/4 896/1489/4 967/1595/4 963/1590/4 +f 819/1385/5 821/1390/5 908/1506/5 907/1505/5 +f 852/1445/4 856/1449/4 934/1542/4 933/1541/4 +f 835/1419/3 836/1421/3 922/1527/3 921/1526/3 +f 821/1390/5 822/1392/5 909/1507/5 908/1506/5 +f 880/1473/4 884/1477/4 955/1578/4 951/1569/4 +f 824/1395/4 844/1437/4 929/1537/4 911/1509/4 +f 836/1421/3 837/1423/3 923/1528/3 922/1527/3 +f 822/1392/5 823/1394/5 910/1508/5 909/1507/5 +f 837/1423/3 838/1425/3 924/1529/3 923/1528/3 +f 868/1461/4 872/1465/4 943/1553/4 940/1548/4 +f 823/1394/5 824/1396/5 911/1510/5 910/1508/5 +f 838/1425/3 839/1427/3 925/1530/3 924/1529/3 +f 896/1489/4 900/1493/4 971/1602/4 967/1595/4 +f 825/1398/2 826/1400/2 913/1513/2 912/1512/2 +f 856/1449/4 860/1453/4 936/1544/4 934/1542/4 +f 839/1427/3 840/1429/3 926/1531/3 925/1530/3 +f 826/1400/2 827/1402/2 914/1514/2 913/1513/2 +f 884/1477/4 888/1481/4 959/1585/4 955/1578/4 +f 844/1437/4 848/1441/4 931/1539/4 929/1537/4 +f 840/1429/3 841/1431/3 927/1533/3 926/1531/3 +f 1105/1801/6 1085/1768/6 1083/1762/6 1082/1760/6 +f 1091/1781/6 1075/1748/6 1078/1752/6 1092/1783/6 +f 1075/1748/6 1070/1741/6 1073/1745/6 1078/1752/6 +f 1070/1741/6 1003/1658/6 999/1652/6 1073/1745/6 +f 1003/1658/6 1010/1667/6 1006/1661/6 999/1652/6 +f 1010/1667/6 1017/1676/6 1013/1670/6 1006/1661/6 +f 1017/1676/6 1023/1684/6 1019/1678/6 1013/1670/6 +f 1023/1684/6 1030/1693/6 1026/1687/6 1019/1678/6 +f 1030/1693/6 1037/1702/6 1033/1696/6 1026/1687/6 +f 1037/1702/6 1043/1710/6 1039/1704/6 1033/1696/6 +f 1043/1710/6 1050/1719/6 1046/1713/6 1039/1704/6 +f 1050/1719/6 1057/1728/6 1053/1722/6 1046/1713/6 +f 1057/1728/6 1093/1786/6 1079/1754/6 1053/1722/6 +f 1093/1786/6 1097/1791/6 1080/1756/6 1079/1754/6 +f 1097/1791/6 1101/1796/6 1081/1758/6 1080/1756/6 +f 1101/1796/6 1105/1801/6 1082/1760/6 1081/1758/6 +f 1089/1776/6 1077/1750/6 1076/1749/6 1088/1774/6 +f 1088/1774/6 1076/1749/6 1074/1747/6 1090/1779/6 +f 1090/1779/6 1074/1747/6 1075/1748/6 1091/1781/6 +f 1077/1750/6 1072/1743/6 1071/1742/6 1076/1749/6 +f 1076/1749/6 1071/1742/6 1069/1740/6 1074/1747/6 +f 1074/1747/6 1069/1740/6 1070/1741/6 1075/1748/6 +f 1072/1743/6 1001/1656/6 1002/1657/6 1071/1742/6 +f 1071/1742/6 1002/1657/6 1005/1660/6 1069/1740/6 +f 995/1643/3 996/1646/3 944/1554/3 945/1556/3 +f 1012/1669/4 1016/1675/4 930/1538/4 932/1540/4 +f 982/1621/2 983/1623/2 961/1587/2 962/1588/2 +f 1052/1721/4 1056/1727/4 1068/1739/4 1067/1738/4 +f 994/1642/3 995/1644/3 945/1557/3 946/1559/3 +f 980/1618/5 981/1619/5 964/1591/5 965/1593/5 +f 1024/1685/4 1028/1691/4 1061/1732/4 1060/1731/4 +f 993/1641/3 994/1642/3 946/1559/3 948/1562/3 +f 979/1617/5 980/1618/5 965/1593/5 966/1594/5 +f 992/1639/3 993/1641/3 948/1562/3 949/1564/3 +f 981/1620/4 1000/1654/4 939/1547/4 964/1592/4 +f 1036/1701/4 1040/1706/4 1064/1735/4 1063/1734/4 +f 978/1616/5 979/1617/5 966/1594/5 968/1596/5 +f 991/1638/3 992/1640/3 949/1565/3 950/1567/3 +f 1008/1665/4 1012/1669/4 932/1540/4 935/1543/4 +f 977/1614/5 978/1616/5 968/1596/5 969/1599/5 +f 1048/1717/4 1052/1721/4 1067/1738/4 1066/1737/4 +f 990/1635/3 991/1638/3 950/1567/3 952/1570/3 +f 976/1612/3 977/1615/3 969/1597/3 970/1600/3 +f 1020/1680/4 1024/1685/4 1060/1731/4 1059/1730/4 +f 989/1634/3 990/1636/3 952/1571/3 953/1573/3 +f 974/1607/2 975/1609/2 972/1605/2 973/1606/2 +f 988/1632/3 989/1634/3 953/1573/3 954/1575/3 +f 1032/1695/4 1036/1701/4 1063/1734/4 1062/1733/4 +f 987/1630/3 988/1633/3 954/1576/3 956/1579/3 +f 1004/1659/4 1008/1665/4 935/1543/4 937/1545/4 +f 1044/1711/4 1048/1717/4 1066/1737/4 1065/1736/4 +f 986/1628/3 987/1630/3 956/1579/3 957/1581/3 +f 1016/1675/4 1020/1680/4 1059/1730/4 930/1538/4 +f 985/1626/3 986/1628/3 957/1581/3 958/1583/3 +f 1056/1727/4 982/1622/4 962/1589/4 1068/1739/4 +f 998/1651/3 976/1612/3 970/1600/3 941/1549/3 +f 975/1610/3 985/1626/3 958/1583/3 972/1603/3 +f 1028/1691/4 1032/1695/4 1062/1733/4 1061/1732/4 +f 997/1649/3 998/1651/3 941/1549/3 942/1551/3 +f 984/1624/2 974/1607/2 973/1606/2 960/1586/2 +f 1000/1654/4 1004/1659/4 937/1545/4 939/1547/4 +f 996/1646/3 997/1649/3 942/1551/3 944/1554/3 +f 1040/1706/4 1044/1711/4 1065/1736/4 1064/1735/4 +f 983/1623/2 984/1624/2 960/1586/2 961/1587/2 +f 949/1566/3 948/1563/3 1026/1688/3 1033/1697/3 +f 965/1593/5 964/1591/5 1089/1777/5 1088/1775/5 +f 932/1540/4 930/1538/4 1014/1672/4 1007/1663/4 +f 948/1563/3 946/1560/3 1019/1679/3 1026/1688/3 +f 1067/1738/4 1068/1739/4 1106/1802/4 1102/1797/4 +f 962/1588/2 961/1587/2 1086/1769/2 1087/1771/2 +f 946/1560/3 945/1558/3 1013/1671/3 1019/1679/3 +f 1060/1731/4 1061/1732/4 1034/1698/4 1027/1689/4 +f 961/1587/2 960/1586/2 1084/1765/2 1086/1769/2 +f 945/1558/3 944/1555/3 1006/1662/3 1013/1671/3 +f 964/1592/4 939/1547/4 1077/1751/4 1089/1778/4 +f 1063/1734/4 1064/1735/4 1054/1724/4 1047/1715/4 +f 944/1555/3 942/1552/3 999/1653/3 1006/1662/3 +f 960/1586/2 973/1606/2 1085/1767/2 1084/1765/2 +f 935/1543/4 932/1540/4 1007/1663/4 1001/1655/4 +f 942/1552/3 941/1550/3 1073/1746/3 999/1653/3 +f 1066/1737/4 1067/1738/4 1102/1797/4 1098/1792/4 +f 972/1604/3 958/1584/3 1082/1761/3 1083/1763/3 +f 941/1550/3 970/1601/3 1078/1753/3 1073/1746/3 +f 1059/1730/4 1060/1731/4 1027/1689/4 1021/1681/4 +f 958/1584/3 957/1582/3 1081/1759/3 1082/1761/3 +f 973/1606/2 972/1605/2 1083/1764/2 1085/1767/2 +f 957/1582/3 956/1580/3 1080/1757/3 1081/1759/3 +f 1062/1733/4 1063/1734/4 1047/1715/4 1041/1707/4 +f 970/1601/3 969/1598/3 1092/1784/3 1078/1753/3 +f 956/1580/3 954/1577/3 1079/1755/3 1080/1757/3 +f 937/1545/4 935/1543/4 1001/1655/4 1072/1744/4 +f 1065/1736/4 1066/1737/4 1098/1792/4 1094/1787/4 +f 954/1577/3 953/1574/3 1053/1723/3 1079/1755/3 +f 969/1599/5 968/1596/5 1091/1782/5 1092/1785/5 +f 930/1538/4 1059/1730/4 1021/1681/4 1014/1672/4 +f 953/1574/3 952/1572/3 1046/1714/3 1053/1723/3 +f 1068/1739/4 962/1589/4 1087/1772/4 1106/1802/4 +f 968/1596/5 966/1594/5 1090/1780/5 1091/1782/5 +f 952/1572/3 950/1568/3 1039/1705/3 1046/1714/3 +f 1061/1732/4 1062/1733/4 1041/1707/4 1034/1698/4 +f 966/1594/5 965/1593/5 1088/1775/5 1090/1780/5 +f 950/1568/3 949/1566/3 1033/1697/3 1039/1705/3 +f 939/1547/4 937/1545/4 1072/1744/4 1077/1751/4 +f 1064/1735/4 1065/1736/4 1094/1787/4 1054/1724/4 +f 1069/1740/6 1005/1660/6 1003/1658/6 1070/1741/6 +f 1001/1656/6 1007/1664/6 1009/1666/6 1002/1657/6 +f 1002/1657/6 1009/1666/6 1011/1668/6 1005/1660/6 +f 1005/1660/6 1011/1668/6 1010/1667/6 1003/1658/6 +f 1007/1664/6 1014/1673/6 1015/1674/6 1009/1666/6 +f 1009/1666/6 1015/1674/6 1018/1677/6 1011/1668/6 +f 1011/1668/6 1018/1677/6 1017/1676/6 1010/1667/6 +f 1014/1673/6 1021/1682/6 1022/1683/6 1015/1674/6 +f 1015/1674/6 1022/1683/6 1025/1686/6 1018/1677/6 +f 1018/1677/6 1025/1686/6 1023/1684/6 1017/1676/6 +f 1021/1682/6 1027/1690/6 1029/1692/6 1022/1683/6 +f 1022/1683/6 1029/1692/6 1031/1694/6 1025/1686/6 +f 1025/1686/6 1031/1694/6 1030/1693/6 1023/1684/6 +f 1027/1690/6 1034/1699/6 1035/1700/6 1029/1692/6 +f 1029/1692/6 1035/1700/6 1038/1703/6 1031/1694/6 +f 1031/1694/6 1038/1703/6 1037/1702/6 1030/1693/6 +f 1034/1699/6 1041/1708/6 1042/1709/6 1035/1700/6 +f 1035/1700/6 1042/1709/6 1045/1712/6 1038/1703/6 +f 1038/1703/6 1045/1712/6 1043/1710/6 1037/1702/6 +f 1041/1708/6 1047/1716/6 1049/1718/6 1042/1709/6 +f 1042/1709/6 1049/1718/6 1051/1720/6 1045/1712/6 +f 1045/1712/6 1051/1720/6 1050/1719/6 1043/1710/6 +f 1047/1716/6 1054/1725/6 1055/1726/6 1049/1718/6 +f 1049/1718/6 1055/1726/6 1058/1729/6 1051/1720/6 +f 1051/1720/6 1058/1729/6 1057/1728/6 1050/1719/6 +f 1054/1725/6 1094/1788/6 1095/1789/6 1055/1726/6 +f 1055/1726/6 1095/1789/6 1096/1790/6 1058/1729/6 +f 1058/1729/6 1096/1790/6 1093/1786/6 1057/1728/6 +f 1094/1788/6 1098/1793/6 1099/1794/6 1095/1789/6 +f 1095/1789/6 1099/1794/6 1100/1795/6 1096/1790/6 +f 1096/1790/6 1100/1795/6 1097/1791/6 1093/1786/6 +f 1098/1793/6 1102/1798/6 1103/1799/6 1099/1794/6 +f 1099/1794/6 1103/1799/6 1104/1800/6 1100/1795/6 +f 1100/1795/6 1104/1800/6 1101/1796/6 1097/1791/6 +f 1102/1798/6 1106/1803/6 1107/1804/6 1103/1799/6 +f 1103/1799/6 1107/1804/6 1108/1805/6 1104/1800/6 +f 1104/1800/6 1108/1805/6 1105/1801/6 1101/1796/6 +f 1106/1803/6 1087/1773/6 1086/1770/6 1107/1804/6 +f 1107/1804/6 1086/1770/6 1084/1766/6 1108/1805/6 +f 1108/1805/6 1084/1766/6 1085/1768/6 1105/1801/6 +f 1193/2001/1 1119/1835/1 1110/1809/1 1118/1833/1 +f 1111/1812/1 1109/1806/1 1133/1865/1 1137/1877/1 +f 1137/1878/1 1133/1866/1 1132/1863/1 1141/1888/1 +f 1141/1888/1 1132/1863/1 1131/1861/1 1145/1896/1 +f 1145/1896/1 1131/1861/1 1130/1858/1 1149/1905/1 +f 1149/1905/1 1130/1858/1 1129/1856/1 1153/1913/1 +f 1153/1913/1 1129/1856/1 1128/1854/1 1157/1921/1 +f 1157/1921/1 1128/1854/1 1127/1852/1 1161/1929/1 +f 1161/1929/1 1127/1852/1 1126/1850/1 1165/1937/1 +f 1165/1937/1 1126/1850/1 1125/1848/1 1169/1945/1 +f 1169/1945/1 1125/1848/1 1124/1846/1 1173/1953/1 +f 1173/1953/1 1124/1846/1 1123/1844/1 1177/1961/1 +f 1177/1961/1 1123/1844/1 1122/1842/1 1181/1969/1 +f 1181/1969/1 1122/1842/1 1121/1839/1 1185/1978/1 +f 1185/1978/1 1121/1839/1 1120/1837/1 1189/1988/1 +f 1189/1988/1 1120/1837/1 1119/1835/1 1193/2001/1 +f 1114/1821/1 1113/1818/1 1135/1871/1 1134/1868/1 +f 1113/1819/1 1112/1815/1 1136/1873/1 1135/1870/1 +f 1112/1816/1 1111/1813/1 1137/1878/1 1136/1874/1 +f 1134/1868/1 1135/1871/1 1139/1883/1 1138/1880/1 +f 1135/1872/1 1136/1875/1 1140/1886/1 1139/1885/1 +f 1136/1876/1 1137/1879/1 1141/1889/1 1140/1887/1 +f 1138/1881/1 1139/1884/1 1143/1892/1 1142/1890/1 +f 1139/1885/1 1140/1886/1 1144/1894/1 1143/1893/1 +f 1140/1887/1 1141/1889/1 1145/1897/1 1144/1895/1 +f 1142/1890/1 1143/1892/1 1147/1901/1 1146/1898/1 +f 1143/1893/1 1144/1894/1 1148/1903/1 1147/1902/1 +f 1144/1895/1 1145/1897/1 1149/1906/1 1148/1904/1 +f 1146/1898/1 1147/1901/1 1151/1909/1 1150/1907/1 +f 1147/1902/1 1148/1903/1 1152/1911/1 1151/1910/1 +f 1148/1904/1 1149/1906/1 1153/1914/1 1152/1912/1 +f 1150/1907/1 1151/1909/1 1155/1917/1 1154/1915/1 +f 1151/1910/1 1152/1911/1 1156/1919/1 1155/1918/1 +f 1152/1912/1 1153/1914/1 1157/1922/1 1156/1920/1 +f 1154/1915/1 1155/1917/1 1159/1925/1 1158/1923/1 +f 1155/1918/1 1156/1919/1 1160/1927/1 1159/1926/1 +f 1156/1920/1 1157/1922/1 1161/1930/1 1160/1928/1 +f 1158/1923/1 1159/1925/1 1163/1933/1 1162/1931/1 +f 1159/1926/1 1160/1927/1 1164/1935/1 1163/1934/1 +f 1160/1928/1 1161/1930/1 1165/1938/1 1164/1936/1 +f 1162/1931/1 1163/1933/1 1167/1941/1 1166/1939/1 +f 1163/1934/1 1164/1935/1 1168/1943/1 1167/1942/1 +f 1164/1936/1 1165/1938/1 1169/1946/1 1168/1944/1 +f 1166/1939/1 1167/1941/1 1171/1949/1 1170/1947/1 +f 1167/1942/1 1168/1943/1 1172/1951/1 1171/1950/1 +f 1168/1944/1 1169/1946/1 1173/1954/1 1172/1952/1 +f 1170/1947/1 1171/1949/1 1175/1957/1 1174/1955/1 +f 1171/1950/1 1172/1951/1 1176/1959/1 1175/1958/1 +f 1172/1952/1 1173/1954/1 1177/1962/1 1176/1960/1 +f 1174/1955/1 1175/1957/1 1179/1965/1 1178/1963/1 +f 1175/1958/1 1176/1959/1 1180/1967/1 1179/1966/1 +f 1176/1960/1 1177/1962/1 1181/1970/1 1180/1968/1 +f 1178/1963/1 1179/1965/1 1183/1974/1 1182/1971/1 +f 1179/1966/1 1180/1967/1 1184/1976/1 1183/1975/1 +f 1180/1968/1 1181/1970/1 1185/1979/1 1184/1977/1 +f 1182/1971/1 1183/1974/1 1187/1983/1 1186/1980/1 +f 1183/1975/1 1184/1976/1 1188/1986/1 1187/1985/1 +f 1184/1977/1 1185/1979/1 1189/1989/1 1188/1987/1 +f 1186/1981/1 1187/1984/1 1191/1994/1 1190/1990/1 +f 1187/1985/1 1188/1986/1 1192/1996/1 1191/1993/1 +f 1188/1987/1 1189/1989/1 1193/2000/1 1192/1997/1 +f 1190/1991/1 1191/1994/1 1116/1827/1 1115/1824/1 +f 1191/1995/1 1192/1998/1 1117/1830/1 1116/1828/1 +f 1192/1999/1 1193/2001/1 1118/1833/1 1117/1831/1 +f 1203/2018/3 1204/2019/3 1274/2144/3 1273/2143/3 +f 1215/2044/5 1216/2046/5 1286/2170/5 1285/2168/5 +f 1224/2060/2 1226/2062/2 1306/2201/2 1302/2194/2 +f 1202/2017/3 1203/2018/3 1273/2143/3 1272/2141/3 +f 1257/2115/2 1261/2122/2 1346/2259/2 1342/2253/2 +f 1214/2041/5 1215/2044/5 1285/2168/5 1284/2165/5 +f 1200/2013/4 1201/2015/4 1271/2139/4 1270/2138/4 +f 1230/2067/2 1233/2073/2 1318/2220/2 1314/2213/2 +f 1213/2039/5 1214/2042/5 1284/2166/5 1283/2163/5 +f 1199/2012/4 1200/2013/4 1270/2138/4 1269/2137/4 +f 1212/2036/5 1213/2039/5 1283/2163/5 1282/2160/5 +f 1201/2014/2 1219/2054/2 1290/2179/2 1271/2140/2 +f 1241/2088/2 1245/2096/2 1330/2237/2 1326/2231/2 +f 1198/2011/4 1199/2012/4 1269/2137/4 1268/2136/4 +f 1211/2034/5 1212/2037/5 1282/2161/5 1281/2158/5 +f 1223/2058/2 1224/2059/2 1302/2195/2 1298/2190/2 +f 1197/2010/4 1198/2011/4 1268/2136/4 1267/2134/4 +f 1253/2110/2 1257/2115/2 1342/2253/2 1338/2249/2 +f 1210/2032/5 1211/2034/5 1281/2158/5 1280/2156/5 +f 1196/2006/5 1197/2008/5 1267/2133/5 1266/2131/5 +f 1228/2064/2 1230/2067/2 1314/2213/2 1310/2208/2 +f 1209/2029/5 1210/2032/5 1280/2156/5 1279/2153/5 +f 1194/2002/3 1195/2005/3 1265/2129/3 1264/2127/3 +f 1208/2027/5 1209/2030/5 1279/2154/5 1278/2151/5 +f 1237/2081/2 1241/2088/2 1326/2231/2 1322/2224/2 +f 1207/2024/5 1208/2027/5 1278/2151/5 1277/2149/5 +f 1221/2056/2 1223/2058/2 1298/2190/2 1294/2184/2 +f 1249/2103/2 1253/2110/2 1338/2249/2 1334/2243/2 +f 1206/2022/5 1207/2024/5 1277/2149/5 1276/2147/5 +f 1226/2062/2 1228/2065/2 1310/2207/2 1306/2201/2 +f 1205/2020/5 1206/2022/5 1276/2147/5 1275/2145/5 +f 1261/2122/2 1202/2016/2 1272/2142/2 1346/2259/2 +f 1218/2052/5 1196/2006/5 1266/2131/5 1288/2175/5 +f 1195/2003/5 1205/2020/5 1275/2145/5 1265/2128/5 +f 1233/2074/2 1237/2081/2 1322/2224/2 1318/2219/2 +f 1217/2050/5 1218/2052/5 1288/2175/5 1287/2173/5 +f 1204/2019/3 1194/2002/3 1264/2127/3 1274/2144/3 +f 1216/2047/5 1217/2050/5 1287/2173/5 1286/2171/5 +f 1219/2054/2 1221/2056/2 1294/2184/2 1290/2179/2 +f 1245/2095/2 1249/2103/2 1334/2243/2 1330/2238/2 +f 1117/1832/3 1118/1834/3 1194/2002/3 1204/2019/3 +f 1131/1862/5 1132/1864/5 1218/2053/5 1217/2051/5 +f 1162/1932/2 1166/1940/2 1237/2081/2 1233/2074/2 +f 1110/1810/5 1119/1836/5 1205/2021/5 1195/2004/5 +f 1132/1864/5 1133/1867/5 1196/2007/5 1218/2053/5 +f 1190/1992/2 1115/1825/2 1202/2016/2 1261/2122/2 +f 1119/1836/5 1120/1838/5 1206/2023/5 1205/2021/5 +f 1150/1908/2 1154/1916/2 1228/2065/2 1226/2062/2 +f 1120/1838/5 1121/1840/5 1207/2025/5 1206/2023/5 +f 1178/1964/2 1182/1972/2 1253/2109/2 1249/2104/2 +f 1138/1882/2 1142/1891/2 1223/2058/2 1221/2056/2 +f 1121/1841/5 1122/1843/5 1208/2028/5 1207/2026/5 +f 1166/1940/2 1170/1948/2 1241/2088/2 1237/2081/2 +f 1122/1843/5 1123/1845/5 1209/2031/5 1208/2028/5 +f 1118/1834/3 1110/1811/3 1195/2005/3 1194/2002/3 +f 1123/1845/5 1124/1847/5 1210/2033/5 1209/2031/5 +f 1154/1916/2 1158/1924/2 1230/2068/2 1228/2065/2 +f 1133/1867/5 1109/1807/5 1197/2009/5 1196/2007/5 +f 1124/1847/5 1125/1849/5 1211/2035/5 1210/2033/5 +f 1182/1973/2 1186/1982/2 1257/2115/2 1253/2110/2 +f 1109/1808/4 1111/1814/4 1198/2011/4 1197/2010/4 +f 1142/1891/2 1146/1899/2 1224/2059/2 1223/2058/2 +f 1125/1849/5 1126/1851/5 1212/2038/5 1211/2035/5 +f 1111/1814/4 1112/1817/4 1199/2012/4 1198/2011/4 +f 1170/1948/2 1174/1956/2 1245/2096/2 1241/2088/2 +f 1114/1822/2 1134/1869/2 1219/2054/2 1201/2014/2 +f 1126/1851/5 1127/1853/5 1213/2040/5 1212/2038/5 +f 1112/1817/4 1113/1820/4 1200/2013/4 1199/2012/4 +f 1127/1853/5 1128/1855/5 1214/2043/5 1213/2040/5 +f 1158/1924/2 1162/1932/2 1233/2074/2 1230/2068/2 +f 1113/1820/4 1114/1823/4 1201/2015/4 1200/2013/4 +f 1128/1855/5 1129/1857/5 1215/2045/5 1214/2043/5 +f 1186/1982/2 1190/1992/2 1261/2122/2 1257/2115/2 +f 1115/1826/3 1116/1829/3 1203/2018/3 1202/2017/3 +f 1146/1900/2 1150/1908/2 1226/2062/2 1224/2060/2 +f 1129/1857/5 1130/1859/5 1216/2048/5 1215/2045/5 +f 1116/1829/3 1117/1832/3 1204/2019/3 1203/2018/3 +f 1174/1956/2 1178/1964/2 1249/2104/2 1245/2096/2 +f 1134/1869/2 1138/1882/2 1221/2056/2 1219/2054/2 +f 1130/1860/5 1131/1862/5 1217/2051/5 1216/2049/5 +f 1395/2333/6 1375/2300/6 1373/2294/6 1372/2292/6 +f 1381/2313/6 1365/2280/6 1368/2284/6 1382/2315/6 +f 1365/2280/6 1360/2273/6 1363/2277/6 1368/2284/6 +f 1360/2273/6 1293/2183/6 1289/2177/6 1363/2277/6 +f 1293/2183/6 1300/2192/6 1296/2186/6 1289/2177/6 +f 1300/2192/6 1307/2203/6 1303/2196/6 1296/2186/6 +f 1307/2203/6 1313/2212/6 1309/2205/6 1303/2196/6 +f 1313/2212/6 1320/2222/6 1316/2215/6 1309/2205/6 +f 1320/2222/6 1327/2233/6 1323/2226/6 1316/2215/6 +f 1327/2233/6 1333/2242/6 1329/2235/6 1323/2226/6 +f 1333/2242/6 1340/2251/6 1336/2245/6 1329/2235/6 +f 1340/2251/6 1347/2260/6 1343/2254/6 1336/2245/6 +f 1347/2260/6 1383/2318/6 1369/2286/6 1343/2254/6 +f 1383/2318/6 1387/2323/6 1370/2288/6 1369/2286/6 +f 1387/2323/6 1391/2328/6 1371/2290/6 1370/2288/6 +f 1391/2328/6 1395/2333/6 1372/2292/6 1371/2290/6 +f 1379/2308/6 1367/2282/6 1366/2281/6 1378/2306/6 +f 1378/2306/6 1366/2281/6 1364/2279/6 1380/2311/6 +f 1380/2311/6 1364/2279/6 1365/2280/6 1381/2313/6 +f 1367/2282/6 1362/2275/6 1361/2274/6 1366/2281/6 +f 1366/2281/6 1361/2274/6 1359/2272/6 1364/2279/6 +f 1364/2279/6 1359/2272/6 1360/2273/6 1365/2280/6 +f 1362/2275/6 1291/2181/6 1292/2182/6 1361/2274/6 +f 1361/2274/6 1292/2182/6 1295/2185/6 1359/2272/6 +f 1285/2169/5 1286/2172/5 1234/2075/5 1235/2077/5 +f 1302/2195/2 1306/2202/2 1220/2055/2 1222/2057/2 +f 1272/2141/3 1273/2143/3 1251/2106/3 1252/2107/3 +f 1342/2253/2 1346/2259/2 1358/2271/2 1357/2270/2 +f 1284/2167/5 1285/2169/5 1235/2077/5 1236/2079/5 +f 1270/2138/4 1271/2139/4 1254/2111/4 1255/2113/4 +f 1314/2213/2 1318/2220/2 1351/2264/2 1350/2263/2 +f 1283/2164/5 1284/2167/5 1236/2079/5 1238/2082/5 +f 1269/2137/4 1270/2138/4 1255/2113/4 1256/2114/4 +f 1282/2162/5 1283/2164/5 1238/2082/5 1239/2084/5 +f 1271/2140/2 1290/2179/2 1229/2066/2 1254/2112/2 +f 1326/2232/2 1330/2238/2 1354/2267/2 1353/2266/2 +f 1268/2136/4 1269/2137/4 1256/2114/4 1258/2116/4 +f 1281/2159/5 1282/2162/5 1239/2084/5 1240/2086/5 +f 1298/2190/2 1302/2195/2 1222/2057/2 1225/2061/2 +f 1267/2134/4 1268/2136/4 1258/2116/4 1259/2119/4 +f 1338/2249/2 1342/2253/2 1357/2270/2 1356/2269/2 +f 1280/2157/5 1281/2159/5 1240/2086/5 1242/2089/5 +f 1266/2132/5 1267/2135/5 1259/2117/5 1260/2120/5 +f 1310/2208/2 1314/2213/2 1350/2263/2 1349/2262/2 +f 1279/2155/5 1280/2157/5 1242/2089/5 1243/2091/5 +f 1264/2127/3 1265/2129/3 1262/2125/3 1263/2126/3 +f 1278/2152/5 1279/2155/5 1243/2091/5 1244/2093/5 +f 1322/2225/2 1326/2232/2 1353/2266/2 1352/2265/2 +f 1277/2150/5 1278/2152/5 1244/2093/5 1246/2097/5 +f 1294/2184/2 1298/2190/2 1225/2061/2 1227/2063/2 +f 1334/2243/2 1338/2249/2 1356/2269/2 1355/2268/2 +f 1276/2148/5 1277/2150/5 1246/2097/5 1247/2099/5 +f 1306/2202/2 1310/2208/2 1349/2262/2 1220/2055/2 +f 1275/2146/5 1276/2148/5 1247/2099/5 1248/2101/5 +f 1346/2259/2 1272/2142/2 1252/2108/2 1358/2271/2 +f 1288/2176/5 1266/2132/5 1260/2120/5 1231/2069/5 +f 1265/2130/5 1275/2146/5 1248/2101/5 1262/2123/5 +f 1318/2220/2 1322/2225/2 1352/2265/2 1351/2264/2 +f 1287/2174/5 1288/2176/5 1231/2069/5 1232/2071/5 +f 1274/2144/3 1264/2127/3 1263/2126/3 1250/2105/3 +f 1290/2179/2 1294/2184/2 1227/2063/2 1229/2066/2 +f 1286/2172/5 1287/2174/5 1232/2071/5 1234/2075/5 +f 1330/2238/2 1334/2243/2 1355/2268/2 1354/2267/2 +f 1273/2143/3 1274/2144/3 1250/2105/3 1251/2106/3 +f 1239/2085/5 1238/2083/5 1316/2216/5 1323/2227/5 +f 1255/2113/4 1254/2111/4 1379/2309/4 1378/2307/4 +f 1222/2057/2 1220/2055/2 1304/2198/2 1297/2188/2 +f 1238/2083/5 1236/2080/5 1309/2206/5 1316/2216/5 +f 1357/2270/2 1358/2271/2 1396/2334/2 1392/2329/2 +f 1252/2107/3 1251/2106/3 1376/2301/3 1377/2303/3 +f 1236/2080/5 1235/2078/5 1303/2197/5 1309/2206/5 +f 1350/2263/2 1351/2264/2 1324/2228/2 1317/2217/2 +f 1251/2106/3 1250/2105/3 1374/2297/3 1376/2301/3 +f 1235/2078/5 1234/2076/5 1296/2187/5 1303/2197/5 +f 1254/2112/2 1229/2066/2 1367/2283/2 1379/2310/2 +f 1353/2266/2 1354/2267/2 1344/2256/2 1337/2247/2 +f 1234/2076/5 1232/2072/5 1289/2178/5 1296/2187/5 +f 1250/2105/3 1263/2126/3 1375/2299/3 1374/2297/3 +f 1225/2061/2 1222/2057/2 1297/2188/2 1291/2180/2 +f 1232/2072/5 1231/2070/5 1363/2278/5 1289/2178/5 +f 1356/2269/2 1357/2270/2 1392/2329/2 1388/2324/2 +f 1262/2124/5 1248/2102/5 1372/2293/5 1373/2295/5 +f 1231/2070/5 1260/2121/5 1368/2285/5 1363/2278/5 +f 1349/2262/2 1350/2263/2 1317/2217/2 1311/2209/2 +f 1248/2102/5 1247/2100/5 1371/2291/5 1372/2293/5 +f 1263/2126/3 1262/2125/3 1373/2296/3 1375/2299/3 +f 1247/2100/5 1246/2098/5 1370/2289/5 1371/2291/5 +f 1352/2265/2 1353/2266/2 1337/2247/2 1331/2239/2 +f 1260/2121/5 1259/2118/5 1382/2316/5 1368/2285/5 +f 1246/2098/5 1244/2094/5 1369/2287/5 1370/2289/5 +f 1227/2063/2 1225/2061/2 1291/2180/2 1362/2276/2 +f 1355/2268/2 1356/2269/2 1388/2324/2 1384/2319/2 +f 1244/2094/5 1243/2092/5 1343/2255/5 1369/2287/5 +f 1259/2119/4 1258/2116/4 1381/2314/4 1382/2317/4 +f 1220/2055/2 1349/2262/2 1311/2209/2 1304/2198/2 +f 1243/2092/5 1242/2090/5 1336/2246/5 1343/2255/5 +f 1358/2271/2 1252/2108/2 1377/2304/2 1396/2334/2 +f 1258/2116/4 1256/2114/4 1380/2312/4 1381/2314/4 +f 1242/2090/5 1240/2087/5 1329/2236/5 1336/2246/5 +f 1351/2264/2 1352/2265/2 1331/2239/2 1324/2228/2 +f 1256/2114/4 1255/2113/4 1378/2307/4 1380/2312/4 +f 1240/2087/5 1239/2085/5 1323/2227/5 1329/2236/5 +f 1229/2066/2 1227/2063/2 1362/2276/2 1367/2283/2 +f 1354/2267/2 1355/2268/2 1384/2319/2 1344/2256/2 +f 1359/2272/6 1295/2185/6 1293/2183/6 1360/2273/6 +f 1291/2181/6 1297/2189/6 1299/2191/6 1292/2182/6 +f 1292/2182/6 1299/2191/6 1301/2193/6 1295/2185/6 +f 1295/2185/6 1301/2193/6 1300/2192/6 1293/2183/6 +f 1297/2189/6 1304/2199/6 1305/2200/6 1299/2191/6 +f 1299/2191/6 1305/2200/6 1308/2204/6 1301/2193/6 +f 1301/2193/6 1308/2204/6 1307/2203/6 1300/2192/6 +f 1304/2199/6 1311/2210/6 1312/2211/6 1305/2200/6 +f 1305/2200/6 1312/2211/6 1315/2214/6 1308/2204/6 +f 1308/2204/6 1315/2214/6 1313/2212/6 1307/2203/6 +f 1311/2210/6 1317/2218/6 1319/2221/6 1312/2211/6 +f 1312/2211/6 1319/2221/6 1321/2223/6 1315/2214/6 +f 1315/2214/6 1321/2223/6 1320/2222/6 1313/2212/6 +f 1317/2218/6 1324/2229/6 1325/2230/6 1319/2221/6 +f 1319/2221/6 1325/2230/6 1328/2234/6 1321/2223/6 +f 1321/2223/6 1328/2234/6 1327/2233/6 1320/2222/6 +f 1324/2229/6 1331/2240/6 1332/2241/6 1325/2230/6 +f 1325/2230/6 1332/2241/6 1335/2244/6 1328/2234/6 +f 1328/2234/6 1335/2244/6 1333/2242/6 1327/2233/6 +f 1331/2240/6 1337/2248/6 1339/2250/6 1332/2241/6 +f 1332/2241/6 1339/2250/6 1341/2252/6 1335/2244/6 +f 1335/2244/6 1341/2252/6 1340/2251/6 1333/2242/6 +f 1337/2248/6 1344/2257/6 1345/2258/6 1339/2250/6 +f 1339/2250/6 1345/2258/6 1348/2261/6 1341/2252/6 +f 1341/2252/6 1348/2261/6 1347/2260/6 1340/2251/6 +f 1344/2257/6 1384/2320/6 1385/2321/6 1345/2258/6 +f 1345/2258/6 1385/2321/6 1386/2322/6 1348/2261/6 +f 1348/2261/6 1386/2322/6 1383/2318/6 1347/2260/6 +f 1384/2320/6 1388/2325/6 1389/2326/6 1385/2321/6 +f 1385/2321/6 1389/2326/6 1390/2327/6 1386/2322/6 +f 1386/2322/6 1390/2327/6 1387/2323/6 1383/2318/6 +f 1388/2325/6 1392/2330/6 1393/2331/6 1389/2326/6 +f 1389/2326/6 1393/2331/6 1394/2332/6 1390/2327/6 +f 1390/2327/6 1394/2332/6 1391/2328/6 1387/2323/6 +f 1392/2330/6 1396/2335/6 1397/2336/6 1393/2331/6 +f 1393/2331/6 1397/2336/6 1398/2337/6 1394/2332/6 +f 1394/2332/6 1398/2337/6 1395/2333/6 1391/2328/6 +f 1396/2335/6 1377/2305/6 1376/2302/6 1397/2336/6 +f 1397/2336/6 1376/2302/6 1374/2298/6 1398/2337/6 +f 1398/2337/6 1374/2298/6 1375/2300/6 1395/2333/6 +o campfire_flame +v -0.424006 -0.425572 0.424006 +v -0.424006 0.773699 0.424006 +v 0.424006 -0.425572 -0.424006 +v 0.424006 0.773699 -0.424006 +v 0.424006 -0.425572 0.424006 +v 0.424006 0.773699 0.424006 +v -0.424006 -0.425572 -0.424006 +v -0.424006 0.773699 -0.424006 +vn -0.7071 -0.0000 -0.7071 +vn -0.7071 -0.0000 0.7071 +vt 0.500100 0.000200 +vt 0.500100 1.000000 +vt 0.999900 0.000200 +vt 0.999900 1.000000 +vt 0.500100 0.000200 +vt 0.500100 1.000000 +vt 0.999900 0.000200 +vt 0.999900 1.000000 +s 0 +usemtl camp_fire_UV_animated_emit +f 1399/2338/7 1400/2339/7 1402/2341/7 1401/2340/7 +f 1403/2342/8 1404/2343/8 1406/2345/8 1405/2344/8 diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl deleted file mode 100644 index 7355efe9f..000000000 --- a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl +++ /dev/null @@ -1,35 +0,0 @@ -# Blender MTL File: 'campfire.blend' -# Material Count: 3 - -newmtl Material.001 -Ns 96.078431 -Ka 1.000000 1.000000 1.000000 -Kd 0.640000 0.640000 0.640000 -Ks 0.500000 0.500000 0.500000 -Ke 0.000000 0.000000 0.000000 -Ni 1.000000 -d 1.000000 -illum 2 -map_Kd G:\minetest-0.4.16-win641\textures\Pixel Perfection v4.0\mcl_campfire_fire.png - -newmtl none -Ns 96.078431 -Ka 1.000000 1.000000 1.000000 -Kd 0.640000 0.640000 0.640000 -Ks 0.500000 0.500000 0.500000 -Ke 0.000000 0.000000 0.000000 -Ni 1.000000 -d 1.000000 -illum 2 -map_Kd \home\nathan\Downloads\mcl_campfire_log.png - -newmtl none_NONE -Ns 96.078431 -Ka 1.000000 1.000000 1.000000 -Kd 0.640000 0.640000 0.640000 -Ks 0.500000 0.500000 0.500000 -Ke 0.000000 0.000000 0.000000 -Ni 1.000000 -d 1.000000 -illum 2 -map_Kd \\home\\nathan\\Downloads\\mcl_campfire_log.png diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj deleted file mode 100644 index 92a377303..000000000 --- a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj +++ /dev/null @@ -1,248 +0,0 @@ -# Blender v2.78 (sub 0) OBJ File: 'campfire.blend' -# www.blender.org -mtllib campfire1.mtl -o nodebox4.005_nodebox4.006 -v 0.243779 -0.499707 -0.497529 -v 0.493779 -0.499707 -0.497421 -v 0.493779 -0.249707 -0.497421 -v 0.243779 -0.249707 -0.497529 -v 0.243349 -0.499707 0.502471 -v 0.493349 -0.499707 0.502578 -v 0.493349 -0.249707 0.502578 -v 0.243349 -0.249707 0.502471 -v 0.493779 -0.499707 -0.497421 -v 0.493779 -0.249707 -0.497421 -v 0.493349 -0.499707 0.502578 -v 0.493349 -0.249707 0.502578 -vt -0.0000 0.7500 -vt -0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt -0.0000 0.7500 -vt -0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vn -0.0004 0.0000 1.0000 -vn 1.0000 -0.0000 0.0004 -vn -0.0000 -1.0000 0.0000 -usemtl none -s off -f 1/1/1 2/2/1 3/3/1 4/4/1 -f 5/5/1 6/6/1 7/7/1 8/8/1 -f 1/9/2 4/10/2 8/11/2 5/5/2 -f 1/9/3 2/12/3 6/13/3 5/5/3 -f 4/14/3 3/15/3 7/16/3 8/17/3 -f 9/18/2 10/19/2 12/20/2 11/21/2 -o nodebox4.004_nodebox4.005 -v -0.500021 -0.499707 -0.497848 -v -0.250021 -0.499707 -0.497741 -v -0.250021 -0.249707 -0.497741 -v -0.500021 -0.249707 -0.497848 -v -0.500451 -0.499707 0.502152 -v -0.250451 -0.499707 0.502259 -v -0.250451 -0.249707 0.502259 -v -0.500451 -0.249707 0.502152 -v -0.250021 -0.499707 -0.497741 -v -0.250021 -0.249707 -0.497741 -v -0.250451 -0.499707 0.502259 -v -0.250451 -0.249707 0.502259 -vt -0.0000 0.7500 -vt -0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt -0.0000 0.7500 -vt -0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vn -0.0004 0.0000 1.0000 -vn 1.0000 -0.0000 0.0004 -vn -0.0000 -1.0000 0.0000 -usemtl none -s off -f 13/22/4 14/23/4 15/24/4 16/25/4 -f 17/26/4 18/27/4 19/28/4 20/29/4 -f 13/30/5 16/31/5 20/32/5 17/26/5 -f 13/30/6 14/33/6 18/34/6 17/26/6 -f 16/35/6 15/36/6 19/37/6 20/38/6 -f 21/39/5 22/40/5 24/41/5 23/42/5 -o nodebox4.001_nodebox4.004 -v 0.500000 -0.312500 -0.493800 -v 0.500000 -0.312500 -0.243800 -v 0.500000 -0.062500 -0.243800 -v 0.500000 -0.062500 -0.493800 -v -0.500000 -0.312500 -0.493800 -v -0.500000 -0.312500 -0.243800 -v -0.500000 -0.062500 -0.243800 -v -0.500000 -0.062500 -0.493800 -v 0.500000 -0.312500 -0.243800 -v 0.500000 -0.062500 -0.243800 -v -0.500000 -0.312500 -0.243800 -v -0.500000 -0.062500 -0.243800 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.7500 -vn -1.0000 0.0000 0.0000 -vn 0.0000 -0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -usemtl none -s off -f 25/43/7 26/44/7 27/45/7 28/46/7 -f 29/47/7 30/48/7 31/49/7 32/50/7 -f 25/51/8 28/52/8 32/53/8 29/47/8 -f 25/51/9 26/54/9 30/55/9 29/47/9 -f 28/56/9 27/57/9 31/58/9 32/59/9 -f 33/60/8 34/61/8 36/62/8 35/63/8 -o Plane -v -0.311754 -0.438770 -0.196249 -v 0.276360 -0.438621 0.247948 -v -0.311276 0.135801 -0.196634 -v 0.276838 0.135950 0.247562 -v -0.274993 -0.438696 0.270317 -v 0.240407 -0.438696 -0.218656 -v -0.275322 0.135875 0.269969 -v 0.240077 0.135875 -0.219003 -vt 0.0000 0.0000 -vt 1.0000 0.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 0.0000 0.0000 -vt 1.0000 0.0000 -vt 1.0000 1.0000 -vt -0.0000 1.0000 -vn -0.6027 0.0010 0.7980 -vn 0.6883 0.0008 0.7255 -usemtl Material.001 -s off -f 37/64/10 38/65/10 40/66/10 39/67/10 -f 41/68/11 42/69/11 44/70/11 43/71/11 -o nodebox3 -v 0.250000 -0.500000 -0.500000 -v 0.250000 -0.500000 0.500000 -v 0.250000 -0.437500 0.500000 -v 0.250000 -0.437500 -0.500000 -v -0.250000 -0.500000 -0.500000 -v -0.250000 -0.500000 0.500000 -v -0.250000 -0.437500 0.500000 -v -0.250000 -0.437500 -0.500000 -vt 1.0000 0.0000 -vt 1.0000 0.0625 -vt 0.0000 0.0625 -vt 0.0000 0.0000 -vt 1.0000 0.0000 -vt 1.0000 0.0625 -vt 0.0000 0.0625 -vt 0.0000 0.0000 -vt 1.0000 0.4375 -vt 0.0000 0.4375 -vt 0.0001 0.0001 -vt 0.9999 0.0001 -vt 1.0000 0.5000 -vt 0.0000 0.5000 -vt 0.0001 0.0001 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vt 0.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -vn -1.0000 0.0000 0.0000 -usemtl none -s off -f 45/72/12 48/73/12 52/74/12 49/75/12 -f 46/76/12 47/77/12 51/78/12 50/79/12 -f 45/72/13 46/80/13 50/81/13 49/82/13 -f 48/83/13 47/84/13 51/85/13 52/86/13 -usemtl none_NONE -f 45/87/14 46/88/14 47/89/14 48/90/14 -f 49/75/14 50/79/14 51/91/14 52/92/14 -o nodebox4 -v 0.500000 -0.312500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v 0.500000 -0.062500 0.250000 -v -0.500000 -0.312500 0.250000 -v -0.500000 -0.312500 0.500000 -v -0.500000 -0.062500 0.500000 -v -0.500000 -0.062500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v -0.500000 -0.312500 0.500000 -v -0.500000 -0.062500 0.500000 -vt -0.0000 0.7500 -vt 0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt -0.0000 0.7500 -vt -0.0000 0.5000 -vt 0.2500 0.5000 -vt 0.2500 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vt 1.0000 0.7500 -vt 1.0000 1.0000 -vt 0.0000 1.0000 -vt -0.0000 0.7500 -vn -1.0000 0.0000 0.0000 -vn 0.0000 -0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -usemtl none -s off -f 53/93/15 54/94/15 55/95/15 56/96/15 -f 57/97/15 58/98/15 59/99/15 60/100/15 -f 53/101/16 56/102/16 60/103/16 57/97/16 -f 53/101/17 54/104/17 58/105/17 57/97/17 -f 56/106/17 55/107/17 59/108/17 60/109/17 -f 61/110/16 62/111/16 64/112/16 63/113/16 diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj deleted file mode 100644 index a17acc05f..000000000 --- a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj +++ /dev/null @@ -1,225 +0,0 @@ -# Blender v2.79 (sub 7) OBJ File: 'campfire.blend' -# www.blender.org -o Plane -v -0.240246 -0.438696 -0.141059 -v 0.205043 -0.438696 0.192756 -v -0.239959 0.135875 -0.141442 -v 0.205331 0.135875 0.192373 -v -0.216088 -0.438696 0.214432 -v 0.181502 -0.438696 -0.162771 -v -0.216417 0.135875 0.214085 -v 0.181172 0.135875 -0.163119 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.000000 -vt 1.000000 0.000000 -vt 1.000000 1.000000 -vt -0.000000 1.000000 -vn -0.5998 0.0008 0.8001 -vn 0.6883 0.0008 0.7255 -g Plane_Plane_Material.001 -s off -f 1/1/1 2/2/1 4/3/1 3/4/1 -f 5/5/2 6/6/2 8/7/2 7/8/2 -o nodebox3 -v 0.250000 -0.500000 -0.500000 -v 0.250000 -0.500000 0.500000 -v 0.250000 -0.437500 0.500000 -v 0.250000 -0.437500 -0.500000 -v -0.250000 -0.500000 -0.500000 -v -0.250000 -0.500000 0.500000 -v -0.250000 -0.437500 0.500000 -v -0.250000 -0.437500 -0.500000 -v 0.243779 -0.499707 -0.497529 -v 0.493779 -0.499707 -0.497421 -v 0.493779 -0.249707 -0.497421 -v 0.243779 -0.249707 -0.497529 -v 0.243349 -0.499707 0.502471 -v 0.493349 -0.499707 0.502579 -v 0.493349 -0.249707 0.502578 -v 0.243349 -0.249707 0.502471 -v 0.493779 -0.499707 -0.497421 -v 0.493779 -0.249707 -0.497421 -v 0.493349 -0.499707 0.502579 -v 0.493349 -0.249707 0.502578 -v -0.500021 -0.499707 -0.497848 -v -0.250021 -0.499707 -0.497741 -v -0.250021 -0.249707 -0.497741 -v -0.500021 -0.249707 -0.497848 -v -0.500451 -0.499707 0.502152 -v -0.250451 -0.499707 0.502259 -v -0.250451 -0.249707 0.502259 -v -0.500451 -0.249707 0.502152 -v -0.250021 -0.499707 -0.497741 -v -0.250021 -0.249707 -0.497741 -v -0.250451 -0.499707 0.502259 -v -0.250451 -0.249707 0.502259 -v 0.500000 -0.312500 -0.493800 -v 0.500000 -0.312500 -0.243800 -v 0.500000 -0.062500 -0.243800 -v 0.500000 -0.062500 -0.493800 -v -0.500000 -0.312500 -0.493800 -v -0.500000 -0.312500 -0.243800 -v -0.500000 -0.062500 -0.243800 -v -0.500000 -0.062500 -0.493800 -v 0.500000 -0.312500 -0.243800 -v 0.500000 -0.062500 -0.243800 -v -0.500000 -0.312500 -0.243800 -v -0.500000 -0.062500 -0.243800 -v 0.500000 -0.312500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v 0.500000 -0.062500 0.250000 -v -0.500000 -0.312500 0.250000 -v -0.500000 -0.312500 0.500000 -v -0.500000 -0.062500 0.500000 -v -0.500000 -0.062500 0.250000 -v 0.500000 -0.312500 0.500000 -v 0.500000 -0.062500 0.500000 -v -0.500000 -0.312500 0.500000 -v -0.500000 -0.062500 0.500000 -vt 0.999982 0.000018 -vt 1.000000 0.062500 -vt 0.000000 0.062500 -vt 0.000018 0.000018 -vt 0.999982 0.000018 -vt 1.000000 0.062500 -vt 0.000000 0.062500 -vt 0.000018 0.000018 -vt 1.000000 0.437500 -vt 0.000000 0.437500 -vt 0.000071 0.000071 -vt 0.999929 0.000071 -vt 1.000000 0.500000 -vt 0.000000 0.500000 -vt 0.000071 0.000071 -vt -0.000000 0.750000 -vt -0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt 0.000000 0.750000 -vt 0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt 0.000000 0.750000 -vt 0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 0.000000 0.750000 -vt -0.000000 0.750000 -vt 0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.500000 -vt 0.250000 0.500000 -vt 0.250000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt 1.000000 0.750000 -vt 1.000000 1.000000 -vt 0.000000 1.000000 -vt -0.000000 0.750000 -vt 0.000000 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.000000 -vt 0.000000 0.000000 -vn 0.0000 0.0000 1.0000 -vn 0.0000 -1.0000 -0.0000 -vn -0.0004 0.0000 1.0000 -vn 1.0000 -0.0000 0.0004 -vn -1.0000 0.0000 0.0000 -g nodebox3_nodebox3_none -s off -f 9/9/3 12/10/3 16/11/3 13/12/3 -f 10/13/3 11/14/3 15/15/3 14/16/3 -f 9/9/4 10/17/4 14/18/4 13/19/4 -f 12/20/4 11/21/4 15/22/4 16/23/4 -f 17/24/5 18/25/5 19/26/5 20/27/5 -f 21/28/5 22/29/5 23/30/5 24/31/5 -f 17/32/6 20/33/6 24/34/6 21/28/6 -f 17/32/4 18/35/4 22/36/4 21/28/4 -f 20/37/4 19/38/4 23/39/4 24/40/4 -f 25/41/6 26/42/6 28/43/6 27/44/6 -f 29/45/5 30/46/5 31/47/5 32/48/5 -f 33/49/5 34/50/5 35/51/5 36/52/5 -f 29/53/6 32/54/6 36/55/6 33/49/6 -f 29/53/4 30/56/4 34/57/4 33/49/4 -f 32/58/4 31/59/4 35/60/4 36/61/4 -f 37/62/6 38/63/6 40/64/6 39/65/6 -f 41/66/7 42/67/7 43/68/7 44/69/7 -f 45/70/7 46/71/7 47/72/7 48/73/7 -f 41/74/3 44/75/3 48/76/3 45/70/3 -f 41/74/4 42/77/4 46/78/4 45/70/4 -f 44/79/4 43/80/4 47/81/4 48/82/4 -f 49/83/3 50/84/3 52/85/3 51/86/3 -f 53/87/7 54/88/7 55/89/7 56/90/7 -f 57/91/7 58/92/7 59/93/7 60/94/7 -f 53/95/3 56/96/3 60/97/3 57/91/3 -f 53/95/4 54/98/4 58/99/4 57/91/4 -f 56/100/4 55/101/4 59/102/4 60/103/4 -f 61/104/3 62/105/3 64/106/3 63/107/3 -g nodebox3_nodebox3_none_NONE -f 9/108/7 10/109/7 11/110/7 12/111/7 -f 13/12/7 14/16/7 15/112/7 16/113/7 diff --git a/mods/ITEMS/mcl_campfires/register.lua b/mods/ITEMS/mcl_campfires/register.lua index 87e9f415a..1dcaccea8 100644 --- a/mods/ITEMS/mcl_campfires/register.lua +++ b/mods/ITEMS/mcl_campfires/register.lua @@ -40,3 +40,19 @@ minetest.register_craft({ { "group:tree", "group:tree", "group:tree" }, } }) + +-- Register Visual Food Entity +minetest.register_entity("mcl_campfires:food_entity", { + initial_properties = { + physical = false, + visual = "wielditem", + wield_item = "mcl_mobitems:mutton", + wield_image = "mcl_mobitems_mutton_raw.png", + visual_size = {x=0.25, y=0.25}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + }, + on_activate = function(self, staticdata) + self.object:set_rotation({x = math.pi / -2, y = 0, z = 0}) + end, +}) diff --git a/mods/ITEMS/mcl_cartography_table/README.md b/mods/ITEMS/mcl_cartography_table/README.md index 4818b6784..0d66c8042 100644 --- a/mods/ITEMS/mcl_cartography_table/README.md +++ b/mods/ITEMS/mcl_cartography_table/README.md @@ -2,7 +2,7 @@ mcl_cartography_table ------------------- Cartography Tables, by PrairieWind -Adds Cartography Tables to MineClone 2/5. +Adds Cartography Tables to VoxeLibre. License of source code ---------------------- @@ -10,4 +10,4 @@ LGPLv2.1 License of media ---------------- -See the main MineClone 2 README.md file. \ No newline at end of file +See the main VoxeLibre README.md file. diff --git a/mods/ITEMS/mcl_cartography_table/init.lua b/mods/ITEMS/mcl_cartography_table/init.lua index dca9493ee..269a49ede 100644 --- a/mods/ITEMS/mcl_cartography_table/init.lua +++ b/mods/ITEMS/mcl_cartography_table/init.lua @@ -26,3 +26,9 @@ minetest.register_craft({ { "group:wood", "group:wood", "" }, } }) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_cartography_table:cartography_table", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ru.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ru.tr new file mode 100644 index 000000000..bc47ab19f --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table=Картографический стол +Used to create or copy maps=Используется для создания или копирования карт +Is used to create or copy maps for use..=Используется для создания или копирования карт. diff --git a/mods/ITEMS/mcl_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index c84e3bb88..89f173399 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -67,12 +67,12 @@ local function register_filled_cauldron(water_level, description, liquid) local water_tex if liquid == "river_water" then id = id .. "r" - water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#0084FF" + water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#0084FF" elseif liquid == "lava" then id = id .. "_lava" - water_tex = "default_lava_source_animated.png^[verticalframe:16:0" + water_tex = "mcl_core_lava_source_animation.png^[verticalframe:16:0" else - water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" + water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#3F76E4" end minetest.register_node(id, { description = description, @@ -94,6 +94,14 @@ local function register_filled_cauldron(water_level, description, liquid) drop = "mcl_cauldrons:cauldron", _mcl_hardness = 2, _mcl_blast_resistance = 2, + on_rightclick = function(pos, node, player, itemstack) + local outcome = mcl_armor.wash_leather_armor(itemstack) + if outcome then + minetest.sound_play("mcl_potions_bottle_pour", + {pos=pos, gain=0.5, max_hear_range=16},true) + end + return outcome + end, }) -- Add entry aliases for the Help diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ru.tr similarity index 58% rename from mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr rename to mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ru.tr index 272ff7c44..b2255594d 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ru.tr @@ -1,7 +1,7 @@ # textdomain: mcl_cauldrons Cauldron=Котёл -Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Котлы используются для хранения воды и медленного наполнения под дождём. Они также могут использоваться для промывания флагов. -Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=Попытайтесь поместить ведро воды в котёл, чтобы наполнить его водой. Попытка поместить пустое ведро приведёт к освобождению котла. Поместите в котёл бутылку воды, чтобы наполнить его на треть. +Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Котлы используются для хранения воды и могут медленно наполняться под дождём. Котлы можно использовать для смывания узоров с флага. +Place a water bucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water. Use an emblazoned banner on a cauldron with water to wash off its top layer.=Используйте ведро воды на котле, чтобы наполнить его водой. Забрать воду из котла можно пустым ведром. Пузырёк с водой также наполняет котёл на одну треть. Cauldron (1/3 Water)=Котёл (1/3 воды) Cauldron (2/3 Water)=Котёл (2/3 воды) Cauldron (3/3 Water)=Котёл (3/3 воды) diff --git a/mods/ITEMS/mcl_cherry_blossom/crafting.lua b/mods/ITEMS/mcl_cherry_blossom/crafting.lua index f26b2af96..5f41ccd13 100644 --- a/mods/ITEMS/mcl_cherry_blossom/crafting.lua +++ b/mods/ITEMS/mcl_cherry_blossom/crafting.lua @@ -2,6 +2,8 @@ local planks = "mcl_cherry_blossom:cherrywood" local logs = "mcl_cherry_blossom:cherrytree" local stripped_logs = "mcl_cherry_blossom:stripped_cherrytree" +local wood = "mcl_cherry_blossom:cherrytree_bark" +local stripped_wood = "mcl_cherry_blossom:stripped_cherrytree_bark" minetest.register_craft({ output = "mcl_cherry_blossom:cherrytree_bark 3", @@ -26,6 +28,27 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "mcl_cherry_blossom:cherrywood 4", + recipe = { + { wood }, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherrywood 4", + recipe = { + { stripped_logs }, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherrywood 4", + recipe = { + { stripped_wood }, + } +}) + minetest.register_craft({ output = "mcl_cherry_blossom:cherry_door 3", recipe = { diff --git a/mods/ITEMS/mcl_cherry_blossom/growth.lua b/mods/ITEMS/mcl_cherry_blossom/growth.lua index 28cedea28..bca926539 100644 --- a/mods/ITEMS/mcl_cherry_blossom/growth.lua +++ b/mods/ITEMS/mcl_cherry_blossom/growth.lua @@ -31,11 +31,25 @@ local cherry_particle = { velocity = vector.zero(), acceleration = vector.new(0,-1,0), size = math.random(1.3,2.5), - texture = "mcl_cherry_blossom_particle.png", + texture = "mcl_cherry_blossom_particle_" .. math.random(1, 12) .. ".png", + animation = { + type = "vertical_frames", + aspect_w = 3, + aspect_h = 3, + length = 0.8, + }, collision_removal = false, collisiondetection = false, } +local wind_direction -- vector +local time_changed -- 0 - afternoon; 1 - evening; 2 - morning +local function change_wind_direction() + local east_west = math.random(-0.5,0.5) + local north_south = math.random(-0.5,0.5) + wind_direction = vector.new(east_west, 0, north_south) +end +change_wind_direction() minetest.register_abm({ label = "Cherry Blossom Particles", @@ -47,6 +61,20 @@ minetest.register_abm({ local pt = table.copy(cherry_particle) pt.pos = vector.offset(pos,math.random(-0.5,0.5),-0.51,math.random(-0.5,0.5)) pt.expirationtime = math.random(1.2,4.5) + pt.texture = "mcl_cherry_blossom_particle_" .. math.random(1, 12) .. ".png" + local time = minetest.get_timeofday() + if time_changed ~= 0 and time > 0.6 and time < 0.605 then + time_changed = 0 + change_wind_direction() + elseif (time_changed ~= 1 and time > 0.8 and time < 0.805) then + time_changed = 1 + change_wind_direction() + elseif (time_changed ~= 2 and time > 0.3 and time < 0.305) then + time_changed = 2 + change_wind_direction() + end + pt.acceleration = pt.acceleration + wind_direction + minetest.add_particle(pt) end) end diff --git a/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.fr.tr b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.fr.tr new file mode 100644 index 000000000..2f6b7db22 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.fr.tr @@ -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 diff --git a/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.pt_BR.tr b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.pt_BR.tr new file mode 100644 index 000000000..e3dc6d2fd --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.pt_BR.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_cherry_blossom +Cherry Log=Tronco de Cerejeira +The trunk of a cherry blossom tree.=O tronco de uma árvore de cerejeira. +Stripped Cherry Log=Tronco de Cerejeira Descascado +The stripped trunk of a cherry blossom tree.=O tronco descascado de uma árvore de cerejeira. +Cherry Bark=Casca de Cerejeira +This is a decorative block surrounded by the bark of a tree trunk.=Esse é um bloco decorativo rodeado pela casca do tronco de uma árvore. +Stripped Cherry Wood=Madeira de Cerejeira Descascada +The stripped wood of a cherry blossom tree.=A madeira descascada da árvore de cerejeira. +Cherry Wood Planks=Tábuas de Cerejeira +Cherry Leaves=Folhas de Cerejeira +Cherry blossom leaves are grown from cherry blossom trees.=Folhas de cerejeira crescem em árvores de cerejeira. +Cherry Sapling=Muda de Cerejeira +Cherry blossom sapling can be planted to grow cherry trees.=Muda de cerejeira pode ser plantada para crescer árvores de cerejeira. +Cherry Door=Porta de Cerejeira +Cherry Trapdoor=Alçapão de Cerejeira +Cherry Stairs=Escadas de Cerejeira +Cherry Slab=Laje de Cerejeira +Double Cherry Slab=Laje Dupla de Cerejeira +Cherry Sign=Placa de Cerejeira +Cherry Fence=Cerca de Cerejeira +Cherry Gate=Portão de Cerejeira +Cherry Pressure Plate=Placa de Pressão de Cerejeira +Cherry Button=Botão de Cerejeira diff --git a/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.ru.tr b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.ru.tr index 408af8b99..1dc530f7a 100644 --- a/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.ru.tr +++ b/mods/ITEMS/mcl_cherry_blossom/locale/mcl_cherry_blossom.ru.tr @@ -1,20 +1,20 @@ # textdomain: mcl_cherry_blossom -Cherry Log=Вишнёвое бревно -The trunk of a cherry blossom tree.=Ствол цветущего вишневого дерева. -Stripped Cherry Log=Обтёсанное вишнёвое бревно +Cherry Log=Вишнёвая древесина +The trunk of a cherry blossom tree.=Ствол цветущего вишнёвого дерева. +Stripped Cherry Log=Обтёсанная вишнёвая древесина The stripped trunk of a cherry blossom tree.=Обтёсанный ствол цветущей вишни. -Cherry Bark=Вишня +Cherry Bark=Вишнёвая кора This is a decorative block surrounded by the bark of a tree trunk.=Это декоративный блок, окруженный корой ствола дерева. -Stripped Cherry Wood=Обтёсанная вишнёвая древесина +Stripped Cherry Wood=Обтёсанная вишнёвая кора The stripped wood of a cherry blossom tree.=Обтёсанная древесина цветущей вишни. Cherry Wood Planks=Вишнёвые доски Cherry Leaves=Вишнёвые листья -Cherry blossom leaves are grown from cherry blossom trees.=Листья цветущей вишни выращивают на вишневых деревьях. +Cherry blossom leaves are grown from cherry blossom trees.=Листья цветущей вишни растут на вишнёвых деревьях. Cherry Sapling=Саженец вишни -Cherry blossom sapling can be planted to grow cherry trees.=Саженец цветущей вишни можно посадить для выращивания вишневых деревьев. +Cherry blossom sapling can be planted to grow cherry trees.=Саженец цветущей вишни можно посадить для выращивания вишнёвых деревьев. Cherry Door=Вишнёвая дверь Cherry Trapdoor=Вишнёвый люк -Cherry Stairs=Вишнёвые ступеньки +Cherry Stairs=Вишнёвые ступени Cherry Slab=Вишнёвая плита Double Cherry Slab=Двойная вишнёвая плита Cherry Sign=Вишнёвая табличка diff --git a/mods/ITEMS/mcl_cherry_blossom/nodes.lua b/mods/ITEMS/mcl_cherry_blossom/nodes.lua index 4b6803123..403982872 100644 --- a/mods/ITEMS/mcl_cherry_blossom/nodes.lua +++ b/mods/ITEMS/mcl_cherry_blossom/nodes.lua @@ -66,9 +66,16 @@ mcl_signs.register_sign_custom("mcl_cherry_blossom", "_cherrywood", "mcl_cherry_blossom_sign_inv.png", "mcl_cherry_blossom_sign_inv.png", S("Cherry Sign")) -- Fences & Gates -mcl_fences.register_fence_and_fence_gate("cherry_fence", S("Cherry Fence"), S("Cherry Gate"), - "mcl_cherry_blossom_planks.png", {handy=1, axey=1, flammable=2, fence_wood=1, fire_encouragement=5, fire_flammability=20}, 2, 15, - {"group:fence_wood"}, mcl_sounds.node_sound_wood_defaults()) +mcl_fences.register_fence_and_fence_gate( + "cherry_fence", + S("Cherry Fence"), + S("Cherry Gate"), + "mcl_cherry_blossom_planks.png", + {handy=1, axey=1, flammable=2, fence_wood=1, fire_encouragement=5, fire_flammability=20}, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) -- Redstone mesecon.register_pressure_plate( diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 38437c73f..da901da32 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1,41 +1,42 @@ local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize + +local string = string +local table = table +local math = math + +local sf = string.format + local mod_doc = minetest.get_modpath("doc") +mcl_chests = {} + -- Christmas chest setup -local it_is_christmas = false -local date = os.date("*t") -if ( - date.month == 12 and ( - date.day == 24 or - date.day == 25 or - date.day == 26 - ) -) then - it_is_christmas = true -end +local it_is_christmas = mcl_util.is_it_christmas() -local tiles_chest_normal_small = {"mcl_chests_normal.png"} -local tiles_chest_normal_double = {"mcl_chests_normal_double.png"} +local tiles_chest_normal_small = { "mcl_chests_normal.png" } +local tiles_chest_normal_double = { "mcl_chests_normal_double.png" } if it_is_christmas then - tiles_chest_normal_small = {"mcl_chests_normal_present.png^mcl_chests_noise.png"} - tiles_chest_normal_double = {"mcl_chests_normal_double_present.png^mcl_chests_noise_double.png"} + tiles_chest_normal_small = { "mcl_chests_normal_present.png^mcl_chests_noise.png" } + tiles_chest_normal_double = { "mcl_chests_normal_double_present.png^mcl_chests_noise_double.png" } end -local tiles_chest_trapped_small = {"mcl_chests_trapped.png"} -local tiles_chest_trapped_double = {"mcl_chests_trapped_double.png"} +local tiles_chest_trapped_small = { "mcl_chests_trapped.png" } +local tiles_chest_trapped_double = { "mcl_chests_trapped_double.png" } if it_is_christmas then - tiles_chest_trapped_small = {"mcl_chests_trapped_present.png^mcl_chests_noise.png"} - tiles_chest_trapped_double = {"mcl_chests_trapped_double_present.png^mcl_chests_noise_double.png"} + tiles_chest_trapped_small = { "mcl_chests_trapped_present.png^mcl_chests_noise.png" } + tiles_chest_trapped_double = { "mcl_chests_trapped_double_present.png^mcl_chests_noise_double.png" } end -local tiles_chest_ender_small = {"mcl_chests_ender.png"} +local tiles_chest_ender_small = { "mcl_chests_ender.png" } -local ender_chest_texture = {"mcl_chests_ender.png"} +local ender_chest_texture = { "mcl_chests_ender.png" } if it_is_christmas then - tiles_chest_ender_small = {"mcl_chests_ender_present.png^mcl_chests_noise.png"} - ender_chest_texture = {"mcl_chests_ender_present.png"} + tiles_chest_ender_small = { "mcl_chests_ender_present.png^mcl_chests_noise.png" } + ender_chest_texture = { "mcl_chests_ender_present.png" } end -- Chest Entity @@ -43,14 +44,14 @@ local animate_chests = (minetest.settings:get_bool("animated_chests") ~= false) local entity_animations = { shulker = { speed = 50, - open = {x = 45, y = 95}, - close = {x = 95, y = 145}, + open = { x = 45, y = 95 }, + close = { x = 95, y = 145 }, }, chest = { speed = 25, - open = {x = 0, y = 7}, - close = {x = 13, y = 20}, - } + open = { x = 0, y = 7 }, + close = { x = 13, y = 20 }, + }, } minetest.register_entity("mcl_chests:chest", { @@ -72,7 +73,8 @@ minetest.register_entity("mcl_chests:chest", { self.players[playername] = true if not self.is_open then self:set_animation("open") - minetest.sound_play(self.sound_prefix .. "_open", {pos=self.node_pos, gain=0.5, max_hear_distance = 16}, true) + minetest.sound_play(self.sound_prefix .. "_open", { pos = self.node_pos, gain = 0.5, max_hear_distance = 16 }, + true) self.is_open = true end end, @@ -85,7 +87,9 @@ minetest.register_entity("mcl_chests:chest", { return end self:set_animation("close") - minetest.sound_play(self.sound_prefix .. "_close", {pos=self.node_pos, gain=0.3, max_hear_distance = 16}, true) + minetest.sound_play(self.sound_prefix .. "_close", + { pos = self.node_pos, gain = 0.3, max_hear_distance = 16 }, + true) self.is_open = false end end, @@ -124,7 +128,7 @@ minetest.register_entity("mcl_chests:chest", { end, on_activate = function(self) - self.object:set_armor_groups({immortal = 1}) + self.object:set_armor_groups({ immortal = 1 }) self.players = {} end, @@ -136,7 +140,7 @@ minetest.register_entity("mcl_chests:chest", { }) local function get_entity_pos(pos, dir, double) - pos = vector.new(pos) + pos = vector.copy(pos) if double then local add, mul, vec, cross = vector.add, vector.multiply, vector.new, vector.cross pos = add(pos, mul(cross(dir, vec(0, 1, 0)), -0.5)) @@ -158,7 +162,8 @@ local function get_entity_info(pos, param2, double, dir, entity_pos) return dir, get_entity_pos(pos, dir, double) end -local function create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) +local function create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, + entity_pos) dir, entity_pos = get_entity_info(pos, param2, double, dir, entity_pos) local obj = minetest.add_entity(entity_pos, "mcl_chests:chest") local luaentity = obj:get_luaentity() @@ -166,9 +171,12 @@ local function create_entity(pos, node_name, textures, param2, double, sound_pre return luaentity end -local function find_or_create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) +local function find_or_create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type + , dir, entity_pos) dir, entity_pos = get_entity_info(pos, param2, double, dir, entity_pos) - return find_entity(entity_pos) or create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, entity_pos) + return find_entity(entity_pos) or + create_entity(pos, node_name, textures, param2, double, sound_prefix, mesh_prefix, animation_type, dir, + entity_pos) end local no_rotate, simple_rotate @@ -179,7 +187,9 @@ if minetest.get_modpath("screwdriver") then local nodename = node.name local nodedef = minetest.registered_nodes[nodename] local dir = minetest.facedir_to_dir(new_param2) - find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, nodedef._chest_entity_sound, nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir) + find_or_create_entity(pos, nodename, nodedef._chest_entity_textures, new_param2, false, + nodedef._chest_entity_sound, + nodedef._chest_entity_mesh, nodedef._chest_entity_animation_type, dir):set_yaw(dir) else return false end @@ -204,10 +214,21 @@ end]] -- To be called if a player opened a chest local function player_chest_open(player, pos, node_name, textures, param2, double, sound, mesh, shulker) local name = player:get_player_name() - open_chests[name] = {pos = pos, node_name = node_name, textures = textures, param2 = param2, double = double, sound = sound, mesh = mesh, shulker = shulker} + open_chests[name] = { + pos = pos, + node_name = node_name, + textures = textures, + param2 = param2, + double = double, + sound = sound, + mesh = mesh, + shulker = shulker + } if animate_chests then local dir = minetest.facedir_to_dir(param2) - find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name) + find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", + dir): + open(name) end end @@ -221,6 +242,7 @@ local function protection_check_move(pos, from_list, from_index, to_list, to_ind return count end end + local function protection_check_put_take(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then @@ -238,24 +260,27 @@ local function chest_update_after_close(pos) local node = minetest.get_node(pos) if node.name == "mcl_chests:trapped_chest_on_small" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_small", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_small", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_small", { "mcl_chests_trapped.png" }, node.param2, false, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_small") mesecon.receptor_off(pos, trapped_chest_mesecons_rules) elseif node.name == "mcl_chests:trapped_chest_on_left" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_left", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_left", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") mesecon.receptor_off(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_right", param2 = node.param2 }) mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) elseif node.name == "mcl_chests:trapped_chest_on_right" then - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_right", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_right", param2 = node.param2 }) mesecon.receptor_off(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_left", param2 = node.param2}) - find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_left", param2 = node.param2 }) + find_or_create_entity(pos_other, "mcl_chests:trapped_chest_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") mesecon.receptor_off(pos_other, trapped_chest_mesecons_rules) end end @@ -268,7 +293,9 @@ local function player_chest_close(player) return end if animate_chests then - find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, open_chest.double, open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name) + find_or_create_entity(open_chest.pos, open_chest.node_name, open_chest.textures, open_chest.param2, + open_chest.double, + open_chest.sound, open_chest.mesh, open_chest.shulker and "shulker" or "chest"):close(name) end chest_update_after_close(open_chest.pos) @@ -276,12 +303,14 @@ local function player_chest_close(player) end -- This is a helper function to register both chests and trapped chests. Trapped chests will make use of the additional parameters -local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tiles_table, hidden, mesecons, on_rightclick_addendum, on_rightclick_addendum_left, on_rightclick_addendum_right, drop, canonical_basename) +local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tiles_table, hidden, mesecons, + on_rightclick_addendum, on_rightclick_addendum_left, on_rightclick_addendum_right, drop, + canonical_basename) -- START OF register_chest FUNCTION BODY if not drop then - drop = "mcl_chests:"..basename + drop = "mcl_chests:" .. basename else - drop = "mcl_chests:"..drop + drop = "mcl_chests:" .. drop end -- The basename of the "canonical" version of the node, if set (e.g.: trapped_chest_on → trapped_chest). -- Used to get a shared formspec ID and to swap the node back to the canonical version in on_construct. @@ -347,12 +376,12 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile return stack:get_count() - leftover:get_count() end - local small_name = "mcl_chests:"..basename.."_small" + local small_name = "mcl_chests:" .. basename .. "_small" local small_textures = tiles_table.small - local left_name = "mcl_chests:"..basename.."_left" + local left_name = "mcl_chests:" .. basename .. "_left" local left_textures = tiles_table.double - minetest.register_node("mcl_chests:"..basename, { + minetest.register_node("mcl_chests:" .. basename, { description = desc, _tt_help = tt_help, _doc_items_longdesc = longdesc, @@ -361,12 +390,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "mesh", mesh = "mcl_chests_chest.b3d", tiles = small_textures, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + use_texture_alpha = "opaque", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {deco_block=1}, + groups = { deco_block = 1 }, on_construct = function(pos, node) local node = minetest.get_node(pos) node.name = small_name @@ -379,9 +407,10 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local function close_forms(canonical_basename, pos) local players = minetest.get_connected_players() - for p=1, #players do + for p = 1, #players do if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z) + minetest.close_formspec(players[p]:get_player_name(), + "mcl_chests:" .. canonical_basename .. "_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) end end end @@ -395,19 +424,27 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", _chest_entity_textures = small_textures, _chest_entity_sound = "default_chest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, drop = drop, - groups = {handy=1,axey=1, container=2, deco_block=1, material_wood=1,flammable=-1,chest_entity=1, not_in_creative_inventory=1}, + groups = { + handy = 1, + axey = 1, + container = 2, + deco_block = 1, + material_wood = 1, + flammable = -1, + chest_entity = 1, + not_in_creative_inventory = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), on_construct = function(pos) @@ -424,7 +461,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile meta:set_string("workaround", nil) -- Done to keep metadata clean -- END OF WORKAROUND -- local inv = meta:get_inventory() - inv:set_size("main", 9*3) + inv:set_size("main", 9 * 3) --[[ The "input" list is *another* workaround (hahahaha!) around the fact that Minetest does not support listrings to put items into an alternative list if the first one happens to be full. See . @@ -435,19 +472,26 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- BEGIN OF LISTRING WORKAROUND inv:set_size("input", 1) -- END OF LISTRING WORKAROUND - if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == "mcl_chests:"..canonical_basename.."_small" then - minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_right",param2=param2}) + if minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "right")).name == + "mcl_chests:" .. canonical_basename .. "_small" then + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_right", param2 = param2 }) local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_left", param2 = param2 }) - create_entity(p, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") - elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == "mcl_chests:"..canonical_basename.."_small" then - minetest.swap_node(pos, {name="mcl_chests:"..canonical_basename.."_left",param2=param2}) - create_entity(pos, "mcl_chests:"..canonical_basename.."_left", left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") + minetest.swap_node(p, { name = "mcl_chests:" .. canonical_basename .. "_left", param2 = param2 }) + create_entity(p, "mcl_chests:" .. canonical_basename .. "_left", left_textures, param2, true, + "default_chest", + "mcl_chests_chest", "chest") + elseif minetest.get_node(mcl_util.get_double_container_neighbor_pos(pos, param2, "left")).name == + "mcl_chests:" .. canonical_basename .. "_small" then + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_left", param2 = param2 }) + create_entity(pos, "mcl_chests:" .. canonical_basename .. "_left", left_textures, param2, true, + "default_chest", + "mcl_chests_chest", "chest") local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - minetest.swap_node(p, { name = "mcl_chests:"..canonical_basename.."_right", param2 = param2 }) + minetest.swap_node(p, { name = "mcl_chests:" .. canonical_basename .. "_right", param2 = param2 }) else - minetest.swap_node(pos, { name = "mcl_chests:"..canonical_basename.."_small", param2 = param2 }) - create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") + minetest.swap_node(pos, { name = "mcl_chests:" .. canonical_basename .. "_small", param2 = param2 }) + create_entity(pos, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", + "chest") end end, after_place_node = function(pos, placer, itemstack, pointed_thing) @@ -459,30 +503,33 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile allow_metadata_inventory_take = protection_check_put_take, allow_metadata_inventory_put = protection_check_put_take, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) inv:add_item("main", stack) end -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + local topnode = minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }) + if topnode and topnode.name and minetest.registered_nodes[topnode.name] then + if minetest.registered_nodes[topnode.name].groups.opaque == 1 then + -- won't open if there is no space from the top + return false + end end local name = minetest.get_meta(pos):get_string("name") if name == "" then @@ -490,24 +537,31 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, - "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]".. - "listring[current_player;main]") + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos.x, pos.y, pos.z), + "label[0.375,4.7;" .. F(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;]", + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + "listring[current_player;main]", + }) + ) if on_rightclick_addendum then on_rightclick_addendum(pos, node, clicker) end - player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", + "mcl_chests_chest") end, on_destruct = function(pos) @@ -521,17 +575,26 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", _chest_entity_textures = left_textures, _chest_entity_sound = "default_chest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", paramtype = "light", paramtype2 = "facedir", - groups = {handy=1,axey=1, container=5,not_in_creative_inventory=1, material_wood=1,flammable=-1,chest_entity=1,double_chest=1}, + groups = { + handy = 1, + axey = 1, + container = 2, + not_in_creative_inventory = 1, + material_wood = 1, + flammable = -1, + chest_entity = 1, + double_chest = 1 + }, drop = drop, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -539,8 +602,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local n = minetest.get_node(pos) local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_right" then - n.name = "mcl_chests:"..canonical_basename.."_small" + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. canonical_basename .. "_right" then + n.name = "mcl_chests:" .. canonical_basename .. "_small" minetest.swap_node(pos, n) end create_entity(pos, left_name, left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") @@ -558,7 +621,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_right" then + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. basename .. "_right" then return end close_forms(canonical_basename, p) @@ -575,11 +638,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 - -- BEGIN OF LISTRING WORKAROUND + -- BEGIN OF LISTRING WORKAROUND elseif listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) return limit_put(stack, inv, other_inv) --[[if inv:room_for_item("main", stack) then return -1 @@ -590,24 +653,25 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile else return 0 end - end]]-- - -- END OF LISTRING WORKAROUND + end]] + -- + -- END OF LISTRING WORKAROUND else return stack:get_count() end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then - local inv = minetest.get_inventory({type="node", pos=pos}) + local inv = minetest.get_inventory({ type = "node", pos = pos }) local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "left") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) inv:set_stack("input", 1, nil) @@ -616,16 +680,17 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - local above_def = minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name] - local above_def_other = minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name] + local above_def = minetest.registered_nodes[minetest.get_node({ x = pos.x, y = pos.y + 1, z = pos.z }).name] + local above_def_other = minetest.registered_nodes[ + minetest.get_node({ x = pos_other.x, y = pos_other.y + 1, z = pos_other.z }).name] if not above_def or above_def.groups.opaque == 1 or not above_def_other or above_def_other.groups.opaque == 1 then -- won't open if there is no space from the top @@ -641,48 +706,92 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, - "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,3.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,7.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,7.5,9,3).. - "list[current_player;main;0,10.75;9,1;]".. - mcl_formspec.get_itemslot_bg(0,10.75,9,1).. - -- BEGIN OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";input]".. - -- END OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]".. - "listring[current_player;main]".. - "listring[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main]") + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,14.15]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos.x, pos.y, pos.z), + mcl_formspec.get_itemslot_bg_v4(0.375, 4.5, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,4.5;9,3;]", pos_other.x, pos_other.y, pos_other.z), + "label[0.375,8.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 8.825, 9, 3), + "list[current_player;main;0.375,8.825;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 12.775, 9, 1), + "list[current_player;main;0.375,12.775;9,1;]", + + --BEGIN OF LISTRING WORKAROUND + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;input]", pos.x, pos.y, pos.z), + --END OF LISTRING WORKAROUND + "listring[current_player;main]" .. + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;main]", pos_other.x, pos_other.y, pos_other.z), + }) + ) if on_rightclick_addendum_left then on_rightclick_addendum_left(pos, node, clicker) end - player_chest_open(clicker, pos, left_name, left_textures, node.param2, true, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos, left_name, left_textures, node.param2, true, "default_chest", + "mcl_chests_chest") end, mesecons = mesecons, 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", nil, 1) + 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", nil, 1) + return inv_other, "main", stack_id + end, }) - minetest.register_node("mcl_chests:"..basename.."_right", { + minetest.register_node("mcl_chests:" .. basename .. "_right", { drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", node_box = { type = "fixed", - fixed = {-0.5, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.5, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, + }, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", + groups = { + handy = 1, + axey = 1, + container = 2, + not_in_creative_inventory = 1, + material_wood = 1, + flammable = -1, + double_chest = 2 }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - groups = {handy=1,axey=1, container=6,not_in_creative_inventory=1, material_wood=1,flammable=-1,double_chest=2}, drop = drop, is_ground_content = false, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -690,8 +799,8 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local n = minetest.get_node(pos) local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..canonical_basename.."_left" then - n.name = "mcl_chests:"..canonical_basename.."_small" + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. canonical_basename .. "_left" then + n.name = "mcl_chests:" .. canonical_basename .. "_small" minetest.swap_node(pos, n) end end, @@ -708,7 +817,7 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "right") - if not p or minetest.get_node(p).name ~= "mcl_chests:"..basename.."_left" then + if not p or minetest.get_node(p).name ~= "mcl_chests:" .. basename .. "_left" then return end close_forms(canonical_basename, p) @@ -725,11 +834,11 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 - -- BEGIN OF LISTRING WORKAROUND + -- BEGIN OF LISTRING WORKAROUND elseif listname == "input" then local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) - local inv = minetest.get_inventory({type="node", pos=pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) + local inv = minetest.get_inventory({ type = "node", pos = pos }) --[[if other_inv:room_for_item("main", stack) then return -1 else @@ -740,23 +849,23 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end end--]] return limit_put(stack, other_inv, inv) - -- END OF LISTRING WORKAROUND + -- END OF LISTRING WORKAROUND else return stack:get_count() end end, on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - minetest.log("action", player:get_player_name().. - " moves stuff in chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_put = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " moves stuff to chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to chest at " .. minetest.pos_to_string(pos)) -- BEGIN OF LISTRING WORKAROUND if listname == "input" then local other_pos = mcl_util.get_double_container_neighbor_pos(pos, minetest.get_node(pos).param2, "right") - local other_inv = minetest.get_inventory({type="node", pos=other_pos}) - local inv = minetest.get_inventory({type="node", pos=pos}) + local other_inv = minetest.get_inventory({ type = "node", pos = other_pos }) + local inv = minetest.get_inventory({ type = "node", pos = pos }) inv:set_stack("input", 1, nil) @@ -765,18 +874,20 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile -- END OF LISTRING WORKAROUND end, on_metadata_inventory_take = function(pos, listname, index, stack, player) - minetest.log("action", player:get_player_name().. - " takes stuff from chest at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from chest at " .. minetest.pos_to_string(pos)) end, _mcl_blast_resistance = 2.5, _mcl_hardness = 2.5, on_rightclick = function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 - or minetest.registered_nodes[minetest.get_node({x = pos_other.x, y = pos_other.y + 1, z = pos_other.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + if minetest.registered_nodes[minetest.get_node(vector.offset(pos, 0, 1, 0)).name].groups.opaque == 1 + or + minetest.registered_nodes[minetest.get_node(vector.offset(pos_other, 0, 1, 0)).name].groups.opaque + == 1 then + -- won't open if there is no space from the top + return false end local name = minetest.get_meta(pos_other):get_string("name") @@ -788,41 +899,76 @@ local function register_chest(basename, desc, longdesc, usagehelp, tt_help, tile end minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, + sf("mcl_chests:%s_%s_%s_%s", canonical_basename, pos.x, pos.y, pos.z), + table.concat({ + "formspec_version[4]", + "size[11.75,14.15]", - "size[9,11.5]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,3.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,3.5,9,3).. - "label[0,7;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,7.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,7.5,9,3).. - "list[current_player;main;0,10.75;9,1;]".. - mcl_formspec.get_itemslot_bg(0,10.75,9,1).. - -- BEGIN OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";input]".. - -- END OF LISTRING WORKAROUND - "listring[current_player;main]".. - "listring[nodemeta:"..pos_other.x..","..pos_other.y..","..pos_other.z..";main]".. - "listring[current_player;main]".. - "listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]") + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,0.75;9,3;]", pos_other.x, pos_other.y, pos_other.z), + mcl_formspec.get_itemslot_bg_v4(0.375, 4.5, 9, 3), + sf("list[nodemeta:%s,%s,%s;main;0.375,4.5;9,3;]", pos.x, pos.y, pos.z), + "label[0.375,8.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 8.825, 9, 3), + "list[current_player;main;0.375,8.825;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 12.775, 9, 1), + "list[current_player;main;0.375,12.775;9,1;]", + + --BEGIN OF LISTRING WORKAROUND + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;input]", pos.x, pos.y, pos.z), + --END OF LISTRING WORKAROUND + "listring[current_player;main]" .. + sf("listring[nodemeta:%s,%s,%s;main]", pos_other.x, pos_other.y, pos_other.z), + "listring[current_player;main]", + sf("listring[nodemeta:%s,%s,%s;main]", pos.x, pos.y, pos.z), + }) + ) if on_rightclick_addendum_right then on_rightclick_addendum_right(pos, node, clicker) end - player_chest_open(clicker, pos_other, left_name, left_textures, node.param2, true, "default_chest", "mcl_chests_chest") + player_chest_open(clicker, pos_other, left_name, left_textures, node.param2, true, "default_chest", + "mcl_chests_chest") end, mesecons = mesecons, 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", nil, 1) + 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", nil, 1) + return inv, "main", stack_id + end, }) if mod_doc then - doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:"..basename.."_left") - doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:"..basename.."_right") + doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:" .. basename .. "_left") + doc.add_entry_alias("nodes", small_name, "nodes", "mcl_chests:" .. basename .. "_right") end -- END OF register_chest FUNCTION BODY @@ -838,6 +984,15 @@ register_chest("chest", { small = tiles_chest_normal_small, double = tiles_chest_normal_double, + inv = { "default_chest_top.png", "mcl_chests_chest_bottom.png", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "mcl_chests_chest_back.png", "default_chest_front.png" }, + --[[left = {"default_chest_top_big.png", "default_chest_top_big.png", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "default_chest_side_big.png^[transformFX", "default_chest_front_big.png"}, + right = {"default_chest_top_big.png^[transformFX", "default_chest_top_big.png^[transformFX", + "mcl_chests_chest_right.png", "mcl_chests_chest_left.png", + "default_chest_side_big.png", "default_chest_front_big.png^[transformFX"},]] -- }, false ) @@ -851,48 +1006,57 @@ register_chest("trapped_chest", S("Trapped Chest"), S("A trapped chest is a container which provides 27 inventory slots. When it is opened, it sends a redstone signal to its adjacent blocks as long it stays open. Trapped chests can be turned into large trapped chests with double the capacity by placing two trapped chests next to each other."), chestusage, - S("27 inventory slots") .. "\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"), + S("27 inventory slots") .. + "\n" .. S("Can be combined to a large chest") .. "\n" .. S("Emits a redstone signal when opened"), traptiles, nil, - {receptor = { - state = mesecon.state.off, - rules = trapped_chest_mesecons_rules, - }}, + { + receptor = { + state = mesecon.state.off, + rules = trapped_chest_mesecons_rules, + }, + }, function(pos, node, clicker) - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_small", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", {"mcl_chests_trapped.png"}, node.param2, false, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_small", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_on_small", { "mcl_chests_trapped.png" }, node.param2, false, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_small") mesecon.receptor_on(pos, trapped_chest_mesecons_rules) end, function(pos, node, clicker) local meta = minetest.get_meta(pos) meta:set_int("players", 1) - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2}) - find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_left", param2 = node.param2 }) + find_or_create_entity(pos, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") mesecon.receptor_on(pos, trapped_chest_mesecons_rules) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_on_right", param2 = node.param2 }) mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules) end, function(pos, node, clicker) local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "right") - minetest.swap_node(pos, {name="mcl_chests:trapped_chest_on_right", param2 = node.param2}) + minetest.swap_node(pos, { name = "mcl_chests:trapped_chest_on_right", param2 = node.param2 }) mesecon.receptor_on(pos, trapped_chest_mesecons_rules) - minetest.swap_node(pos_other, {name="mcl_chests:trapped_chest_on_left", param2 = node.param2}) - find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + minetest.swap_node(pos_other, { name = "mcl_chests:trapped_chest_on_left", param2 = node.param2 }) + find_or_create_entity(pos_other, "mcl_chests:trapped_chest_on_left", tiles_chest_trapped_double, node.param2, + true, + "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") mesecon.receptor_on(pos_other, trapped_chest_mesecons_rules) end ) register_chest("trapped_chest_on", nil, nil, nil, nil, traptiles, true, - {receptor = { - state = mesecon.state.on, - rules = trapped_chest_mesecons_rules, - }}, + { + receptor = { + state = mesecon.state.on, + rules = trapped_chest_mesecons_rules, + }, + }, nil, nil, nil, "trapped_chest", "trapped_chest" @@ -946,77 +1110,86 @@ end) minetest.register_craft({ output = "mcl_chests:chest", recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"group:wood", "", "group:wood"}, - {"group:wood", "group:wood", "group:wood"}, - } + { "group:wood", "group:wood", "group:wood" }, + { "group:wood", "", "group:wood" }, + { "group:wood", "group:wood", "group:wood" }, + }, }) minetest.register_craft({ type = "fuel", recipe = "mcl_chests:chest", - burntime = 15 + burntime = 15, }) minetest.register_craft({ type = "fuel", recipe = "mcl_chests:trapped_chest", - burntime = 15 + burntime = 15, }) minetest.register_node("mcl_chests:ender_chest", { description = S("Ender Chest"), - _tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"), - _doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), + _tt_help = S("27 interdimensional inventory slots") .. + "\n" .. S("Put items inside, retrieve them from any ender chest"), + _doc_items_longdesc = S( + "Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), _doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."), drawtype = "mesh", mesh = "mcl_chests_chest.b3d", tiles = tiles_chest_ender_small, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + use_texture_alpha = "opaque", paramtype = "light", paramtype2 = "facedir", - stack_max = 64, - groups = {deco_block=1}, + groups = { deco_block = 1 }, sounds = mcl_sounds.node_sound_stone_defaults(), - on_construct = function(pos, node) + on_construct = function(pos) local node = minetest.get_node(pos) node.name = "mcl_chests:ender_chest_small" minetest.set_node(pos, node) end, }) -local formspec_ender_chest = "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Ender Chest"))).."]".. - "list[current_player;enderchest;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[current_player;enderchest]".. - "listring[current_player;main]" +local formspec_ender_chest = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Ender Chest"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[current_player;enderchest;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(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;enderchest]", + "listring[current_player;main]", +}) minetest.register_node("mcl_chests:ender_chest_small", { description = S("Ender Chest"), - _tt_help = S("27 interdimensional inventory slots") .. "\n" .. S("Put items inside, retrieve them from any ender chest"), - _doc_items_longdesc = S("Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), + _tt_help = S("27 interdimensional inventory slots") .. + "\n" .. S("Put items inside, retrieve them from any ender chest"), + _doc_items_longdesc = S( + "Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players."), _doc_items_usagehelp = S("Rightclick the ender chest to access your personal interdimensional inventory."), drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, + fixed = { -0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375 }, }, _chest_entity_textures = ender_chest_texture, _chest_entity_sound = "mcl_chests_enderchest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", -- Note: The “container” group is missing here because the ender chest does not -- have an inventory on its own - groups = {pickaxey=1, deco_block=1, material_stone=1, chest_entity=1, not_in_creative_inventory=1}, + groups = { pickaxey = 1, deco_block = 1, material_stone = 1, chest_entity = 1, not_in_creative_inventory = 1 }, is_ground_content = false, paramtype = "light", light_source = 7, @@ -1024,15 +1197,18 @@ minetest.register_node("mcl_chests:ender_chest_small", { sounds = mcl_sounds.node_sound_stone_defaults(), drop = "mcl_core:obsidian 8", on_construct = function(pos) - create_entity(pos, "mcl_chests:ender_chest_small", ender_chest_texture, minetest.get_node(pos).param2, false, "mcl_chests_enderchest", "mcl_chests_chest", "chest") + create_entity(pos, "mcl_chests:ender_chest_small", ender_chest_texture, minetest.get_node(pos).param2, false, + "mcl_chests_enderchest", "mcl_chests_chest", "chest") end, on_rightclick = function(pos, node, clicker) - if minetest.registered_nodes[minetest.get_node({x = pos.x, y = pos.y + 1, z = pos.z}).name].groups.opaque == 1 then - -- won't open if there is no space from the top - return false + if minetest.registered_nodes[minetest.get_node(vector.offset(pos, 0, 1, 0)).name].groups.opaque == 1 then + -- won't open if there is no space from the top + return false end - minetest.show_formspec(clicker:get_player_name(), "mcl_chests:ender_chest_"..clicker:get_player_name(), formspec_ender_chest) - player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", ender_chest_texture, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest") + minetest.show_formspec(clicker:get_player_name(), "mcl_chests:ender_chest_" .. clicker:get_player_name(), + formspec_ender_chest) + player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", ender_chest_texture, node.param2, false, + "mcl_chests_enderchest", "mcl_chests_chest") end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1041,21 +1217,21 @@ minetest.register_node("mcl_chests:ender_chest_small", { end, _mcl_blast_resistance = 3000, _mcl_hardness = 22.5, - _mcl_silk_touch_drop = {"mcl_chests:ender_chest"}, + _mcl_silk_touch_drop = { "mcl_chests:ender_chest" }, on_rotate = simple_rotate, }) minetest.register_on_joinplayer(function(player) local inv = player:get_inventory() - inv:set_size("enderchest", 9*3) + inv:set_size("enderchest", 9 * 3) end) minetest.register_allow_player_inventory_action(function(player, action, inv, info) if inv:get_location().type == "player" and ( - action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest") - or action == "put" and info.listname == "enderchest" - or action == "take" and info.listname == "enderchest" - ) then + action == "move" and (info.from_list == "enderchest" or info.to_list == "enderchest") + or action == "put" and info.listname == "enderchest" + or action == "take" and info.listname == "enderchest" + ) then local def = player:get_wielded_item():get_definition() local range = (def and def.range or player:get_inventory():get_stack("hand", 1):get_definition().range) + 1 if not minetest.find_node_near(player:get_pos(), range, "mcl_chests:ender_chest_small", true) then @@ -1067,10 +1243,10 @@ end) minetest.register_craft({ output = "mcl_chests:ender_chest", recipe = { - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, - {"mcl_core:obsidian", "mcl_end:ender_eye", "mcl_core:obsidian"}, - {"mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian"}, - } + { "mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian" }, + { "mcl_core:obsidian", "mcl_end:ender_eye", "mcl_core:obsidian" }, + { "mcl_core:obsidian", "mcl_core:obsidian", "mcl_core:obsidian" }, + }, }) -- Shulker boxes @@ -1113,21 +1289,29 @@ local shulker_mob_textures = { } local canonical_shulker_color = "violet" +--WARNING: after formspec v4 update, old shulker boxes will need to be placed again to get the new formspec local function formspec_shulker_box(name) - if name == "" then + if not name or name == "" then name = S("Shulker Box") end - return "size[9,8.75]".. - "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[context;main;0,0.5;9,3;]".. - mcl_formspec.get_itemslot_bg(0,0.5,9,3).. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "listring[context;main]".. - "listring[current_player;main]" + + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, name)) .. "]", + mcl_formspec.get_itemslot_bg_v4(0.375, 0.75, 9, 3), + "list[context;main;0.375,0.75;9,3;]", + "label[0.375,4.7;" .. F(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[context;main]", + "listring[current_player;main]", + }) end local function set_shulkerbox_meta(nmeta, imeta) @@ -1143,28 +1327,38 @@ for color, desc in pairs(boxtypes) do local longdesc, usagehelp, create_entry, entry_name if mod_doc then if is_canonical then - longdesc = S("A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.") - usagehelp = S("To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.") + longdesc = S( + "A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.") + usagehelp = S( + "To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.") entry_name = S("Shulker Box") else create_entry = false end end - local small_name = "mcl_chests:"..color.."_shulker_box_small" + local small_name = "mcl_chests:" .. color .. "_shulker_box_small" - minetest.register_node("mcl_chests:"..color.."_shulker_box", { + minetest.register_node("mcl_chests:" .. color .. "_shulker_box", { description = desc, _tt_help = S("27 inventory slots") .. "\n" .. S("Can be carried around with its contents"), _doc_items_create_entry = create_entry, _doc_items_entry_name = entry_name, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - tiles = {mob_texture}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + tiles = { mob_texture }, + use_texture_alpha = "opaque", drawtype = "mesh", mesh = "mcl_chests_shulker.b3d", - groups = {handy=1,pickaxey=1, container=3, deco_block=1, dig_by_piston=1, shulker_box=1, old_shulker_box_node=1}, + groups = { + handy = 1, + pickaxey = 1, + container = 2, + deco_block = 1, + dig_by_piston = 1, + shulker_box = 1, + old_shulker_box_node = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 1, @@ -1182,7 +1376,7 @@ for color, desc in pairs(boxtypes) do local iinv_main = minetest.deserialize(imetadata) local ninv = nmeta:get_inventory() ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(nmeta, itemstack:get_meta()) if minetest.is_creative_enabled(placer:get_player_name()) then @@ -1198,12 +1392,12 @@ for color, desc in pairs(boxtypes) do _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Place shulker box as node if minetest.registered_nodes[dropnode.name].buildable_to then - minetest.set_node(droppos, {name = small_name, param2 = minetest.dir_to_facedir(dropdir)}) - local ninv = minetest.get_inventory({type="node", pos=droppos}) + minetest.set_node(droppos, { name = small_name, param2 = minetest.dir_to_facedir(dropdir) }) + local ninv = minetest.get_inventory({ type = "node", pos = droppos }) local imetadata = stack:get_metadata() local iinv_main = minetest.deserialize(imetadata) ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(minetest.get_meta(droppos), stack:get_meta()) stack:take_item() end @@ -1221,30 +1415,40 @@ for color, desc in pairs(boxtypes) do drawtype = "nodebox", node_box = { type = "fixed", - fixed = {-0.48, -0.5, -0.48, 0.48, 0.489, 0.48}, + fixed = { -0.48, -0.5, -0.48, 0.48, 0.489, 0.48 }, }, - tiles = {"blank.png^[resize:16x16"}, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, - _chest_entity_textures = {mob_texture}, + tiles = { "blank.png^[resize:16x16" }, + use_texture_alpha = "clip", + _chest_entity_textures = { mob_texture }, _chest_entity_sound = "mcl_chests_shulker", _chest_entity_mesh = "mcl_chests_shulker", _chest_entity_animation_type = "shulker", - groups = {handy=1,pickaxey=1, container=3, deco_block=1, dig_by_piston=1, shulker_box=1, chest_entity=1, not_in_creative_inventory=1}, + groups = { + handy = 1, + pickaxey = 1, + container = 2, + deco_block = 1, + dig_by_piston = 1, + shulker_box = 1, + chest_entity = 1, + not_in_creative_inventory = 1 + }, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 1, drop = "", paramtype = "light", paramtype2 = "facedir", --- TODO: Make shulker boxes rotatable --- This doesn't work, it just destroys the inventory: --- on_place = minetest.rotate_node, + -- TODO: Make shulker boxes rotatable + -- This doesn't work, it just destroys the inventory: + -- on_place = minetest.rotate_node, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", formspec_shulker_box(nil)) local inv = meta:get_inventory() - inv:set_size("main", 9*3) - create_entity(pos, small_name, {mob_texture}, minetest.get_node(pos).param2, false, "mcl_chests_shulker", "mcl_chests_shulker", "shulker") + inv:set_size("main", 9 * 3) + create_entity(pos, small_name, { mob_texture }, minetest.get_node(pos).param2, false, "mcl_chests_shulker", + "mcl_chests_shulker", "shulker") end, after_place_node = function(pos, placer, itemstack, pointed_thing) local nmeta = minetest.get_meta(pos) @@ -1252,7 +1456,7 @@ for color, desc in pairs(boxtypes) do local iinv_main = minetest.deserialize(imetadata) local ninv = nmeta:get_inventory() ninv:set_list("main", iinv_main) - ninv:set_size("main", 9*3) + ninv:set_size("main", 9 * 3) set_shulkerbox_meta(nmeta, itemstack:get_meta()) if minetest.is_creative_enabled(placer:get_player_name()) then @@ -1266,7 +1470,8 @@ for color, desc in pairs(boxtypes) do end end, on_rightclick = function(pos, node, clicker) - player_chest_open(clicker, pos, small_name, {mob_texture}, node.param2, false, "mcl_chests_shulker", "mcl_chests_shulker", true) + player_chest_open(clicker, pos, small_name, { mob_texture }, node.param2, false, "mcl_chests_shulker", + "mcl_chests_shulker", true) end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1277,12 +1482,12 @@ for color, desc in pairs(boxtypes) do local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local items = {} - for i=1, inv:get_size("main") do + for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) items[i] = stack:to_string() end local data = minetest.serialize(items) - local boxitem = ItemStack("mcl_chests:"..color.."_shulker_box") + local boxitem = ItemStack("mcl_chests:" .. color .. "_shulker_box") local boxitem_meta = boxitem:get_meta() boxitem_meta:set_string("description", meta:get_string("description")) boxitem_meta:set_string("name", meta:get_string("name")) @@ -1314,27 +1519,42 @@ for color, desc in pairs(boxtypes) do end, _mcl_blast_resistance = 6, _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, 1) + end, }) if mod_doc and not is_canonical then - doc.add_entry_alias("nodes", "mcl_chests:"..canonical_shulker_color.."_shulker_box", "nodes", "mcl_chests:"..color.."_shulker_box") - doc.add_entry_alias("nodes", "mcl_chests:"..canonical_shulker_color.."_shulker_box_small", "nodes", "mcl_chests:"..color.."_shulker_box_small") + doc.add_entry_alias("nodes", "mcl_chests:" .. canonical_shulker_color .. "_shulker_box", "nodes", + "mcl_chests:" .. color .. "_shulker_box") + doc.add_entry_alias("nodes", "mcl_chests:" .. canonical_shulker_color .. "_shulker_box_small", "nodes", + "mcl_chests:" .. color .. "_shulker_box_small") end minetest.register_craft({ type = "shapeless", - output = "mcl_chests:"..color.."_shulker_box", - recipe = { "group:shulker_box", "mcl_dye:"..color } + output = "mcl_chests:" .. color .. "_shulker_box", + recipe = { "group:shulker_box", "mcl_dye:" .. color }, }) 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({ output = "mcl_chests:violet_shulker_box", recipe = { - {"mcl_mobitems:shulker_shell"}, - {"mcl_chests:chest"}, - {"mcl_mobitems:shulker_shell"}, - } + { "mcl_mobitems:shulker_shell" }, + { "mcl_chests:chest" }, + { "mcl_mobitems:shulker_shell" }, + }, }) -- Save metadata of shulker box when used in crafting @@ -1362,13 +1582,14 @@ local function select_and_spawn_entity(pos, node) local node_name = node.name local node_def = minetest.registered_nodes[node_name] local double_chest = minetest.get_item_group(node_name, "double_chest") > 0 - find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type) + find_or_create_entity(pos, node_name, node_def._chest_entity_textures, node.param2, double_chest, + node_def._chest_entity_sound, node_def._chest_entity_mesh, node_def._chest_entity_animation_type) end minetest.register_lbm({ label = "Spawn Chest entities", name = "mcl_chests:spawn_chest_entities", - nodenames = {"group:chest_entity"}, + nodenames = { "group:chest_entity" }, run_at_every_load = true, action = select_and_spawn_entity, }) @@ -1376,7 +1597,9 @@ minetest.register_lbm({ minetest.register_lbm({ label = "Replace old chest nodes", name = "mcl_chests:replace_old", - nodenames = {"mcl_chests:chest", "mcl_chests:trapped_chest", "mcl_chests:trapped_chest_on", "mcl_chests:ender_chest", "group:old_shulker_box_node"}, + nodenames = { "mcl_chests:chest", "mcl_chests:trapped_chest", "mcl_chests:trapped_chest_on", + "mcl_chests:ender_chest", + "group:old_shulker_box_node" }, run_at_every_load = true, action = function(pos, node) local node_name = node.name @@ -1384,7 +1607,7 @@ minetest.register_lbm({ minetest.swap_node(pos, node) select_and_spawn_entity(pos, node) if node_name == "mcl_chests:trapped_chest_on" then - minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " ..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos)) chest_update_after_close(pos) elseif node_name == "mcl_chests:ender_chest" then local meta = minetest.get_meta(pos) @@ -1399,29 +1622,30 @@ minetest.register_lbm({ -- Fixes redstone weirdness. label = "Disable active trapped chests", name = "mcl_chests:reset_trapped_chests", - nodenames = { "mcl_chests:trapped_chest_on_small", "mcl_chests:trapped_chest_on_left", "mcl_chests:trapped_chest_on_right" }, + nodenames = { "mcl_chests:trapped_chest_on_small", "mcl_chests:trapped_chest_on_left", + "mcl_chests:trapped_chest_on_right" }, run_at_every_load = true, action = function(pos, node) - minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " ..minetest.pos_to_string(pos)) + minetest.log("action", "[mcl_chests] Disabled active trapped chest on load: " .. minetest.pos_to_string(pos)) chest_update_after_close(pos) end, }) minetest.register_lbm({ - label = "Update shulker box formspecs (0.60.0)", - name = "mcl_chests:update_shulker_box_formspecs_0_60_0", + label = "Update shulker box formspecs (0.72.0)", + name = "mcl_chests:update_shulker_box_formspecs_0_72_0", nodenames = { "group:shulker_box" }, run_at_every_load = false, action = function(pos, node) local meta = minetest.get_meta(pos) - meta:set_string("formspec", formspec_shulker_box) + meta:set_string("formspec", formspec_shulker_box(meta:get_string("name"))) end, }) minetest.register_lbm({ label = "Upgrade old ender chest formspec", name = "mcl_chests:replace_old_ender_form", - nodenames = {"mcl_chests:ender_chest_small"}, + nodenames = { "mcl_chests:ender_chest_small" }, run_at_every_load = false, action = function(pos, node) minetest.get_meta(pos):set_string("formspec", "") diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.ru.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.ru.tr index dc25458c2..6bdb1783b 100644 --- a/mods/ITEMS/mcl_chests/locale/mcl_chests.ru.tr +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.ru.tr @@ -1,36 +1,36 @@ # textdomain: mcl_chests Chest=Сундук -Chests are containers which provide 27 inventory slots. Chests can be turned into large chests with double the capacity by placing two chests next to each other.=Сундуки это хранилища, предоставляющие 27 отсеков инвентаря. Сундук можно превратить в большой сундук, удвоив его вместительность, для этого нужно поставить ещё один сундук рядом с уже имеющимся. -To access its inventory, rightclick it. When broken, the items will drop out.=Чтобы получить доступ к инвентарю, кликните по сундуку правой клавишей. Если сломать сундук, то он превратится в носимый предмет. +Chests are containers which provide 27 inventory slots. Chests can be turned into large chests with double the capacity by placing two chests next to each other.=Сундук это хранилище, предоставляющее 27 слотов инвентаря. Сундук можно превратить в большой сундук с двойной вместительностью, если поставить ещё один сундук рядом с уже имеющимся. +To access its inventory, rightclick it. When broken, the items will drop out.=Чтобы открыть инвентарь сундука, кликните по нему правой кнопкой мыши. Если сломать сундук, вещи из его инвентаря выпадут. Trapped Chest=Сундук-ловушка -A trapped chest is a container which provides 27 inventory slots. When it is opened, it sends a redstone signal to its adjacent blocks as long it stays open. Trapped chests can be turned into large trapped chests with double the capacity by placing two trapped chests next to each other.=Сундук-ловушка - это хранилище, предоставляющее 27 отсеков инвентаря. При открытии он посылает сигнал редстоуна соседним блокам всё время, пока остается открытым. Сундук-ловушку можно превратить в большой сундук-ловушку, удвоив его вместительность, для этого нужно поставить ещё один сундук-ловушку рядом с уже имеющимся. -Ender Chest=Сундук Предела -Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players.=Сундук Предела предоставляет вам доступ к одиночному персональному межпространственному инвентарю из 27 отсеков. Этот инвентарь остаётся прежним, неважно какой из сундуков Предела вы используете для доступа к нему. Если вы положите предмет в сундук Предела, вы обнаружите его во всех остальных сундуках Предела. Каждый игрок видит только свои собственные предметы и не видит предметы остальных игроков. -Rightclick the ender chest to access your personal interdimensional inventory.=Кликните правой по сундуку Предела, чтобы получить доступ к вашему персональному межпространственному инвентарю. +A trapped chest is a container which provides 27 inventory slots. When it is opened, it sends a redstone signal to its adjacent blocks as long it stays open. Trapped chests can be turned into large trapped chests with double the capacity by placing two trapped chests next to each other.=Сундук-ловушка это хранилище, предоставляющее 27 слотов инвентаря. Когда сундук-ловушка открыт, он посылает сигнал редстоуна рядом стоящим блокам. Сундук-ловушку можно превратить в большой сундук-ловушку с двойной вместительностью, если поставить ещё один сундук-ловушку рядом с уже имеющимся. +Ender Chest=Сундук Края +Ender chests grant you access to a single personal interdimensional inventory with 27 slots. This inventory is the same no matter from which ender chest you access it from. If you put one item into one ender chest, you will find it in all other ender chests. Each player will only see their own items, but not the items of other players.=Сундук Края предоставляет вам доступ к персональному межпространственному инвентарю из 27 слотов. Этот инвентарь остаётся прежним, неважно какой из сундуков Края вы используете для доступа к нему. Если вы положите предмет в сундук Предела, вы обнаружите его во всех остальных сундуках Предела. Каждый игрок видит только свои собственные предметы и не видит предметы остальных игроков. +Rightclick the ender chest to access your personal interdimensional inventory.=Кликните правой кнопкой мыши по сундуку Края, чтобы получить доступ к вашему персональному межпространственному инвентарю. White Shulker Box=Белый ящик шалкера Light Grey Shulker Box=Светло-серый ящик шалкера Orange Shulker Box=Оранжевый ящик шалкера -Cyan Shulker Box=Голубой ящик шалкера -Magenta Shulker Box=Фиолетовый ящик шалкера -Purple Shulker Box=Пурпурный ящик шалкера -Light Blue Shulker Box=Светло-голубой ящик шалкера +Cyan Shulker Box=Бирюзовый ящик шалкера +Magenta Shulker Box=Сиреневый ящик шалкера +Purple Shulker Box=Фиолетовый ящик шалкера +Light Blue Shulker Box=Голубой ящик шалкера Blue Shulker Box=Синий ящик шалкера Yellow Shulker Box=Жёлтый ящик шалкера Brown Shulker Box=Коричневый ящик шалкера -Lime Shulker Box=Зелёный лаймовый ящик шалкера +Lime Shulker Box=Лаймовый ящик шалкера Green Shulker Box=Зелёный ящик шалкера Pink Shulker Box=Розовый ящик шалкера Red Shulker Box=Красный ящик шалкера Grey Shulker Box=Серый ящик шалкера Black Shulker Box=Чёрный ящик шалкера -A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.=Ящик шалкера это переносное хранилище, предоставляющее 27 отсеков инвентаря для любых предметов, за исключением ящиков шалкера. Ящики шалкера сохраняют в себе инвентарь, если их сломать, так что их вместе со всем инвентарём можно переносить как один предмет. Ящики шалкера могут быть разных цветов. -To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.=Чтобы получить доступ к инвентарю ящика шалкера, поставьте его куда-нибудь и кликните по нему правой клавишей. Чтобы взять с собой ящик шалкера со всем его содержимым, просто сломайте его, а потом подберите, ни один предмет из него не выпадет. Чтобы вновь получить доступ к содержимому, его надо снова поставить. +A shulker box is a portable container which provides 27 inventory slots for any item except shulker boxes. Shulker boxes keep their inventory when broken, so shulker boxes as well as their contents can be taken as a single item. Shulker boxes come in many different colors.=Ящик шалкера это переносное хранилище, предоставляющее 27 слотов инвентаря для любых предметов, за исключением ящиков шалкера. Ящики шалкера сохраняют в себе инвентарь если их сломать, так что их вместе со всем инвентарём можно переносить как один предмет. Ящики шалкера могут быть разных цветов. +To access the inventory of a shulker box, place and right-click it. To take a shulker box and its contents with you, just break and collect it, the items will not fall out. Place the shulker box again to be able to retrieve its contents.=Чтобы получить доступ к инвентарю ящика шалкера поставьте его и кликните по нему правой кнопкой мыши. Чтобы взять с собой ящик шалкера со всем его содержимым просто сломайте его, а потом подберите, ни один предмет из него не выпадет. Чтобы вновь получить доступ к содержимому, его нужно снова поставить. Shulker Box=Ящик шалкера Large Chest=Большой сундук Inventory=Инвентарь -27 inventory slots=27 отсеков инвентаря -Can be carried around with its contents=Можно переносить вместе со всем содержимым +27 inventory slots=27 слотов инвентаря +Can be carried around with its contents=Можно переносить вместе с содержимым Can be combined to a large chest=Можно объединить в большой сундук -27 interdimensional inventory slots=27 межпространственных отсеков инвентаря -Put items inside, retrieve them from any ender chest=Положите внутрь предмет и получите его из любого сундука Предела +27 interdimensional inventory slots=27 межпространственных слотов инвентаря +Put items inside, retrieve them from any ender chest=Положите внутрь предмет и получите его из любого сундука Края Emits a redstone signal when opened=Подаёт сигнал редстоуна, будучи открытым diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.ru.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.ru.tr index dca0f960c..bb24223a2 100644 --- a/mods/ITEMS/mcl_clock/locale/mcl_clock.ru.tr +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_clock Clocks are tools which shows the current time of day in the Overworld.=Часы это инструмент, показывающий текущее время Верхнего Мира. -The clock contains a rotating disc with a sun symbol (yellow disc) and moon symbol and a little “pointer” which shows the current time of day by estimating the real position of the sun and the moon in the sky. Noon is represented by the sun symbol and midnight is represented by the moon symbol.=Часы имеют вращающийся диск со значком солнца (жёлтый диск) и луны, а также маленькую стрелку, которая показывает время, обозначая реальное положение солнца и луны в небе. Полдень обозначается символом солнца, а полночь символом луны. +The clock contains a rotating disc with a sun symbol (yellow disc) and moon symbol and a little “pointer” which shows the current time of day by estimating the real position of the sun and the moon in the sky. Noon is represented by the sun symbol and midnight is represented by the moon symbol.=Часы имеют вращающийся диск со значком солнца и луны, а также маленькую стрелку, которая показывает время, обозначая реальное положение солнца и луны в небе. Полдень обозначается символом солнца, а полночь символом луны. Clock=Часы Displays the time of day in the Overworld=Показывают время Верхнего Мира diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr index 4501fc1be..41336b19f 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Sementes de Cacau +Grows at the side of jungle trees=Cresce nas laterais de árvores da selva. +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Sementes de cacau podem ser usadas para plantar cacau, cozinhar biscoitos e fabricar corante marrom. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clique com o botão direito na lateral de um tronco de árvore da selva (Madeira da Selva) para plantar um cacau jovem. Premature Cocoa Pod=Vagem de Cacau Prematuro Cocoa pods grow on the side of jungle trees in 3 stages.=Vagens de cacau crescem ao lado de árvores de selva em 3 estágios. Medium Cocoa Pod=Vagem de Cacau Média diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr index 064c01fd3..acce2fa83 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr @@ -1,10 +1,10 @@ # textdomain: mcl_cocoas Cocoa Beans=Какао-бобы -Grows at the side of jungle trees=Растут на стволах деревьев джунглей +Grows at the side of jungle trees=Растут на стволах тропических деревьев Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Какао-бобы можно использовать для посадки какао, выпечки печенья или изготовления коричневого красителя. -Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по боковой части ствола дерева джунглей, чтобы посадить молодое какао. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао. Premature Cocoa Pod=Молодой стручок какао Cocoa pods grow on the side of jungle trees in 3 stages.=Стручки какао растут на деревьях джунглей в 3 этапа. Medium Cocoa Pod=Средний стручок какао Mature Cocoa Pod=Зрелый стручок какао -A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further.=Зрелый стручок какао вырос на дереве джунглей до своего полного размера и готов к сбору в качестве какао-бобов. Дальше ему расти некуда. +A mature cocoa pod grew on a jungle tree to its full size and it is ready to be harvested for cocoa beans. It won't grow any further.=Зрелый стручок какао вырос на тропическом дереве до своего полного размера и готов к сбору в качестве какао-бобов. Стручок не будет расти дальше. diff --git a/mods/ITEMS/mcl_colorblocks/init.lua b/mods/ITEMS/mcl_colorblocks/init.lua index 6eec8a9df..dff30484a 100644 --- a/mods/ITEMS/mcl_colorblocks/init.lua +++ b/mods/ITEMS/mcl_colorblocks/init.lua @@ -4,27 +4,28 @@ local doc_mod = minetest.get_modpath("doc") local block = {} block.dyes = { - {"white", S("White Terracotta"), S("White Glazed Terracotta"), S("White Concrete Powder"), S("White Concrete"), "white"}, - {"grey", S("Grey Terracotta"), S("Grey Glazed Terracotta"), S("Grey Concrete Powder"), S("Grey Concrete"), "dark_grey"}, - {"silver", S("Light Grey Terracotta"), S("Light Grey Glazed Terracotta"), S("Light Grey Concrete Powder"), S("Light Grey Concrete"), "grey"}, - {"black", S("Black Terracotta"), S("Black Glazed Terracotta"), S("Black Concrete Powder"), S("Black Concrete"), "black"}, - {"red", S("Red Terracotta"), S("Red Glazed Terracotta"), S("Red Concrete Powder"), S("Red Concrete"), "red"}, - {"yellow", S("Yellow Terracotta"), S("Yellow Glazed Terracotta"), S("Yellow Concrete Powder"), S("Yellow Concrete"), "yellow"}, - {"green", S("Green Terracotta"), S("Green Glazed Terracotta"), S("Green Concrete Powder"), S("Green Concrete"), "dark_green"}, - {"cyan", S("Cyan Terracotta"), S("Cyan Glazed Terracotta"), S("Cyan Concrete Powder"), S("Cyan Concrete"), "cyan"}, - {"blue", S("Blue Terracotta"), S("Blue Glazed Terracotta"), S("Blue Concrete Powder"), S("Blue Concrete"), "blue"}, - {"magenta", S("Magenta Terracotta"), S("Magenta Glazed Terracotta"), S("Magenta Concrete Powder"), S("Magenta Concrete"), "magenta"}, - {"orange", S("Orange Terracotta"), S("Orange Glazed Terracotta"), S("Orange Concrete Powder"), S("Orange Concrete"), "orange"}, - {"purple", S("Purple Terracotta"), S("Purple Glazed Terracotta"), S("Purple Concrete Powder"), S("Purple Concrete"), "violet"}, - {"brown", S("Brown Terracotta"), S("Brown Glazed Terracotta"), S("Brown Concrete Powder"), S("Brown Concrete"), "brown"}, - {"pink", S("Pink Terracotta"), S("Pink Glazed Terracotta"), S("Pink Concrete Powder"), S("Pink Concrete"), "pink"}, - {"lime", S("Lime Terracotta"), S("Lime Glazed Terracotta"), S("Lime Concrete Powder"), S("Lime Concrete"), "green"}, - {"light_blue", S("Light Blue Terracotta"), S("Light Blue Glazed Terracotta"), S("Light Blue Concrete Powder"), S("Light Blue Concrete"), "lightblue"}, + {"white", S("White Terracotta"), S("White Glazed Terracotta"), S("White Glazed Terracotta Pillar"), S("White Concrete Powder"), S("White Concrete"), "white"}, + {"grey", S("Grey Terracotta"), S("Grey Glazed Terracotta"), S("Grey Glazed Terracotta Pillar"), S("Grey Concrete Powder"), S("Grey Concrete"), "dark_grey"}, + {"silver", S("Light Grey Terracotta"), S("Light Grey Glazed Terracotta"), S("Light Grey Glazed Terracotta Pillar"), S("Light Grey Concrete Powder"), S("Light Grey Concrete"), "grey"}, + {"black", S("Black Terracotta"), S("Black Glazed Terracotta"), S("Black Glazed Terracotta Pillar"), S("Black Concrete Powder"), S("Black Concrete"), "black"}, + {"red", S("Red Terracotta"), S("Red Glazed Terracotta"), S("Red Glazed Terracotta Pillar"), S("Red Concrete Powder"), S("Red Concrete"), "red"}, + {"yellow", S("Yellow Terracotta"), S("Yellow Glazed Terracotta"), S("Yellow Glazed Terracotta Pillar"), S("Yellow Concrete Powder"), S("Yellow Concrete"), "yellow"}, + {"green", S("Green Terracotta"), S("Green Glazed Terracotta"), S("Green Glazed Terracotta Pillar"), S("Green Concrete Powder"), S("Green Concrete"), "dark_green"}, + {"cyan", S("Cyan Terracotta"), S("Cyan Glazed Terracotta"), S("Cyan Glazed Terracotta Pillar"), S("Cyan Concrete Powder"), S("Cyan Concrete"), "cyan"}, + {"blue", S("Blue Terracotta"), S("Blue Glazed Terracotta"), S("Blue Glazed Terracotta Pillar"), S("Blue Concrete Powder"), S("Blue Concrete"), "blue"}, + {"magenta", S("Magenta Terracotta"), S("Magenta Glazed Terracotta"), S("Magenta Glazed Terracotta Pillar"), S("Magenta Concrete Powder"), S("Magenta Concrete"), "magenta"}, + {"orange", S("Orange Terracotta"), S("Orange Glazed Terracotta"), S("Orange Glazed Terracotta Pillar"), S("Orange Concrete Powder"), S("Orange Concrete"), "orange"}, + {"purple", S("Purple Terracotta"), S("Purple Glazed Terracotta"), S("Purple Glazed Terracotta Pillar"), S("Purple Concrete Powder"), S("Purple Concrete"), "violet"}, + {"brown", S("Brown Terracotta"), S("Brown Glazed Terracotta"), S("Brown Glazed Terracotta Pillar"), S("Brown Concrete Powder"), S("Brown Concrete"), "brown"}, + {"pink", S("Pink Terracotta"), S("Pink Glazed Terracotta"), S("Pink Glazed Terracotta Pillar"), S("Pink Concrete Powder"), S("Pink Concrete"), "pink"}, + {"lime", S("Lime Terracotta"), S("Lime Glazed Terracotta"), S("Lime Glazed Terracotta Pillar"), S("Lime Concrete Powder"), S("Lime Concrete"), "green"}, + {"light_blue", S("Light Blue Terracotta"), S("Light Blue Glazed Terracotta"), S("Light Blue Glazed Terracotta Pillar"), S("Light Blue Concrete Powder"), S("Light Blue Concrete"), "lightblue"}, } local canonical_color = "yellow" local hc_desc = S("Terracotta is a basic building material. It comes in many different colors.") local gt_desc = S("Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.") +local gtp_desc = S("Glazed terracotta pillar is a decorative block with a complex pattern. It can be used with Glazed terracotta to make uneven patterns.") local cp_desc = S("Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.") local c_desc = S("Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.") local cp_tt = S("Turns into concrete on water contact") @@ -57,25 +58,28 @@ for _, row in ipairs(block.dyes) do local is_canonical = name == canonical_color local sdesc_hc = row[2] local sdesc_gt = row[3] - local sdesc_cp = row[4] - local sdesc_c = row[5] - local ldesc_hc, ldesc_gt, ldesc_cp, ldesc_c + local sdesc_gtp = row[4] + local sdesc_cp = row[5] + local sdesc_c = row[6] + local ldesc_hc, ldesc_gt, ldesc_cp, ldesc_c, ldesc_gtp local create_entry - local ename_hc, ename_gt, ename_cp, ename_c + local ename_hc, ename_gt, ename_cp, ename_c, ename_gtp local ltt_cp = cp_tt if is_canonical then ldesc_hc = hc_desc ldesc_gt = gt_desc + ldesc_gtp = gtp_desc ldesc_cp = cp_desc ldesc_c = c_desc ename_hc = S("Colored Terracotta") ename_gt = S("Glazed Terracotta") + ename_gtp = S("Glazed Terracotta Pillar") ename_cp = S("Concrete Powder") ename_c = S("Concrete") else create_entry = false end - local craft_color_group = row[6] + local craft_color_group = row[7] -- Node Definition minetest.register_node("mcl_colorblocks:hardened_clay_"..name, { description = sdesc_hc, @@ -162,6 +166,22 @@ for _, row in ipairs(block.dyes) do _mcl_hardness = 1.4, on_rotate = on_rotate, }) + minetest.register_node("mcl_colorblocks:glazed_terracotta_pillar_"..name, { + description = sdesc_gtp, + _doc_items_longdesc = ldesc_gtp, + _doc_items_create_entry = create_entry, + _doc_items_entry_name = ename_gtp, + tiles = {"mcl_colorblocks_glazed_terracotta_pillar_top_"..name..".png", "mcl_colorblocks_glazed_terracotta_pillar_top_"..name..".png", "mcl_colorblocks_glazed_terracotta_pillar_side_"..name..".png"}, + groups = {handy=1,pickaxey=1, glazed_terracotta=1,building_block=1, material_stone=1}, + paramtype2 = "facedir", + stack_max = 64, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.4, + on_place = mcl_util.rotate_axis, + on_rotate = on_rotate, + }) if not is_canonical and doc_mod then doc.add_entry_alias("nodes", "mcl_colorblocks:hardened_clay_"..canonical_color, "nodes", "mcl_colorblocks:hardened_clay_"..name) @@ -196,6 +216,16 @@ for _, row in ipairs(block.dyes) do recipe = "mcl_colorblocks:hardened_clay_"..name, cooktime = 10, }) + + minetest.register_craft({ + output = "mcl_colorblocks:glazed_terracotta_pillar_"..name.." 2", + recipe = { + {"mcl_colorblocks:glazed_terracotta_"..name}, + {"mcl_colorblocks:glazed_terracotta_"..name}, + } + }) + + mcl_stonecutter.register_recipe("mcl_colorblocks:glazed_terracotta_"..name, "mcl_colorblocks:glazed_terracotta_pillar_"..name) end end diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr index f71b54063..d58e737da 100644 --- a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr @@ -1,76 +1,94 @@ # textdomain: mcl_colorblocks White Terracotta=Terre cuite blanche -White Glazed Terracotta=Terre cuite emaillée blanche +White Glazed Terracotta=Terre cuite émaillée blanche +White Glazed Terracotta Pillar=Pilier de terre cuite émaillée blanche White Concrete Powder=Béton en poudre blanc White Concrete=Béton blanc Grey Terracotta=Terre cuite grise -Grey Glazed Terracotta=Terre cuite emaillée grise -Grey Concrete Powder=Béton en goudre gris +Grey Glazed Terracotta=Terre cuite émaillée grise +Grey Glazed Terracotta Pillar=Pilier de terre cuite émaillée grise +Grey Concrete Powder=Béton en poudre gris Grey Concrete=Béton gris Light Grey Terracotta=Terre cuite gris clair -Light Grey Glazed Terracotta=Terre cuite emaillée gris clair +Light Grey Glazed Terracotta=Terre cuite émaillée gris clair +Light Grey Glazed Terracotta Pillar=Pilier de terre cuite émaillée gris clair Light Grey Concrete Powder=Béton en poudre gris clair Light Grey Concrete=Béton gris clair -Black Terracotta=Terre cuite noir -Black Glazed Terracotta=Terre cuite emaillée noir +Black Terracotta=Terre cuite noire +Black Glazed Terracotta=Terre cuite émaillée noire +Black Glazed Terracotta Pillar=Pilier de terre cuite émaillée noire Black Concrete Powder=Béton en poudre noir Black Concrete=Béton noir Red Terracotta=Terre cuite rouge -Red Glazed Terracotta=Terre cuite emaillée rouge +Red Glazed Terracotta=Terre cuite émaillée rouge +Red Glazed Terracotta Pillar=Pilier de terre cuite émaillée rouge Red Concrete Powder=Béton en poudre rouge Red Concrete=Béton rouge Yellow Terracotta=Terre cuite jaune -Yellow Glazed Terracotta=Terre cuite emaillée jaune +Yellow Glazed Terracotta=Terre cuite émaillée jaune +Yellow Glazed Terracotta Pillar=Pilier de terre cuite émaillée jaune Yellow Concrete Powder=Béton en poudre jaune Yellow Concrete=Béton jaune Green Terracotta=Terre cuite verte -Green Glazed Terracotta=Terre cuite emaillée verte +Green Glazed Terracotta=Terre cuite émaillée verte +Green Glazed Terracotta Pillar=Pilier de terre cuite émaillée verte Green Concrete Powder=Béton en poudre vert Green Concrete=Béton vert Cyan Terracotta=Terre cuite cyan -Cyan Glazed Terracotta=Terre cuite emaillée cyan +Cyan Glazed Terracotta=Terre cuite émaillée cyan +Cyan Glazed Terracotta Pillar=Pilier de terre cuite émaillée cyan Cyan Concrete Powder=Béton en poudre cyan Cyan Concrete=Béton cyan Blue Terracotta=Terre cuite bleue -Blue Glazed Terracotta=Terre cuite emaillée bleue +Blue Glazed Terracotta=Terre cuite émaillée bleue +Blue Glazed Terracotta Pillar=Pilier de terre cuite émaillée bleue Blue Concrete Powder=Béton en poudre bleu Blue Concrete=Béton bleu Magenta Terracotta=Terre cuite magenta -Magenta Glazed Terracotta=Terre cuite emaillée magenta +Magenta Glazed Terracotta=Terre cuite émaillée magenta +Magenta Glazed Terracotta Pillar=Pilier de terre cuite émaillée magenta Magenta Concrete Powder=Béton en poudre magenta Magenta Concrete=Béton magenta Orange Terracotta=Terre cuite orange -Orange Glazed Terracotta=Terre cuite emaillée orange +Orange Glazed Terracotta=Terre cuite émaillée orange +Orange Glazed Terracotta Pillar=Pilier de terre cuite émaillée orange Orange Concrete Powder=Béton en poudre orange Orange Concrete=Béton orange Purple Terracotta=Terre cuite violette -Purple Glazed Terracotta=Terre cuite emaillée violette +Purple Glazed Terracotta=Terre cuite émaillée violette +Purple Glazed Terracotta Pillar=Pilier de terre cuite émaillée violette Purple Concrete Powder=Béton en poudre violet Purple Concrete=Béton violet Brown Terracotta=Terre cuite marron -Brown Glazed Terracotta=Terre cuite emaillée marron +Brown Glazed Terracotta=Terre cuite émaillée marron +Brown Glazed Terracotta Pillar=Pilier de terre cuite émaillée marron Brown Concrete Powder=Béton en poudre marron Brown Concrete=Béton marron Pink Terracotta=Terre cuite rose -Pink Glazed Terracotta=Terre cuite emaillée rose +Pink Glazed Terracotta=Terre cuite émaillée rose +Pink Glazed Terracotta Pillar=Pilier de terre cuite émaillée rose Pink Concrete Powder=Béton en poudre rose Pink Concrete=Béton rose Lime Terracotta=Terre cuite verte clair -Lime Glazed Terracotta=Terre cuite emaillée verte clair +Lime Glazed Terracotta=Terre cuite émaillée verte clair +Lime Glazed Terracotta Pillar=Pilier de terre cuite émaillée verte clair Lime Concrete Powder=Béton en poudre vert clair Lime Concrete=Béton vert clair Light Blue Terracotta=Terre cuite bleu clair -Light Blue Glazed Terracotta=Terre cuite emaillée bleu clair +Light Blue Glazed Terracotta=Terre cuite émaillée bleu clair +Light Blue Glazed Terracotta Pillar=Pilier de terre cuite émaillée bleu clair Light Blue Concrete Powder=Béton en poudre bleu clair Light Blue Concrete=Béton bleu clair -Terracotta is a basic building material. It comes in many different colors.=La terre cuite est un matériau de construction de base. Il est disponible dans de nombreuses couleurs différentes. -Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=La terre cuite émaillée est un bloc décoratif au motif complexe. Il peut être tourné en le plaçant dans différentes directions. -Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.=La poudre de béton est utilisée pour créer du béton, mais elle peut également être utilisée comme décoration elle-même. Il est disponible en différentes couleurs. La poudre de béton se transforme en béton de la même couleur au contact de l'eau. -Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Le béton est un bloc décoratif qui se décline en de nombreuses couleurs différentes. Il est remarquable pour avoir une couleur très forte et propre. +Terracotta is a basic building material. It comes in many different colors.=La terre cuite est un matériau de construction de base. Elle est disponible dans de nombreuses couleurs différentes. +Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=La terre cuite émaillée est un bloc décoratif au motif complexe. Elle peut être tournée en la plaçant dans différentes directions. +Glazed terracotta pillar is a decorative block with a complex pattern. It can be used with Glazed terracotta to make uneven patterns.=Le pilier de terre cuite émaillée est un bloc décoratif au motif complexe. Il peut être utilisé avec la terre cuite émaillée pour réaliser des motifs irréguliers. +Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.=La poudre de béton est utilisée pour créer du béton, mais elle peut également être utilisée comme décoration elle-même. Elle est disponible en différentes couleurs. La poudre de béton se transforme en béton de la même couleur au contact de l'eau. +Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Le béton est un bloc décoratif qui se décline en de nombreuses couleurs différentes. Il est remarquable pour avoir une couleur très forte et nette. Terracotta=Terre cuite Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=La terre cuite est un matériau de construction de base qui se décline en de nombreuses couleurs différentes. Ce bloc particulier n'est pas coloré. Colored Terracotta=Terre cuite colorée -Glazed Terracotta=Terre cuite emaillée +Glazed Terracotta=Terre cuite émaillée +Glazed Terracotta Pillar=Pilier de terre cuite émaillée Concrete Powder=Béton en poudre Concrete=Béton Turns into concrete on water contact=Se transforme en béton au contact de l'eau diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ru.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ru.tr index e1d694457..784154c25 100644 --- a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ru.tr +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ru.tr @@ -27,26 +27,26 @@ Green Terracotta=Зелёная керамика Green Glazed Terracotta=Зелёная глазурованная керамика Green Concrete Powder=Зелёный цемент Green Concrete=Зелёный бетон -Cyan Terracotta=Голубая керамика -Cyan Glazed Terracotta=Голубая глазурованная керамика -Cyan Concrete Powder=Голубой цемент -Cyan Concrete=Голубой бетон +Cyan Terracotta=Бирюзовая керамика +Cyan Glazed Terracotta=Бирюзовая глазурованная керамика +Cyan Concrete Powder=Бирюзовый цемент +Cyan Concrete=Бирюзовый бетон Blue Terracotta=Синяя керамика Blue Glazed Terracotta=Синяя глазурованная керамика Blue Concrete Powder=Синий цемент Blue Concrete=Синий бетон -Magenta Terracotta=Фиолетовая керамика -Magenta Glazed Terracotta=Фиолетовая глазурованная керамика -Magenta Concrete Powder=Фиолетовый цемент -Magenta Concrete=Фиолетовый бетон +Magenta Terracotta=Сиреневая керамика +Magenta Glazed Terracotta=Сиреневая глазурованная керамика +Magenta Concrete Powder=Сиреневый цемент +Magenta Concrete=Сиреневый бетон Orange Terracotta=Оранжевая керамика Orange Glazed Terracotta=Оранжевая глазурованная керамика Orange Concrete Powder=Оранжевый цемент Orange Concrete=Оранжевый бетон -Purple Terracotta=Пурпурная керамика -Purple Glazed Terracotta=Пурпурная глазурованная керамика -Purple Concrete Powder=Пурпурный цемент -Purple Concrete=Пурпурный бетон +Purple Terracotta=Фиолетовая керамика +Purple Glazed Terracotta=Фиолетовая глазурованная керамика +Purple Concrete Powder=Фиолетовый цемент +Purple Concrete=Фиолетовый бетон Brown Terracotta=Коричневая керамика Brown Glazed Terracotta=Коричневая глазурованная керамика Brown Concrete Powder=Коричневый цемент @@ -55,20 +55,20 @@ Pink Terracotta=Розовая керамика Pink Glazed Terracotta=Розовая глазурованная керамика Pink Concrete Powder=Розовый цемент Pink Concrete=Розовый бетон -Lime Terracotta=Зелёная лаймовая керамика -Lime Glazed Terracotta=Зелёная лаймовая глазурованная керамика -Lime Concrete Powder=Зелёный лаймовый цемент -Lime Concrete=Зелёный лаймовый бетон -Light Blue Terracotta=Светло-голубая керамика -Light Blue Glazed Terracotta=Светло-голубая глазурованная керамика -Light Blue Concrete Powder=Светло-голубой цемент -Light Blue Concrete=Светло-голубой бетон -Terracotta is a basic building material. It comes in many different colors.=Керамика это основной строительный материал. Он бывает разных цветов. +Lime Terracotta=Лаймовая керамика +Lime Glazed Terracotta=Лаймовая глазурованная керамика +Lime Concrete Powder=Лаймовый цемент +Lime Concrete=Лаймовый бетон +Light Blue Terracotta=Голубая керамика +Light Blue Glazed Terracotta=Голубая глазурованная керамика +Light Blue Concrete Powder=Голубой цемент +Light Blue Concrete=Голубой бетон +Terracotta is a basic building material. It comes in many different colors.=Керамика это базовый строительный материал. Она бывает разных цветов. Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=Глазурованная керамика это декоративный блок со сложным орнаментом. -Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.=Цемент используется для создания бетона, хотя также может быть украшением сам по себе. Он бывает разных цветов. При контакте с водой цемент превращается в бетон, сохраняя свой цвет. -Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Бетон это декоративный блок, который бывает разных цветов. Бетон славится хорошим и чистым цветом. -Terracotta=Керамика -Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=Керамика - основной строительный материал, который может быть разных цветов. Обычный блок керамики не окрашен. +Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.=Цемент используется для создания бетона, хотя также может быть декорацией сам по себе. Он бывает разных цветов. При контакте с водой цемент превращается в бетон того же цвета. +Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Бетон это декоративный блок, который может быть разных цветов. Бетон приметен своим хорошим и чистым цветом. +Terracotta=Терракота +Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=Терракота это базовый строительный материал, который может быть разных цветов. Конкретно этот блок не окрашен. Colored Terracotta=Окрашенная керамика Glazed Terracotta=Глазурованная керамика Concrete Powder=Цемент diff --git a/mods/ITEMS/mcl_colorblocks/locale/template.txt b/mods/ITEMS/mcl_colorblocks/locale/template.txt index ca1c059a1..8fbe7713f 100644 --- a/mods/ITEMS/mcl_colorblocks/locale/template.txt +++ b/mods/ITEMS/mcl_colorblocks/locale/template.txt @@ -1,76 +1,94 @@ # textdomain: mcl_colorblocks White Terracotta= White Glazed Terracotta= +White Glazed Terracotta Pillar= White Concrete Powder= White Concrete= Grey Terracotta= Grey Glazed Terracotta= +Grey Glazed Terracotta Pillar= Grey Concrete Powder= Grey Concrete= Light Grey Terracotta= Light Grey Glazed Terracotta= +Light Grey Glazed Terracotta Pillar= Light Grey Concrete Powder= Light Grey Concrete= Black Terracotta= Black Glazed Terracotta= +Black Glazed Terracotta Pillar= Black Concrete Powder= Black Concrete= Red Terracotta= Red Glazed Terracotta= +Red Glazed Terracotta Pillar= Red Concrete Powder= Red Concrete= Yellow Terracotta= Yellow Glazed Terracotta= +Yellow Glazed Terracotta Pillar= Yellow Concrete Powder= Yellow Concrete= Green Terracotta= Green Glazed Terracotta= +Green Glazed Terracotta Pillar= Green Concrete Powder= Green Concrete= Cyan Terracotta= Cyan Glazed Terracotta= +Cyan Glazed Terracotta Pillar= Cyan Concrete Powder= Cyan Concrete= Blue Terracotta= Blue Glazed Terracotta= +Blue Glazed Terracotta Pillar= Blue Concrete Powder= Blue Concrete= Magenta Terracotta= Magenta Glazed Terracotta= +Magenta Glazed Terracotta Pillar= Magenta Concrete Powder= Magenta Concrete= Orange Terracotta= Orange Glazed Terracotta= +Orange Glazed Terracotta Pillar= Orange Concrete Powder= Orange Concrete= Purple Terracotta= Purple Glazed Terracotta= +Purple Glazed Terracotta Pillar= Purple Concrete Powder= Purple Concrete= Brown Terracotta= Brown Glazed Terracotta= +Brown Glazed Terracotta Pillar= Brown Concrete Powder= Brown Concrete= Pink Terracotta= Pink Glazed Terracotta= +Pink Glazed Terracotta Pillar= Pink Concrete Powder= Pink Concrete= Lime Terracotta= Lime Glazed Terracotta= +Lime Glazed Terracotta Pillar= Lime Concrete Powder= Lime Concrete= Light Blue Terracotta= Light Blue Glazed Terracotta= +Light Blue Glazed Terracotta Pillar= Light Blue Concrete Powder= Light Blue Concrete= Terracotta is a basic building material. It comes in many different colors.= Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.= +Glazed terracotta pillar is a decorative block with a complex pattern. It can be used with Glazed terracotta to make uneven patterns.= Concrete powder is used for creating concrete, but it can also be used as decoration itself. It comes in different colors. Concrete powder turns into concrete of the same color when it comes in contact with water.= Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.= Terracotta= Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.= Colored Terracotta= Glazed Terracotta= +Glazed Terracotta Pillar= Concrete Powder= Concrete= Turns into concrete on water contact= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr index 77b36cad9..ca6eb8dcd 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr @@ -1,9 +1,14 @@ # textdomain: mcl_compass Compass=Brújula -Points to the world origin= -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Las brújulas son herramientas que apuntan al origen del mundo (X @ = 0, Z @ = 0) o al punto de generación en el mundo. -A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= -Lodestone Compass= -Points to a lodestone= -Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= -A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= +Points to the world origin=Apunta hacia el punto de generación del mundo +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Las brújulas son herramientas que apuntan al origen del mundo (X@=0, Z@=0) o al punto de generación en la superficie. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Una brújula siempre apunta al punto de generación del mundo cuando el jugador está en la superficie. En otras dimensiones, gira aleatoriamente. +Lodestone Compass=Brújula magnetizada +Points to a lodestone=Apunta hacia una magnetita +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Las brújulas magnetizadas se parecen a las brújulas normales, pero apuntan a una magnetita específica. +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=Una brújula magnetizada puede fabricarse a partir de una brújula normal, siempre que estén en la misma dimensión. Si no están en la misma dimensión, la brújula magnetizada girará aleatoriamente, de forma similar a una brújula normal cuando está fuera de la superficie. Una brújula magnetizada puede volver a enlazarse con otra magnetita. +Lodestone=Magnetita +Recovery Compass=Brújula de recuperación +Points to your last death location=Apunta hacia la ubicación de tu última muerte +Recovery Compasses are compasses that point to your last death location=Las brújulas de recuperación son brújulas que apuntan hacia la ubicación de tu última muerte +Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around=Las brújulas de recuperación siempre apuntan hacia la ubicación de tu última muerte, en caso de que aún no hayas muerto, simplemente girará aleatoriamente diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr index 7fd98de87..a187c3da0 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr @@ -1,9 +1,14 @@ # textdomain: mcl_compass Compass=Компас -Points to the world origin=Указывает на начало мира -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Компас - инструмент, показывающий на начало мира (X@=0, Z@=0) или на точку возрождения в Верхнем Мире. -A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.= -Lodestone Compass= -Points to a lodestone= -Lodestone compasses resemble regular compasses, but they point to a specific lodestone.= -A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.= +Points to the world origin=Указывает на центр мира +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Компас - инструмент, показывающий на цента мира (X@=0, Z@=0) или на точку возрождения в Верхнем Мире. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Компас в Верхнем мире всегда указывает на мировую точку спауна. В других измерениях он крутится случайно. +Lodestone Compass=Магнетитовый компас +Points to a lodestone=Указывает на магнетит +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Магнетитовый компас напоминает обычный компас, но указывает на определенный блок магнетита. +A Lodestone compass can be made from an ordinary compass by using it on a lodestone. After becoming a lodestone compass, it always points to its linked lodestone, provided that they are in the same dimension. If not in the same dimension, the lodestone compass spins randomly, similarly to a regular compass when outside the overworld. A lodestone compass can be relinked with another lodestone.=Магнетитовый компас может быть сделан из обычного компаса использовав его на магнетите. После этого он всегда указывает на привязанный блок магнетит если он находится в том же измерении. Если нет, то магнетитовый компас будет крутится случайно, схоже с обычным компасом вне Верхнего мира. Магнетитовый компас может перепривязаться к другому магнетиту. +Lodestone=Магнетит +Recovery Compass=Компас восстановления +Points to your last death location=Указывает на место вашей последней смерти +Recovery Compasses are compasses that point to your last death location=Компас восстановления указывает на место вашей последней смерти +Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around=Компас восстановления всегда указывает на место вашей последней смерти, если вы еще не умирали, он будет крутится случайно. diff --git a/mods/ITEMS/mcl_composters/init.lua b/mods/ITEMS/mcl_composters/init.lua index d60422afd..efa08c75c 100644 --- a/mods/ITEMS/mcl_composters/init.lua +++ b/mods/ITEMS/mcl_composters/init.lua @@ -81,34 +81,44 @@ local function composter_add_item(pos, node, player, itemstack, pointed_thing) max_hear_distance = 16, }, true) end - -- calculate leveling up chance - local rand = math.random(0,100) - if chance >= rand then - -- get current compost level - local level = registered_nodes[node.name]["_mcl_compost_level"] - -- spawn green particles above new layer - mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0)) - -- update composter block - if level < 7 then - level = level + 1 - else - level = "ready" - 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) + composter_progress_chance(pos, node, chance) + end + return itemstack +end + +--- Math and node swap during compost progression +---@param pos Vector Position of the node +---@param node node +---@param chance integer Value of "compostability" group of inserted item +function composter_progress_chance(pos, node, chance) + -- calculate leveling up chance + local rand = math.random(0,100) + if chance >= rand then + -- get current compost level + local level = registered_nodes[node.name]["_mcl_compost_level"] + -- spawn green particles above new layer + mcl_dye.add_bone_meal_particle(vector_offset(pos, 0, level/8, 0)) + -- update composter block + if level < 7 then + level = level + 1 + else + level = "ready" + 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) end end end - return itemstack end --- 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) return itemstack 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 swap_node(pos, {name="mcl_composters:composter"}) -- spawn bone meal item @@ -175,6 +189,14 @@ local function composter_get_nodeboxes(level) } 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. -- -- This is the craftable base model that can be placed in an inventory. @@ -197,12 +219,40 @@ minetest.register_node("mcl_composters:composter", { groups = { handy=1, material_wood=1, deco_block=1, dirtifier=1, flammable=2, fire_encouragement=3, fire_flammability=4, + container = 2 }, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_hardness = 0.6, _mcl_blast_resistance = 0.6, _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, 1) + 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. @@ -228,7 +278,7 @@ local function register_filled_composter(level) handy=1, material_wood=1, deco_block=1, dirtifier=1, not_in_creative_inventory=1, not_in_craft_guide=1, flammable=2, fire_encouragement=3, fire_flammability=4, - comparator_signal=level + comparator_signal=level, container = 2 }, sounds = mcl_sounds.node_sound_wood_defaults(), drop = "mcl_composters:composter", @@ -236,7 +286,28 @@ local function register_filled_composter(level) _mcl_blast_resistance = 0.6, _mcl_compost_level = level, 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, 1) + 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 @@ -270,14 +341,32 @@ minetest.register_node("mcl_composters:composter_ready", { handy=1, material_wood=1, deco_block=1, dirtifier=1, not_in_creative_inventory=1, not_in_craft_guide=1, flammable=2, fire_encouragement=3, fire_flammability=4, - comparator_signal=8 + comparator_signal=8, container = 2 }, sounds = mcl_sounds.node_sound_wood_defaults(), drop = "mcl_composters:composter", _mcl_hardness = 0.6, _mcl_blast_resistance = 0.6, _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 diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr index db472dad4..39f172199 100644 --- a/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr @@ -1,7 +1,7 @@ # textdomain: mcl_composters -Composter=Перегнойница -Composters can convert various organic items into bonemeal.=Перегнойницы могут превращать многочисленные растительные предметы в костную муку. -Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter."=Используйте растительные предметы на перегнойнице, чтобы заполнить её слоями перегноя. Каждый раз, когда какой-либо предмет помещается в перегнойницу, существует вероятность возникновения добавочного слоя перегноя. Некоторые предметы могут чаще, чем другие приводит к появлению добавочного слоя перегноя. После заполнения на семь слоёв перегноя, перегнойница будет полна. После задержки примерно в одну секунду из перегнойницы можно будет извлечь костную муку. Нажатие правой кнопки мыши по перегнойнице извлекает костную муку и опорожняет её. -filled=заполнена -ready for harvest=готов к жатве -Converts organic items into bonemeal=Превращает растительные предметы в костную муку \ No newline at end of file +Composter=Компостер +Composters can convert various organic items into bonemeal.=Компостер может перерабатывать органические предметы в костную муку +Use organic items on the composter to fill it with layers of compost. Every time an item is put in the composter, there is a chance that the composter adds another layer of compost. Some items have a bigger chance of adding an extra layer than other items. After filling up with 7 layers of compost, the composter is full. After a delay of approximately one second the composter becomes ready and bone meal can be retrieved from it. Right-clicking the composter takes out the bone meal empties the composter.=Используйте органические предметы на компостере, чтобы заполнить его слоями перегноя. Каждый раз когда в компостер попадает предмет, есть шанс что в компостере появится новый слой перегноя. Некоторые предметы имеют больший шанс на появление нового слоя. После заполнения 7 слоями перегноя, компостер можно опустошить, забрав из него костную муку. После задержки в одну секунду компостер будет готов и костная мука будет извлечена из него. Правым кликом по компостеру чтобы забрать костную муку. +filled=заполнен +ready for harvest=готов к сбору +Converts organic items into bonemeal=Перерабатывает органику в костную муку diff --git a/mods/ITEMS/mcl_composters/mod.conf b/mods/ITEMS/mcl_composters/mod.conf index 86d729887..ed6119d3a 100644 --- a/mods/ITEMS/mcl_composters/mod.conf +++ b/mods/ITEMS/mcl_composters/mod.conf @@ -1,5 +1,5 @@ name = mcl_composters author = kabou 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 diff --git a/mods/ITEMS/mcl_compressed_blocks/init.lua b/mods/ITEMS/mcl_compressed_blocks/init.lua new file mode 100644 index 000000000..e81c7f4a0 --- /dev/null +++ b/mods/ITEMS/mcl_compressed_blocks/init.lua @@ -0,0 +1,5 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +dofile(modpath.."/nodes.lua") +dofile(modpath.."/recipes.lua") diff --git a/mods/ITEMS/mcl_compressed_blocks/mod.conf b/mods/ITEMS/mcl_compressed_blocks/mod.conf new file mode 100644 index 000000000..d3c5771c9 --- /dev/null +++ b/mods/ITEMS/mcl_compressed_blocks/mod.conf @@ -0,0 +1,3 @@ +name = mcl_compressed_blocks +depends = mcl_core +description = adds compressed blocks to voxelibre diff --git a/mods/ITEMS/mcl_compressed_blocks/nodes.lua b/mods/ITEMS/mcl_compressed_blocks/nodes.lua new file mode 100644 index 000000000..32c47bfd4 --- /dev/null +++ b/mods/ITEMS/mcl_compressed_blocks/nodes.lua @@ -0,0 +1,121 @@ +--Compressed Cobblestone +minetest.register_node("mcl_compressed_blocks:compressed_cobblestone", { + description = "Compressed Cobblestone", + _doc_items_longdesc = ("Compressed Cobblestone is a decorative block made from 9 Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 11, + _mcl_hardness = 3, +}) + +--Double Compressed Cobble +minetest.register_node("mcl_compressed_blocks:double_compressed_cobblestone", { + description = "Double Compressed Cobblestone", + _doc_items_longdesc = ("Double Compressed Cobblestone is a decorative block made from 9 Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_double_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 19, + _mcl_hardness = 4, +}) + +--Triple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:triple_compressed_cobblestone", { + description = "Triple Compressed Cobblestone", + _doc_items_longdesc = ("Triple Compressed Cobblestone is a decorative block made from 9 Double Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_triple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 33, + _mcl_hardness = 5, +}) + +--Quadruple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:quadruple_compressed_cobblestone", { + description = "Quadruple Compressed Cobblestone", + _doc_items_longdesc = ("Quadruple Compressed Cobblestone is a decorative block made from 9 Triple Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_quadruple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 58, + _mcl_hardness = 7, +}) + +--Quintuple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:quintuple_compressed_cobblestone", { + description = "Quintuple Compressed Cobblestone", + _doc_items_longdesc = ("Quintuple Compressed Cobblestone is a decorative block made from 9 Quadruple Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_quintuple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 102, + _mcl_hardness = 9, +}) + +--Sextuple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:sextuple_compressed_cobblestone", { + description = "Sextuple Compressed Cobblestone", + _doc_items_longdesc = ("Sextuple Compressed Cobblestone is a decorative block made from 9 Quintuple Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_sextuple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 179, + _mcl_hardness = 12, +}) + +--Septuple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:septuple_compressed_cobblestone", { + description = "Septuple Compressed Cobblestone", + _doc_items_longdesc = ("Septuple Compressed Cobblestone is a decorative block made from 9 Sextuple Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_septuple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 313, + _mcl_hardness = 16, +}) + +--Ocutple Compressed Cobble +minetest.register_node("mcl_compressed_blocks:octuple_compressed_cobblestone", { + description = "Octuple Compressed Cobblestone", + _doc_items_longdesc = ("Octuple Compressed Cobblestone is a decorative block made from 9 Septuple Compressed Cobblestone. It is useful for saving space in your inventories."), + _doc_items_hidden = false, + tiles = {"mcl_compressed_blocks_octuple_compressed_cobblestone.png"}, + is_ground_content = true, + stack_max = 64, + groups = {pickaxey=1, stone=1, building_block=1}, + drop = { + + max_items = 2, + items = { + {items = {"mcl_core:diamond 9"}}, + {items = {"mcl_nether:netherite_scrap 18"}}, + }, + }, + + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 548, + _mcl_hardness = 21, + _mcl_silk_touch_drop = true, +}) diff --git a/mods/ITEMS/mcl_compressed_blocks/recipes.lua b/mods/ITEMS/mcl_compressed_blocks/recipes.lua new file mode 100644 index 000000000..a02e8c612 --- /dev/null +++ b/mods/ITEMS/mcl_compressed_blocks/recipes.lua @@ -0,0 +1,127 @@ +minetest.register_craft({ + output = "mcl_compressed_blocks:compressed_cobblestone", + recipe = { + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, + { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, + }, +}) + +minetest.register_craft({ + output = "mcl_core:cobble 9", + recipe = { + { "mcl_compressed_blocks:compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:double_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone" }, + { "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone" }, + { "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone", "mcl_compressed_blocks:compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:double_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:triple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone" }, + { "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone" }, + { "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone", "mcl_compressed_blocks:double_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:double_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:triple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:quadruple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone" }, + { "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone" }, + { "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone", "mcl_compressed_blocks:triple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:triple_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:quadruple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:quintuple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone" }, + { "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone" }, + { "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone", "mcl_compressed_blocks:quadruple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:quadruple_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:quintuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:sextuple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone", "mcl_compressed_blocks:quintuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:quintuple_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:sextuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:septuple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone", "mcl_compressed_blocks:sextuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:sextuple_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:septuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:octuple_compressed_cobblestone", + recipe = { + { "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone" }, + { "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone", "mcl_compressed_blocks:septuple_compressed_cobblestone" }, + }, +}) + +minetest.register_craft({ + output = "mcl_compressed_blocks:septuple_compressed_cobblestone 9", + recipe = { + { "mcl_compressed_blocks:octuple_compressed_cobblestone" }, + }, +}) diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_compressed_cobblestone.png new file mode 100644 index 000000000..30ba3c4a1 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_double_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_double_compressed_cobblestone.png new file mode 100644 index 000000000..593422c03 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_double_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_octuple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_octuple_compressed_cobblestone.png new file mode 100644 index 000000000..b8d302487 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_octuple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quadruple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quadruple_compressed_cobblestone.png new file mode 100644 index 000000000..ac897b8c0 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quadruple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quintuple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quintuple_compressed_cobblestone.png new file mode 100644 index 000000000..d82c648b4 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_quintuple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_septuple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_septuple_compressed_cobblestone.png new file mode 100644 index 000000000..75bfd2d49 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_septuple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_sextuple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_sextuple_compressed_cobblestone.png new file mode 100644 index 000000000..4ffce6d77 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_sextuple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_triple_compressed_cobblestone.png b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_triple_compressed_cobblestone.png new file mode 100644 index 000000000..d42c7bf29 Binary files /dev/null and b/mods/ITEMS/mcl_compressed_blocks/textures/mcl_compressed_blocks_triple_compressed_cobblestone.png differ diff --git a/mods/ITEMS/mcl_copper/README.md b/mods/ITEMS/mcl_copper/README.md index 6a6f2d7d2..fa12cd5c7 100644 --- a/mods/ITEMS/mcl_copper/README.md +++ b/mods/ITEMS/mcl_copper/README.md @@ -1,4 +1,4 @@ -# MineClone2 Copper +# VoxeLibre Copper ### by NO11 diff --git a/mods/ITEMS/mcl_copper/crafting.lua b/mods/ITEMS/mcl_copper/crafting.lua index ce280fcdf..9b0976d3a 100644 --- a/mods/ITEMS/mcl_copper/crafting.lua +++ b/mods/ITEMS/mcl_copper/crafting.lua @@ -10,8 +10,9 @@ minetest.register_craft({ minetest.register_craft({ output = "mcl_copper:block", recipe = { - { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, - { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, + { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, + { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, + { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, }, }) @@ -40,7 +41,7 @@ minetest.register_craft({ }) minetest.register_craft({ - output = "mcl_copper:mcl_copper:block_weathered_cut 4", + output = "mcl_copper:block_weathered_cut 4", recipe = { { "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, { "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, @@ -58,8 +59,14 @@ for _, w in ipairs(waxable_blocks) do }) 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({ - output = "mcl_copper:copper_ingot 4", + output = "mcl_copper:copper_ingot 9", recipe = { { "mcl_copper:block" }, }, diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.ru.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.ru.tr new file mode 100644 index 000000000..50600e57b --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.ru.tr @@ -0,0 +1,57 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=Медный блок — это декоративный блок. +A block used for compact raw copper storage.=Блок используется для компактного хранения необработанной меди. +Block of Copper=Медный блок +Waxed Block of Copper=Вощёный медный блок +Block of Raw Copper=Блок необработанной меди +Copper Ingot=Медный слиток +Copper Ore=Медная руда +Cut copper is a decorative block.=Резной медный блок это декоративный блок. +Cut Copper=Резной медный блок +Waxed Cut Copper=Вощёный резной медный блок +Double Slab of Cut Copper=Двойная плита из резного медного блока +Double Slab of Exposed Cut Copper=Двойная плита из потемневшего резного медного блока +Double Slab of Oxidized Cut Copper=Двойная плита из окисленного резного медного блока +Double Slab of Weathered Cut Copper=Двойная плита из состаренного резного медного блока +Waxed Double Slab of Cut Copper=Вощёная двойная плита из резного медного блока +Waxed Double Slab of Exposed Cut Copper=Вощёная двойная плита из потемневшего резного медного блока +Waxed Double Slab of Oxidized Cut Copper=Вощёная двойная плита из окисленного резного медного блока +Waxed Double Slab of Weathered Cut Copper=Вощёная двойная плита из состаренного резного медного блока +Exposed copper is a decorative block.=Потемневший медный блок это декоративный блок. +Exposed Copper=Потемневший медный блок +Waxed Exposed Copper=Вощёный потемневший медный блок +Exposed cut copper is a decorative block.=Потемневший резной медный блок это декоративный блок. +Exposed Cut Copper=Потемневший резной медный блок +Waxed Exposed Cut Copper=Вощёный потемневший резной медный блок +Molten Raw Copper. It is used to craft blocks.=Медный слиток. Используется для крафта блоков. +Oxidized copper is a decorative block.=Окисленный медный блок это декоративный блок. +Oxidized Copper=Окисленный медный блок +Waxed Oxidized Copper=Вощёный окисленный медный блок +Oxidized cut copper is a decorative block.=Окисленный резной медный блок это декоративный блок. +Oxidized Cut Copper=Окисленный резной медный блок +Waxed Oxidized Cut Copper=Вощёный окисленный резной медный блок +Raw Copper. Mine a Copper Ore to get it.=Необработанная медь. Добудьте медную руду, чтобы получить её. +Raw Copper=Необработанная медь +Slab of Cut Copper=Плита из резного медного блока +Slab of Exposed Cut Copper=Плита из потемневшего резного медного блока +Slab of Oxidized Cut Copper=Плита из окисленного резного медного блока +Slab of Weathered Cut Copper=Плита из состаренного резного медного блока +Waxed Slab of Cut Copper=Вощёная плита из резного медного блока +Waxed Slab of Exposed Cut Copper=Вощёная плита из потемневшего резного медного блока +Waxed Slab of Oxidized Cut Copper=Вощёная плита из окисленного резного медного блока +Waxed Slab of Weathered Cut Copper=Вощёная плита из состаренного резного медного блока +Some copper contained in stone, it is pretty common and can be found below sea level.=Залежи медной руды находятся в камне, медь довольно распространена и может быть найдена ниже уровня моря. +Stairs of Cut Copper=Ступени из резного медного блока +Stairs of Exposed Cut Copper=Ступени из потемневшего резного медного блока +Stairs of Oxidized Cut Copper=Ступени из окисленного резного медного блока +Stairs of Weathered Cut Copper=Ступени из состаренного резного медного блока +Waxed Stairs of Cut Copper=Вощёные ступени из резного медного блока +Waxed Stairs of Exposed Cut Copper=Вощёные ступени из потемневшего резного медного блока +Waxed Stairs of Oxidized Cut Copper=Вощёные ступени из окисленного резного медного блока +Waxed Stairs of Weathered Cut Copper=Вощёные ступени из состаренного резного медного блока +Weathered copper is a decorative block.=Состаренный медный блок это декоративный блок. +Weathered Copper=Состаренный медный блок +Waxed Weathered Copper=Вощёный состаренный медный блок +Weathered cut copper is a decorative block.=Состаренный резной медный блок это декоративный блок. +Weathered Cut Copper=Состаренный резной медный блок +Waxed Weathered Cut Copper=Вощёный состаренный резной медный блок diff --git a/mods/ITEMS/mcl_copper/mod.conf b/mods/ITEMS/mcl_copper/mod.conf index a48ee56f7..64937b2e1 100644 --- a/mods/ITEMS/mcl_copper/mod.conf +++ b/mods/ITEMS/mcl_copper/mod.conf @@ -1,4 +1,4 @@ name = mcl_copper 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. diff --git a/mods/ITEMS/mcl_core/README.txt b/mods/ITEMS/mcl_core/README.txt index 6c48d74fd..5a1d5d88f 100644 --- a/mods/ITEMS/mcl_core/README.txt +++ b/mods/ITEMS/mcl_core/README.txt @@ -1,4 +1,4 @@ -MineClone 2 core mod +VoxeLibre core mod ==================== Originally forked from Minetest Game's default mod in the distant past. diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index 32a5f7cbc..f95d42ad2 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -167,20 +167,81 @@ local function eat_gapple(itemstack, placer, pointed_thing) return itemstack end - local regen_duration, absorbtion_factor = 5, 1 + local regen_duration, absorption = 5, 1 if itemstack:get_name() == "mcl_core:apple_gold_enchanted" then - regen_duration, absorbtion_factor = 20, 4 - mcl_potions.fire_resistance_func(placer, 1, 300) - mcl_potions.leaping_func(placer, 1, 300) + regen_duration, absorption = 20, 4 + mcl_potions.give_effect("fire_resistance", placer, 1, 300) + mcl_potions.give_effect_by_level("leaping", placer, 1, 300) if enable_fapples then - mcl_potions.swiftness_func(placer, absorbtion_factor, 120) + mcl_potions.give_effect_by_level("swiftness", placer, absorption, 120) end end - -- TODO: Absorbtion - mcl_potions.regeneration_func(placer, 2, regen_duration) + mcl_potions.give_effect_by_level("absorption", placer, absorption, 120) + mcl_potions.give_effect_by_level("regeneration", placer, 2, regen_duration) return gapple_hunger_restore(itemstack, placer, pointed_thing) end +local function eat_gapple_delayed(itemstack, placer, pointed_thing) + + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + elseif pointed_thing.type == "object" then + return itemstack + end + + local function eat_gapple(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + elseif pointed_thing.type == "object" then + return itemstack + end + + local regen_duration, absorption = 5, 1 + if itemstack:get_name() == "mcl_core:apple_gold_enchanted" then + regen_duration, absorption = 20, 4 + mcl_potions.give_effect("fire_resistance", placer, 1, 300) + mcl_potions.give_effect_by_level("leaping", placer, 1, 300) + if enable_fapples then + mcl_potions.give_effect_by_level("swiftness", placer, absorption, 120) + end + end + mcl_potions.give_effect_by_level("absorption", placer, absorption, 120) + mcl_potions.give_effect_by_level("regeneration", placer, 2, regen_duration) + --return gapple_hunger_restore(itemstack, placer, pointed_thing) + end + + -- Wrapper for handling mcl_hunger delayed eating + local name = placer:get_player_name() + mcl_hunger.eat_internal[name]._custom_itemstack = itemstack -- Used as comparison to make sure the custom wrapper executes only when the same item is eaten + mcl_hunger.eat_internal[name]._custom_var = { + itemstack = itemstack, + placer = placer, + pointed_thing = pointed_thing, + } + mcl_hunger.eat_internal[name]._custom_func = eat_gapple + mcl_hunger.eat_internal[name]._custom_wrapper = function(name) + + mcl_hunger.eat_internal[name]._custom_func( + mcl_hunger.eat_internal[name]._custom_var.itemstack, + mcl_hunger.eat_internal[name]._custom_var.placer, + mcl_hunger.eat_internal[name]._custom_var.pointed_thing + ) + end + + --mcl_hunger.eat_internal[name]._custom_do_delayed = true -- Only _custom_wrapper will be executed after holding RMB or LMB within a specified delay + minetest.do_item_eat(4, nil, itemstack, placer, pointed_thing) +end + minetest.register_craftitem("mcl_core:apple_gold", { -- TODO: Add special highlight color description = S("Golden Apple"), @@ -188,8 +249,10 @@ minetest.register_craftitem("mcl_core:apple_gold", { wield_image = "mcl_core_apple_golden.png", inventory_image = "mcl_core_apple_golden.png", stack_max = 64, - on_place = eat_gapple, - on_secondary_use = eat_gapple, + --on_place = eat_gapple, -- Will do effect immediately but not reduce item count until eating delay ends which makes it exploitable by deliberately not finishing delay + --on_secondary_use = eat_gapple, + on_place = eat_gapple_delayed, + on_secondary_use = eat_gapple_delayed, groups = { food = 2, eatable = 4, can_eat_when_full = 1 }, _mcl_saturation = 9.6, }) @@ -200,8 +263,10 @@ minetest.register_craftitem("mcl_core:apple_gold_enchanted", { wield_image = "mcl_core_apple_golden.png" .. mcl_enchanting.overlay, inventory_image = "mcl_core_apple_golden.png" .. mcl_enchanting.overlay, stack_max = 64, - on_place = eat_gapple, - on_secondary_use = eat_gapple, + --on_place = eat_gapple, + --on_secondary_use = eat_gapple, + on_place = eat_gapple_delayed, + on_secondary_use = eat_gapple_delayed, groups = { food = 2, eatable = 4, can_eat_when_full = 1 }, _mcl_saturation = 9.6, }) diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index b7623bf11..ad2346dd9 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -1581,7 +1581,7 @@ end -- MUST NOT be called if there is a snow cover node above pos. function mcl_core.clear_snow_dirt(pos, node) local def = minetest.registered_nodes[node.name] - if def._mcl_snowless then + if def and def._mcl_snowless then minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2}) end end @@ -1602,7 +1602,7 @@ function mcl_core.on_snowable_construct(pos) -- Make snowed if needed if minetest.get_item_group(anode.name, "snow_cover") == 1 then local def = minetest.registered_nodes[node.name] - if def._mcl_snowed then + if def and def._mcl_snowed then minetest.swap_node(pos, {name = def._mcl_snowed, param2=node.param2}) end end @@ -1623,7 +1623,7 @@ function mcl_core.on_snow_construct(pos) local npos = {x=pos.x, y=pos.y-1, z=pos.z} local node = minetest.get_node(npos) local def = minetest.registered_nodes[node.name] - if def._mcl_snowed then + if def and def._mcl_snowed then minetest.swap_node(npos, {name = def._mcl_snowed, param2=node.param2}) end end diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index e66d8b115..db90b43c6 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -132,8 +132,8 @@ Jungle leaves are grown from jungle trees.=Les feuilles d'acajou poussent sur le Ladder=Échelle Lapis Lazuli=Lapis-lazuli Lapis Lazuli are required for enchanting items on an enchanting table.=Les lapis-lazuli sont nécessaires pour enchanter des objets sur une table d'enchantement. -Lapis Lazuli Block=Bloc de lapis-Lazuli -Lapis Lazuli Ore=Minerai de lapis-Lazuli +Lapis Lazuli Block=Bloc de lapis-lazuli +Lapis Lazuli Ore=Minerai de lapis-lazuli Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Le minerai de lapis-lazuli produit du lapis-lazuli. Il peut être rarement trouvé dans des filons près du fond du monde. Lava Source=Source de Lave Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=La lave est chaude et plutôt dangereuse. Ne le touchez pas, cela vous fera beaucoup de mal et il est difficile d'en sortir. @@ -208,8 +208,8 @@ Stripped Acacia Log=Bûche d'acacia écorcée Stripped Acacia Wood=Bois d'acacia écorcé Stripped Birch Log=Bûche de bouleau écorcée Stripped Birch Wood=Bois de bouleau écorcé -Stripped Dark Oak Log=Bûche de Chêne Noir -Stripped Dark Oak Wood=Bois de Chêne Noir +Stripped Dark Oak Log=Bûche de chêne noir +Stripped Dark Oak Wood=Bois de chêne noir Stripped Jungle Log=Bûche d'acajou écorcée Stripped Jungle Wood=Bois d'acajou écorcé Stripped Oak Log=Bûche de chêne écorcée diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index bf8ce9e4f..6f29bd37e 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -1,260 +1,291 @@ # textdomain: mcl_core @1 could not survive in lava.=@1 не смог(ла) выжить в лаве. @1 died in lava.=@1 погиб(ла) в лаве. -@1 melted in lava.=@1 расплавился(лась) в лаве. +@1 melted in lava.=@1 был(а) расплавлен(а) в лаве. @1 took a bath in a hot lava tub.=@1 принял(а) ванну с горячей лавой. A block of diamond is mostly a shiny decorative block but also useful as a compact storage of diamonds.=Алмазный блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения алмазов. A block of emerald is mostly a shiny decorative block but also useful as a compact storage of emeralds.=Изумрудный блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения изумрудов. A block of gold is mostly a shiny decorative block but also useful as a compact storage of gold ingots.=Золотой блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения золотых слитков. -A block of iron is mostly a decorative block but also useful as a compact storage of iron ingots.=Алмазный блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения железных слитков. +A block of iron is mostly a decorative block but also useful as a compact storage of iron ingots.=Железный блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения железных слитков. A cactus can only be placed on top of another cactus or any sand.=Кактус можно поставить только на верхушку другого кактуса или на любой песок. A decorative and mostly transparent block.=Декоративный и преимущественно прозрачный блок. -A grass block is dirt with a grass cover. Grass blocks are resourceful blocks which allow the growth of all sorts of plants. They can be turned into farmland with a hoe and turned into grass paths with a shovel. In light, the grass slowly spreads onto dirt nearby. Under an opaque block or a liquid, a grass block may turn back to dirt.=Травяной блок это грязь, покрытая травой. Травяные блоки удобны тем, что позволяют выращивать любые сорта растений. Их можно превратить в грядки при помощи мотыги или в тропинки при помощи лопаты. При наличии света трава понемногу распространяется на грязь по соседству. Под непрозрачным блоком или жидкостью травяной блок может превратиться обратно в грязь. -A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Ляпис-лазурный блок это, прежде всего, декоративный блок, но он также удобен для компактного хранения ляпис-лазури. -A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Источник лавы поджигает пару воздушных блоков над ним, если они расположены рядом с легковоспламенимым блоком. -A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns.=Сегмент лестницы, позволяющий вам карабкаться вертикально. Лестницы можно устанавливать только на стороны твёрдых блоков. Их нельзя разместить на стекле, листьях, льду, светящемся камне и морских фонарях. -Acacia Bark=Кора акации -Acacia Leaves=Листва акации +A grass block is dirt with a grass cover. Grass blocks are resourceful blocks which allow the growth of all sorts of plants. They can be turned into farmland with a hoe and turned into grass paths with a shovel. In light, the grass slowly spreads onto dirt nearby. Under an opaque block or a liquid, a grass block may turn back to dirt.=Дёрн это блок земли, покрытый травой. Дёрн удобен тем, что на нём могут расти разнообразные растения. Дёрн можно превратить в грядку при помощи мотыги или в тропинку при помощи лопаты. При наличии света дёрн понемногу распространяется на блоки земли по соседству. Под непрозрачным блоком или жидкостью дёрн может превратиться обратно в землю. +A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Блок лазурита это, прежде всего, декоративный блок, но он также удобен для компактного хранения лазурита. +A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Источник лавы поджигает пару воздушных блоков над ним, если они расположены рядом с воспламенимым блоком. +A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns.=Лестница позволяет вам карабкаться вертикально. Лестницы можно устанавливать только сбоку на твёрдые блокои. Их нельзя разместить на стекле, листьях, льду, светящемся камне и морских фонарях. +Acacia Bark=Акациевая кора +Acacia Leaves=Акациевая листва Acacia Sapling=Саженец акации -Acacia Wood=Акация -Acacia Wood Planks=Доски акации +Acacia Wood=Акациевая древесина +Acacia Wood Planks=Акациевые доски Acacia leaves are grown from acacia trees.=Листва акации произрастает на деревьях акации. Andesite=Андезит Andesite is an igneous rock.=Андезит это камень вулканической природы. Apple=Яблоко -Apples are food items which can be eaten.=Яблоки относятся к продуктовым предметам, которые можно есть. +Apples are food items which can be eaten.=Яблоки это съедобный продукт. Barrier=Барьер -Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Барьеры это невидимые блоки-препятствия. Они могут использоваться, например, для создания границ карты. Монстры и животные не будут появляться на барьерах. Заборы с барьерами визуально не связываются. Другие блоки могут строиться на барьерах, как на любых других блоках. +Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block.=Барьеры это невидимые блоки-препятствия. Они могут использоваться, например, для создания границ карты. Монстры и животные не будут спауниться на барьерах. Заборы с барьерами не соединяются. Другие блоки могут строиться на барьерах, как на любых других блоках. Bedrock=Бедрок -Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Бедрок это очень твёрдый камень. Его невозможно сломать, выкопать или сдвинуть обычным способом, за исключением творческого режима. -Birch Bark=Кора берёзы -Birch Leaves=Листва берёзы +Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Бедрок это очень твёрдый камень. Его невозможно сломать, добыть или сдвинуть обычным способом, за исключением творческого режима. +Birch Bark=Берёзовая кора +Birch Leaves=Берёзовая листва Birch Sapling=Саженец берёзы -Birch Wood=Берёза +Birch Wood=Берёзовая древесина Birch Wood Planks=Берёзовые доски Birch leaves are grown from birch trees.=Листва берёзы произрастает на берёзах. -Black Stained Glass=Чёрное витражное стекло +Black Stained Glass=Чёрное стекло Block of Coal=Угольный блок Block of Diamond=Алмазный блок Block of Emerald=Изумрудный блок Block of Gold=Золотой блок Block of Iron=Железный блок -Blocks of coal are useful as a compact storage of coal and very useful as a furnace fuel. A block of coal is as efficient as 10 coal.=Угольный блок удобен для компактного хранения угля, а также как топливо для печи. -Blue Stained Glass=Синее витражное стекло +Blocks of coal are useful as a compact storage of coal and very useful as a furnace fuel. A block of coal is as efficient as 10 coal.=Угольный блок удобен для компактного хранения угля, а также полезен как топливо для печи. +Blue Stained Glass=Синее стекло Bone Block=Костный блок Bone blocks are decorative blocks and a compact storage of bone meal.=Костные блоки это декоративные блоки, а также способ компактного хранения костной муки. -Bowl=Чаша -Bowls are mainly used to hold tasty soups.=Чаши чаще всего используются для хранения вкусных супов. +Bowl=Миска +Bowls are mainly used to hold tasty soups.=Миски используются для крафта вкусных супов. Brick=Кирпич Brick Block=Кирпичный блок Brick blocks are a good building material for building solid houses and can take quite a punch.=Кирпичные блоки это отличный строительный материал для создания прочных домов, они выдерживают довольно сильные удары. Bricks are used to craft brick blocks.=Кирпичи используются для создания кирпичных блоков. -Brown Stained Glass=Коричневое витражное стекло +Brown Stained Glass=Коричневое стекло Cactus=Кактус Charcoal=Древесный уголь -Charcoal is an alternative furnace fuel created by cooking wood in a furnace. It has the same burning time as coal and also shares many of its crafting recipes, but it can not be used to create coal blocks.=Древесный уголь это альтернативное печное топливо, получаемое путём сжигания дерева в качестве ингредиента в печи. Оно имеет такую же длительность горения, как и каменный уголь, но из него нельзя сделать угольные блоки. -Chiseled Stone Bricks=Точёный каменный блок -Chiseled Red Sandstone=Точёный красный камень -Chiseled Sandstone=Точёный песчаник -Chiseled red sandstone is a decorative building block.=Точёный красный камень это декоративный строительный блок. -Chiseled sandstone is a decorative building block.=Точёный песчаник это декоративный строительный блок. -Clay=Глина -Clay Ball=Глиняный шарик -Clay balls are a raw material, mainly used to create bricks in the furnace.=Глиняные шарики это необработанный материал, в основном используемый для создания кирпичей при помощи печи. -Clay is a versatile kind of earth commonly found at beaches underwater.=Глина это универсальный тип почвы, часто встречающийся под водой возле отмелей. +Charcoal is an alternative furnace fuel created by cooking wood in a furnace. It has the same burning time as coal and also shares many of its crafting recipes, but it can not be used to create coal blocks.=Древесный уголь это альтернативное печное топливо, получаемое путём сжигания древесины в качестве ингредиента в печи. Оно имеет такую же длительность горения, как и каменный уголь, но из него нельзя сделать угольные блоки. +Chiseled Stone Bricks=Декоративные каменные кирпичи +Chiseled Red Sandstone=Декоративный красный песчаник +Chiseled Sandstone=Декоративный песчаник +Chiseled red sandstone is a decorative building block.=Декоративный красный песчаник это декоративный строительный блок. +Chiseled sandstone is a decorative building block.=Декоративный песчаник это декоративный строительный блок. +Clay=Глиняный блок +Clay Ball=Глина +Clay balls are a raw material, mainly used to create bricks in the furnace.=Глина это необработанный материал, в основном используемый для создания кирпичей при помощи печи. +Clay is a versatile kind of earth commonly found at beaches underwater.=Глиняный блок это тип почвы, часто встречающийся на побережьях под водой. Coal=Уголь Coal Ore=Угольная руда -Coarse Dirt=Твёрдая грязь -Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=Твёрдая грязь равносильна почве для некоторых растений и похожа на обычную грязь, но на ней не растёт трава. +Coarse Dirt=Каменистая земля +Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=Каменистая земля это почва для некоторых растений и похожа на обычную землю, но на ней никогда не растёт трава. Cobblestone=Булыжник Cobweb=Паутина Cobwebs can be walked through, but significantly slow you down.=Паутину можно пройти насквозь, но она ощутимо снижает вашу скорость. -Cracked Stone Bricks=Треснутые каменные блоки -Cut Red Sandstone=Резной красный камень +Cracked Stone Bricks=Потрескавшиеся каменные кирпичи +Cut Red Sandstone=Резной красный песчаник Cut Sandstone=Резной песчаник -Cut red sandstone is a decorative building block.=Резной красный камень это декоративный строительный блок. +Cut red sandstone is a decorative building block.=Резной красный песчаник это декоративный строительный блок. Cut sandstone is a decorative building block.=Резной песчаник это декоративный строительный блок. -Cyan Stained Glass=Голубое витражное стекло +Cyan Stained Glass=Бирюзовое стекло Dark Oak Bark=Кора тёмного дуба Dark Oak Leaves=Листва тёмного дуба Dark Oak Sapling=Саженец тёмного дуба -Dark Oak Wood=Тёмный дуб +Dark Oak Wood=Древесина тёмного дуба Dark Oak Wood Planks=Доски из тёмного дуба Dark oak leaves are grown from dark oak trees.=Листва тёмного дуба произрастает на деревьях тёмного дуба. -Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.=Из саженцев тёмного дуба могут вырастать деревья, но для этого надо высаживать их группами. Одинокие саженцы не будут расти. Группа из четырёх саженцев станет деревом через некоторое время после высадки на освещённый участок почвы (или грязи) в виде квадрата 2*2. +Dark oak saplings can grow into dark oaks, but only in groups. A lonely dark oak sapling won't grow. A group of four dark oak saplings grows into a dark oak after some time when they are placed on soil (such as dirt) in a 2×2 square and exposed to light.=Из саженцев тёмного дуба могут вырастать деревья, но для этого надо высаживать их группами. Одинарные саженцы не будут расти. Группа из четырёх саженцев станет деревом через некоторое время после высадки на освещённый участок почвы в виде квадрата 2×2. Dead Bush=Мёртвый куст Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=Мёртвые кусты это непримечательные растения, часто встречающиеся в засушливых областях. Их можно собирать, чтобы сделать из них палки. Diamond=Алмаз Diamond Ore=Алмазная руда -Diamond ore is rare and can be found in clusters near the bottom of the world.=Алмазная руда встречается редко, в виде скоплений около дна мира. +Diamond ore is rare and can be found in clusters near the bottom of the world.=Алмазная руда встречается редко, в виде скоплений в нижних слоях мира. Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Алмазы это драгоценные камни, используемые для создания брони и инструментов высшего качества. Diorite=Диорит Diorite is an igneous rock.=Диорит это камень вулканической природы. -Dirt=Грязь -Dirt acts as a soil for a few plants. When in light, this block may grow a grass or mycelium cover if such blocks are nearby.=Грязь то же самое, что почва для некоторых растений. Под освещением на этом блоке может прорасти трава или мицелий, если такие блоки уже есть поблизости. +Dirt=Земля +Dirt acts as a soil for a few plants. When in light, this block may grow a grass or mycelium cover if such blocks are nearby.=Земля это почва для некоторых растений. Под освещением на этом блоке может прорасти трава или мицелий, если такие блоки уже есть поблизости. Emerald=Изумруд Emerald Ore=Изумрудная руда -Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are used in villager trades as currency.= +Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку, а не в кластерах. +Emeralds are used in villager trades as currency.=Изумруды используют деревенские жители в качестве валюты. Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава Flowing Water=Текущая вода -Frosted Ice=Намёрзший лёд -Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=Намёрзший лёд это быстро исчезающий твёрдый блок. Он за несколько секунд тает, превращаясь в источник воды. +Frosted Ice=Подмороженный лёд +Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=Подмороженный лёд это быстро исчезающий твёрдый блок. Он растает через несколько секунд, превратившись в источник воды. Glass=Стекло Gold Ingot=Золотой слиток Gold Nugget=Золотой самородок Gold Ore=Золотая руда Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=Золотые самородки это мелкие частички чистого золота, которые можно объединять в золотые слитки. Golden Apple=Золотое яблоко -Golden apples are precious food items which can be eaten.=Золотые яблоки это изысканные продуктовые предметы, которые можно есть. +Golden apples are precious food items which can be eaten.=Золотые яблоки это ценный съедобный продукт. Granite=Гранит -Grass Block=Травяной блок +Grass Block=Дёрн Grass Path=Тропинка -Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created with a shovel. A grass path turns into dirt when it is below a solid block.=Тропинки это декоративная разновидность травяных блоков. Их верхняя часть окрашена другим цветом, а они сами чуть ниже, чтобы это смотрелось как притоптанная трава. Такие блоки можно создать при помощи лопаты. При помещении под твёрдый блок данные блоки превращаются в грязь. +Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created with a shovel. A grass path turns into dirt when it is below a solid block.=Тропинки это декоративная разновидность травяных блоков. Их верхняя часть окрашена другим цветом, а они сами чуть ниже, чтобы это смотрелось как притоптанная трава. Такие блоки можно создать при помощи лопаты. При помещении под твёрдый блок данные блоки превращаются в землю. Gravel=Гравий -Green Stained Glass=Зелёное витражное стекло -Grey Stained Glass=Серое витражное стекло +Green Stained Glass=Зелёное стекло +Grey Stained Glass=Серое стекло Ice=Лёд -Ice is a solid block usually found in cold areas. It melts near block light sources at a light level of 12 or higher. When it melts or is broken while resting on top of another block, it will turn into a water source.=Лёд это твёрдый блок, обычно встречающийся в холодных областях. Он плавится, когда рядом имеется источник света уровня 12 и выше. Если он плавится или ломается, будучи расположенным на другом блоке, то превращается в источник воды. -In the End dimension, starting a fire on this block will create an eternal fire.=В измерении Предела разжигание огня на этом блоке создаст вечный огонь. +Ice is a solid block usually found in cold areas. It melts near block light sources at a light level of 12 or higher. When it melts or is broken while resting on top of another block, it will turn into a water source.=Лёд это твёрдый блок, обычно встречающийся в холодных областях. Он тает, когда рядом имеется источник света уровня 12 и выше. Если он тает или ломается, будучи расположенным на другом блоке, то превращается в источник воды. +In the End dimension, starting a fire on this block will create an eternal fire.=В измерении Края разжигание огня на этом блоке создаст вечный огонь. Iron Ingot=Железный слиток Iron Nugget=Железный самородок Iron Ore=Железная руда Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Железные самородки это маленькие частички чистого железа, которые можно объединять в железные слитки. -Jungle Bark=Кора дерева джунглей -Jungle Leaves=Листва дерева джунглей -Jungle Sapling=Саженец дерева джунглей -Jungle Wood=Дерево джунглей -Jungle Wood Planks=Доски из дерева джунглей -Jungle leaves are grown from jungle trees.=Листва дерева джунглей произрастает на деревьях джунглей. +Jungle Bark=Кора тропического дерева +Jungle Leaves=Листва тропического дерева +Jungle Sapling=Саженец тропического дерева +Jungle Wood=Древесина тропического дерева +Jungle Wood Planks=Доски из тропического дерева +Jungle leaves are grown from jungle trees.=Листва тропического дерева произрастает на тропических деревьях. Ladder=Лестница -Lapis Lazuli=Ляпис-лазурь -Lapis Lazuli are required for enchanting items on an enchanting table.=Лазурит требуется для зачарования предметов на столе зачаровывания. -Lapis Lazuli Block=Ляпис-лазурный блок -Lapis Lazuli Ore=Ляпис-лазурная руда -Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Ляпис-лазурная руда это руда ляпис-лазури. Она изредка встречается в виде скоплений вблизи дна мира. +Lapis Lazuli=Лазурит +Lapis Lazuli are required for enchanting items on an enchanting table.=Лазурит требуется для зачарования предметов на столе зачарований. +Lapis Lazuli Block=Блок лазурита +Lapis Lazuli Ore=Лазуритовая руда +Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Лазуритовая руда это руда лазурита. Она изредка встречается в виде скоплений в нижних слоях мира. Lava Source=Источник лавы -Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=Лава горячая и довольно опасная. Не прикасайтесь к ней, это причинит сильную боль, и выбраться из неё сложно. -Light Blue Stained Glass=Светло-голубое витражное стекло -Light Grey Stained Glass=Светло-серое витражное стекло -Lime Stained Glass=Зелёное лаймовое витражное стекло -Lit Redstone Ore=Светящаяся руда красного камня -Magenta Stained Glass=Фиолетовое витражное стекло -Molten gold. It is used to craft armor, tools, and whatnot.=Чистое золото. Используется для создания брони, инструментов и чего угодно. -Molten iron. It is used to craft armor, tools, and whatnot.=Чистое железо. Используется для создания брони, инструментов и чего угодно. -Mossy Cobblestone=Мшистый булыжник -Mossy Stone Bricks=Мшистый каменный блок +Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=Лава горячая и довольно опасная. Не прикасайтесь к ней, это нанесет вам урон, и выплыть из неё сложно. +Light Blue Stained Glass=Голубое стекло +Light Grey Stained Glass=Светло-серое стекло +Lime Stained Glass=Лаймовое стекло +Lit Redstone Ore=Светящаяся руда редстоуна +Magenta Stained Glass=Сиреневое стекло +Molten gold. It is used to craft armor, tools, and whatnot.=Золотой слиток. Используется для создания брони, инструментов и прочего. +Molten iron. It is used to craft armor, tools, and whatnot.=Железный слиток. Используется для создания брони, инструментов и прочего. +Mossy Cobblestone=Замшелый булыжник +Mossy Stone Bricks=Замшелые каменные кирпичи Mycelium=Мицелий -Mycelium is a type of dirt and the ideal soil for mushrooms. Unlike other dirt-type blocks, it can not be turned into farmland with a hoe. In light, mycelium slowly spreads over nearby dirt. Under an opaque block or a liquid, it eventually turns back into dirt.=Мицелий это тип грязи, идеально подходящий для грибов. В отличие от других грязевых блоков, он не может быть превращён в грядку при помощи мотыги. При наличии освещения мицелий медленно распространяется по соседствующей с ним грязи. Под непрозрачным блоком или жидкостью со временем превращается обратно в грязь. -Oak Bark=Кора дуба -Oak Leaves=Листва дуба +Mycelium is a type of dirt and the ideal soil for mushrooms. Unlike other dirt-type blocks, it can not be turned into farmland with a hoe. In light, mycelium slowly spreads over nearby dirt. Under an opaque block or a liquid, it eventually turns back into dirt.=Мицелий это идеальная почва для грибов. В отличие от других земляных блоков, он не может быть превращён в грядку при помощи мотыги. При наличии освещения мицелий медленно распространяется по соседствующие с ним блоки земли. Под непрозрачным блоком или жидкостью со временем превращается обратно в землю. +Oak Bark=Дубовая кора +Oak Leaves=Дубовая листва Oak Sapling=Саженец дуба -Oak Wood=Дуб +Oak Wood=Дубовая древесина Oak Wood Planks=Дубовые доски Oak leaves are grown from oak trees.=Листва дуба произрастает на дубовых деревьях. Obsidian=Обсидиан Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava.=Обсидиан это чрезвычайно твёрдый минерал с высочайшей взрывоустойчивостью. -One of the most common blocks in the world, almost the entire underground consists of stone. It sometimes contains ores. Stone may be created when water meets lava.=Один из самых обычных блоков мира, почти вся подземная часть состоит из камня. Иногда он содержит руду. Камень может создаться при встрече воды с лавой. -Orange Stained Glass=Оранжевое витражное стекло -Packed Ice=Упакованный лёд -Packed ice is a compressed form of ice. It is opaque and solid.=Упакованный лёд это сжатая форма льда. Он непрозрачный и твёрдый. +One of the most common blocks in the world, almost the entire underground consists of stone. It sometimes contains ores. Stone may be created when water meets lava.=Один из самых распространённых блоков в мире, почти вся подземная часть состоит из камня. Иногда он содержит руду. Камень может создаться при встрече воды с лавой. +Orange Stained Glass=Оранжевое стекло +Packed Ice=Плотный лёд +Packed ice is a compressed form of ice. It is opaque and solid.=Плотный лёд это сжатая форма льда. Он непрозрачный и твёрдый. Paper=Бумага Paper is used to craft books and maps.=Бумага используется для создания книг и карт. -Pink Stained Glass=Розовое витражное стекло +Pink Stained Glass=Розовое стекло Podzol=Подзол -Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Подзол это тип грязи, встречающийся в таёжных лесах. Только несколько растений имеют способность выжить на нём. -Polished Andesite=Гладкий андезит -Polished Diorite=Гладкий диорит -Polished Granite=Гладкий гранит -Polished Stone=Гладкий камень -Polished andesite is a decorative building block made from andesite.=Гладкий андезит это декоративный строительный блок, сделанный из андезита. -Polished diorite is a decorative building block made from diorite.=Гладкий диорит это декоративный строительный блок, сделанный из диорита. -Polished granite is a decorative building block made from granite.=Гладкий гранит это декоративный строительный блок, сделанный из гранита. -Purple Stained Glass=Пурпурное витражное стекло +Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Подзол это тип земли, встречающийся в таёжных лесах. Только несколько растений имеют способность выжить на нём. +Polished Andesite=Полированный андезит +Polished Diorite=Полированный диорит +Polished Granite=Полированный гранит +Polished Stone=Полированный камень +Polished andesite is a decorative building block made from andesite.=Гладкий андезит это декоративный строительный блок из андезита. +Polished diorite is a decorative building block made from diorite.=Гладкий диорит это декоративный строительный блок из диорита. +Polished granite is a decorative building block made from granite.=Гладкий гранит это декоративный строительный блок из гранита. +Purple Stained Glass=Фиолетовое стекло Realm Barrier=Барьер области Red Sand=Красный песок Red Sandstone=Красный песчаник -Red Stained Glass=Красное витражное стекло +Red Stained Glass=Красное стекло Red sand is found in large quantities in mesa biomes.=Красный песок в больших количествах встречается в биомах столовых гор. -Red sandstone is compressed red sand and is a rather soft kind of stone.=Красный песчаник это сжатый красный песок, мягкая разновидность камня. -Redstone Ore=Краснокаменная руда -Redstone ore is commonly found near the bottom of the world. It glows when it is punched or walked upon.=Краснокаменная руда обычно содержится вблизи дна мира. +Red sandstone is compressed red sand and is a rather soft kind of stone.=Красный песчаник это сжатый красный песок, некая разновидность камня. +Redstone Ore=Редстоуновая руда +Redstone ore is commonly found near the bottom of the world. It glows when it is punched or walked upon.=Редстоуновая руда обычно содержится в нижних слоях мира. Sand=Песок Sand is found in large quantities at beaches and deserts.=Песок в больших количествах встречается на пляжах и в пустынях. Sandstone=Песчаник -Sandstone is compressed sand and is a rather soft kind of stone.=Песчаник это сжатый песок, мягкая разновидность камня. +Sandstone is compressed sand and is a rather soft kind of stone.=Песчаник это сжатый песок, некая разновидность камня. Slime Block=Блок слизи -Slime blocks are very bouncy and prevent fall damage.=Блок слизи очень упруг и спасает от повреждений при падении. -Smooth Red Sandstone=Гладкий красный камень +Slime blocks are very bouncy and prevent fall damage.=Блок слизи очень упругий и спасает от повреждений при падении. +Smooth Red Sandstone=Гладкий красный песчаник Smooth Sandstone=Гладкий песчаник -Smooth red sandstone is a decorative building block.=Гладкий красный камень это декоративный строительный блок. -Smooth sandstone is compressed sand and is a rather soft kind of stone.=Гладкий песчаник это сжатый песок, мягкая разновидность камня. +Smooth red sandstone is a decorative building block.=Гладкий красный песчаник это декоративный строительный блок. +Smooth sandstone is compressed sand and is a rather soft kind of stone.=Гладкий песчаник это сжатый песок, некая разновидность камня. Snow=Снег -Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Немного угля содержится в камне, это обычное явление, скопления таких блоков встречаются около возвышенностей. -Some iron contained in stone, it is prety common and can be found below sea level.=Немного железа содержится в камне, это довольно обычное явление, такие блоки встречаются ниже уровня моря. -Spruce Bark=Кора ели -Spruce Leaves=Хвоя +Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Уголь содержится в камне, он весьма распространён, скопления таких блоков встречаются около возвышенностей. +Some iron contained in stone, it is prety common and can be found below sea level.=Железо содержится в камне, оно весьма распространено, такие блоки встречаются ниже уровня моря. +Spruce Bark=Еловая кора +Spruce Leaves=Еловая хвоя Spruce Sapling=Саженец ели -Spruce Wood=Ель +Spruce Wood=Еловая древесина Spruce Wood Planks=Еловые доски Spruce leaves are grown from spruce trees.=Хвоя растёт на еловых деревьях. -Stained glass is a decorative and mostly transparent block which comes in various different colors.=Витражное стекло это декоративный и в основном прозрачный блок, встречающийся в различных расцветках. +Stained glass is a decorative and mostly transparent block which comes in various different colors.=Окрашенное стекло это декоративный прозрачный блок, встречающийся в различных расцветках. Stick=Палка -Sticks are a very versatile crafting material; used in countless crafting recipes.=Палки это универсальный материал, используемый для создания различных вещей, присутствует во многих рецептах. +Sticks are a very versatile crafting material; used in countless crafting recipes.=Палки это универсальный материал, используемый для крафта различных предметов, присутствует во многих рецептах. Stone=Камень -Stone Bricks=Каменные блоки +Stripped Acacia Log=Обтёсанная акациевая древесина +Stripped Acacia Wood=Обтёсанная акациевая кора +Stripped Birch Log=Обтёсанная берёзовая древесина +Stripped Birch Wood=Обтёсанная берёзовая кора +Stripped Dark Oak Log=Обтёсанная древесина тёмного дуба +Stripped Dark Oak Wood=Обтёсанная кора тёмного дуба +Stripped Jungle Log=Обтёсанная тропическая древесина +Stripped Jungle Wood=Обтёсанная тропическая кора +Stripped Oak Log=Обтёсанная дубовая древесина +Stripped Oak Wood=Обтёсанная дубовая кора +Stripped Spruce Log=Обтёсанная еловая древесина +Stripped Spruce Wood=Обтёсанная еловая кора +Stone Bricks=Каменные кирпичи Sugar=Сахар Sugar Canes=Сахарный тростник -Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly grow up to 3 blocks when they are next to water and are placed on a grass block, dirt, sand, red sand, podzol or coarse dirt. When a sugar cane is broken, all sugar canes connected above will break as well.=Сахарный тростник это растение, имеющее некоторое применение в крафтинге. Если тростник находится по соседству с водой на травяном блоке, грязи, красном песке, подзоле или грубой грязи, он будет медленно расти вверх до 3 блоков. Если сломать тростник, все верхние части также сломаются. +Sugar canes are a plant which has some uses in crafting. Sugar canes will slowly grow up to 3 blocks when they are next to water and are placed on a grass block, dirt, sand, red sand, podzol or coarse dirt. When a sugar cane is broken, all sugar canes connected above will break as well.=Сахарный тростник это растение, используемое в крафте. Если тростник находится по соседству с водой на дёрне, земле, песке, красном песке, подзоле или каменистой земле, он будет медленно расти вверх до 3 блоков. Если сломать тростник, все верхние части также сломаются. Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Сахарный тростник может быть помещён только на верхушку другого сахарного тростника, либо на верхнюю часть другого блока, на котором он может расти. Sugar comes from sugar canes and is used to make sweet foods.=Сахар добывают из сахарного тростника и используют для приготовления сладких продуктов. -The trunk of a birch tree.=Берёзовый ствол -The trunk of a dark oak tree.=Ствол тёмного дуба -The trunk of a jungle tree.=Ствол дерева джунглей -The trunk of a spruce tree.=Еловый ствол -The trunk of an acacia.=Ствол акации -The trunk of an oak tree.=Дубовый ствол -This block consists of a couple of loose stones and can't support itself.=Этот блок состоит из пары рыхлых камней и не может удержать себя. -This is a decorative block surrounded by the bark of a tree trunk.=Это декоративный блок, окружённый древесной корой. -This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Это целый блок снега. Снег такой толщины обычно встречается в экстремально холодных зонах. -This is a piece of cactus commonly found in dry areas, especially deserts. Over time, cacti will grow up to 3 blocks high on sand or red sand. A cactus hurts living beings touching it with a damage of 1 HP every half second. When a cactus block is broken, all cactus blocks connected above it will break as well.=Это часть кактуса, обычно встречающегося в засушливых областях, особенно в пустынях. Со временем кактусы растут до 3 блоков вверх на песке или красном песке. Кактус колет живых существ, трогающих его, причиняя урон в 1 HP каждые полсекунды. Если сломать кактус, все вышестоящие блоки сломаются также. +The stripped trunk of an acacia tree.=Обтёсанное акациевое бревно. +The stripped trunk of a birch tree.=Обтёсанное берёзовое бревно. +The stripped trunk of a dark oak tree.=Обтёсанное бревно тёмного дуба. +The stripped trunk of a jungle tree.=Обтёсанное тропическое бревно. +The stripped trunk of an oak tree.=Обтёсанное дубовое бревно. +The stripped trunk of a spruce tree.=Обтёсанное еловое бревно. +The trunk of a birch tree.=Берёзовое бревно. +The trunk of a dark oak tree.=Бревно тёмного дуба. +The trunk of a jungle tree.=Тропическое бревно. +The trunk of a spruce tree.=Еловое бревно. +The trunk of an acacia.=Акациевое бревно. +The trunk of an oak tree.=Дубовое бревно. +The stripped wood of an acacia tree.=Обтёсанная акациевая кора. +The stripped wood of a birch tree.=Обтёсанная берёзовая кора. +The stripped wood of a dark oak tree.=Обтёсанная кора тёмного дуба. +The stripped wood of a jungle tree.=Обтёсанная тропическая кора. +The stripped wood of an oak tree.=Обтёсанная дубовая кора. +The stripped wood of a spruce tree.=Обтёсанная еловая кора. +This block consists of a couple of loose stones and can't support itself.=Этот блок рыхлый и не может поддерживать себя. +This is a decorative block surrounded by the bark of a tree trunk.=Это декоративный блок из древесной коры. +This is a decorative block.=Это декоративный блок. +This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Это блок снега. Снег такой толщины обычно встречается в экстремально холодных зонах. +This is a piece of cactus commonly found in dry areas, especially deserts. Over time, cacti will grow up to 3 blocks high on sand or red sand. A cactus hurts living beings touching it with a damage of 1 HP every half second. When a cactus block is broken, all cactus blocks connected above it will break as well.=Это кактус, обычно встречающийся в засушливых регионах, особенно в пустынях. Со временем кактусы вырастают до 3 блоков вверх на песке или красном песке. Кактус колет живых существ, касающихся его, причиняя урон в 1 единицу здоровья каждые полсекунды. Если сломать кактус, все вышестоящие блоки сломаются также. This stone contains pure gold, a rare metal.=Этот камень содержит чистое золото, редкий металл. -Top Snow=Наст -Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=Наст это верхний слой снега. Он тает вблизи не солнечных источников света с яркостью уровня 12 и выше. +Top Snow=Слой снега +Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=Слой снега. Он тает вблизи источников света с яркостью уровня 12 и выше. Vines=Лоза -Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Лоза это блок, по которому можно карабкаться, он может быть помещён по сторонам твёрдого кубического блока. +Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Лоза это блок, по которому можно карабкаться, он может быть помещён по сторонам твёрдого блока. Void=Пустота Water=Вода Water Source=Источник воды Water is abundant in oceans and also appears in a few springs in the ground. You can swim easily in water, but you need to catch your breath from time to time.=Вода изобилует в океанах и также встречается в виде ключей под землёй. -When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=После высадки на почву (например, грязь) при наличии света саженец берёзы вырастет в берёзу через некоторое время. -When placed on soil (such as dirt) and exposed to light, a jungle sapling will grow into a jungle tree after some time. When there are 4 jungle saplings in a 2×2 square, they will grow to a huge jungle tree.=После высадки на почву (например, грязь) при наличии света саженец дерева джунглей вырастет в дерево джунглей через некоторое время. Если высадить 4 саженца по схеме 2*2, вырастет огромное дерево джунглей. -When placed on soil (such as dirt) and exposed to light, a spruce sapling will grow into a spruce after some time. When there are 4 spruce saplings in a 2×2 square, they will grow to a huge spruce.=После высадки на почву (например, грязь) при наличии света саженец ели вырастет в ель через некоторое время. Если высадить 4 саженца по схеме 2*2, вырастет огромная ель. -When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=После высадки на почву (например, грязь) при наличии света саженец акации вырастет в акацию через некоторое время. -When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=После высадки на почву (например, грязь) при наличии света саженец дуба вырастет в дуб через некоторое время. +When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=После посадки на почву (например, на землю) при наличии света саженец берёзы вырастет в берёзу через некоторое время. +When placed on soil (such as dirt) and exposed to light, a jungle sapling will grow into a jungle tree after some time. When there are 4 jungle saplings in a 2×2 square, they will grow to a huge jungle tree.=После посадки на почву (например, на землю) при наличии света саженец тропического дерева вырастет в тропическое дерево через некоторое время. Если высадить 4 саженца по схеме 2×2, вырастет огромное тропическое дерево. +When placed on soil (such as dirt) and exposed to light, a spruce sapling will grow into a spruce after some time. When there are 4 spruce saplings in a 2×2 square, they will grow to a huge spruce.=После посадки на почву (например, на землю) при наличии света саженец ели вырастет в ель через некоторое время. Если высадить 4 саженца по схеме 2×2, вырастет огромная ель. +When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=После посадки на почву (например, на землю) при наличии света саженец акации вырастет в акацию через некоторое время. +When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=После посадки на почву (например, на землю) при наличии света саженец дуба вырастет в дуб через некоторое время. When you hold a barrier in hand, you reveal all placed barriers in a short distance around you.=Когда вы держите барьер в руке, вы видите все барьеры, размещённые вокруг вас вблизи. -White Stained Glass=Белое витражное стекло -Yellow Stained Glass=Жёлтое витражное стекло -“Coal” refers to coal lumps obtained by digging coal ore which can be found underground. Coal is your standard furnace fuel, but it can also be used to make torches, coal blocks and a few other things.=“Уголь” относится к угольным кускам, добываемым из угольной руды, которую можно встретить под землёй. Уголь это стандартное печное топливо для вас, но он также нужен, чтобы сделать факелы, угольные блоки и несколько других вещей. +White Stained Glass=Белое стекло +Yellow Stained Glass=Жёлтое стекло +“Coal” refers to coal lumps obtained by digging coal ore which can be found underground. Coal is your standard furnace fuel, but it can also be used to make torches, coal blocks and a few other things.=“Уголь” относится к угольным кускам, добываемым из угольной руды, которую можно встретить под землёй. Уголь это стандартное печное топливо, но он также нужен, чтобы сделать факелы, угольные блоки и некоторые другие предметы. Water interacts with lava in various ways:=Вода взаимодействует с лавой по-разному: -• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=• Если вода прямо над источником лавы или соседствует с ним в горизонтальном направлении, лава превращается в обсидиан. -• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.=• Если текущая вода прикасается к текущей лаве сверху или сбоку, лава превращается в булыжник. -• When water is directly below lava, the water turns into stone.=• Если вода попадает прямо под лаву, эта вода превращается в камень. +• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=• Если вода прямо над источником лавы или соседствует с ним в горизонтальном направлении, источник лавы превращается в обсидиан. +• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.=• Если текущая вода прикасается к текущей лаве сверху или сбоку, текущая лава превращается в булыжник. +• When water is directly below lava, the water turns into stone.=• Если вода попадает прямо под лаву, этот источник воды превращается в камень. Lava interacts with water various ways:=Лава взаимодействует с водой по-разному: -• When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Когда источник лавы прямо под водой, либо вода сбоку от него, лава превращается в обсидиан. -• When lava is directly above water, the water turns into stone.=• Когда лава прямо над водой, вода превращается в камень. -Stained Glass=Витражное стекло -Granite is an igneous rock.=Гранит это камень вулканической природы. -Top snow can be stacked and has one of 8 different height levels. At levels 2-8, top snow is collidable. Top snow drops 2-9 snowballs, depending on its height.=Наст может стыковаться и иметь один из 8 разных уровней высоты. При уровнях 2-8 в снег нельзя провалиться. Верхний снег превращается в 2-9 снежков, в зависимости от его высоты. -This block can only be placed on full solid blocks and on another top snow (which increases its height).=Этот блок можно поместить только на целый твёрдый блок либо на другой наст (что увеличит его высоту). +• When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Когда источник лавы прямо под водой, либо вода сбоку от него, источник лавы превращается в обсидиан. +• When lava is directly above water, the water turns into stone.=• Когда лава прямо над водой, источник воды превращается в камень. +Stained Glass=Окрашенное стекло +Granite is an igneous rock.=Гранит это камень вулканической породы. +Top snow can be stacked and has one of 8 different height levels. At levels 2-8, top snow is collidable. Top snow drops 2-9 snowballs, depending on its height.=Слои снега могут наслаиваться друг на друга и иметь один из 8 разных уровней высоты. При уровнях 2-8 слой снега становится непроходиымы. Слой снега дропает 2-9 снежков, в зависимости от его высоты. +This block can only be placed on full solid blocks and on another top snow (which increases its height).=Этот блок можно поместить только на целый твёрдый блок либо на другой слой (что увеличит его высоту). Needs soil and water to grow=Нуждается в почве и воде, чтобы расти Needs soil and light to grow=Нуждается в почве и свете, чтобы расти Grows on sand=Растёт на песке -Contact damage: @1 per half second=Повреждение при контакте: @1 за полсекунды +Contact damage: @1 per half second=Урон при контакте: @1 HP/0.5 с Slows down movement=Замедляет перемещение -2×2 saplings required=Высаживается по схеме 2*2 -2×2 saplings @= large tree=2*2 саженца @= большое дерево -Grows on sand or dirt next to water=Растёт на песке или грязи рядом с водой -Stackable=Можно состыковать +2×2 saplings required=Высаживается по схеме 2×2 +2×2 saplings @= large tree=2×2 саженца @= большое дерево +Grows on sand or dirt next to water=Растёт на песке или земле рядом с водой +Stackable=Наслаивается +Crying Obsidian=Плачущий обсидиан +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=Плачущий обсидиан это светящийся обсидиан который может сгенерироваться как часть разрушенных порталов. +Enchanted Golden Apple=Зачарованное золотое яблоко +Light=Свет +Lights are invisible blocks. They are used to light up adventure maps and the like.=Свет это невидимые блоки. Используются для подсветки приключенческих карт и всё в этом роде. +When you hold a light in hand, you reveal all placed lights in a short distance around you.=Когда вы держите свет в руке, вы видите все расставленные блоки света на небольшой дистанции от вас. diff --git a/mods/ITEMS/mcl_core/mod.conf b/mods/ITEMS/mcl_core/mod.conf index 45018df75..d96f159b5 100644 --- a/mods/ITEMS/mcl_core/mod.conf +++ b/mods/ITEMS/mcl_core/mod.conf @@ -1,4 +1,4 @@ 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. -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 diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 79cd37d8e..db2561082 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -406,7 +406,7 @@ mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_wi minetest.register_node("mcl_core:grass_path", { tiles = {"mcl_core_grass_path_top.png", "default_dirt.png", "mcl_core_grass_path_side.png"}, description = S("Grass Path"), - _doc_items_longdesc = S("Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created with a shovel. A grass path turns into dirt when it is below a solid block."), + _doc_items_longdesc = S("Grass paths are a decorative variant of grass blocks. Their top has a different color and they are a bit lower than grass blocks, making them useful to build footpaths. Grass paths can be created by right clicking with a shovel. A grass path turns into dirt when it is below a solid block or when shift+right clicked with a shovel."), drop = "mcl_core:dirt", is_ground_content = true, use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, @@ -419,7 +419,7 @@ minetest.register_node("mcl_core:grass_path", { {-0.5, -0.5, -0.5, 0.5, 0.4375, 0.5}, } }, - groups = {handy=1,shovely=1, cultivatable=2, dirtifies_below_solid=1, dirtifier=1, deco_block=1 }, + groups = {handy=1,shovely=1, cultivatable=2, dirtifies_below_solid=1, dirtifier=1, deco_block=1, path_remove_possible=1 }, sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), @@ -1038,7 +1038,7 @@ for i=1,8 do -- Get position where snow would be placed local target - if minetest.registered_nodes[unode.name].buildable_to then + if def and def.buildable_to then target = under else target = above @@ -1124,6 +1124,19 @@ minetest.register_node("mcl_core:snowblock", { _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 if minetest.get_modpath("doc") then doc.add_entry_alias("nodes", "mcl_core:stone_with_redstone", "nodes", "mcl_core:stone_with_redstone_lit") diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua index 79b440f61..805385124 100644 --- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua +++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua @@ -135,4 +135,4 @@ minetest.register_node("mcl_core:reeds", { end, _mcl_blast_resistance = 0, _mcl_hardness = 0, -}) +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_core/nodes_climb.lua b/mods/ITEMS/mcl_core/nodes_climb.lua index 33a34f899..0de0e9abd 100644 --- a/mods/ITEMS/mcl_core/nodes_climb.lua +++ b/mods/ITEMS/mcl_core/nodes_climb.lua @@ -11,12 +11,39 @@ local function rotate_climbable(pos, node, user, mode) return false end +---Updates the trapdoor above (if any). +--- +---@param pos mt.Vector The position of the ladder. +---@param event "place" | "destruct" The place or destruct event. +function mcl_core.update_trapdoor(pos, event) + local top_pos = vector.offset(pos, 0, 1, 0) + local top_node = minetest.get_node_or_nil(top_pos) + + if top_node and minetest.get_item_group(top_node.name, "trapdoor") == 2 then + local new_name = top_node.name + if event == "place" then + new_name = string.gsub(new_name, "open$", "ladder") + elseif event == "destruct" then + new_name = string.gsub(new_name, "ladder$", "open") + end + + -- If node above is an opened trapdoor + minetest.swap_node(top_pos, { + name = new_name, + param1 = top_node.param1, + param2 = top_node.param2, + }) + end +end + +-- TODO: Move ladders into their own API. minetest.register_node("mcl_core:ladder", { description = S("Ladder"), - _doc_items_longdesc = S("A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns."), + _doc_items_longdesc = S( + "A piece of ladder which allows you to climb vertically. Ladders can only be placed on the side of solid blocks and not on glass, leaves, ice, slabs, glowstone, nor sea lanterns."), drawtype = "signlike", is_ground_content = false, - tiles = {"default_ladder.png"}, + tiles = { "default_ladder.png" }, inventory_image = "default_ladder.png", wield_image = "default_ladder.png", paramtype = "light", @@ -26,14 +53,21 @@ minetest.register_node("mcl_core:ladder", { climbable = true, node_box = { type = "wallmounted", - wall_side = { -0.5, -0.5, -0.5, -7/16, 0.5, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 }, }, selection_box = { type = "wallmounted", - wall_side = { -0.5, -0.5, -0.5, -7/16, 0.5, 0.5 }, + wall_side = { -0.5, -0.5, -0.5, -7 / 16, 0.5, 0.5 }, }, stack_max = 64, - groups = {handy=1,axey=1, attached_node=1, deco_block=1, dig_by_piston=1}, + groups = { + handy = 1, + axey = 1, + attached_node = 1, + deco_block = 1, + dig_by_piston = 1, + ladder = 1 + }, sounds = mcl_sounds.node_sound_wood_defaults(), node_placement_prediction = "", -- Restrict placement of ladders @@ -53,7 +87,7 @@ minetest.register_node("mcl_core:ladder", { -- Don't allow to place the ladder at particular nodes if (groups and (groups.glass or groups.leaves or groups.slab)) or - node.name == "mcl_core:ladder" or node.name == "mcl_core:ice" or node.name == "mcl_nether:glowstone" or node.name == "mcl_ocean:sea_lantern" then + node.name == "mcl_core:ladder" or node.name == "mcl_core:ice" or node.name == "mcl_nether:glowstone" or node.name == "mcl_ocean:sea_lantern" then return itemstack end @@ -75,12 +109,17 @@ minetest.register_node("mcl_core:ladder", { if success then if idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) + minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true) end end return itemstack end, - + after_destruct = function(pos, old) + mcl_core.update_trapdoor(pos, "destruct") + end, + after_place_node = function(pos) + mcl_core.update_trapdoor(pos, "place") + end, _mcl_blast_resistance = 0.4, _mcl_hardness = 0.4, on_rotate = rotate_climbable, @@ -89,9 +128,10 @@ minetest.register_node("mcl_core:ladder", { minetest.register_node("mcl_core:vine", { description = S("Vines"), - _doc_items_longdesc = S("Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread."), + _doc_items_longdesc = S( + "Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread."), drawtype = "signlike", - tiles = {"mcl_core_vine.png"}, + tiles = { "mcl_core_vine.png" }, color = "#48B518", inventory_image = "mcl_core_vine.png", wield_image = "mcl_core_vine.png", @@ -107,9 +147,19 @@ minetest.register_node("mcl_core:vine", { }, stack_max = 64, groups = { - handy = 1, axey = 1, shearsy = 1, swordy = 1, deco_block = 1, - dig_by_piston = 1, destroy_by_lava_flow = 1, compostability = 50, - flammable = 2, fire_encouragement = 15, fire_flammability = 100, foliage_palette_wallmounted = 1 + handy = 1, + axey = 1, + shearsy = 1, + swordy = 1, + deco_block = 1, + dig_by_piston = 1, + destroy_by_lava_flow = 1, + compostability = 50, + flammable = 2, + fire_encouragement = 15, + fire_flammability = 100, + foliage_palette_wallmounted = 1, + ladder = 1 }, sounds = mcl_sounds.node_sound_leaves_defaults(), drop = "", @@ -151,7 +201,7 @@ minetest.register_node("mcl_core:vine", { if success then if idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) + minetest.sound_play(idef.sounds.place, { pos = above, gain = 1 }, true) end end return itemstack @@ -174,13 +224,19 @@ minetest.register_node("mcl_core:vine", { -- If dug, also dig a “dependant” vine below it. -- A vine is dependant if it hangs from this node and has no supporting block. on_dig = function(pos, node, digger) - local below = vector.offset(pos,0,-1,0) + local below = vector.offset(pos, 0, -1, 0) local belownode = minetest.get_node(below) minetest.node_dig(pos, node, digger) if belownode.name == node.name and (not mcl_core.check_vines_supported(below, belownode)) then minetest.registered_nodes[node.name].on_dig(below, node, digger) end end, + after_destruct = function(pos, old) + mcl_core.update_trapdoor(pos, "destruct") + end, + after_place_node = function(pos) + mcl_core.update_trapdoor(pos, "place") + end, _mcl_blast_resistance = 0.2, diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index e55664432..9a7318af7 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -18,17 +18,17 @@ end minetest.register_node("mcl_core:water_flowing", { description = S("Flowing Water"), _doc_items_create_entry = false, - wield_image = "default_water_flowing_animated.png^[verticalframe:64:0", + wield_image = "mcl_core_water_flow_animation.png^[verticalframe:64:0", drawtype = "flowingliquid", - tiles = {"default_water_flowing_animated.png^[verticalframe:64:0"}, + tiles = {"mcl_core_water_flow_animation.png^[verticalframe:64:0"}, special_tiles = { { - image="default_water_flowing_animated.png", + image="mcl_core_water_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, { - image="default_water_flowing_animated.png", + image="mcl_core_water_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, @@ -71,12 +71,12 @@ S("• When water is directly below lava, the water turns into stone."), drawtype = "liquid", waving = 3, tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + {name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} }, special_tiles = { -- New-style water source material (mostly unused) { - name="default_water_source_animated.png", + name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}, backface_culling = false, } @@ -119,17 +119,17 @@ S("• When water is directly below lava, the water turns into stone."), minetest.register_node("mcl_core:lava_flowing", { description = S("Flowing Lava"), _doc_items_create_entry = false, - wield_image = "default_lava_flowing_animated.png^[verticalframe:64:0", + wield_image = "mcl_core_lava_flow_animation.png^[verticalframe:64:0", drawtype = "flowingliquid", - tiles = {"default_lava_flowing_animated.png^[verticalframe:64:0"}, + tiles = {"mcl_core_lava_flow_animation.png^[verticalframe:64:0"}, special_tiles = { { - image="default_lava_flowing_animated.png", + image="mcl_core_lava_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=6.6} }, { - image="default_lava_flowing_animated.png", + image="mcl_core_lava_flow_animation.png", backface_culling=false, animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=6.6} }, @@ -182,12 +182,12 @@ S("• When flowing water touches flowing lava either from above or horizontally S("• When lava is directly above water, the water turns into stone."), drawtype = "liquid", tiles = { - {name="default_lava_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} + {name="mcl_core_lava_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}} }, special_tiles = { -- New-style lava source material (mostly unused) { - name="default_lava_source_animated.png", + name="mcl_core_lava_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}, backface_culling = false, } diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index d830cc310..ec8eae74e 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -139,8 +139,8 @@ minetest.register_node("mcl_core:deadbush", { sunlight_propagates = true, walkable = false, buildable_to = true, - groups = {handy = 1, shearsy = 1, flammable = 3, attached_node = 1, plant = 1, non_mycelium_plant = 1, dig_by_water = 1, - destroy_by_lava_flow = 1, deco_block = 1, fire_encouragement = 60, fire_flammability = 100}, + groups = {handy = 1, shearsy = 1, flammable = 3, attached_node = 1, plant = 1, non_mycelium_plant = 1, dig_by_piston = 1, + dig_by_water = 1, destroy_by_lava_flow = 1, deco_block = 1, fire_encouragement = 60, fire_flammability = 100}, drop = { max_items = 1, items = { @@ -164,6 +164,12 @@ minetest.register_node("mcl_core:deadbush", { _mcl_hardness = 0, }) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_core:deadbush", + burntime = 5, +}) + minetest.register_node("mcl_core:barrier", { description = S("Barrier"), _doc_items_longdesc = S("Barriers are invisible walkable blocks. They are used to create boundaries of adventure maps and the like. Monsters and animals won't appear on barriers, and fences do not connect to barriers. Other blocks can be built on barriers like on any other block."), diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 7f6b9ccc5..2f114362d 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -1,34 +1,51 @@ +---@diagnostic disable lowercase-global + local S = minetest.get_translator(minetest.get_current_modname()) -local formspec_escape = minetest.formspec_escape -local show_formspec = minetest.show_formspec +local F = minetest.formspec_escape local C = minetest.colorize -local text_color = "#313131" -local itemslot_bg = mcl_formspec.get_itemslot_bg +local show_formspec = minetest.show_formspec mcl_crafting_table = {} -function mcl_crafting_table.show_crafting_form(player) - player:get_inventory():set_width("craft", 3) - player:get_inventory():set_size("craft", 9) +mcl_crafting_table.formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", - show_formspec(player:get_player_name(), "main", - "size[9,8.75]".. - "image[4.7,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4;"..formspec_escape(C(text_color, S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - itemslot_bg(0,7.74,9,1).. - "label[1.75,0;"..formspec_escape(C(text_color, S("Crafting"))).."]".. - "list[current_player;craft;1.75,0.5;3,3;]".. - itemslot_bg(1.75,0.5,3,3).. - "list[current_player;craftpreview;6.1,1.5;1,1;]".. - itemslot_bg(6.1,1.5,1,1).. - "image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..formspec_escape(S("Recipe book")).."]".. - "listring[current_player;main]".. - "listring[current_player;craft]" - ) + "label[2.25,0.375;" .. F(C(mcl_formspec.label_color, S("Crafting"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.25, 0.75, 3, 3), + "list[current_player;craft;2.25,0.75;3,3;]", + + "image[6.125,2;1.5,1;gui_crafting_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(8.2, 2, 1, 1, 0.2), + "list[current_player;craftpreview;8.2,2;1,1;]", + + "label[0.375,4.7;" .. F(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;craft]", + "listring[current_player;main]", + + --Crafting guide button + "image_button[0.325,1.95;1.1,1.1;craftguide_book.png;__mcl_craftguide;]", + "tooltip[__mcl_craftguide;" .. F(S("Recipe book")) .. "]", +}) + +---@param player ObjectRef +function mcl_crafting_table.show_crafting_form(player) + local inv = player:get_inventory() + if inv then + inv:set_width("craft", 3) + inv:set_size("craft", 9) + end + + show_formspec(player:get_player_name(), "main", mcl_crafting_table.formspec) end minetest.register_node("mcl_crafting_table:crafting_table", { @@ -38,10 +55,10 @@ minetest.register_node("mcl_crafting_table:crafting_table", { _doc_items_usagehelp = S("Rightclick the crafting table to access the 3×3 crafting grid."), _doc_items_hidden = false, is_ground_content = false, - tiles = {"crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png", - "crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png"}, + tiles = { "crafting_workbench_top.png", "default_wood.png", "crafting_workbench_side.png", + "crafting_workbench_side.png", "crafting_workbench_front.png", "crafting_workbench_front.png" }, paramtype2 = "facedir", - groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, + groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, flammable = -1 }, on_rightclick = function(pos, node, player, itemstack) if not player:get_player_control().sneak then mcl_crafting_table.show_crafting_form(player) @@ -55,9 +72,9 @@ minetest.register_node("mcl_crafting_table:crafting_table", { minetest.register_craft({ output = "mcl_crafting_table:crafting_table", recipe = { - {"group:wood", "group:wood"}, - {"group:wood", "group:wood"} - } + { "group:wood", "group:wood" }, + { "group:wood", "group:wood" } + }, }) minetest.register_craft({ diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.fr.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.fr.tr index 23caccff7..0e4a59a9a 100644 --- a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.fr.tr +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.fr.tr @@ -1,6 +1,6 @@ # textdomain: mcl_crafting_table Crafting Table=Etabli -A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Un établi est un bloc qui vous donne accès à une grille d'établi 3×3 qui vous permet d'effectuer des objets avancés. +A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Un établi est un bloc qui vous donne accès à une grille d'établi 3×3 qui vous permet de fabriquer des objets avancés. Rightclick the crafting table to access the 3×3 crafting grid.=Faites un clic droit sur l'établi pour accéder à la grille d'établi 3x3. Recipe book=Livre de Recette Crafting=Fabriquer diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ru.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ru.tr index 1e4eb560f..c84437a3c 100644 --- a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ru.tr +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ru.tr @@ -1,8 +1,8 @@ # textdomain: mcl_crafting_table Crafting Table=Верстак -A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Верстак это блок, позволяющий крафтить в решётке 3×3, что позволяет выполнять продвинутый крафтинг. -Rightclick the crafting table to access the 3×3 crafting grid.=Кликните правой для получения доступа к решётке крафтинга 3×3. +A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Верстак это блок с сеткой крафта 3×3, что позволяет использовать продвинутые рецепты. +Rightclick the crafting table to access the 3×3 crafting grid.=Кликните правой кнопкой мыши для получения доступа к сетке крафта 3×3. Recipe book=Книга рецептов -Crafting=Крафтинг +Crafting=Крафт Inventory=Инвентарь -3×3 crafting grid=Решётка крафтинга 3×3 +3×3 crafting grid=Сетка крафта 3×3 \ No newline at end of file diff --git a/mods/ITEMS/mcl_crimson/README.md b/mods/ITEMS/mcl_crimson/README.md index 45c475c11..196148795 100644 --- a/mods/ITEMS/mcl_crimson/README.md +++ b/mods/ITEMS/mcl_crimson/README.md @@ -1,4 +1,4 @@ -# Mineclone Crimson originally by debiankaios. Modified by MCL2 dev team +# VoxeLibre Crimson originally by debiankaios. Modified by VoxeLibre dev team Textures are from PixelPerfection other than: @@ -7,4 +7,4 @@ Exhale (License - CC-BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/): mcl_crimson_warped_hyphae_wood.png mcl_crimson_warped_hyphae_wood_2nd.png mcl_crimson_crimson_hyphae_wood.png -mcl_crimson_crimson_fungus.png \ No newline at end of file +mcl_crimson_crimson_fungus.png diff --git a/mods/ITEMS/mcl_crimson/alias.lua b/mods/ITEMS/mcl_crimson/alias.lua new file mode 100644 index 000000000..cbc76ef2e --- /dev/null +++ b/mods/ITEMS/mcl_crimson/alias.lua @@ -0,0 +1,4 @@ +minetest.register_alias("mcl_flowerpots:flower_pot_crimson fungus", "mcl_flowerpots:flower_pot_crimson_fungus") +minetest.register_alias("mcl_flowerpots:flower_pot_crimson roots", "mcl_flowerpots:flower_pot_crimson_roots") +minetest.register_alias("mcl_flowerpots:flower_pot_warped fungus", "mcl_flowerpots:flower_pot_warped_fungus") +minetest.register_alias("mcl_flowerpots:flower_pot_warped roots", "mcl_flowerpots:flower_pot_warped_roots") diff --git a/mods/ITEMS/mcl_crimson/init.lua b/mods/ITEMS/mcl_crimson/init.lua index 3ec6d60e4..3a7862019 100644 --- a/mods/ITEMS/mcl_crimson/init.lua +++ b/mods/ITEMS/mcl_crimson/init.lua @@ -5,8 +5,8 @@ local modpath = minetest.get_modpath(modname) -- by debiankaios -- adapted for mcl2 by cora -local wood_slab_groups = {handy = 1, axey = 1, flammable = 3, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, wood_slab = 1} -local wood_stair_groups = {handy = 1, axey = 1, flammable = 3, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, wood_stairs = 1} +local wood_slab_groups = {handy = 1, axey = 1, material_wood = 1, wood_slab = 1} +local wood_stair_groups = {handy = 1, axey = 1, material_wood = 1, wood_stairs = 1} local function generate_warped_tree(pos) minetest.place_schematic(pos,modpath.."/schematics/warped_fungus_1.mts","random",nil,false,"place_center_x,place_center_z") @@ -99,7 +99,7 @@ minetest.register_node("mcl_crimson:warped_fungus", { }) mcl_flowerpots.register_potted_flower("mcl_crimson:warped_fungus", { - name = "warped fungus", + name = "warped_fungus", desc = S("Warped Fungus"), image = "mcl_crimson_warped_fungus.png", }) @@ -148,6 +148,22 @@ minetest.register_node("mcl_crimson:twisting_vines", { end return itemstack end, + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local above = pointed_thing.above + local unode = minetest.get_node(under) + if under.y < above.y then + minetest.set_node(above, {name = "mcl_crimson:twisting_vines"}) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + else + if unode.name == "mcl_crimson:twisting_vines" then + return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing) + end + end + return itemstack + end, on_dig = function(pos, node, digger) local above = vector.offset(pos,0,1,0) local abovenode = minetest.get_node(above) @@ -223,7 +239,22 @@ minetest.register_node("mcl_crimson:weeping_vines", { end return itemstack end, - + on_place = function(itemstack, placer, pointed_thing) + local under = pointed_thing.under + local above = pointed_thing.above + local unode = minetest.get_node(under) + if under.y > above.y then + minetest.set_node(above, {name = "mcl_crimson:weeping_vines"}) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + else + if unode.name == "mcl_crimson:weeping_vines" then + return minetest.registered_nodes[unode.name].on_rightclick(under, unode, placer, itemstack, pointed_thing) + end + end + return itemstack + end, on_dig = function(pos, node, digger) local below = vector.offset(pos,0,-1,0) local belownode = minetest.get_node(below) @@ -297,7 +328,7 @@ minetest.register_node("mcl_crimson:warped_roots", { }) mcl_flowerpots.register_potted_flower("mcl_crimson:warped_roots", { - name = "warped roots", + name = "warped_roots", desc = S("Warped Roots"), image = "mcl_crimson_warped_roots.png", }) @@ -432,7 +463,7 @@ minetest.register_craft({ minetest.register_node("mcl_crimson:warped_hyphae_wood", { description = S("Warped Hyphae Wood"), tiles = {"mcl_crimson_warped_hyphae_wood.png"}, - groups = {handy = 5,axey = 1, flammable = 3, wood=1,building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20}, + groups = {handy = 5,axey = 1, wood=1,building_block = 1, material_wood = 1}, sounds = mcl_sounds.node_sound_wood_defaults(), _mcl_hardness = 2, }) @@ -447,6 +478,27 @@ minetest.register_craft({ }, }) +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_wood 4", + recipe = { + {"mcl_crimson:warped_hyphae_bark"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_wood 4", + recipe = { + {"mcl_crimson:stripped_warped_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_wood 4", + recipe = { + {"mcl_crimson:stripped_warped_hyphae_bark"}, + }, +}) + minetest.register_craft({ output = "mcl_crimson:warped_nylium 2", recipe = { @@ -490,7 +542,7 @@ minetest.register_node("mcl_crimson:crimson_fungus", { }) mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_fungus", { - name = "crimson fungus", + name = "crimson_fungus", desc = S("Crimson Fungus"), image = "mcl_crimson_crimson_fungus.png", }) @@ -516,7 +568,7 @@ minetest.register_node("mcl_crimson:crimson_roots", { }) mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_roots", { - name = "crimson roots", + name = "crimson_roots", desc = S("Crimson Roots"), image = "mcl_crimson_crimson_roots.png", }) @@ -639,6 +691,27 @@ minetest.register_craft({ }, }) +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_wood 4", + recipe = { + {"mcl_crimson:crimson_hyphae_bark"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_wood 4", + recipe = { + {"mcl_crimson:stripped_crimson_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_wood 4", + recipe = { + {"mcl_crimson:stripped_crimson_hyphae_bark"}, + }, +}) + minetest.register_craft({ output = "mcl_crimson:crimson_nylium 2", recipe = { @@ -663,12 +736,28 @@ mcl_dye.register_on_bone_meal_apply(function(pt,user) end end) +minetest.register_abm({ + label = "Turn Crimson Nylium and Warped Nylium below solid block into Netherrack", + nodenames = {"mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"}, + neighbors = {"group:solid"}, + interval = 8, + chance = 50, + action = function(pos, node) + local above = {x = pos.x, y = pos.y + 1, z = pos.z} + local name = minetest.get_node(above).name + local nodedef = minetest.registered_nodes[name] + if name ~= "ignore" and nodedef and (nodedef.groups and nodedef.groups.solid) then + minetest.set_node(pos, {name = "mcl_nether:netherrack"}) + end + end +}) + mcl_doors:register_door("mcl_crimson:crimson_door", { description = S("Crimson Door"), _doc_items_longdesc = S("Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal."), _doc_items_usagehelp = S("To open or close a wooden door, rightclick it or supply its lower half with a redstone signal."), inventory_image = "mcl_crimson_crimson_door.png", - groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + groups = {handy=1,axey=1, material_wood=1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, tiles_bottom = "mcl_crimson_crimson_door_bottom.png", @@ -683,7 +772,7 @@ mcl_doors:register_trapdoor("mcl_crimson:crimson_trapdoor", { tile_front = "mcl_crimson_crimson_trapdoor.png", tile_side = "mcl_crimson_crimson_trapdoor_side.png", wield_image = "mcl_crimson_crimson_trapdoor.png", - groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -694,7 +783,7 @@ mcl_fences.register_fence_and_fence_gate( S("Crimson Fence"), S("Crimson Fence Gate"), "mcl_crimson_crimson_fence.png", - {handy=1,axey=1, flammable=2,fence_wood=1, fire_encouragement=5, fire_flammability=20}, + {handy=1,axey=1,fence_wood=1}, minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_hardness, minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_blast_resistance, {"group:fence_wood"}, @@ -706,7 +795,7 @@ mcl_doors:register_door("mcl_crimson:warped_door", { _doc_items_longdesc = S("Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal."), _doc_items_usagehelp = S("To open or close a wooden door, rightclick it or supply its lower half with a redstone signal."), inventory_image = "mcl_crimson_warped_door.png", - groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + groups = {handy=1,axey=1, material_wood=1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, tiles_bottom = "mcl_crimson_warped_door_bottom.png", @@ -721,7 +810,7 @@ mcl_doors:register_trapdoor("mcl_crimson:warped_trapdoor", { tile_front = "mcl_crimson_warped_trapdoor.png", tile_side = "mcl_crimson_warped_trapdoor_side.png", wield_image = "mcl_crimson_warped_trapdoor.png", - groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -732,7 +821,7 @@ mcl_fences.register_fence_and_fence_gate( S("Warped Fence"), S("Warped Fence Gate"), "mcl_crimson_warped_fence.png", - {handy=1,axey=1, flammable=2,fence_wood=1, fire_encouragement=5, fire_flammability=20}, + {handy=1,axey=1,fence_wood=1}, minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_hardness, minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_blast_resistance, {"group:fence_wood"}, @@ -807,3 +896,5 @@ minetest.register_craft({ {"mcl_core:stick", warped_wood, "mcl_core:stick"}, } }) + +dofile(modpath.."/alias.lua") diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ru.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ru.tr new file mode 100644 index 000000000..4f7690442 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ru.tr @@ -0,0 +1,51 @@ +# textdomain: mcl_crimson + +Warped Fungus=Искажённый грибок +Warped fungus is a mushroom found in the nether's warped forest.=Искажённый грибок можно найти в искажённых лесах Незера +Twisting Vines=Извилистые лианы +Weeping Vines=Плакучие лианы +Nether Sprouts=Адские ростки +Warped Roots=Искажённые корни +Warped Wart Block=Искажённый блок адского нароста +Shroomlight=Грибосвет +Warped Hyphae=Искажённая ножка +The stem of a warped hyphae=Ножка искажённого гриба +Warped Hyphae Bark=Искажённые гифы +This is a decorative block surrounded by the bark of an hyphae.=Декоративный блок окруженный корой гифов. +Stripped Warped Hyphae=Обтёсанная искажённая ножка +The stripped hyphae of a warped fungus=Обтёсанная искажённая ножка +Stripped Warped Hyphae Bark=Обтёсанные гифы +The stripped hyphae bark of a warped fungus=Обтёсанные гифы искажённого гриба +Warped Nylium=Искажённый нилий +Warped Checknode - only to check!=Искажённый тестовый блок +Warped Hyphae Wood=Искажённые доски +Warped Stair=Искажённые ступени +Warped Slab=Искажённая плита +Crimson Fungus=Багровый грибок +Crimson fungus is a mushroom found in the nether's crimson forest.=Багровый грибок можно найти в багровых лесах Незера +Crimson Roots=Багровые корни +Crimson Hyphae=Багровая ножка +The stem of a crimson hyphae=Ножка багрового гриба +Crimson Hyphae Bark=Багровые гифы +Stripped Crimson Hyphae=Обтёсанная багровая ножка +The stripped stem of a crimson hyphae=Обтёсанная багровая ножка +Stripped Crimson Hyphae Bark=Обтёсанные багровые гифы +The stripped wood of a crimson hyphae=Обтёсанные багровые гифы +Crimson Hyphae Wood=Багровые доски +Crimson Stair=Багровые ступени +Crimson Slab=Багровая плита +Double Crimson Slab=Двойная багровая плита +Crimson Nylium=Багровый нилий +Crimson Door=Багровая дверь +Crimson Trapdoor=Багровый люк +Crimson Fence=Багровый забор +Crimson Fence Gate=Багровая калитка +Crimson Checknode - only to check!=Багровый тестовый блок +Warped Door=Искажённая дверь +Warped Trapdoor=Искажённый люк +Warped Fence=Искажённый забор +Warped Fence Gate=Искажённая калитка +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери это преграды высотой в 2 блока, которые можно открывать и закрывать вручную и по сигналу редстоуна. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Чтобы открыть или закрыть деревянную дверь, кликните правой либо подайте к её нижней части сигнал редстоуна. +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Деревянные люки это горизонтальные преграды, которые можно открывать и закрывать вручную и по сигналу редстоуна. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Чтобы открыть или закрыть деревянный люк, кликните по нему правой кнопкой либо подайте на него сигнал редстоуна. diff --git a/mods/ITEMS/mcl_deepslate/README.md b/mods/ITEMS/mcl_deepslate/README.md index 398e70361..e0147da0c 100644 --- a/mods/ITEMS/mcl_deepslate/README.md +++ b/mods/ITEMS/mcl_deepslate/README.md @@ -1,12 +1,10 @@ -# Mineclone2 New Ores and Deepslate +# VoxeLibre New Ores and Deepslate by NO11 -This mod adds Deepslate to the Minetest game Mineclone2, which Minecraft adds in version 1.17. +This mod adds Deepslate to the Minetest game VoxeLibre, which Minecraft adds in version 1.17. Find new ores or build something from the 30 new blocks! Deepslate is generated directly above the lava layer in overworld. -Important: You need my "Mineclone2 Raw Ores" mod for this mod to work! -All other dependencies are automatically in the mineclone2 game. -Optionally use "Mineclone2 Copper" to get the deepslate copper ore as well. +All dependencies are automatically in the VoxeLibre game. You can find all craft recipes for deepslate blocks here: https://minecraft.fandom.com/wiki/Deepslate_(disambiguation) diff --git a/mods/ITEMS/mcl_deepslate/init.lua b/mods/ITEMS/mcl_deepslate/init.lua index a1182246a..0abb0c579 100644 --- a/mods/ITEMS/mcl_deepslate/init.lua +++ b/mods/ITEMS/mcl_deepslate/init.lua @@ -218,7 +218,10 @@ local function register_deepslate_variant(item, desc, longdesc) end if item ~= "chiseled" then mcl_stairs.register_stair_and_slab_simple("deepslate_"..item, "mcl_deepslate:deepslate_"..item, S(desc.." Stairs"), S(desc.." Slab"), S("Double "..desc.." Slab")) - mcl_walls.register_wall("mcl_deepslate:deepslate"..item.."wall", S(desc.." Wall"), "mcl_deepslate:deepslate_"..item) + mcl_walls.register_wall( + "mcl_deepslate:deepslate"..item.."wall", + S(desc.." Wall"), + "mcl_deepslate:deepslate_"..item) end end @@ -240,6 +243,10 @@ for i = 1, 3 do output = "mcl_deepslate:deepslate_"..deepslate_variants[i+1][1].." 4", 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 for _, p in pairs({ "bricks", "tiles" }) do @@ -272,3 +279,5 @@ minetest.register_craft({ { "mcl_stairs:slab_deepslate_cobbled" }, }, }) + +mcl_stonecutter.register_recipe("mcl_deepslate:deepslate_cobbled", "mcl_deepslate:deepslate_chiseled") diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr index 18fcc415b..2c0ffaa55 100644 --- a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr @@ -18,8 +18,8 @@ Deepslate coal ore is a variant of coal ore that can generate in deepslate and t Deepslate Coal Ore=Minerai de charbon de l'ardoise des abîmes Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=Le minerai de cuivre de l'ardoise des abîmes est une variante de minerai de cuivre qui apparaît dans l'ardoise des abîmes et les filons de tuf. Deepslate Copper Ore=Minerai de cuivre de l'ardoise des abîmes -Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Le minerai de diamand de l'ardoise des abîmes est une variante de minerai de diamand qui apparaît dans l'ardoise des abîmes et les filons de tuf. -Deepslate Diamond Ore=Minerai de diamand de l'ardoise des abîmes +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Le minerai de diamant de l'ardoise des abîmes est une variante de minerai de diamant qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Diamond Ore=Minerai de diamant de l'ardoise des abîmes Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=Le minerai d'émeraude de l'ardoise des abîmes est une variante de minerai d'émeraude qui apparaît dans l'ardoise des abîmes et les filons de tuf. Deepslate Emerald Ore=Minerai d'émeraude de l'ardoise des abîmes Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=Le minerai d'or de l'ardoise des abîmes est une variante de minerai d'or qui apparaît dans l'ardoise des abîmes et les filons de tuf. diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.tr index 4f7c6ad24..e86bb42e9 100644 --- a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.tr +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.tr @@ -50,4 +50,4 @@ Polished Deepslate Stairs=Escadas de Ardósia Polida Polished Deepslate Wall=Muro de Ardósia Polida Polished Deepslate=Ardósia Polida Tuff=Tufo -Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y=16.=Tufo é uma rocha ornamental formada a partir de cinzas vulcânicas, ocorrendo em bolhas no subsolo abaixo de Y=16. +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y@=16.=Tufo é uma rocha ornamental formada a partir de cinzas vulcânicas, ocorrendo em bolhas no subsolo abaixo de Y@=16. diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ru.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ru.tr new file mode 100644 index 000000000..070f83491 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ru.tr @@ -0,0 +1,53 @@ +# textdomain: mcl_deepslate +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=Заражённый блок это блок, после добычи которого спаунится чешуйница. Блок выглядит идентично своему нормальному варианту. +Chiseled deepslate is the chiseled version of deepslate.=Резной сланец это резной вариант глубинного сланца. +Chiseled Deepslate=Резной сланец +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=Дроблёный сланец это вариант камня, схожий на булыжник или чернокамень. +Cobbled Deepslate Slab=Плита из дроблёного сланца +Cobbled Deepslate Stairs=Ступени из дроблёного сланца +Cobbled Deepslate Wall=Стена из дроблёного сланца +Cobbled Deepslate=Дроблёный сланец +Cracked Deepslate Bricks=Потрескавшиеся сланцевые кирпичи +Cracked Deepslate Tiles=Потрескавшаяся сланцевая плитка +Deepslate bricks are the brick version of deepslate.=Сланцевые кирпичи это кирпичный вариант глубинного сланца. +Deepslate Bricks Slab=Плита из сланцевых кирпичей +Deepslate Bricks Stairs=Ступени из сланцевых кирпичей +Deepslate Bricks Wall=Стена из сланцевых кирпичей +Deepslate Bricks=Сланцевые кирпичи +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=Глубинная угольная руда это вариант угольной руды, генерирующийся в глубинном сланце. +Deepslate Coal Ore=Глубинная угольная руда +Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=Глубинная медная руда это вариант медной руды, генерирующийся в глубинном сланце. +Deepslate Copper Ore=Глубинная медная руда +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Глубинная алмазная руда это вариант алмазной руды, генерирующийся в глубинном сланце. +Deepslate Diamond Ore=Глубинная алмазная руда +Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=Глубинная изумрудная руда это вариант изумрудной руды, генерирующийся в глубинном сланце. +Deepslate Emerald Ore=Глубинная изумрудная руда +Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=Глубинная золотая руда это вариант золотой руды, генерирующийся в глубинном сланце. +Deepslate Gold Ore=Глубинная золотая руда +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=Глубинная железная руда это вариант железной руды, генерирующийся в глубинном сланце. +Deepslate Iron Ore=Глубинная железная руда +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=Глубинный сланец это камень, который можно найти в глубине Верхнего мира. Схож с обычным камнем, но сланец твёрже. +Deepslate Lapis Lazuli Ore=Глубинная лазуритовая руда +Deepslate lapis lazuli ore is a variant of lapis lazuli ore that can generate in deepslate and tuff blobs.=Глубинная лазуритовая руда это вариант лазуритовой руды, генерирующийся в глубинном сланце. +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=Глубинная редстоуновая руда это вариант редстоуновой руды, генерирующийся в глубинном сланце. +Deepslate Redstone Ore=Глубинная редстоуновая руда +Deepslate tiles are a decorative variant of deepslate.=Сланцевая плитка это декоративный вариант глубинного сланца. +Deepslate Tiles Slab=Плита из сланцевой плитки +Deepslate Tiles Stairs=Ступени из сланцевой плитки +Deepslate Tiles Wall=Стена из сланцевой плитки +Deepslate Tiles=Сланцевая плитка +Deepslate=Глубинный сланец +Double Cobbled Deepslate Slab=Двойная плита из дроблёного сланца +Double Deepslate Bricks Slab=Двойная плита из сланцевых кирпичей +Double Deepslate Tiles Slab=Двойная плита из сланцевой плитки +Double Polished Deepslate Slab=Двойная плита из полированного сланца +Hides a silverfish=Прячет в себе чешуйницу +Infested Deepslate=Заражённый глубинный сланец +Lit Deepslate Redstone Ore=Светящаяся глубинная редстоуновая руда +Polished deepslate is the stone-like polished version of deepslate.=Полированный сланец это гладкая версия глубинного сланца. +Polished Deepslate Slab=Плита из полированного сланца +Polished Deepslate Stairs=Ступени из полированного сланца +Polished Deepslate Wall=Стена из полированного сланца +Polished Deepslate=Полированный сланец +Tuff=Туф +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y@=16.=Туф орнаментальный камень сформированный из вулканического пепла, появляется в виде подземных скоплений ниже Y@=16. diff --git a/mods/ITEMS/mcl_deepslate/mod.conf b/mods/ITEMS/mcl_deepslate/mod.conf index 7e9a44cfc..e542c3fb0 100644 --- a/mods/ITEMS/mcl_deepslate/mod.conf +++ b/mods/ITEMS/mcl_deepslate/mod.conf @@ -1,4 +1,4 @@ name = mcl_deepslate 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 diff --git a/mods/ITEMS/mcl_doors/README.txt b/mods/ITEMS/mcl_doors/README.txt index c0cfc0525..94558822e 100644 --- a/mods/ITEMS/mcl_doors/README.txt +++ b/mods/ITEMS/mcl_doors/README.txt @@ -23,7 +23,7 @@ Steel door sounds open & close (CC-BY-3.0) by HazMatt License/authors of texture files -------------------------------------- -Same as media license for MineClone 2 (see root directory). +Same as media license for VoxeLibre (see root directory). With modifications by GitHub user kingoscargames: - `doors_item_steel.png` diff --git a/mods/ITEMS/mcl_doors/api_trapdoors.lua b/mods/ITEMS/mcl_doors/api_trapdoors.lua index 5b7a0e5d0..8bbefdda3 100644 --- a/mods/ITEMS/mcl_doors/api_trapdoors.lua +++ b/mods/ITEMS/mcl_doors/api_trapdoors.lua @@ -67,12 +67,23 @@ function mcl_doors:register_trapdoor(name, def) local tmp_node -- Close if minetest.get_item_group(me.name, "trapdoor") == 2 then - minetest.sound_play(def.sound_close, {pos = pos, gain = 0.3, max_hear_distance = 16}, true) - tmp_node = {name=name, param1=me.param1, param2=me.param2} - -- Open + minetest.sound_play(def.sound_close, { pos = pos, gain = 0.3, max_hear_distance = 16 }, true) + tmp_node = { name = name, param1 = me.param1, param2 = me.param2 } + -- Open else - minetest.sound_play(def.sound_open, {pos = pos, gain = 0.3, max_hear_distance = 16}, true) - tmp_node = {name=name.."_open", param1=me.param1, param2=me.param2} + minetest.sound_play(def.sound_open, { pos = pos, gain = 0.3, max_hear_distance = 16 }, true) + + local bottom_node = minetest.get_node_or_nil(vector.offset(pos, 0, -1, 0)) + local name_end = "_open" + + -- Checking if there is something underneath the trapdoor + if bottom_node then + local is_ladder = minetest.get_item_group(bottom_node.name, "ladder") + if is_ladder > 0 then + name_end = "_ladder" + end + end + tmp_node = { name = name .. name_end, param1 = me.param1, param2 = me.param2 } end minetest.set_node(pos, tmp_node) end @@ -89,20 +100,22 @@ function mcl_doors:register_trapdoor(name, def) longdesc = def._doc_items_longdesc if not longdesc then if def.only_redstone_can_open then - longdesc = S("Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can only be opened or closed by redstone power.") + longdesc = S( + "Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can only be opened or closed by redstone power.") else - longdesc = S("Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can be opened or closed by hand or redstone power.") + longdesc = S( + "Trapdoors are horizontal barriers which can be opened or closed and climbed like a ladder when open. They occupy the upper or lower part of a block, depending on how they have been placed. This trapdoor can be opened or closed by hand or redstone power.") end end usagehelp = def._doc_items_usagehelp if not usagehelp and not def.only_redstone_can_open then usagehelp = S("To open or close this trapdoor, rightclick it or send a redstone signal to it.") end - if def.only_redstone_can_open then - tt_help = S("Openable by redstone power") - else - tt_help = S("Openable by players and redstone power") - end + if def.only_redstone_can_open then + tt_help = S("Openable by redstone power") + else + tt_help = S("Openable by players and redstone power") + end -- Closed trapdoor @@ -128,7 +141,7 @@ function mcl_doors:register_trapdoor(name, def) _doc_items_usagehelp = usagehelp, drawtype = "nodebox", tiles = tiles_closed, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + use_texture_alpha = "clip", inventory_image = def.inventory_image, wield_image = def.wield_image, is_ground_content = false, @@ -143,13 +156,15 @@ function mcl_doors:register_trapdoor(name, def) node_box = { type = "fixed", fixed = { - {-8/16, -8/16, -8/16, 8/16, -5/16, 8/16},}, + { -8 / 16, -8 / 16, -8 / 16, 8 / 16, -5 / 16, 8 / 16 }, }, + }, + mesecons = { + effector = { + action_on = (function(pos, node) + punch(pos) + end), + } }, - mesecons = {effector = { - action_on = (function(pos, node) - punch(pos) - end), - }}, on_place = function(itemstack, placer, pointed_thing) local p0 = pointed_thing.under local p1 = pointed_thing.above @@ -164,7 +179,7 @@ function mcl_doors:register_trapdoor(name, def) --local origname = itemstack:get_name() if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5) - or (fpos < -0.5 and fpos > -0.999999999) then + or (fpos < -0.5 and fpos > -0.999999999) then param2 = param2 + 20 if param2 == 21 then param2 = 23 @@ -193,16 +208,44 @@ function mcl_doors:register_trapdoor(name, def) groups_open.trapdoor = 2 groups_open.not_in_creative_inventory = 1 - minetest.register_node(name.."_open", { + -- Non-climbable opened + minetest.register_node(name .. "_open", { drawtype = "nodebox", tiles = tiles_open, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + use_texture_alpha = "clip", + is_ground_content = false, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + pointable = true, + groups = groups_open, + _mcl_hardness = def._mcl_hardness, + _mcl_blast_resistance = def._mcl_blast_resistance, + sounds = def.sounds, + drop = name, + node_box = { + type = "fixed", + fixed = { -0.5, -0.5, 5 / 16, 0.5, 0.5, 0.5 } + }, + on_rightclick = on_rightclick, + mesecons = { + effector = { + action_off = (function(pos, node) + punch(pos) + end), + } + }, + on_rotate = on_rotate, + }) + + -- Climbable opened + minetest.register_node(name .. "_ladder", { + drawtype = "nodebox", + tiles = tiles_open, + use_texture_alpha = "clip", is_ground_content = false, paramtype = "light", paramtype2 = "facedir", - -- TODO: Implement Minecraft behaviour: Climbable if directly above - -- ladder w/ matching orientation. - -- Current behavour: Always climbable climbable = true, sunlight_propagates = true, pointable = true, @@ -213,19 +256,20 @@ function mcl_doors:register_trapdoor(name, def) drop = name, node_box = { type = "fixed", - fixed = {-0.5, -0.5, 5/16, 0.5, 0.5, 0.5} + fixed = { -0.5, -0.5, 5 / 16, 0.5, 0.5, 0.5 } }, on_rightclick = on_rightclick, - mesecons = {effector = { - action_off = (function(pos, node) - punch(pos) - end), - }}, + mesecons = { + effector = { + action_off = (function(pos, node) + punch(pos) + end), + } + }, on_rotate = on_rotate, }) if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", name, "nodes", name.."_open") + doc.add_entry_alias("nodes", name, "nodes", name .. "_open") end - end diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr index c7d3ddaa1..01de53274 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr @@ -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. Openable by players and redstone power=Ouvrable par les joueurs et 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. diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr index 321c99e33..fe6245f56 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr @@ -20,5 +20,5 @@ Wooden trapdoors are horizontal barriers whch can be opened and closed by hand o To open or close the trapdoor, rightclick it or send a redstone signal to it.=Para abrir ou fechar um alçapão, aperte com o botão direito nela ou acione-o com um sinal de redstone. Iron Trapdoor=Alçapão de Ferro 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.=Alçapões de ferro são barreiras horizontais que podem ser abertas ou fechadas por sinais de redstone, mas não manualmente. Eles ocupam a parte inferior ou superior de um bloco, dependendo de como foram colocados. Quando abertos, podem ser escaladas como escadas. -Openable by players and redstone power=Aberto por jogadores ou sinal de redstone +Openable by players and redstone power=Aberto por jogadores e sinal de redstone Openable by redstone power=Aberto por sinal de redstone diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.ru.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.ru.tr index 1515a2cd2..525bd075f 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.ru.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.ru.tr @@ -1,24 +1,26 @@ # textdomain: mcl_doors -Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери это сдвоенные блочные преграды, которые можно открывать и закрывать вручную и по сигналу редстоуна. +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери это преграды высотой в 2 блока, которые можно открывать и закрывать вручную и по сигналу редстоуна. To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Чтобы открыть или закрыть деревянную дверь, кликните правой либо подайте к её нижней части сигнал редстоуна. Oak Door=Дубовая дверь -Acacia Door=Дверь из акации +Acacia Door=Акациевая дверь Birch Door=Берёзовая дверь Dark Oak Door=Дверь из тёмного дуба -Jungle Door=Дверь из дерева джунглей +Jungle Door=Дверь из тропического дерева Spruce Door=Еловая дверь Iron Door=Железная дверь -Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=Железные двери это сдвоенные блочные преграды, которые можно открывать и закрывать только по сигналу редстоуна и нельзя вручную. +Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=Железные двери это преграды высотой в 2 блока, которые можно открывать и закрывать только по сигналу редстоуна, но не вручную. To open or close an iron door, supply its lower half with a redstone signal.=Чтобы открыть или закрыть железную дверь, подайте на её нижнюю часть сигнал редстоуна. Oak Trapdoor=Дубовый люк -Acacia Trapdoor=Люк из акации +Acacia Trapdoor=Акациевый люк Birch Trapdoor=Берёзовый люк Spruce Trapdoor=Еловый люк Dark Oak Trapdoor=Люк из тёмного дуба -Jungle Trapdoor=Люк из дерева джунглей +Jungle Trapdoor=Люк из тропического дерева Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Деревянные люки это горизонтальные преграды, которые можно открывать и закрывать вручную и по сигналу редстоуна. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. To open or close the trapdoor, rightclick it or send a redstone signal to it.=Чтобы открыть или закрыть деревянные люк, кликните по нему правой клавишей либо подайте на него сигнал редстоуна. Iron Trapdoor=Железный люк -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.=Железные люки это горизонтальные преграды, которые можно открывать и закрывать только по сигналу редстоуна и нельзя вручную. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. -Openable by players and redstone power=Открывается игроками и действием редстоуна -Openable by redstone power=Открывается действием редстоуна +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.=Железные люки это горизонтальные преграды, которые можно открывать и закрывать только по сигналу редстоуна, но не вручную. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. +Openable by players and redstone power=Открывается игроками и сигналом редстоуна +Openable by redstone power=Открывается сигналом редстоуна +This door is a 2-block high barrier which can only be opened by redstone power, not by hand.=Эта дверь - преграда высотой в 2 блока, которую можно открывать и закрывать по сигналу редстоуна, но не вручную. +This door is a 2-block high barrier which can be opened or closed by hand or by redstone power.=Эта дверь - преграда высотой в 2 блока, которую можно открывать и закрывать вручную и по сигналу редстоуна. diff --git a/mods/ITEMS/mcl_doors/locale/template.txt b/mods/ITEMS/mcl_doors/locale/template.txt index d8c7c8609..2d21c72ac 100644 --- a/mods/ITEMS/mcl_doors/locale/template.txt +++ b/mods/ITEMS/mcl_doors/locale/template.txt @@ -22,3 +22,5 @@ Iron Trapdoor= 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.= Openable by players and redstone power= Openable by redstone power= +This door is a 2-block high barrier which can only be opened by redstone power, not by hand.= +This door is a 2-block high barrier which can be opened or closed by hand or by redstone power.= diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index abd6ed1d9..c14f7eaeb 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -182,6 +182,10 @@ local function apply_bone_meal(pointed_thing, user) local n = minetest.get_node(pos) if n.name == "" then return false end + if mcl_util.check_area_protection(pos, pointed_thing.above, user) then + return false + end + for _, func in pairs(mcl_dye.bone_meal_callbacks) do if func(pointed_thing, user) then return true diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr index 921983ec0..85e5b9605 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr @@ -1,5 +1,5 @@ # textdomain: mcl_dye -White Dye=Biały farba +White Dye=Biała farba Light Grey Dye=Jasnoszara farba Grey Dye=Szara farba Black Dye=Czarny farba diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr index 2b6aef9f0..14ff0b091 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr @@ -1,26 +1,26 @@ # textdomain: mcl_dye Bone Meal=Farinha de Osso -Light Grey Dye=Tintura Cinza Claro -Grey Dye=Tintura Cinza +Light Grey Dye=Corante Cinza Claro +Grey Dye=Corante Cinza Ink Sac=Saco de Tinta -Purple Dye=Tintura Roxa +Purple Dye=Corante Roxo Lapis Lazuli=Lápis-lazuli -Light Blue Dye=Tintura Azul Claro -Cyan Dye=Tintura Ciano -Green Dye=Tintura Verde -Lime Dye=Tintura Lima -Yellow Dye=Tintura Amarela +Light Blue Dye=Corante Azul Claro +Cyan Dye=Corante Ciano +Green Dye=Corante Verde +Lime Dye=Corante Lima +Yellow Dye=Corante Amarelo Cocoa Beans=Sementes de Cacau -Orange Dye=Tintura Laranja -Red Dye=Tintura Vermelha -Magenta Dye=Tintura Magenta -Pink Dye=Tintura Rosa -This item is a dye which is used for dyeing and crafting.=Este item é uma tintura e pode ser usado para tingir ou fabricar. +Orange Dye=Corante Laranja +Red Dye=Corante Vermelho +Magenta Dye=Corante Magenta +Pink Dye=Corante Rosa +This item is a dye which is used for dyeing and crafting.=Este item é uma corante e pode ser usado para tingir ou fabricar. Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Clique com o botão direito em uma ovelha para tingir sua lã. Outras coisas são tingidas ao fabricá-las. Bone Meal=Farinha de Osso -Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Farinha de osso é uma tintura branca e também é útil como fertilizante ao acelerar o crescimento de diversas plantas. +Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Farinha de osso é um corante branco e também é útil como fertilizante ao acelerar o crescimento de diversas plantas. Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Clique com o botão direito em uma ovelha para tornar sua lã branca. Clique com o botão direito em uma planta para acelerar seu crescimento. Note que nem todas as plantas podem ser fertilizadas assim. Quando você clica com o botão direito em um bloco de grama, grama alta e flores crescerão ao redor. -Cocoa beans are a brown dye and can be used to plant cocoas.=Sementes de cacau são um pigmento marrom e podem ser usadas para plantar cacau. +Cocoa beans are a brown dye and can be used to plant cocoas.=Sementes de cacau são um corante marrom e podem ser usadas para plantar cacau. Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clique com o botão direito em uma ovelha para tornar sua lã marrom. Clique com o botão direito na lateral de um tronco de árvore da selva para plantar um cacau jovem. Cocoa Beans=Sementes de Cacau Grows at the side of jungle trees=Cresce na lateral de árvores da selva diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr index fc45a4bb4..d595bb6a1 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr @@ -3,25 +3,25 @@ White Dye=Белый краситель Light Grey Dye=Светло-серый краситель Grey Dye=Серый краситель Black Dye=Чёрный краситель -Purple Dye=Пурпурный краситель -Blue Dye=голубой краситель -Light Blue Dye=Светло-голубой краситель -Cyan Dye=Голубой краситель +Purple Dye=Фиолетовый краситель +Blue Dye=Синий краситель +Light Blue Dye=Голубой краситель +Cyan Dye=Бирюзовый краситель Green Dye=Зеленый краситель -Lime Dye=Зелёный лаймовый краситель +Lime Dye=Лаймовый краситель Yellow Dye=Желтый краситель Brown Dye=Коричневый краситель Orange Dye=Оранжевый краситель Red Dye=Красный краситель -Magenta Dye=Фиолетовый краситель +Magenta Dye=Сиреневый краситель Pink Dye=Розовый краситель -This item is a dye which is used for dyeing and crafting.=Это краситель, которые используется, чтобы окрашивать и крафтить. -Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Кликните правой по овце, чтобы окрасить её шерсть. Остальные вещи окрашиваются путём крафтинга. +This item is a dye which is used for dyeing and crafting.=Это краситель, который используется для окрашивания и крафта. +Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Кликните правой по овце, чтобы окрасить её шерсть. Остальные вещи окрашиваются путём крафта. Bone Meal=Костная мука Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Костная мука является белым красителем. Она также полезна в качестве удобрения, чтобы увеличить скорость роста многих растений. Rightclick a sheep to turn its wool white. Rightclick a plant to speed up its growth. Note that not all plants can be fertilized like this. When you rightclick a grass block, tall grass and flowers will grow all over the place.=Кликните правой по овце, чтобы сделать её шерсть белой. Кликните правой по растению, чтобы ускорить его рост. Имейте в виду, что не все растения можно удобрять таким способом. Если вы кликнете по травяному блоку, то на этом месте вырастет высокая трава и цветы. Cocoa beans are a brown dye and can be used to plant cocoas.=Какао-бобы являются коричневым красителем. Их также можно использовать, чтобы посадить какао. -Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола дерева джунглей, чтобы посадить молодое какао. +Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Кликните правой по овце, чтобы сделать её шерсть коричневой. Кликните правой по боковой части ствола тропического дерева, чтобы посадить молодое какао. Cocoa Beans=Какао-бобы -Grows at the side of jungle trees=Растут на стволах деревьев джунглей +Grows at the side of jungle trees=Растут на стволах тропических деревьев Speeds up plant growth=Ускоряет рост растений diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index f137b4230..44b3a5bd6 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -133,7 +133,11 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, if wielditem then local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect") if fire_aspect_level > 0 then - mcl_burning.set_on_fire(player, fire_aspect_level * 4) + local player_pos = player:get_pos() + local hitter_pos = hitter:get_pos() + if vector.distance(hitter_pos, player_pos) <= 3 then + mcl_burning.set_on_fire(player, fire_aspect_level * 4) + end end end end @@ -201,7 +205,8 @@ walkover.register_global(function(pos, _, player) if frost_walker <= 0 then return end - local radius = frost_walker + 2 + -- 1011 = sqrt(4096000)/2; 4096000 is the max number of nodes for find_nodes_in_area_under_air + local radius = math.min(frost_walker + 2, 1011) local minp = {x = pos.x - radius, y = pos.y, z = pos.z - radius} local maxp = {x = pos.x + radius, y = pos.y, z = pos.z + radius} local positions = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:water_source") @@ -276,11 +281,73 @@ function minetest.calculate_knockback(player, hitter, time_from_last_punch, tool if hitter then luaentity = hitter:get_luaentity() end - if hitter and hitter:is_player() then + if hitter and hitter:is_player() and distance <= 3 then local wielditem = hitter:get_wielded_item() - knockback = knockback + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") + --knockback = knockback + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback") + local enchant = mcl_enchanting.get_enchantment(wielditem, "knockback") + knockback = knockback + 3.22 * enchant + -- add vertical lift to knockback + local v = player:get_velocity() + local added_v = 0 + local invul = player:get_meta():get_int("mcl_damage:invulnerable") + if v and v.y <= 0.01 and v.y >= -0.01 and invul == 0 then + local regular_v = 6.4 + local enchant_v = 7 + regular_v = regular_v * math.abs(dir.y - 1) + enchant_v = enchant_v * math.abs(dir.y - 1) + if enchant == 0 then + player:add_velocity({x = 0, y = regular_v, z = 0}) + added_v = regular_v + else + player:add_velocity({x = 0, y = enchant_v, z = 0}) + added_v = enchant_v + end + -- add minimum knockback + if knockback <= 1.5 then + knockback = knockback + 4.875 + elseif knockback <= 6.19 then + knockback = knockback + 0.609375 + end + end + -- counteract forward velocity when hit + local self_dir_dot = (v.x * dir.x) + (v.z * dir.z) + if self_dir_dot < 0 then + player:add_velocity({x = v.x * -1, y = 0, z = v.z * -1}) + end + -- add player velocity to knockback + local h_name = hitter:get_player_name() + local hv = hitter:get_velocity() + local dir_dot = (hv.x * dir.x) + (hv.z * dir.z) + local hitter_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z)) + if dir_dot > 0 and mcl_sprint.is_sprinting(h_name) then + knockback = knockback + hitter_mag * 0.6875 + elseif dir_dot > 0 then + knockback = knockback + hitter_mag * 0.515625 + end + -- reduce floatiness + minetest.after(0.25, function() + player:add_velocity({x = 0, y = (v.y + added_v) * -0.375, z = 0}) + end) + -- reduce knockback when moving towards hitter while attacking + local self_dir_dot = (v.x * dir.x) + (v.z * dir.z) + local control = player:get_player_control() + if self_dir_dot < -4.3 and control.up and control.LMB then + knockback = knockback * 0.6 + end + -- remove knockback if invulnerable + if invul > 0 then + knockback = 0 + end + elseif hitter and hitter:is_player() and distance > 3 then + knockback = 0 elseif luaentity and luaentity._knockback then - knockback = knockback + luaentity._knockback + local kb = knockback + luaentity._knockback / 4 + local punch_dir = dir + punch_dir.y = 0 + punch_dir = vector.normalize(punch_dir) * kb + punch_dir.y = 4 + player:add_velocity(punch_dir) + knockback = 0 end return knockback end @@ -419,6 +486,7 @@ mcl_experience.register_on_add_xp(function(player, xp) end stack:set_wear(math.floor(new_wear)) + tt.reload_itemstack_description(stack) -- update tooltip inv:set_stack(list, index, stack) end diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index fa6dea353..dd01d5950 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -2,7 +2,8 @@ local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape function mcl_enchanting.is_book(itemname) - return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or itemname == "mcl_books:book_enchanted" + return itemname == "mcl_books:book" or itemname == "mcl_enchanting:book_enchanted" or + itemname == "mcl_books:book_enchanted" end function mcl_enchanting.get_enchantments(itemstack) @@ -54,11 +55,13 @@ end function mcl_enchanting.get_enchantment_description(enchantment, level) local enchantment_def = mcl_enchanting.enchantments[enchantment] - return enchantment_def.name .. (enchantment_def.max_level == 1 and "" or " " .. mcl_enchanting.roman_numerals.toRoman(level)) + return enchantment_def.name .. + (enchantment_def.max_level == 1 and "" or " " .. mcl_util.to_roman(level)) end function mcl_enchanting.get_colorized_enchantment_description(enchantment, level) - return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, mcl_enchanting.get_enchantment_description(enchantment, level)) + return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and mcl_colors.RED or mcl_colors.GRAY, + mcl_enchanting.get_enchantment_description(enchantment, level)) end function mcl_enchanting.get_enchanted_itemstring(itemname) @@ -79,7 +82,8 @@ function mcl_enchanting.not_enchantable_on_enchanting_table(itemname) end function mcl_enchanting.is_enchantable(itemname) - return mcl_enchanting.get_enchantability(itemname) > 0 or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) + return mcl_enchanting.get_enchantability(itemname) > 0 or + mcl_enchanting.not_enchantable_on_enchanting_table(itemname) end function mcl_enchanting.can_enchant_freshly(itemname) @@ -150,7 +154,8 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) for incompatible in pairs(enchantment_def.incompatible) do local incompatible_level = item_enchantments[incompatible] if incompatible_level then - return false, "incompatible", mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) + return false, "incompatible", + mcl_enchanting.get_enchantment_description(incompatible, incompatible_level) end end end @@ -169,20 +174,24 @@ function mcl_enchanting.combine(itemstack, combine_with) local itemname = itemstack:get_name() local combine_name = combine_with:get_name() local enchanted_itemname = mcl_enchanting.get_enchanted_itemstring(itemname) - if not enchanted_itemname or enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and not mcl_enchanting.is_book(combine_name) then + if not enchanted_itemname or + enchanted_itemname ~= mcl_enchanting.get_enchanted_itemstring(combine_name) and + not mcl_enchanting.is_book(combine_name) then return false end local enchantments = mcl_enchanting.get_enchantments(itemstack) + local any_new_enchantment = false for enchantment, combine_level in pairs(mcl_enchanting.get_enchantments(combine_with)) do local enchantment_def = mcl_enchanting.enchantments[enchantment] local enchantment_level = enchantments[enchantment] - if enchantment_level then + if enchantment_level then -- The enchantment already exist in the provided item if enchantment_level == combine_level then enchantment_level = math.min(enchantment_level + 1, enchantment_def.max_level) else enchantment_level = math.max(enchantment_level, combine_level) end - elseif mcl_enchanting.item_supports_enchantment(itemname, enchantment) then + any_new_enchantment = any_new_enchantment or ( enchantment_level ~= enchantments[enchantment] ) + elseif mcl_enchanting.item_supports_enchantment(itemname, enchantment) then -- this is a new enchantement to try to add local supported = true for incompatible in pairs(enchantment_def.incompatible) do if enchantments[incompatible] then @@ -192,24 +201,18 @@ function mcl_enchanting.combine(itemstack, combine_with) end if supported then enchantment_level = combine_level + any_new_enchantment = true end end if enchantment_level and enchantment_level > 0 then enchantments[enchantment] = enchantment_level end end - local any_enchantment = false - for enchantment, enchantment_level in pairs(enchantments) do - if enchantment_level > 0 then - any_enchantment = true - break - end - end - if any_enchantment then + if any_new_enchantment then itemstack:set_name(enchanted_itemname) + mcl_enchanting.set_enchantments(itemstack, enchantments) end - mcl_enchanting.set_enchantments(itemstack, enchantments) - return true + return any_new_enchantment end function mcl_enchanting.enchantments_snippet(_, _, itemstack) @@ -219,7 +222,7 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) local enchantments = mcl_enchanting.get_enchantments(itemstack) local text = "" for enchantment, level in pairs(enchantments) do - text = text .. mcl_enchanting.get_colorized_enchantment_description(enchantment, level) .. "\n" + text = text .. mcl_enchanting.get_colorized_enchantment_description(enchantment, level) .. "\n" end if text ~= "" then if not itemstack:get_definition()._tt_original_description then @@ -267,7 +270,7 @@ function mcl_enchanting.initialize() for itemname, itemdef in pairs(minetest.registered_items) do if mcl_enchanting.can_enchant_freshly(itemname) and not mcl_enchanting.is_book(itemname) then local new_name = itemname .. "_enchanted" - minetest.override_item(itemname, {_mcl_enchanting_enchanted_tool = new_name}) + minetest.override_item(itemname, { _mcl_enchanting_enchanted_tool = new_name }) local new_def = table.copy(itemdef) new_def.inventory_image = itemdef.inventory_image .. mcl_enchanting.overlay if new_def.wield_image then @@ -303,7 +306,7 @@ end function mcl_enchanting.random(pr, ...) local r = pr and pr:next(...) or math.random(...) - if pr and not ({...})[1] then + if pr and not ({ ... })[1] then r = r / 32767 end @@ -328,20 +331,24 @@ function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, ex return #possible > 0 and possible[mcl_enchanting.random(pr, 1, #possible)] end -function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) +function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, + ignore_already_enchanted, pr) local itemname = itemstack:get_name() - if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then + if (not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted) or + mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then return end itemstack = ItemStack(itemstack) local enchantability = minetest.get_item_group(itemname, "enchantability") - enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + enchantability = 1 + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) + + mcl_enchanting.random(pr, 0, math.floor(enchantability / 4)) enchantment_level = enchantment_level + enchantability - enchantment_level = enchantment_level + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 + enchantment_level = enchantment_level + + enchantment_level * (mcl_enchanting.random(pr) + mcl_enchanting.random(pr) - 1) * 0.15 enchantment_level = math.max(math.floor(enchantment_level + 0.5), 1) local enchantments = {} @@ -387,7 +394,6 @@ function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_leve enchantments[selected_enchantment] = enchantment_power mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) end - until not no_reduced_bonus_chance and mcl_enchanting.random(pr) >= (enchantment_level + 1) / 50 return enchantments, description @@ -397,13 +403,15 @@ function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchant local enchantments repeat - enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) + enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, + no_reduced_bonus_chance, ignore_already_enchanted, pr) until enchantments return enchantments end -function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) +function mcl_enchanting.enchant_randomly(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, + ignore_already_enchanted, pr) local enchantments = mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) mcl_enchanting.set_enchanted_itemstring(itemstack) @@ -416,7 +424,8 @@ function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr) local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr) if enchantment then - mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) + mcl_enchanting.enchant(stack, enchantment, + mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) end return stack @@ -426,7 +435,8 @@ function mcl_enchanting.get_random_glyph_row() local glyphs = "" local x = 1.3 for i = 1, 9 do - glyphs = glyphs .. "image[".. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]" + glyphs = glyphs .. + "image[" .. x .. ",0.1;0.5,0.5;mcl_enchanting_glyph_" .. math.random(18) .. ".png^[colorize:#675D49:255]" x = x + 0.6 end return glyphs @@ -459,7 +469,7 @@ end function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) local itemname = itemstack:get_name() if (not mcl_enchanting.can_enchant_freshly(itemname)) or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) then - return {false, false, false} + return { false, false, false } end local meta = player:get_meta() local player_slots = minetest.deserialize(meta:get_string("mcl_enchanting:slots")) or {} @@ -475,7 +485,7 @@ function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) meta:set_string("mcl_enchanting:slots", minetest.serialize(player_slots)) return player_bookshelves_item_slots else - return {false, false, false} + return { false, false, false } end end end @@ -491,28 +501,33 @@ function mcl_enchanting.show_enchanting_formspec(player) local inv = player:get_inventory() local num_bookshelves = meta:get_int("mcl_enchanting:num_bookshelves") local table_name = meta:get_string("mcl_enchanting:table_name") - local formspec = "" - .. "size[9.07,8.6;]" - .. "formspec_version[3]" - .. "label[0,0;" .. C("#313131") .. F(table_name) .. "]" - .. mcl_formspec.get_itemslot_bg(0.2, 2.4, 1, 1) - .. "list[current_player;enchanting_item;0.2,2.4;1,1]" - .. mcl_formspec.get_itemslot_bg(1.1, 2.4, 1, 1) - .. "image[1.1,2.4;1,1;mcl_enchanting_lapis_background.png]" - .. "list[current_player;enchanting_lapis;1.1,2.4;1,1]" - .. "label[0,4;" .. C("#313131") .. F(S("Inventory")).."]" - .. mcl_formspec.get_itemslot_bg(0, 4.5, 9, 3) - .. mcl_formspec.get_itemslot_bg(0, 7.74, 9, 1) - .. "list[current_player;main;0,4.5;9,3;9]" - .. "listring[current_player;enchanting_item]" - .. "listring[current_player;main]" - .. "listring[current_player;enchanting]" - .. "listring[current_player;main]" - .. "listring[current_player;enchanting_lapis]" - .. "listring[current_player;main]" - .. "list[current_player;main;0,7.74;9,1;]" - .. "real_coordinates[true]" - .. "image[3.15,0.6;7.6,4.1;mcl_enchanting_button_background.png]" + + local formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color) .. table_name) .. "]", + mcl_formspec.get_itemslot_bg_v4(1, 3.25, 1, 1), + "list[current_player;enchanting_item;1,3.25;1,1]", + mcl_formspec.get_itemslot_bg_v4(2.25, 3.25, 1, 1), + "image[2.25,3.25;1,1;mcl_enchanting_lapis_background.png]", + "list[current_player;enchanting_lapis;2.25,3.25;1,1]", + "image[4.125,0.56;7.25,4.1;mcl_enchanting_button_background.png]", + "label[0.375,4.7;" .. F(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;enchanting_item]", + "listring[current_player;main]", + "listring[current_player;enchanting]", + "listring[current_player;main]", + "listring[current_player;enchanting_lapis]", + "listring[current_player;main]", + }) + local itemstack = inv:get_stack("enchanting_item", 1) local player_levels = mcl_experience.get_level(player) local y = 0.65 @@ -520,24 +535,50 @@ function mcl_enchanting.show_enchanting_formspec(player) local table_slots = mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) for i, slot in ipairs(table_slots) do any_enchantment = any_enchantment or slot - local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({name = "mcl_core:lapis", count = i})) + local enough_lapis = inv:contains_item("enchanting_lapis", ItemStack({ name = "mcl_core:lapis", count = i })) local enough_levels = slot and slot.level_requirement <= player_levels local can_enchant = (slot and enough_lapis and enough_levels) local ending = (can_enchant and "" or "_off") local hover_ending = (can_enchant and "_hovered" or "_off") formspec = formspec - .. "container[3.2," .. y .. "]" - .. (slot and "tooltip[button_" .. i .. ";" .. C("#818181") .. ((slot.description and F(slot.description)) or "") .. " " .. C("#FFFFFF") .. " . . . ?\n\n" .. (enough_levels and C(enough_lapis and "#818181" or "#FC5454") .. F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") - .. "style[button_" .. i .. ";bgimg=mcl_enchanting_button" .. ending .. ".png;bgimg_hovered=mcl_enchanting_button" .. hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" - .. "button[0,0;7.5,1.3;button_" .. i .. ";]" + .. "container[4.125," .. y .. "]" + .. + ( + slot and + "tooltip[button_" .. + i .. + ";" .. + C("#818181") .. + ((slot.description and F(slot.description)) or "") .. + " " .. + C("#FFFFFF") .. + " . . . ?\n\n" .. + ( + enough_levels and + C(enough_lapis and "#818181" or "#FC5454") .. + F(S("@1 Lapis Lazuli", i)) .. "\n" .. C("#818181") .. F(S("@1 Enchantment Levels", i)) or + C("#FC5454") .. F(S("Level requirement: @1", slot.level_requirement))) .. "]" or "") + .. + "style[button_" .. + i .. + ";bgimg=mcl_enchanting_button" .. + ending .. + ".png;bgimg_hovered=mcl_enchanting_button" .. + hover_ending .. ".png;bgimg_pressed=mcl_enchanting_button" .. hover_ending .. ".png]" + .. "button[0,0;7.25,1.3;button_" .. i .. ";]" .. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "") - .. (slot and "label[7.2,1.1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") + .. (slot and "label[6.8,1;" .. C(can_enchant and "#80FF20" or "#407F10") .. slot.level_requirement .. "]" or "") .. (slot and slot.glyphs or "") .. "container_end[]" - y = y + 1.35 + y = y + 1.3 end formspec = formspec - .. "image[" .. (any_enchantment and 0.58 or 1.15) .. ",1.2;" .. (any_enchantment and 2 or 0.87) .. ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]" + .. + "image[" .. + (any_enchantment and 1.1 or 1.67) .. + ",1.2;" .. + (any_enchantment and 2 or 0.87) .. + ",1.43;mcl_enchanting_book_" .. (any_enchantment and "open" or "closed") .. ".png]" minetest.show_formspec(name, "mcl_enchanting:table", formspec) end @@ -555,7 +596,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) local meta = player:get_meta() local num_bookshelfes = meta:get_int("mcl_enchanting:num_bookshelves") local itemstack = inv:get_stack("enchanting_item", 1) - local cost = ItemStack({name = "mcl_core:lapis", count = button_pressed}) + local cost = ItemStack({ name = "mcl_core:lapis", count = button_pressed }) if not inv:contains_item("enchanting_lapis", cost) then return end @@ -573,7 +614,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchantments(itemstack, slot.enchantments) inv:set_stack("enchanting_item", 1, itemstack) - minetest.sound_play("mcl_enchanting_enchant", {to_player = name, gain = 5.0}) + minetest.sound_play("mcl_enchanting_enchant", { to_player = name, gain = 5.0 }) mcl_enchanting.reset_table_slots(player) mcl_enchanting.show_enchanting_formspec(player) awards.unlock(player:get_player_name(), "mcl:enchanter") @@ -603,7 +644,8 @@ function mcl_enchanting.is_enchanting_inventory_action(action, inventory, invent end function mcl_enchanting.allow_inventory_action(player, action, inventory, inventory_info) - local is_enchanting_action, do_limit = mcl_enchanting.is_enchanting_inventory_action(action, inventory, inventory_info) + local is_enchanting_action, do_limit = mcl_enchanting.is_enchanting_inventory_action(action, inventory, + inventory_info) if is_enchanting_action and do_limit then if action == "move" then local listname = inventory_info.to_list @@ -645,13 +687,15 @@ function mcl_enchanting.on_inventory_action(player, action, inventory, inventory end function mcl_enchanting.schedule_book_animation(self, anim) - self.scheduled_anim = {timer = self.anim_length, anim = anim} + self.scheduled_anim = { timer = self.anim_length, anim = anim } end function mcl_enchanting.set_book_animation(self, anim) local anim_index = mcl_enchanting.book_animations[anim] - local start, stop = mcl_enchanting.book_animation_steps[anim_index], mcl_enchanting.book_animation_steps[anim_index + 1] - self.object:set_animation({x = start, y = stop}, mcl_enchanting.book_animation_speed, 0, mcl_enchanting.book_animation_loop[anim] or false) + local start, stop = mcl_enchanting.book_animation_steps[anim_index], + mcl_enchanting.book_animation_steps[anim_index + 1] + self.object:set_animation({ x = start, y = stop }, mcl_enchanting.book_animation_speed, 0, + mcl_enchanting.book_animation_loop[anim] or false) self.scheduled_anim = nil self.anim_length = (stop - start) / 40 end @@ -661,7 +705,7 @@ function mcl_enchanting.check_animation_schedule(self, dtime) if schedanim then schedanim.timer = schedanim.timer - dtime if schedanim.timer <= 0 then - mcl_enchanting.set_book_animation(self, schedanim.anim) + mcl_enchanting.set_book_animation(self, schedanim.anim) end end end @@ -669,7 +713,7 @@ end function mcl_enchanting.look_at(self, pos2) local pos1 = self.object:get_pos() local vec = vector.subtract(pos1, pos2) - local yaw = math.atan(vec.z / vec.x) - math.pi/2 + local yaw = math.atan(vec.z / vec.x) - math.pi / 2 yaw = yaw + (pos1.x >= pos2.x and math.pi or 0) self.object:set_yaw(yaw + math.pi) end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index 9f9fbd271..02ed1ee85 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -11,7 +11,6 @@ mcl_enchanting = { book_animation_steps = {0, 640, 680, 700, 740}, book_animation_loop = {["open"] = true, ["close"] = true}, book_animation_speed = 40, - roman_numerals = dofile(modpath .. "/roman_numerals.lua"), -- https://exercism.io/tracks/lua/exercises/roman-numerals/solutions/73c2fb7521e347209312d115f872fa49 enchantments = {}, overlay = "^[colorize:purple:50", --overlay = "^[invert:rgb^[multiply:#4df44d:50^[invert:rgb", diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr index 80912a711..23cf257da 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr @@ -36,7 +36,7 @@ Increases mob loot.=Augmente le butin des mobs. Increases rate of good loot (enchanting books, etc.)=Augmente le taux de bon butin (livres enchanteurs, etc.) Increases sweeping attack damage.=Augmente les dégâts de l'épée Increases underwater movement speed.=Augmente la vitesse de déplacement sous l'eau. -Increases walking speed on soul sand.=Augmente la vitesse de marche sur le sable de l'âme. +Increases walking speed on soul sand.=Augmente la vitesse de marche sur le sable des âmes. Infinity=Infinité Item destroyed on death.=Objet détruit à la mort. Knockback=Recul diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.pt_BR.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.pt_BR.tr new file mode 100644 index 000000000..f17678f3f --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.pt_BR.tr @@ -0,0 +1,144 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=Flechas atravessam múltiplos objetos. +Arrows set target on fire.=Flechas colocam fogo no alvo. +Bane of Arthropods=Ruína dos Artrópodes +Channeling=Condutividade + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canaliza um relâmpago em direção ao alvo. Funciona apenas durante tempestades e se o alvo estiver desobistruido por blocos opacos. + +Curse of Vanishing=Maldição do Desaparecimento +Decreases crossbow charging time.=Diminui o tempo de recarga da besta. +Decreases time until rod catches something.=Diminui o tempo para a vara coletar alguma coisa. +Depth Strider=Passos Profundos +Efficiency=Eficiência +Extends underwater breathing time.=Extende o tempo de respiração em baixo da água. +Fire Aspect=Aspecto Flamejante +Flame=Chama +Fortune=Fortuna +Frost Walker=Passos Gelados +Impaling=Penetração +Increases arrow damage.=Aumenta o dano das flechas. +Increases arrow knockback.=Aumenta a repulsão das flechas. +Increases certain block drops.=Aumenta o drop de certos blocos. + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Aumenta o dano e aplica Lentidão IV para mobs artrópodes (aranhas, aranhas de cavernas, traças e endermites). + +Increases damage to undead mobs.=Aumenta o dano para mobs mortos-vivos. +Increases damage.=Aumenta o dano +Increases item durability.=Aumenta a durabilidade do item. +Increases knockback.=Aumenta a repulsão. +Increases mining speed.=Aumenta a velocidade de mineração. +Increases mob loot.=Aumenta o saque de mobs. +Increases rate of good loot (enchanting books, etc.)=Aumenta a taxa de bons saques (livros encantados, etc.) +Increases sweeping attack damage.= +Increases underwater movement speed.=Aumenta a velocidade de movimento embaixo da água. +Increases walking speed on soul sand.=Aumenta a velocidade de caminhada na areia das almas. +Infinity=Infinidade +Item destroyed on death.=Item é destruído na morte. +Knockback=Repulsão +Looting=Saque +Loyalty=Lealdade +Luck of the Sea=Sorte do Mar +Lure=Isca +Mending=Remendo +Mined blocks drop themselves.=Blocos minerados dropam a si mesmos. +Multishot=Rajada +Piercing=Perfuração +Power=Força +Punch=Impacto +Quick Charge=Recarga Rápida +Repair the item while gaining XP orbs.=Repara o item enquanto ganha orbes de XP. +Respiration=Respiração +Riptide=Correnteza +Sets target on fire.=Coloca fogo no alvo. +Sharpness=Afiação +Shoot 3 arrows at the cost of one.=Atira 3 flechas ao custo de uma. +Shooting consumes no regular arrows.=Atirar não consome flechas normais. +Silk Touch=Toque Suave +Smite=Julgamento +Soul Speed=Velocidade das Almas +Sweeping Edge=Alcance +Trident deals additional damage to ocean mobs.=Tridente dá dano adicional em mobs oceanicos. + +Trident launches player with itself when thrown. Works only in water or rain.=Tridente lança o jogador junto de si mesmo quando lançado. + +Trident returns after being thrown. Higher levels reduce return time.=Tridente retorna depois de ser arremessado. Níveis altos reduzem o tempo de retorno. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Transforma a água abaixo do jogador em gelo e previne o dano dos blocos de magma. + +Unbreaking=Inquebrável + +### engine.lua ### + +@1 Enchantment Levels=@1 Níveis de Encantamento +@1 Lapis Lazuli=@1 Lápis Lazuli +Inventory=Inventário +Level requirement: @1=Nível requerido: @1 + +### init.lua ### + +'@1' is not a valid number='@1' não é um número válido +'@1' is not a valid number.='@1' não é um número válido. + []= [] +@1 can't be combined with @2.=@1 não pode ser combinado com @2. + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.=Depois de finalmente selecionar seu encantamento; clique com o botão esquerdo na seleção, e você irá ver ambos os lápis lazuli e seus níveis de experiência serem consumidos. E, um item encantado deixado em seu lugar. + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=Depois de posicionar seus itens nos slots, as opções de encantamentos serão mostradas. Passe o mouse sobre as opções para ler o que está disponível para você. + +Enchant=Encantar +Enchant an item=Encantar um item +Enchanted Book=Livro Encantado +Enchanting Table=Mesa de Encantamento + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=A mesa de encantamentos permitem a você encantar armaduras, ferramentas, armas, e livros com várias habilidades. Mas, ao custo de alguma experiência, e lápis lazuli. + +Enchanting succeded.=Encantamento sucessido. +Forcefully enchant an item=Encantamento forçado em um item. + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.=Posicione uma ferramenta, armadura, arma ou livro no slot superior esquerdo, e então posicione 1-3 lápis lazuli no slot da direita. + +Player '@1' cannot be found.=Jogador '@1' não pôde ser encontrado. +Rightclick the Enchanting Table to open the enchanting menu.=Clique com o botão direito na mesa de encantamentos para abrir o menu de encantamentos. +Spend experience, and lapis to enchant various items.=Invista experiência, e lápis para encantar vários itens. + +The number you have entered (@1) is too big, it must be at most @2.=O número que você inseriu (@1) é muito grande, deve ser no máximo @2. + +The number you have entered (@1) is too small, it must be at least @2.=O número que você inseriu (@1) é muito pequeno, deve ser no mínimo @2. + +The selected enchantment can't be added to the target item.=O encantamento selecionado não pode ser adicionado ao item alvo. +The target doesn't hold an item.=O alvo não está segurando um item. +The target item is not enchantable.=O item alvo não é encantável. +There is no such enchantment '@1'.=Não existe um encantamento '@1'. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Essas opções são aleatorias, e dependentes do nível de experiência; mas a força do encantamento pode ser aumentado. + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.=Para aumentar a força do encantamento, posicione estantes de livros em volta da mesa de encantamentos. Porém, você precisará manter 1 bloco de ar entre a mesa e as estantes para potencializar a mesa de encantamentos. + +Usage: /enchant []=Uso: /enchant [] +Usage: /forceenchant []=Uso: /forceenchant [] + + +##### not used anymore ##### + +# textdomain: mcl_enchanting +Aqua Affinity=Afinidade Aquática +Increases underwater mining speed.=Aumenta a velocidade de mineração em baixo da água. +Blast Protection=Proteção Contra Explosões +Reduces explosion damage and knockback.=Reduz dano de explosão e repulsão. +Curse of Binding=Maldição do Ligamento +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Item não pode ser removido dos slots de armadura exceto em caso de morte, quebra ou no Modo Criativo. +Feather Falling=Peso-Pena +Reduces fall damage.=Reduz o dano de queda. +Fire Protection=Proteção Contra Fogo +Reduces fire damage.=Reduz o dano do fogo. +Projectile Protection=Proteção Contra Projéteis +Reduces projectile damage.=Reduz danos de projéteis. +Protection=Proteção +Reduces most types of damage by 4% for each level.=Reduz a maioria dos tipos de danos em 4% para cada nível. +Thorns=Espinhos +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflete parte do dano recebido quando acertado, ao custo de reduzir a durabilidade em cada processo. diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr index 6cd1e1db6..66d76b578 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr @@ -1,100 +1,144 @@ # textdomain: mcl_enchanting -Aqua Affinity=Родство с водой -Increases underwater mining speed.=Увеличивает скорость добычи под водой. -Bane of Arthropods=Бич членистоногих -Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Увеличивает урон и применяет Замедление IV к насекомым и членистоногим (паукам, пещерным паукам, чешуйницам и чешуйницам края). -Blast Protection=Взрывоустойчивость -Reduces explosion damage and knockback.=Уменьшает урон и отдачу от взрывов. -Channeling=Громовержец -Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Бьёт молнией в цель. Работает только во время грозы, когда цель не защищена плотными блоками. -Curse of Binding=Проклятие несъёмности -Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Предмет не может быть изъят из слота доспехов, кроме как в результате смерти, разрушения или в креативном режиме. -Curse of Vanishing=Проклятье утраты -Item destroyed on death.=Предмет уничтожается при смерти. -Depth Strider=Покоритель глубин -Increases underwater movement speed.=Увеличивает скорость передвижения под водой. -Efficiency=Эффективность -Increases mining speed.=Увеличивает скорость добычи. -Feather Falling=Невесомость -Reduces fall damage.=Снижает урон от падения. -Fire Aspect=Заговор огня -Sets target on fire.=Поджигает цель. -Fire Protection=Защита от огня -Reduces fire damage.=Уменьшает урон от огня. -Flame=Пламя -Arrows set target on fire.=Стрелы поджигают цель. -Fortune=Удача -Increases certain block drops.=Увеличивает выпадение ресурсов из блоков. -Frost Walker=Ледоход -Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Превращает воду под игроком в замороженный лёд и предотвращает урон от магмовых блоков. -Impaling=Пронзатель -Trident deals additional damage to ocean mobs.=Трезубец наносит дополнительный урон океаническим мобам. -Infinity=Бесконечность -Shooting consumes no regular arrows.=При стрельбе не расходуются стрелы. -Knockback=Отскок -Increases knockback.=Увеличивает отдачу. -Looting=Добыча -Increases mob loot.=Увеличивает добычу от мобов. -Loyalty=Верность -Trident returns after being thrown. Higher levels reduce return time.=Возвращает трезубец после броска. Более высокие уровни сокращают время возврата. -Luck of the Sea=Везучий рыбак -Increases rate of good loot (enchanting books, etc.)=Увеличивает шанс поймать сокровище (зачарованные книги и т.п.) -Lure=Приманка -Decreases time until rod catches something.=Уменьшает время ожидания клёва. -Mending=Починка -Repair the item while gaining XP orbs.=Предмет чинится при сборе жемчужин опыта. -Multishot=Залп -Shoot 3 arrows at the cost of one.=Выстреливают три стрелы по стоимости одной. -Piercing=Бронебойность + + +### enchantments.lua ### + Arrows passes through multiple objects.=Стрела пробивает насквозь несколько объектов. -Power=Сила -Increases arrow damage.=Увеличивает урон от стрел. -Projectile Protection=Защита от снарядов -Reduces projectile damage.=Уменьшает урон от снарядов. -Protection=Защита -Reduces most types of damage by 4% for each level.=Уменьшает большинство повреждений на 4% за каждый уровень. -Punch=Отбрасывание -Increases arrow knockback.=Увеличивает отбрасывание от стрелы. -Quick Charge=Быстрая перезарядка +Arrows set target on fire.=Стрелы поджигают цель. +Bane of Arthropods=Бич членистоногих +Channeling=Громовержец + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Бьёт молнией в цель. Работает только во время грозы, когда цель не защищена плотными блоками. + +Curse of Vanishing=Проклятье утраты Decreases crossbow charging time.=Уменьшает время заряда снаряда. -Respiration=Подводное дыхание +Decreases time until rod catches something.=Уменьшает время ожидания клёва. +Depth Strider=Покоритель глубин +Efficiency=Эффективность Extends underwater breathing time.=Увеличивает время дыхания под водой. -Riptide=Тягун -Trident launches player with itself when thrown. Works only in water or rain.=Трезубец тянет игрока за собой. Работает только в воде или под дождём. -Sharpness=Острота +Fire Aspect=Заговор огня +Flame=Горящая стрела +Fortune=Удача +Frost Walker=Ледоход +Impaling=Пронзатель +Increases arrow damage.=Увеличивает урон от стрел. +Increases arrow knockback.=Увеличивает отбрасывание от стрелы. +Increases certain block drops.=Даёт шанс выпадения большего количества ресурсов из блоков. + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Увеличивает урон и применяет Замедление IV к насекомым и членистоногим (паукам, пещерным паукам, чешуйницам и чешуйницам Края). + +Increases damage to undead mobs.=Дополнительный урон нежити. Increases damage.=Увеличенный урон. -Silk Touch=Шёлковое касание -Mined blocks drop themselves.=Добываемый блок выпадает сам, даже если из него должно выпадать что-то другое. -Smite=Небесная кара -Increases damage to undead mobs.=Дополнительный урон мертвякам (зомби и т.п.). -Soul Speed=Скорость души -Increases walking speed on soul sand.=Увеличивает скорость ходьбы по песку душ. -Sweeping Edge=Разящий клинок -Increases sweeping attack damage.=Увеличивает урон по мобам, стоящих рядом с целью. -Thorns=Шипы -Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Отражают некоторый урон, получаемый от ударов, за счёт снижения прочности с каждым разом. -Unbreaking=Нерушимость Increases item durability.=Увеличивает прочность предмета. +Increases knockback.=Увеличивает отдачу. +Increases mining speed.=Увеличивает скорость добычи. +Increases mob loot.=Увеличивает добычу от мобов. +Increases rate of good loot (enchanting books, etc.)=Увеличивает шанс поймать сокровище (зачарованные книги и т.п.) +Increases sweeping attack damage.=Увеличивает урон по мобам, стоящих рядом с целью. +Increases underwater movement speed.=Увеличивает скорость передвижения под водой. +Increases walking speed on soul sand.=Увеличивает скорость ходьбы по песку душ. +Infinity=Бесконечность +Item destroyed on death.=Предмет уничтожается при смерти. +Knockback=Отдача +Looting=Добыча +Loyalty=Верность +Luck of the Sea=Везучий рыбак +Lure=Приманка +Mending=Починка +Mined blocks drop themselves.=Добываемый блок выпадает сам, даже если из него должно выпадать что-то другое. +Multishot=Залп +Piercing=Бронебойность +Power=Сила +Punch=Отбрасывание +Quick Charge=Быстрая перезарядка +Repair the item while gaining XP orbs.=Предмет чинится при сборе сфер опыта. +Respiration=Подводное дыхание +Riptide=Тягун +Sets target on fire.=Поджигает цель. +Sharpness=Острота +Shoot 3 arrows at the cost of one.=Выстреливают три стрелы по стоимости одной. +Shooting consumes no regular arrows.=При стрельбе не расходуются обычные стрелы. +Silk Touch=Шёлковое касание +Smite=Небесная кара +Soul Speed=Скорость души +Sweeping Edge=Разящий клинок +Trident deals additional damage to ocean mobs.=Трезубец наносит дополнительный урон океаническим мобам. + +Trident launches player with itself when thrown. Works only in water or rain.=Трезубец тянет игрока за собой. Работает только в воде или под дождём. + +Trident returns after being thrown. Higher levels reduce return time.=Возвращает трезубец после броска. Более высокие уровни сокращают время возврата. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Превращает воду под игроком в подмороженный лёд и предотвращает урон от магмовых блоков. + +Unbreaking=Прочность + +### engine.lua ### + +@1 Enchantment Levels=@1 уровень зачаровывания +@1 Lapis Lazuli=@1 лазурит(а) Inventory=Инвентарь -@1 Lapis Lazuli=@1 Ляпис-лазурь -@1 Enchantment Levels=@1 Уровень зачаровывания Level requirement: @1=Требуемый уровень: @1 -Enchant an item=Зачаровать предмет - []=<игрок> <зачарование> [<уровень>] -Usage: /enchant []=Использование: /enchant <игрок> <зачарование> [<уровень>] -Player '@1' cannot be found.=Не удалось найти игрока '@1'. -There is no such enchantment '@1'.=Нет такого зачаровывания: '@1'. -The target doesn't hold an item.=Цель не держит предмета. -The selected enchantment can't be added to the target item.=Выбранное зачарование не может быть добавлено к целевому предмету. + +### init.lua ### + '@1' is not a valid number='@1' не является допустимым числом -The number you have entered (@1) is too big, it must be at most @2.=Число, которое вы задали (@1), слишком велико, оно может быть максимум @2. -The number you have entered (@1) is too small, it must be at least @2.=Число, которое вы задали (@1), слишком мало, оно может быть минимум @2. -@1 can't be combined with @2.=@1 нельзя сочетать с @2. -Enchanting succeded.=Зачарование выполнено. -Forcefully enchant an item=Принудительно зачаровать предмет -Usage: /forceenchant []=Использование: /forceenchant <игрок> <зачарование> [<уровень>] -The target item is not enchantable.=Указана незачаровываемая цель. '@1' is not a valid number.='@1' не является допустимым числом. + []=<игрок> <зачарование> [<уровень>] +@1 can't be combined with @2.=@1 нельзя сочетать с @2. + +After finally selecting your enchantment; left-click on the selection, and you will see both the lapis lazuli and your experience levels consumed. And, an enchanted item left in its place.=Кликните на выбранное зачарование - ваш опыт и лазурит потратятся, и зачарованный предмет появится слева. + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=Варианты зачарований будут показаны как только вы разместите предметы в слоты. Наведите, чтобы прочитать что вам доступно. + +Enchant=Зачаровать +Enchant an item=Зачаровать предмет Enchanted Book=Зачарованная книга Enchanting Table=Стол зачаровывания -Enchant=Зачарование + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=Стол зачаровывания позволяет зачаровывать броню, инструменты, оружие и книги разными способностями. Но ценой опыта и лазурита. + +Enchanting succeded.=Зачарование выполнено. +Forcefully enchant an item=Принудительно зачаровать предмет + +Place a tool, armor, weapon or book into the top left slot, and then place 1-3 Lapis Lazuli in the slot to the right.=Поместите инстумент, броню, оружие или книгу в верхний левый слот, затем поместите 1-3 лазурита в правый слот. + +Player '@1' cannot be found.=Не удалось найти игрока '@1'. +Rightclick the Enchanting Table to open the enchanting menu.=Правый клик по столу зачаровывания, чтобы открыть меню зачаровывания. +Spend experience, and lapis to enchant various items.=Зачаровывает предметы за опыт и лазурит + +The number you have entered (@1) is too big, it must be at most @2.=Число, которое вы задали (@1), слишком велико, оно должно быть максимум @2. + +The number you have entered (@1) is too small, it must be at least @2.=Число, которое вы задали (@1), слишком мало, оно должно быть минимум @2. + +The selected enchantment can't be added to the target item.=Выбранное зачарование не может быть добавлено к целевому предмету. +The target doesn't hold an item.=Цель не держит предмета. +The target item is not enchantable.=Целевой предмет нельзя зачаровать. +There is no such enchantment '@1'.=Нет такого зачарования: '@1'. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Эти опции случайны и зависят от уровня опыта; но зачарование может быть усилено. + +To increase the enchantment strength, place bookshelves around the enchanting table. However, you will need to keep 1 air node between the table, & the bookshelves to empower the enchanting table.=Чтобы усилить зачарование, поставьте книжные полки вокруг стола зачаровывания. Но вам нужно сохранять 1 блок пустого пространства между столом и полками. + +Usage: /enchant []=Использование: /enchant <игрок> <зачарование> [<уровень>] +Usage: /forceenchant []=Использование: /forceenchant <игрок> <зачарование> [<уровень>] + + +##### not used anymore ##### + +# textdomain: mcl_enchanting +Aqua Affinity= +Increases underwater mining speed.= +Blast Protection= +Reduces explosion damage and knockback.= +Curse of Binding= +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= +Feather Falling= +Reduces fall damage.= +Fire Protection= +Reduces fire damage.= +Projectile Protection= +Reduces projectile damage.= +Protection= +Reduces most types of damage by 4% for each level.= +Thorns= +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.= diff --git a/mods/ITEMS/mcl_enchanting/locale/template.txt b/mods/ITEMS/mcl_enchanting/locale/template.txt index 59876dcf3..2a0890d91 100644 --- a/mods/ITEMS/mcl_enchanting/locale/template.txt +++ b/mods/ITEMS/mcl_enchanting/locale/template.txt @@ -130,7 +130,7 @@ Aqua Affinity= Increases underwater mining speed.= Blast Protection= Reduces explosion damage and knockback.= -Curse of Binding=Malédiction du lien éternel +Curse of Binding= Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.= Feather Falling= Reduces fall damage.= diff --git a/mods/ITEMS/mcl_enchanting/mod.conf b/mods/ITEMS/mcl_enchanting/mod.conf index 610492857..d163fcd55 100644 --- a/mods/ITEMS/mcl_enchanting/mod.conf +++ b/mods/ITEMS/mcl_enchanting/mod.conf @@ -1,5 +1,5 @@ name = mcl_enchanting description = Enchanting for MineClone2 -depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience +depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience, mcl_util optional_depends = screwdriver author = Fleckenstein diff --git a/mods/ITEMS/mcl_enchanting/roman_numerals.lua b/mods/ITEMS/mcl_enchanting/roman_numerals.lua deleted file mode 100644 index f40c65406..000000000 --- a/mods/ITEMS/mcl_enchanting/roman_numerals.lua +++ /dev/null @@ -1,34 +0,0 @@ --------------------------------------------------------------------- ---! @file ---! @brief Convert from normal numbers to Roman Numerals ---------------------------------------------------------------------- -local conversionTable = { - { number = 1000, symbol = "M" }, - { number = 900, symbol = "CM" }, - { number = 500, symbol = "D" }, - { number = 400, symbol = "CD" }, - { number = 100, symbol = "C" }, - { number = 90, symbol = "XC" }, - { number = 50, symbol = "L" }, - { number = 40, symbol = "XL" }, - { number = 10, symbol = "X" }, - { number = 9, symbol = "IX" }, - { number = 5, symbol = "V" }, - { number = 4, symbol = "IV" }, - { number = 1, symbol = "I" } -} - -return{ - toRoman = function(number) - local romanNumeral = "" - - for _,table in pairs (conversionTable) do - while(number >= table.number) do - romanNumeral = romanNumeral .. table.symbol - number = number - table.number - end - end - - return romanNumeral - end -} diff --git a/mods/ITEMS/mcl_end/building.lua b/mods/ITEMS/mcl_end/building.lua index 82f6e76e4..837f09943 100644 --- a/mods/ITEMS/mcl_end/building.lua +++ b/mods/ITEMS/mcl_end/building.lua @@ -59,31 +59,22 @@ minetest.register_node("mcl_end:purpur_pillar", { _mcl_hardness = 1.5, }) -minetest.register_node("mcl_end:end_rod", { +local end_rod_name = "mcl_end:end_rod" +local end_rod_def = { description = S("End Rod"), _doc_items_longdesc = S("End rods are decorative light sources."), tiles = { - "mcl_end_end_rod_top.png", - "mcl_end_end_rod_bottom.png", - "mcl_end_end_rod_side.png", - "mcl_end_end_rod_side.png", - "mcl_end_end_rod_side.png", - "mcl_end_end_rod_side.png", + "mcl_end_end_rod.png", }, - drawtype = "nodebox", + drawtype = "mesh", + mesh = "mcl_end_rod.obj", is_ground_content = false, paramtype = "light", paramtype2 = "facedir", light_source = minetest.LIGHT_MAX, sunlight_propagates = true, - groups = { dig_immediate=3, deco_block=1, destroy_by_lava_flow=1, }, - node_box = { - type = "fixed", - fixed = { - {-0.125, -0.5, -0.125, 0.125, -0.4375, 0.125}, -- Base - {-0.0625, -0.4375, -0.0625, 0.0625, 0.5, 0.0625}, -- Rod - }, - }, + groups = { dig_immediate=3, deco_block=1, destroy_by_lava_flow=1, end_rod=1 }, + use_texture_alpha = "clip", selection_box = { type = "fixed", fixed = { @@ -132,7 +123,54 @@ minetest.register_node("mcl_end:end_rod", { sounds = mcl_sounds.node_sound_glass_defaults(), _mcl_blast_resistance = 0, -}) +} +minetest.register_node(end_rod_name, end_rod_def) + +-- register colored end_rods +local colored_end_rods = { + {"white", S("White End Rod"), "white"}, + {"grey", S("Grey End Rod"), "dark_grey"}, + {"silver", S("Light Grey End Rod"), "grey"}, + {"black", S("Black End Rod"), "black"}, + {"red", S("Red End Rod"), "red"}, + {"yellow", S("Yellow End Rod"), "yellow"}, + {"green", S("Green End Rod"), "dark_green"}, + {"cyan", S("Cyan End Rod"), "cyan"}, + {"blue", S("Blue End Rod"), "blue"}, + {"magenta", S("Magenta End Rod"), "magenta"}, + {"orange", S("Orange End Rod"), "orange"}, + {"purple", S("Purple End Rod"), "violet"}, + {"brown", S("Brown End Rod"), "brown"}, + {"pink", S("Pink End Rod"), "pink"}, + {"lime", S("Lime End Rod"), "green"}, + {"lightblue", S("Light Blue End Rod"), "lightblue"}, +} +local end_rod_mask = "^[mask:mcl_end_end_rod_mask.png" +for num, row in ipairs(colored_end_rods) do + local name = row[1] + local desc = row[2] + local dye = row[3] + local def = table.copy(end_rod_def) + def.description = desc + def._doc_items_longdesc = nil + def._doc_items_create_entry = false + def.use_texture_alpha = "clip" + local side_tex + if name == "pink" then + def.tiles[1] = def.tiles[1] .. "^(" .. def.tiles[1] .. end_rod_mask .. "^[multiply:" .. name .. "^[hsl:0:300)" + elseif num > 4 then + def.tiles[1] = def.tiles[1] .. "^(" .. def.tiles[1] .. end_rod_mask .. "^[multiply:" .. name .. "^[hsl:0:300^[opacity:120)" + else + def.tiles[1] = def.tiles[1] .. "^(" .. def.tiles[1] .. end_rod_mask .. "^[multiply:" .. name .. "^[hsl:0:-100^[opacity:170)" + end + minetest.register_node(end_rod_name.."_"..name, def) + minetest.register_craft({ + type = "shapeless", + output = end_rod_name.."_"..name, + recipe = {"group:end_rod", "mcl_dye:"..dye} + }) +end + minetest.register_node("mcl_end:dragon_egg", { description = S("Dragon Egg"), @@ -211,3 +249,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") diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 4dc54db18..7f2064a3e 100644 --- a/mods/ITEMS/mcl_end/chorus_plant.lua +++ b/mods/ITEMS/mcl_end/chorus_plant.lua @@ -155,7 +155,8 @@ minetest.register_node("mcl_end:chorus_flower", { 1) On top of end stone or chorus plant 2) On top of air and horizontally adjacent to exactly 1 chorus plant ]] local pos - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then pos = pointed_thing.under else pos = pointed_thing.above @@ -283,7 +284,8 @@ minetest.register_node("mcl_end:chorus_plant", { condition is met: - placed on end stone or any chorus node ]] local pos_place, node_check - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then pos_place = pointed_thing.under node_check = node_above else diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index b5adc7cb6..788107601 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -22,14 +22,15 @@ minetest.register_entity("mcl_end:ender_eye", { self._phase = 0 end end + if not self._luck then self._luck = 0 end end, on_step = function(self, dtime) self._age = self._age + dtime if self._age >= 3 then -- End of life - local r = math.random(1,5) - if r == 1 then + local r = math.random(1,15) + self._luck + if r <= 3 then -- 20% chance to get destroyed completely. -- 100% if in Creative Mode self.object:remove() @@ -85,11 +86,12 @@ minetest.register_craftitem("mcl_end:ender_eye", { if user == nil then return end + local player_name = user:get_player_name() local origin = user:get_pos() origin.y = origin.y + 1.5 local strongholds = mcl_structures.registered_structures["end_shrine"].static_pos local dim = mcl_worlds.pos_to_dimension(origin) - local is_creative = minetest.is_creative_enabled(user:get_player_name()) + local is_creative = minetest.is_creative_enabled(player_name) -- Just drop the eye of ender if there are no strongholds if #strongholds <= 0 or dim ~= "overworld" then @@ -124,6 +126,8 @@ minetest.register_craftitem("mcl_end:ender_eye", { -- Throw it! local obj = minetest.add_entity(origin, "mcl_end:ender_eye") local dir + local ent = obj:get_luaentity() + ent._luck = mcl_luck.get_luck(player_name) if lowest_dist <= 25 then local velocity = 4 diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.de.tr b/mods/ITEMS/mcl_end/locale/mcl_end.de.tr index 69a3408bb..9fb4c6b88 100644 --- a/mods/ITEMS/mcl_end/locale/mcl_end.de.tr +++ b/mods/ITEMS/mcl_end/locale/mcl_end.de.tr @@ -5,6 +5,22 @@ Purpur Block=Purpurblock Purpur Pillar=Purpursäule End Rod=Endstab End rods are decorative light sources.=Endstäbe sind dekorative Lichtquellen. +White End Rod=Weißer Endstab +Grey End Rod=Grauer Endstab +Light Grey End Rod=Hellgrauer Endstab +Black End Rod=Schwarzer Endstab +Red End Rod=Roter Endstab +Yellow End Rod=Gelber Endstab +Green End Rod=Grüner Endstab +Cyan End Rod=Türkiser Endstab +Blue End Rod=Blauer Endstab +Magenta End Rod=Magenta Endstab +Orange End Rod=Orange Endstab +Purple End Rod=Violetter Endstab +Brown End Rod=Brauner Endstab +Pink End Rod=Rosa Endstab +Lime End Rod=Lindgrüner Endstab +Light Blue End Rod=Hellblauer Endstab Dragon Egg=Drachenei A dragon egg is a decorative item which can be placed.=Ein Drahenei ist ein dekorativer, platzierbarer Gegenstand. Chorus Flower=Chorusblume diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr index 8e2d21e52..516663bd9 100644 --- a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr +++ b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr @@ -17,7 +17,7 @@ A chorus plant stem is the part of a chorus plant which holds the whole plant to Chorus Fruit=Fruit de chorus A chorus fruit is an edible fruit from the chorus plant which is home to the End. Eating it teleports you to the top of a random solid block nearby, provided you won't end up inside a liquid, solid or harmful blocks. Teleportation might fail if there are very few or no places to teleport to.=Un fruit de chorus est un fruit comestible de l'usine de chorus qui abrite la fin. Le manger vous téléporte au sommet d'un bloc solide aléatoire à proximité, à condition de ne pas vous retrouver dans un bloc liquide, solide ou nuisible. La téléportation peut échouer s'il y a très peu ou pas d'endroits où se téléporter. Popped Chorus Fruit=Chorus éclaté -Eye of Ender=Œil de l'Ender +Eye of Ender=Oeil de l'Ender This item is used to locate End portal shrines in the Overworld and to activate End portals.=Cet objet est utilisé pour localiser les sanctuaires du portail de l'End dans l'Overworld et pour activer les portails de l'End. Use the attack key to release the eye of ender. It will rise and fly in the horizontal direction of the closest end portal shrine. If you're very close, the eye of ender will take the direct path to the End portal shrine instead. After a few seconds, it stops. It may drop as an item, but there's a 20% chance it shatters.=Utilisez la touche d'attaque pour libérer l'œil d'Ender. Il s'élèvera et volera dans la direction horizontale du sanctuaire portail de l'End le plus proche. Si vous êtes très proche, l'œil d'Ender empruntera le chemin direct vers le sanctuaire du portail de l'End. Après quelques secondes, il s'arrête. Il peut tomber en tant qu'objet, mais il y a 20% de chances qu'il se brise. To activate an End portal, eyes of ender need to be placed into each block of an intact End portal frame.=Pour activer un portail de l'End, les yeux d'ender doivent être placés dans chaque bloc d'un cadre de portail de l'End intact. diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr b/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr index e6526b265..e159f738b 100644 --- a/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr +++ b/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr @@ -5,6 +5,22 @@ Purpur Block=Blok purpury Purpur Pillar=Filar purpury End Rod=Różdżka Kresu End rods are decorative light sources.=Różdżki Kresu są dekoracyjnymi źródłami światła. +White End Rod=Biała Różdżka Kresu +Grey End Rod=Szara Różdżka Kresu +Light Grey End Rod=Jasnoszara Różdżka Kresu +Black End Rod=Czarna Różdżka Kresu +Red End Rod=Czerwona Różdżka Kresu +Yellow End Rod=Żółta Różdżka Kresu +Green End Rod=Zielona Różdżka Kresu +Cyan End Rod=Błękitna Różdżka Kresu +Blue End Rod=Niebieska Różdżka Kresu +Magenta End Rod=Karmazynowa Różdżka Kresu +Orange End Rod=Pomarańczowa Różdżka Kresu +Purple End Rod=Fioletowa Różdżka Kresu +Brown End Rod=Brązowa Różdżka Kresu +Pink End Rod=Różowa Różdżka Kresu +Lime End Rod=Jasnozielona Różdżka Kresu +Light Blue End Rod=Jasnoniebieska Różdżka Kresu Dragon Egg=Jajo smoka A dragon egg is a decorative item which can be placed.=Jajo smoka jest przedmiotem dekoracyjnym, który można postawić. Chorus Flower=Kwiat refrenusu diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr b/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr index 6ab7a3c67..0f259cdcf 100644 --- a/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr +++ b/mods/ITEMS/mcl_end/locale/mcl_end.ru.tr @@ -1,33 +1,33 @@ # textdomain: mcl_end -End Stone=Камень Предела -End Stone Bricks=Кирпичи из камня Предела +End Stone=Камень Края +End Stone Bricks=Кирпичи из камня Края Purpur Block=Пурпурный блок Purpur Pillar=Пурпурная колонна -End Rod=Стержень Предела -End rods are decorative light sources.=Стержень Предела это декоративный светильник. -Dragon Egg=Драконье яйцо -A dragon egg is a decorative item which can be placed.=Драконье яйцо это декоративный предмет, который можно поставить. +End Rod=Стержень Края +End rods are decorative light sources.=Стержень Края это декоративный источник света. +Dragon Egg=Яйцо дракона +A dragon egg is a decorative item which can be placed.=Яйцо дракона это декоративный предмет, который можно поставить. Chorus Flower=Цветок коруса A chorus flower is the living part of a chorus plant. It can grow into a tall chorus plant, step by step. When it grows, it may die on old age eventually. It also dies when it is unable to grow.=Цветок коруса это живая часть растения коруса. Он может шаг за шагом вырасти в высокое растение коруса. Когда он растёт, то может иногда умирать от старости. Он также умирает, если не может расти. -Place it and wait for it to grow. It can only be placed on top of end stone, on top of a chorus plant stem, or at the side of exactly one chorus plant stem.=Установите его на место и ожидайте роста. Его можно помещать только на верхушку камня предела, а также верхнюю часть либо строго одну сторону стебля растения коруса. +Place it and wait for it to grow. It can only be placed on top of end stone, on top of a chorus plant stem, or at the side of exactly one chorus plant stem.=Установите его и ждите, пока он вырастет. Его можно помещать только на камень Края, а также на верхнюю часть стебля растения коруса. Dead Chorus Flower=Мёртвый цветок коруса -This is a part of a chorus plant. It doesn't grow. Chorus flowers die of old age or when they are unable to grow. A dead chorus flower can be harvested to obtain a fresh chorus flower which is able to grow again.=Это часть растения коруса. Она не растёт. Цветы коруса умирают от старости или когда не могут расти. Мёртвый цветок коруса можно собрать, чтобы получить свежий цветок коруса, который может вырасти вновь. +This is a part of a chorus plant. It doesn't grow. Chorus flowers die of old age or when they are unable to grow. A dead chorus flower can be harvested to obtain a fresh chorus flower which is able to grow again.=Это часть растения коруса. Он не растёт. Цветы коруса умирают от старости или когда не могут расти. Мёртвый цветок коруса можно собрать, чтобы получить свежий цветок коруса, который может вырасти вновь. Chorus Plant Stem=Стебель растения коруса -A chorus plant stem is the part of a chorus plant which holds the whole plant together. It needs end stone as its soil. Stems are grown from chorus flowers.=Стебель растения коруса это часть растения коруса, которая связывает всё растение вместе. Ему нужен камень предела как почва. Стебли растут из цветков коруса. +A chorus plant stem is the part of a chorus plant which holds the whole plant together. It needs end stone as its soil. Stems are grown from chorus flowers.=Стебель растения коруса это часть растения коруса, которая связывает всё растение вместе. Ему нужен камень Края как почва. Стебли растут из цветков коруса. Chorus Fruit=Фрукт коруса -A chorus fruit is an edible fruit from the chorus plant which is home to the End. Eating it teleports you to the top of a random solid block nearby, provided you won't end up inside a liquid, solid or harmful blocks. Teleportation might fail if there are very few or no places to teleport to.=Фрукт коруса это съедобный фрукт растения коруса, домом которого является Предел. Употребление его в пищу телепортирует вас к вершине случайного твёрдого блок поблизости. Вы не закончите жизнь внутри жидкого, твёрдого или опасного блока, но телепортация может потерпеть неудачу, если поблизости слишком мало подходящих мест или такие места отсутствуют. -Popped Chorus Fruit=Лопнувший фрукт коруса -Eye of Ender=Око Предела -This item is used to locate End portal shrines in the Overworld and to activate End portals.=Этот предмет используется для обнаружения храмов порталов в Верхнем Мире и активации порталов Предела. -Use the attack key to release the eye of ender. It will rise and fly in the horizontal direction of the closest end portal shrine. If you're very close, the eye of ender will take the direct path to the End portal shrine instead. After a few seconds, it stops. It may drop as an item, but there's a 20% chance it shatters.=Используйте клавишу [Атаковать], чтобы освободить око Предела. Оно поднимется и полетит в горизонтальном направлении к ближайшему храму портала. Если вы очень близко к храму портала Предела, то око Предела полетит к нему напрямую. Оно остановится через несколько секунд. Оно может превратиться обратно в предмет, но есть 20-процентная вероятность того, что оно разобьётся. -To activate an End portal, eyes of ender need to be placed into each block of an intact End portal frame.=Чтобы активировать портал Предела, нужно поместить по оку Предела на каждый блок целой рамки портала. -NOTE: The End dimension is currently incomplete and might change in future versions.=Предупреждение: Измерение Предела в настоящее время не завершено полностью и может измениться в будущих версиях. -The stem attaches itself to end stone and other chorus blocks.=Стебель присоединяется к камню Предела, а также к другим блокам коруса. -Grows on end stone=Растёт на камнях Предела +A chorus fruit is an edible fruit from the chorus plant which is home to the End. Eating it teleports you to the top of a random solid block nearby, provided you won't end up inside a liquid, solid or harmful blocks. Teleportation might fail if there are very few or no places to teleport to.=Фрукт коруса это съедобный фрукт растения коруса, домом которого является Край. Употребление его в пищу телепортирует вас к вершине случайного твёрдого блок поблизости. Вы не закончите жизнь внутри жидкого, твёрдого или опасного блока, но телепортация может потерпеть неудачу, если поблизости слишком мало подходящих мест или такие места отсутствуют. +Popped Chorus Fruit=Приготовленный плод коруса +Eye of Ender=Око Края +This item is used to locate End portal shrines in the Overworld and to activate End portals.=Этот предмет используется для обнаружения храмов с порталами в Верхнем Мире и для активации порталов Края. +Use the attack key to release the eye of ender. It will rise and fly in the horizontal direction of the closest end portal shrine. If you're very close, the eye of ender will take the direct path to the End portal shrine instead. After a few seconds, it stops. It may drop as an item, but there's a 20% chance it shatters.=Используйте клавишу [Атаковать], чтобы кинуть око Края. Оно поднимется и полетит в горизонтальном направлении к ближайшему храму с порталом. Если вы очень близко к храму портала Края, то око Края полетит к нему напрямую. Оно остановится через несколько секунд. Оно может превратиться обратно в предмет, но есть 20-процентная вероятность того, что око разобьётся. +To activate an End portal, eyes of ender need to be placed into each block of an intact End portal frame.=Чтобы активировать портал Края, нужно поместить по оку Края на каждый блок всей рамки портала. +NOTE: The End dimension is currently incomplete and might change in future versions.=Предупреждение: Измерение Края в настоящее время не завершено полностью и может измениться в будущих версиях. +The stem attaches itself to end stone and other chorus blocks.=Стебель присоединяется к камню Края, а также к другим блокам коруса. +Grows on end stone=Растёт на камне Края Randomly teleports you when eaten=Телепортирует случайным образом при употреблении в пищу -Guides the way to the mysterious End dimension=Показывает путь к загадочному измерению Предела -End Crystal=Кристалл Предела -End Crystals are explosive devices. They can be placed on Obsidian or Bedrock. Ignite them by a punch or a hit with an arrow. End Crystals can also be used the spawn the Ender Dragon by placing one at each side of the End Exit Portal.=Кристаллы Предела - это взрывные устройства. Их можно размещать на обсидиане или бедроке. Подрывайте их ударом или попаданием стрелы. Кристаллы Предела также можно использовать для порождения Дракона Предела, для этого их нужно поместить по одной штуке с каждой стороны выходного портала Предела. +Guides the way to the mysterious End dimension=Показывает путь к загадочному измерению Края +End Crystal=Кристалл Края +End Crystals are explosive devices. They can be placed on Obsidian or Bedrock. Ignite them by a punch or a hit with an arrow. End Crystals can also be used the spawn the Ender Dragon by placing one at each side of the End Exit Portal.=Кристаллы Края это взрывающиеся устройства. Их можно размещать на обсидиане или бедроке. Подрывайте их ударом или попаданием стрелы. Кристаллы Края также можно использовать для возрождения Дракона Края, для этого их нужно поместить по одной штуке с каждой стороны выходного портала Края. Explosion radius: @1=Радиус взрыва: @1 -Ignited by a punch or a hit with an arrow=Поджигается ударом или при попадании стрелы -Place the End Crystal on Obsidian or Bedrock, then punch it or hit it with an arrow to cause an huge and probably deadly explosion. To Spawn the Ender Dragon, place one at each side of the End Exit Portal.=Разместите кристалл Предела на обсидиане или бедроке и ударьте по нему или попадите в него стрелой, чтобы вызвать огромный и, вероятно, смертельный взрыв. Чтобы вызвать Дракона Предела, поместите по одной штуке с каждой стороны портала выходного портала Предела. +Ignited by a punch or a hit with an arrow=Взрывается от удара или при попадании стрелы +Place the End Crystal on Obsidian or Bedrock, then punch it or hit it with an arrow to cause an huge and probably deadly explosion. To Spawn the Ender Dragon, place one at each side of the End Exit Portal.=Разместите кристалл Края на обсидиане или бедроке и ударьте по нему или попадите в него стрелой, чтобы вызвать огромный и смертоносный взрыв. Чтобы привызвать Дракона Края, поместите по одной штуке с каждой стороны выходного портала Края. diff --git a/mods/ITEMS/mcl_end/locale/template.txt b/mods/ITEMS/mcl_end/locale/template.txt index 08c7de07b..4040b3756 100644 --- a/mods/ITEMS/mcl_end/locale/template.txt +++ b/mods/ITEMS/mcl_end/locale/template.txt @@ -5,6 +5,22 @@ Purpur Block= Purpur Pillar= End Rod= End rods are decorative light sources.= +White End Rod= +Grey End Rod= +Light Grey End Rod= +Black End Rod= +Red End Rod= +Yellow End Rod= +Green End Rod= +Cyan End Rod= +Blue End Rod= +Magenta End Rod= +Orange End Rod= +Purple End Rod= +Brown End Rod= +Pink End Rod= +Lime End Rod= +Light Blue End Rod= Dragon Egg= A dragon egg is a decorative item which can be placed.= Chorus Flower= diff --git a/mods/ITEMS/mcl_end/mod.conf b/mods/ITEMS/mcl_end/mod.conf index 021417e86..3666ace19 100644 --- a/mods/ITEMS/mcl_end/mod.conf +++ b/mods/ITEMS/mcl_end/mod.conf @@ -1,2 +1,2 @@ name = mcl_end -depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures \ No newline at end of file +depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures, mcl_stonecutter, mcl_luck diff --git a/mods/ITEMS/mcl_end/models/mcl_end_rod.obj b/mods/ITEMS/mcl_end/models/mcl_end_rod.obj new file mode 100644 index 000000000..f1050c550 --- /dev/null +++ b/mods/ITEMS/mcl_end/models/mcl_end_rod.obj @@ -0,0 +1,67 @@ +# Blender 3.6.7 +# www.blender.org +o Cube +v 0.125000 -0.437500 -0.125000 +v 0.125000 -0.500000 -0.125000 +v 0.125000 -0.437500 0.125000 +v 0.125000 -0.500000 0.125000 +v -0.125000 -0.437500 -0.125000 +v -0.125000 -0.500000 -0.125000 +v -0.125000 -0.437500 0.125000 +v -0.125000 -0.500000 0.125000 +v -0.062500 -0.437500 0.062500 +v -0.062500 0.500000 0.062500 +v -0.062500 -0.437500 -0.062500 +v -0.062500 0.500000 -0.062500 +v 0.062500 -0.437500 0.062500 +v 0.062500 0.500000 0.062500 +v 0.062500 -0.437500 -0.062500 +v 0.062500 0.500000 -0.062500 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vt 0.250000 1.000000 +vt -0.000000 1.000000 +vt -0.000000 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.000000 +vt 0.250000 0.062500 +vt 0.000000 0.062500 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.062500 +vt 0.750000 0.062500 +vt 0.750000 0.000000 +vt 0.000000 0.437500 +vt 0.250000 0.437500 +vt 0.250000 0.687500 +vt 0.000000 0.687500 +vt 0.500000 0.000000 +vt 0.500000 0.062500 +vt 1.000000 1.000000 +vt 0.875000 1.000000 +vt 0.875000 0.062500 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vt 0.625000 0.062500 +vt 0.500000 1.000000 +vt 0.187500 0.812500 +vt 0.187500 0.937500 +vt 0.062500 0.937500 +vt 0.062500 0.812500 +s 0 +f 1/1/1 5/2/1 7/3/1 3/4/1 +f 4/5/2 3/6/2 7/7/2 8/8/2 +f 8/9/3 7/10/3 5/11/3 6/12/3 +f 6/13/4 2/14/4 4/15/4 8/16/4 +f 2/17/5 1/18/5 3/6/5 4/5/5 +f 6/12/6 5/11/6 1/18/6 2/17/6 +f 9/10/3 10/19/3 12/20/3 11/21/3 +f 11/21/6 12/20/6 16/22/6 15/11/6 +f 15/11/5 16/22/5 14/23/5 13/24/5 +f 13/24/2 14/23/2 10/25/2 9/18/2 +f 11/26/4 15/27/4 13/28/4 9/29/4 +f 16/27/1 12/28/1 10/29/1 14/26/1 diff --git a/mods/ITEMS/mcl_farming/README.txt b/mods/ITEMS/mcl_farming/README.txt index 02cdaf93a..8fadc5ec6 100644 --- a/mods/ITEMS/mcl_farming/README.txt +++ b/mods/ITEMS/mcl_farming/README.txt @@ -1,7 +1,7 @@ ===FARMING MOD for MINETEST-C55=== by PilzAdam -Modified heavily by MineClone 2 Dev Team. +Modified heavily by VoxeLibre Dev Team. Introduction: This mod adds farming to Minetest. diff --git a/mods/ITEMS/mcl_farming/beetroot.lua b/mods/ITEMS/mcl_farming/beetroot.lua index 3785db111..f32b2bf8e 100644 --- a/mods/ITEMS/mcl_farming/beetroot.lua +++ b/mods/ITEMS/mcl_farming/beetroot.lua @@ -157,7 +157,7 @@ minetest.register_craftitem("mcl_farming:beetroot_soup", { wield_image = "mcl_farming_beetroot_soup.png", on_place = minetest.item_eat(6, "mcl_core:bowl"), on_secondary_use = minetest.item_eat(6, "mcl_core:bowl"), - groups = { food = 3, eatable = 6 }, + groups = { food = 2, eatable = 6 }, _mcl_saturation = 7.2, }) diff --git a/mods/ITEMS/mcl_farming/carrots.lua b/mods/ITEMS/mcl_farming/carrots.lua index f21285445..e8e295d8b 100644 --- a/mods/ITEMS/mcl_farming/carrots.lua +++ b/mods/ITEMS/mcl_farming/carrots.lua @@ -78,6 +78,13 @@ minetest.register_node("mcl_farming:carrot", { groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:carrot_item"}, + min_count = 2, + max_count = 4, + cap = 5, + } }) minetest.register_craftitem("mcl_farming:carrot_item", { diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index 72d8f7b7a..0a389522e 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -43,6 +43,7 @@ local hoe_on_place_function = function(wear_divisor) if create_soil(pointed_thing.under, user:get_inventory()) then if not minetest.is_creative_enabled(user:get_player_name()) then itemstack:add_wear(65535/wear_divisor) + tt.reload_itemstack_description(itemstack) -- update tooltip end return itemstack end @@ -54,7 +55,7 @@ local uses = { stone = 132, iron = 251, gold = 33, - diamond = 1562, + diamond = 1562, netherite = 2031, } @@ -274,26 +275,26 @@ minetest.register_craft({ {"mcl_core:diamond", "mcl_core:diamond"}, {"mcl_core:stick", ""}, {"mcl_core:stick", ""} - } -}) - -minetest.register_tool("mcl_farming:hoe_netherite", { - description = S("Netherite Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.netherite), - _doc_items_longdesc = hoe_longdesc, - _doc_items_usagehelp = hoe_usagehelp, - inventory_image = "farming_tool_netheritehoe.png", - wield_scale = mcl_vars.tool_wield_scale, - on_place = hoe_on_place_function(uses.netherite), - groups = { tool=1, hoe=1, enchantability=10, fire_immune=1 }, - tool_capabilities = { - full_punch_interval = 0.25, - damage_groups = { fleshy = 4, }, - punch_attack_uses = uses.netherite, - }, - _repair_material = "mcl_nether:netherite_ingot", - _mcl_toollike_wield = true, - _mcl_diggroups = { - hoey = { speed = 8, level = 5, uses = uses.netherite } - }, -}) + } +}) + +minetest.register_tool("mcl_farming:hoe_netherite", { + description = S("Netherite Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.netherite), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_netheritehoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.netherite), + groups = { tool=1, hoe=1, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 0.25, + damage_groups = { fleshy = 4, }, + punch_attack_uses = uses.netherite, + }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 8, level = 5, uses = uses.netherite } + }, +}) diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr index 5b14b109b..f7746b6ad 100644 --- a/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr @@ -96,10 +96,10 @@ Hay bales are decorative blocks made from wheat.=Les balles de foin sont des blo To carve a face into the pumpkin, use the shears on the side you want to carve.=Pour sculpter un visage dans la citrouille, utilisez les cisailles du côté que vous souhaitez sculpter. Use the “Place” key on an animal to try to feed it wheat.=Utilisez la touche "Placer" sur un animal pour essayer de le nourrir de blé. Grows on farmland=Pousse sur les terres agricoles -Turns block into farmland=Transforme un bloc en terres agricoles +Turns block into farmland=Transforme un bloc en terre agricole 60% chance of poisoning=60% de chances d'empoisonnement Surface for crops=Surface pour les cultures Can become wet=Peut devenir humide Uses: @1=Utilisations : @1 -Sweet Berry Bush (Stage @1)=Buisson de baies sucrées (étape 1) +Sweet Berry Bush (Stage @1)=Buisson de baies sucrées (étape @1) Sweet Berry=Baie sucrée diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.ru.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.ru.tr index f587fb943..467761f0e 100644 --- a/mods/ITEMS/mcl_farming/locale/mcl_farming.ru.tr +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.ru.tr @@ -1,99 +1,105 @@ # textdomain: mcl_farming Beetroot Seeds=Семена свёклы -Grows into a beetroot plant. Chickens like beetroot seeds.=Вырастают на свёкле. Куры обожают свекольные семена. -Place the beetroot seeds on farmland (which can be created with a hoe) to plant a beetroot plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it beetroot seeds.=Положите семена свёклы на грядку (которую можно создать при помощи мотыги), чтобы посадить свёклу. Они прорастают при солнечном свете и растут быстрее на увлажнённой почке. Кликните правой по животному, чтобы накормить его семенами свёклы. +Grows into a beetroot plant. Chickens like beetroot seeds.=Из них вырастает свёкла. Куры любят свекольные семена. +Place the beetroot seeds on farmland (which can be created with a hoe) to plant a beetroot plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it beetroot seeds.=Положите семена свёклы на грядку (которую можно создать при помощи мотыги), чтобы посадить свёклу. Семена растут при солнечном свете, их рост происходит быстрее на увлажнённой почве. Кликните правой по животному, чтобы покормить его семенами свёклы. Premature Beetroot Plant (Stage 1)=Рассада молодой свёклы (стадия 1) Beetroot plants are plants which grow on farmland under sunlight in 4 stages. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=Свёкла растёт в 4 стадии на грядках под действием солнечного света. На увлажнённой грядке процесс пойдёт чуть быстрее. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревших экземпляров. Premature Beetroot Plant=Рассада молодой свёклы Premature Beetroot Plant (Stage 2)=Рассада молодой свёклы (стадия 2) Premature Beetroot Plant (Stage 3)=Рассада молодой свёклы (стадия 3) Mature Beetroot Plant=Созревшая свёкла -A mature beetroot plant is a farming plant which is ready to be harvested for a beetroot and some beetroot seeds. It won't grow any further.=Созревшая свёкла это культивируемое растение, с которого уже можно собирать урожай свёклы и некоторое количество свекольных семян. Дальше расти она уже не будет. +A mature beetroot plant is a farming plant which is ready to be harvested for a beetroot and some beetroot seeds. It won't grow any further.=Созревшая свёкла это культивируемое растение, с которого уже можно собирать урожай свёклы и несколько свекольных семян. Дальше расти она уже не будет. Beetroot=Свёкла Beetroots are both used as food item and a dye ingredient. Pigs like beetroots, too.=Свёкла это еда и ингредиент для красителя. Свёклу также очень любят свиньи. -Hold it in your hand and right-click to eat it. Rightclick an animal to feed it.=Чтобы съесть, кликните правой, держа её в руке. Или кликните правой по животному, чтобы покормить его. -Beetroot Soup=Борщ -Beetroot soup is a food item.=Борщ можно есть, он съедобен. +Hold it in your hand and right-click to eat it. Rightclick an animal to feed it.=Чтобы съесть свёклу, возьмите её в руки с кликните правой кнопкой мыши. Или кликните правой кнопкой мыши по животному, чтобы покормить его. +Beetroot Soup=Свекольный суп +Beetroot soup is a food item.=Свекольный суп можно съесть. Premature Carrot Plant=Рассада молодой моркови -Carrot plants are plants which grow on farmland under sunlight in 8 stages, but only 4 stages can be visually told apart. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=Морковь растёт в 8 стадий на грядках под действием солнечного света, но визуально различить можно только 4 стадии. На увлажнённой грядке рост идёт чуть быстрее. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревших экземпляров. +Carrot plants are plants which grow on farmland under sunlight in 8 stages, but only 4 stages can be visually told apart. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=Морковь растёт в 8 стадий на грядках под действием солнечного света, но визуально различить можно только 4 стадии. На увлажнённой грядке рост идёт чуть быстрее. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревшей моркови. Premature Carrot Plant (Stage @1)=Рассада молодой моркови (стадия @1) Mature Carrot Plant=Созревшая морковь Mature carrot plants are ready to be harvested for carrots. They won't grow any further.=Созревшая морковь готова к сбору. Дальше расти она уже не будет. Carrot=Морковь Carrots can be eaten and planted. Pigs and rabbits like carrots.=Морковь можно есть и садить. Свиньи и кролики очень любят морковь. -Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant the carrot. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=Чтобы съесть, кликните правой, держа её в руке. Или поместите её на грядку, чтобы посадить морковь. Она растёт под действием солнечного света, на влажных грядках процесс идёт быстрее. Или кликните правой по животному, чтобы покормить его. +Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant the carrot. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=Чтобы съесть морковь, возьмите её в руки с кликните правой кнопкой мыши. Или кликните правой кнопкой мыши по животному, чтобы покормить его. Морковь растёт под действием солнечного света, на влажных грядках процесс идёт быстрее. Golden Carrot=Золотая морковь -A golden carrot is a precious food item which can be eaten. It is really, really filling!=Золотая морковь это изысканный продуктовый предмет, которые можно есть. Она отлично, отлично утоляет голод! +A golden carrot is a precious food item which can be eaten. It is really, really filling!=Золотая морковь это ценный съедобный продукт. Она отлично утоляет голод! Hoes are essential tools for growing crops. They are used to create farmland in order to plant seeds on it. Hoes can also be used as very weak weapons in a pinch.=Мотыга это инструмент, необходимый для выращивания урожая. Она используется для создания грядок, на которые потом можно высадить семена. В случае необходимости мотыгу можно использовать и в качестве слабого оружия. -Use the hoe on a cultivatable block (by rightclicking it) to turn it into farmland. Dirt, grass blocks and grass paths are cultivatable blocks. Using a hoe on coarse dirt turns it into dirt.=Примените мотыгу к культивируемому блоку (кликнув правой по нему), чтобы превратить его в грядку. Грязь, травяные блоки и тропинки это культивируемые блоки. Разрыхлив мотыгой грубую грязь, вы получите из её обыкновенную грязь. +Use the hoe on a cultivatable block (by rightclicking it) to turn it into farmland. Dirt, grass blocks and grass paths are cultivatable blocks. Using a hoe on coarse dirt turns it into dirt.=Примените мотыгу к культивируемому блоку (кликнув правой кнопкой мыши по нему), чтобы превратить его в грядку. Земля, дёрн и тропинки это культивируемые блоки. Разрыхлив мотыгой каменистую землю, вы получите из неё обычную землю. Wood Hoe=Деревянная мотыга Stone Hoe=Каменная мотыга Iron Hoe=Железная мотыга Golden Hoe=Золотая мотыга Diamond Hoe=Алмазная мотыга -Melon Seeds=Семена дыни +Netherite Hoe=Незеритовая мотыга +Melon Seeds=Семена арбуза Grows into a melon stem which in turn grows melons. Chickens like melon seeds.=Из них вырастают дыневые стебли, из которых, в свою очередь, вырастают дыни. Семена дыни любят куры. -Place the melon seeds on farmland (which can be created with a hoe) to plant a melon stem. Melon stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem will attempt to grow a melon at the side. Rightclick an animal to feed it melon seeds.=Положите семена дыни на грядку (которую можно создать при помощи мотыги), чтобы посадить дыню. Дыневые стебли прорастают при солнечном свете, они растут быстрее на увлажнённой почке. На боку вызревшего стебля будет пытаться расти дыня. Кликните правой по животному, чтобы накормить его дыневыми семенами. -Melon=Дыня -A melon is a block which can be grown from melon stems, which in turn are grown from melon seeds. It can be harvested for melon slices.=Дыня это блок, который может расти на дыневом стебле, выросшем из семян дыни. -Premature Melon Stem=Созревший дыневый стебель -Melon stems grow on farmland in 8 stages. On hydrated farmland, the growth is a bit quicker. Mature melon stems are able to grow melons.=Стебель дыни растёт на грядке в 8 стадий. На увлажнённой грядке рост происходит немного быстрее. На созревших стеблях могут расти дыни. -Premature Melon Stem (Stage @1)=Молодой стебель дыни (стадия @1) -Mature Melon Stem=Созревший дыневый стебель -A mature melon stem attempts to grow a melon at one of its four adjacent blocks. A melon can only grow on top of farmland, dirt, or a grass block. When a melon is next to a melon stem, the melon stem immediately bends and connects to the melon. While connected, a melon stem can't grow another melon. As soon all melons around the stem have been removed, it loses the connection and is ready to grow another melon.=Зрелый стебель дыни пытается вырастить дыню на одном из четырех соседних блоков. Дыня может расти только на грядках, грязи или на травяном блоке. Когда дыня находится рядом со стеблем, он сразу же изгибается и соединяется с ней. При этом стебель не может выращивать другую дыню. И только когда все дыни вокруг стебля убраны, он будет готов вырастить другую дыню. -Melon Slice=Кусок дыни -This is a food item which can be eaten.=Это продуктовый предмет, его можно есть. +Place the melon seeds on farmland (which can be created with a hoe) to plant a melon stem. Melon stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem will attempt to grow a melon at the side. Rightclick an animal to feed it melon seeds.=Положите семена арбуза на грядку (которую можно создать при помощи мотыги), чтобы посадить арбуз. Стебли арбуза прорастают при солнечном свете, их рост происходит быстрее на увлажнённой почве. Сбоку созревшего стебля будет вырастет арбуз. Кликните правой кнопкой мыши по животному, чтобы покормить его арбузными семенами. +Melon=Арбуз +A melon is a block which can be grown from melon stems, which in turn are grown from melon seeds. It can be harvested for melon slices.=Арбуз это блок, который может расти на арбузном стебле, выросшем из семян арбуза. +Premature Melon Stem=Созревший арбузный стебель +Melon stems grow on farmland in 8 stages. On hydrated farmland, the growth is a bit quicker. Mature melon stems are able to grow melons.=Стебель арбуза растёт на грядке в 8 стадий. На увлажнённой грядке рост происходит немного быстрее. На созревших стеблях могут расти арбузы. +Premature Melon Stem (Stage @1)=Молодой стебель арбуза (стадия @1) +Mature Melon Stem=Созревший арбузный стебель +A mature melon stem attempts to grow a melon at one of its four adjacent blocks. A melon can only grow on top of farmland, dirt, or a grass block. When a melon is next to a melon stem, the melon stem immediately bends and connects to the melon. While connected, a melon stem can't grow another melon. As soon all melons around the stem have been removed, it loses the connection and is ready to grow another melon.=Зрелый стебель арбуза пытается вырастить арбуз на одном из четырех соседних блоков. Арбуз может расти только на грядках, земле или на дёрне. Когда арбуз находится рядом со стеблем, стебель сразу же изгибается и соединяется с ней. При этом стебель не может выращивать другой арбуз. И только когда все арбузы вокруг стебля убраны, он будет готов вырастить другой арбуз. +Melon Slice=Ломтик арбуза +This is a food item which can be eaten.=Это съедобный продукт. Premature Potato Plant=Молодой картофель Potato plants are plants which grow on farmland under sunlight in 8 stages, but only 4 stages can be visually told apart. On hydrated farmland, they grow a bit faster. They can be harvested at any time but will only yield a profit when mature.=Картофель растёт в 8 стадий на грядках под действием солнечного света, но визуально различить можно только 4 стадии. На увлажнённой грядке рост идёт чуть быстрее. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревших экземпляров. Premature Potato Plant (Stage @1)=Саженец молодого картофеля (стадия @1) Mature Potato Plant=Созревший картофель Mature potato plants are ready to be harvested for potatoes. They won't grow any further.=Созревший картофель готов к сбору. Дальше расти он уже не будет. Potato=Картофель -Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes.=Картофель это продуктовый предмет, его можно есть, готовить в печи, а также садить. Картофель любят свиньи. -Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant it. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=Чтобы съесть, кликните правой, держа его в руке. Или поместите его на грядку, чтобы посадить картофель. Он растёт под действием солнечного света, на влажных грядках процесс идёт быстрее. Или кликните правой по животному, чтобы покормить его. +Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes.=Картофель это съедобный продукт, его можно съесть, готовить в печи, а также садить. Картофель любят свиньи. +Hold it in your hand and rightclick to eat it. Place it on top of farmland to plant it. It grows in sunlight and grows faster on hydrated farmland. Rightclick an animal to feed it.=Чтобы съесть картофель, возьмите его в руки с кликните правой кнопкой мыши. Или кликните картофелем на грядку, чтобы посадить его. Кликните правой кнопкой мыши по животному, чтобы покормить его. Картофель растёт под действием солнечного света, на влажных грядках процесс идёт быстрее. Baked Potato=Печёный картофель -Baked potatoes are food items which are more filling than the unbaked ones.=Печёный картофель это продуктовый предмет, который насыщает лучше, чем сырой картофель. +Baked potatoes are food items which are more filling than the unbaked ones.=Печёный картофель это съедобный продукт, который насыщает лучше, чем сырой картофель. Poisonous Potato=Ядовитый картофель -This potato doesn't look too healthy. You can eat it to restore hunger points, but there's a 60% chance it will poison you briefly.=Этот картофель вреден для здоровья. Его можно есть для восстановления очков голода, но с вероятностью 60% он вас ненадолго отравит. +This potato doesn't look too healthy. You can eat it to restore hunger points, but there's a 60% chance it will poison you briefly.=Этот картофель вреден. Его можно есть для восстановления очков голода, но с вероятностью 60% вы ненадолго отравитесь. Pumpkin Seeds=Семена тыквы Grows into a pumpkin stem which in turn grows pumpkins. Chickens like pumpkin seeds.=Из них вырастают тыквенный стебель, на котором, в свою очередь, растут тыквы. -Place the pumpkin seeds on farmland (which can be created with a hoe) to plant a pumpkin stem. Pumpkin stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem attempts to grow a pumpkin next to it. Rightclick an animal to feed it pumpkin seeds.=Положите семена тыквы на грядку (которую можно создать при помощи мотыги), чтобы посадить тыкву. Тыквенные стебли прорастают при солнечном свете, они растут быстрее на увлажнённой почке. Когда стебель созреет, то попытается вырастить тыкву рядом с собой. Кликните правой по животному, чтобы накормить его тыквенными семенами. +Place the pumpkin seeds on farmland (which can be created with a hoe) to plant a pumpkin stem. Pumpkin stems grow in sunlight and grow faster on hydrated farmland. When mature, the stem attempts to grow a pumpkin next to it. Rightclick an animal to feed it pumpkin seeds.=Положите семена тыквы на грядку (которую можно создать при помощи мотыги), чтобы посадить тыкву. Тыквенные стебли прорастают при солнечном свете, они растут быстрее на увлажнённой почве. Когда стебель созреет, то попытается вырастить тыкву рядом с собой. Кликните правой кнопкой мыши по животному, чтобы покормить его. Premature Pumpkin Stem=Созревший тыквенный стебель Pumpkin stems grow on farmland in 8 stages. On hydrated farmland, the growth is a bit quicker. Mature pumpkin stems are able to grow pumpkins.=Стебель тыквы растёт на грядке в 8 стадий. На увлажнённой грядке рост происходит немного быстрее. На созревших стеблях могут расти тыквы. Premature Pumpkin Stem (Stage @1)=Молодой стебель тыквы (стадия @1) Mature Pumpkin Stem=Созревший тыквенный стебель A mature pumpkin stem attempts to grow a pumpkin at one of its four adjacent blocks. A pumpkin can only grow on top of farmland, dirt or a grass block. When a pumpkin is next to a pumpkin stem, the pumpkin stem immediately bends and connects to the pumpkin. A connected pumpkin stem can't grow another pumpkin. As soon all pumpkins around the stem have been removed, it loses the connection and is ready to grow another pumpkin.=Зрелый стебель тыквы пытается вырастить тыкву на одном из четырех соседних блоков. Тыква может расти только на грядках, грязи или на травяном блоке. Когда тыква находится рядом со стеблем, он сразу же изгибается и соединяется с ней. При этом стебель не может выращивать другую тыкву. И только когда все тыквы вокруг стебля убраны, он будет готов вырастить другую тыкву. -Faceless Pumpkin=Безликая тыква -A faceless pumpkin is a decorative block. It can be carved with shears to obtain pumpkin seeds.=Безликая тыква это декоративный блок. Его можно разрезать ножницами для получения семян тыквы. -Pumpkin=Тыква -A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.=Тыкву можно носить как шлем. Тыквы растут из тыквенных стеблей, которые растут из семян тыквы. +Faceless Pumpkin=Тыква +A faceless pumpkin is a decorative block. It can be carved with shears to obtain pumpkin seeds.=Тыква это декоративный блок. Её можно разрезать ножницами для получения семян тыквы. +Pumpkin=Вырезанная тыква +A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.=Вырезанную тыкву можно носить как шлем. Тыквы растут из тыквенных стеблей, которые растут из семян тыквы. Jack o'Lantern=Светильник Джека A jack o'lantern is a traditional Halloween decoration made from a pumpkin. It glows brightly.=Светильник Джека это традиционное украшение на Хеллоуин, изготавливаемое из тыквы. Он ярко светит. Pumpkin Pie=Тыквенный пирог -A pumpkin pie is a tasty food item which can be eaten.=Тыквенный пирог это вкусный продуктовый предмет, который можно съесть. +A pumpkin pie is a tasty food item which can be eaten.=Тыквенный пирог это вкусный съедобный продукт. Farmland=Грядка -Farmland is used for farming, a necessary surface to plant crops. It is created when a hoe is used on dirt or a similar block. Plants are able to grow on farmland, but slowly. Farmland will become hydrated farmland (on which plants grow faster) when it rains or a water source is nearby. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=Грядка нужна для земледелия, она представляет собой поверхность для высадки культур. Он создается при применении мотыги к грязи и тому подобным блокам. Растения могут расти на грядках, но медленно. Грядки превратятся в увлажнённые грядки, если пойдёт дождь, либо если поблизости есть источник воды. Этот блок превратится обратно в грязь, если поместить на него твёрдый блок, а также под действием поршневого рычага. +Farmland is used for farming, a necessary surface to plant crops. It is created when a hoe is used on dirt or a similar block. Plants are able to grow on farmland, but slowly. Farmland will become hydrated farmland (on which plants grow faster) when it rains or a water source is nearby. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=Грядка нужна для земледелия, она представляет собой поверхность для высадки культур. Он создается при применении мотыги к земле и тому подобным блокам. Растения могут расти на грядках, но медленно. Грядки превратятся в увлажнённые грядки, если пойдёт дождь, либо если поблизости есть источник воды. Этот блок превратится обратно в землю, если поместить на него твёрдый блок, или действовать на блок поршнем. Hydrated Farmland=Увлажнённая грядка -Hydrated farmland is used in farming, this is where you can plant and grow some plants. It is created when farmland is under rain or near water. Without water, this block will dry out eventually. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=Увлажнённая грядка нужна для земледелия, на ней вы можете выращивать некоторые растения. Она создается, когда обыкновенная грядка попадает под дождь, либо рядом есть источник воды. Без воды этот блок рано или поздно высохнет. Увлажнённая грядка превратится обратно в грязь, если поместить на неё твёрдый блок, либо она попадёт под действие поршневого рычага. +Hydrated farmland is used in farming, this is where you can plant and grow some plants. It is created when farmland is under rain or near water. Without water, this block will dry out eventually. This block will turn back to dirt when a solid block appears above it or a piston arm extends above it.=Увлажнённая грядка нужна для земледелия, на ней вы можете выращивать некоторые растения. Она создается, когда обыкновенная грядка попадает под дождь, либо рядом есть источник воды. Без воды этот блок рано или поздно высохнет. Этот блок превратится обратно в землю, если поместить на него твёрдый блок, или действовать на блок поршнем. Wheat Seeds=Семена пшеницы Grows into a wheat plant. Chickens like wheat seeds.=Вырастают в пшеницу. Семена пшеницы любят куры. -Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant. They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds.=Положите семена пшеницы на грядку (которую можно создать при помощи мотыги), чтобы посадить пшеницу. Семена растут при солнечном свете, их рост происходит быстрее на увлажнённой почке. Кликните правой по животному, чтобы накормить его семенами пшеницы. +Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant.=Положите семена пшеницы на грядку (которую можно создать при помощи мотыги), чтобы посадить пшеницу. +They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds.=Семена растут при солнечном свете, их рост происходит быстрее на увлажнённой почве. Кликните правой кнопкой мыши по животному, чтобы покормить его. Premature Wheat Plant=Ростки молодой пшеницы -Premature wheat plants grow on farmland under sunlight in 8 stages. On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.=Молодая пшеница растёт на грядке под действием солнечного света за 8 стадий. На увлажнённой грядке она растёт быстрее. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревших экземпляров. +Premature wheat plants grow on farmland under sunlight in 8 stages.=Молодая пшеница растёт на грядке под солнечным светов за 8 стадий. +On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.=Семена растут быстрее на увлажнённой почве. Собирать урожай можно на любой стадии, но выгода будет только при сборе созревших экземпляров. Premature Wheat Plant (Stage @1)=Ростки молодой пшеницы (стадия @1) Mature Wheat Plant=Зрелая пшеница -Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further.=Зрелая пшеница готова к сбору сена и семян, дальше расти она уже не будет. +Mature wheat plants are ready to be harvested for wheat and wheat seeds.=Зрелая пшеница готова к сбору ради пшеницы и семян. +They won't grow any further.=Растение больше не вырастет. Wheat=Пшеница -Wheat is used in crafting. Some animals like wheat.=Пшеницы используется для крафтинга. Некоторые животные любят пшеницу. +Wheat is used in crafting. Some animals like wheat.=Пшеница используется для крафта. Некоторые животные любят пшеницу. Cookie=Печенье Bread=Хлеб -Hay Bale=Стог сена -Hay bales are decorative blocks made from wheat.=Стог сена - декоративный блок, сделанный из пшеницы. -To carve a face into the pumpkin, use the shears on the side you want to carve.=Чтобы вырезать лицо на тыкве, примените ножницы к выбранной стороне тыквы. -Use the “Place” key on an animal to try to feed it wheat.=Нажмите клавишу “Разместить” на животном, чтобы попытаться покормить его пшеницей. -Grows on farmland=Прорастает(ют) на грядке -Turns block into farmland=Превращает блоки в грядки +Hay Bale=Сноп сена +Hay bales are decorative blocks made from wheat.=Сноп сена - декоративный блок сделанный из пшеницы. +To carve a face into the pumpkin, use the shears on the side you want to carve.=Чтобы вырезать лицо на тыкве примените ножницы к выбранной стороне тыквы. +Use the “Place” key on an animal to try to feed it wheat.=Нажмите клавишу [Использовать] на животном, чтобы попытаться покормить его пшеницей. +Grows on farmland=Прорастает на грядке +Turns block into farmland=Делает из блока грядку 60% chance of poisoning=Вероятность отравления: 60% Surface for crops=Поверхность для культур Can become wet=Может намокать -Uses: @1=Выдерживает: @1 использований(е,я) +Uses: @1=Использований: @1 +Sweet Berry Bush (Stage @1)=Куст сладкой ягоды (стадия @1) +Sweet Berry=Сладкая ягода diff --git a/mods/ITEMS/mcl_farming/potatoes.lua b/mods/ITEMS/mcl_farming/potatoes.lua index e29219fd8..66c5169c4 100644 --- a/mods/ITEMS/mcl_farming/potatoes.lua +++ b/mods/ITEMS/mcl_farming/potatoes.lua @@ -83,6 +83,13 @@ minetest.register_node("mcl_farming:potato", { groups = {dig_immediate=3, not_in_creative_inventory=1,plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:potato_item"}, + min_count = 2, + max_count = 4, + cap = 5 + } }) minetest.register_craftitem("mcl_farming:potato_item", { @@ -135,7 +142,7 @@ minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, -- 60% chance of poisoning with poisonous potato if itemstack:get_name() == "mcl_farming:potato_item_poison" then if math.random(1,10) >= 6 then - mcl_potions.poison_func(user, 1, 5) + mcl_potions.give_effect_by_level("poison", user, 1, 5) end end diff --git a/mods/ITEMS/mcl_farming/pumpkin.lua b/mods/ITEMS/mcl_farming/pumpkin.lua index 7387a78c9..fe437f5cf 100644 --- a/mods/ITEMS/mcl_farming/pumpkin.lua +++ b/mods/ITEMS/mcl_farming/pumpkin.lua @@ -38,7 +38,7 @@ local stem_drop = { { items = {"mcl_farming:pumpkin_seeds 2"}, rarity = 31 }, -- 3 seeds: 1/125 chance - { items = {"mcl_farming:pumkin_seeds 3"}, rarity = 125 }, + { items = {"mcl_farming:pumpkin_seeds 3"}, rarity = 125 }, }, } @@ -101,7 +101,7 @@ local pumpkin_base_def = { tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png"}, groups = { 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(), on_rotate = on_rotate, @@ -119,7 +119,7 @@ pumpkin_face_base_def.groups.non_combat_armor=1 pumpkin_face_base_def.groups.armor_head=1 pumpkin_face_base_def.groups.non_combat_armor_head=1 pumpkin_face_base_def._mcl_armor_mob_range_factor = 0 -pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman" +pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:rover" pumpkin_face_base_def._mcl_armor_element = "head" pumpkin_face_base_def._mcl_armor_texture = "mcl_farming_pumpkin_face.png" @@ -199,7 +199,7 @@ minetest.register_node("mcl_farming:pumpkin_face_light", { paramtype2 = "facedir", 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"}, - 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(), on_construct = function(pos) -- Attempt to spawn iron golem or snow golem diff --git a/mods/ITEMS/mcl_farming/sweet_berry.lua b/mods/ITEMS/mcl_farming/sweet_berry.lua index 7dc6326a4..fdcc460df 100644 --- a/mods/ITEMS/mcl_farming/sweet_berry.lua +++ b/mods/ITEMS/mcl_farming/sweet_berry.lua @@ -20,7 +20,7 @@ for i=0, 3 do sunlight_propagates = true, paramtype2 = "meshoptions", place_param2 = 3, - liquid_viscosity = 15, + liquid_viscosity = 7, liquidtype = "source", liquid_alternative_flowing = node_name, liquid_alternative_source = node_name, @@ -53,7 +53,7 @@ for i=0, 3 do end if 3 ~= i and mcl_dye and clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then - mcl_dye.apply_bone_meal({under=pos},clicker) + mcl_dye.apply_bone_meal({under=pos, above=vector.offset(pos,0,1,0)},clicker) if not minetest.is_creative_enabled(pn) then itemstack:take_item() end diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index 15fd98e2a..676cc1301 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -89,6 +89,13 @@ minetest.register_node("mcl_farming:wheat", { dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1}, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:wheat_seeds"}, + min_count = 1, + max_count = 6, + cap = 7 + } }) mcl_farming:add_plant("plant_wheat", "mcl_farming:wheat", {"mcl_farming:wheat_1", "mcl_farming:wheat_2", "mcl_farming:wheat_3", "mcl_farming:wheat_4", "mcl_farming:wheat_5", "mcl_farming:wheat_6", "mcl_farming:wheat_7"}, 25, 20) diff --git a/mods/ITEMS/mcl_fences/API.md b/mods/ITEMS/mcl_fences/API.md index 39ba314f2..01e04fdc6 100644 --- a/mods/ITEMS/mcl_fences/API.md +++ b/mods/ITEMS/mcl_fences/API.md @@ -1,4 +1,4 @@ -# API for adding MineClone 2 fences +# API for adding VoxeLibre fences This API allows you to add fences and fence gates. The recommended function is `mcl_fences.register_fence_and_fence_gate`. diff --git a/mods/ITEMS/mcl_fences/init.lua b/mods/ITEMS/mcl_fences/init.lua index b14d103d2..5555fbfc0 100644 --- a/mods/ITEMS/mcl_fences/init.lua +++ b/mods/ITEMS/mcl_fences/init.lua @@ -269,7 +269,16 @@ for w=1, #woods do id = wood[1].."_fence" id_gate = wood[1].."_fence_gate" end - mcl_fences.register_fence_and_fence_gate(id, wood[2], wood[3], wood[4], wood_groups, 2, 15, wood_connect, wood_sounds) + mcl_fences.register_fence_and_fence_gate( + id, + wood[2], + wood[3], + wood[4], + wood_groups, + minetest.registered_nodes["mcl_core:wood"]._mcl_hardness, + minetest.registered_nodes["mcl_core:wood"]._mcl_blast_resistance, + wood_connect, + wood_sounds) minetest.register_craft({ output = "mcl_fences:"..id.." 3", @@ -289,7 +298,15 @@ end -- Nether Brick Fence (without fence gate!) -mcl_fences.register_fence("nether_brick_fence", S("Nether Brick Fence"), "mcl_fences_fence_nether_brick.png", {pickaxey=1, deco_block=1, fence_nether_brick=1}, 2, 30, {"group:fence_nether_brick"}, mcl_sounds.node_sound_stone_defaults()) +mcl_fences.register_fence( + "nether_brick_fence", + S("Nether Brick Fence"), + "mcl_fences_fence_nether_brick.png", + {pickaxey=1, deco_block=1, fence_nether_brick=1}, + minetest.registered_nodes["mcl_nether:nether_brick"]._mcl_hardness, + minetest.registered_nodes["mcl_nether:nether_brick"]._mcl_blast_resistance, + {"group:fence_nether_brick"}, + mcl_sounds.node_sound_stone_defaults()) minetest.register_craft({ output = "mcl_fences:nether_brick_fence 6", diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr index 1044cf148..e161b5c9d 100644 --- a/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr @@ -1,18 +1,18 @@ # textdomain: mcl_fences -Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Les barrières sont des structures qui bloquent le chemin. Les barrières se connecteront les unes aux autres et aux blocs solides. Ils ne peuvent pas être sautés par un simple saut. -Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Les portillons peuvent être ouvertes ou fermées et ne peuvent pas être sautées. Les barrières se connecteront bien aux portillions. -Right-click the fence gate to open or close it.=Cliquez avec le bouton droit sur le portillon pour l'ouvrir ou la fermer. -Oak Fence=Barrière en bois de Chêne -Oak Fence Gate=Portillon en bois de Chêne -Spruce Fence=Barrière en bois de Sapin -Spruce Fence Gate=Portillon en bois de Sapin -Birch Fence=Barrière en bois de Bouleau -Birch Fence Gate=Portillon en bois de Bouleau -Jungle Fence=Barrière en bois d'Acajou -Jungle Fence Gate=Portillon en bois d'Acajou -Dark Oak Fence=Barrière en bois de Chêne Noir -Dark Oak Fence Gate=Portillon en bois de Chêne Noir -Acacia Fence=Barrière en bois d'Acacia -Acacia Fence Gate=Portillon en bois d'Acacia -Nether Brick Fence=Barrière en Brique du Nether +Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Les barrières sont des structures qui bloquent le chemin. Les barrières se connecteront les unes aux autres et aux blocs solides. Elles ne peuvent pas être sautées par un simple saut. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Les portillons peuvent être ouverts ou fermés et ne peuvent pas être sautés. Les barrières se connecteront bien aux portillons. +Right-click the fence gate to open or close it.=Cliquez avec le bouton droit sur le portillon pour l'ouvrir ou le fermer. +Oak Fence=Barrière en bois de chêne +Oak Fence Gate=Portillon en bois de chêne +Spruce Fence=Barrière en bois de sapin +Spruce Fence Gate=Portillon en bois de sapin +Birch Fence=Barrière en bois de bouleau +Birch Fence Gate=Portillon en bois de bouleau +Jungle Fence=Barrière en bois d'acajou +Jungle Fence Gate=Portillon en bois d'acajou +Dark Oak Fence=Barrière en bois de chêne noir +Dark Oak Fence Gate=Portillon en bois de chêne noir +Acacia Fence=Barrière en bois d'acacia +Acacia Fence Gate=Portillon en bois d'acacia +Nether Brick Fence=Barrière en brique du Nether Openable by players and redstone power=Ouvrable par les joueurs et la puissance redstone diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.pt_BR.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.pt_BR.tr new file mode 100644 index 000000000..69349e48b --- /dev/null +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.pt_BR.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_fences +Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Cercas são estruturas as quais bloqueiam o caminho. Cercas vão conectar umas nas outras e em blocos sólidos. Não podem ser puladas com um simples pulo. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Portões podem ser abertos ou fechados e não podem ser pulados. As cercas irão se conectar aos portões. +Right-click the fence gate to open or close it.=Clique com o botão direito no portão para abri-lo ou fecha-lo. +Oak Fence=Cerca de Carvalho +Oak Fence Gate=Portão de Carvalho +Spruce Fence=Cerca de Pinheiro +Spruce Fence Gate=Portão de Pinheiro +Birch Fence=Cerca de Bétula +Birch Fence Gate=Portão de Bétula +Jungle Fence=Cerca da Selva +Jungle Fence Gate=Portão da Selva +Dark Oak Fence=Cerca de Carvalho Escuro +Dark Oak Fence Gate=Portão de Carvalho Escuro +Acacia Fence=Cerca de Acácia +Acacia Fence Gate=Portão de Acácia +Nether Brick Fence=Cerca de Tijolos do Nether +Openable by players and redstone power=Aberto por jogadores e sinal de redstone diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.ru.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.ru.tr index bafd9ba83..bd265b9b6 100644 --- a/mods/ITEMS/mcl_fences/locale/mcl_fences.ru.tr +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.ru.tr @@ -1,18 +1,18 @@ # textdomain: mcl_fences -Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Заборы это сооружения, преграждающие путь. Блоки заборов соединяются между собой и прикрепляются к твёрдым блокам. Через них нельзя перепрыгивать одиночным прыжком. -Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Калитки могут быть открытыми и закрытыми. Их нельзя перепрыгивать. -Right-click the fence gate to open or close it.=Кликните правой по калитке, чтобы открыть или закрыть её. +Fences are structures which block the way. Fences will connect to each other and solid blocks. They cannot be jumped over with a simple jump.=Заборы это сооружения, преграждающие путь. Блоки заборов соединяются между собой и твёрдыми блоками. Через забор нельзя перепрыгнуть. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Калитки могут быть открыты и закрыты. Калитки нельзя перепрыгивать. +Right-click the fence gate to open or close it.=Кликните правой кнопкой мыши по калитке, чтобы открыть или закрыть её. Oak Fence=Дубовый забор Oak Fence Gate=Дубовая калитка Spruce Fence=Еловый забор Spruce Fence Gate=Еловая калитка Birch Fence=Берёзовый забор Birch Fence Gate=Берёзовая калитка -Jungle Fence=Забор из дерева джунглей -Jungle Fence Gate=Калитка из дерева джунглей +Jungle Fence=Забор из тропического дерева +Jungle Fence Gate=Калитка из тропического дерева Dark Oak Fence=Забор из тёмного дуба Dark Oak Fence Gate=Калитка из тёмного дуба -Acacia Fence=Забор из акации -Acacia Fence Gate=Калитка из акации +Acacia Fence=Акациевый забор +Acacia Fence Gate=Акациевая калитка Nether Brick Fence=Забор из адского кирпича -Openable by players and redstone power=Открываются игроками и сигналами редстоуна +Openable by players and redstone power=Открывается игроками и сигналом редстоуна diff --git a/mods/ITEMS/mcl_fire/README.txt b/mods/ITEMS/mcl_fire/README.txt index af46528a5..c189cbd9a 100644 --- a/mods/ITEMS/mcl_fire/README.txt +++ b/mods/ITEMS/mcl_fire/README.txt @@ -1,4 +1,4 @@ -mcl_fire: Fire mod for MineClone 2 +mcl_fire: Fire mod for VoxeLibre Based on fire from Minetest Game ================================== diff --git a/mods/ITEMS/mcl_fire/fire_charge.lua b/mods/ITEMS/mcl_fire/fire_charge.lua index 4d18e44ed..446d5878d 100644 --- a/mods/ITEMS/mcl_fire/fire_charge.lua +++ b/mods/ITEMS/mcl_fire/fire_charge.lua @@ -27,18 +27,19 @@ minetest.register_craftitem("mcl_fire:fire_charge", { end -- Ignite/light fire + local used = nil local node = get_node(pointed_thing.under) if pointed_thing.type == "node" then local nodedef = minetest.registered_nodes[node.name] if nodedef and nodedef._on_ignite then local overwrite = nodedef._on_ignite(user, pointed_thing) if not overwrite then - mcl_fire.set_fire(pointed_thing, user, false) + used = mcl_fire.set_fire(pointed_thing, user, false) end else - mcl_fire.set_fire(pointed_thing, user, false) + used = mcl_fire.set_fire(pointed_thing, user, false) end - if not minetest.is_creative_enabled(user:get_player_name()) then + if not minetest.is_creative_enabled(user:get_player_name()) and used then itemstack:take_item() end end diff --git a/mods/ITEMS/mcl_fire/flint_and_steel.lua b/mods/ITEMS/mcl_fire/flint_and_steel.lua index 39a4ce882..ca8def983 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -31,23 +31,22 @@ minetest.register_tool("mcl_fire:flint_and_steel", { {pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8}, true ) - local used = false + local used = nil if pointed_thing.type == "node" then local nodedef = minetest.registered_nodes[get_node(pointed_thing.under).name] if nodedef and nodedef._on_ignite then local overwrite = nodedef._on_ignite(user, pointed_thing) if not overwrite then - mcl_fire.set_fire(pointed_thing, user, false) + used = mcl_fire.set_fire(pointed_thing, user, false) end else - mcl_fire.set_fire(pointed_thing, user, false) + used = mcl_fire.set_fire(pointed_thing, user, false) end - used = true end if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then minetest.sound_play(idef.sound.breaks, {pos=user:get_pos(), gain=0.5}, true) end - if (not minetest.is_creative_enabled(user:get_player_name())) and used == true then + if (not minetest.is_creative_enabled(user:get_player_name())) and used then itemstack:add_wear(65535/65) -- 65 uses end return itemstack @@ -66,6 +65,12 @@ minetest.register_tool("mcl_fire:flint_and_steel", { if not minetest.is_creative_enabled("") then stack:add_wear(65535/65) -- 65 uses end + -- Ignite Campfire + elseif minetest.get_item_group(dropnode.name, "campfire") ~= 0 then + add_node(droppos, {name=dropnode.name.."_lit"}) + if not minetest.is_creative_enabled("") then + stack:add_wear(65535/65) -- 65 uses + end end return stack end, diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 70e0769c4..02fa29061 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -469,7 +469,7 @@ function mcl_fire.set_fire(pointed_thing, player, allow_on_fire) return end - add_node(pointed_thing.above, {name="mcl_fire:fire"}) + return add_node(pointed_thing.above, {name="mcl_fire:fire"}) end minetest.register_lbm({ diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.es.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.es.tr index 6f36b293c..dfef491ab 100644 --- a/mods/ITEMS/mcl_fire/locale/mcl_fire.es.tr +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.es.tr @@ -1,17 +1,19 @@ # textdomain: mcl_fire Fire Charge=Carga de fuego -Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=Las cargas de fuego son principalmente proyectiles que se pueden lanzar desde dispensadores, volarán en línea recta y estallarán en un incendio al impactar. Alternativamente, se pueden usar para encender incendios directamente. -Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=Ponga la carga de fuego en un dispensador y suminístrele poder de redstone para lanzarlo. Para encender un fuego directamente, simplemente coloque la carga de fuego en el suelo, que la usa. +Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=Las cargas de fuego son principalmente proyectiles que se pueden lanzar desde dispensadores, volarán en línea recta y estallarán en un incendio al impactar. Alternativamente, se pueden usar para encender fuegos directamente. +Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=Ponga la carga de fuego en un dispensador y suminístrele poder de redstone para lanzarla. Para encender un fuego directamente, simplemente coloque la carga de fuego en el suelo, que la usa. Flint and Steel=Mechero -Flint and steel is a tool to start fires and ignite blocks.=El mechero es una herramienta para iniciar incendios y encender bloques. -Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=Haga clic derecho en la superficie de un bloque para intentar encender un fuego frente a él o encender el bloque. Unos pocos bloques tienen una reacción única cuando se encienden. -Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=El fuego es un tipo de bloque dañino y destructivo pero de corta duración. Destruirá y se extenderá hacia bloques casi inflamables, pero el fuego desaparecerá cuando no quede nada para quemar. Se extinguirá por el agua y la lluvia cercanas. El fuego puede destruirse de manera segura golpeándolo, pero es doloroso si te paras directamente en él. Si se inicia un fuego por encima de la base o un bloque de magma, se convertirá inmediatamente en un fuego eterno. -Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=El fuego es un tipo de bloque dañino pero no destructivo de corta duración. Desaparecerá cuando no haya un bloque inflamable alrededor. El fuego no destruye bloques, al menos no en este mundo. Se extinguirá por el agua y la lluvia cercanas. El fuego puede destruirse de manera segura golpeándolo, pero es doloroso si te paras directamente en él. Si se inicia un fuego por encima de la base o un bloque de magma, se convertirá inmediatamente en un fuego eterno. +Flint and steel is a tool to start fires and ignite blocks.=El mechero es una herramienta para iniciar fuegos y encender bloques. +Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=Haga clic derecho en la superficie de un bloque para intentar encender un fuego frente a él o encender el bloque. Algunos bloques tienen una reacción única cuando se encienden. +Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=El fuego es un tipo de bloque dañino y destructivo pero de corta duración. Destruirá y se extenderá hacia bloques inflamables cercanos, pero el fuego desaparecerá cuando no quede nada para quemar. Se extinguirá por agua cercana o lluvia. El fuego puede destruirse de manera segura golpeándolo, pero es doloroso si te paras directamente en él. Si se inicia un fuego por encima de un bloque de netherrack o magma, se convertirá inmediatamente en un fuego eterno. +Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=El fuego es un tipo de bloque dañino pero no destructivo de corta duración. Desaparecerá cuando no haya un bloque inflamable alrededor. El fuego no destruye bloques, al menos no en este mundo. Se extinguirá por el agua y la lluvia cercanas. El fuego puede destruirse de manera segura golpeándolo, pero es doloroso si te paras directamente en él. Si se inicia un fuego por encima de un bloque de netherrack o magma, se convertirá inmediatamente en un fuego eterno. Eternal fire is a damaging block that might create more fire. It will create fire around it when flammable blocks are nearby. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=El fuego eterno es un bloque dañino que podría crear más fuego. Creará fuego alrededor cuando haya bloques inflamables cerca. El fuego eterno se puede extinguir con golpes y bloques de agua cercanos. Aparte del fuego (normal), el fuego eterno no se extingue por sí solo y también continúa ardiendo bajo la lluvia. Golpear el fuego eterno es seguro, pero duele si te paras dentro. Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=El fuego eterno es un bloque dañino. El fuego eterno se puede extinguir con golpes y bloques de agua cercanos. Aparte del fuego (normal), el fuego eterno no se extingue por sí solo y también continúa ardiendo bajo la lluvia. Golpear el fuego eterno es seguro, pero duele si te paras dentro. @1 has been cooked crisp.=@1 se ha cocinado crujientemente. @1 felt the burn.=@1 sintió la quemadura. @1 died in the flames.=@1 murió en las llamas. -@1 died in a fire.=@ 1 murió en un incendio. +@1 died in a fire.=@1 murió en un incendio. Fire=Fuego Eternal Fire=Fuego eterno +Dispenser projectile=Dispensador de proyectiles +Starts fires and ignites blocks=Provoca incendios y pone bloques en llamas diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.pt_BR.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.pt_BR.tr new file mode 100644 index 000000000..f14b142a1 --- /dev/null +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.pt_BR.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_fire +Fire Charge=Bola de Fogo +Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=Bolas de fogo são primariamente Projéteis aos quais podem ser lançados por ejetores, eles voarão em linha reta e explodirão em chamas no impacto. Alternativamente, elas podem ser usadas para acender fogos diretamente. +Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=Ponha a bola de fogo em um ejetor e forneça-o uma carga de redstone para lança-la. Para acender um fogo diretamente, simplesmente posicione a bola de fogo no chão, o que a consumirá. +Flint and Steel=Isqueiro +Flint and steel is a tool to start fires and ignite blocks.=Isqueiro é uma ferramenta que põe fogo e acende blocos. +Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=Clique com o botão direito na superfície de um bloco para tentar acender um fogo em frente ou acender um bloco. Poucos blocos têm uma reação única quando acesos. +Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Fogo é um tipo de bloco danoso e destrutivo de vida curta. Destruirá e se espalhará para blocos inflamáveis próximos, mas o fogo vai desaparecer quando não restar mais nada para queimar. Será extinguido por água próxima ou pela chuva. O fogo pode ser destruído em segurança socando-o, mas é doloroso se você ficar em pé diretamente nele. Se um fogo for iniciado sobre netherrack ou bloco de magma, será transformado imediatamente em fogo eterno. +Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Fogo é um tipo de bloco danoso mas não destrutivo de vida curta. Irá desaparecer quando não houver mais blocos inflamáveis por perto. O fogo não destrói blocos, pelo menos não nesse mundo. Será extinguido por água próxima ou chuva. O fogo pode ser destruído em segurança socando-o, mas é doloroso se você ficar em pé diretamente nele. Se um fogo for iniciado sobre netherrack ou bloco de magma, será transformado imediatamente em fogo eterno. +Eternal fire is a damaging block that might create more fire. It will create fire around it when flammable blocks are nearby. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Fogo eterno é um bloco danoso que pode criar mais fogo. Irá criar fogo em volta quando blocos inflamáveis estão por perto. O fogo eterno pode ser extinguido por socos ou blocos de água próximos. Diferente do fogo (normal), o fogo eterno não se extingue sozinho e também continua queimando sob chuvas. Socar o fogo eterno é seguro, mas machuca se você ficar em pé dentro. +Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Fogo eterno é um bloco danoso. O fogo eterno pode ser extinguido por socos ou blocos de água próximos. Diferente do fogo (normal), o fogo eterno não se extingue sozinho e também continua queimando sob chuvas. Socar o fogo eterno é seguro, mas machuca se você ficar em pé dentro. +@1 has been cooked crisp.=@1 foi cozido crocante. +@1 felt the burn.=@1 sentiu a queimadura. +@1 died in the flames.=@1 morreu em chamas. +@1 died in a fire.=@1 morreu em um fogo. +Fire=Fogo +Eternal Fire=Fogo Eterno +Dispenser projectile=Projétil do Ejetor +Starts fires and ignites blocks=Põe fogo e acende blocos diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.ru.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.ru.tr index 941a73aaa..957bb6b9b 100644 --- a/mods/ITEMS/mcl_fire/locale/mcl_fire.ru.tr +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.ru.tr @@ -1,19 +1,19 @@ # textdomain: mcl_fire Fire Charge=Огненный шар -Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=Огненные шары это прежде всего снаряды, которые могут быть выпущены из диспенсеров, они полетят по прямой линии и превратятся в огонь при ударе. Они также могут быть использованы для непосредственного поджигания блоков. -Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=Положите огненный шар в диспенсер и подайте на него энергию редстоуна для запуска. Чтобы непосредственно поджигать блоки, просто поместите его на поверхность. +Fire charges are primarily projectiles which can be launched from dispensers, they will fly in a straight line and burst into a fire on impact. Alternatively, they can be used to ignite fires directly.=Огненные шары это снаряды, которые могут быть выпущены из раздатчика, они полетят по прямой линии и взорвутся при столкновении. Они также могут быть использованы для непосредственного поджигания блоков. +Put the fire charge into a dispenser and supply it with redstone power to launch it. To ignite a fire directly, simply place the fire charge on the ground, which uses it up.=Положите огненный шар в раздатчик и подайте на него сигнал редстоуна для запуска. Чтобы непосредственно поджигать блоки, просто используйте его на поверхности блока. Flint and Steel=Огниво Flint and steel is a tool to start fires and ignite blocks.=Огниво это инструмент для добывания огня. -Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=Кликните правой по поверхности блока, чтобы попытаться зажечь огонь перед ней либо поджечь блок. Некоторые блоки реагируют на поджигание индивидуально. -Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Огонь - это повреждающий и разрушающий, но недолговечный блок. Он будет уничтожать и переходить на соседние легковоспламенимые блоки, но исчезнет, когда больше будет нечему гореть. Он будет погашен близлежащей водой или дождем. Его можно безопасно убрать, стукнув по нему, но если вы стоите прямо в нём, это причинит вам вред. Если огонь зажжён над адским камнем или блоком магмы, он мгновенно превращается в вечный огонь. -Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Огонь - это повреждающий, но не разрушающий и недолговечный блок. Он исчезнет, когда вокруг не останется легковоспламенимых блоков. Огонь не уничтожает блоки, по крайней мере, в этом мире. Он будет погашен близлежащей водой или дождем. Его можно безопасно убрать, стукнув по нему, но если вы стоите прямо в нём, это причинит вам вред. Если огонь зажжён над адским камнем или блоком магмы, он мгновенно превращается в вечный огонь. -Eternal fire is a damaging block that might create more fire. It will create fire around it when flammable blocks are nearby. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Вечный огонь - это повреждающий блок, который может создать больше огня. Он будет создавать огонь вокруг себя, если поблизости окажутся легковоспламенимые блоки. Вечный огонь можно потушить ударами и находящимися рядом водными блоками. В отличие от (обычного) огня, вечный огонь не гаснет сам по себе и также продолжает гореть под дождем. Бить вечный огонь безопасно, но он причиняет боль, если вы стоите внутри. -Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Вечный огонь - это повреждающий блок. Вечный огонь можно потушить ударами и находящимися рядом водными блоками. В отличие от (обычного) огня, вечный огонь не гаснет сам по себе и также продолжает гореть под дождем. Бить вечный огонь безопасно, но он причиняет боль, если вы стоите внутри. -@1 has been cooked crisp.=@1 был(а) заживо приготовлен(а). -@1 felt the burn.=@1 испытал(а) ожог. -@1 died in the flames.=@1 умер(ла) в пламени. -@1 died in a fire.=@1 умер(ла) в огне. +Rightclick the surface of a block to attempt to light a fire in front of it or ignite the block. A few blocks have an unique reaction when ignited.=Кликните правой кнопкой мыши по поверхности блока, чтобы попытаться зажечь огонь перед ним, либо поджечь сам блок. Некоторые блоки реагируют на поджигание индивидуально. +Fire is a damaging and destructive but short-lived kind of block. It will destroy and spread towards near flammable blocks, but fire will disappear when there is nothing to burn left. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Огонь это уничтожающий и поджигающий, но недолговечный блок. Он будет уничтожать и переходить на соседние воспламенимые блоки, но исчезнет, когда больше будет нечему гореть. Он будет погашен водой или дождем. Его можно безопасно убрать, ударив по нему, но если вы стоите прямо в огне, это причинит вам урон. Если огонь зажжён над адский каменем или блоком магмы, он превращается в вечный огонь. +Fire is a damaging but non-destructive short-lived kind of block. It will disappear when there is no flammable block around. Fire does not destroy blocks, at least not in this world. It will be extinguished by nearby water and rain. Fire can be destroyed safely by punching it, but it is hurtful if you stand directly in it. If a fire is started above netherrack or a magma block, it will immediately turn into an eternal fire.=Огонь это уничтожающий и поджигающий, но недолговечный блок. В этом мире огонь не уничтожает блоки. Он будет погашен водой или дождем. Его можно безопасно убрать, ударив по нему, но если вы стоите прямо в огне, это причинит вам урон. Если огонь зажжён над адский камнем или блоком магмы, он превращается в вечный огонь. +Eternal fire is a damaging block that might create more fire. It will create fire around it when flammable blocks are nearby. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Вечный огонь это поджигающий блок, который может создать еще больше огня. Он будет создавать огонь вокруг себя, если поблизости окажутся воспламенимые блоки. Вечный огонь можно потушить ударом или водой. В отличие от обычного огня, вечный огонь не гаснет сам по себе и также продолжает гореть под дождем. Бить вечный огонь безопасно, но он причиняет урон, если вы стоите внутри огня. +Eternal fire is a damaging block. Eternal fire can be extinguished by punches and nearby water blocks. Other than (normal) fire, eternal fire does not get extinguished on its own and also continues to burn under rain. Punching eternal fire is safe, but it hurts if you stand inside.=Вечный огонь это поджигающий блок. В этом мире огонь не распространяется на соседние блоки. Вечный огонь можно потушить ударом или водой. В отличие от обычного огня, вечный огонь не гаснет сам по себе и также продолжает гореть под дождем. Бить вечный огонь безопасно, но он причиняет урон, если вы стоите внутри огня. +@1 has been cooked crisp.=@1 был(а) зажарен(а) до хрустящей корочки. +@1 felt the burn.=@1 сгорел(а). +@1 died in the flames.=@1 погиб(ла) в пламени. +@1 died in a fire.=@1 погиб(ла) в огне. Fire=Огонь Eternal Fire=Вечный огонь -Dispenser projectile=Диспенсер снаряда -Starts fires and ignites blocks=Высекает огонь, поджигает блоки +Dispenser projectile=Снаряд раздатчика +Starts fires and ignites blocks=Высекает огонь и поджигает блоки diff --git a/mods/ITEMS/mcl_fireworks/README.txt b/mods/ITEMS/mcl_fireworks/README.txt index 4cf71fc9b..3202bc137 100644 --- a/mods/ITEMS/mcl_fireworks/README.txt +++ b/mods/ITEMS/mcl_fireworks/README.txt @@ -1,4 +1,4 @@ -Firework mod for Mineclone 2 +Firework mod for VoxeLibre by NO11 and and some parts by j45 diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pt_BR.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pt_BR.tr new file mode 100644 index 000000000..6b42dd610 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=Foguete +Flight Duration:=Duração de Voo: diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr index e66eb06a5..d985213b7 100644 --- a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr @@ -1,3 +1,3 @@ # textdomain: mcl_fireworks -Firework Rocket= -Flight Duration:= \ No newline at end of file +Firework Rocket=Фейерверк +Flight Duration:=Длительности полёта: \ No newline at end of file diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index 893a376f5..f381ffefc 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -1,6 +1,7 @@ --Fishing Rod, Bobber, and Flying Bobber mechanics and Bobber artwork by Rootyjr. local S = minetest.get_translator(minetest.get_current_modname()) +local FISHING_ROD_DURABILITY = 65 local bobber_ENTITY={ physical = false, @@ -38,7 +39,7 @@ local fish = function(itemstack, player, pointed_thing) local ent = nil local noent = true - local durability = 65 + local durability = FISHING_ROD_DURABILITY local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") if unbreaking > 0 then durability = durability * (unbreaking + 1) @@ -61,8 +62,8 @@ local fish = function(itemstack, player, pointed_thing) local junk_values = {10, 8.1, 6.1, 4.2} local luck_of_the_sea = math.min(mcl_enchanting.get_enchantment(itemstack, "luck_of_the_sea"), 3) local index = luck_of_the_sea + 1 - local fish_value = fish_values[index] - local junk_value = junk_values[index] + fish_value + local fish_value = fish_values[index] - mcl_luck.get_luck(ent.player) + local junk_value = junk_values[index] + fish_value - mcl_luck.get_luck(ent.player) if r <= fish_value then -- Fish items = mcl_loot.get_loot({ @@ -113,6 +114,8 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_mobitems:saddle", }, { itemstring = "mcl_flowers:waterlily", }, { itemstring = "mcl_mobitems:nautilus_shell", }, + { itemstring = "mcl_mobitems:spectre_membrane", }, + { itemstring = "mcl_mobitems:crystalline_drop", }, }, stacks_min = 1, stacks_max = 1, @@ -140,6 +143,7 @@ local fish = function(itemstack, player, pointed_thing) if not minetest.is_creative_enabled(player:get_player_name()) then local idef = itemstack:get_definition() itemstack:add_wear(65535/durability) -- 65 uses + tt.reload_itemstack_description(itemstack) -- update tooltip if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) end @@ -154,6 +158,7 @@ local fish = function(itemstack, player, pointed_thing) if not minetest.is_creative_enabled(player:get_player_name()) then local idef = itemstack:get_definition() itemstack:add_wear((65535/durability)*2) -- if so and not creative then wear double like in MC. + tt.reload_itemstack_description(itemstack) -- update tooltip if itemstack:get_count() == 0 and idef.sound and idef.sound.breaks then minetest.sound_play(idef.sound.breaks, {pos=player:get_pos(), gain=0.5}, true) end @@ -435,7 +440,7 @@ minetest.register_craftitem("mcl_fishing:fish_raw", { on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), stack_max = 64, - groups = { food=2, eatable = 2, smoker_cookable = 1 }, + groups = { food=2, eatable = 2, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 0.4, }) @@ -465,7 +470,7 @@ minetest.register_craftitem("mcl_fishing:salmon_raw", { on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), stack_max = 64, - groups = { food=2, eatable = 2, smoker_cookable = 1 }, + groups = { food=2, eatable = 2, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 0.4, }) @@ -516,7 +521,8 @@ minetest.register_craftitem("mcl_fishing:pufferfish_raw", { minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing) if itemstack:get_name() == "mcl_fishing:pufferfish_raw" then - mcl_potions.poison_func(user, 1/3, 60) + mcl_potions.give_effect_by_level("poison", user, 3, 60) + mcl_potions.give_effect_by_level("nausea", user, 2, 20) end end ) diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.fr.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.fr.tr index 2bac42bbd..0f23417c9 100644 --- a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.fr.tr +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.fr.tr @@ -2,7 +2,7 @@ Fishing Rod=Canne à pêche Fishing rods can be used to catch fish.=Les cannes à pêche peuvent être utilisées pour attraper du poisson. Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=Clic droit pour lancer le bouchon. Lorsqu'il s'enfonce, cliquez de nouveau avec le bouton droit pour rembobiner. Qui sait ce que tu vas attraper? -Raw Fish=Poisson Cru +Raw Fish=Poisson cru Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Le poisson cru est obtenu par la pêche et est un aliment qui peut être mangé en toute sécurité. La cuisson améliore sa valeur nutritive. Cooked Fish=Poisson cuit Mmh, fish! This is a healthy food item.=Mmh, poisson! Il s'agit d'un aliment sain. @@ -10,9 +10,9 @@ Raw Salmon=Saumon cru Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Le saumon cru est obtenu par la pêche et est un aliment qui peut être consommé en toute sécurité. La cuisson améliore sa valeur nutritive. Cooked Salmon=Saumon cuit This is a healthy food item which can be eaten.=Il s'agit d'un aliment sain qui peut être consommé. -Clownfish=Poisson-Clown +Clownfish=Poisson-clown Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Le poisson-clown peut être obtenu par la pêche (et la chance) et est un aliment qui peut être mangé en toute sécurité. -Pufferfish=Poisson-Globe +Pufferfish=Poisson-globe Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Le poisson-globe est une espèce de poisson commune et peut être obtenu par la pêche. Ils peuvent techniquement être mangés, mais ils sont très mauvais pour les humains. Manger un poisson-globe ne restaure que 1 point de faim et vous empoisonnera fortement (ce qui draine votre santé de manière non fatale) et provoque une grave intoxication alimentaire (qui augmente votre faim). Catches fish in water=Attrape les poissons dans l'eau Very poisonous=Très toxique diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pt_BR.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pt_BR.tr new file mode 100644 index 000000000..638858432 --- /dev/null +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pt_BR.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_fishing +Fishing Rod=Vara de Pesca +Fishing rods can be used to catch fish.=Varas de pesca podem ser usadas para coletar peixes. +Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=Clique com o botão direito para lançar a boia de pesca. Quando esta afundar clique com o botão direito novamente para enrola-la como um item. Quem sabe o que você está prestes a coletar? +Raw Fish=Peixe Cru +Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Peixe cru é obtido através da pesca e é um item de comida ao qual pode ser comido em segurança. Cozinha-lo aumenta seu valor nutricional. +Cooked Fish=Peixe Cozido +Mmh, fish! This is a healthy food item.=Mmh, peixe! Esse é um item de comida saudável. +Raw Salmon=Salmão Cru +Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Salmão cru é obtido através da pesca e é um item de comida ao qual pode ser comido em segurança. Cozinha-lo aumenta seu valor nutricional. +Cooked Salmon=Salmão Cozido +This is a healthy food item which can be eaten.=Esse é um item de comida saudável ao qual pode ser comido. +Clownfish=Peixe-Palhaço +Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Peixes-Palhaço podem ser obtidos com pesca (e sorte) e são um item de comida ao qual pode ser comido em segurança. +Pufferfish=Baiacu +Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Baiacus são uma espécie comum de peixe e podem ser obtidos através da pesca. Tecnicamente eles podem ser comidos, mas eles são muito ruins para humanos. Comer um baiacu restaura apenas 1 ponto de fome e irá lhe envenenar muito (o que drenará sua saúde de forma não-fatal) e causará uma séria intoxicação alimentar (o que aumentará sua fome). +Catches fish in water=Coleta peixes na água. +Very poisonous=Muito venenoso diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ru.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ru.tr index 9ed0e4f8d..d432d965f 100644 --- a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ru.tr +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ru.tr @@ -1,18 +1,18 @@ # textdomain: mcl_fishing Fishing Rod=Удочка -Fishing rods can be used to catch fish.=Удочка используется при ловле рыбы. -Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=Кликните правой для запуска поплавка. Когда он потонет, кликните снова, чтобы вытащить ваш улов. Кстати, что вы собираетесь поймать? -Raw Fish=Сырая рыба -Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Сырая рыба добывается при помощи удочки и это продукт, который можно безопасно есть. При приготовлении её питательная ценность растёт. -Cooked Fish=Приготовленная рыба -Mmh, fish! This is a healthy food item.=Ммм, рыба! Это продуктовый предмет здорового питания. +Fishing rods can be used to catch fish.=Удочка используется для ловли рыбы. +Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=Кликните правой кнопкой мыши чтобы закинуть поплавок. Когда он потонет, кликните снова, чтобы вытащить ваш улов. Кто знает что вам может попасться? +Raw Fish=Сырая треска +Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Сырая треска добывается при помощи удочки и это съедобный продукт. После приготовлении её питательная ценность растёт. +Cooked Fish=Приготовленная треска +Mmh, fish! This is a healthy food item.=Ммм, рыба! Это съедобный продукт. Raw Salmon=Сырой лосось -Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Сырой лосось добывается при помощи удочки и это продукт, который можно безопасно есть. При приготовлении его питательная ценность растёт. +Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Сырой лосось добывается при помощи удочки и это съедобный продукт. При приготовлении его питательная ценность растёт. Cooked Salmon=Приготовленный лосось -This is a healthy food item which can be eaten.=Это продуктовый предмет здорового питания. +This is a healthy food item which can be eaten.=Это съедобный продукт. Clownfish=Тропическая рыба -Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Тропическая рыба добывается при помощи удочки (и удачи) и это продукт, который можно безопасно есть. +Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Тропическая рыба добывается при помощи удочки (и удачи) и это съедобный продукт. Pufferfish=Иглобрюх -Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Иглобрюхи - распространенный вид рыбы и могут быть пойманы на удочку. Технически их можно есть, но они очень вредны для людей. Употребление иглобрюха в пищу восстанавливает всего 1 очко голода, но отравит вас очень тяжело (несмертельно уменьшит ваше здоровье), вы получите серьёзное пищевое отравление (которое увеличивает голод). +Pufferfish are a common species of fish and can be obtained by fishing. They can technically be eaten, but they are very bad for humans. Eating a pufferfish only restores 1 hunger point and will poison you very badly (which drains your health non-fatally) and causes serious food poisoning (which increases your hunger).=Иглобрюх - распространенный вид рыбы, который может быть пойман на удочку. Технически их можно есть, но они очень ядовиты. Употребление иглобрюха в пищу восстанавливает всего 1 очко голода, но сильно отравит вас (несмертельно уменьшит ваше здоровье) и даст сильное пищевое отравление (которое увеличивает голод). Catches fish in water=Ловит рыбу в воде Very poisonous=Очень ядовит diff --git a/mods/ITEMS/mcl_fishing/mod.conf b/mods/ITEMS/mcl_fishing/mod.conf index 71bde6146..1af715aaf 100644 --- a/mods/ITEMS/mcl_fishing/mod.conf +++ b/mods/ITEMS/mcl_fishing/mod.conf @@ -1,3 +1,3 @@ name = mcl_fishing description = Adds fish and fishing poles to go fishing. -depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors, mcl_buckets +depends = mcl_core, mcl_sounds, mcl_loot, mcl_mobs, mcl_enchanting, mcl_throwing, mcl_colors, mcl_buckets, mcl_luck diff --git a/mods/ITEMS/mcl_fletching_table/README.md b/mods/ITEMS/mcl_fletching_table/README.md index a30e2c1b4..e6b41a7a5 100644 --- a/mods/ITEMS/mcl_fletching_table/README.md +++ b/mods/ITEMS/mcl_fletching_table/README.md @@ -2,7 +2,7 @@ mcl_fletching_table ------------------- Fletching Tables, by PrairieWind -Adds Fletching Tables to MineClone 2/5. +Adds Fletching Tables to VoxeLibre. License of source code ---------------------- diff --git a/mods/ITEMS/mcl_fletching_table/init.lua b/mods/ITEMS/mcl_fletching_table/init.lua index 7cb66f8b1..7392e1e8f 100644 --- a/mods/ITEMS/mcl_fletching_table/init.lua +++ b/mods/ITEMS/mcl_fletching_table/init.lua @@ -23,4 +23,10 @@ minetest.register_craft({ { "group:wood", "group:wood", "" }, { "group:wood", "group:wood", "" }, } -}) \ No newline at end of file +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_fletching_table:fletching_table", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.pt_BR.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.pt_BR.tr new file mode 100644 index 000000000..a2b7e38b5 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table=Bancada de Arco e Flecha +A fletching table=Uma bancada de arco e flecha +This is the fletcher villager's work station. It currently has no use beyond decoration.=Essa é a estação de trabalho do aldeão flecheiro. Atualmente não possui usos além de decoração. diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ru.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ru.tr new file mode 100644 index 000000000..d44a333ac --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table=Стол лучника +A fletching table=Стол лучника +This is the fletcher villager's work station. It currently has no use beyond decoration.=Это рабочее место жителя лучника. На данный момент не имеет применения помимо декоративного. \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr index 362b96c57..067eded9b 100644 --- a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr @@ -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. 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 +Cherry Sapling Flower Pot=Pousse de Cerisier en pot diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pt_BR.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pt_BR.tr new file mode 100644 index 000000000..563e252c3 --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pt_BR.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_flowerpots +Dandelion Flower Pot=Vaso com Dente-de-Leão +Poppy Flower Pot=Vaso com Papoula +Blue Orchid Flower Pot=Vaso com Orquídea Azul +Allium Flower Pot=Vaso com Alho Silvestre +Azure Bluet Flower Pot=Vaso com Flor Silvestre Azul +Red Tulip Flower Pot=Vaso com Tulipa Vermelha +Pink Tulip Flower Pot=Vaso com Tulipa Rose +White Tulip Flower Pot=Vaso com Tulipa Branca +Orange Tulip Flower Pot=Vaso com Tulipa Laranja +Oxeye Daisy Flower Pot=Vaso com Margarida +Brown Mushroom Flower Pot=Vaso com Cogumelo Marrom +Red Mushroom Flower Pot=Vaso com Cogumelo Vermelho +Oak Sapling Flower Pot=Vaso com Muda de Carvalho +Acacia Sapling Flower Pot=Vaso com Muda de Acácia +Jungle Sapling Flower Pot=Vaso com Muda da Selva +Dark Oak Sapling Flower Pot=Vaso com Muda de Carvalho Escuro +Spruce Sapling Flower Pot=Vaso com Muda de Pinheiro +Birch Sapling Flower Pot=Vaso com Muda de Bétula +Dead Bush Flower Pot=Vaso com Arbusto Morto +Fern Flower Pot=Vaso com Samambaia +Cactus Flower Pot=Vaso com Cacto +Flower Pot=Vaso +Flower pots are decorative blocks in which flowers and other small plants can be placed.=Vasos são blocos decorativos aos quais flores e plantas pequenas podem ser posicionadas. +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.=Apenas posicione uma planta no vaso. Vasos podem segurar flores pequenas (não mais altas que 1 bloco), mudas, samambaias, arbustos mortos, cogumelos e cactos. Clique com o botão direito em uma planta envasada para recolher a planta. +Can hold a small flower or plant=Pode segurar uma flor ou planta pequenas +Cherry Sapling Flower Pot=Vaso com Muda de Cerejeira diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ru.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ru.tr index 6bb6be923..8ee6ddc26 100644 --- a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ru.tr +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ru.tr @@ -3,24 +3,25 @@ Dandelion Flower Pot=Одуванчик в горшке Poppy Flower Pot=Мак в горшке Blue Orchid Flower Pot=Голубая орхидея в горшке Allium Flower Pot=Лук в горшке -Azure Bluet Flower Pot=Хоустония Альба в горшке +Azure Bluet Flower Pot=Хаустония серая в горшке Red Tulip Flower Pot=Красный тюльпан в горшке Pink Tulip Flower Pot=Розовый тюльпан в горшке White Tulip Flower Pot=Белый тюльпан в горшке Orange Tulip Flower Pot=Оранжевый тюльпан в горшке -Oxeye Daisy Flower Pot=Нивяник обыкновенный в горшке +Oxeye Daisy Flower Pot=Нивяник в горшке Brown Mushroom Flower Pot=Коричневый гриб в горшке Red Mushroom Flower Pot=Красный гриб в горшке Oak Sapling Flower Pot=Саженец дуба в горшке Acacia Sapling Flower Pot=Саженец акации в горшке -Jungle Sapling Flower Pot=Саженец дерева джунглей в горшке +Jungle Sapling Flower Pot=Саженец тропического дерева в горшке Dark Oak Sapling Flower Pot=Саженец тёмного дуба в горшке Spruce Sapling Flower Pot=Саженец ели в горшке Birch Sapling Flower Pot=Саженец берёзы в горшке Dead Bush Flower Pot=Мёртвый куст в горшке -Fern Flower Pot=Цветок папоротника в горшке +Fern Flower Pot=Папоротник в горшке Cactus Flower Pot=Кактус в горшке Flower Pot=Цветочный горшок Flower pots are decorative blocks in which flowers and other small plants can be placed.=Цветочные горшки это декоративные блоки, в которые можно посадить цветы и другие небольшие растения. 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.=Просто поместите растение в цветочный горшок. Цветочные горшки могут выдержать небольшие цветы (не выше 1 блока), саженцы, папоротники, мёртвые кусты, грибы и кактусы. Кликните правой по горшёчному растению, чтобы вытащить его из горшка. -Can hold a small flower or plant=Можно использовать для высадки небольшого растения или цветка +Can hold a small flower or plant=Можно использовать, чтобы посадить растение или цветок +Cherry Sapling Flower Pot=Саженец вишнёвого дерева в горшке \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index e89d01b65..85a65a165 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -128,8 +128,6 @@ local fortune_wheat_seed_drop = { overwrite = true, } --- CHECKME: How does tall grass behave when pushed by a piston? - --- Tall Grass --- local def_tallgrass = { description = S("Tall Grass"), @@ -155,7 +153,7 @@ local def_tallgrass = { groups = { handy = 1, shearsy = 1, attached_node = 1, deco_block = 1, plant = 1, place_flowerlike = 2, non_mycelium_plant = 1, - flammable = 3, fire_encouragement = 60, fire_flammability = 100, + flammable = 3, fire_encouragement = 60, fire_flammability = 10, dig_by_piston = 1, dig_by_water = 1, destroy_by_lava_flow = 1, compostability = 30, grass_palette = 1 }, sounds = mcl_sounds.node_sound_leaves_defaults(), @@ -185,6 +183,39 @@ def_fern.groups.compostability = 65 minetest.register_node("mcl_flowers:fern", def_fern) + +--- Clover --- +-- Similar deal as fern, we can copy a lot from tall grass +local def_clover = table.copy(def_tallgrass) +def_clover.description = S("Clover") +def_clover._doc_items_longdesc = S("Clovers are small plants which occur naturally in plains and other temperate biomes. They can be picked up and planted again.") +def_clover.drawtype = "mesh" +def_clover.mesh = "mcl_clover_3leaf.obj" +def_clover.tiles = { "mcl_flowers_clover.png" } +def_clover.inventory_image = "mcl_flowers_clover_inv.png" +def_clover.wield_image = "mcl_flowers_clover_inv.png" +def_clover.use_texture_alpha = "clip" +def_clover.drop = "mcl_flowers:clover" +def_clover.selection_box = { + type = "fixed", + fixed = { -4/16, -0.5, -4/16, 4/16, 0, 4/16 }, +} +def_clover.groups.compostability = 30 + +minetest.register_node("mcl_flowers:clover", def_clover) + +local def_4l_clover = table.copy(def_clover) +def_4l_clover.description = S("Four-leaf Clover") +def_4l_clover._doc_items_longdesc = S("Clovers are small plants which occur naturally in plains and other temperate biomes. They can be picked up and planted again.") +def_4l_clover.mesh = "mcl_clover_4leaf.obj" +def_4l_clover.tiles = { "mcl_flowers_fourleaf_clover.png" } +def_4l_clover.inventory_image = "mcl_flowers_fourleaf_clover_inv.png" +def_4l_clover.wield_image = "mcl_flowers_fourleaf_clover_inv.png" +def_4l_clover.use_texture_alpha = "clip" +def_4l_clover.drop = "mcl_flowers:fourleaf_clover" + +minetest.register_node("mcl_flowers:fourleaf_clover", def_4l_clover) + if has_mcl_flowerpots then mcl_flowerpots.register_potted_flower("mcl_flowers:fern", { name = "fern", @@ -194,7 +225,7 @@ if has_mcl_flowerpots then }) end -local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_img, selbox_radius, selbox_top_height, drop, shears_drop, is_flower, grass_color, fortune_drop) +local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_img, selbox_radius, selbox_top_height, drop, shears_drop, is_flower, grass_color, fortune_drop, mesh) if not inv_img then inv_img = top_img end @@ -238,13 +269,28 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im drop_top = drop drop_bottom = drop end + -- Sunflower mesh and tiles + local top_drawtype, bottom_drawtype + local alpha = nil + local bottom_tiles = {} + if not mesh then + top_drawtype = "plantlike" + bottom_drawtype = "plantlike" + table.insert(bottom_tiles, bottom_img) + else + top_drawtype = "airlike" + bottom_drawtype = "mesh" + bottom_tiles = bottom_img + alpha = "clip" + end + -- Bottom minetest.register_node("mcl_flowers:"..name, { description = desc, _doc_items_create_entry = create_entry, _doc_items_longdesc = longdesc, _doc_items_usagehelp = plant_usage_help, - drawtype = "plantlike", - tiles = { bottom_img }, + drawtype = bottom_drawtype, + tiles = bottom_tiles, inventory_image = inv_img, wield_image = inv_img, sunlight_propagates = true, @@ -252,11 +298,12 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im paramtype2 = paramtype2, palette = palette, walkable = false, - buildable_to = true, + buildable_to = false, drop = drop_bottom, _mcl_shears_drop = shears_drop, _mcl_fortune_drop = fortune_drop, node_placement_prediction = "", + use_texture_alpha = alpha, selection_box = { type = "fixed", fixed = { -selbox_radius, -0.5, -selbox_radius, selbox_radius, 0.5, selbox_radius }, @@ -336,6 +383,7 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im end, groups = bottom_groups, sounds = mcl_sounds.node_sound_leaves_defaults(), + mesh = mesh }) local top_groups = table.copy(bottom_groups) @@ -347,14 +395,15 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im minetest.register_node("mcl_flowers:"..name.."_top", { description = desc.." " .. S("(Top Part)"), _doc_items_create_entry = false, - drawtype = "plantlike", + drawtype = top_drawtype, tiles = { top_img }, sunlight_propagates = true, paramtype = "light", paramtype2 = paramtype2, palette = palette, walkable = false, - buildable_to = true, + buildable_to = false, + use_texture_alpha = alpha, selection_box = { type = "fixed", fixed = { -selbox_radius, -0.5, -selbox_radius, selbox_radius, selbox_top_height, selbox_radius }, @@ -384,9 +433,7 @@ end add_large_plant("peony", S("Peony"), S("A peony is a large plant which occupies two blocks. It is mainly used in dye production."), "mcl_flowers_double_plant_paeonia_bottom.png", "mcl_flowers_double_plant_paeonia_top.png", nil, 5/16, 6/16) add_large_plant("rose_bush", S("Rose Bush"), S("A rose bush is a large plant which occupies two blocks. It is safe to touch it. Rose bushes are mainly used in dye production."), "mcl_flowers_double_plant_rose_bottom.png", "mcl_flowers_double_plant_rose_top.png", nil, 5/16, 1/16) add_large_plant("lilac", S("Lilac"), S("A lilac is a large plant which occupies two blocks. It is mainly used in dye production."), "mcl_flowers_double_plant_syringa_bottom.png", "mcl_flowers_double_plant_syringa_top.png", nil, 5/16, 6/16) - --- TODO: Make the sunflower face East. Requires a mesh for the top node. -add_large_plant("sunflower", S("Sunflower"), S("A sunflower is a large plant which occupies two blocks. It is mainly used in dye production."), "mcl_flowers_double_plant_sunflower_bottom.png", "mcl_flowers_double_plant_sunflower_top.png^mcl_flowers_double_plant_sunflower_front.png", "mcl_flowers_double_plant_sunflower_front.png", 6/16, 6/16) +add_large_plant("sunflower", S("Sunflower"), S("A sunflower is a large plant which occupies two blocks. It is mainly used in dye production."), {"mcl_flowers_double_plant_sunflower_bottom.png", "mcl_flowers_double_plant_sunflower_bottom.png", "mcl_flowers_double_plant_sunflower_front.png", "mcl_flowers_double_plant_sunflower_back.png"}, nil, "mcl_flowers_double_plant_sunflower_front.png", 6/16, 6/16, "mcl_flowers:sunflower", nil, true, nil, nil, "mcl_flowers_sunflower.obj") local longdesc_grass = S("Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.") local longdesc_fern = S("Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.") diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pt_BR.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pt_BR.tr new file mode 100644 index 000000000..dcd5b5a14 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pt_BR.tr @@ -0,0 +1,35 @@ +# textdomain: mcl_flowers +This is a small flower. Small flowers are mainly used for dye production and can also be potted.=Isso é uma flor pequena. Flores pequenas são majoritariamente usadas para a produção de corantes e também podem ser envasadas. +It can only be placed on a block on which it would also survive.=Apenas pode ser posicionada em um bloco ao qual vai sobreviver. +Poppy=Papoula +Dandelion=Dente-de-Leão +Oxeye Daisy=Margarida +Orange Tulip=Tulipa Laranja +Pink Tulip=Tulipa Rosa +Red Tulip=Tulipa Vermelha +White Tulip=Tulipa Branca +Allium=Alho Silvestre +Azure Bluet=Flor Silvestre Azul +Blue Orchid=Orquídea Azul +Wither Rose=Flor do Wither +Lily of the Valley=Lírio do Vale +Cornflower=Centáurea +Tall Grass=Grama Alta +Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Grama alta é uma planta pequena que muitas vezes ocorre na superfície de gramados. Pode ser colhida para obter sementes de trigo. Usando farinha de osso, a grama alta pode ser transformada em grama alta dupla a qual têm dois blocos de altura. +Fern=Samambaia +Ferns are small plants which occur naturally in jungles and taigas. They can be harvested for wheat seeds. By using bone meal, a fern can be turned into a large fern which is two blocks high.=Samambaias são plantas pequenas que ocorrem naturalmente em selvas e taigas. Podem ser colhidas para obter sementes de trigo. Usando farinha de osso, uma samambaia pode ser transformada em uma samambaia grande a qual têm dois blocos de altura. +(Top Part)=(Parte de Cima) +Peony=Peônia +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Uma peônia é uma planta alta que ocupa dois blocos. É majoritariamente usada para a produção de corante. +Rose Bush=Roseira +A rose bush is a large plant which occupies two blocks. It is safe to touch it. Rose bushes are mainly used in dye production.=Uma roseira é uma planta alta que ocupa dois blocos. É seguro tocá-la. Roseiras são majoritariamente usadas para a produção de corante. +Lilac=Lilás +A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=Uma lilás é uma planta alta que ocupa dois blocos. É majoritariamente usada para a produção de corante. +Sunflower=Girassol +A sunflower is a large plant which occupies two blocks. It is mainly used in dye production.=Um girassol é uma planta alta que ocupa dois blocos. É majoritariamente usada para a produção de corante. +Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.=Grama alta dupla é uma variante da grama alta e ocupa dois blocos. Pode ser colhida para obter sementes de trigo. +Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.=Samambaia grande é uma variante da samambaia e ocupa dois blocos. Pode ser colhida para obter sementes de trigo. +Double Tallgrass=Grama Alta Dupla +Large Fern=Samambaia Grande +Lily Pad=Vitória-Régia +A lily pad is a flat plant block which can be walked on. They can be placed on water sources, ice and frosted ice.=Uma vitória-régia é um bloco de planta plano que pode ser pisado. Podem ser posicionadas em fontes de água, gelo e gelo fosco. diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ru.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ru.tr index f5cb5e18d..7f1ff3eef 100644 --- a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ru.tr +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ru.tr @@ -1,16 +1,19 @@ # textdomain: mcl_flowers -This is a small flower. Small flowers are mainly used for dye production and can also be potted.=Это небольшой цветок. Такие цветы в основном используются для производства красителей. Их можно садить в горшки. -It can only be placed on a block on which it would also survive.=Его можно высаживать только на те блоки, на которых он может расти. +This is a small flower. Small flowers are mainly used for dye production and can also be potted.=Это небольшой цветок. Такие цветы в основном используются для производства красителей. Их можно посадить в горшки. +It can only be placed on a block on which it would also survive.=Это можно высаживать только на те блоки, на которых оно может расти. Poppy=Мак Dandelion=Одуванчик -Oxeye Daisy=Нивяник обыкновенный +Oxeye Daisy=Нивяник Orange Tulip=Оранжевый тюльпан Pink Tulip=Розовый тюльпан Red Tulip=Красный тюльпан White Tulip=Белый тюльпан Allium=Лук -Azure Bluet=Хоустония Альба +Azure Bluet=Хаустония серая Blue Orchid=Голубая орхидея +Wither Rose=Роза иссушения +Lily of the Valley=Ландыш +Cornflower=Василёк Tall Grass=Высокая трава Tall grass is a small plant which often occurs on the surface of grasslands. It can be harvested for wheat seeds. By using bone meal, tall grass can be turned into double tallgrass which is two blocks high.=Высокая трава это маленькое растение, часто встречающееся на поверхности лугов. Их можно собирать, добывая семена пшеницы. С помощью костной муки высокая трава может быть превращена в двойную высокую траву (2 блока в высоту). Fern=Папоротник @@ -28,5 +31,5 @@ Double tallgrass a variant of tall grass and occupies two blocks. It can be harv Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.=Большой папоротник - вид папоротника, занимающий два блока. Его можно собирать, добывая семена пшеницы. Double Tallgrass=Двойная высокая трава Large Fern=Большой папоротник -Lily Pad=Лилия -A lily pad is a flat plant block which can be walked on. They can be placed on water sources, ice and frosted ice.=Лилия это плоский растительный блок, по которому можно ходить. Он размещается на водных источниках, а также на льду и замороженном льду. +Lily Pad=Кувшинка +A lily pad is a flat plant block which can be walked on. They can be placed on water sources, ice and frosted ice.=Кувшинка это плоский растительный блок, по которому можно ходить. Он размещается на водных источниках, а также на льду и замороженном льду. diff --git a/mods/ITEMS/mcl_flowers/models/mcl_clover_3leaf.obj b/mods/ITEMS/mcl_flowers/models/mcl_clover_3leaf.obj new file mode 100644 index 000000000..57c0d5a3a --- /dev/null +++ b/mods/ITEMS/mcl_flowers/models/mcl_clover_3leaf.obj @@ -0,0 +1,38 @@ +# Blender 3.6.7 +# www.blender.org +mtllib mcl_clover_3leaf.mtl +o Plane +v 0.000000 -0.280000 0.000000 +v 0.000000 -0.280000 0.000000 +v -0.250000 -0.280000 -0.250000 +v 0.250000 -0.280000 -0.250000 +v 0.035355 -0.500000 0.035355 +v 0.035355 -0.300000 0.035355 +v -0.035355 -0.500000 -0.035355 +v -0.035355 -0.300000 -0.035355 +v 0.035355 -0.500000 -0.035355 +v 0.035355 -0.300000 -0.035355 +v -0.035355 -0.500000 0.035355 +v -0.035355 -0.300000 0.035355 +v -0.091506 -0.280000 0.341506 +v -0.341506 -0.280000 -0.091506 +v 0.000000 -0.280000 0.000000 +v 0.341506 -0.280000 -0.091506 +v 0.091506 -0.280000 0.341506 +vn -0.0000 1.0000 -0.0000 +vn -0.7071 -0.0000 0.7071 +vn 0.7071 -0.0000 0.7071 +vt 0.500000 0.437500 +vt 1.000000 0.937500 +vt 0.000000 0.937500 +vt 0.437500 0.062500 +vt 0.562500 0.062500 +vt 0.562500 0.437500 +vt 0.437500 0.437500 +s 0 +usemtl Material.001 +f 2/1/1 4/2/1 3/3/1 +f 5/4/2 6/5/2 8/6/2 7/7/2 +f 9/4/3 10/5/3 12/6/3 11/7/3 +f 1/1/1 14/2/1 13/3/1 +f 15/1/1 17/2/1 16/3/1 diff --git a/mods/ITEMS/mcl_flowers/models/mcl_clover_4leaf.obj b/mods/ITEMS/mcl_flowers/models/mcl_clover_4leaf.obj new file mode 100644 index 000000000..3662f5f99 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/models/mcl_clover_4leaf.obj @@ -0,0 +1,32 @@ +# Blender 3.6.7 +# www.blender.org +mtllib mcl_clover_4leaf.mtl +o Plane +v -0.250000 -0.280000 0.250000 +v 0.250000 -0.280000 0.250000 +v -0.250000 -0.280000 -0.250000 +v 0.250000 -0.280000 -0.250000 +v 0.035355 -0.500000 0.035355 +v 0.035355 -0.300000 0.035355 +v -0.035355 -0.500000 -0.035355 +v -0.035355 -0.300000 -0.035355 +v 0.035355 -0.500000 -0.035355 +v 0.035355 -0.300000 -0.035355 +v -0.035355 -0.500000 0.035355 +v -0.035355 -0.300000 0.035355 +vn -0.0000 1.0000 -0.0000 +vn -0.7071 -0.0000 0.7071 +vn 0.7071 -0.0000 0.7071 +vt 0.000000 0.125000 +vt 0.875000 0.125000 +vt 0.875000 1.000000 +vt 0.000000 1.000000 +vt 0.875000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.375000 +vt 0.875000 0.375000 +s 0 +usemtl Material.001 +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/5/3 10/6/3 12/7/3 11/8/3 diff --git a/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.mtl b/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.mtl new file mode 100644 index 000000000..1a72d010b --- /dev/null +++ b/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.mtl @@ -0,0 +1,32 @@ +# Blender 3.6.4 MTL File: 'sunflower.blend' +# www.blender.org + +newmtl Flower_1 +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd C:/Minetest-5.8/games/mineclone2/textures/mcl_flowers_double_plant_sunflower_front.png + +newmtl Flower_2 +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd C:/Minetest-5.8/games/mineclone2/textures/mcl_flowers_double_plant_sunflower_back.png + +newmtl Stem +Ns 250.000000 +Ka 1.000000 1.000000 1.000000 +Ks 0.500000 0.500000 0.500000 +Ke 0.000000 0.000000 0.000000 +Ni 1.450000 +d 1.000000 +illum 2 +map_Kd C:/Minetest-5.8/games/mineclone2/textures/mcl_flowers_double_plant_sunflower_bottom.png diff --git a/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.obj b/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.obj new file mode 100644 index 000000000..fb9dfc7cf --- /dev/null +++ b/mods/ITEMS/mcl_flowers/models/mcl_flowers_sunflower.obj @@ -0,0 +1,59 @@ +# Blender 3.6.4 +# www.blender.org +mtllib mcl_flowers_sunflower.mtl +o Stem_1 +v 0.381859 1.050000 0.309359 +v -0.236859 1.050000 -0.309359 +v 0.381859 -0.500000 0.309359 +v -0.236859 -0.500000 -0.309359 +vn -0.7071 -0.0000 0.7071 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +s 0 +g Stem_1_Stem +usemtl Stem +f 1/1/1 2/2/1 4/3/1 3/4/1 +o Stem_2 +v -0.236859 1.050000 0.309359 +v 0.381859 1.050000 -0.309359 +v -0.236859 -0.500000 0.309359 +v 0.381859 -0.500000 -0.309359 +vn -0.7071 -0.0000 -0.7071 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +s 0 +g Stem_2_Stem +usemtl Stem +f 5/5/2 6/6/2 8/7/2 7/8/2 +o Flower_1 +v 0.247500 1.433013 -0.500000 +v -0.252500 0.766987 -0.500000 +v 0.247500 1.433013 0.500000 +v -0.252500 0.766987 0.500000 +vn -0.8660 0.5000 -0.0000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +s 0 +g Flower_1_Flower_1 +usemtl Flower_1 +f 9/9/3 10/10/3 12/11/3 11/12/3 +o Flower_2 +v 0.252500 1.432013 -0.500000 +v -0.247500 0.765988 -0.500000 +v 0.252500 1.432013 0.500000 +v -0.247500 0.765988 0.500000 +vn -0.8660 0.5000 -0.0000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +s 0 +g Flower_2_Flower_2 +usemtl Flower_2 +f 13/13/4 14/14/4 16/15/4 15/16/4 diff --git a/mods/ITEMS/mcl_furnaces/README.md b/mods/ITEMS/mcl_furnaces/README.md index c7282124b..00a5f8fdb 100644 --- a/mods/ITEMS/mcl_furnaces/README.md +++ b/mods/ITEMS/mcl_furnaces/README.md @@ -1,4 +1,4 @@ -Furnaces for MineClone 2. +Furnaces for VoxeLibre. Heavily based on Minetest Game (default/furnace.lua). License of source code @@ -9,4 +9,4 @@ Modified by Wuzzy. License of media ---------------- -See the main MineClone 2 README.md file. +See the main VoxeLibre README.md file. diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index 8cb8ad5a0..704848656 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -1,67 +1,92 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 +mcl_furnaces = {} + -- -- Formspecs -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Furnace"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Furnace"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +96,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -108,7 +133,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -303,7 +328,7 @@ local function furnace_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = cooked.time ~= 0 if cookable then -- Successful cooking requires space in dst slot and time @@ -321,7 +346,7 @@ local function furnace_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -356,7 +381,7 @@ local function furnace_node_timer(pos, elapsed) if srclist[1]:get_name() == "mcl_sponges:sponge_wet" then inv:set_stack("fuel", 1, "mcl_buckets:bucket_water") fuellist = inv:get_list("fuel") - -- Also for river water + -- Also for river water elseif srclist[1]:get_name() == "mcl_sponges:sponge_wet_river_water" then inv:set_stack("fuel", 1, "mcl_buckets:bucket_river_water") fuellist = inv:get_list("fuel") @@ -366,7 +391,7 @@ local function furnace_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -413,15 +438,40 @@ local function furnace_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) return result 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", nil, 1) + else + return inv, "fuel", mcl_util.select_stack(hop_inv, hop_list, inv, "fuel", mcl_util.is_fuel, 1) + end +end + local on_rotate, after_rotate_active if minetest.get_modpath("screwdriver") then on_rotate = screwdriver.rotate_simple @@ -440,11 +490,11 @@ minetest.register_node("mcl_furnaces:furnace", { _tt_help = S("Uses fuel to smelt or cook items"), _doc_items_longdesc = S("Furnaces cook or smelt several items, using a furnace fuel, into something else."), _doc_items_usagehelp = - S("Use the furnace to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The furnace will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."), + S("Use the furnace to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The furnace will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "default_furnace_top.png", "default_furnace_bottom.png", @@ -452,7 +502,7 @@ minetest.register_node("mcl_furnaces:furnace", { "default_furnace_side.png", "default_furnace_front.png" }, 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, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -462,10 +512,11 @@ minetest.register_node("mcl_furnaces:furnace", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -514,6 +565,11 @@ minetest.register_node("mcl_furnaces:furnace", { _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, 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", { @@ -528,7 +584,7 @@ minetest.register_node("mcl_furnaces:furnace_active", { paramtype = "light", light_source = LIGHT_ACTIVE_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, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = furnace_node_timer, @@ -538,10 +594,11 @@ minetest.register_node("mcl_furnaces:furnace_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -567,13 +624,15 @@ minetest.register_node("mcl_furnaces:furnace_active", { _mcl_hardness = 3.5, on_rotate = on_rotate, 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({ output = "mcl_furnaces:furnace", recipe = { { "group:cobble", "group:cobble", "group:cobble" }, - { "group:cobble", "", "group:cobble" }, + { "group:cobble", "", "group:cobble" }, { "group:cobble", "group:cobble", "group:cobble" }, } }) @@ -586,7 +645,7 @@ end minetest.register_lbm({ label = "Active furnace flame particles", name = "mcl_furnaces:flames", - nodenames = {"mcl_furnaces:furnace_active"}, + nodenames = { "mcl_furnaces:furnace_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pt_BR.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pt_BR.tr new file mode 100644 index 000000000..e7e02f52b --- /dev/null +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pt_BR.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_furnaces +Furnace=Fornalha +Furnaces cook or smelt several items, using a furnace fuel, into something else.=Fornalhas cozinham ou derretem vários itens, usando um combustível de fornalha,para transformá=los em outras coisas. +Use the furnace to open the furnace menu.=Use a fornalha para abrir o menu da fornalha. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Posicione um combustível de fornalha no slot mais baixo e o material fonte no slot acima. +The furnace will slowly use its fuel to smelt the item.=A fornalha irá usar lentamente seu combustível para derreter o item. +The result will be placed into the output slot at the right side.=O resultado será posicionado no slot de saída no lado direito. +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Use o livro de receitas para ver o que você pode derreter, o que você pode usar como combustível e por quanto tempo irá queimar. +Burning Furnace=Fornalha Queimando +Recipe book=Livro de receitas +Inventory=Inventário +Uses fuel to smelt or cook items=Usa combustível para derreter ou cozinhar itens diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ru.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ru.tr index 1ba8732df..ab01ce701 100644 --- a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ru.tr +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ru.tr @@ -1,9 +1,12 @@ # textdomain: mcl_furnaces Furnace=Печь -Furnaces cook or smelt several items, using a furnace fuel, into something else.=В печи готовят или переплавляют предметы, но для этого требуется загрузить топливо. -Use the furnace to open the furnace menu. Place a furnace fuel in the lower slot and the source material in the upper slot. The furnace will slowly use its fuel to smelt the item. The result will be placed into the output slot at the right side.=[Используйте] печь, чтобы открыть её меню. Положите печное топливо в нижний отсек, а материал-источник в верхний. Печь будет понемногу расходовать топливо для переплавки предмета. Получившийся в результате предмет будет помещён в выходной отсек справа. -Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Используйте книгу рецептов, чтобы узнать, что вы можете переплавить в печи, что сгодится в качестве топлива и как долго будет идти процесс. +Furnaces cook or smelt several items, using a furnace fuel, into something else.=В печи готовят или переплавляют предметы, с помощью топлива. +Use the furnace to open the furnace menu.=Используйте печь, чтобы открыть её меню. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Положите топливо в нижний слот и материал в верхний. +The furnace will slowly use its fuel to smelt the item.=Печь будет медленно использовать топливо, чтобы переплавить предмет. +The result will be placed into the output slot at the right side.=Результат будет помещен в выходной слот с правой стороны. +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Используйте книгу рецептов, чтобы узнать, что вы можете переплавить в печи, что можно использовать как топливо и как долго оно будет гореть. Burning Furnace=Горящая печь Recipe book=Книга рецептов Inventory=Инвентарь -Uses fuel to smelt or cook items=Расходует топливо для приготовления или переплавки предметов +Uses fuel to smelt or cook items=Расходует топливо для приготовления или переплавки предметов \ No newline at end of file diff --git a/mods/ITEMS/mcl_grindstone/init.lua b/mods/ITEMS/mcl_grindstone/init.lua index 00c373536..f3ceaf825 100644 --- a/mods/ITEMS/mcl_grindstone/init.lua +++ b/mods/ITEMS/mcl_grindstone/init.lua @@ -1,37 +1,54 @@ -- Code based from mcl_anvils +mcl_grindstone = {} + local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize local MAX_WEAR = 65535 --- formspecs -local function get_grindstone_formspec() - return "size[9,8.75]".. - "image[3,1.5;1.5,1;gui_crafting_arrow.png]".. - "label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "label[1,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair & Disenchant"))).."]".. - "list[context;main;0,0;8,4;]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "list[context;input;1,1;1,1;]".. - mcl_formspec.get_itemslot_bg(1,1,1,1).. - "list[context;input;1,2;1,1;1]".. - mcl_formspec.get_itemslot_bg(1,2,1,1).. - "list[context;output;6,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(6,1.5,1,1).. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" -end +local grindstone_formspec = table.concat({ + "formspec_version[6]", + "size[11.75,10.425]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Repair & Disenchant"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 1.25, 1, 1), + "list[context;input;2.875,1.25;1,1;]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 2.625, 1, 1), + "list[context;input;2.875,2.625;1,1;1]", + + "image[2.375,1;2,2.875;grindstone_gui_9.png;2]", + + "image[1.875,1.5;0.5,2.875;grindstone_gui_9.png;2]", + "image[4.375,1.5;0.5,2.875;grindstone_gui_9.png;2]", + + "image[5.5,1.95;1.5,1;gui_crafting_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 1.9375, 1, 1), + "list[context;output;7.875,1.9375;1,1;]", + + "label[0.375,4.7;" .. F(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[context;output]", + "listring[current_player;main]", + "listring[context;input]", + "listring[current_player;main]", +}) -- Creates a new item with the wear of the items and custom name local function create_new_item(name_item, meta, wear) local new_item = ItemStack(name_item) if wear ~= nil then - new_item:set_wear(wear) + new_item:set_wear(wear) end local new_meta = new_item:get_meta() new_meta:set_string("name", meta:get_string("name")) @@ -40,7 +57,7 @@ local function create_new_item(name_item, meta, wear) end -- If an item has an enchanment then remove "_enchanted" from the name -local function remove_enchant_name(stack) +function mcl_grindstone.remove_enchant_name(stack) if mcl_enchanting.is_enchanted(stack:get_name()) then local name = stack:get_name() return name.sub(name, 1, -11) @@ -86,7 +103,6 @@ local function fix_stack_size(stack) return count end - -- Update the inventory slots of an grindstone node. -- meta: Metadata of grindstone node local function update_grindstone_slots(meta) @@ -102,8 +118,8 @@ local function update_grindstone_slots(meta) local def1 = input1:get_definition() local def2 = input2:get_definition() -- Remove enchant name if they have one - local name1 = remove_enchant_name(input1) - local name2 = remove_enchant_name(input2) + local name1 = mcl_grindstone.remove_enchant_name(input1) + local name2 = mcl_grindstone.remove_enchant_name(input2) -- Calculate repair local function calculate_repair(dur1, dur2) @@ -122,14 +138,14 @@ local function update_grindstone_slots(meta) else new_output = "" end - -- Check if at least one input has an item - -- Check if the item is's an enchanted book or tool + -- Check if at least one input has an item + -- Check if the item is's an enchanted book or tool elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then if input2:is_empty() then local def1 = input1:get_definition() local meta = input1:get_meta() if def1.type == "tool" and mcl_enchanting.is_enchanted(input1:get_name()) then - local name = remove_enchant_name(input1) + local name = mcl_grindstone.remove_enchant_name(input1) local wear = input1:get_wear() local new_item = create_new_item(name, meta, wear) new_output = transfer_curse(input1, new_item) @@ -143,7 +159,7 @@ local function update_grindstone_slots(meta) local def2 = input2:get_definition() local meta = input2:get_meta() if def2.type == "tool" and mcl_enchanting.is_enchanted(input2:get_name()) then - local name = remove_enchant_name(input2) + local name = mcl_grindstone.remove_enchant_name(input2) local wear = input2:get_wear() local new_item = create_new_item(name, meta, wear) new_output = transfer_curse(input2, new_item) @@ -168,10 +184,10 @@ end -- Drop any items inside the grindstone if destroyed local function drop_grindstone_items(pos, meta) local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do local stack = inv:get_stack("input", i) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { x = pos.x + math.random(0, 10) / 10 - 0.5, y = pos.y, z = pos.z + math.random(0, 10) / 10 - 0.5 } minetest.add_item(p, stack) end end @@ -181,11 +197,11 @@ local node_box = { type = "fixed", -- created with nodebox editor fixed = { - {-0.25, -0.25, -0.375, 0.25, 0.5, 0.375}, - {-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875}, - {0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875}, - {0.25, -0.5, -0.125, 0.375, -0.0625, 0.125}, - {-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125}, + { -0.25, -0.25, -0.375, 0.25, 0.5, 0.375 }, + { -0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875 }, + { 0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875 }, + { 0.25, -0.5, -0.125, 0.375, -0.0625, 0.125 }, + { -0.375, -0.5, -0.125, -0.25, -0.0625, 0.125 }, } } @@ -193,11 +209,11 @@ minetest.register_node("mcl_grindstone:grindstone", { description = S("Grindstone"), _tt_help = S("Used to disenchant/fix tools"), _doc_items_longdesc = S("Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station."), - _doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.").."\n".. - S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n".. - S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n".. - S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n".. - S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."), + _doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.") .. "\n" .. + S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.") .. "\n" .. + S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.") .. "\n" .. + S("If both items have enchantments the player will get xp from both items from the disenchant.") .. "\n" .. + S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."), tiles = { "grindstone_top.png", "grindstone_top.png", @@ -212,7 +228,7 @@ minetest.register_node("mcl_grindstone:grindstone", { selection_box = node_box, collision_box = node_box, sounds = mcl_sounds.node_sound_stone_defaults(), - groups = {pickaxey = 1, deco_block = 1}, + groups = { pickaxey = 1, deco_block = 1 }, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) @@ -268,7 +284,7 @@ minetest.register_node("mcl_grindstone:grindstone", { local meta = minetest.get_meta(pos) if from_list == "output" and to_list == "input" then local inv = meta:get_inventory() - for i=1, inv:get_size("input") do + for i = 1, inv:get_size("input") do if i ~= to_index then local istack = inv:get_stack("input", i) istack:set_count(math.max(0, istack:get_count() - count)) @@ -289,8 +305,8 @@ minetest.register_node("mcl_grindstone:grindstone", { if not input1:is_empty() and not input2:is_empty() then -- Get xp earnt from the enchanted items xp_earnt = calculate_xp(input1) + calculate_xp(input1) - input1:take_item() - input2:take_item() + input1:take_item(1) + input2:take_item(1) inv:set_stack("input", 1, input1) inv:set_stack("input", 2, input2) else @@ -320,14 +336,13 @@ minetest.register_node("mcl_grindstone:grindstone", { local inv = meta:get_inventory() inv:set_size("input", 2) inv:set_size("output", 1) - local form = get_grindstone_formspec() - meta:set_string("formspec", form) + meta:set_string("formspec", grindstone_formspec) end, on_rightclick = function(pos, node, player, itemstack) if not player:get_player_control().sneak then local meta = minetest.get_meta(pos) update_grindstone_slots(meta) - meta:set_string("formspec", get_grindstone_formspec()) + meta:set_string("formspec", grindstone_formspec) end end, _mcl_blast_resistance = 6, @@ -337,7 +352,7 @@ minetest.register_node("mcl_grindstone:grindstone", { minetest.register_craft({ output = "mcl_grindstone:grindstone", recipe = { - { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick"}, - { "group:wood", "", "group:wood"}, + { "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick" }, + { "group:wood", "", "group:wood" }, } }) diff --git a/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.pt_BR.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.pt_BR.tr new file mode 100644 index 000000000..03a5ca41e --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory=Inventário +Repair & Disenchant=Reparar & Desencantar +Grindstone=Rebolo +Used to disenchant/fix tools=Usado para desencantar/consertar ferramentas +Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.=Rebolos desencantam ferramentas e armaduras exceto as maldições, e consertam dois itens do mesmo tipo e ainda é a estação de trabalho do armeiro. +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=Para usar o rebolo, clique com o botão direito nele. +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=Para desencantar um item posicione o item encantado em um dos slots de entrada e pegue o item desencantado na saída. +To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.=Para consertar uma ferramenta você precisará de uma ferramenta do mesmo tipo e material, ponha ambos os itens nos slots de entrada e o slot de saída irá combinar a durabilidade dos dois itens com um bônus de 5%. +If both items have enchantments the player will get xp from both items from the disenchant.=Se ambos itens possuem encantamentos o jogador receberá XP de ambos os itens no desencanto. +Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.=Maldições não podem ser removidas e serão transferidas para o novo item reparado, se ambos os itens tiverem maldições diferentes, as maldições serão combinadas. diff --git a/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ru.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ru.tr new file mode 100644 index 000000000..aba4d733d --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ru.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory=Инвентарь +Repair & Disenchant=Починить и снять зачарования +Grindstone=Точило +Used to disenchant/fix tools=Используется для снятия зачарований и для починки инструментов +Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.=Точило снимает все зачарования с инструментов и брони кроме проклятий, чинит два предмета одного типа, а также служит рабочим местом жителя оружейника. +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=Чтобы использовать точило кликните правой кнопкой по нему. Два входных слота слева и один выходной слот справа. +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=Чтобы снять зачарования положите предмет в один входной слот и заберите полученный предмет с выходного слота. +To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.=Чтобы починить инструмент вам нужен еще один инструмент того же типа и из того же материала, положите оба инструмента во входные слоты и в выходном слоте их запас прочности соединится с 5% бонусом. +If both items have enchantments the player will get xp from both items from the disenchant.=Если оба предмета имеют зачарования игрок получит XP от снятия зачарований с каждого предмета7 +Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.=Проклятия нельзя снять и они будут переданы на новый предмет, если оба предмета имеют разные проклятия, то они будут совмещены. \ No newline at end of file diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pt_BR.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pt_BR.tr new file mode 100644 index 000000000..63f37d579 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Hambúrguer + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Um hambúrguer saboroso certamente atrairá os aldeões como um laço. Pode ser comido. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Um hambúrguer saboroso certamente atrairá os aldeões.'Pagarei com prazer na terça-feira, por um hambúrguer hoje.' - Wimpy. + +Burger Time!=Hora do Hambúrguer! +Craft a Hamburger.=Fabrique um hambúrguer. +Wield this item to pull villagers to you.=Segure esse item para atrair aldeões até você. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr index 736f182a5..70401678b 100644 --- a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr @@ -1,10 +1,10 @@ # textdomain: mcl_hamburger A Hamburger=Гамбургер -A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Вкусный гамбургер, который обязательно привлечет жителей деревни, как наживку. Можно есть. +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Вкусный гамбургер, который привлечет жителей деревни как наживка. Можно съесть. -A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Вкусный гамбургер, который обязательно привлечет жителей деревни. — Я с радостью заплачу тебе во вторник за гамбургер сегодня. - Вимпи. +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Вкусный гамбургер, который привлечет жителей деревни. Burger Time!=Время бургеров! -Craft a Hamburger.=Изготовить гамбургер. -Wield this item to pull villagers to you.=Используйте этот предмет, чтобы притягивать к себе жителей деревни. +Craft a Hamburger.=Приготовьте гамбургер. +Wield this item to pull villagers to you.=Возьмите этот предмет, чтобы приманивать к себе деревенских жителей diff --git a/mods/ITEMS/mcl_hamburger/readme.txt b/mods/ITEMS/mcl_hamburger/readme.txt index e479c01b9..da11f5527 100644 --- a/mods/ITEMS/mcl_hamburger/readme.txt +++ b/mods/ITEMS/mcl_hamburger/readme.txt @@ -27,7 +27,7 @@ suggestions are always welcome! The images contained within have been altered to be more legible within the game and not rendered with weird antialiasing by Michieal. All extraneous information in the images have been removed to decrease file size. -This mod is licensed under CC-BY-SA 3, with the intent of it being used by the Mineclone 2 game for Minetest. +This mod is licensed under CC-BY-SA 3, with the intent of it being used by the VoxeLibre game for Minetest. This code was written by Michieal, with additions included by Cora. The achievement "Burger Time!" is an homage to the classic coin-op arcade game BurgerTime, by Data East (1982) and diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index 69c26b97d..5409f21c4 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -264,11 +264,11 @@ mcl_heads.register_head{ } mcl_heads.register_head{ - name = "creeper", - texture = "mcl_heads_creeper.png", - description = S("Creeper Head"), - longdesc = S("A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%."), - range_mob = "mobs_mc:creeper", + name = "stalker", + texture = "mcl_heads_stalker.png", + description = S("Stalker Head"), + longdesc = S("A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%."), + range_mob = "mobs_mc:stalker", range_factor = 0.5, } diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.de.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.de.tr index 75e92aef9..0d829b62b 100644 --- a/mods/ITEMS/mcl_heads/locale/mcl_heads.de.tr +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.de.tr @@ -1,8 +1,8 @@ # textdomain: mcl_heads Zombie Head=Zombiekopf A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=Ein Zombiekopf ist ein kleiner dekorativer Block, der so wie ein Kopf eines Zombies aussieht. Er kann auch als Helm getragen werden, was den Erkennungsradius von Zombies um 50% verringert. -Creeper Head=Creeper-Kopf -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=Ein Creeperkopf ist ein kleiner dekorativer Block, der so wie ein Kopf eines Creepers aussieht. Er kann auch als Helm getragen werden, was den Erkennungsradius von Creepern um 50% verringert. +Stalker Head=Stalker-Kopf +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.=Ein Stalkerkopf ist ein kleiner dekorativer Block, der so wie ein Kopf eines Stalkers aussieht. Er kann auch als Helm getragen werden, was den Erkennungsradius von Stalkern um 50% verringert. Human Head=Menschenkopf A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Ein Menschenkopf ist ein kleiner dekorativer Block, der so wie der Kopf eines Menschen (das heißt, einer Spielerfigur) aussieht. Er kann auch als Helm zum Spaß getragen werden, aber er bietet keinerlei Schutz. Skeleton Skull=Skelettschädel diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.es.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.es.tr index 308dd8b28..3c9a2a1c1 100644 --- a/mods/ITEMS/mcl_heads/locale/mcl_heads.es.tr +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.es.tr @@ -1,8 +1,8 @@ # textdomain: mcl_heads Zombie Head=Cabeza de zombie A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet for fun, but does not offer any protection.=Una cabeza de zombie es un pequeño bloque decorativo que se asemeja a la cabeza de un zombie. También se puede usar como casco por diversión, pero no ofrece ninguna protección. -Creeper Head=Cabeza de creeper -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet for fun, but does not offer any protection.=Una cabeza de creeper es un pequeño bloque decorativo que se asemeja a la cabeza de un creeper. También se puede usar como casco por diversión, pero no ofrece ninguna protección. +Stalker Head=Cabeza de stalker +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet for fun, but does not offer any protection.=Una cabeza de stalker es un pequeño bloque decorativo que se asemeja a la cabeza de un stalker. También se puede usar como casco por diversión, pero no ofrece ninguna protección. Human Head=Cabeza humana A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Una cabeza humana es un pequeño bloque decorativo que se asemeja a la cabeza de un humano (es decir, un personaje jugador). También se puede usar como casco por diversión, pero no ofrece ninguna protección. Skeleton Skull=Calavera de esqueleto diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.fr.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.fr.tr index 56436f519..dd6c20339 100644 --- a/mods/ITEMS/mcl_heads/locale/mcl_heads.fr.tr +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.fr.tr @@ -1,8 +1,8 @@ # textdomain: mcl_heads Zombie Head=Tête de Zombie A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=Une tête de zombie est un petit bloc décoratif qui ressemble à la tête d'un zombie. Il peut également être porté comme un casque, ce qui réduit la plage de détection des zombies de 50%. -Creeper Head=Tête de Creeper -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=Une tête de creepers est un petit bloc décoratif qui ressemble à la tête d'un creeper. Il peut également être porté comme un casque, ce qui réduit la plage de détection des creepers de 50%. +Stalker Head=Tête de Stalker +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.=Une tête de stalkers est un petit bloc décoratif qui ressemble à la tête d'un stalker. Il peut également être porté comme un casque, ce qui réduit la plage de détection des stalkers de 50%. Human Head=Tête de Joueur A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Une tête de joueur est un petit bloc décoratif qui ressemble à la tête d'un humain (c'est-à-dire un personnage de joueur). Il peut également être porté comme un casque pour le plaisir, mais n'offre aucune protection. Skeleton Skull=Crâne de Squelette diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr index 4ed4bbbee..9091f92cb 100644 --- a/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr @@ -1,8 +1,8 @@ # textdomain: mcl_heads Zombie Head=Głowa zombie A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=Głowa zombie jest małym blokiem dekoracyjnym i przypomina głowę zombie. Może być noszona jako hełm co zmniejsza obszar wykrycia przez zombie o 50%. -Creeper Head=Głowa creepera -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=Głowa creepera jest małym blokiem dekoracyjnym i przypomina głowę creepera. Może być noszona jako hełm co zmniejsza obszar wykrycia przez creepera o 50%. +Stalker Head=Głowa stalkera +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.=Głowa stalkera jest małym blokiem dekoracyjnym i przypomina głowę stalkera. Może być noszona jako hełm co zmniejsza obszar wykrycia przez stalkera o 50%. Human Head=Głowa człowieka A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Głowa człowieka jest małym blokiem dekoracyjnym i przypomina głowę człowieka. Może być noszona jako hełm dla zabawy, ale nie zapewnia żadnej dodatkowej ochrony. Skeleton Skull=Głowa szkieleta diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.pt_BR.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.pt_BR.tr new file mode 100644 index 000000000..91cef7627 --- /dev/null +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_heads +Zombie Head=Cabeça de Zumbi +A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=Uma cabeça de zumbi é um pequeno bloco decorativo ao qual remete a cabeça de um zumbi. Também pode ser usado como um capacete, o que reduz o alcançe de detecção dos zumbis em 50%. +Stalker Head=Cabeça de Stalker +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.=Uma cabeça de stalker é um pequeno bloco decorativo ao qual remete a cabeça de um stalker. Também pode ser usado como um capacete, o que reduz o alcançe de detecção dos stalkers em 50%. +Human Head=Cabeça Humana +A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Uma cabeça de humano é um pequeno bloco decorativo ao qual remete a cabeça de um humano (ou seja, o personagem do jogador). Também pode ser usado como um capacete por diversão, mas não oferece nenhuma proteção. +Skeleton Skull=Cabeça de Esqueleto +A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%.=Uma cabeça de esqueleto é um pequeno bloco decorativo ao qual remete a cabeça de um esqueleto. Também pode ser usado como um capacete, o que reduz o alcançe de detecção dos esqueletos em 50%. +Wither Skeleton Skull=Cabeça de Esqueleto Wither +A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.=Uma cabeça de esqueleto wither é um pequeno bloco decorativo ao qual remete a cabeça de um esqueleto wither. Também pode ser usado como um capacete por diversão, mas não oferece nenhuma proteção. diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.ru.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.ru.tr index 28f2de4ff..dbedbbfe0 100644 --- a/mods/ITEMS/mcl_heads/locale/mcl_heads.ru.tr +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.ru.tr @@ -1,11 +1,11 @@ # textdomain: mcl_heads Zombie Head=Голова зомби A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.=Голова зомби это небольшой декоративный блок, немного похожий на голову зомби. Его можно носить в качестве шлема, что уменьшит радиус обнаружения вас зомби на 50%. -Creeper Head=Голова крипера -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.=Голова крипера это небольшой декоративный блок, немного похожий на голову крипера. Его можно носить в качестве шлема, что уменьшит радиус обнаружения вас крипером на 50%. -Human Head=Голова человека -A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Голова человека это небольшой декоративный блок, немного похожий на голову человека (например, игрового персонажа). Его можно носить в качестве шлема просто для смеха, он не даёт никакой защиты. +Stalker Head=Голова сталкера +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.=Голова сталкера это небольшой декоративный блок, немного похожий на голову сталкера. Его можно носить в качестве шлема, что уменьшит радиус обнаружения вас сталкером на 50%. +Human Head=Голова игрока +A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.=Голова игрока это небольшой декоративный блок, немного похожий на голову игрового персонажа. Его можно носить в качестве шлема просто для веселья, он не даёт никакой защиты. Skeleton Skull=Череп скелета A skeleton skull is a small decorative block which resembles the skull of a skeleton. It can also be worn as a helmet, which reduces the detection range of skeletons by 50%.=Череп скелета это небольшой декоративный блок, немного похожий на череп скелета. Его можно носить в качестве шлема, что уменьшит радиус обнаружения вас скелетом на 50%. Wither Skeleton Skull=Череп скелета-иссушителя -A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.=Череп скелета-иссушителя это небольшой декоративный блок, немного похожий на череп скелета-иссушителя. Его можно носить в качестве шлема просто для смеха, он не даёт никакой защиты. +A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton. It can also be worn as a helmet for fun, but does not offer any protection.=Череп скелета-иссушителя это небольшой декоративный блок, немного похожий на череп скелета-иссушителя. Его можно носить в качестве шлема просто для веселья, он не даёт никакой защиты. diff --git a/mods/ITEMS/mcl_heads/locale/template.txt b/mods/ITEMS/mcl_heads/locale/template.txt index 59321099a..6fe2a212f 100644 --- a/mods/ITEMS/mcl_heads/locale/template.txt +++ b/mods/ITEMS/mcl_heads/locale/template.txt @@ -1,8 +1,8 @@ # textdomain: mcl_heads Zombie Head= A zombie head is a small decorative block which resembles the head of a zombie. It can also be worn as a helmet, which reduces the detection range of zombies by 50%.= -Creeper Head= -A creeper head is a small decorative block which resembles the head of a creeper. It can also be worn as a helmet, which reduces the detection range of creepers by 50%.= +Stalker Head= +A stalker head is a small decorative block which resembles the head of a stalker. It can also be worn as a helmet, which reduces the detection range of stalkers by 50%.= Human Head= A human head is a small decorative block which resembles the head of a human (i.e. a player character). It can also be worn as a helmet for fun, but does not offer any protection.= Skeleton Skull= diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr index 90382020a..f22ae7702 100644 --- a/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr @@ -1,5 +1,6 @@ -Honeycomb=Bloque de panal -Used to craft beehives and protect copper blocks from further oxidation.=Se utiliza para fabricar apiarios de avejas y para proteger bloques de cobre +# textdomain: mcl_honey +Honeycomb=Panal +Used to craft beehives and protect copper blocks from further oxidation.=Se utiliza para fabricar apiarios de abejas y para proteger bloques de cobre de mayor oxidación. Use on copper blocks to prevent further oxidation.=Usa sobre bloques de cobre para evitar mayor oxidación. Honeycomb Block=Bloque de panal Honeycomb Block. Used as a decoration.=Bloque de panal. Se utiliza como decoración como decoración diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.pt_BR.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.pt_BR.tr new file mode 100644 index 000000000..cb6ae1d53 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_honey +Honeycomb=Favo de Mel +Used to craft beehives and protect copper blocks from further oxidation.=Usado para fabricar colméias artificiais e protejer blocos de cobre da oxidação adicional. +Use on copper blocks to prevent further oxidation.=Use em blocos de cobre para previnir oxidação adicional. +Honeycomb Block=Bloco de Favo de Mel +Honeycomb Block. Used as a decoration.=Bloco de Favo de Mel. Usado como decoração +Honey Bottle=Garrafa de Mel +Honey Bottle is used to craft honey blocks and to restore hunger points.=Garrafa de Mel é usada para fabricar blocos de mel e para restaurar pontos de fome. +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.=Beber irá restaurar 6 pontos de fome. Também pode ser usada para fabricar blocos de mel. +Honey Block=Bloco de Mel +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.=Bloco de Mel. Usado como decoração e em redstone. É pegajoso em alguns lados. diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.ru.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.ru.tr new file mode 100644 index 000000000..ab43afd83 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.ru.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_honey +Honeycomb=Пчелиные соты +Used to craft beehives and protect copper blocks from further oxidation.=Используется для создания ульев и для защиты медных блоков от дальнейшего окисления. +Use on copper blocks to prevent further oxidation.=Используйте на медном блоке, чтобы предотвратить дальнейшеее окисление. +Honeycomb Block=Блок пчелиных сот +Honeycomb Block. Used as a decoration.=Блок пчелиных сот. Декорация. +Honey Bottle=Бутылочка мёда +Honey Bottle is used to craft honey blocks and to restore hunger points.=Бутылочка мёда используется при создании блоков мёда и для восстановления голода. +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.=Выпив вы восстановите 6 очков голода. Также используется при создании блоков мёда. +Honey Block=Блок мёда +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.=Блок мёда. Используется как декорация и в механизмах редстоуна. Липкий по бокам. \ No newline at end of file diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 15bc922ff..ec7f7ab8f 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -12,26 +12,95 @@ end --[[ BEGIN OF NODE DEFINITIONS ]] local mcl_hoppers_formspec = table.concat({ - "size[9,7]", - "label[2,0;" .. F(C("#313131", S("Hopper"))) .. "]", - "list[context;main;2,0.5;5,1;]", - mcl_formspec.get_itemslot_bg(2, 0.5, 5, 1), - "label[0,2;" .. F(C("#313131", S("Inventory"))) .. "]", - "list[current_player;main;0,2.5;9,3;9]", - mcl_formspec.get_itemslot_bg(0, 2.5, 9, 3), - "list[current_player;main;0,5.74;9,1;]", - mcl_formspec.get_itemslot_bg(0, 5.74, 9, 1), + "formspec_version[4]", + "size[11.75,8.175]", + + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Hopper"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(2.875, 0.75, 5, 1), + "list[context;main;2.875,0.75;5,1;]", + + "label[0.375,2.45;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 2.85, 9, 3), + "list[current_player;main;0.375,2.85;9,3;9]", + + mcl_formspec.get_itemslot_bg_v4(0.375, 6.8, 9, 1), + "list[current_player;main;0.375,6.8;9,1;]", + "listring[context;main]", "listring[current_player;main]", }) +local function straight_hopper_act(pos, node, active_object_count, active_count_wider) + local timer = minetest.get_node_timer(pos) + if timer:is_started() then + --Pause if already recived item this tick + return + end + timer:start(1.0) + + -- Move from internal inventory to dst first + local dst_pos = vector.offset(pos, 0, -1, 0) + local dst_node = minetest.get_node(dst_pos) + local dst_name = dst_node.name + local dst_def = minetest.registered_nodes[dst_name] + + if dst_def and dst_def._mcl_hopper_act then + dst_def._mcl_hopper_act( dst_pos, dst_node, active_object_count, active_count_wider ) + end + + mcl_util.hopper_push(pos, dst_pos) + local src_pos = vector.offset(pos, 0, 1, 0) + mcl_util.hopper_pull(pos, src_pos) +end + +local function bent_hopper_act(pos, node, active_object_count, active_object_count_wider) + local timer = minetest.get_node_timer(pos) + if timer:is_started() then + --Pause if already recived item this tick + return + end + timer:start(1.0) + + -- Check if we are empty + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local empty = inv:is_empty("main") + + -- Determine to which side the hopper is facing, get nodes + local face = minetest.get_node(pos).param2 + local dst_pos = {} + if face == 0 then + dst_pos = vector.offset(pos, -1, 0, 0) + elseif face == 1 then + dst_pos = vector.offset(pos, 0, 0, 1) + elseif face == 2 then + dst_pos = vector.offset(pos, 1, 0, 0) + elseif face == 3 then + dst_pos = vector.offset(pos, 0, 0, -1) + end + local dst_node = minetest.get_node(dst_pos) + local dst_name = dst_node.name + local dst_def = minetest.registered_nodes[dst_name] + if dst_def and dst_def._mcl_hopper_act then + dst_def._mcl_hopper_act( dst_pos, dst_node, active_object_count, active_object_count_wider ) + end + if not empty then + mcl_util.hopper_push(pos, dst_pos) + end + + local src_pos = vector.offset(pos, 0, 1, 0) + mcl_util.hopper_pull(pos, src_pos) +end + -- Downwards hopper (base definition) ---@type node_definition local def_hopper = { inventory_image = "mcl_hoppers_item.png", wield_image = "mcl_hoppers_item.png", - groups = {pickaxey = 1, container = 2, deco_block = 1, hopper = 1}, + groups = { pickaxey = 1, container = 2, deco_block = 1, hopper = 1 }, drawtype = "nodebox", paramtype = "light", -- FIXME: mcl_hoppers_hopper_inside.png is unused by hoppers. @@ -47,25 +116,25 @@ local def_hopper = { type = "fixed", fixed = { --funnel walls - {-0.5, 0.0, 0.4, 0.5, 0.5, 0.5}, - {0.4, 0.0, -0.5, 0.5, 0.5, 0.5}, - {-0.5, 0.0, -0.5, -0.4, 0.5, 0.5}, - {-0.5, 0.0, -0.5, 0.5, 0.5, -0.4}, + { -0.5, 0.0, 0.4, 0.5, 0.5, 0.5 }, + { 0.4, 0.0, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, -0.4, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, 0.5, 0.5, -0.4 }, --funnel base - {-0.5, 0.0, -0.5, 0.5, 0.1, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.1, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.1, -0.3, -0.1, 0.1, -0.5, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.1, -0.3, -0.1, 0.1, -0.5, 0.1 }, }, }, selection_box = { type = "fixed", fixed = { --funnel - {-0.5, 0.0, -0.5, 0.5, 0.5, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.5, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.1, -0.3, -0.1, 0.1, -0.5, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.1, -0.3, -0.1, 0.1, -0.5, 0.1 }, }, }, is_ground_content = false, @@ -199,6 +268,7 @@ def_hopper_enabled.mesecons = { end, }, } +def_hopper_enabled._mcl_hopper_act = straight_hopper_act minetest.register_node("mcl_hoppers:hopper", def_hopper_enabled) @@ -248,25 +318,25 @@ local def_hopper_side = { type = "fixed", fixed = { --funnel walls - {-0.5, 0.0, 0.4, 0.5, 0.5, 0.5}, - {0.4, 0.0, -0.5, 0.5, 0.5, 0.5}, - {-0.5, 0.0, -0.5, -0.4, 0.5, 0.5}, - {-0.5, 0.0, -0.5, 0.5, 0.5, -0.4}, + { -0.5, 0.0, 0.4, 0.5, 0.5, 0.5 }, + { 0.4, 0.0, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, -0.4, 0.5, 0.5 }, + { -0.5, 0.0, -0.5, 0.5, 0.5, -0.4 }, --funnel base - {-0.5, 0.0, -0.5, 0.5, 0.1, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.1, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.5, -0.3, -0.1, 0.1, -0.1, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.5, -0.3, -0.1, 0.1, -0.1, 0.1 }, }, }, selection_box = { type = "fixed", fixed = { --funnel - {-0.5, 0.0, -0.5, 0.5, 0.5, 0.5}, + { -0.5, 0.0, -0.5, 0.5, 0.5, 0.5 }, --spout - {-0.3, -0.3, -0.3, 0.3, 0.0, 0.3}, - {-0.5, -0.3, -0.1, 0.1, -0.1, 0.1}, + { -0.3, -0.3, -0.3, 0.3, 0.0, 0.3 }, + { -0.5, -0.3, -0.1, 0.1, -0.1, 0.1 }, }, }, is_ground_content = false, @@ -348,6 +418,7 @@ def_hopper_side_enabled.mesecons = { end, }, } +def_hopper_side_enabled._mcl_hopper_act = bent_hopper_act minetest.register_node("mcl_hoppers:hopper_side", def_hopper_side_enabled) ---@type node_definition @@ -463,31 +534,38 @@ minetest.register_abm({ if entity and entity.name then --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() 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.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 (hm_pos.y == pos.y + 1) + if (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.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("Minecart close enough") if entity.name == "mcl_minecarts:hopper_minecart" then 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) 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.z >= pos.z - DIST_FROM_MC and hm_pos.z <= pos.z + DIST_FROM_MC) then mcl_log("Minecart close enough") if entity.name == "mcl_minecarts:hopper_minecart" then 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) end end @@ -538,222 +616,26 @@ minetest.register_abm({ end, }) ----Returns true if itemstack is fuel, but not for lava bucket if destination already has one ----@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 - +-- Register push/pull for "straight" hopper minetest.register_abm({ label = "Hopper/container item exchange", - nodenames = {"mcl_hoppers:hopper"}, - neighbors = {"group:container"}, + nodenames = { "mcl_hoppers:hopper" }, + neighbors = { "group:container" }, interval = 1.0, chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - -- Get node pos' for item transfer - local uppos = vector.offset(pos, 0, 1, 0) - 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 - - -- Move an item from the hopper into container below - local downnode = minetest.get_node(downpos) - if not minetest.registered_nodes[downnode.name] then return end - mcl_util.move_item_container(pos, downpos) - end, + action = straight_hopper_act, }) +-- Register push/pull for "bent" hopper minetest.register_abm({ label = "Side-hopper/container item exchange", - nodenames = {"mcl_hoppers:hopper_side"}, - neighbors = {"group:container"}, + nodenames = { "mcl_hoppers:hopper_side" }, + neighbors = { "group:container" }, interval = 1.0, chance = 1, - action = function(pos, node, active_object_count, active_object_count_wider) - -- Determine to which side the hopper is facing, get nodes - local face = minetest.get_node(pos).param2 - local front = {} - if face == 0 then - front = vector.offset(pos, -1, 0, 0) - elseif face == 1 then - front = vector.offset(pos, 0, 0, 1) - elseif face == 2 then - front = vector.offset(pos, 1, 0, 0) - elseif face == 3 then - front = vector.offset(pos, 0, 0, -1) - end - local above = vector.offset(pos, 0, 1, 0) - - local frontnode = minetest.get_node(front) - if not minetest.registered_nodes[frontnode.name] then return end - - -- Suck an item from the container above into the hopper - local abovenode = minetest.get_node(above) - if not minetest.registered_nodes[abovenode.name] then return end - local g = minetest.get_item_group(abovenode.name, "container") - 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 - - -- 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 + action = bent_hopper_act, }) -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({ output = "mcl_hoppers:hopper", recipe = { @@ -772,7 +654,7 @@ end minetest.register_alias("mcl_hoppers:hopper_item", "mcl_hoppers:hopper") minetest.register_lbm({ - label = "Update hopper formspecs (0.60.0", + label = "Update hopper formspecs (0.60.0)", name = "mcl_hoppers:update_formspec_0_60_0", nodenames = {"group:hopper"}, run_at_every_load = false, diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pt_BR.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pt_BR.tr new file mode 100644 index 000000000..3ed5bcfad --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pt_BR.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_hoppers +Hopper=Funil +Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.=Funis são recipientes com 5 slots de inventário. Eles coletam itens largados acima, pegam itens de um recipiente acima e tentam colocar seus itens em um recipiente adjacente. Funis podem ir tanto para baixo quanto para os lados. Funis interagem com baús, liberadores, ejetores, caixas shulker, fornalhas e funis. +Hoppers interact with containers the following way:=Funis interagem com recipientes da seguinte maneira: +• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot=• Fornalhas: Funis acima irão colocar itens no slot da fonte. Funis abaixo pegam itens do slot de saída. Eles também pegam itens do slot de combustível quando estes não podem ser usados como combustível. Funis laterais que apontem para a fornalha colocam itens no slot de combustível. +• Ender chests: No interaction.=• Baús do ender: Sem interações. +• Other containers: Normal interaction.=• Outros recipientes: Interação normal. +Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.= Funis pode ser desativados quando alimentados com carga de redstone. Funis desativados não movem itens. +To place a hopper vertically, place it on the floor or a ceiling. To place it sideways, place it at the side of a block. Use the hopper to access its inventory.=Para posicionar um funil verticalmente, posicione-o no chão ou no teto. Para posiciona-lo lateralmente, posicione-o na lateral de um bloco. Use o funil para acessar seu inventário. +Disabled Hopper=Funil Desativado +Side Hopper=Funil Lateral +Disabled Side Hopper=Funil Lateral Desativado +Inventory=Inventário +5 inventory slots=5 slots de inventário +Collects items from above, moves items to container below=Coleta itens vindos de cima, move itens para recipientes abaixo. +Can be disabled with redstone power=Pode ser desativado com carga de redstone diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ru.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ru.tr index ac7e82b17..03dbcad3c 100644 --- a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ru.tr +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ru.tr @@ -1,16 +1,16 @@ # textdomain: mcl_hoppers Hopper=Воронка -Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.=Воронка это контейнер с 5 отсеками инвентаря. Она может собирать предметы, брошенные сверху, брать предметы из контейнеров сверху, а также пытаться класть свои предметы в примыкающий контейнер. Воронки могут действовать вниз или вбок. Воронки взаимодействуют с сундуками, выбрасывателями, диспенсерами, ящиками шалкеров, печами и другими воронками. +Hoppers are containers with 5 inventory slots. They collect dropped items from above, take items from a container above and attempt to put its items it into an adjacent container. Hoppers can go either downwards or sideways. Hoppers interact with chests, droppers, dispensers, shulker boxes, furnaces and hoppers.=Воронка это контейнер с 5 слотами инвентаря. Она может собирать предметы, брошенные сверху, брать предметы из контейнеров сверху, а также пытаться положить свои предметы в примыкающий контейнер. Воронки могут действовать вниз или вбок. Воронки взаимодействуют с сундуками, выбрасывателями, раздатчиками, ящиками шалкеров, печами и другими воронками. Hoppers interact with containers the following way:=Воронка взаимодействует с контейнерами следующим образом: -• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot=• Печи: размещённые выше воронки будут складывать предметы во входной отсек. Воронки, размещённые ниже, будут доставать предметы из выходного отсека. Они также может доставать предметы из топливного отсека, если эти предметы не могут использоваться в качестве топлива. Боковые воронки, нацеленные на печь, помещают предметы в топливный отсек. -• Ender chests: No interaction.=• Сундук Предела: не взаимодействует. -• Other containers: Normal interaction.=• Прочие контейнеры: взаимодействует обычно. -Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=Воронки могут быть отключены, когда на них подаётся энергия редстоуна. +• Furnaces: Hoppers from above will put items into the source slot. Hoppers from below take items from the output slot. They also take items from the fuel slot when they can't be used as a fuel. Sideway hoppers that point to the furnace put items into the fuel slot=• Печи: размещённые наверху воронки будут складывать предметы во входной слот. Воронки, размещённые снизу, будут брать предметы из выходного слота печи. Они также может доставать предметы из топливного слота, если эти предметы не могут использоваться в качестве топлива. Воронки сбоку, присоединённые к печи, помещают предметы в топливный слот. +• Ender chests: No interaction.=• Сундук Края: не взаимодействует. +• Other containers: Normal interaction.=• Прочие контейнеры: взаимодействует как обычно. +Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=Воронки могут быть отключены, когда на них подаётся сигнал редстоуна. To place a hopper vertically, place it on the floor or a ceiling. To place it sideways, place it at the side of a block. Use the hopper to access its inventory.=Чтобы установить воронку вертикально, поместите её на пол или потолок. Чтобы установить воронку по направлению в сторону, разместите её на боковой стороне блока. Нажмите [Использовать] для доступа к инвентарю воронки. Disabled Hopper=Отключенная воронка Side Hopper=Боковая воронка Disabled Side Hopper=Отключенная боковая воронка Inventory=Инвентарь -5 inventory slots=5 отсеков инвентаря +5 inventory slots=5 слотов инвентаря Collects items from above, moves items to container below=Собирает предметы сверху, передаёт их в контейнер ниже -Can be disabled with redstone power=Может быть отключена с помощью энергии редстоуна +Can be disabled with redstone power=Может быть отключена с помощью сигнала редстоуна diff --git a/mods/ITEMS/mcl_itemframes/README.txt b/mods/ITEMS/mcl_itemframes/README.txt index c2756a1c9..99495b850 100644 --- a/mods/ITEMS/mcl_itemframes/README.txt +++ b/mods/ITEMS/mcl_itemframes/README.txt @@ -1,12 +1,12 @@ This mod has been rewritten and revamped by Michieal / Faerraven. Based on the code originally done by Zeg9, and then -heavily modified by the Mineclone 2 dev team. +heavily modified by the VoxeLibre dev team. This mod now supports all the base item frame functions, like rotating the displayed item, which it didn't do before it was rewritten. Additionally, Glow Frames have been added in, and item frames now has an API to allow new item frames to be created in other modules. Now requires the Screwdriver to have full functionality. -The code is licenced under the standard MineClone 2 license for usage, with the requirement that this readme is +The code is licenced under the standard VoxeLibre license for usage, with the requirement that this readme is included in the code / module. Model created by 22i, licensed under the diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua index 999becf05..b1b59e423 100644 --- a/mods/ITEMS/mcl_itemframes/item_frames_API.lua +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -638,7 +638,7 @@ function mcl_itemframes.create_base_definitions() paramtype = "light", paramtype2 = "facedir", 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, supported_node_facedir = 1 }, sounds = mcl_sounds.node_sound_defaults(), node_placement_prediction = "", diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pt_BR.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pt_BR.tr new file mode 100644 index 000000000..4c55b470f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_itemframes +Item Frame=Moldura +Item frames are decorative blocks in which items can be placed.=Molduras são blocos decorativos aos quais itens podem ser posicionadas. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Apenas posicione qualquer item na moldura. Use a moldura de novo para pegar o item de volta. +Can hold an item.=Pode segurar um item. +Glowing Item Frame=Moldura Brilhante +Glowing item frames are decorative blocks in which items can be placed.=Molduras brilhantes são blocos decorativos aos quais itens podem ser posicionados. +Can hold an item and glows.=Pode segurar um item e brilha. +Glow and Behold!=Brilhe e Veja! +Craft a glow item frame.=Fabrique uma moldura brilhante. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr index 73320ce14..84af50ab7 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr @@ -1,10 +1,10 @@ # textdomain: mcl_itemframes Item Frame=Рамка -Item frames are decorative blocks in which items can be placed.=Рамки — это отделочные блоки, в которых можно хранить предметы. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто вставьте в рамку любой предмет. Нажмите правой кнопкой мыши на рамку, чтобы взять предмет обратно. -Can hold an item.=Может хранить предмет. -Glowing Item Frame=Светящаяся рамка предмета -Glowing item frames are decorative blocks in which items can be placed.=Светящиеся рамки предметов — это отделочные блоки, в которых можно хранить предметы и заставлять их светиться. -Can hold an item and glows.=Может хранить предмет и светится. +Item frames are decorative blocks in which items can be placed.=Рамки это декоративные блоки, в которые можно помещать предметы. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Просто поместите в рамку любой предмет. Используйте рамку вновь, чтобы забрать из неё предмет обратно. +Can hold an item.=Может хранить предмет +Glowing Item Frame=Светящаяся рамка +Glowing item frames are decorative blocks in which items can be placed.=Светящаяся рамка это декоративный блок в который можно положить предметы. +Can hold an item and glows.=Светится и может хранить предмет Glow and Behold!=Сияй и созерцай! -Craft a glow item frame.=Создание светящейся рамки. \ No newline at end of file +Craft a glow item frame.=Создайте светящуюся рамку. \ No newline at end of file diff --git a/mods/ITEMS/mcl_jukebox/README.md b/mods/ITEMS/mcl_jukebox/README.md index 6376362bb..581addb09 100644 --- a/mods/ITEMS/mcl_jukebox/README.md +++ b/mods/ITEMS/mcl_jukebox/README.md @@ -1,4 +1,4 @@ -# Jukebox mod for MineClone 2. +# Jukebox mod for VoxeLibre. Based on the `jdukebox` mod by Jordach. This adds a jukebox block and music disc. Just place a music disc in a jukebox and music starts @@ -25,7 +25,7 @@ Note: 9 tracks are included. 3 music disc textures are currently unused. ### License Code licenced as GPLv3. Music under individual licenses (see abbreviations -above). Texture license: See main MineClone 2 README.md file. +above). Texture license: See main VoxeLibre README.md file. See here for the full license texts: diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index d817bdac7..e64bc52c7 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -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."), tiles = {"mcl_jukebox_top.png", "mcl_jukebox_side.png", "mcl_jukebox_side.png"}, 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, on_construct = function(pos) local meta = minetest.get_meta(pos) diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pt_BR.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pt_BR.tr new file mode 100644 index 000000000..6b46f67b9 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_jukebox +Music Disc=Disco de Música +A music disc holds a single music track which can be used in a jukebox to play music.=Um disco de música contém uma única faixa de música ao qual pode ser usado em uma jukebox para tocar música. +Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players.=Posicione um disco de música em uma jukebox vazia para tocar a música. Use novamente a jukebox para pegar o disco de música de volta. A música pode ser ouvida apenas por você, não por outros jogadores. +Music Disc=Disco de Música +@1—@2=@1-@2 +Jukebox=Jukebox +Jukeboxes play music when they're supplied with a music disc.=Jukeboxes tocam música quando são abastecidas com um disco de música. +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.=Posicione um disco de música em uma jukebox vazia para inserir o disco de música e tocar a música. Se a jukebox já tiver um disco de música, você pegará esse disco de música de volta antes. A música pode ser ouvida apenas por você, não por outros jogadores. +Now playing: @1—@2=Tocando: @1-@2 +Uses music discs to play music=Use discos de música para tocar música diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ru.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ru.tr index 1787ca229..977b154c7 100644 --- a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ru.tr +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ru.tr @@ -1,11 +1,11 @@ # textdomain: mcl_jukebox -Music Disc=Диск с музыкой -A music disc holds a single music track which can be used in a jukebox to play music.=Диск с музыкой содержит одну музыкальную запись, которую можно прослушивать при помощи проигрывателя. -Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players.=Поместите диск в пустой проигрыватель, чтобы включить музыку. [Используйте] проигрыватель вновь, чтобы вытащить диск. Музыку слышите только вы, другие игроки не слышат. -Music Disc=Диск с музыкой +Music Disc=Пластинка +A music disc holds a single music track which can be used in a jukebox to play music.=Пластинка содержит один музыкальный трек, который можно прослушивать при помощи проигрывателя. +Place a music disc into an empty jukebox to play the music. Use the jukebox again to retrieve the music disc. The music can only be heard by you, not by other players.=Поместите пластинку в пустой проигрыватель, чтобы включить музыку. Используйте проигрыватель снова, чтобы вытащить пластинку. Музыку слышите только вы, другие игроки не слышат. +Music Disc=Пластинка @1—@2=@1—@2 Jukebox=Проигрыватель -Jukeboxes play music when they're supplied with a music disc.=Проигрыватель воспроизводит музыку, если снабдить его музыкальным диском. -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.=Поместите диск в пустой проигрыватель, диск окажется в проигрывателе и заиграет музыка. Если в проигрывателе уже есть диск, вы сначала извлечёте его. Музыку можете услышать только вы, другие игроки не услышат. +Jukeboxes play music when they're supplied with a music disc.=Проигрыватель воспроизводит музыку, если положить в него пластинку +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.=Поместите пластинку в пустой проигрыватель, чтобы включить музыку. Если в проигрывателе уже есть пластинка, вы сначала извлечёте его. Музыку можете услышать только вы, другие игроки её не слышат. Now playing: @1—@2=Сейчас звучит: @1-@2 -Uses music discs to play music=Проигрывает музыку с дисков +Uses music discs to play music=Проигрывает музыку с пластинок diff --git a/mods/ITEMS/mcl_lanterns/init.lua b/mods/ITEMS/mcl_lanterns/init.lua index 5be325e48..f978358b7 100644 --- a/mods/ITEMS/mcl_lanterns/init.lua +++ b/mods/ITEMS/mcl_lanterns/init.lua @@ -118,7 +118,7 @@ function mcl_lanterns.register_lantern(name, def) node_placement_prediction = "", sunlight_propagates = true, light_source = def.light_level, - groups = {pickaxey = 1, attached_node = 1, deco_block = 1, lantern = 1}, + groups = {pickaxey = 1, attached_node = 1, deco_block = 1, lantern = 1, dig_by_piston=1}, selection_box = { type = "fixed", fixed = { diff --git a/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.pt_BR.tr b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.pt_BR.tr new file mode 100644 index 000000000..de683f688 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.pt_BR.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_lanterns +Lantern=Lanterna +Soul Lantern=Lanterna das Almas +Lanterns are light sources which can be placed on the top or the bottom of most blocks.=Lanternas são fontes de luz as quais podem ser posicionadas na parte superior ou inferior da maioria blocos. +Chain=Corrente +Chains are metallic decoration blocks.=Correntes são blocos de decoração metálicos. diff --git a/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ru.tr b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ru.tr new file mode 100644 index 000000000..ce14bd382 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ru.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_lanterns +Lantern=Фонарь +Soul Lantern=Фонарь душ +Lanterns are light sources which can be placed on the top or the bottom of most blocks.=Фонари это источники света которые можно поставить сверху или снизу большинства блоков. +Chain=Цепь +Chains are metallic decoration blocks.=Цепи это металлические декоративные блоки. \ No newline at end of file diff --git a/mods/ITEMS/mcl_lectern/README.txt b/mods/ITEMS/mcl_lectern/README.txt index 8afe7108e..9427c4d4a 100644 --- a/mods/ITEMS/mcl_lectern/README.txt +++ b/mods/ITEMS/mcl_lectern/README.txt @@ -1,13 +1,13 @@ --- -# Mineclone2-Lectern +# VoxeLibre-Lectern --- -A ground up creation of a lectern to be used in MineClone 2. Requires Minetest and Mineclone2. +A ground up creation of a lectern to be used in VoxeLibre. Requires Minetest and VoxeLibre. --- Created by Michieal (FaerRaven) @ DateTime: 01/07/2023 (07JAN2023) -* Made for MineClone 2 by Michieal. +* Made for VoxeLibrea by Michieal. * Texture made by Michieal; The model borrows the top from NathanS21's (Nathan Salapat) Lectern model; The rest of the lectern model was created by Michieal. * Creation date: 01/07/2023 (07JAN2023) diff --git a/mods/ITEMS/mcl_lectern/init.lua b/mods/ITEMS/mcl_lectern/init.lua index 98366b7b8..e98422249 100644 --- a/mods/ITEMS/mcl_lectern/init.lua +++ b/mods/ITEMS/mcl_lectern/init.lua @@ -76,8 +76,7 @@ local lectern_def = { if wdir == 0 then return itemstack -- IE., no Hanging Lecterns for you! - end - if wdir == 1 then + else -- (only make standing nodes...) -- Determine the rotation based on player's yaw local yaw = pi * 2 - placer:get_look_horizontal() @@ -136,5 +135,11 @@ minetest.register_craft({ } }) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_lectern:lectern", + burntime = 15, +}) + -- Base Aliases. minetest.register_alias("lectern", "mcl_lectern:lectern") diff --git a/mods/ITEMS/mcl_lectern/locale/mcl_lectern.pt_BR.tr b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.pt_BR.tr new file mode 100644 index 000000000..58b0e693d --- /dev/null +++ b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_lectern +Lectern=Atril +Lecterns not only look good, but are job site blocks for Librarians.=Atris não apenas são bonitos, mas são a estação de trabalho dos Bibliotecários. +Place the Lectern on a solid node for best results. May attract villagers, so it's best to place outside of where you call 'home'.=Posicione o atril em um bloco sólido para melhores resultados. Talvez atraia aldeões, então é melhor posicioná-lo do lado de fora do que você chama de 'lar'. diff --git a/mods/ITEMS/mcl_lectern/locale/mcl_lectern.ru.tr b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.ru.tr new file mode 100644 index 000000000..8728de159 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_lectern +Lectern=Кафедра +Lecterns not only look good, but are job site blocks for Librarians.=Кафедра не только красиво выглядит, но и служит рабочим местом для жителей библиотекарей +Place the Lectern on a solid node for best results. May attract villagers, so it's best to place outside of where you call 'home'.=Поставьте кафедру на твердый блок. Может привлечь жителей, так что лучше ставить в том месте, которое вы могли бы назвать 'домом'. \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.pt_BR.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.pt_BR.tr new file mode 100644 index 000000000..4a57a6dbf --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=Para-Raios +A block that attracts lightning=Um bloco que atrai raios diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ru.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ru.tr new file mode 100644 index 000000000..80fd8ba68 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=Громоотвод +A block that attracts lightning=Блок который притягивает молнии \ No newline at end of file diff --git a/mods/ITEMS/mcl_loom/README.md b/mods/ITEMS/mcl_loom/README.md index e91bad8fd..279ec65f4 100644 --- a/mods/ITEMS/mcl_loom/README.md +++ b/mods/ITEMS/mcl_loom/README.md @@ -2,7 +2,7 @@ mcl_loom -------- Looms, by PrairieWind -Adds Looms to MineClone 2/5. Used to add patterns to banners. +Adds Looms to VoxeLibre. Used to add patterns to banners. License of source code ---------------------- diff --git a/mods/ITEMS/mcl_loom/init.lua b/mods/ITEMS/mcl_loom/init.lua index 5475980bd..4562d286e 100644 --- a/mods/ITEMS/mcl_loom/init.lua +++ b/mods/ITEMS/mcl_loom/init.lua @@ -26,3 +26,9 @@ minetest.register_craft({ { "group:wood", "group:wood", "" }, } }) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_loom:loom", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.pt_BR.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.pt_BR.tr new file mode 100644 index 000000000..eef49ba0f --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom=Tear +Used to create banner designs=Usado para criar designs nos estandartes +This is the shepherd villager's work station. It is used to create banner designs.=Essa é a estação de trabalho do aldeão pastor. É usado para criar designs nos estandartes. diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr index 2442f76d5..c3a800100 100644 --- a/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr @@ -1,4 +1,4 @@ # textdomain: mcl_loom Loom=Ткацкий станок Used to create banner designs=Позволяет создавать узоры на флаге -This is the shepherd villager's work station. It is used to create banner designs.=Это рабочее место пастуха. Позволяет создавать узоры на флаге +This is the shepherd villager's work station. It is used to create banner designs.=Это рабочее место жителя пастуха. Позволяет создавать узоры на флаге diff --git a/mods/ITEMS/mcl_mangrove/init.lua b/mods/ITEMS/mcl_mangrove/init.lua index 6e7767541..a8ab01370 100644 --- a/mods/ITEMS/mcl_mangrove/init.lua +++ b/mods/ITEMS/mcl_mangrove/init.lua @@ -183,7 +183,7 @@ mcl_flowerpots.register_potted_flower("mcl_mangrove:propagule", { image = "mcl_mangrove_propagule.png", }) -local water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" +local water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#3F76E4" local wlroots = { description = S("water logged mangrove roots"), @@ -194,12 +194,12 @@ local wlroots = { S("These cannot be crafted yet only occure when get in contact of water."), _doc_items_hidden = false, tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} + {name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} }, special_tiles = { -- New-style water source material (mostly unused) { - name="default_water_source_animated.png", + name="mcl_core_water_source_animation.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, backface_culling = false, } @@ -221,7 +221,7 @@ local wlroots = { liquids_pointable = true, drop = "mcl_mangrove:mangrove_roots", groups = { - handy = 1, hoey = 1, water=3, liquid=3, puts_out_fire=1, dig_by_piston = 1, deco_block = 1, not_in_creative_inventory=1 }, + handy = 1, hoey = 1, water=3, liquid=3, puts_out_fire=1, dig_by_piston = 1, deco_block = 1, waterlogged = 1, not_in_creative_inventory=1 }, _mcl_blast_resistance = 100, _mcl_hardness = -1, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode on_construct = function(pos) @@ -245,7 +245,7 @@ local rwlroots = table.copy(wlroots) -- FIXME luacheck complains that this is a repeated definition of water_tex. -- Maybe the tiles definition below should be replaced with the animated tile -- definition as per above? -water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#0084FF" +water_tex = "mcl_core_water_source_animation.png^[verticalframe:16:0^[multiply:#0084FF" rwlroots.tiles = { "("..water_tex..")^mcl_mangrove_roots_top.png", "("..water_tex..")^mcl_mangrove_roots_side.png", @@ -266,7 +266,7 @@ minetest.register_node("mcl_mangrove:river_water_logged_roots",rwlroots) minetest.register_node("mcl_mangrove:mangrove_mud_roots", { description = S("Muddy Mangrove Roots"), - _tt_help = S("crafted with Mud and Mangrove roots"), + _tt_help = S("Crafted with Mud and Mangrove roots"), _doc_items_longdesc = S("Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it."), tiles = { "mcl_mud.png^mcl_mangrove_roots_top.png", @@ -399,12 +399,39 @@ minetest.register_craft({ } }) +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood 4", + recipe = { + {"mcl_mangrove:mangrove_tree_bark"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood 4", + recipe = { + {"mcl_mangrove:mangrove_stripped"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood 4", + recipe = { + {"mcl_mangrove:mangrove_stripped_bark"}, + } + }) + minetest.register_craft({ type = "fuel", recipe = "group:fence_wood", burntime = 15, }) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mangrove:mangrove_roots", + burntime = 15, +}) + local adjacents = { vector.new(1,0,0), vector.new(-1,0,0), diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr index 4d1590dbd..94cc9ac6d 100644 --- a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr @@ -6,9 +6,9 @@ The bark of a Mangrove tree.=L'écorce d'un palétuvier. Mangrove Wood Planks=Planches de palétuvier Mangrove Leaves=Feuilles de palétuvier Mangrove leaves are grown from mangrove trees.=les feuilles de palétuvier poussent sur les palétuviers. -Stripped Mangrove Wood=Bûche de palétuvier écorcée +Stripped Mangrove Log=Bûche de palétuvier écorcée The stripped wood of a Mangrove tree=La bûche écorcée d'un palétuvier -Stripped Mangrove Bark=Bois de palétuvier écorcé +Stripped Mangrove Wood=Bois de palétuvier écorcé The stripped bark of a Mangrove tree=Le bois écorcé d'un palétuvier Mangrove Roots=Racines de palétuvier Mangrove roots are decorative blocks that form as part of mangrove trees.=Les racines de palétuvier sont des blocs décoratifs qui font partie des palétuviers. @@ -21,7 +21,7 @@ water logged mangrove roots=racines de palétuvier immergées Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=Les racines de palétuvier sont un bloc plein mais qui peut être immergé et ne remplace pas l'eau. These cannot be crafted yet only occure when get in contact of water.=Elles ne peuvent être fabriquées mais se forment au contact de l'eau. Muddy Mangrove Roots=Racines de palétuvier boueuses -crafted with Mud and Mangrove roots=fabriqué avec de la boue et des racines de palétuvier +Crafted with Mud and Mangrove roots=Fabriqué avec de la boue et des racines de palétuvier Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=Les racines de palétuvier boueuses sont un bloc du marécage de la mangrove. Il noie un joueur à l'intérieur. Mangrove Door=Porte en palétuvier Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Les portes en bois sont des barrières hautes à 2 blocs qui peuvent être ouvertes ou fermées à la main et par un signal redstone. diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr index 6df59f6fb..e5b826bb7 100644 --- a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr @@ -6,9 +6,9 @@ The bark of a Mangrove tree.=マングローブの木の樹皮です。 Mangrove Wood Planks=マングローブの板材 Mangrove Leaves=マングローブの葉 Mangrove leaves are grown from mangrove trees.=マングローブの葉は、マングローブの木から育ちます。 -Stripped Mangrove Wood=樹皮を剥いだマングローブの木 +Stripped Mangrove Log=樹皮を剥いだマングローブの木 The stripped wood of a Mangrove tree=剥き身となったマングローブの木 -Stripped Mangrove Bark=剥がされたマングローブの樹皮 +Stripped Mangrove Wood=剥がされたマングローブの樹皮 The stripped bark of a Mangrove tree=マングローブの木から剥がされた樹皮 Mangrove Roots=マングローブの根 Mangrove roots are decorative blocks that form as part of mangrove trees.=マングローブの根は、マングローブの木の一部として形成される装飾ブロックです。 @@ -21,7 +21,7 @@ water logged mangrove roots=水没したマングローブの根 Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=マングローブの根は、フルブロックであるにもかかわらず水没することがあり、水が流出しない These cannot be crafted yet only occure when get in contact of water.=これはクラフトできないものの、水と接触したときだけ発生します。 Muddy Mangrove Roots=泥に塗れたマングローブの根 -crafted with Mud and Mangrove roots=泥とマングローブの根で作られたもの +Crafted with Mud and Mangrove roots=泥とマングローブの根で作られたもの Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=泥に塗れたマングローブの根は、マングローブの沼地から1ブロックの場所にあります。 Mangrove Door=マングローブのドア Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=木製のドアは、高さ2ブロックの障壁で、手やレッドストーンの信号で開閉できます。 diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.pt_BR.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.pt_BR.tr new file mode 100644 index 000000000..07b1f4826 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.pt_BR.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood=Madeira de Mangue +The trunk of a Mangrove tree.=O tronco de uma árvore de mangue. +Mangrove Bark=Casca de Mangue +The bark of a Mangrove tree.=A casca de uma árvore de mangue. +Mangrove Wood Planks=Tábuas de Mangue +Mangrove Leaves=Folhas de Mangue +Mangrove leaves are grown from mangrove trees.=Folhas de mangue crescem em árvores de mangue. +Stripped Mangrove Log=Tronco de Mangue Descascado +The stripped wood of a Mangrove tree=A madeira descascada de uma árvore de mangue. +Stripped Mangrove Wood=Madeira de Mangue Descascada +The stripped bark of a Mangrove tree=A casca descascada de uma árvore de mangue. +Mangrove Roots=Raízes de Mangue +Mangrove roots are decorative blocks that form as part of mangrove trees.=Raízes de mangue são blocos decorativos que se formam como parte das árvores de mangue. +Mangrove Propagule=Propágulo de Mangue +Needs soil and light to grow=Precisa de solo e luz para crescer +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.=Quando posicionado em solo (como em terra) e exposto à luz, um propágulo irá crescer uma árvore de mangue depois de algum tempo. +Hanging Propagule=Propágulo Pendurado +Grows on Mangrove leaves=Cresce em folhas de mangue +water logged mangrove roots=Raízes de Mangue Alagadas +Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=Raízes de mangue, mesmo sendo um bloco inteiro, podem ser alagadas e não escorre água delas. +These cannot be crafted yet only occure when get in contact of water.=Essas não podem ser fabricadas ainda ocorrendo apenas quando tem contato com a água. +Muddy Mangrove Roots=Raízes Barrentas de Mangue +Crafted with Mud and Mangrove roots=Fabricadas com barro e raízes de mangue +Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=Raízes barrentas de mangue é um bloco dos pântanos de mangue. Afunda o jogador um pouco para dentro de si. +Mangrove Door=Porta de Mangue +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Portas de madeira são barreiras de 2 blocos de altura as quais podem ser abertas ou fechadas pela mão e por um sinal de redstone. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Para abrir ou fechar uma porta de madeira, clique com o botão direito nela ou alimente-a em sua metade inferior com um sinal de redstone. +Mangrove Trapdoor=Alçapão de Mangue +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Alçapões de madeira são barreiras horizontais as quais podem ser abertas ou fechadas com a mão ou um sinal de redstone. Eles ocupam a parte superior ou inferior de um bloco, dependendo de como eles foram posicionados. Quando abertos, eles podem ser escalados como uma escada. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Para abrir e fechar o alçapão, clique com o botão direito nele ou envie um sinal de redstone para ele. +Mangrove Wood Fence=Cerca de Mangue +Mangrove Wood Fence Gate=Portão de Mangue +Mangrove Wood Stairs=Escadas de Mangue +Mangrove Wood Slab=Laje de Mangue +Double Mangrove Wood Slab=Laje Dupla de Mangue diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ru.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ru.tr new file mode 100644 index 000000000..c16f757cf --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ru.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood=Мангровая древесина +The trunk of a Mangrove tree.=Ствол мангрового дерева. +Mangrove Bark=Мангровая кора +The bark of a Mangrove tree.=Кора мангрового дерева. +Mangrove Wood Planks=Мангровые доски +Mangrove Leaves=Мангровые листья +Mangrove leaves are grown from mangrove trees.=Мангровые листья растут на мангровых деревьях. +Stripped Mangrove Log=Обтёсанная мангровая древесина +The stripped wood of a Mangrove tree=Обтёсанная мангровая древесина +Stripped Mangrove Wood=Обтёсанная мангровая кора +The stripped bark of a Mangrove tree=Обтёсанная мангровая кора +Mangrove Roots=Мангровые корни +Mangrove roots are decorative blocks that form as part of mangrove trees.=Мангровые корни это декоративный блок который формирует часть мангровых деревьев. +Mangrove Propagule=Мангровый отросток +Needs soil and light to grow=Нуждается в почве и свете, чтобы расти +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.=После посадки на почву (например, на землю) при наличии света мангровый отросток вырастет в мангровое дерево через некоторое время. +Hanging Propagule=Свисающий мангровый отросток +Grows on Mangrove leaves=Растет на мангровой листве. +water logged mangrove roots=Затопленные мангровые корни +Mangrove roots, despite being a full block, can be waterlogged and do not flow water out=Мангровые корни, не смотря на то что это полный блок, может быть затоплен и не выпускать воду наружу. +These cannot be crafted yet only occure when get in contact of water.=Нельзя скрафтить, появляется только при контакте с водой. +Muddy Mangrove Roots=Грязные мангровые корни +Crafted with Mud and Mangrove roots=Крафтится с помощью грязи и мангровых корней +Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.=Грязные мангровые корни это блок из мангровых болот. Игрок немного погружается внутрь них. +Mangrove Door=Мангровая дверь +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Деревянные двери это преграды высотой в 2 блока, которые можно открывать и закрывать вручную и по сигналу редстоуна. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Чтобы открыть или закрыть деревянную дверь, кликните правой либо подайте к её нижней части сигнал редстоуна. +Mangrove Trapdoor=Мангровый люк +Wooden trapdoors are horizontal barriers which can be opened and closed by hand or a redstone signal. 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.=Деревянные люки это горизонтальные преграды, которые можно открывать и закрывать вручную и по сигналу редстоуна. Они занимают верхнюю или нижнюю часть блока, в зависимости от того, как они были установлены. В открытом состоянии по ним можно карабкаться, как по лестницам. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Чтобы открыть или закрыть деревянный люк, кликните по нему правой кнопкой либо подайте на него сигнал редстоуна. +Mangrove Wood Fence=Мангровый забор +Mangrove Wood Fence Gate=Мангровая калитка +Mangrove Wood Stairs=Мангровые ступени +Mangrove Wood Slab=Мангровая плита +Double Mangrove Wood Slab=Двойная мангровая плита diff --git a/mods/ITEMS/mcl_mangrove/locale/template.txt b/mods/ITEMS/mcl_mangrove/locale/template.txt index 3de2b9ced..cc0fccf48 100644 --- a/mods/ITEMS/mcl_mangrove/locale/template.txt +++ b/mods/ITEMS/mcl_mangrove/locale/template.txt @@ -6,9 +6,9 @@ The bark of a Mangrove tree.= Mangrove Wood Planks= Mangrove Leaves= Mangrove leaves are grown from mangrove trees.= -Stripped Mangrove Wood= +Stripped Mangrove Log= The stripped wood of a Mangrove tree= -Stripped Mangrove Bark= +Stripped Mangrove Wood= The stripped bark of a Mangrove tree= Mangrove Roots= Mangrove roots are decorative blocks that form as part of mangrove trees.= @@ -21,7 +21,7 @@ water logged mangrove roots= Mangrove roots, despite being a full block, can be waterlogged and do not flow water out= These cannot be crafted yet only occure when get in contact of water.= Muddy Mangrove Roots= -crafted with Mud and Mangrove roots= +Crafted with Mud and Mangrove roots= Muddy Mangrove Roots is a block from mangrove swamp.It drowns player a bit inside it.= Mangrove Door= Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.= diff --git a/mods/ITEMS/mcl_maps/colors.json b/mods/ITEMS/mcl_maps/colors.json index 4929a2f66..ae09ab483 100644 --- a/mods/ITEMS/mcl_maps/colors.json +++ b/mods/ITEMS/mcl_maps/colors.json @@ -4664,7 +4664,7 @@ 126, 164 ], - "default_water_source_animated.png": [ + "mcl_core_water_source_animation.png": [ 37, 98, 129 @@ -4984,7 +4984,7 @@ 79, 64 ], - "default_water_flowing_animated.png": [ + "mcl_core_water_flow_animation.png": [ 38, 101, 129 @@ -5009,7 +5009,7 @@ 89, 86 ], - "default_lava_flowing_animated.png": [ + "mcl_core_lava_flow_animation.png": [ 177, 42, 16 @@ -5059,7 +5059,7 @@ 142, 123 ], - "default_lava_source_animated.png": [ + "mcl_core_lava_source_animation.png": [ 180, 45, 17 @@ -6604,16 +6604,6 @@ 56, 64 ], - "default_river_water_flowing_animated.png": [ - 38, - 123, - 130 - ], - "default_river_water_source_animated.png": [ - 37, - 120, - 130 - ], "mcl_armor_stand_item.png": [ 134, 114, @@ -9009,17 +8999,17 @@ 127, 113 ], - "bucket_river_water.png": [ + "mcl_buckets_river_water_bucket.png": [ 139, 152, 155 ], - "bucket_water.png": [ + "mcl_buckets_water_bucket.png": [ 139, 147, 155 ], - "bucket.png": [ + "mcl_buckets_bucket.png": [ 147, 143, 139 diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.pt_BR.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.pt_BR.tr new file mode 100644 index 000000000..a28d211b0 --- /dev/null +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_maps +Empty Map=Mapa Vazio +Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Mapas vazios não são úteis como mapas, mas eles podem ser empilhados e transfomados em mapas aos quais podem ser usados. +Rightclick to create a filled map (which can't be stacked anymore).=Clique com o botão direito para criar um mapa preenchido (ao qual não pode mais ser empilhado). +Map=Mapa +Shows a map image.=Mostra uma imagem do mapa. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Quando criado, o mapa salva a área próxima como uma imagem que pode ser visualizada sempre que você segurar o mapa. +Hold the map in your hand. This will display a map on your screen.=Segure o mapa em suas mãos. Isso mostrará um mapa em sua tela. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr index 3bb7d6a19..9c3631f37 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr @@ -1,5 +1,8 @@ # textdomain: mcl_maps Empty Map=Пустая карта -Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Пустые карты не могут использоваться в качестве карт, но могут складываться в стопки, а также могут быть превращены в полноценные карты. -Rightclick to start using the map (which can't be stacked anymore).=Нажмите правую кнопку мыши, чтобы начать использовать карту (её больше нельзя будет уложить в стопку). +Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Пустые карты не так полезны как карты, но могут складываться в стопки, а также могут быть превращены в полноценные карты. +Rightclick to create a filled map (which can't be stacked anymore).=Правый клик, чтобы заполнить карту (больше не может складываться в стопки). Map=Карта +Shows a map image.=Показать карту. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=После создания карта сохраняет ближайшую местность которую можно посмотеть в любое время взяв карту в руки. +Hold the map in your hand. This will display a map on your screen.=Возьмите карту в руки. Так появится изображение карты на экране. diff --git a/mods/ITEMS/mcl_mobitems/init.lua b/mods/ITEMS/mcl_mobitems/init.lua index 1767dfd1e..c1b814fec 100644 --- a/mods/ITEMS/mcl_mobitems/init.lua +++ b/mods/ITEMS/mcl_mobitems/init.lua @@ -20,7 +20,7 @@ minetest.register_craftitem("mcl_mobitems:mutton", { wield_image = "mcl_mobitems_mutton_raw.png", on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), - groups = { food = 2, eatable = 2, smoker_cookable = 1 }, + groups = { food = 2, eatable = 2, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 1.2, stack_max = 64, }) @@ -44,7 +44,7 @@ minetest.register_craftitem("mcl_mobitems:beef", { wield_image = "mcl_mobitems_beef_raw.png", on_place = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3), - groups = { food = 2, eatable = 3, smoker_cookable = 1 }, + groups = { food = 2, eatable = 3, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 1.8, stack_max = 64, }) @@ -69,7 +69,7 @@ minetest.register_craftitem("mcl_mobitems:chicken", { wield_image = "mcl_mobitems_chicken_raw.png", on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), - groups = { food = 2, eatable = 2, smoker_cookable = 1 }, + groups = { food = 2, eatable = 2, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 1.2, stack_max = 64, }) @@ -93,7 +93,7 @@ minetest.register_craftitem("mcl_mobitems:porkchop", { wield_image = "mcl_mobitems_porkchop_raw.png", on_place = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3), - groups = { food = 2, eatable = 3, smoker_cookable = 1 }, + groups = { food = 2, eatable = 3, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 1.8, stack_max = 64, }) @@ -117,7 +117,7 @@ minetest.register_craftitem("mcl_mobitems:rabbit", { wield_image = "mcl_mobitems_rabbit_raw.png", on_place = minetest.item_eat(3), on_secondary_use = minetest.item_eat(3), - groups = { food = 2, eatable = 3, smoker_cookable = 1 }, + groups = { food = 2, eatable = 3, smoker_cookable = 1, campfire_cookable = 1 }, _mcl_saturation = 1.8, stack_max = 64, }) @@ -134,15 +134,49 @@ minetest.register_craftitem("mcl_mobitems:cooked_rabbit", { stack_max = 64, }) --- Reset food poisoning and status effects -local function drink_milk(itemstack, player, pointed_thing) - local bucket = minetest.do_item_eat(0, "mcl_buckets:bucket_empty", itemstack, player, pointed_thing) - -- Check if we were allowed to drink this (eat delay check) - if mcl_hunger.active and (bucket:get_name() ~= "mcl_mobitems:milk_bucket" or minetest.is_creative_enabled(player:get_player_name())) then - mcl_hunger.stop_poison(player) +local function drink_milk_delayed(itemstack, player, pointed_thing) + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + if player and not player:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, player, itemstack) or itemstack + end + end + elseif pointed_thing.type == "object" then + return itemstack end - mcl_potions._reset_player_effects(player) - return bucket + + local function drink_milk(itemstack, player, pointed_thing) + -- Check if we were allowed to drink this (eat delay check) + if mcl_hunger.active and ( + player:get_inventory():get_stack("main", player:get_wield_index(), itemstack) == "mcl_mobitems:milk_bucket" or + minetest.is_creative_enabled(player:get_player_name()) + ) then + mcl_hunger.stop_poison(player) + end + mcl_potions._reset_effects(player) + end + + -- Wrapper for handling mcl_hunger delayed eating + local name = player:get_player_name() + local hunger_internal = mcl_hunger.eat_internal[name] + hunger_internal._custom_itemstack = itemstack -- Used as comparison to make sure the custom wrapper executes only when the same item is eaten + hunger_internal._custom_var = { + itemstack = itemstack, + player = player, + pointed_thing = pointed_thing, + } + hunger_internal._custom_func = drink_milk + hunger_internal._custom_wrapper = function(name) + local hunger_internal2 = mcl_hunger.eat_internal[name] + hunger_internal2._custom_func( + hunger_internal2._custom_var.itemstack, + hunger_internal2._custom_var.player, + hunger_internal2._custom_var.pointed_thing + ) + end + + minetest.do_item_eat(0, "mcl_buckets:bucket_empty", itemstack, player, pointed_thing) end minetest.register_craftitem("mcl_mobitems:milk_bucket", { @@ -152,8 +186,8 @@ minetest.register_craftitem("mcl_mobitems:milk_bucket", { _doc_items_usagehelp = S("Use the placement key to drink the milk."), inventory_image = "mcl_mobitems_bucket_milk.png", wield_image = "mcl_mobitems_bucket_milk.png", - on_place = drink_milk, - on_secondary_use = drink_milk, + on_place = drink_milk_delayed, + on_secondary_use = drink_milk_delayed, stack_max = 1, groups = { food = 3, can_eat_when_full = 1 }, }) @@ -197,6 +231,46 @@ minetest.register_craftitem("mcl_mobitems:string",{ groups = { craftitem = 1 }, }) +minetest.register_craftitem("mcl_mobitems:spectre_membrane",{ + description = S("Spectre Membrane"), + _doc_items_longdesc = S("This is a crafting component dropped from dead spectres."), + inventory_image = "vl_mobitems_spectre_membrane.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:shiny_ice_crystal",{ + description = S("Shiny Ice Crystal"), + _doc_items_longdesc = S("This item is mainly used for crafting."), + inventory_image = "vl_mobitems_ice_crystal.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:aery_charge",{ + description = S("Aery Charge"), + _doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO shoot? + inventory_image = "vl_mobitems_aery_charge.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:crystalline_drop",{ + description = S("Crystalline Drop"), + _doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO other uses? + inventory_image = "vl_mobitems_crystalline_drop.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:earthen_ash",{ + description = S("Earthen Ash"), + _doc_items_longdesc = S("This item is mainly used for crafting."), -- TODO other uses? + inventory_image = "vl_mobitems_earthen_ash.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + minetest.register_craftitem("mcl_mobitems:blaze_rod", { description = S("Blaze Rod"), _doc_items_longdesc = S("This is a crafting component dropped from dead blazes."), @@ -298,7 +372,7 @@ minetest.register_craftitem("mcl_mobitems:rabbit_stew", { stack_max = 1, on_place = minetest.item_eat(10, "mcl_core:bowl"), on_secondary_use = minetest.item_eat(10, "mcl_core:bowl"), - groups = { food = 3, eatable = 10 }, + groups = { food = 2, eatable = 10 }, _mcl_saturation = 12.0, }) @@ -570,6 +644,6 @@ minetest.register_craft({ minetest.register_on_item_eat(function (hp_change, replace_with_item, itemstack, user, pointed_thing) -- poisoning with spider eye if itemstack:get_name() == "mcl_mobitems:spider_eye" then - mcl_potions.poison_func(user, 1, 4) + mcl_potions.give_effect_by_level("poison", user, 1, 4) end end) diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr index 9e94befa4..0b3e20f39 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr @@ -2,7 +2,7 @@ Rotten Flesh=Chair putréfiée 80% chance of food poisoning=80% de chances d'intoxication alimentaire -Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while.=Beurk! Ce morceau de chair a clairement connu des jours meilleurs. Si vous êtes vraiment désespéré, vous pouvez le manger pour restaurer quelques points de faim, mais il y a 80% de chances qu'il provoque une intoxication alimentaire, ce qui augmente votre faim pendant un certain temps. +Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while.=Beurk ! Ce morceau de chair a clairement connu des jours meilleurs. Si vous êtes vraiment désespéré, vous pouvez le manger pour restaurer quelques points de faim, mais il y a 80% de chances qu'il provoque une intoxication alimentaire, ce qui augmente votre faim pendant un certain temps. Raw Mutton=Mouton cru @@ -10,7 +10,7 @@ Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will gr Cooked Mutton=Mouton cuit Cooked mutton is the cooked flesh from a sheep and is used as food.=Le mouton cuit est la chair cuite d'un mouton et est utilisé comme nourriture. -Raw Beef=Boeuf Cru +Raw Beef=Boeuf cru Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.=Le boeuf cru est la chair des vaches et peut être mangé en toute sécurité. La cuisson augmentera considérablement sa valeur nutritive. @@ -23,25 +23,25 @@ Raw chicken is a food item which is not safe to consume. You can eat it to resto Cooked Chicken=Poulet cuit A cooked chicken is a healthy food item which can be eaten.=Un poulet cuit est un aliment sain qui peut être mangé. -Raw Porkchop=Porc Cru +Raw Porkchop=Porc cru A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.=Un porc cru est la chair d'un porc et peut être mangée en toute sécurité. La cuisson augmentera considérablement sa valeur nutritive. Cooked Porkchop=Porc cuit Cooked porkchop is the cooked flesh of a pig and is used as food.=Le porc cuit est la chair cuite d'un porc et est utilisé comme aliment. -Raw Rabbit=Lapin Cru +Raw Rabbit=Lapin cru Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.=Le lapin cru est un aliment provenant d'un lapin mort. Il peut être mangé en toute sécurité. La cuisson augmentera sa valeur nutritive. Cooked Rabbit=Lapin cuit This is a food item which can be eaten.=Il s'agit d'un aliment qui peut être mangé. Milk=Lait -Removes all status effects=Supprime tous les effets de statut! +Removes all status effects=Supprime tous les effets de statut ! Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=Le lait est très rafraîchissant et peut être obtenu en utilisant un seau sur une vache. Le boire supprimera tous les effets de statut, mais ne restaure aucun point de faim. Use the placement key to drink the milk.=Utilisez la touche de placement pour boire le lait. -Spider Eye=Œil d'araignée +Spider Eye=Oeil d'araignée Poisonous=Toxique Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly.=Les yeux d'araignée sont utilisés principalement dans l'artisanat. Si vous êtes vraiment désespéré, vous pouvez manger un œil d'araignée, mais cela vous empoisonnera brièvement. @@ -102,7 +102,7 @@ A warped fungus on a stick can be used on saddled striders to ride them.=Un cham Place it on a saddled strider to mount it. You can now ride the strider like a horse. Striders will also walk towards you when you just wield the fungus on a stick.=Placez-le sur un arpenteur sellé pour le monter. Vous pouvez maintenant monter l'arpenteur comme un cheval. Les arpenteurs marcheront également vers vous lorsque vous brandirez le champignon sur un bâton. Nautilus Shell=Coquille de nautile -Used to craft a conduit=Utilisé pour fabriquer un conduit. +Used to craft a conduit=Utilisé pour fabriquer un conduit The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell.=La Coquille de nautile est utilisée pour fabriquer un conduit. Elles peuvent être obtenues en pêchant ou en tuant un noyé qui tient une coquille. Heart of the Sea=Coeur de la Mer The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest.=Le Cœur de la Mer est utilisé pour fabriquer un conduit. Il peut être obtenu dans un coffre au trésor enterré. diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr index a58bfb474..484bc2d61 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr @@ -58,6 +58,12 @@ This item is dropped by dead squids. Squid ink can be used to as an ingredient String=Nić Strings are used in crafting.=Nić jest użyteczna w wytwarzaniu. +Spectre Membrane=Błona Widma +This is a crafting component dropped from dead spectres.=Jest to materiał do wytwarzania wypadający z martwych widm. +Shiny Ice Crystal=Lśniący Kryształ Lodu +Aery Charge=Powietrzny Ładunek +Crystalline Drop=Krystaliczna Kropla +Earthen Ash=Ziemny Popiół Blaze Rod=Płomienna różdżka This is a crafting component dropped from dead blazes.=Jest to materiał do wytwarzania wypadający z martwych płomyków. Blaze Powder=Płomienny proszek diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr index 4e3fc020b..a8771c238 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr @@ -1,105 +1,120 @@ # textdomain: mcl_mobitems -Rotten Flesh=Гнилое мясо -80% chance of food poisoning=Вероятность отравления 80% +Rotten Flesh=Гнилая плоть +80% chance of food poisoning=Вероятность отравления: 80% -Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while.=БУЭ! Этот кусок гнили явно знавал лучшие времена. Если вы отчаялись, то можете съесть его, восстановив несколько очков голода, но с вероятностью 80% вы получите пищевое отравление, которое усилит ваш голод на некоторое время. +Yuck! This piece of flesh clearly has seen better days. If you're really desperate, you can eat it to restore a few hunger points, but there's a 80% chance it causes food poisoning, which increases your hunger for a while.=Буэ! Этот кусок гнили явно знавал лучшие времена. Если вы отчаялись, то можете съесть его, восстановив несколько очков голода, но с вероятностью 80% вы получите пищевое отравление, которое усилит ваш голод на некоторое время. Raw Mutton=Сырая баранина Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.=Сырая баранина это мясо овцы, его можно безопасно есть. Приготовление значительно увеличивает его питательную ценность. Cooked Mutton=Жареная баранина -Cooked mutton is the cooked flesh from a sheep and is used as food.=Жареная баранина это запечённое мясо овцы, употребляемое в пищу. +Cooked mutton is the cooked flesh from a sheep and is used as food.=Жареная баранина это приготовленное мясо овцы, это съедобный продукт. Raw Beef=Сырая говядина Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.=Сырая говядина это мясо коровы, его можно безопасно есть. Приготовление значительно увеличивает его питательную ценность. -Steak=Стейк -Steak is cooked beef from cows and can be eaten.=Стейк это приготовленное мясо коровы, его можно есть. -Raw Chicken=Сырая курица -30% chance of food poisoning=Вероятность отравления 30% +Steak=Жареная говядина +Steak is cooked beef from cows and can be eaten.=Жареная говядина это приготовленное мясо коровы, это съедобный продукт. +Raw Chicken=Сырая курятина +30% chance of food poisoning=Вероятность отравления: 30% -Raw chicken is a food item which is not safe to consume. You can eat it to restore a few hunger points, but there's a 30% chance to suffer from food poisoning, which increases your hunger rate for a while. Cooking raw chicken will make it safe to eat and increases its nutritional value.=Сырая курица это продуктовый предмет, небезопасный для употребления. Вы можете его съесть для восстановления нескольких очков голода, но с вероятностью 30% вы пострадаете от пищевого отравление, которое усилит ваш голод на некоторое время. Приготовление сырой курицы сделает её безопасной для еды, значительно увеличив питательную ценность. +Raw chicken is a food item which is not safe to consume. You can eat it to restore a few hunger points, but there's a 30% chance to suffer from food poisoning, which increases your hunger rate for a while. Cooking raw chicken will make it safe to eat and increases its nutritional value.=Сырая курица это съедобный предмет, небезопасный для употребления. Вы можете его съесть для восстановления нескольких очков голода, но с вероятностью 30% вы пострадаете от пищевого отравление, которое усилит ваш голод на некоторое время. Приготовление сырой курицы сделает её безопасной для еды, значительно увеличив питательную ценность. -Cooked Chicken=Жареный цыплёнок -A cooked chicken is a healthy food item which can be eaten.=Жареный цыплёнок это здоровый питательный продукт, его можно есть. +Cooked Chicken=Жареная курятина +A cooked chicken is a healthy food item which can be eaten.=Жареная курица это съедобный продукт. Raw Porkchop=Сырая свинина A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.=Сырая свинина это мясо свиньи, его можно безопасно есть. Приготовление значительно увеличивает его питательную ценность. -Cooked Porkchop=Свиная отбивная -Cooked porkchop is the cooked flesh of a pig and is used as food.=Свиная отбивная это приготовленное мясо свиньи, его можно есть. +Cooked Porkchop=Жареная свинина +Cooked porkchop is the cooked flesh of a pig and is used as food.=Жареная свинина это приготовленное мясо свиньи, это съедобный продукт. Raw Rabbit=Сырая крольчатина Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.=Сырая крольчатина это мясо кролика, его можно безопасно есть. Приготовление значительно увеличивает его питательную ценность. -Cooked Rabbit=Приготовленный кролик -This is a food item which can be eaten.=Это пищевой продукт, его можно есть. +Cooked Rabbit=Жареная крольчатина +This is a food item which can be eaten.=Приготовленная крольчатина это съедобный продукт. Milk=Молоко Removes all status effects=Убирает все эффекты состояния -Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=Молоко отлично освежает, его можно получить, применив ведро к корове. Выпив молока, вы избавитесь от всех эффектов состояния, но не восстановите очков голода. +Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will remove all status effects, but restores no hunger points.=Молоко отлично освежает, его можно получить, использовав ведро на корове. Выпив молока, вы избавитесь от всех эффектов, но не восстановите очков голода. -Use the placement key to drink the milk.=Используйте клавишу размещения, чтобы выпить молоко. +Use the placement key to drink the milk.=Используйте правую кнопку мыши, чтобы выпить молоко. Spider Eye=Паучий глаз Poisonous=Ядовито -Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly.=Паучьи глаза в основном используются для крафтинга. Если вы отчаялись, то можете съесть их, но они вас на некоторое время отравят. +Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly.=Паучьи глаза в основном используются для крафта. Если вы отчаялись, то можете съесть их, но они вас на некоторое время отравят. Bone=Кость Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient.=Кости можно использовать для приручения волков, чтобы они защищали вас. -Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Положите кость рядом с волками, чтобы привлечь их. Используйте клавишу “Разместить” на волке, чтобы дать ему кость и приручить его. Вы можете командовать приручёнными волками с помощью клавиши “Разместить”. +Wield the bone near wolves to attract them. Use the “Place” key on the wolf to give it a bone and tame it. You can then give commands to the tamed wolf by using the “Place” key on it.=Возьмите в руку кость рядом с волками, чтобы привлечь их. Используйте кость на волке, чтобы приручить его. Вы можете командовать приручёнными волками с помощи правой кнопки мыши. Squid Ink Sac=Чернильный мешок -This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.= +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.=Этот предмет выпадает с мёртвых спрутов. Используется для создания книги с пером и чёрного красителя. -String=Нити -Strings are used in crafting.=Нити используются для крафтинга +String=Нить +Strings are used in crafting.=Нить используются для крафта Blaze Rod=Огненный стержень -This is a crafting component dropped from dead blazes.=Это крафтинговый ингредиент, отбрасываемый ифритом +This is a crafting component dropped from dead blazes.=Это материал для крафта, выпадающий из ифрита. Blaze Powder=Огненный порошок -This item is mainly used for crafting.=Этот предмет в основном используется для крафтинга. +This item is mainly used for crafting.=Огненный порошок это материал для крафта и топливо для варочной стойки. Magma Cream=Лавовый крем -Magma cream is a crafting component.=Лавовый крем это крафтинговый компонент. +Magma cream is a crafting component.=Лавовый крем это материал для крафта. Ghast Tear=Слеза гаста Place this item in an item frame as decoration.=Поместите это в рамку как украшение. Nether Star=Звезда Ада -A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=Звезда Ада выбрасывается при смерти иссушителя. Поместите её в рамку, чтобы показать миру ваше величие! Либо просто как украшение. +A nether star is dropped when the Wither dies. Place it in an item frame to show the world how hardcore you are! Or just as decoration.=Звезда Ада выбрасывается при смерти иссушителя. Поместите её в рамку, чтобы показать миру ваше величие! Leather=Кожа -Leather is a versatile crafting component.=Кожа это универсальный крафт-компонент. +Leather is a versatile crafting component.=Кожа это универсальный материал для крафта. Feather=Перо -Feathers are used in crafting and are dropped from chickens.=Перо используется для крафтинга и выпадает из кур. +Feathers are used in crafting and are dropped from chickens.=Перо выпадает из кур и используется для крафта. Rabbit Hide=Кроличья шкурка Rabbit hide is used to create leather.=Кроличья шкурка используется для создания кожи. Rabbit's Foot=Кроличья лапка Must be your lucky day! Place this item in an item frame for decoration.=У вас счастливый день! Поместите этот предмет в рамку как украшение. Saddle=Седло Can be placed on animals to ride them=Можно устанавливать на животных, чтобы ездить на них -Saddles can be put on some animals in order to mount them.=Седло можно поставить на некоторых животных, чтобы закрепляться на них. +Saddles can be put on some animals in order to mount them.=Седло можно поставить на некоторых животных, чтобы сесть на них. -Use the placement key with the saddle in your hand to try to put on the saddle. Saddles fit on horses, mules, donkeys and pigs. Horses, mules and donkeys need to be tamed first, otherwise they'll reject the saddle. Saddled animals can be mounted by using the placement key on them again.=Используйте клавишу размещения, держа седло в руке, чтобы попытаться надеть его. Сёдла подходят для лошадей, мулов, осликов и свиней. Лошади, мулы и ослики должны быть предварительно приручены, иначе они откажутся от седла. На осёдланных животных можно сесть, снова нажав на них клавишу размещения. +Use the placement key with the saddle in your hand to try to put on the saddle. Saddles fit on horses, mules, donkeys and pigs. Horses, mules and donkeys need to be tamed first, otherwise they'll reject the saddle. Saddled animals can be mounted by using the placement key on them again.=Используйте седло на животном, чтобы попытаться надеть его. Сёдла подходят для лошадей, мулов, ослов и свиней. Лошади, мулы и ослы должны быть предварительно приручены, иначе они откажутся от седла. На осёдланных животных можно сесть, снова нажав на них кнопку использования. -Rabbit Stew=Рагу из кролика -Rabbit stew is a very nutricious food item.=Рагу из кролика это очень питательный продукт. +Rabbit Stew=Тушёный кролик +Rabbit stew is a very nutricious food item.=Рагу из кролика это очень питательный съедобный продукт. Shulker Shell=Панцирь шалкера -Shulker shells are used in crafting. They are dropped from dead shulkers.=Панцирь шалкера используется для крафтинга. Он выпадает из мёртвого шалкера. +Shulker shells are used in crafting. They are dropped from dead shulkers.=Панцирь шалкера используется для крафта. Он выпадает из мёртвого шалкера. Slimeball=Слизь -Slimeballs are used in crafting. They are dropped from slimes.=Слизь используется для крафтинга. Она выпадает из слизняков. +Slimeballs are used in crafting. They are dropped from slimes.=Слизь используется для крафта. Она выпадает из слизняков. Gunpowder=Порох Carrot on a Stick=Удочка с морковью Lets you ride a saddled pig=Позволяет вам ездить на осёдланной свинье A carrot on a stick can be used on saddled pigs to ride them.=Удочку с морковью можно использовать, чтобы оседлать свинью и поехать на ней. -Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=Поместите это на осёдланную свинью, чтобы закрепиться на ней. Теперь вы можете ехать на ней, как на лошади. Свиньи также идут вперёд, когда вы просто держите удочку с морковью. +Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick.=Поместите это на осёдланную свинью, чтобы сесть на неё. Теперь вы можете ехать на ней, как на лошади. Свиньи приманиваются к вам, когда вы просто держите удочку с морковью. -Iron Horse Armor=Железные доспехи лошади -Iron horse armor can be worn by horses to increase their protection from harm a bit.=Железные доспехи лошади, надетые на лошадь, немного защищают её от вреда. -Golden Horse Armor=Золотые доспехи лошади -Golden horse armor can be worn by horses to increase their protection from harm.=Золотые доспехи лошади, надетые на лошадь, защищают её от вреда. -Diamond Horse Armor=Алмазные доспехи лошади -Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Алмазные доспехи лошади, надетые на лошадь, отлично защищают её от вреда. -Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Поместите это на лошадь, чтобы одеть лошадь в доспехи. Ослики и мулы не могут носить лошадиные доспехи. +Warped fungus on a Stick=Удочка с искажённым грибком +Lets you ride a strider=Позволяет вам ездить на страйдере +A warped fungus on a stick can be used on saddled striders to ride them.=Удочку с искажённым грибком можно использовать осёдланном страйдере, чтобы поехать на нём. +Place it on a saddled strider to mount it. You can now ride the strider like a horse. Striders will also walk towards you when you just wield the fungus on a stick.=Поместите это на осёдланном страйдере, чтобы сесть на него. Теперь вы можете ехать на нем, как на лошади. Страйдеры приманиваются к вам, когда вы просто держите удочку с искажённым грибком. + +Nautilus Shell=Раковина наутилуса +Used to craft a conduit=Используется при создании морского проводника +The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell.=Раковина наутилуса используется при создании морского проводника. Раковины можно получить при рыбалке или при убийстве утопленников держащих раковину. +Heart of the Sea=Сердце моря +The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest.=Сердце моря используется при создании морского проводника. Их можно найти в закопанных сундуках с сокровищем. + +Iron Horse Armor=Железная конская броня +Iron horse armor can be worn by horses to increase their protection from harm a bit.=Железную конскую броню можно надеть на лошадь, чтобы немного увеличить её защиту от урона. +Golden Horse Armor=Золотая конская броня +Golden horse armor can be worn by horses to increase their protection from harm.=Золотую конскую броню можно надеть на лошадь, чтобы увеличить её защиту от урона. +Diamond Horse Armor=Алмазная конская броня +Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Алмазную конскую броню можно надеть на лошадь, чтобы значительно увеличить её защиту от урона. +Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Используйте конскую броню на лошади, чтобы надеть её. Ослы и мулы не могут носить конскую броню. + +Glow Ink Sac=Светящийся чернильный мешок +Use it to craft the Glow Item Frame.=Используется для создания светящейся рамки. +Use the Glow Ink Sac and the normal Item Frame to craft the Glow Item Frame.=Используйте светящийся чернильный мешок на обычной рамке, чтобы создать светящуюся рамку. diff --git a/mods/ITEMS/mcl_mobspawners/README.md b/mods/ITEMS/mcl_mobspawners/README.md index 26ac39386..726036c9b 100644 --- a/mods/ITEMS/mcl_mobspawners/README.md +++ b/mods/ITEMS/mcl_mobspawners/README.md @@ -1,8 +1,8 @@ -This mod adds a mob spawner for MineClone 2. +This mod adds a mob spawner for VoxeLibre. Monsters will appear around the mob spawner in semi-regular intervals. This mod is originally based on the mob spawner from Mobs Redo by TenPlus1 -but has been modified quite a lot to fit the needs of MineClone 2. +but has been modified quite a lot to fit the needs of VoxeLibre. Players can get a mob spawner by `giveme` and is initially empty after placing. diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index c5c2212b6..83c03804e 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -39,7 +39,7 @@ end local doll_size_overrides = { ["mobs_mc:guardian"] = { x = 0.6, y = 0.6 }, ["mobs_mc:guardian_elder"] = { x = 0.72, y = 0.72 }, - ["mobs_mc:enderman"] = { x = 0.8, y = 0.8 }, + ["mobs_mc:rover"] = { x = 0.8, y = 0.8 }, ["mobs_mc:iron_golem"] = { x = 0.9, y = 0.9 }, ["mobs_mc:ghast"] = { x = 1.05, y = 1.05 }, ["mobs_mc:wither"] = { x = 1.2, y = 1.2 }, @@ -63,8 +63,8 @@ local function set_doll_properties(doll, mob) xs = doll_size_overrides[mob].x ys = doll_size_overrides[mob].y else - xs = mobinfo.visual_size.x * 0.33333 - ys = mobinfo.visual_size.y * 0.33333 + xs = (mobinfo.visual_size.x or 0) * 0.33333 + ys = (mobinfo.visual_size.y or 0) * 0.33333 end local prop = { mesh = mobinfo.mesh, @@ -83,6 +83,13 @@ local function respawn_doll(pos) local mob = meta:get_string("Mob") local doll if mob and mob ~= "" then + -- Handle conversion of mob spawners + local convert_to = (minetest.registered_entities[mob] or {})._convert_to + if convert_to then + mob = convert_to + meta:set_string("Mob", mob) + end + doll = find_doll(pos) if not doll then doll = spawn_doll(pos) @@ -128,7 +135,6 @@ function mcl_mobspawners.setup_spawner(pos, Mob, MinLight, MaxLight, MaxMobsInAr end set_doll_properties(doll, Mob) - -- Start spawning very soon local t = minetest.get_node_timer(pos) t:start(2) @@ -165,7 +171,6 @@ local function spawn_mobs(pos, elapsed) local count = 0 local ent - local timer = minetest.get_node_timer(pos) -- spawn mob if player detected and in range @@ -301,7 +306,8 @@ minetest.register_node("mcl_mobspawners:spawner", { local new_itemstack, success = minetest.item_place(itemstack, placer, pointed_thing) if success then local placepos - if minetest.registered_nodes[node_under.name].buildable_to then + local def = minetest.registered_nodes[node_under.name] + if def and def.buildable_to then placepos = pointed_thing.under else placepos = pointed_thing.above @@ -357,11 +363,15 @@ doll_def.on_activate = function(self, staticdata, dtime_s) if mob == "" or mob == nil then mob = default_mob end + + -- Handle conversion of mob spawners + local convert_to = (minetest.registered_entities[mob] or {})._convert_to + if convert_to then mob = convert_to end + set_doll_properties(self.object, mob) self.object:set_velocity({x=0, y=0, z=0}) self.object:set_acceleration({x=0, y=0, z=0}) self.object:set_armor_groups({immortal=1}) - end doll_def.on_step = function(self, dtime) @@ -389,3 +399,11 @@ minetest.register_lbm({ respawn_doll(pos) end, }) + +minetest.register_on_mods_loaded(function() + for name,mobinfo in pairs(minetest.registered_entities) do + if ( mobinfo.is_mob or name:find("mobs_mc") ) and not ( mobinfo.visual_size or mobinfo._convert_to ) then + minetest.log("warning", "Definition for "..tostring(name).." is missing field 'visual_size', mob spawners will not work properly") + end + end +end) diff --git a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ru.tr b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ru.tr index c018167c0..7c5bce336 100644 --- a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ru.tr +++ b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_mobspawners -Mob Spawner=Спаунер (порождатель) мобов -A mob spawner regularily causes mobs to appear around it while a player is nearby. Some mob spawners are disabled while in light.=Спаунер постоянно вызывает появление мобов вокруг себя, пока поблизости находится игрок. Некоторые спаунеры отключаются под действием света. -If you have a spawn egg, you can use it to change the mob to spawn. Just place the item on the mob spawner. Player-set mob spawners always spawn mobs regardless of the light level.=Если у вас есть порождающее яйцо, вы можете использовать его, чтобы выбрать моба, который будет появляться. Просто поместите этот предмет на спаунер. Настроенные игроками спаунеры работают всегда, независимо от уровня освещения. -Makes mobs appear=Создаёт мобов +Mob Spawner=Спаунер мобов +A mob spawner regularily causes mobs to appear around it while a player is nearby. Some mob spawners are disabled while in light.=Спаунер постоянно спаунит мобов вокруг себя, пока поблизости находится игрок. Некоторые спаунеры отключаются под действием света. +If you have a spawn egg, you can use it to change the mob to spawn. Just place the item on the mob spawner. Player-set mob spawners always spawn mobs regardless of the light level.=Если у вас есть яйцо спауна, вы можете использовать его, чтобы выбрать моба, который будет спауниться. Просто используйте яйцо на спаунере. Настроенные игроками спаунеры работают всегда, независимо от уровня освещения. +Makes mobs appear=Спаунит мобов diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pt_BR.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pt_BR.tr new file mode 100644 index 000000000..ae5e247b1 --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pt_BR.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_monster_eggs +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=Um bloco infestado é um bloco ao qual uma traça irá sair quando quebrá-lo. Parece idêntico a sua contraparte normal. +Infested Stone=Pedra Infestada +Infested Cobblestone=Pedregulho Infestado +Infested Stone Bricks=Tijolos de Pedra Infestados +Infested Cracked Stone Bricks=Tijolos de Pedra Rachados Infestados +Infested Mossy Stone Bricks=Tijolos de Pedra Musgosos Infestados +Infested Chiseled Stone Bricks=Tijolos de Pedra Talhados Infestados +Hides a silverfish=Escondem uma traça diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ru.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ru.tr index 6902b610f..25d135d7b 100644 --- a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ru.tr +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ru.tr @@ -1,9 +1,9 @@ # textdomain: mcl_monster_eggs -An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=Блок с икрой - это блок, из которого вылетает чешуйница, если его сломать. Выглядит идентично своему обычному аналогу. -Infested Stone=Камень с икрой -Infested Cobblestone=Булыжник с икрой -Infested Stone Bricks=Каменные блоки с икрой -Infested Cracked Stone Bricks=Треснутые каменные блоки с икрой -Infested Mossy Stone Bricks=Мшистый каменный блок с икрой -Infested Chiseled Stone Bricks=Точёный каменный блок с икрой -Hides a silverfish=Скрывает чешуйницу +An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart.=Заражённый блок это блок, после добычи которого спаунится чешуйница. Блок выглядит идентично своему нормальному варианту. +Infested Stone=Заражённый камень +Infested Cobblestone=Заражённый булыжник +Infested Stone Bricks=Заражённые каменные кирпичи +Infested Cracked Stone Bricks=Заражённые треснутые каменные кирпичи +Infested Mossy Stone Bricks=Заражённые замшелые каменные кирпичи +Infested Chiseled Stone Bricks=Заражённые резные каменные кирпичи +Hides a silverfish=Прячет в себе чешуйницу \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/init.lua b/mods/ITEMS/mcl_mud/init.lua index 64ff36c09..3c3e66a99 100644 --- a/mods/ITEMS/mcl_mud/init.lua +++ b/mods/ITEMS/mcl_mud/init.lua @@ -62,4 +62,4 @@ minetest.register_craft({ {"mcl_mud:packed_mud", "mcl_mud:packed_mud"}, {"mcl_mud:packed_mud", "mcl_mud:packed_mud"} } -}) \ No newline at end of file +}) diff --git a/mods/ITEMS/mcl_mud/locale/mcl_mud.pt_BR.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.pt_BR.tr new file mode 100644 index 000000000..c3b5edf0e --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.pt_BR.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud=Barro +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.=Barro é um bloco decorativo gerado em manguezais. Barro também pode ser obtido usando garrafas de água em blocos de terra ou terra infértil. +Packed Mud=Barro Seco +Packed mud is a decorative block used to craft mud bricks.=Barro seco é um bloco decorativo usado para fabricar tijolos de barro. +Mud Bricks=Tijolos de Barro +Decorative block crafted from packed mud.=Bloco decorativo fabricado a partir de barro seco. diff --git a/mods/ITEMS/mcl_mud/locale/mcl_mud.ru.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.ru.tr new file mode 100644 index 000000000..305a32bf5 --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.ru.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud=Грязь +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.=Декоративный блок генерирующийся в мангровых болотах. Также может быть получена использовав пузырёк воды на земле или каменистой земле. +Packed Mud=Уплотнённая грязь +Packed mud is a decorative block used to craft mud bricks.=Декоративный блок. Используется для создания саманных кирпичей. +Mud Bricks=Саманные кирпичи +Decorative block crafted from packed mud.=Декоративный блок, созданный из уплотнённой грязи. \ No newline at end of file diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr index 40b6644d1..cba5f8019 100644 --- a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr @@ -9,7 +9,7 @@ Huge brown mushroom blocks are the cap parts of huge brown mushrooms. It consist The stem part of a huge brown mushroom.=La partie tige d'un énorme champignon brun. Huge Brown Mushroom Block=Bloc de champignon marron géant Huge Brown Mushroom Stem=Tige de champignon marron géant -Huge Brown Mushroom All-Faces Stem=Tige de Champignon marron géant avec pores +Huge Brown Mushroom All-Faces Stem=Tige de champignon marron géant avec pores Brown mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Les champignons bruns sont des champignons qui poussent et se propagent dans l'obscurité, mais sont sensibles à la lumière. Ils sont non comestibles en tant que tels, mais ils peuvent être utilisés pour fabriquer des aliments. Red mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Les champignons rouges sont des champignons qui poussent et se propagent dans l'obscurité, mais sont sensibles à la lumière. Ils sont non comestibles en tant que tels, mais ils peuvent être utilisés pour fabriquer des aliments. A single mushroom of this species will slowly spread over time towards a random solid opaque block with a light level of 12 or lower in a 3×3×3 cube around the mushroom. It stops spreading when there are 5 or more mushrooms of the same species within an area of 9×3×9 blocks around the mushroom.=Un seul champignon de cette espèce se propagera lentement au fil du temps vers un bloc opaque solide aléatoire avec un niveau de lumière de 12 ou moins dans un cube 3×3×3 autour du champignon. Il cesse de se propager lorsqu'il y a 5 champignons ou plus de la même espèce dans une zone de 9×3×9 blocs autour du champignon. diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ru.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ru.tr index ba3cb171e..32c6c107e 100644 --- a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ru.tr +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ru.tr @@ -1,24 +1,24 @@ # textdomain: mcl_mushrooms -This decorative block is like a huge mushroom stem, but with the stem texture on all sides.=Этот декоративный блок похож на огромную ножку гриба, но имеет структуру ножки с каждой стороны. -Huge red mushroom blocks are the cap parts of huge red mushrooms. It consists of a red skin and can have pores on each of its sides.=Блоки огромных красных грибов это части шляпок огромных красных грибов. Они состоят из красной кожицы и могут иметь поры на каждой стороне. -The stem part of a huge red mushroom.=Часть ножки огромного красного гриба. -Huge Red Mushroom Block=Блок огромного красного гриба -Huge Red Mushroom Stem=Ножка огромного красного гриба -Huge Red Mushroom All-Faces Stem=Многоликая ножка огромного красного гриба -Huge brown mushroom blocks are the cap parts of huge brown mushrooms. It consists of a brown skin and can have pores on each of its sides.=Блоки огромных коричневых грибов это части шляпок огромных коричневых грибов. Они состоят из коричневой кожицы и могут иметь поры на каждой стороне. -The stem part of a huge brown mushroom.=Часть ножки огромного коричневого гриба. -Huge Brown Mushroom Block=Блок огромного коричневого гриба -Huge Brown Mushroom Stem=Ножка огромного коричневого гриба -Huge Brown Mushroom All-Faces Stem=Многоликая ножка огромного коричневого гриба -Brown mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Коричневые грибы растут в темноте, но чувствительны к свету. Они несъедобны как таковые, но их можно использовать для приготовления продуктов питания. -Red mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Красные грибы растут в темноте, но чувствительны к свету. Они несъедобны как таковые, но их можно использовать для приготовления продуктов питания. -A single mushroom of this species will slowly spread over time towards a random solid opaque block with a light level of 12 or lower in a 3×3×3 cube around the mushroom. It stops spreading when there are 5 or more mushrooms of the same species within an area of 9×3×9 blocks around the mushroom.=Одиночный гриб этого вида со временем будет медленно распространяться в направлении случайного твердого непрозрачного блока при уровне освещённости 12 и ниже пределах куба 3×3×3 вокруг себя. Он перестает распространяться, когда будет уже 5 и более грибов одного и того же вида на участке 9×3×9 блоков вокруг гриба. -Mushrooms will eventually uproot at a light level of 12 or higher. On mycelium or podzol, they survive and spread at any light level.=Грибы вымирают при уровне света 12 и выше. Но на мицелии и подзоле они выживают и распространяются при любом уровне освещенности. -This mushroom can be placed on mycelium and podzol at any light level. It can also be placed on blocks which are both solid and opaque, as long as the light level at daytime is not higher than 12.=Этот гриб можно высадить на мицелий и подзол при любом уровне света. Его также можно размещать на плотных непрозрачных блоках, если уровень освещенности в дневное время не превышает 12. +This decorative block is like a huge mushroom stem, but with the stem texture on all sides.=Этот декоративный блок похож на большую ножку гриба, но имеет текстуру ножки с каждой стороны. +Huge red mushroom blocks are the cap parts of huge red mushrooms. It consists of a red skin and can have pores on each of its sides.=Блоки больших красных грибов это части шляпок больших красных грибов. Они состоят из красной кожицы и могут иметь поры на каждой стороне. +The stem part of a huge red mushroom.=Часть ножки большого красного гриба. +Huge Red Mushroom Block=Блок большого красного гриба +Huge Red Mushroom Stem=Ножка большого красного гриба +Huge Red Mushroom All-Faces Stem=Всесторонняя ножка большого красного гриба +Huge brown mushroom blocks are the cap parts of huge brown mushrooms. It consists of a brown skin and can have pores on each of its sides.=Блоки больших коричневых грибов это части шляпок больших коричневых грибов. Они состоят из коричневой кожицы и могут иметь поры на каждой стороне. +The stem part of a huge brown mushroom.=Часть ножки большого коричневого гриба. +Huge Brown Mushroom Block=Блок большого коричневого гриба +Huge Brown Mushroom Stem=Ножка большого коричневого гриба +Huge Brown Mushroom All-Faces Stem=Всесторонняя ножка большого коричневого гриба +Brown mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Коричневые грибы растут в темноте, но чувствительны к свету. Они несъедобны как таковые, но их можно использовать для приготовления съедобных продуктов. +Red mushrooms are fungi which grow and spread in darkness, but are sensitive to light. They are inedible as such, but they can be used to craft food items.=Красные грибы растут в темноте, но чувствительны к свету. Они несъедобны как таковые, но их можно использовать для приготовления съедобных продуктов. +A single mushroom of this species will slowly spread over time towards a random solid opaque block with a light level of 12 or lower in a 3×3×3 cube around the mushroom. It stops spreading when there are 5 or more mushrooms of the same species within an area of 9×3×9 blocks around the mushroom.=Одиночный гриб этого вида со временем будет медленно распространяться в направлении случайного твёрдого непрозрачного блока при уровне освещённости 12 и ниже, в пределах куба 3×3×3 вокруг себя. Он перестает распространяться, когда будет уже 5 и более грибов одного и того же вида на участке 9×3×9 блоков вокруг гриба. +Mushrooms will eventually uproot at a light level of 12 or higher. On mycelium or podzol, they survive and spread at any light level.=Грибы погибают при уровне света 12 и выше. Но на мицелии и подзоле они выживают и распространяются при любом уровне освещенности. +This mushroom can be placed on mycelium and podzol at any light level. It can also be placed on blocks which are both solid and opaque, as long as the light level at daytime is not higher than 12.=Этот гриб можно высадить на мицелий и подзол при любом уровне света. Его также можно размещать на твёрдых непрозрачных блоках, если уровень освещенности в дневное время не превышает 12. Brown Mushroom=Коричневый гриб Red Mushroom=Красный гриб -Mushroom Stew=Грибная похлёбка -Mushroom stew is a healthy soup which can be consumed to restore some hunger points.=Грибная похлёбка - это полезный суп, который можно употребить в пищу для восстановления нескольких очков голода. -By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.=Если поместить блоки огромных грибов одного и того же вида рядом друг с другом, стороны, которыми они соприкасаются друг с другом, сразу превратятся в поры. -Grows on podzol, mycelium and other blocks=Растёт на подзолах, мицелии и других блоках +Mushroom Stew=Тушёные грибы +Mushroom stew is a healthy soup which can be consumed to restore some hunger points.=Тушёные грибы это полезный суп, который можно употребить в пищу для восстановления нескольких очков голода. +By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.=Если поместить блоки больших грибов одного и того же вида рядом друг с другом, стороны, которыми они соприкасаются друг с другом, сразу превратятся в поры. +Grows on podzol, mycelium and other blocks=Растёт на подзоле, мицелии и других блоках Spreads in darkness=Распространяется в темноте diff --git a/mods/ITEMS/mcl_mushrooms/small.lua b/mods/ITEMS/mcl_mushrooms/small.lua index f6fbd2909..4d1ffa2f5 100644 --- a/mods/ITEMS/mcl_mushrooms/small.lua +++ b/mods/ITEMS/mcl_mushrooms/small.lua @@ -87,7 +87,7 @@ minetest.register_craftitem("mcl_mushrooms:mushroom_stew", { inventory_image = "farming_mushroom_stew.png", on_place = minetest.item_eat(6, "mcl_core:bowl"), on_secondary_use = minetest.item_eat(6, "mcl_core:bowl"), - groups = { food = 3, eatable = 6 }, + groups = { food = 2, eatable = 6 }, _mcl_saturation = 7.2, stack_max = 1, }) diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 548bd90d5..b69355d5d 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -135,7 +135,7 @@ minetest.register_node("mcl_nether:magma", { -- From walkover mod on_walk_over = function(loc, nodeiamon, player) local armor_feet = player:get_inventory():get_stack("armor", 5) - if player and player:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof")) then + if player and player:get_player_control().sneak or (minetest.global_exists("mcl_enchanting") and mcl_enchanting.has_enchantment(armor_feet, "frost_walker")) or (minetest.global_exists("mcl_potions") and mcl_potions.has_effect(player, "fire_resistance")) then return end -- Hurt players standing on top of this block @@ -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()).."/lava.lua") diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr index 70d8ca8e0..9e6d4e9d8 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr @@ -1,42 +1,42 @@ # textdomain: mcl_nether -Glowstone=Pierre Lumineuse -Glowstone is a naturally-glowing block which is home to the Nether.=La Pierre Lumineuse est un bloc naturellement brillant originaire du Nether. +Glowstone=Pierre lumineuse +Glowstone is a naturally-glowing block which is home to the Nether.=La pierre lumineuse est un bloc naturellement brillant originaire du Nether. Nether Quartz Ore=Minerai de quartz du Nether Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Le minerai de quartz du Nether est un minerai contenant du quartz du Nether. Il se trouve généralement autour de la netherrack dans le Nether. Netherrack=Netherrack Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=La netherrack est un bloc de pierre originaire du Nether. Démarrer un feu sur ce bloc créera un feu éternel. -Magma Block=Bloc de Magma +Magma Block=Bloc de magma Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=Les blocs de magma sont des blocs solides chauds qui blessent quiconque s'y tient, à moins d'avoir une résistance au feu. Démarrer un feu sur ce bloc créera un feu éternel. @1 stood too long on a magma block.=@1 s'est tenu trop longtemps sur un bloc de magma. Soul Sand=Sable des âmes -Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Le sable de l'âme est un bloc du Nether. On ne peut marcher que lentement sur le sable de l'âme. L'effet de ralentissement est amplifié lorsque le sable de l'âme est au-dessus de la glace, de la glace tassée ou d'un bloc de slime. -Nether Brick Block=Bloc de Briques du Nether -Red Nether Brick Block=Bloc de Briques Rouges du Nether -Nether Wart Block=Bloc de Verrues du Nether +Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Le sable des âmes est un bloc du Nether. On ne peut marcher que lentement sur le sable des âmes. L'effet de ralentissement est amplifié lorsque le sable des âmes est au-dessus de la glace, de la glace tassée ou d'un bloc de slime. +Nether Brick Block=Bloc de briques du Nether +Red Nether Brick Block=Bloc de briques rouges du Nether +Nether Wart Block=Bloc de verrues du Nether A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrues du Nether est un bloc purement décoratif fabriqué à partir de verrues du Nether. -Block of Quartz=Bloc de Quartz -Chiseled Quartz Block=Bloc de Quartz sculpté -Pillar Quartz Block=Bloc de Quartz rayé -Smooth Quartz=Quartz Lisse -Glowstone Dust=Poudre Lumineuse +Block of Quartz=Bloc de quartz +Chiseled Quartz Block=Bloc de quartz sculpté +Pillar Quartz Block=Bloc de quartz rayé +Smooth Quartz=Quartz lisse +Glowstone Dust=Poudre lumineuse Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=La poudre lumineuse est la poussière qui sort des pierres lumineuses brisées. Elle est principalement utilisée dans l'artisanat. Nether Quartz=Quartz du Nether Nether quartz is a versatile crafting ingredient.=Le quartz du Nether est un ingrédient artisanal polyvalent. Nether Brick=Brique du Nether Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Les briques du Nether sont le principal ingrédient pour la fabrication de blocs de briques et de clôtures du Nether. -Nether Lava Source=Source de Lave du Nether -Flowing Nether Lava=Lave du Nether en mouvement -Premature Nether Wart (Stage 1)=Verrue du Néant prématurée (étape 1) -A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Une verrue du Nether prématurée vient d'être plantée sur du sable d'âme. La verrue du Nether pousse lentement sur le sable de l'âme en 4 étapes (les deuxième et troisième étapes semblent identiques). Bien que la verrue du Nether soit originaire du Nether, elle se développe dans toutes les dimensions. +Nether Lava Source=Source de lave du Nether +Flowing Nether Lava=Lave du Nether en mouvement +Premature Nether Wart (Stage 1)=Verrue du Nether prématurée (étape 1) +A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Une verrue du Nether prématurée vient d'être plantée sur du sable des âmes. La verrue du Nether pousse lentement sur le sable des âmes en 4 étapes (les deuxième et troisième étapes semblent identiques). Bien que la verrue du Nether soit originaire du Nether, elle se développe dans toutes les dimensions. Premature Nether Wart (Stage 2)=Verrue du Nether prématurée (étape 2) Premature Nether Wart (Stage 3)=Verrue du Nether prématurée (étape 3) -Mature Nether Wart=Verrue du Nether Mature +Mature Nether Wart=Verrue du Nether mature The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=La verrue du Nether mature est une plante du Nether qui a atteint sa taille maximale et ne poussera plus. Elle est prête à être récoltée. Nether Wart=Verrues du Nether -Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Les verrues du Nether sont des plantes originaires du Nether. Elles peuvent être plantées sur du sable d'âme et se développer en 4 étapes. -Place this item on soul sand to plant it and watch it grow.=Placez cet article sur du sable d'âme pour le planter et regardez-le grandir. +Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Les verrues du Nether sont des plantes originaires du Nether. Elles peuvent être plantées sur du sable des âmes et se développer en 4 étapes. +Place this item on soul sand to plant it and watch it grow.=Placez cet article sur du sable des âmes pour le planter et regardez-le grandir. Burns your feet=Vous brûle les pieds -Grows on soul sand=Pousse sur le sable de l'âme +Grows on soul sand=Pousse sur le sable des âmes Reduces walking speed=Réduit la vitesse de marche Netherite Scrap=Fragments de netherite Netherite Ingot=Lingot de netherite diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr index f546d16ca..8f440cfb3 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr @@ -1,40 +1,46 @@ # textdomain: mcl_nether -Glowstone=Светящийся камень -Glowstone is a naturally-glowing block which is home to the Nether.=Светящийся камень это природный источник света, блок, встречающийся в Аду. +Glowstone=Светокамень +Glowstone is a naturally-glowing block which is home to the Nether.=Светокамень это природный светящийся блок, встречающийся в Незере. Nether Quartz Ore=Кварцевая руда -Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Кварцевая руда это порода, содержащая адский кварц. Часто встречается в Аду вокруг адского камня. +Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Кварцевая руда это порода, содержащая кварц. Часто встречается в Незере вокруг незерита. Netherrack=Адский камень -Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=Адский камень это блок, выглядящий как камень, домом которого является Ад. Разжигание огня на этом блоке создаст вечный огонь. +Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=Адский камень это блок, выглядящий как камень, домом которого является Незер. Разжигание огня на этом блоке создаст вечный огонь. Magma Block=Блок магмы -Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=Блоки магмы это горячие твёрдые блоки, причиняющие боль тем, кто на них стоит, если у них нет защиты от огня. Разжигание огня на таком блоке создаст вечный огонь. +Magma blocks are hot solid blocks which hurt anyone standing on it, unless they have fire resistance. Starting a fire on this block will create an eternal fire.=Блоки магмы это горячие твёрдые блоки, причиняющие урон тем, кто на них стоит, если у них нет защиты от огня. Разжигание огня на таком блоке создаст вечный огонь. @1 stood too long on a magma block.=@1 слишком долго стоял(а) на магмовом блоке. Soul Sand=Песок душ -Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Песок душ это блок из Ада. Идти по нему можно только медленно. Замедляющий эффект усиливается, если песок душ лежит на льду, упакованном льду или блоке слизи. +Soul sand is a block from the Nether. One can only slowly walk on soul sand. The slowing effect is amplified when the soul sand is on top of ice, packed ice or a slime block.=Песок душ это блок из Незера. Идти по нему можно только медленно. Замедляющий эффект усиливается, если песок душ стоит на льду, плотном льду или блоке слизи. Nether Brick Block=Блок адского кирпича -Red Nether Brick Block=Красный блок адского кирпича +Red Nether Brick Block=Блок красного адского кирпича Nether Wart Block=Блок адского нароста -A nether wart block is a purely decorative block made from nether wart.=Блок адского нароста это чисто декоративный блок, сделанный из адского нароста. +A nether wart block is a purely decorative block made from nether wart.=Блок адского нароста это декоративный блок, сделанный из адского нароста. Block of Quartz=Кварцевый блок -Chiseled Quartz Block=Точёный кварцевый блок -Pillar Quartz Block=Кварцевый столб +Chiseled Quartz Block=Резной кварцевый блок +Pillar Quartz Block=Кварцевая колонна Smooth Quartz=Гладкий кварц -Glowstone Dust=Светящаяся пыль -Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=Светящаяся пыль это пыль, которая получается из сломанного светящегося камня. -Nether Quartz=Адский кварц -Nether quartz is a versatile crafting ingredient.=Адский кварц это универсальный ингредиент для крафтинга. +Glowstone Dust=Светопыль +Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=Светопыль это пыль, которая получается из сломанного светящегося камня. +Nether Quartz=Кварц +Nether quartz is a versatile crafting ingredient.=Кварц это универсальный материал для крафта. Nether Brick=Адский кирпич -Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Адские кирпичи это главный ингредиент для создания блоков адских кирпичей. +Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Адские кирпичи это главный материал для создания блоков адских кирпичей. Nether Lava Source=Адский источник лавы Flowing Nether Lava=Текущая адская лава Premature Nether Wart (Stage 1)=Саженец адского нароста (стадия 1) -A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Саженец адского нароста был недавно высажен на песке душ. Его медленный рост происходит 4 стадии (вторая и третья стадии неотличимы на глаз). Хотя домом адского нароста является Ад, он растёт в любом измерении. +A premature nether wart has just recently been planted on soul sand. Nether wart slowly grows on soul sand in 4 stages (the second and third stages look identical). Although nether wart is home to the Nether, it grows in any dimension.=Саженец адского нароста был недавно посажен на песке душ. Его медленный рост происходит 4 стадии (вторая и третья стадии неотличимы на глаз). Хотя домом адского нароста является Ад, он растёт в любом измерении. Premature Nether Wart (Stage 2)=Саженец адского нароста (стадия 2) Premature Nether Wart (Stage 3)=Саженец адского нароста (стадия 3) Mature Nether Wart=Зрелый адский нарост -The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=Зрелый адский нарост это растение Ада, достигшее своего полного размера, дальше расти оно уже не будет. Оно готово к сбору в качестве предметов. +The mature nether wart is a plant from the Nether and reached its full size and won't grow any further. It is ready to be harvested for its items.=Зрелый адский нарост это растение Незера, достигшее своего полного размера, дальше расти оно уже не будет. Оно готово к сбору в качестве предметов. Nether Wart=Адский нарост -Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Адские наросты это растения, домом которых является Ад. Их можно высаживать на песке душ, и они растут в 4 стадии. -Place this item on soul sand to plant it and watch it grow.=Поместите этот предмет на песок душ, чтобы посадить его и наблюдать за его ростом. +Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Адские наросты это растения, домом которых является Незер. Их можно высаживать на песке душ, и они растут в 4 стадии. +Place this item on soul sand to plant it and watch it grow.=Поместите этот предмет на песок душ, чтобы посадить его для выращивания. Burns your feet=Обжигает ваши ноги Grows on soul sand=Растёт на песке душ Reduces walking speed=Уменьшает скорость ходьбы +Netherite Scrap=Незеритовый скрап +Netherite Ingot=Незеритовый слиток +Ancient Debris=Древние обломки +Ancient debris can be found in the nether and is very very rare.=Древние обломки можно очень редко найти в Незере +Netherite Block=Незеритовый блок +Netherite block is very hard and can be made of 9 netherite ingots.=Незеритовый блок очень крепкий. Может быть создан из 9 незеритовых слитков. diff --git a/mods/ITEMS/mcl_nether/mod.conf b/mods/ITEMS/mcl_nether/mod.conf index f5ffa61ac..afeca9967 100644 --- a/mods/ITEMS/mcl_nether/mod.conf +++ b/mods/ITEMS/mcl_nether/mod.conf @@ -1,3 +1,3 @@ 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 diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 1084dfa77..530d96093 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -267,7 +267,8 @@ function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flow -- Flowing liquid: Grow 1 step, but also turn the tip node into a liquid source. if downward_flowing then local alt_liq = mt_registered_nodes[node_tip.name].liquid_alternative_source - if alt_liq then + local alt_liq_accessible = mt_get_item_group(node_tip.name,"waterlogged") -- returns 0 if it isn't waterlogged. + if alt_liq and not alt_liq_accessible then mt_set_node(pos_tip, {name=alt_liq}) end end diff --git a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.fr.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.fr.tr index a1b3f0b77..7521ff74c 100644 --- a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.fr.tr +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.fr.tr @@ -1,51 +1,51 @@ # textdomain: mcl_ocean Sea Lantern=Lanterne aquatique -Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Les lanternes marines sont des sources lumineuses décoratives qui ont fière allure sous l'eau mais peuvent être placées n'importe où. +Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Les lanternes aquatiques sont des sources lumineuses décoratives qui ont fière allure sous l'eau mais peuvent être placées n'importe où. Prismarine=Prismarine -Prismarine is used as a building block. It slowly changes its color.=La prismarine est utilisée comme bloc de construction. Il change lentement de couleur. -Prismarine Bricks=Prismarine Taillée -Dark Prismarine=Prismarine Sombre -Prismarine Crystals=Cristaux de Prismarine -Prismarine Shard=Éclat de Prismarine -Dried Kelp=Algue Séchée -Dried Kelp Block=Bloc d'Algue Séchée -Brain Coral Block=Bloc de Corail -Brain Coral Fan=Gorgone de Corail -Brain Coral=Corail -Bubble Coral Block=Bloc de Corail Bulles -Bubble Coral Fan=Gorgone de Corail Bulles -Bubble Coral=Corail Bulles -Fire Coral Block=Bloc Corail de Feu -Fire Coral Fan=Gorgone Corail de Feu -Fire Coral=Corail de Feu -Horn Coral Block=Bloc de Corail Corné -Horn Coral Fan=Gorgone de Corail Corné -Horn Coral=Corail Corné -Tube Coral Block=Bloc de Corail Tubulaire -Tube Coral Fan=Gorgone de Corail Tubulaire -Tube Coral=Corail Tubulaire -Dead Brain Coral Block=Bloc de Corail Mort -Dead Brain Coral Fan=Gorgone de Corail Mort -Dead Brain Coral=Corail Mort -Dead Bubble Coral Block=Bloc de Corail Bulles Mort -Dead Bubble Coral Fan=Gorgone de Corail Bulles Mort -Dead Bubble Coral=Corail Bulles Mort -Dead Fire Coral Block=Bloc de Corail de Feu Mort -Dead Fire Coral Fan=Gorgone de Corail de Feu Mort -Dead Fire Coral=Corail de Feu Mort -Dead Horn Coral Block=Bloc de Corail Corné Mort -Dead Horn Coral Fan=Gorgone de Corail Corné Mort -Dead Horn Coral=Corail Corné Mort -Dead Tube Coral Block=Bloc de Corail Tubulaire Mort -Dead Tube Coral Fan=Gorgone de Corail Tubulaire Mort -Dead Tube Coral=Corail Tubulaire Mort +Prismarine is used as a building block. It slowly changes its color.=La prismarine est utilisée comme bloc de construction. Elle change lentement de couleur. +Prismarine Bricks=Prismarine taillée +Dark Prismarine=Prismarine sombre +Prismarine Crystals=Cristaux de prismarine +Prismarine Shard=Éclat de prismarine +Dried Kelp=Algue séchée +Dried Kelp Block=Bloc d'algue séchée +Brain Coral Block=Bloc de corail cerveau +Brain Coral Fan=Gorgone de corail cerveau +Brain Coral=Corail cerveau +Bubble Coral Block=Bloc de corail bulles +Bubble Coral Fan=Gorgone de corail bulles +Bubble Coral=Corail bulles +Fire Coral Block=Bloc de corail de feu +Fire Coral Fan=Gorgone de corail de feu +Fire Coral=Corail de feu +Horn Coral Block=Bloc de corail corné +Horn Coral Fan=Gorgone de corail corné +Horn Coral=Corail corné +Tube Coral Block=Bloc de corail tubulaire +Tube Coral Fan=Gorgone de corail tubulaire +Tube Coral=Corail tubulaire +Dead Brain Coral Block=Bloc de corail cerveau mort +Dead Brain Coral Fan=Gorgone de corail cerveau mort +Dead Brain Coral=Corail cerveau mort +Dead Bubble Coral Block=Bloc de corail bulles mort +Dead Bubble Coral Fan=Gorgone de corail bulles mort +Dead Bubble Coral=Corail bulles mort +Dead Fire Coral Block=Bloc de corail de feu mort +Dead Fire Coral Fan=Gorgone de corail de feu mort +Dead Fire Coral=Corail de feu mort +Dead Horn Coral Block=Bloc de corail corné mort +Dead Horn Coral Fan=Gorgone de corail corné mort +Dead Horn Coral=Corail corné mort +Dead Tube Coral Block=Bloc de corail tubulaire mort +Dead Tube Coral Fan=Gorgone de corail tubulaire mort +Dead Tube Coral=Corail tubulaire mort Seagrass=Herbe aquatique Kelp=Algue -Kelp grows inside water on top of dirt, sand or gravel.=Les Algues pousse à l'intérieur de l'eau sur la terre, le sable ou le gravier. +Kelp grows inside water on top of dirt, sand or gravel.=Les algues poussent dans l'eau sur la terre, le sable ou le gravier. Coral blocks live in the oceans and need a water source next to them to survive. Without water, they die off.=Les blocs de corail vivent dans les océans et ont besoin d'une source d'eau à côté d'eux pour survivre. Sans eau, ils meurent. -Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Les coraux se développent au-dessus des blocs de corail et doivent être à l'intérieur d'une source d'eau pour survivre. Sans eau, il mourra, ainsi que le bloc de corail en dessous. -Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Les gorgones de coraux se développent au-dessus des blocs de corail et doivent être à l'intérieur d'une source d'eau pour survivre. Sans eau, il mourra, ainsi que le bloc de corail en dessous. -Seagrass grows inside water on top of dirt, sand or gravel.=Les herbiers aquatique poussent à l'intérieur de l'eau sur la terre, le sable ou le gravier. +Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Les coraux se développent au-dessus des blocs de corail et doivent être dans une source d'eau pour survivre. Sans eau, il mourra, ainsi que le bloc de corail en dessous. +Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Les gorgones de corail se développent au-dessus des blocs de corail et doivent être dans une source d'eau pour survivre. Sans eau, elle mourra, ainsi que le bloc de corail en dessous. +Seagrass grows inside water on top of dirt, sand or gravel.=Les herbiers aquatique poussent dans l'eau sur la terre, le sable ou le gravier. A decorative block that serves as a great furnace fuel.=Un bloc décoratif qui sert de bon combustible pour le four. Dried kelp is a food item.=L'algue séchée est un aliment. Grows on coral block of same species=Pousse sur un bloc de corail de la même espèce @@ -53,7 +53,7 @@ Needs water to live=A besoin d'eau pour vivre Grows in water on dirt, sand, gravel=Pousse dans l'eau sur la terre, le sable et le gravier Glows in the water=Brille dans l'eau 4 possible sizes=4 tailles possibles -Grows on dead brain coral block=Pousse sur un bloc de corail mort +Grows on dead brain coral block=Pousse sur un bloc de corail cerveau mort Sea Pickle=Cornichon de mer -Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Les cornichons de mer poussent sur des blocs de corail morts et fournissent de la lumière lorsqu'ils sont sous l'eau. Ils viennent en 4 tailles qui varient en luminosité. -It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=Il ne peut être placé que sur des blocs de corail morts. Placer un cornichon sur un autre cornichon le rendra plus brillant et plus brillant. \ No newline at end of file +Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Les cornichons de mer poussent sur des blocs de corail cerveau mort et fournissent de la lumière lorsqu'ils sont sous l'eau. Ils viennent en 4 tailles qui varient en luminosité. +It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=Il ne peut être placé que sur des blocs de corail cerveau mort. Placer un cornichon sur un autre cornichon le rendra plus grand et plus brillant. diff --git a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.pt_BR.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.pt_BR.tr new file mode 100644 index 000000000..2e522e1b5 --- /dev/null +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.pt_BR.tr @@ -0,0 +1,60 @@ +# textdomain: mcl_ocean +Sea Lantern=Lanterna do Mar +Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Lanternas do mar são fontes de luz decorativas as quais ficam bonitas em baixo d'água mas podem ser posicionadas em qualquer lugar. +Prismarine=Prismarinho +Prismarine is used as a building block. It slowly changes its color.=Prismarinho é usado como um bloco de costrução. Muda de cor lentamente. +Prismarine Bricks=Tijolos de Prismarinho +Dark Prismarine=Prismarinho Escuro +Prismarine Crystals=Cristais de Prismarinho +Prismarine Shard=Fragmentos de Prismarinho +Dried Kelp=Alga Seca +Dried Kelp Block=Bloco de Alga Seca +Brain Coral Block=Bloco de Coral-de-Cérebro +Brain Coral Fan=Gorgônia-de-Cérebro +Brain Coral=Coral-de-Cérebro +Bubble Coral Block=Bloco de Coral-de-Bolha +Bubble Coral Fan=Gorgônia-de-Bolha +Bubble Coral=Coral-de-Bolha +Fire Coral Block=Bloco de Coral-de-Fogo +Fire Coral Fan=Gorgônia-de-Fogo +Fire Coral=Coral-de-Fogo +Horn Coral Block=Bloco de Coral-de-Chifre +Horn Coral Fan=Gorgônia-de-Chifre +Horn Coral=Coral-de-Chifre +Tube Coral Block=Bloco de Coral-de-Tubo +Tube Coral Fan=Gorgônia-de-Tubo +Tube Coral=Coral-de-Tubo +Dead Brain Coral Block=Bloco de Coral-de-Cérebro Morto +Dead Brain Coral Fan=Gorgônia-de-Cérebro Morta +Dead Brain Coral=Coral-de-Cérebro Morto +Dead Bubble Coral Block=Bloco de Coral-de-Bolha Morto +Dead Bubble Coral Fan=Gorgônia-de-Bolha Morta +Dead Bubble Coral=Coral-de-Bolha Morto +Dead Fire Coral Block=Bloco de Coral-de-Fogo Morto +Dead Fire Coral Fan=Gorgônia-de-Fogo Morta +Dead Fire Coral=Coral-de-Fogo Morto +Dead Horn Coral Block=Bloco de Coral-de-Chifre Morto +Dead Horn Coral Fan=Gorgônia-de-Chifre Morta +Dead Horn Coral=Coral-de-Chifre Morto +Dead Tube Coral Block=Bloco de Coral-de-Tubo Morto +Dead Tube Coral Fan=Gorgônia-de-Tubo Morta +Dead Tube Coral=Coral-de-Tubo Morto +Seagrass=Grama Marinha +Kelp=Alga +Kelp grows inside water on top of dirt, sand or gravel.=Alga cresce dentro da água sobre terra, areia ou cascalho. +Coral blocks live in the oceans and need a water source next to them to survive. Without water, they die off.=Blocos de corais vivem em oceanos e precisam de uma fonte de água próxima para sobreviver. Sem água, eles morrem. +Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Corais crescem sobre blocos de corais e precisam estar dentro de uma fonte de água para sobreviver. Sem água, eles morrem, assim como o bloco de coral abaixo. +Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Gorgônias crescem sobre blocos de corais e precisam estar dentro de uma fonte de água para sobreviver. Sem água, elas morrem, assim como o bloco de coral abaixo. +Seagrass grows inside water on top of dirt, sand or gravel.=Grama marinha cresce dento da água sobre terra, areia ou cascalho. +A decorative block that serves as a great furnace fuel.=Um bloco decorativo que serve como uma ótimo combustível de fornalha. +Dried kelp is a food item.=Alga seca é um item de comida. +Grows on coral block of same species=Cresce em blocos de corais da mesma espécie +Needs water to live=Precisa de água para viver +Grows in water on dirt, sand, gravel=Cresce na água sobre a terra, areia, cascalho +Glows in the water=Brilha na água +4 possible sizes=4 tamanhos possíveis +Grows on dead brain coral block=Cresce no bloco de coral-de-cérebro morto +Sea Pickle=Pepino-do-Mar +Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Pepino-do-mar cresce em blocos de coral-de-cérebro mortos e fornecem luz quando estão em baixo d'água. Eles vêm em 4 tamanhos que variam em luminosidade. +It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=Podem ser posicionados apenas sobre blocos de coral-de-cérebro mortos. Posicionar um pepino-do-mar em outro pepino-do-mar o fará crescer e brilhar. + diff --git a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ru.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ru.tr index e7e5a12e3..d3d5d2db4 100644 --- a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ru.tr +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ru.tr @@ -1,59 +1,59 @@ # textdomain: mcl_ocean -Sea Lantern=Морской светильник -Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Морской светильник это декоративный источник света. Он отлично смотрится под водой, но размещать его можно в любых местах. +Sea Lantern=Морской фонарь +Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Морской фонарь это декоративный источник света. Он отлично смотрится под водой, но размещать его можно в любых местах. Prismarine=Призмарин -Prismarine is used as a building block. It slowly changes its color.=Призмарин хорош как строительный блок. Он медленно меняет свой цвет. +Prismarine is used as a building block. It slowly changes its color.=Призмарин это строительный блок. Он медленно меняет свой цвет. Prismarine Bricks=Призмариновые кирпичи Dark Prismarine=Тёмный призмарин -Prismarine Crystals=Призмариновые кристаллы +Prismarine Crystals=Призмариновый кристалл Prismarine Shard=Осколок призмарина Dried Kelp=Сушёная ламинария -Dried Kelp Block=Блок сухой ламинарии -Brain Coral Block=Блок мозгового коралла -Brain Coral Fan=Вентилятор мозгового коралла +Dried Kelp Block=Блок сушёной ламинарии +Brain Coral Block=Мозговой коралловый блок +Brain Coral Fan=Мозговой веерный коралл Brain Coral=Мозговой коралл -Bubble Coral Block=Блок пузыристого коралла -Bubble Coral Fan=Вентилятор пузыристого коралла -Bubble Coral=Пузыристый коралл -Fire Coral Block=Блок огненного коралла -Fire Coral Fan=Вентилятор огненного коралла +Bubble Coral Block=Пузырчатый коралловый блок +Bubble Coral Fan=Пузырчатый веерный коралл +Bubble Coral=Пузырчатый коралл +Fire Coral Block=Огненный коралловый блок +Fire Coral Fan=Огненный веерный коралл Fire Coral=Огненный коралл -Horn Coral Block=Блок рожкового коралла -Horn Coral Fan=Вентилятор рожкового коралла -Horn Coral=Рожковый коралл -Tube Coral Block=Блок трубного коралла -Tube Coral Fan=Вентилятор трубного коралла -Tube Coral=Трубный коралл -Dead Brain Coral Block=Блок мёртвого мозгового коралла -Dead Brain Coral Fan=Вентилятор мёртвого мозгового коралла +Horn Coral Block=Роговый коралловый блок +Horn Coral Fan=Роговый веерный коралл +Horn Coral=Роговый коралл +Tube Coral Block=Трубчатый коралловый блок +Tube Coral Fan=Трубчатый веерный коралл +Tube Coral=Трубчатый коралл +Dead Brain Coral Block=Мёртвый мозговой коралловый блок +Dead Brain Coral Fan=Мёртвый веерный мозговой коралл Dead Brain Coral=Мёртвый мозговой коралл -Dead Bubble Coral Block=Блок мёртвого пузыристого коралла -Dead Bubble Coral Fan=Вентилятор мёртвого пузыристого коралла -Dead Bubble Coral=Мёртвый пузыристый коралл -Dead Fire Coral Block=Блок мёртвого огненного коралла -Dead Fire Coral Fan=Вентилятор мёртвого огненного коралла +Dead Bubble Coral Block=Мёртвый пузырчатый коралловый блок +Dead Bubble Coral Fan=Мёртвый веерный пузырчатый коралл +Dead Bubble Coral=Мёртвый пузырчатый коралл +Dead Fire Coral Block=Мёртвый огненный коралловый блок +Dead Fire Coral Fan=Мёртвый веерный огненный коралл Dead Fire Coral=Мёртвый огненный коралл -Dead Horn Coral Block=Блок мёртвого рожкового коралла -Dead Horn Coral Fan=Вентилятор мёртвого рожкового коралла -Dead Horn Coral=Мёртвый рожковый коралл -Dead Tube Coral Block=Блок мёртвого трубного коралла -Dead Tube Coral Fan=Вентилятор мёртвого трубного коралла -Dead Tube Coral=Мёртвый трубный коралл +Dead Horn Coral Block=Мёртвый роговый коралловый блок +Dead Horn Coral Fan=Мёртвый веерный роговый коралл +Dead Horn Coral=Мёртвый роговый коралл +Dead Tube Coral Block=Мёртвый трубчатый коралловый блок +Dead Tube Coral Fan=Мёртвый веерный трубчатый коралл +Dead Tube Coral=Мёртвый трубчатый коралл Seagrass=Водоросли Kelp=Ламинария -Kelp grows inside water on top of dirt, sand or gravel.=Водоросли растут в воде поверх грязи, песка или гравия. +Kelp grows inside water on top of dirt, sand or gravel.=Ламинария растет под водой на земле, песке или гравии. Coral blocks live in the oceans and need a water source next to them to survive. Without water, they die off.=Коралловые блоки живут в океанах и нуждаются в источниках воды рядом с ними, чтобы выжить. Без воды они умирают. -Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Кораллы растут на вершинах коралловых блоков и должны быть внутри источника воды, чтобы жить. Без воды они умирают, как и коралловые блоки внизу. -Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Кораллов вентиляторы растут на вершинах коралловых блоков и должны быть внутри источника воды, чтобы выжить. Без воды они умирают, как и коралловые блоки внизу. -Seagrass grows inside water on top of dirt, sand or gravel.=Водоросли растут в воде поверх грязи, песка или гравия. +Corals grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Кораллы растут на коралловых блоках и должны быть внутри источника воды, чтобы жить. Без воды они умирают, как и коралловые блоки внизу. +Corals fans grow on top of coral blocks and need to be inside a water source to survive. Without water, it will die off, as well as the coral block below.=Веерные кораллы растут на коралловых блоках и должны быть внутри источника воды, чтобы выжить. Без воды они умирают, как и коралловые блоки внизу. +Seagrass grows inside water on top of dirt, sand or gravel.=Водоросли растут под водой на земле, песке или гравии. A decorative block that serves as a great furnace fuel.=Декоративный блок, служащий отличным топливом для печи. -Dried kelp is a food item.=Сушеная ламинария - это продуктовый предмет. +Dried kelp is a food item.=Сушёная ламинария это съедобный продукт. Grows on coral block of same species=Растет на коралловом блоке того же вида Needs water to live=Нуждается в воде, чтобы жить -Grows in water on dirt, sand, gravel=Растёт в воде на грязи, песке, гравии +Grows in water on dirt, sand, gravel=Растёт под водой на земле, песке, гравии Glows in the water=Светится в воде 4 possible sizes=4 возможных размера -Grows on dead brain coral block=Растёт на блоке мёртвого коралла +Grows on dead brain coral block=Растёт на блоке мёртвого мозгового коралла Sea Pickle=Морской огурец -Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Морские огурцы растут на мертвых коралловых блоках и дают свет под водой. Они бывают четырёх размеров, которые различаются по яркости. -It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=Это можно помещать только на верхушку блока мертвого мозгового коралла. Помещение морского огурца на другой морской огурец приведёт к тому, что он вырастет и станет ярче. +Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Морские огурцы растут на мертвых мозговых коралловых блоках и излучают свет под водой. Они бывают четырёх размеров, которые отличаются яркостью. +It can only be placed on top of dead brain coral blocks. Placing a sea pickle on another sea pickle will make it grow and brighter.=Морской огурец можно помещать только на мёртвый мозговой коралловый блок. Помещение морского огурца на другой морской огурец приведёт к тому, что он вырастет и станет светить ярче. diff --git a/mods/ITEMS/mcl_ocean/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index 32d17538d..fff07cb7e 100644 --- a/mods/ITEMS/mcl_ocean/prismarine.lua +++ b/mods/ITEMS/mcl_ocean/prismarine.lua @@ -52,7 +52,7 @@ minetest.register_node("mcl_ocean:prismarine_brick", { tiles = {"mcl_ocean_prismarine_bricks.png"}, groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 1.5, + _mcl_blast_resistance = 6, _mcl_hardness = 1.5, }) @@ -64,7 +64,7 @@ minetest.register_node("mcl_ocean:prismarine_dark", { tiles = {"mcl_ocean_prismarine_dark.png"}, groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 1.5, + _mcl_blast_resistance = 6, _mcl_hardness = 1.5, }) diff --git a/mods/ITEMS/mcl_portals/README.md b/mods/ITEMS/mcl_portals/README.md index d3faaa8e2..4d00275b3 100644 --- a/mods/ITEMS/mcl_portals/README.md +++ b/mods/ITEMS/mcl_portals/README.md @@ -1,4 +1,4 @@ -# Portals mod for MineClone 2 +# Portals mod for VoxeLibre ## How to create portals Nether portal: Build an upright frame of obsidian, 4 blocks wide and 5 blocks high, and use a flint and steel inside it. @@ -8,7 +8,7 @@ End portal: Build an upright frame of red nether brick blocks, 4 blocks wide and Created by maikerumine and Wuzzy. Code license: MIT License (see `LICENSE`). -Texture license: See README.md in main MineClone 2 directory. +Texture license: See README.md in main VoxeLibre directory. `mcl_portals_teleport.ogg` * License: [CC BY 3.0](http://creativecommons.org/licenses/by/3.0/) diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.de.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.de.tr index 58478faa4..52408ef95 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.de.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.de.tr @@ -1,5 +1,6 @@ # textdomain: mcl_portals End Portal=Endportal +Used to construct end portals=Benutzt zur Konstruktion von Endportalen An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Ein Endportal teleportiert Kreaturen und Objekte zur mysteriösen Ende-Dimension (und wieder zurück!). Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Springen Sie ins Portal, um sich zu teleportieren. Von der Oberwelt aus werden Sie zu einer festen Position im Ende hin teleportiert. Eine 5×5-Obsidianplattform wird am Zielort erzeugt. Im Ende werden Sie zurück zu Ihrem Startpunkt in der Oberwelt teleportiert. End Portal Frame=Endportalrahmen @@ -7,13 +8,14 @@ End portal frames are used in the construction of End portals. Each block has a NOTE: The End dimension is currently incomplete and might change in future versions.=ANMERKUNG: Die Ende-Dimension ist momentan unfertig und könnte sich in künftigen Versionen ändern. 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.=Um ein Endportal zu bauen, brauchen sie 12 Endportalrahmen und 12 Enderaugen. Die Endportalrahmenblöcke muss um ein horizontales Feld von 3×3 platziert sein, wobei jeder von ihnen nach innen zeigt. Jede andere Anordnung wird nicht funktionieren. Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.=Platzieren Sie ein Enderauge in jeden Block. Das Endportal wird sich in der Mitte öffnen, wenn das letzte Auge platziert wurde. +Once placed, an eye of ender can not be taken back.=Sobald platziert, kann ein Enderauge nicht mehr zurück genommen werden. End Portal Frame with Eye of Ender=Endportalrahmen mit Enderauge +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal=Netherportal A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Ein Netherportal teleportiert Kreaturen und Objekte zur heißen und gefährlichen Nether-Dimension (und zurück!). Betreten auf eigene Gefahr! 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.=Stellen Sie sich ins Portal für einen Moment, um sich zu teleportieren. Beim ersten Mal wird auch ein Portal in der anderen Dimension erschaffen. Wenn ein Netherportal im Nether gebaut wird, wird es zurück zur Oberwelt führen. Ein Netherportal wird zerstört, wenn das Obsidian, das ihn umgibt, zerstört wird, oder, wenn es einer Explosion ausgesetzt war. Obsidian is also used as the frame of Nether portals.=Obsidian wird auch als Rahmen von Netherportalen benutzt. To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Um ein Netherportal zu öffnen, platzieren Sie einen aufrechten Rahmen aus Obsidian mit einer Breite von mindestens 4 Blöcken und einer Höhe von mindestens 5 Blöcken, nur mit Luft in der Mitte. Nachdem Sie den Rahmen gebaut haben, entfachen Sie ein Feuer im Obsidianrahmen. Netherportale funktionieren nur in der Oberwelt und im Nether. -Once placed, an eye of ender can not be taken back.=Sobald platziert, kann ein Enderauge nicht mehr zurück genommen werden. -Used to construct end portals=Benutzt zur Konstruktion von Endportalen -Liquid container=Flüssigkeitsbehälter -No effect=Keine Wirkung diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.es.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.es.tr index 5f8509026..49964bd69 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.es.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.es.tr @@ -1,5 +1,6 @@ # textdomain: mcl_portals End Portal=Portal del End +Used to construct end portals= An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Un portal final teletransporta criaturas y objetos a la misteriosa dimensión final (¡y viceversa!). Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Salta al portal para teletransportarte. Entrar en un portal final en el Overworld te teletransporta a una posición fija en la dimensión final y crea una plataforma de obsidiana 5 × 5 en tu destino. Los portales finales en el final lo llevarán de regreso a su punto de generación en el mundo terrenal End Portal Frame=Marco de portal del End @@ -7,13 +8,14 @@ End portal frames are used in the construction of End portals. Each block has a NOTE: The End dimension is currently incomplete and might change in future versions.=NOTA: El portal del end está actualmente incompleto y puede cambiar en futuras versiones. 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.=Para crear un portal final, necesita 12 marcos de portal final y 12 ojos de ender. Los marcos del portal final deben estar dispuestos alrededor de un área horizontal de 3 × 3 con cada bloque mirando hacia adentro. Cualquier otro arreglo fallará. Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.=Coloque un ojo de ender en cada bloque. El portal final aparece en el medio después de colocar el ojo final. +Once placed, an eye of ender can not be taken back.=Una vez colocado, un ojo de ender no puede ser retirado. End Portal Frame with Eye of Ender=Marco de portal del End con ojo de ender +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal=Portal del Nether A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Un portal Nether teletransporta criaturas y objetos a la dimensión Nether ardiente y peligrosa (¡y viceversa!). ¡Entra bajo tu propio riesgo! 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.=SPárate en el portal por un momento para activar la teletransportación. Entrar en un portal Nether por primera vez también creará un nuevo portal en la otra dimensión. Si se ha construido un portal Nether en Nether, conducirá al Overworld. Un portal abisal se destruye si se destruye cualquiera de las obsidianas que lo rodean, o si quedó atrapado en una explosión. Obsidian is also used as the frame of Nether portals.=La obsidiana también se usa como marco de portal del End. To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.= -Once placed, an eye of ender can not be taken back.=Una vez colocado, un ojo de ender no puede ser retirado. - -#OUTDATED: -#To open a Nether portal, place an upright frame of obsidian with a width of 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Para abrir un portal Nether, coloque un marco vertical de obsidiana con un ancho de 4 bloques y una altura de 5 bloques, dejando solo aire en el centro. Después de colocar este marco, enciende un fuego en el marco de obsidiana. Los portales de Nether solo funcionan en Overworld y Nether. diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr index 714075502..3fca2e134 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr @@ -1,15 +1,21 @@ # textdomain: mcl_portals End Portal=Portail de l'End +Used to construct end portals=Utilisé pour construire des portails de l'End An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Un portail de l'End téléporte des créatures et des objets dans la mystérieuse dimension de l'End (et vice-versa !). Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Sautez dans le portail pour vous téléporter. Entrer dans un portail de l'End dans l'Overworld vous téléporte à une position fixe dans la dimension de l'End et crée une plate-forme d'obsidienne 5×5 à votre destination. Les portails de l'End dans l'End vous ramèneront à votre point d'apparition dans l'Overworld. 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. 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.=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.=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. End Portal Frame with Eye of Ender=Cadre de portail de l'End avec œil d'Ender +End Gateway Portal=Portail de Passage de l'End +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!).=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.=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 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. Obsidian is also used as the frame of Nether portals.=L'obsidienne est aussi utilisée comme cadre des portails du Nether. To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Pour ouvrir un portail du Nether, placez un cadre vertical d'obsidienne d'une largeur d'au moins 4 blocs et d'une hauteur de 5 blocs, ne laissant que de l'air au centre. Après avoir placé ce cadre, allumez un feu dans le cadre d'obsidienne. Les portails du Nether ne fonctionnent que dans l'Overworld et le Nether. -Once placed, an eye of ender can not be taken back.=Une fois placé, un œil d'Ender ne peut pas être repris. -Used to construct end portals=Utilisé pour construire des portails de l'End diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr index aea984691..8daeb9bfc 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr @@ -1,15 +1,21 @@ # textdomain: mcl_portals End Portal=エンドポータル +Used to construct end portals=エンドポータルの構築に使用 An End portal teleports creatures and objects to the mysterious End dimension (and back!).=エンドポータルは、生物や物を不可思議なエンドの次元にテレポートさせます(また戻ってくる事も可能)。 Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=ポータルに飛び込むとテレポート。(オーバーワールドにあるエンドポータルに入ると、エンド次元の固定位置にテレポートし、目的地に5×5の黒曜石のプラットフォームが作成されます。そのエンドポータルに入れば、オーバーワールドのスポーン地点に戻れます) End Portal Frame=エンドポータル・フレーム End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=エンドポータル・フレームは、エンダーアイを入れるソケットがあり、エンドポータルの構築に使われます。 NOTE: The End dimension is currently incomplete and might change in future 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.= +Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.= +Once placed, an eye of ender can not be taken back.=エンダーアイは、一度置くと取り戻せません。 End Portal Frame with Eye of Ender=エンドポータル・フレーム(エンダーアイ入り) +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal=ネザーポータル A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=ネザーポータルは、生物や物を熱くて危険なネザー次元にテレポートさせます(また戻ってくる事も可能)。入るのは自己責任で! 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.=ポータルの中でしばらく立っていると、テレポートが有効になります。初めて入った時は、異次元の方にも新たなポータルが作られます(それはオーバーワールドに通じています)。ネザーポータルは、それを囲む黒曜石のどれかが破壊されたり、爆発に巻き込まれたりすると壊れます。 Obsidian is also used as the frame of Nether portals.=黒曜石は、ネザーポータルの枠組としても使われます。 To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=ネザーポータルを開くには、まず黒曜石で直立した枠組を構築します(幅4ブロック以上、高さ5ブロック以上。内側は中空にして黒曜石を配置)。その後、枠の中に火をつけます。ネザーポータルは、オーバーワールドとネザーでしか使えません。 -Once placed, an eye of ender can not be taken back.=エンダーアイは、一度置くと取り戻せません。 -Used to construct end portals=エンドポータルの構築に使用 diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.pl.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.pl.tr index 18d9b4b7b..4263f6085 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.pl.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.pl.tr @@ -1,15 +1,21 @@ # textdomain: mcl_portals End Portal=Portal Kresu +Used to construct end portals=Używane do konstrukcji portali Kresu An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Portal Kresu teleportuje osoby i rzeczy do tajemniczego wymiaru Kresu (i z powrotem!). Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Wskocz do portalu by się teleportować. Wejście do portalu Kresu na Powierzchni przeniesie cię do ustalonej pozycji w wymiarze Kresu i tworzy obsydianową platformę 5×5 w tym miejscu. Portal Kresu w Kresie przeniesie cię do twojego miejsca odradzania. End Portal Frame=Rama portalu Kresu End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=Ramy portalu Kresu są wykorzystywane do konstrukcji portali Kresu. Każdy blok ma miejsce na oko Kresu. NOTE: The End dimension is currently incomplete and might change in future versions.=UWAGA: Wymiar Kresu jest aktualnie nieukończony i może się zmienić w przyszłych wersjach. +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.= +Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.= +Once placed, an eye of ender can not be taken back.=Raz umieszczone oko Kresu nie może być odzyskane End Portal Frame with Eye of Ender=Rama portalu Kresu z okiem Kresu. +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal=Portal Netheru A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Portal Netheru teleportuje osoby i obiekty do gorącego i niebezpiecznego wymiaru Nether (i z powrotem!). Wejdź na własne ryzyko! 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.=Stań w portalu na krótki moment aby aktywować teleport. Wejście przez portal Netheru po raz pierwszy stworzy również nowy portal w drugim wymiarze. Jeśli portal Netheru został zbudowany w Netherze będzie prowadził z powrotem na Powierzchnię. Portal Netheru przestanie działać jeśli któryś z otaczających go bloków obsydianu zostanie zniszczony lub gdy dosięgnie go wybuch. Obsidian is also used as the frame of Nether portals.=Obsydian jest również wykorzystywany do budowania portali Netheru. To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Aby otworzyć portal Netheru umieść ramę z obsydianu o szerokości co najmniej 4 i wysokości 5 bloków, zostawiając tylko powietrze wewnątrz. Po postawieniu tej ramy rozpal ogień wewnątrz ramy. Portale Netheru działają tylko w Netherze i na Powierzchni. -Once placed, an eye of ender can not be taken back.=Raz umieszczone oko Kresu nie może być odzyskane -Used to construct end portals=Używane do konstrukcji portali Kresu diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.ru.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.ru.tr index 8b6310793..bc6b224f1 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.ru.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.ru.tr @@ -1,15 +1,21 @@ # textdomain: mcl_portals -End Portal=Портал Предела -An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Портал Предела телепортирует создания и объекты в загадочное измерение Предел (и обратно!) -Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Прыгайте в портал, чтобы телепортироваться. Вход в портал Предела в Верхнем мире телепортирует вас в определённое место в измерении Предела и создаёт обсидиановую платформу 5×5 в пункте вашего назначения. Портал предела в Пределе перебросит вас в вашу точку возрождения в Верхнем мире. -End Portal Frame=Рамка портала Предела -End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=Рамка портала Предела используется для построения порталов Предела. Каждый блок имеет отсек для ока Предела. -NOTE: The End dimension is currently incomplete and might change in future versions.=Предупреждение: Измерение Предел в данный момент не завершено и может измениться в будущих версиях. -End Portal Frame with Eye of Ender=Рамка портала Предела с оком Предела +End Portal=Портал Края +Used to construct end portals=Используется для создания порталов Края +An End portal teleports creatures and objects to the mysterious End dimension (and back!).=Портал Края телепортирует существ и объекты в загадочное измерение Края (и обратно!) +Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=Прыгайте в портал, чтобы телепортироваться. Портал Края в Верхнем мире телепортирует вас в определённое место в измерении Края и создаёт обсидиановую платформу 5×5 в пункте вашего назначения. Портал Края в измерении Края телепортирует вас в вашу точку возрождения в Верхнем мире. +End Portal Frame=Рамка портала Края +End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=Рамка портала Края используется для построения порталов Края. Каждый блок имеет слот для ока Края. +NOTE: The End dimension is currently incomplete and might change in future 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.=Чтобы создать портал Края, вам нужны 12 рамок портала Края и 12 ок Края. Рамки портала устанавливаются горизонтально 3×3 с каждым блоком лицом вовнутрь. Любая другая структура ничего не даст. +Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.=Поставьте око Края в каждый блок. Портал Края появится по середине после установки последнего ока. +Once placed, an eye of ender can not be taken back.=Размещенное око Края нельзя забрать обратно. +End Portal Frame with Eye of Ender=Рамка портала Края с оком Края +End Gateway Portal=Врата Края +Used to construct end gateway portals=Используется для постройки врат Края +An End gateway portal teleports creatures and objects to the outer End (and 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.=Киньте жемчуг Края в портал чтобы телепортироваться. Войдя во портал врат рядом с Верхним миром, вы телепортируетесь во внешний Край. На месте прибытия появится еще одни врата, которые перенесут вас обратно. Nether Portal=Адский портал -A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Адский портал переносит создания и объекты в горячее и опасное измерение Ад (и обратно!). Используйте на свой страх и риск! -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.=Стойте в портале несколько секунд для запуска телепортации. Вход в портал Ада в первый раз приведёт к созданию аналогичного портала в другом измерении. Если Адский портал создан в Аду, он ведёт в Верхний мир. Портал Ада уничтожается, если уничтожается любой блок обсидиана из окружающих его, либо при задевании взрывом. -Obsidian is also used as the frame of Nether portals.=Обсидиан также используется в качестве рамки портала Ада -To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Чтобы открыть портал Ада, постройте рамку из обсидиана шириной не менее 4 блоков и высото не менее 5, оставляя в центре лишь воздух. После создания обсидиановой рамки зажгите в ней огонь. Адские порталы работают только в Верхнем мире и в Аду. -Once placed, an eye of ender can not be taken back.=Однажды размещённое, око Предела нельзя взять обратно. -Used to construct end portals=Используется для создания порталов Предела +A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=Адский портал переносит создания и объекты в горячее и опасное измерение Незера (и обратно!). Используйте на свой страх и риск! +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.=Стойте в портале несколько секунд для запуска телепортации. Вход в портал Незера в первый раз приведёт к созданию аналогичного портала в другом измерении. Если Адский портал создан в Незере, он приведёт в Верхний мир. Адский портал уничтожается, если уничтожается любой блок обсидиана из окружающих его, либо при задевании взрывом. +Obsidian is also used as the frame of Nether portals.=Обсидиан также используется в качестве рамки Адского портала +To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=Чтобы открыть Адский портал, постройте рамку из обсидиана шириной не менее 4 блоков и высотой не менее 5, оставляя в центре рамки лишь воздух. После создания обсидиановой рамки зажгите в ней огонь. Адские порталы работают только в Верхнем мире и в Незере. diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr index a6b389036..7d1031459 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr @@ -1,15 +1,21 @@ # textdomain: mcl_portals End Portal=終界傳送門 +Used to construct end portals=用於建造終界傳送門 An End portal teleports creatures and objects to the mysterious End dimension (and back!).=終界傳送門用於將生物和實體到達終末之界(或回來!)。 Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.=跳入傳送門進行傳送。進入終界傳送門會將你傳送到終界的一個固定位置,並在你的目的地創建一個5×5的黑曜石平台。終界的傳送門會將你帶回你在主界的出生點。 End Portal Frame=終界傳送門框架 End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.=終界傳送門框架用於建造終界傳送門。每個框架都有一個插座,用於放置終界之眼。 NOTE: The End dimension is currently incomplete and might change in future 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.= +Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.= +Once placed, an eye of ender can not be taken back.=在擺放後,終界之眼無法再取回。 End Portal Frame with Eye of Ender=含終界之眼的終界傳送門框架 +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal=地獄傳送門 A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!=地獄傳送門將生物和實體傳送到炎熱和危險的地獄(或回來!)。進入後風險自負! 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.=在傳送門中站立片刻以激活傳送。第一次進入地獄傳送門也會在另一維度創建一個新的傳送門。如果在地獄建立了地獄傳送門,它將會通​​向主世界。如果圍繞著它的任何黑曜石被毀壞,或者它被捲入一場爆炸,地獄傳送門就會被破壞。 Obsidian is also used as the frame of Nether portals.=黑曜石也被用來作為地獄傳送門的框架。 To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.=要打開地獄傳送門,需要放置一個直立的黑曜石框架,寬度至少為4塊,高度為5塊,中間只留有空氣。放置這個框架後,在黑曜石框架中點火。地獄傳送門只在主世界上和地獄起作用。 -Once placed, an eye of ender can not be taken back.=在擺放後,終界之眼無法再取回。 -Used to construct end portals=用於建造終界傳送門 diff --git a/mods/ITEMS/mcl_portals/locale/template.txt b/mods/ITEMS/mcl_portals/locale/template.txt index 21f5e21f8..5a154a698 100644 --- a/mods/ITEMS/mcl_portals/locale/template.txt +++ b/mods/ITEMS/mcl_portals/locale/template.txt @@ -1,15 +1,21 @@ # textdomain: mcl_portals End Portal= +Used to construct end portals= An End portal teleports creatures and objects to the mysterious End dimension (and back!).= Hop into the portal to teleport. Entering an End portal in the Overworld teleports you to a fixed position in the End dimension and creates a 5×5 obsidian platform at your destination. End portals in the End will lead back to your spawn point in the Overworld.= End Portal Frame= End portal frames are used in the construction of End portals. Each block has a socket for an eye of ender.= NOTE: The End dimension is currently incomplete and might change in future 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.= +Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.= +Once placed, an eye of ender can not be taken back.= End Portal Frame with Eye of Ender= +End Gateway Portal= +Used to construct end gateway portals= +An End gateway portal teleports creatures and objects to the outer End (and 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.= Nether Portal= A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!= 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.= Obsidian is also used as the frame of Nether portals.= To open a Nether portal, place an upright frame of obsidian with a width of at least 4 blocks and a height of 5 blocks, leaving only air in the center. After placing this frame, light a fire in the obsidian frame. Nether portals only work in the Overworld and the Nether.= -Once placed, an eye of ender can not be taken back.= -Used to construct end portals= diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index 5f889d86f..d261b4bd3 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -2,8 +2,6 @@ local modname = minetest.get_current_modname() local S = minetest.get_translator(modname) local modpath = minetest.get_modpath(modname) -local SCAN_2_MAP_CHUNKS = true -- slower but helps to find more suitable places - -- Localize functions for better performance local abs = math.abs local ceil = math.ceil @@ -16,21 +14,117 @@ local add = vector.add local mul = vector.multiply local sub = vector.subtract +local log = function(level, message) + minetest.log(level, string.format("[mcl_portals] %s", message)) +end + +-- Resources + +-- Issue that has a lot of context: https://git.minetest.land/VoxeLibre/VoxeLibre/issues/4120 +-- Minecraft portal mechanics: https://minecraft.fandom.com/wiki/Tutorials/Nether_portals +-- Flow diagram: https://docs.google.com/drawings/d/1WIl4pVuxgOxI3Ncxk4g6D1pL4Fyll3bQ-fX6L9yyiLw/edit +-- Useful boundaries: https://git.minetest.land/VoxeLibre/VoxeLibre/wiki/World-structure%3A-positions%2C-boundaries%2C-blocks%2C-chunks%2C-dimensions%2C-barriers-and-the-void + -- Setup + +-- === CAUTION === +-- the following values: SEARCH_DISTANCE_OVERWORLD, SEARCH_DISTANCE_NETHER, +-- BUILD_DISTANCE_XY, W_MAX, and NETHER_COMPRESSION have been set to together +-- guarantee that standard 2-wide portals will never split into two exits. +-- Splitting will still occur rarely for portals in the overworld wider than 2, +-- will still be likely for portals in the nether wider than 16, and guaranteed +-- for portals in the nether wider than 18. +-- Changing one value without changing the others might have uninteded +-- consequences. You have been warned :-) + +-- Distance compression factor for the nether. If you change this, you might +-- want to recalculate SEARCH_DISTANCE_* and W_MAX too. +local NETHER_COMPRESSION = 8 +-- Maximum distance from the ideal build spot where active parts of portals are +-- allowed to be placed. +-- There is a tradeoff here between the "walking" distance (distance to walk in +-- the overworld to get a new nether portal exit, which we want to be as similar +-- to Minecraft as possible, which is 136 [16*8+8]), and the area available for +-- exit search (which we want to maximise). +-- For our mapgen performance reasons, our search area is clipped by chunk, so +-- in the unlucky corner case the worst-case build area could be a quarter of +-- the expected size. +-- For MC build distance of 16, which gives a build area of 1,089 X-Z blocks +-- [(16+16+1)*(16+16+1)]. To guarantee this area here, we'd need to pick a build +-- distance of 32 [(32+32+1)*(32+32+1)/4]. But build distance of 32 implies +-- walking distance of 264 [32*8+8], which is already quite far, so need to pick +-- the right tradeoff: +-- +-- Build dist Minimum build area Minimum walk distance +-- 48 2,401 392 +-- 32 1,089 264 +-- 24 625 200 +-- 16 289 136 +local BUILD_DISTANCE_XZ = 24 +-- The following two values define distance to search existing portal exits for. +-- For context, Minecraft search is "8 chunks away" for the overworld (17 +-- chunks centered on the ideal position), and "1 chunk away" for the nether (3 +-- chunks centered on the ideal position). +-- To prevent portal splitting on spawned portals, we add one to the build +-- distance: spawned portals are 2-wide, so we need to make sure that we can +-- reach the second exit block (which can spawn in the direction away from the +-- player). +-- The search is boundary-inclusive, meaning for position 0 in the overworld, +-- search will be from -N to N. +-- If you change this, keep in mind our exits table keying divisor is 256, so +-- small changes might have outsize performance impact. At <=128, max 4 buckets +-- are searched, at 200 max 9 buckets are searched. +local SEARCH_DISTANCE_NETHER = BUILD_DISTANCE_XZ + 1 -- 25 +local SEARCH_DISTANCE_OVERWORLD = SEARCH_DISTANCE_NETHER * NETHER_COMPRESSION -- 200 +-- Limits of portal sizes (includes the frame) local W_MIN, W_MAX = 4, 23 local H_MIN, H_MAX = 5, 23 +-- Limits to active nodes (mcl_portals:portal) local N_MIN, N_MAX = 6, (W_MAX-2) * (H_MAX-2) -local TRAVEL_X, TRAVEL_Y, TRAVEL_Z = 8, 1, 8 local LIM_MIN, LIM_MAX = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max local PLAYER_COOLOFF, MOB_COOLOFF = 3, 14 -- for this many seconds they won't teleported again local TOUCH_CHATTER_TIME = 1 -- prevent multiple teleportation attempts caused by multiple portal touches, for this number of seconds local CHATTER_US = TOUCH_CHATTER_TIME * 1000000 local DELAY = 3 -- seconds before teleporting in Nether portal in Survival mode (4 minus ABM interval time) -local DISTANCE_MAX = 128 +-- Speeds up the search by allowing some non-air nodes to be replaced when +-- looking for acceptable portal locations. Setting this lower means the +-- algorithm will do more searching. Even at 0, there is no risk of finding +-- nothing - the most airy location will be used as fallback anyway. +local ACCEPTABLE_PORTAL_REPLACES = 2 + + local PORTAL = "mcl_portals:portal" local OBSIDIAN = "mcl_core:obsidian" -local O_Y_MIN, O_Y_MAX = max(mcl_vars.mg_overworld_min, -31), min(mcl_vars.mg_overworld_max, 2048) -local N_Y_MIN, N_Y_MAX = mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_top_min - H_MIN + +-- Dimension-specific Y boundaries for portal exit search. Portal search +-- algorithm will only ever look at two vertically offset chunks. It will +-- select whether the second chunk is up or down based on which side has more +-- "valid" Y-space (where valid is defined as space between *_Y_MIN and +-- *_Y_MAX). +-- For nether, selection of the boundaries doesn't matter, because it fits +-- entirely within two chunks. +local N_Y_MIN = mcl_vars.mg_lava_nether_max + 1 +local N_Y_MAX = mcl_vars.mg_bedrock_nether_top_min +local N_Y_SPAN = N_Y_MAX - N_Y_MIN +-- Overworld however is much taller. Let's select the boundaries so that we +-- maximise the Y-space (so align with chunk boundary), and also pick an area +-- that has a good chance of having "find_nodes_in_area_under_air" return +-- something (so ideally caves, or surface, not just sky). +-- For the bottom bound, we try for the first chunk boundary in the negative Ys (-32). +local O_Y_MIN = max(mcl_vars.mg_lava_overworld_max + 1, mcl_vars.central_chunk_offset_in_nodes) +-- Since O_Y_MIN is also used as a base for converting coordinates, we need to +-- make sure the top bound is high enough to encompass entire nether height. In +-- v7 mapgen nether is flatter than overworld, so this results in a span of +-- exactly two chunks. +-- Due to the O_Y_MIN being used as a base, the preferred build locations will +-- be in the bottom part of the overworld range (in v7 around -32 to 61), and +-- the high locations will be used as a fallback. If we see too many +-- underground portals, we may need to shift just this base upwards (new setting). +local O_Y_SPAN = max(N_Y_SPAN, 2 * mcl_vars.chunk_size_in_nodes - 1) +local O_Y_MAX = min(mcl_vars.mg_overworld_max_official, O_Y_MIN + O_Y_SPAN) + +log("verbose", string.format("N_Y_MIN=%.1f, N_Y_MAX=%.1f, O_Y_MIN=%.1f, O_Y_MAX=%.1f", N_Y_MIN, N_Y_MAX, O_Y_MIN, O_Y_MAX)) +log("verbose", string.format("Nether span is %.1f, overworld span is %.1f", N_Y_MAX-N_Y_MIN+1, O_Y_MAX-O_Y_MIN+1)) -- Alpha and particles local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" @@ -47,11 +141,26 @@ end local chatter = {} -local queue = {} -local chunks = {} +-- Searching for portal exits, finding locations and building portals can be time consuming. +-- We can queue origins together, on the assumption they will all go to the same place in the end. +local origin_queue = {} +-- At the same time, we never want to build two portals in the same area at the +-- same time, because they will interfere and we can end up with broken portals, +-- possibly stranding the player. We won't use queue here - double queueing can +-- lead to deadlocks. We will instead interrupt the portal building, and rely +-- on the ABM to try again later. +local chunk_building = {} local storage = mcl_portals.storage + +-- `exits` is a table storing portal exits (both nether or overworld) bucketed +-- by 256x256 areas (with each bucket containing many exits, and covering entire range of Y). +-- An exit is a location of ignited PORTAL block, with another PORTAL block above +-- and obsidian below. Thus each portal will register at minimum two exits, but more +-- for bigger portals up to the maximum of W_MAX-2. +-- This table should be maintained using `add_exits`, `remove_exits` and `find_exit`. local exits = {} + local keys = minetest.deserialize(storage:get_string("nether_exits_keys") or "return {}") or {} for _, key in pairs(keys) do local n = tonumber(key) @@ -59,14 +168,6 @@ for _, key in pairs(keys) do exits[key] = minetest.deserialize(storage:get_string("nether_exits_"..key) or "return {}") or {} end end -minetest.register_on_shutdown(function() - local keys={} - for key, data in pairs(exits) do - storage:set_string("nether_exits_"..tostring(key), minetest.serialize(data)) - keys[#keys+1] = key - end - storage:set_string("nether_exits_keys", minetest.serialize(keys)) -end) local get_node = mcl_vars.get_node local set_node = minetest.set_node @@ -74,7 +175,6 @@ local registered_nodes = minetest.registered_nodes local is_protected = minetest.is_protected local find_nodes_in_area = minetest.find_nodes_in_area local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air -local log = minetest.log local pos_to_string = minetest.pos_to_string local is_area_protected = minetest.is_area_protected local get_us_time = minetest.get_us_time @@ -92,15 +192,19 @@ local limits = { }, } -local function save_portal_pos(pos,target_pos) - local p1 = vector.offset(pos,-2,-1,-2) - local p2 = vector.offset(pos,2,15,2) +-- Deletes exit from this portal's node storage. +local function delete_portal_pos(pos) + local p1 = vector.offset(pos,-5,-1,-5) + local p2 = vector.offset(pos,5,5,5) local nn = find_nodes_in_area(p1,p2,{"mcl_portals:portal"}) for _,p in pairs(nn) do - minetest.get_meta(p):set_string("target_portal",minetest.hash_node_position(target_pos)) + minetest.get_meta(p):set_string("target_portal","") end end +-- Gets exit for this portal from node storage. After Jan 2024 this is only used +-- for old portals, so that players don't get surprises. New portals, or portals that lost +-- node storage due to destruction should use the lookup table. local function get_portal_pos(pos) local p1 = vector.offset(pos,-5,-1,-5) local p2 = vector.offset(pos,5,5,5) @@ -113,124 +217,290 @@ local function get_portal_pos(pos) end end --- This function registers exits from Nether portals. --- Incoming verification performed: two nodes must be portal nodes, and an obsidian below them. --- If the verification passes - position adds to the table and saves to mod storage on exit. +-- `exits` is a lookup table bucketing exits by 256x256 areas. This function +-- returns a key for provided position p. +local function get_exit_key(p) + local x, z = floor(p.x), floor(p.z) + return floor(z/256) * 256 + floor(x/256) +end + +-- Add an exit to the exits table without writing to disk. Returns the exits +-- table key if modification was done, and specifies whether the key was new. local function add_exit(p) - if not p or not p.y or not p.z or not p.x then return end + local retval = {key=false, new=false} + + if not p or not p.y or not p.z or not p.x then + return retval + end local x, y, z = floor(p.x), floor(p.y), floor(p.z) local p = {x = x, y = y, z = z} - if get_node({x=x,y=y-1,z=z}).name ~= OBSIDIAN or get_node(p).name ~= PORTAL or get_node({x=x,y=y+1,z=z}).name ~= PORTAL then return end - local k = floor(z/256) * 256 + floor(x/256) + + if get_node({x=x,y=y-1,z=z}).name ~= OBSIDIAN + or get_node(p).name ~= PORTAL + or get_node({x=x,y=y+1,z=z}).name ~= PORTAL + then + return retval + end + + local k = get_exit_key(p) if not exits[k] then exits[k]={} + retval.new = true end + local e = exits[k] for i = 1, #e do local t = e[i] if t and t.x == p.x and t.y == p.y and t.z == p.z then - return + return retval end end + e[#e+1] = p - log("action", "[mcl_portals] Exit added at " .. pos_to_string(p)) + retval.key = k + return retval end --- This function removes Nether portals exits. +-- This function registers one or more exits from Nether portals and writes +-- updated table buckets to disk. +-- Exit position must be an ignited PORTAL block that sits on top of obsidian, +-- and has additional PORTAL block above it. +-- This function will silently skip exits that are invalid during the call-time. +-- If the verification passes, a new exit is added to the table of exits and +-- saved to mod storage later. Duplicate exits will be skipped and won't cause +-- writes. +local function add_exits(positions) + local keys_to_write = {} + local new_key_present = false + + for _, p in ipairs(positions) do + local r = add_exit(p) + if r.key ~= false then + if r.new then + new_key_present = true + keys[#keys+1] = r.key + end + keys_to_write[#keys_to_write+1] = r.key + log("verbose", "Exit added at " .. pos_to_string(p)) + end + end + + for _, key in ipairs(keys_to_write) do + storage:set_string("nether_exits_"..tostring(key), minetest.serialize(exits[key])) + end + if new_key_present then + storage:set_string("nether_exits_keys", minetest.serialize(keys)) + end +end + +-- Removes one portal exit from the exits table without writing to disk. +-- Returns the false or bucket key if change was made. local function remove_exit(p) - if not p or not p.y or not p.z or not p.x then return end + if not p or not p.y or not p.z or not p.x then + return false + end + local x, y, z = floor(p.x), floor(p.y), floor(p.z) - local k = floor(z/256) * 256 + floor(x/256) - if not exits[k] then return end local p = {x = x, y = y, z = z} + + local k = get_exit_key(p) + if not exits[k] then + return false + end + local e = exits[k] if e then for i, t in pairs(e) do if t and t.x == x and t.y == y and t.z == z then e[i] = nil - log("action", "[mcl_portals] Nether portal removed from " .. pos_to_string(p)) - return + return k end end end + + return false end --- This functon searches Nether portal nodes whitin distance specified -local function find_exit(p, dx, dy, dz) - if not p or not p.y or not p.z or not p.x then return end - local dx, dy, dz = dx or DISTANCE_MAX, dy or DISTANCE_MAX, dz or DISTANCE_MAX - if dx < 1 or dy < 1 or dz < 1 then return false end +-- Removes one or more portal exits and writes updated table buckets to disk. +local function remove_exits(positions) + local keys_to_write = {} + + for _, p in ipairs(positions) do + r = remove_exit(p) + if r ~= false then + keys_to_write[#keys_to_write+1] = r + log("verbose", "Exit removed from " .. pos_to_string(p)) + end + end + + for _, key in ipairs(keys_to_write) do + storage:set_string("nether_exits_"..tostring(key), minetest.serialize(exits[key])) + end +end + +-- Searches for portal exits nearby point p within the distances specified by dx +-- and dz (but only in the same dimension). Otherwise as in Minecraft, the +-- search is bounded by X and Z, but not Y. +-- If multiple exits are found, use Euclidean distance to find the nearest. This +-- uses all three coordinates. +local function find_exit(p, dx, dz) + local dim = mcl_worlds.pos_to_dimension(p) + + if not p or not p.y or not p.z or not p.x then + log("warning", "Corrupt position passed to find_exit: "..pos_to_string(p)..".") + return + end + if dx < 1 or dz < 1 then return false end - --y values aren't used local x = floor(p.x) - --local y = floor(p.y) - local z = floor(p.z) + local z = floor(p.z) - local x1 = x-dx+1 - --local y1 = y-dy+1 - local z1 = z-dz+1 + local x1 = x-dx + local z1 = z-dz - local x2 = x+dx-1 - --local y2 = y+dy-1 - local z2 = z+dz-1 + local x2 = x+dx + local z2 = z+dz + -- Scan the relevant hash table keys for viable exits. Dimension's entire Y is scanned. local k1x, k2x = floor(x1/256), floor(x2/256) local k1z, k2z = floor(z1/256), floor(z2/256) - - local t, d - for kx = k1x, k2x do for kz = k1z, k2z do - local k = kz*256 + kx - local e = exits[k] - if e then - for _, t0 in pairs(e) do - local d0 = dist(p, t0) - if not d or d>d0 then - d = d0 - t = t0 - if d==0 then return t end + local nearest_exit, nearest_distance + for kx = k1x, k2x do + for kz = k1z, k2z do + local k = kz*256 + kx + local e = exits[k] + if e then + for _, t0 in pairs(e) do + if mcl_worlds.pos_to_dimension(t0) == dim then + -- exit is in the correct dimension + if abs(t0.x-p.x) <= dx and abs(t0.z-p.z) <= dz then + -- exit is within the search range + local d0 = dist(p, t0) + if not nearest_distance or nearest_distance>d0 then + -- it is the only exit so far, or it is the Euclidean-closest exit + nearest_distance = d0 + nearest_exit = t0 + if nearest_distance==0 then return nearest_exit end + end + end + end end end end - end end - - if t and abs(t.x-p.x) <= dx and abs(t.y-p.y) <= dy and abs(t.z-p.z) <= dz then - return t end + + return nearest_exit end - --- Ping-Pong the coordinate for Fast Travelling, https://git.minetest.land/Wuzzy/MineClone2/issues/795#issuecomment-11058 -local function ping_pong(x, m, l1, l2) - if x < 0 then - return l1 + abs(((x*m+l1) % (l1*4)) - (l1*2)), floor(x*m/l1/2) + ((ceil(x*m/l1)+1)%2) * ((x*m)%l1)/l1 - end - return l2 - abs(((x*m+l2) % (l2*4)) - (l2*2)), floor(x*m/l2/2) + (floor(x*m/l2)%2) * ((x*m)%l2)/l2 -end - -local function get_target(p) - if p and p.y and p.x and p.z then - local x, z = p.x, p.z - local y, d = mcl_worlds.y_to_layer(p.y) - local o1, o2 -- y offset - if y then - if d=="nether" then - x, o1 = ping_pong(x, TRAVEL_X, LIM_MIN, LIM_MAX) - z, o2 = ping_pong(z, TRAVEL_Z, LIM_MIN, LIM_MAX) - y = floor(y * TRAVEL_Y + (o1+o2) / 16 * LIM_MAX) - y = min(max(y + O_Y_MIN, O_Y_MIN), O_Y_MAX) - elseif d=="overworld" then - x, y, z = floor(x / TRAVEL_X + 0.5), floor(y / TRAVEL_Y + 0.5), floor(z / TRAVEL_Z + 0.5) - y = min(max(y + N_Y_MIN, N_Y_MIN), N_Y_MAX) - end - return {x=x, y=y, z=z}, d +minetest.register_chatcommand("dumpportalkeys", { + description = S("Dump all portal keys"), + privs = { debug = true }, + func = function(name, param) + keys = {} + for k, _ in pairs(exits) do + keys[#keys+1] = k end + output = string.format("Nether portal exits keys: %s", table.concat(keys, ", ")) + return true, output + end, +}) + +local function dump_key(key) + output = string.format("[%d] => ", tonumber(key)) + for _,p in pairs(exits[tonumber(key)]) do + output = output .. minetest.pos_to_string(p) .. " " end + output = output .. "\n" + return output +end + +minetest.register_chatcommand("dumpportalexits", { + description = S("Dump coordinates of registered nether portal exits"), + privs = { debug = true }, + params = "[key]", + func = function(name, param) + local key = param + + if not key or key == "" then + output = "Nether portal exit locations (all dimensions):\n" + else + output = string.format("Nether portal exit locations for key [%s] (all dimensions):\n", key) + end + + if not key or key == "" then + local count = 0 + for k, _ in pairs(exits) do + count = count + 1 + if count>100 then + output = output .. "The list exceeds 100 keys, truncated. Try /dumpportalkeys, then /dumpportalexits KEY" + break + end + + output = output .. dump_key(k) + end + else + -- key specified, no limits + if not exits[tonumber(key)] then + output = output .. string.format("No exits in key [%s]\n", key) + else + dump_key(key) + end + end + + return true, output + end, +}) + +-- Map coordinates between dimensions. Distances in X and Z are scaled by NETHER_COMPRESSION. +-- Distances in Y are mapped directly. Caller should check the return value, this function +-- returns nil if there is no valid mapping - for example if the target would be out of world. +local function get_target(p) + if not p or not p.y or not p.x or not p.z then + return + end + + local _, dim = mcl_worlds.y_to_layer(p.y) + local x,y,z + if dim=="nether" then + -- traveling to OW + x = floor(p.x * NETHER_COMPRESSION) + z = floor(p.z * NETHER_COMPRESSION) + + if x>=LIM_MAX or x<=LIM_MIN or z>=LIM_MAX or z<=LIM_MIN then + -- Traveling out of bounds is forbidden. + return + end + + y = max(min(p.y, N_Y_MAX), N_Y_MIN) + y = y - N_Y_MIN + y = O_Y_MIN + y + y = max(min(y, O_Y_MAX), O_Y_MIN) + else + -- traveling to the nether + x = floor(p.x / NETHER_COMPRESSION) + z = floor(p.z / NETHER_COMPRESSION) + + if x>=LIM_MAX or x<=LIM_MIN or z>=LIM_MAX or z<=LIM_MIN then + -- Traveling out of bounds is forbidden. + return + end + + y = max(min(p.y, O_Y_MAX), O_Y_MIN) + y = y - O_Y_MIN + y = N_Y_MIN + y + y = max(min(y, N_Y_MAX), N_Y_MIN) + end + + return vector.new(x,y,z) end -- Destroy a nether portal. Connected portal nodes are searched and removed -- using 'bulk_set_node'. This function is called from 'after_destruct' of -- nether portal nodes. The flag 'destroying_portal' is used to avoid this -- function being called recursively through callbacks in 'bulk_set_node'. +-- To maintain portal integrity, it is permitted to destroy protected portal +-- blocks if the portal structure is only partly protected, and the player +-- destroys the part that is sticking out. local destroying_portal = false local function destroy_nether_portal(pos, node) if destroying_portal then @@ -267,7 +537,7 @@ local function destroy_nether_portal(pos, node) end check_remove({x = pos.x, y = pos.y - 1, z = pos.z}) check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) - remove_exit(pos) + remove_exits({pos}) i = i + 1 end @@ -277,6 +547,7 @@ end local on_rotate if minetest.get_modpath("screwdriver") then + -- Presumably because it messes with the placement of exits. on_rotate = screwdriver.disallow end @@ -335,14 +606,12 @@ minetest.register_node(PORTAL, { _mcl_blast_resistance = 0, }) -local function light_frame(x1, y1, z1, x2, y2, z2, name, node, node_frame) +local function build_and_light_frame(x1, y1, z1, x2, y2, z2, name) local orientation = 0 if x1 == x2 then orientation = 1 end local pos = {} - local node = node or {name = PORTAL, param2 = orientation} - local node_frame = node_frame or {name = OBSIDIAN} for x = x1 - 1 + orientation, x2 + 1 - orientation do pos.x = x for z = z1 - orientation, z2 + orientation do @@ -351,28 +620,87 @@ local function light_frame(x1, y1, z1, x2, y2, z2, name, node, node_frame) pos.y = y local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2) if frame then - set_node(pos, node_frame) + set_node(pos, {name = OBSIDIAN}) else - set_node(pos, node) - add_exit({x=pos.x, y=pos.y-1, z=pos.z}) + set_node(pos, {name = PORTAL, param2 = orientation}) + add_exits({ + {x=pos.x, y=pos.y-1, z=pos.z} + }) end end end end end ---Build arrival portal -function build_nether_portal(pos, width, height, orientation, name, clear_before_build) - local width, height, orientation = width or W_MIN - 2, height or H_MIN - 2, orientation or random(0, 1) +-- Create a portal, where cube_pos1 is the "bottom-left" coordinate of the +-- W_MINxH_MIN cube to contain the portal - i.e. the coordinate with the +-- smallest X, Y and Z. We will be placing the portal in the middle-ish, so +-- that block +1,+1,+1 is guaranteed to be a portal block. The build area +-- includes frame. +-- Small obsidian platform will be created on either side of the exit if there +-- is no nodes there, or nodes underneath (one step down is permitted). +-- Orientation 0 is portal alongside X axis, 1 alongside Z. +function build_nether_portal(cube_pos1, width, height, orientation, name, clear_before_build) + local width, height, orientation = width or W_MIN, height or H_MIN, orientation or random(0, 1) + local width_inner = width-2 + local height_inner = height-2 + + local cube_pos2 = add(cube_pos1, vector.new(width-1, height-1, width-1)) + if is_area_protected(cube_pos1, cube_pos2, name) then + if name then + minetest.chat_send_player(name, "Unable to build portal, area is protected.") + end + return + end + + -- Calculate "bottom-left" position of the PORTAL blocks. + -- Offset Y because we don't want it in the floor. + -- Offset X and Z to fit the frame and place the portal in the middle-ish. + local pos = add(cube_pos1, vector.new(1,1,1)) if clear_before_build then - light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name, {name="air"}, {name="air"}) + local clear1, clear2 + if orientation == 0 then + clear1 = vector.new( + cube_pos1.x, + cube_pos1.y + 1, -- do not delete floor + cube_pos1.z + ) + clear2 = vector.new( + cube_pos1.x + width - 1, + cube_pos1.y + height - 2, + cube_pos1.z + 2 -- both sides of the entrance, so player has somewhere to step. + ) + else + clear1 = vector.new( + cube_pos1.x, + cube_pos1.y + 1, -- do not delete floor + cube_pos1.z + ) + clear2 = vector.new( + cube_pos1.x + 2, -- both sides of the entrance, so player has somewhere to step. + cube_pos1.y + height - 2, + cube_pos1.z + width - 1 + ) + end + + log("verbose", "Clearing between "..pos_to_string(clear1).." and "..pos_to_string(clear2)) + local airs = {} + for x = clear1.x, clear2.x do + for y = clear1.y, clear2.y do + for z = clear1.z, clear2.z do + airs[#airs+1] = vector.new(x,y,z) + end + end + end + minetest.bulk_set_node(airs, {name="air"}) end - light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), name) + + build_and_light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width_inner - 1), pos.y + height_inner - 1, pos.z + orientation * (width_inner - 1), name) -- Build obsidian platform: - for x = pos.x - orientation, pos.x + orientation + (width - 1) * (1 - orientation), 1 + orientation do - for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width - 1) * orientation, 2 - orientation do + for x = pos.x - orientation, pos.x + orientation + (width_inner - 1) * (1 - orientation), 1 + orientation do + for z = pos.z - 1 + orientation, pos.z + 1 - orientation + (width_inner - 1) * orientation, 2 - orientation do local pp = {x = x, y = pos.y - 1, z = z} local pp_1 = {x = x, y = pos.y - 2, z = z} local nn = get_node(pp).name @@ -383,11 +711,12 @@ function build_nether_portal(pos, width, height, orientation, name, clear_before end end - log("action", "[mcl_portals] Destination Nether portal generated at "..pos_to_string(pos).."!") + log("verbose", "Portal generated at "..pos_to_string(pos).."!") return pos end +-- Spawn portal at location - spawning is not guaranteed if target area is protected. function mcl_portals.spawn_nether_portal(pos, rot, pr, name) if not pos then return end local o = 0 @@ -398,9 +727,73 @@ function mcl_portals.spawn_nether_portal(pos, rot, pr, name) o = random(0,1) end end - build_nether_portal(pos, nil, nil, o, name, true) + return build_nether_portal(pos, W_MIN, H_MIN, o, name, true) end +-- Useful for testing - it lets player point to a block and create the portal in +-- the exact spot using the block as floor, with correct orientation (facing the +-- player). Alternatively, portals can be created at exact locations and +-- orientations (which spawn structure doesn't support). +minetest.register_chatcommand("spawnportal", { + description = S("Spawn a new nether portal at pointed thing, or at [x],[y],[z]. " + .."The portal will either face the player, or use the passed [orientation]. " + .."Orientation 0 means alongside X axis."), + privs = { debug = true }, + params = "[x] [y] [z] [orientation]", + func = function(name, param) + local params = {} + for p in param:gmatch("-?[0-9]+") do table.insert(params, p) end + + local exit + if #params==0 then + local player = minetest.get_player_by_name(name) + if not player then return false, "Player not found" end + + local yaw = player:get_look_horizontal() + local player_rotation = yaw / (math.pi*2) + local orientation + if (player_rotation<=0.875 and player_rotation>0.625) + or (player_rotation<=0.375 and player_rotation>0.125) + then + orientation = "90" + else + orientation = "0" + end + + local pointed_thing = mcl_util.get_pointed_thing(player, false) + if not pointed_thing then return false, "Not pointing to anything" end + if pointed_thing.type~="node" then return false, "Not pointing to a node" end + + local pos = pointed_thing.under + -- Portal node will appear above the pointed node. The pointed node will turn into obsidian. + exit = mcl_portals.spawn_nether_portal(add(pos, vector.new(-1,0,-1)), orientation, nil, name) + elseif #params==3 or #params==4 then + pos = { + x=tonumber(params[1]), + y=tonumber(params[2]), + z=tonumber(params[3]) + } + + local orientation = 0 + if #params==4 then + if tonumber(params[4])==1 then orientation = "90" else orientation = "0" end + end + + -- Portal will be placed so that the first registered exit is at requested location. + exit = mcl_portals.spawn_nether_portal(add(pos, vector.new(-1,-1,-1)), orientation, nil, name) + else + return false, "Invalid parameters. Pass either zero, three or four" + end + + if exit then + return true, "Spawned!" + else + return false, "Unable to spawn portal, area could be protected" + end + end, +}) + + -- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation local function stop_teleport_cooloff(o) cooloff[o] = nil @@ -429,195 +822,398 @@ local function finalize_teleport(obj, exit) end local _, dim = mcl_worlds.y_to_layer(exit.y) - local saved_portal = find_exit(get_portal_pos(objpos),10,10,10) - - if saved_portal then exit = saved_portal end - - -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} - if get_node(objpos).name ~= PORTAL then return end - - -- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 1 of 2 -- TODO: Remove -- - -- Old worlds have no exits indexed - adding the exit to return here: - add_exit(objpos) - -- TEMPORATY CODE SECTION ENDS HERE -- + if get_node(objpos).name ~= PORTAL then + log("action", "Entity no longer standing in portal") + return + end + -- In case something went wrong, make sure the origin portal is always added as a viable exit. + -- In the ideal case, this is not needed, as the exits are added upon ignition. Before Jan 2024 this + -- was broken, so there will be a lot of half-added portals out there! + add_exits({objpos}) -- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation teleport_cooloff(obj) - -- Teleport - save_portal_pos(objpos,exit) obj:set_pos(exit) - minetest.after(1,function() - save_portal_pos(exit,objpos) - end) + + local lua_entity = obj:get_luaentity() if is_player then mcl_worlds.dimension_change(obj, dim) minetest.sound_play("mcl_portals_teleport", {pos=exit, gain=0.5, max_hear_distance = 16}, true) - log("action", "[mcl_portals] player "..name.." teleported to Nether portal at "..pos_to_string(exit)..".") + log("action", "Player "..name.." teleported to portal at "..pos_to_string(exit)..".") if dim == "nether" then awards.unlock(obj:get_player_name(), "mcl:theNether") end - else - log("action", "[mcl_portals] entity teleported to Nether portal at "..pos_to_string(exit)..".") + elseif lua_entity then + log("verbose", string.format( + "Entity %s teleported to portal at %s", + lua_entity.name, + pos_to_string(exit) + )) end end -local function create_portal_2(pos1, name, obj) - local orientation = 0 - local pos2 = {x = pos1.x + 3, y = pos1.y + 3, z = pos1.z + 3} - local nodes = find_nodes_in_area(pos1, pos2, {"air"}) - if #nodes == 64 then - orientation = random(0,1) +local function is_origin_queued(origin) + local key = pos_to_string(origin) + if origin_queue[key] then + return true else - pos2.x = pos2.x - 1 - nodes = find_nodes_in_area(pos1, pos2, {"air"}) - if #nodes == 48 then - orientation = 1 + return false + end +end + +local function is_entity_queued() + for _, q in pairs(origin_queue) do + if q[obj] then + return true end end - local exit = build_nether_portal(pos1, W_MIN-2, H_MIN-2, orientation, name) - finalize_teleport(obj, exit) - local cn = mcl_vars.get_chunk_number(pos1) - chunks[cn] = nil - if queue[cn] then - for next_obj, _ in pairs(queue[cn]) do - if next_obj ~= obj then - finalize_teleport(next_obj, exit) + + return false +end + +local function origin_enqueue(obj, origin) + local key = pos_to_string(origin) + log("verbose", string.format("Queueing entity for origin %s", key)) + local q = origin_queue[key] or {} + if not q[obj] then + q[obj] = true + origin_queue[key] = q + end +end + +-- Flush the queue of entities waiting for specific origin. +-- Pass nil/false exit to purge the queue without teleporting. +local function origin_flush(origin, exit) + local key = pos_to_string(origin) + + local count_teleported = 0 + local count_removed = 0 + if origin_queue[key] then + for obj, value in pairs(origin_queue[key]) do + if value and exit then + finalize_teleport(obj, exit) + count_teleported = count_teleported + 1 + else + count_removed = count_removed + 1 end end - queue[cn] = nil + origin_queue[key] = nil end + log("verbose", string.format( + "Finished flushing entities waiting for origin %s: removed %d, proceeded to teleport %d", + key, + count_removed, + count_teleported + )) +end + +local function find_build_limits(pos, target_dim) + -- Find node extremes of the pos's chunk. + -- According to what people said in minetest discord and couple of docs, mapgen + -- works on entire chunks, so we need to limit the search to chunk boundary. + -- The goal is to emerge at most two chunks. + local chunk_limit1 = add( + mul( + mcl_vars.pos_to_chunk(pos), + mcl_vars.chunk_size_in_nodes + ), + vector.new( + mcl_vars.central_chunk_offset_in_nodes, + mcl_vars.central_chunk_offset_in_nodes, + mcl_vars.central_chunk_offset_in_nodes + ) + ) + local chunk_limit2 = add( + chunk_limit1, + vector.new( + mcl_vars.chunk_size_in_nodes - 1, + mcl_vars.chunk_size_in_nodes - 1, + mcl_vars.chunk_size_in_nodes - 1 + ) + ) + + -- Limit search area by using search distances. There is no Y build limit. + local build_limit1 = add( + pos, + -- minus 1 to account for the pos block being included. + -- plus 1 to account for the portal block offset (ignore frame) + vector.new(-BUILD_DISTANCE_XZ-1+1, 0, -BUILD_DISTANCE_XZ-1+1) + ) + local build_limit2 = add( + pos, + -- plus 1 to account for the portal block offset (ignore frame) + -- minus potential portal width, so that the generated portal doesn't "stick out" + vector.new(BUILD_DISTANCE_XZ+1-(W_MIN-1), 0, BUILD_DISTANCE_XZ+1-(W_MIN-1)) + ) + + -- Start with chunk limits + pos1 = vector.new(chunk_limit1.x, chunk_limit1.y, chunk_limit1.z) + pos2 = vector.new(chunk_limit2.x, chunk_limit2.y, chunk_limit2.z) + + -- Make sure the portal is not built beyond chunk boundary + -- (we will be searching for the node with lowest X, Y and Z) + pos2.x = pos2.x-(W_MIN-1) + pos2.y = pos2.y-(H_MIN-1) + pos2.z = pos2.z-(W_MIN-1) + -- Avoid negative volumes + if pos2.x < pos1.x then pos2.x = pos1.x end + if pos2.y < pos1.y then pos2.y = pos1.y end + if pos2.z < pos1.z then pos2.z = pos1.z end + + -- Apply build distances. + pos1 = { + x = max(pos1.x, build_limit1.x), + y = pos1.y, + z = max(pos1.z, build_limit1.z) + } + pos2 = { + x = min(pos2.x, build_limit2.x), + y = pos2.y, + z = min(pos2.z, build_limit2.z) + } + + -- Apply dimension-specific distances, so that player does not end up in void or in lava. + local limit1, limit2 = limits[target_dim].pmin, limits[target_dim].pmax + pos1 = { + x = max(pos1.x, limit1.x), + y = max(pos1.y, limit1.y), + z = max(pos1.z, limit1.z) + } + pos2 = { + x = min(pos2.x, limit2.x), + y = min(pos2.y, limit2.y), + z = min(pos2.z, limit2.z) + } + + local diff = add(pos2, mul(pos1, -1)) + local area = diff.x * diff.z + local msg = string.format( + "Portal build area between %s-%s, a %dx%dx%d cuboid with floor area of %d nodes. " + .."Chunk limit was at [%s,%s]. " + .."Ideal build area was at [(%d,*,%d),(%d,*,%d)].", + pos_to_string(pos1), + pos_to_string(pos2), + diff.x, + diff.y, + diff.z, + area, + pos_to_string(chunk_limit1), + pos_to_string(chunk_limit2), + build_limit1.x, + build_limit1.z, + build_limit2.x, + build_limit2.z + ) + log("verbose", msg) + + return pos1, pos2 end local function get_lava_level(pos, pos1, pos2) if pos.y > -1000 then - return max(min(mcl_vars.mg_lava_overworld_max, pos2.y-1), pos1.y+1) + return mcl_vars.mg_lava_overworld_max end - return max(min(mcl_vars.mg_lava_nether_max, pos2.y-1), pos1.y+1) + return mcl_vars.mg_lava_nether_max end -local function ecb_scan_area_2(blockpos, action, calls_remaining, param) +local function search_for_build_location(blockpos, action, calls_remaining, param) if calls_remaining and calls_remaining > 0 then return end - local pos, pos1, pos2, name, obj = param.pos, param.pos1, param.pos2, param.name or "", param.obj - local pos0, distance - local lava = get_lava_level(pos, pos1, pos2) - -- THIS IS A TEMPORATY CODE SECTION FOR COMPATIBILITY REASONS -- 2 of 2 -- TODO: Remove -- - -- Find portals for old worlds (new worlds keep them all in the table): + local target, pos1, pos2, name, obj = param.target, param.pos1, param.pos2, param.name or "", param.obj + local chunk = mcl_vars.get_chunk_number(target) + local pos0, distance + local most_airy_count, most_airy_pos, most_airy_distance = param.most_airy_count, param.most_airy_pos, param.most_airy_distance + local lava = get_lava_level(target, pos1, pos2) + + -- Portal might still exist in the area even though nothing was found in the table. + -- This could be due to bugs, or old worlds (portals added before the exits table). + -- Handle gracefully by searching and adding exits as appropriate. + local exit local portals = find_nodes_in_area(pos1, pos2, {PORTAL}) if portals and #portals>0 then for _, p in pairs(portals) do - add_exit(p) + -- This will only add legitimate exits that are not on the list, + -- and will only save if there was any changes. + add_exits({p}) end - local exit = find_exit(pos) - if exit then - finalize_teleport(obj, exit) + + if param.target_dim=="nether" then + exit = find_exit(target, SEARCH_DISTANCE_NETHER, SEARCH_DISTANCE_NETHER) + else + exit = find_exit(target, SEARCH_DISTANCE_OVERWORLD, SEARCH_DISTANCE_OVERWORLD) end + end + + if exit then + log("verbose", "Using a newly found exit at "..pos_to_string(exit)) + origin_flush(param.origin, exit) + chunk_building[chunk] = false return end - -- TEMPORATY CODE SECTION ENDS HERE -- + -- No suitable portal was found, look for a suitable space and build a new one in the emerged blocks. local nodes = find_nodes_in_area_under_air(pos1, pos2, {"group:building_block"}) + -- Sort by distance so that we are checking the nearest nodes first. + -- This can speed up the search considerably if there is space around the ideal X and Z. + table.sort(nodes, function(a,b) + local da = dist(param.ideal_target, add(a, vector.new(1,1,1))) + local db = dist(param.ideal_target, add(b, vector.new(1,1,1))) + return da 0 then for i=1,nc do local node = nodes[i] - local node1 = {x=node.x, y=node.y+1, z=node.z } - local node2 = {x=node.x+2, y=node.y+3, z=node.z+2} + local portal_node = add(node, vector.new(1,1,1)) -- Skip the frame + local node1 = add(node, vector.new(0,1,0)) -- Floor can be solid + local node2 = add(node, vector.new(W_MIN-1,H_MIN-1,W_MIN-1)) + local nodes2 = find_nodes_in_area(node1, node2, {"air"}) if nodes2 then local nc2 = #nodes2 - if nc2 == 27 and not is_area_protected(node, node2, name) then - local distance0 = dist(pos, node) - if distance0 < 2 then - log("action", "[mcl_portals] found space at pos "..pos_to_string(node).." - creating a portal") - create_portal_2(node1, name, obj) - return - end - if not distance or (distance0 < distance) or (distance0 < distance-1 and node.y > lava and pos0.y < lava) then - log("verbose", "[mcl_portals] found distance "..tostring(distance0).." at pos "..pos_to_string(node)) + + if not is_area_protected(node, node2, name) and node.y > lava then + local distance0 = dist(param.ideal_target, portal_node) + + if nc2 >= (W_MIN*(H_MIN-1)*W_MIN) - ACCEPTABLE_PORTAL_REPLACES then + -- We have sorted the candidates by distance, this is the best location. distance = distance0 - pos0 = {x=node1.x, y=node1.y, z=node1.z} + pos0 = {x=node.x, y=node.y, z=node.z} + log("verbose", "Found acceptable location at "..pos_to_string(pos0)..", distance "..distance0..", air nodes "..nc2) + break + elseif not most_airy_pos or nc2>most_airy_count then + -- Remember the cube with the most amount of air as a fallback. + most_airy_count = nc2 + most_airy_distance = distance0 + most_airy_pos = {x=node.x, y=node.y, z=node.z} + log("verbose", "Found fallback location at "..pos_to_string(most_airy_pos)..", distance "..distance0..", air nodes "..nc2) + elseif most_airy_pos and nc2==most_airy_count and distance0= pos1.x and p.x <= pos2.x and p.y >= pos1.y and p.y <= pos2.y and p.z >= pos1.z and p.z <= pos2.z then - log("action", "[mcl_portals] Making additional search in chunk below, because current one doesn't contain any air space for portal, target pos "..pos_to_string(p)) - minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = p, pos1 = pos1, pos2 = pos2, name=name, obj=obj}) + -- Look in chunks above or below, depending on which side has more + -- space. Since our Y map distance is quite short due to the flatness of + -- the non-lava nether, falling back like this should cover entire Y range. + if param.chunk_counter==1 then + if limits[param.target_dim].pmax.y-target.y > target.y-limits[param.target_dim].pmin.y then + -- Look up + direction = 1 + log("verbose", "No space found, emerging one chunk above") + else + -- Look down + direction = -1 + log("verbose", "No space found, emerging one chunk below") + end + + local new_target = {x=target.x, y=target.y + direction * mcl_vars.chunk_size_in_nodes, z=target.z} + pos1, pos2 = find_build_limits(new_target, param.target_dim) + local diff = add(pos2, mul(pos1, -1)) + + -- Only emerge if there is sufficient headroom to actually fit entire portal. + if diff.y+1>=H_MIN then + local new_chunk = mcl_vars.get_chunk_number(new_target) + if chunk_building[new_chunk] then + log("verbose", string.format("Secondary chunk %s is currently busy, backing off", new_chunk)) + origin_flush(param.origin, nil) + return + end + + chunk_building[new_chunk] = true + minetest.emerge_area(pos1, pos2, search_for_build_location, { + origin=param.origin, + target = new_target, + target_dim = target_dim, + ideal_target = param.ideal_target, + pos1 = pos1, + pos2 = pos2, + name=name, + obj=obj, + chunk_counter=param.chunk_counter+1, + most_airy_count=most_airy_count, + most_airy_pos=most_airy_pos, + most_airy_distance=most_airy_distance + }) + + chunk_building[chunk] = false return end end - log("action", "[mcl_portals] found no space, reverting to target pos "..pos_to_string(pos).." - creating a portal") - if pos.y < lava then - pos.y = lava + 1 - else - pos.y = pos.y + 1 + -- Fall back to the most airy position in previous chunk, in this chunk, + -- or if all else fails to ideal position. This could replace a lot of blocks. + local fallback = param.ideal_target + + if most_airy_pos then + log( + "verbose", + string.format( + "Falling back to the most airy position at %s, distance %d", + pos_to_string(most_airy_pos), + most_airy_distance + ) + ) + fallback = most_airy_pos end - create_portal_2(pos, name, obj) + + if fallback.y <= lava then + fallback.y = lava + 1 + end + + log("verbose", "Forcing portal at "..pos_to_string(fallback)..", lava at "..lava) + local exit = build_nether_portal(fallback, W_MIN, H_MIN, random(0,1), name, true) + origin_flush(param.origin, exit) + chunk_building[chunk] = false end -local function create_portal(pos, limit1, limit2, name, obj) - local cn = mcl_vars.get_chunk_number(pos) - if chunks[cn] then - local q = queue[cn] or {} - q[obj] = true - queue[cn] = q +local function create_portal(origin, target, target_dim, name, obj) + local chunk = mcl_vars.get_chunk_number(target) + if chunk_building[chunk] then + log("verbose", string.format("Primary chunk %s is currently busy, backing off", chunk)) + origin_flush(origin, nil) return end - chunks[cn] = true + chunk_building[chunk] = true - -- we need to emerge the area here, but currently (mt5.4/mcl20.71) map generation is slow - -- so we'll emerge single chunk only: 5x5x5 blocks, 80x80x80 nodes maximum - -- and maybe one more chunk from below if (SCAN_2_MAP_CHUNKS = true) - - local pos1 = add(mul(mcl_vars.pos_to_chunk(pos), mcl_vars.chunk_size_in_nodes), mcl_vars.central_chunk_offset_in_nodes) - local pos2 = add(pos1, mcl_vars.chunk_size_in_nodes - 1) - - if not SCAN_2_MAP_CHUNKS then - if limit1 and limit1.x and limit1.y and limit1.z then - pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} - end - if limit2 and limit2.x and limit2.y and limit2.z then - pos2 = {x = min(max(limit2.x, pos.x), pos2.x), y = min(max(limit2.y, pos.y), pos2.y), z = min(max(limit2.z, pos.z), pos2.z)} - end - minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj}) - return - end - - -- Basically the copy of code above, with minor additions to continue the search in single additional chunk below: - local next_chunk_1 = {x = pos1.x, y = pos1.y - mcl_vars.chunk_size_in_nodes, z = pos1.z} - local next_chunk_2 = add(next_chunk_1, mcl_vars.chunk_size_in_nodes - 1) - local next_pos = {x = pos.x, y=max(next_chunk_2.y, limit1.y), z = pos.z} - if limit1 and limit1.x and limit1.y and limit1.z then - pos1 = {x = max(min(limit1.x, pos.x), pos1.x), y = max(min(limit1.y, pos.y), pos1.y), z = max(min(limit1.z, pos.z), pos1.z)} - next_chunk_1 = {x = max(min(limit1.x, next_pos.x), next_chunk_1.x), y = max(min(limit1.y, next_pos.y), next_chunk_1.y), z = max(min(limit1.z, next_pos.z), next_chunk_1.z)} - end - if limit2 and limit2.x and limit2.y and limit2.z then - pos2 = {x = min(max(limit2.x, pos.x), pos2.x), y = min(max(limit2.y, pos.y), pos2.y), z = min(max(limit2.z, pos.z), pos2.z)} - next_chunk_2 = {x = min(max(limit2.x, next_pos.x), next_chunk_2.x), y = min(max(limit2.y, next_pos.y), next_chunk_2.y), z = min(max(limit2.z, next_pos.z), next_chunk_2.z)} - end - minetest.emerge_area(pos1, pos2, ecb_scan_area_2, {pos = vector.new(pos), pos1 = pos1, pos2 = pos2, name=name, obj=obj, next_chunk_1 = next_chunk_1, next_chunk_2 = next_chunk_2, next_pos = next_pos}) + local pos1, pos2 = find_build_limits(target, target_dim) + minetest.emerge_area(pos1, pos2, search_for_build_location, { + origin = origin, + target = target, + target_dim = target_dim, + ideal_target = vector.new(target.x, target.y, target.z), -- copy + pos1 = pos1, + pos2 = pos2, + name=name, + obj=obj, + chunk_counter=1 + }) end local function available_for_nether_portal(p) + -- No need to check for protected - non-owner can't ignite blocks anyway. + local nn = get_node(p).name local obsidian = nn == OBSIDIAN if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then @@ -681,11 +1277,23 @@ local function check_and_light_shape(pos, orientation) return false end + -- Light the portal for i = 1, node_counter do - local node_pos = node_list[i] - minetest.set_node(node_pos, {name = PORTAL, param2 = orientation}) - add_exit(node_pos) + minetest.set_node(node_list[i], {name = PORTAL, param2 = orientation}) end + + -- Register valid portal exits (each portal has at least two!) + -- Before Jan 2024, there was a bug that did not register all exits upon ignition. + -- This means portals lit before that time will only become live as people use them + -- (and only specific portal blocks). + for i = 1, node_counter do + -- Improvement possible: we are only interested in the bottom + -- blocks as exits, but here all ignited blocks are passed in. + -- This can cause a lot of failed validations on very large + -- portals that we know can be skipped. + add_exits({node_list[i]}) + end + return true end @@ -695,11 +1303,22 @@ end -- If no Nether portal can be lit, nothing happens. -- Returns true if portal created function mcl_portals.light_nether_portal(pos) + -- Only allow to make portals in Overworld and Nether local dim = mcl_worlds.pos_to_dimension(pos) if dim ~= "overworld" and dim ~= "nether" then return false end + + if not get_target(pos) then + -- Prevent ignition of portals that would lead to out of bounds positions. + log("verbose", string.format( + "No target found for position %s - portal would lead to invalid exit", + pos_to_string(pos) + )) + return + end + local orientation = random(0, 1) for orientation_iteration = 1, 2 do if check_and_light_shape(pos, orientation) then @@ -710,33 +1329,103 @@ function mcl_portals.light_nether_portal(pos) return false end +local function check_portal_then_teleport(obj, origin, exit) + -- Check we are not sending the player on a one-way trip. + minetest.emerge_area(exit, exit, function (blockpos, action, calls_remaining, param) + if calls_remaining and calls_remaining > 0 then return end + + if get_node(exit).name ~= PORTAL then + -- Bogus exit! Break the teleportation so we don't strand the player. + -- The process will begin again after cooloff through the ABM, and might either + -- find another exit, or build a new portal. This will manifest to the + -- player as a teleportation that takes longer than usual. + log("warning", "removing bogus portal exit encountered at "..pos_to_string(exit)..", exit no longer exists") + + remove_exits({exit}) + -- Also remove from structure storage, otherwise ABM will try the same bad exit again. + local objpos = obj:get_pos() + delete_portal_pos({x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)}) + + origin_flush(origin, nil) + return + end + + origin_flush(origin, exit) + end) +end + + -- Teleport function -local function teleport_no_delay(obj, pos) +local function teleport_no_delay(obj, portal_pos) local is_player = obj:is_player() if (not is_player and not obj:get_luaentity()) or cooloff[obj] then return end local objpos = obj:get_pos() if not objpos then return end - -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y - objpos = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} - if get_node(objpos).name ~= PORTAL then return end + local _, current_dim = mcl_worlds.y_to_layer(objpos.y) + local target_dim = dimension_to_teleport[current_dim] - local target, dim = get_target(objpos) - if not target then return end + -- If player stands, player is at ca. something+0.5 which might cause precision problems, so we used ceil for objpos.y + origin = {x = floor(objpos.x+0.5), y = ceil(objpos.y), z = floor(objpos.z+0.5)} + if get_node(origin).name ~= PORTAL then return end + + local target = get_target(origin) + if not target then + log("verbose", string.format( + "No target found for position %s - no valid exit found", + pos_to_string(origin) + )) + return + end local name if is_player then name = obj:get_player_name() end - local exit = find_exit(target) + if is_entity_queued(obj) then + -- Let's not allow one entity to generate a lot of work by just moving around in a portal. + log("verbose", "Entity already queued") + return + end + + log("verbose", string.format("Target calculated as %s", pos_to_string(target))) + + local already_queued = is_origin_queued(origin) + origin_enqueue(obj, origin) + + if already_queued then + -- Origin is already being processed, so wait in queue for the result. + log("verbose", string.format("Origin %s already queued", pos_to_string(origin))) + return + end + + local exit + local saved_portal_position = get_portal_pos(origin) + if saved_portal_position then + -- Before Jan 2024, portal exits were sticky - they were stored + -- in nodes. If such a position is found, look for the exit + -- there, so that the players don't get any surprises. + -- Sticky exit can be removed by destroying and rebuilding the portal. + log("verbose", "Using block-saved portal exit: "..pos_to_string(saved_portal_position)..".") + exit = find_exit(saved_portal_position, 10, 10) + end + + if not exit then + -- Search for nearest suitable exit in the lookup table. + if target_dim=="nether" then + exit = find_exit(target, SEARCH_DISTANCE_NETHER, SEARCH_DISTANCE_NETHER) + else + exit = find_exit(target, SEARCH_DISTANCE_OVERWORLD, SEARCH_DISTANCE_OVERWORLD) + end + end + if exit then - finalize_teleport(obj, exit) + log("verbose", "Exit found at "..pos_to_string(exit).." for target "..pos_to_string(target).." traveling from "..pos_to_string(origin)) + check_portal_then_teleport(obj, origin, exit) else - dim = dimension_to_teleport[dim] - -- need to create arrival portal - create_portal(target, limits[dim].pmin, limits[dim].pmax, name, obj) + create_portal(origin, target, target_dim, name, obj) end end @@ -846,8 +1535,9 @@ minetest.register_abm({ }) end end - for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel - local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do + -- Teleport players, mobs, boats etc. + local lua_entity = obj:get_luaentity() if (obj:is_player() or lua_entity) and prevent_portal_chatter(obj) then teleport(obj, pos) end @@ -865,7 +1555,9 @@ local usagehelp = S("To open a Nether portal, place an upright frame of obsidian minetest.override_item(OBSIDIAN, { _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - after_destruct = function(pos, node) + on_destruct = function(pos, node) + -- Permit extinguishing of protected portals if the frame is + -- sticking out of the protected area to maintain integrity. local function check_remove(pos, orientation) local node = get_node(pos) if node and node.name == PORTAL then @@ -884,13 +1576,14 @@ minetest.override_item(OBSIDIAN, { _on_ignite = function(user, pointed_thing) local x, y, z = pointed_thing.under.x, pointed_thing.under.y, pointed_thing.under.z - -- Check empty spaces around obsidian and light all frames found: + -- Check empty spaces around obsidian and light all frames found. + -- Permit igniting of portals that are partly protected to maintain integrity. local portals_placed = mcl_portals.light_nether_portal({x = x - 1, y = y, z = z}) or mcl_portals.light_nether_portal({x = x + 1, y = y, z = z}) or mcl_portals.light_nether_portal({x = x, y = y - 1, z = z}) or mcl_portals.light_nether_portal({x = x, y = y + 1, z = z}) or mcl_portals.light_nether_portal({x = x, y = y, z = z - 1}) or mcl_portals.light_nether_portal({x = x, y = y, z = z + 1}) if portals_placed then - log("action", "[mcl_portals] Nether portal activated at "..pos_to_string({x=x,y=y,z=z})..".") + log("verbose", "Nether portal activated at "..pos_to_string({x=x,y=y,z=z})..".") if minetest.get_modpath("doc") then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", PORTAL) @@ -911,13 +1604,21 @@ mcl_structures.register_structure("nether_portal",{ nospawn = true, filenames = { modpath.."/schematics/mcl_portals_nether_portal.mts" - }, - after_place = function(pos,def,pr,blockseed) - end + } }) mcl_structures.register_structure("nether_portal_open",{ nospawn = true, filenames = { modpath.."/schematics/mcl_portals_nether_portal_open.mts" }, + after_place = function(pos,def,pr,blockseed) + -- The mts is the smallest portal (two wide) and places the first PORTAL block + -- above the location of the caller (y+1). The second one is either at x+1 or z+1. + local portals = find_nodes_in_area(add(pos, vector.new(0,1,0)), add(pos, vector.new(1,1,1)), {PORTAL}) + if portals and #portals>0 then + for _, p in pairs(portals) do + add_exits({p}) + end + end + end }) diff --git a/mods/ITEMS/mcl_potions/API.md b/mods/ITEMS/mcl_potions/API.md new file mode 100644 index 000000000..2bcef0c71 --- /dev/null +++ b/mods/ITEMS/mcl_potions/API.md @@ -0,0 +1,346 @@ +## Potions and Effects API + + +* [Potions and Effects API](#potions-and-effects-api) + * [Namespace](#namespace) + * [Effects](#effects) + * [Functions](#functions) + * [Deprecated Functions](#deprecated-functions) + * [Tables](#tables) + * [Internally registered effects](#internally-registered-effects) + * [Constants](#constants) + * [Effect Definition](#effect-definition) + * [HP Hudbar Modifiers](#hp-hudbar-modifiers) + * [Functions](#functions) + * [HP Hudbar Modifier Definition](#hp-hudbar-modifier-definition) + * [Potions](#potions) + * [Functions](#functions) + * [Tables](#tables) + * [Internally registered potions](#internally-registered-potions) + * [Constants](#constants) + * [Potion Definition](#potion-definition) + * [Brewing](#brewing) + * [Functions](#functions) + * [Miscellaneous Functions](#miscellaneous-functions) + + +### Namespace +All of the API is defined in the `mcl_potions` namespace. + +### Effects +This section describes parts of the API related to defining and managing effects on players and entities. The mod defines a bunch of effects internally using the same API as described below. + +#### Functions +`mcl_potions.register_effect(def)` – takes an effect definition (`def`) and registers an effect if the definition is valid, and adds the known parts of the definition as well as the outcomes of processing of some parts of the definition to the `mcl_potions.registered_effects` table. This should only be used at load time. + + +`mcl_potions.apply_haste_fatigue(toolcaps, h_fac, f_fac)` – takes a table of tool capabilities (`toolcaps`) and modifies it using the provided haste factor (`h_fac`) and fatigue factor (`f_fac`). The factors default to no-op values. + + +`mcl_potions.hf_update_internal(hand, object)` – returns the `hand` of the `object` updated according to their combined haste and fatigue. **This doesn't change anything by itself!** Manual update of the hand with the hand returned by this function has to be done. This should only be called in situations that are *directly* impacted by haste and/or fatigue, and therefore require an update of the hand. + + +`mcl_potions.update_haste_and_fatigue(player)` – updates haste and fatigue on a `player` (described by an ObjectRef). This should be called whenever an update of the haste-type and fatigue-type effects is desired. + + +`mcl_potions._reset_haste_fatigue_item_meta(player)` – resets the item meta changes caused by haste-type and fatigue-type effects throughout the inventory of the `player` described by an ObjectRef. + + +`mcl_potions._clear_cached_effect_data(object)` – clears cashed effect data for the `object`. This shouldn't be used for resetting effects. + + +`mcl_potions._reset_effects(object, set_hud)` – actually resets the effects for the `object`. It also updates HUD if `set_hud` is `true` or undefined (`nil`). + + +`mcl_potions._save_player_effects(player)` – saves all effects of the `player` described by an ObjectRef to metadata. + + +`mcl_potions._load_player_effects(player)` – loads all effects from the metadata of the `player` described by an ObjectRef. + + +`mcl_potions._load_entity_effects(entity)` – loads all effects from the `entity` (a LuaEntity). + + +`mcl_potions.has_effect(object, effect_name)` – returns `true` if `object` (described by an ObjectRef) has the effect of the ID `effect_name`, `false` otherwise. + + +`mcl_potions.get_effect(object, effect_name)` - returns a table containing values of the effect of the ID `effect_name` on the `object` if the object has the named effect, `false` otherwise. + +* table returned by the above function is like this: +```lua + effect = { + dur = float -- duration of the effect in seconds, may be infinite + timer = float -- how much of the duration (in seconds) has already elapsed + no_particles = bool -- if this is true, no particles signifying this effect will appear + + -- player-only fields + hud_index = int -- position in the HUD used by this effect (icon, level, timer) - probably meaningless outside mcl_potions + + -- optional fields + factor = float -- power of the effect if the effect uses factor; this may mean different things depending on the effect + step = float -- how often (in seconds) the on_step() function of the effect is executed, if it exists + hit_timer = float -- how much of the step (in seconds) has already elapsed + + -- effect-specific fields + -- effects in mcl_potions have their own fields here, for now external effects can't add any here + blocked = bool -- used by conduit power + high = bool -- used by nausea + vignette = int -- handle to the HUD vignette of the effect, used by effects that use one + absorb = float -- "HP" of the absorption effect + waypoints = table -- used by glowing, indexed by player ObjectRef, contains HUD handles for the glowing waypoints + flash = float -- used by darkness, denotes vision range modifier + flashdir = bool -- used by darkness, denotes whether vision range is increasing (or decreasing) + } +``` + + +`mcl_potions.get_effect_level(object, effect_name)` – returns the level of the effect of the ID `effect_name` on the `object`. If the effect has no levels, returns `1`. If the object doesn't have the effect, returns `0`. If the effect is not registered, returns `nil`. + + +`mcl_potions.get_total_haste(object)` – returns the total haste of the `object` (from all haste-type effects). + + +`mcl_potions.get_total_fatigue(object)` – returns the total fatigue of the `object` (from all fatigue-type effects). + + +`mcl_potions.clear_effect(object, effect)` – attempts to remove the effect of the ID `effect` from the `object`. If the effect is not registered, logs a warning and returns `false`. Otherwise, returns `nil`. + + +`mcl_potions.make_invisible(obj_ref, hide)` – makes the object going by the `obj_ref` invisible if `hide` is true, visible otherwise. + + +`mcl_potions.register_generic_resistance_predicate(predicate)` – registers an arbitrary effect resistance predicate. This can be used e.g. to make some entity resistant to all (or some) effects under specific conditions. + +* `predicate` – `function(object, effect_name)` - return `true` if `object` resists effect of the ID `effect_name` + + +`mcl_potions.give_effect(name, object, factor, duration, no_particles)` – attempts to give effect of the ID `name` to the `object` with the provided `factor` and `duration`. If `no_particles` is `true`, no particles will be emitted from the object when under the effect. If the effect is not registered, target is invalid (or resistant), or the same effect with more potency is already applied to the target, this function does nothing and returns `false`. On success, this returns `true`. + + +`mcl_potions.give_effect_by_level(name, object, level, duration, no_particles)` – attempts to give effect of the ID `name` to the `object` with the provided `level` and `duration`. If `no_particles` is `true`, no particles will be emitted from the object when under the effect. This converts `level` to factor and calls `mcl_potions.give_effect()` internally, returning the return value of that function. `level` equal to `0` is no-op. + + +`mcl_potions.healing_func(object, hp)` – attempts to heal the `object` by `hp`. Negative `hp` harms magically instead. + + +#### Deprecated functions +**Don't use the following functions, use the above API instead!** The following are only provided for backwards compatibility and will be removed later. They all call `mcl_potions.give_effect()` internally. + +* `mcl_potions.strength_func(object, factor, duration)` +* `mcl_potions.leaping_func(object, factor, duration)` +* `mcl_potions.weakness_func(object, factor, duration)` +* `mcl_potions.swiftness_func(object, factor, duration)` +* `mcl_potions.slowness_func(object, factor, duration)` +* `mcl_potions.withering_func(object, factor, duration)` +* `mcl_potions.poison_func(object, factor, duration)` +* `mcl_potions.regeneration_func(object, factor, duration)` +* `mcl_potions.invisiblility_func(object, null, duration)` +* `mcl_potions.water_breathing_func(object, null, duration)` +* `mcl_potions.fire_resistance_func(object, null, duration)` +* `mcl_potions.night_vision_func(object, null, duration)` +* `mcl_potions.bad_omen_func(object, factor, duration)` + + + +#### Tables +`mcl_potions.registered_effects` – contains all effects that have been registered. You can read from it various data about the effects. You can overwrite the data and alter the effects' definitions too, but this is discouraged, i.e. only do this if you really know what you are doing. You shouldn't add effects directly to this table, as this would skip important setup; instead use the `mcl_potions.register_effect()` function, which is described above. + +#### Internally registered effects +You can't register effects going by these names, because they are already used: + +* `invisibility` +* `poison` +* `regeneration` +* `strength` +* `weakness` +* `weakness` +* `dolphin_grace` +* `leaping` +* `slow_falling` +* `swiftness` +* `slowness` +* `levitation` +* `night_vision` +* `darkness` +* `glowing` +* `health_boost` +* `absorption` +* `fire_resistance` +* `resistance` +* `luck` +* `bad_luck` +* `bad_omen` +* `hero_of_village` +* `withering` +* `frost` +* `blindness` +* `nausea` +* `food_poisoning` +* `saturation` +* `haste` +* `fatigue` +* `conduit_power` + +#### Constants +`mcl_potions.LONGEST_MINING_TIME` – longest mining time of one block that can be achieved by slowing down the mining by fatigue-type effects. + +`mcl_potions.LONGEST_PUNCH_INTERVAL` – longest punch interval that can be achieved by slowing down the punching by fatigue-type effects. + +#### Effect Definition +```lua +def = { +-- required parameters in def: + name = string -- effect name in code (unique ID) - can't be one of the reserved words ("list", "heal", "remove", "clear") + description = S(string) -- actual effect name in game +-- optional parameters in def: + get_tt = function(factor) -- returns tooltip description text for use with potions + icon = string -- file name of the effect icon in HUD - defaults to one based on name + res_condition = function(object) -- returning true if target is to be resistant to the effect + on_start = function(object, factor) -- called when dealing the effect + on_load = function(object, factor) -- called on_joinplayer and on_activate + on_step = function(dtime, object, factor, duration) -- running every step for all objects with this effect + on_hit_timer = function(object, factor, duration) -- if defined runs a hit_timer depending on timer_uses_factor value + on_end = function(object) -- called when the effect wears off + after_end = function(object) -- called when the effect wears off, after purging the data of the effect + on_save_effect = function(object -- called when the effect is to be serialized for saving (supposed to do cleanup) + particle_color = string -- colorstring for particles - defaults to #3000EE + uses_factor = bool -- whether factor affects the effect + lvl1_factor = number -- factor for lvl1 effect - defaults to 1 if uses_factor + lvl2_factor = number -- factor for lvl2 effect - defaults to 2 if uses_factor + timer_uses_factor = bool -- whether hit_timer uses factor (uses_factor must be true) or a constant value (hit_timer_step must be defined) + hit_timer_step = float -- interval between hit_timer hits + damage_modifier = string -- damage flag of which damage is changed as defined by modifier_func, pass empty string for all damage + dmg_mod_is_type = bool -- damage_modifier string is used as type instead of flag of damage, defaults to false + modifier_func = function(damage, effect_vals) -- see damage_modifier, if not defined damage_modifier defaults to 100% resistance + modifier_priority = integer -- priority passed when registering damage_modifier - defaults to -50 + affects_item_speed = table +-- -- if provided, effect gets added to the item_speed_effects table, this should be true if the effect affects item speeds, +-- -- otherwise it won't work properly with other such effects (like haste and fatigue) +-- -- -- factor_is_positive - bool - whether values of factor between 0 and 1 should be considered +factor% or speed multiplier +-- -- -- - obviously +factor% is positive and speed multiplier is negative interpretation +-- -- -- - values of factor higher than 1 will have a positive effect regardless +-- -- -- - values of factor lower than 0 will have a negative effect regardless +} +``` + +### HP Hudbar Modifiers +This part of the API allows complex modification of the HP hudbar. It is mainly required here, so it is defined here. It may be moved to a different mod in the future. + +#### Functions +`mcl_potions.register_hp_hudbar_modifier(def)` – this function takes a modifier definition (`def`, described below) and registers a HP hudbar modifier if the definition is valid. + +#### HP Hudbar Modifier Definition +```lua +def = { +-- required parameters in def: + predicate = function(player) -- returns true if player fulfills the requirements (eg. has the effects) for the hudbar look + icon = string -- name of the icon to which the modifier should change the HP hudbar heart + priority = signed_int -- lower gets checked first, and first fulfilled predicate applies its modifier +} +``` + +### Potions +Magic! + +#### Functions +`mcl_potions.register_potion(def)` – takes a potion definition (`def`) and registers a potion if the definition is valid, and adds the known parts of the definition as well as the outcomes of processing of some parts of the definition to the `mcl_potions.registered_effects` table. This, depending on some fields of the definition, may as well register the corresponding splash potion, lingering potion and tipped arrow. This should only be used at load time. + +`mcl_potions.register_splash(name, descr, color, def)` – registers a splash potion (item and entity when thrown). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`. + +`mcl_potions.register_lingering(name, descr, color, def)` – registers a lingering potion (item and entity when thrown). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`. + +`mcl_potions.register_arrow(name, desc, color, def)` – registers a tipped arrow (item and entity when shot). This is mostly part of the internal API and probably shouldn't be used from outside, therefore not providing exact description. This is used by `mcl_potions.register_potion()`. + +#### Tables +`mcl_potions.registered_potions` – contains all potions that have been registered. You can read from it various data about the potions. You can overwrite the data and alter the definitions too, but this is discouraged, i.e. only do this if you really know what you are doing. You shouldn't add potions directly to this table, because they have to be registered as items too; instead use the `mcl_potions.register_potion()` function, which is described above. Some brewing recipes are autofilled based on this table after the loading of all the mods is done. + +#### Constants +* `mcl_potions.POTENT_FACTOR = 2` +* `mcl_potions.PLUS_FACTOR = 8/3` +* `mcl_potions.INV_FACTOR = 0.50` +* `mcl_potions.DURATION = 180` +* `mcl_potions.DURATION_INV = mcl_potions.DURATION * mcl_potions.INV_FACTOR` +* `mcl_potions.DURATION_POISON = 45` +* `mcl_potions.II_FACTOR = mcl_potions.POTENT_FACTOR` – **DEPRECATED** +* `mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR` – **DEPRECATED** +* `mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR` – **DEPRECATED** +* `mcl_potions.SPLASH_FACTOR = 0.75` +* `mcl_potions.LINGERING_FACTOR = 0.25` + +#### Potion Definition +```lua +def = { +-- required parameters in def: + name = string, -- potion name in code +-- optional parameters in def: + desc_prefix = S(string), -- part of visible potion name, comes before the word "Potion" + desc_suffix = S(string), -- part of visible potion name, comes after the word "Potion" + _tt = S(string), -- custom tooltip text + _dynamic_tt = function(level), -- returns custom tooltip text dependent on potion level + _longdesc = S(string), -- text for in=game documentation + stack_max = int, -- max stack size - defaults to 1 + image = string, -- name of a custom texture of the potion icon + color = string, -- colorstring for potion icon when image is not defined - defaults to #0000FF + groups = table, -- item groups definition for the regular potion, not splash or lingering - +-- - must contain _mcl_potion=1 for tooltip to include dynamic_tt and effects +-- - defaults to {brewitem=1, food=3, can_eat_when_full=1, _mcl_potion=1} + nocreative = bool, -- adds a not_in_creative_inventory=1 group - defaults to false + _effect_list = {, -- all the effects dealt by the potion in the format of tables +-- -- the name of each sub-table should be a name of a registered effect, and fields can be the following: + uses_level = bool, -- whether the level of the potion affects the level of the effect - +-- -- -- - defaults to the uses_factor field of the effect definition + level = int, -- used as the effect level if uses_level is false and for lvl1 potions - defaults to 1 + level_scaling = int, -- used as the number of effect levels added per potion level - defaults to 1 - +-- -- -- - this has no effect if uses_level is false + dur = float, -- duration of the effect in seconds - defaults to mcl_potions.DURATION + dur_variable = bool, -- whether variants of the potion should have the length of this effect changed - +-- -- -- - defaults to true +-- -- -- - if at least one effect has this set to true, the potion has a "plus" variant + effect_stacks = bool, -- whether the effect stacks - defaults to false + } + uses_level = bool, -- whether the potion should come at different levels - +-- - defaults to true if uses_level is true for at least one effect, else false + drinkable = bool, -- defaults to true + has_splash = bool, -- defaults to true + has_lingering = bool, -- defaults to true + has_arrow = bool, -- defaults to false + has_potent = bool, -- whether there is a potent (e.g. II) variant - defaults to the value of uses_level + default_potent_level = int, -- potion level used for the default potent variant - defaults to 2 + default_extend_level = int, -- extention level (amount of +) used for the default extended variant - defaults to 1 + custom_on_use = function(user, level), -- called when the potion is drunk, returns true on success + custom_effect = function(object, level, plus), -- called when the potion effects are applied, returns true on success + custom_splash_effect = function(pos, level), -- called when the splash potion explodes, returns true on success + custom_linger_effect = function(pos, radius, level), -- called on the lingering potion step, returns true on success +} +``` + +### Brewing +Functions supporting brewing potions, used by the `mcl_brewing` module, which calls `mcl_potions.get_alchemy()`. + +#### Functions +`mcl_potions.register_ingredient_potion(input, out_table)` – registers a potion (`input`, item string) that can be combined with multiple ingredients for different outcomes; `out_table` contains the recipes for those outcomes + +`mcl_potions.register_water_brew(ingr, potion)` – registers a `potion` (item string) brewed from water with a specific ingredient (`ingr`) + +`mcl_potions.register_awkward_brew(ingr, potion)` – registers a `potion` (item string) brewed from an awkward potion with a specific ingredient (`ingr`) + +`mcl_potions.register_mundane_brew(ingr, potion)` – registers a `potion` (item string) brewed from a mundane potion with a specific ingredient (`ingr`) + +`mcl_potions.register_thick_brew(ingr, potion)` – registers a `potion` (item string) brewed from a thick potion with a specific ingredient (`ingr`) + +`mcl_potions.register_table_modifier(ingr, modifier)` – registers a brewing recipe altering the potion using a table; this is supposed to substitute one item with another + +`mcl_potions.register_inversion_recipe(input, output)` – what it says + +`mcl_potions.register_meta_modifier(ingr, mod_func)` – registers a brewing recipe altering the potion using a function; this is supposed to be a recipe that changes metadata only + +`mcl_potions.get_alchemy(ingr, pot)` – finds an alchemical recipe for given ingredient and potion; returns outcome + +### Miscellaneous Functions +`mcl_potions._extinguish_nearby_fire(pos, radius)` – attempts to extinguish fires in an area, both on objects and nodes. + +`mcl_potions._add_spawner(obj, color)` – adds a particle spawner denoting an effect being in action. + +`mcl_potions._use_potion(obj, color)` – visual and sound effects of drinking a potion. + +`mcl_potions.is_obj_hit(self, pos)` – determines if an object is hit (by a thrown potion). diff --git a/mods/ITEMS/mcl_potions/README.txt b/mods/ITEMS/mcl_potions/README.txt index 7ebe4ba6c..0bc98bcff 100644 --- a/mods/ITEMS/mcl_potions/README.txt +++ b/mods/ITEMS/mcl_potions/README.txt @@ -1,5 +1,5 @@ License information: * Code: MIT License -* Textures: See main MineClone 2 README.md file +* Textures: See main VoxeLibre README.md file * Sounds: CC0 diff --git a/mods/ITEMS/mcl_potions/commands.lua b/mods/ITEMS/mcl_potions/commands.lua index 76ac71e72..1c2cd7347 100644 --- a/mods/ITEMS/mcl_potions/commands.lua +++ b/mods/ITEMS/mcl_potions/commands.lua @@ -8,22 +8,9 @@ local S = minetest.get_translator(minetest.get_current_modname()) -- ░╚════╝░╚═╝░░╚═╝╚═╝░░╚═╝░░░╚═╝░░░  ░╚════╝░░╚════╝░╚═╝░░░░░╚═╝╚═╝░░░░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝╚═════╝░╚═════╝░ -local get_chat_function = {} - -get_chat_function["poison"] = mcl_potions.poison_func -get_chat_function["regeneration"] = mcl_potions.regeneration_func -get_chat_function["invisibility"] = mcl_potions.invisiblility_func -get_chat_function["fire_resistance"] = mcl_potions.fire_resistance_func -get_chat_function["night_vision"] = mcl_potions.night_vision_func -get_chat_function["water_breathing"] = mcl_potions.water_breathing_func -get_chat_function["leaping"] = mcl_potions.leaping_func -get_chat_function["swiftness"] = mcl_potions.swiftness_func -get_chat_function["heal"] = mcl_potions.healing_func -get_chat_function["bad_omen"] = mcl_potions.bad_omen_func - minetest.register_chatcommand("effect",{ - params = S(" []"), - description = S("Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 = 100%)"), + params = S("|heal|list|clear|remove |INF [] [] [NOPART]"), + description = S("Add a status effect to yourself. Arguments: : name of status effect. Passing \"list\" as effect name lists available effects. Passing \"heal\" as effect name heals (or harms) by amount designed by the next parameter. Passing \"clear\" as effect name removes all effects. Passing \"remove\" as effect name removes the effect named by the next parameter. : duration in seconds. Passing \"INF\" as duration makes the effect infinite. (: amount of healing when the effect is \"heal\", passing a negative value subtracts health. : name of a status effect to be removed when using \"remove\" as the previous parameter.) : effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. : effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect."), privs = {server = true}, func = function(name, params) @@ -36,22 +23,93 @@ minetest.register_chatcommand("effect",{ if not P[1] then return false, S("Missing effect parameter!") - elseif not tonumber(P[2]) then + elseif P[1] == "list" then + local effects = "heal" + for effect, _ in pairs(mcl_potions.registered_effects) do + effects = effects .. ", " .. effect + end + return true, effects + elseif P[1] == "heal" then + local hp = tonumber(P[2]) + if not hp or hp == 0 then + return false, S("Missing or invalid heal amount parameter!") + else + mcl_potions.healing_func(minetest.get_player_by_name(name), hp) + if hp > 0 then + if hp < 1 then hp = 1 end + return true, S("Player @1 healed by @2 HP.", name, hp) + else + if hp > -1 then hp = -1 end + return true, S("Player @1 harmed by @2 HP.", name, hp) + end + end + elseif P[1] == "clear" then + mcl_potions._reset_effects(minetest.get_player_by_name(name)) + return true, S("Effects cleared for player @1", name) + elseif P[1] == "remove" then + if not P[2] then + return false, S("Missing effect parameter!") + end + if mcl_potions.registered_effects[P[2]] then + mcl_potions.clear_effect(minetest.get_player_by_name(name), P[2]) + return true, S("Removed effect @1 from player @2", P[2], name) + else + return false, S("@1 is not an available status effect.", P[2]) + end + elseif not tonumber(P[2]) and P[2] ~= "INF" then return false, S("Missing or invalid duration parameter!") - elseif P[3] and not tonumber(P[3]) then - return false, S("Invalid factor parameter!") - end - -- Default factor = 1 - if not P[3] then - P[3] = 1.0 + elseif P[3] and not tonumber(P[3]) and P[3] ~= "F" and P[3] ~= "NOPART" then + return false, S("Invalid level parameter!") + elseif P[3] and P[3] == "F" and not P[4] then + return false, S("Missing or invalid factor parameter when level is F!") end - if get_chat_function[P[1]] then - get_chat_function[P[1]](minetest.get_player_by_name(name), tonumber(P[3]), tonumber(P[2])) - return true + -- Default level = 1 + if not P[3] then + P[3] = 1 + elseif P[3] == "NOPART" then + P[3] = 1 + P[4] = "NOPART" + end + + local inf = P[2] == "INF" + + local nopart = false + if P[3] == "F" then + nopart = P[5] == "NOPART" + else + nopart = P[4] == "NOPART" + end + + local def = mcl_potions.registered_effects[P[1]] + if def then + if P[3] == "F" then + local given = mcl_potions.give_effect(P[1], minetest.get_player_by_name(name), tonumber(P[4]), inf and "INF" or tonumber(P[2]), nopart) + if given then + if def.uses_factor then + return true, S("@1 effect given to player @2 for @3 seconds with factor of @4.", def.description, name, P[2], P[4]) + else + return true, S("@1 effect given to player @2 for @3 seconds.", def.description, name, P[2]) + end + else + return false, S("Giving effect @1 to player @2 failed.", def.description, name) + end + else + local given = mcl_potions.give_effect_by_level(P[1], minetest.get_player_by_name(name), tonumber(P[3]), inf and "INF" or tonumber(P[2]), nopart) + if given then + if def.uses_factor then + return true, S("@1 effect on level @2 given to player @3 for @4 seconds.", def.description, P[3], name, P[2]) + else + return true, S("@1 effect given to player @2 for @3 seconds.", def.description, name, P[2]) + end + else + return false, S("Giving effect @1 to player @2 failed.", def.description, name) + end + end else return false, S("@1 is not an available status effect.", P[1]) end end, }) + diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index de3f6df10..a1c838814 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -1,43 +1,1233 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + local EF = {} -EF.invisible = {} -EF.poisoned = {} -EF.regenerating = {} -EF.strong = {} -EF.weak = {} -EF.water_breathing = {} -EF.leaping = {} -EF.swift = {} -- for swiftness AND slowness -EF.night_vision = {} -EF.fire_proof = {} -EF.bad_omen = {} +mcl_potions.registered_effects = {} +local registered_effects = mcl_potions.registered_effects -- shorthand ref + +-- effects affecting item speed utilize numerous hacks, so they have to be counted separately +local item_speed_effects = {} local EFFECT_TYPES = 0 -for _,_ in pairs(EF) do - EFFECT_TYPES = EFFECT_TYPES + 1 +minetest.register_on_mods_loaded(function() + for _,_ in pairs(EF) do + EFFECT_TYPES = EFFECT_TYPES + 1 + end +end) + +-- ██████╗░███████╗░██████╗░██╗░██████╗████████╗███████╗██████╗ +-- ██╔══██╗██╔════╝██╔════╝░██║██╔════╝╚══██╔══╝██╔════╝██╔══██╗ +-- ██████╔╝█████╗░░██║░░██╗░██║╚█████╗░░░░██║░░░█████╗░░██████╔╝ +-- ██╔══██╗██╔══╝░░██║░░╚██╗██║░╚═══██╗░░░██║░░░██╔══╝░░██╔══██╗ +-- ██║░░██║███████╗╚██████╔╝██║██████╔╝░░░██║░░░███████╗██║░░██║ +-- ╚═╝░░╚═╝╚══════╝░╚═════╝░╚═╝╚═════╝░░░░╚═╝░░░╚══════╝╚═╝░░╚═╝ +-- +-- ███████╗███████╗███████╗███████╗░█████╗░████████╗░██████╗ +-- ██╔════╝██╔════╝██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔════╝ +-- █████╗░░█████╗░░█████╗░░█████╗░░██║░░╚═╝░░░██║░░░╚█████╗░ +-- ██╔══╝░░██╔══╝░░██╔══╝░░██╔══╝░░██║░░██╗░░░██║░░░░╚═══██╗ +-- ███████╗██║░░░░░██║░░░░░███████╗╚█████╔╝░░░██║░░░██████╔╝ +-- ╚══════╝╚═╝░░░░░╚═╝░░░░░╚══════╝░╚════╝░░░░╚═╝░░░╚═════╝░ + +local function generate_linear_lvl_to_fac(l1, l2) + local a = l2 - l1 + local b = 2*l1 - l2 + return function(level) + return (a*level + b) + end +end + +local function generate_linear_fac_to_lvl(l1, l2) + local a = 1/(l2 - l1) + local b = -(2*l1 - l2) * a + return function(factor) + return math.round(a*factor + b) + end +end + +local function generate_rational_lvl_to_fac(l1, l2) + local a = (l1 - l2) * 2 + local b = 2*l2 - l1 + return function(level) + if level == 0 then return 0 end + return (a/level + b) + end +end + +local function generate_rational_fac_to_lvl(l1, l2) + local a = (l1 - l2) * 2 + local b = 2*l2 - l1 + return function(factor) + if (factor - b) == 0 then return math.huge end + return math.round(a/(factor - b)) + end +end + +local function generate_modifier_func(name, dmg_flag, mod_func, is_type) + if dmg_flag == "" then return function(object, damage, reason) + if EF[name][object] and not reason.flags.bypasses_magic then + return mod_func and mod_func(damage, EF[name][object]) or 0 + end + end + elseif is_type then return function(object, damage, reason) + if EF[name][object] and not reason.flags.bypasses_magic and reason.type == dmg_flag then + return mod_func and mod_func(damage, EF[name][object]) or 0 + end + end + else return function(object, damage, reason) + if EF[name][object] and not reason.flags.bypasses_magic and reason.flags[dmg_flag] then + return mod_func and mod_func(damage, EF[name][object]) or 0 + end + end end +end + +-- API - registers an effect +-- required parameters in def: +-- name - string - effect name in code +-- description - translated string - actual effect name in game +-- optional parameters in def: +-- get_tt - function(factor) - returns tooltip description text for use with potions +-- icon - string - file name of the effect icon in HUD - defaults to one based on name +-- res_condition - function(object) - returning true if target is to be resistant to the effect +-- on_start - function(object, factor) - called when dealing the effect +-- on_load - function(object, factor) - called on_joinplayer and on_activate +-- on_step - function(dtime, object, factor, duration) - running every step for all objects with this effect +-- on_hit_timer - function(object, factor, duration) - if defined runs a hit_timer depending on timer_uses_factor value +-- on_end - function(object) - called when the effect wears off +-- after_end - function(object) - called when the effect wears off, after purging the data of the effect +-- on_save_effect - function(object - called when the effect is to be serialized for saving (supposed to do cleanup) +-- particle_color - string - colorstring for particles - defaults to #3000EE +-- uses_factor - bool - whether factor affects the effect +-- lvl1_factor - number - factor for lvl1 effect - defaults to 1 if uses_factor +-- lvl2_factor - number - factor for lvl2 effect - defaults to 2 if uses_factor +-- timer_uses_factor - bool - whether hit_timer uses factor (uses_factor must be true) or a constant value (hit_timer_step must be defined) +-- hit_timer_step - float - interval between hit_timer hits +-- damage_modifier - string - damage flag of which damage is changed as defined by modifier_func, pass empty string for all damage +-- dmg_mod_is_type - bool - damage_modifier string is used as type instead of flag of damage, defaults to false +-- modifier_func - function(damage, effect_vals) - see damage_modifier, if not defined damage_modifier defaults to 100% resistance +-- modifier_priority - integer - priority passed when registering damage_modifier - defaults to -50 +-- affects_item_speed - table +-- -- if provided, effect gets added to the item_speed_effects table, this should be true if the effect affects item speeds, +-- -- otherwise it won't work properly with other such effects (like haste and fatigue) +-- -- -- factor_is_positive - bool - whether values of factor between 0 and 1 should be considered +factor% or speed multiplier +-- -- -- - obviously +factor% is positive and speed multiplier is negative interpretation +-- -- -- - values of factor higher than 1 will have a positive effect regardless +-- -- -- - values of factor lower than 0 will have a negative effect regardless +-- -- -- - open an issue on our tracker if you have a usage that isn't supported by this API +function mcl_potions.register_effect(def) + local modname = minetest.get_current_modname() + local name = def.name + if name == nil then + error("Unable to register effect: name is nil") + end + if type(name) ~= "string" then + error("Unable to register effect: name is not a string") + end + if name == "list" or name == "heal" or name == "remove" or name == "clear" then + error("Unable to register effect: " .. name .. " is a reserved word") + end + if registered_effects[name] then + error("Effect named "..name.." already registered!") + end + if not def.description or type(def.description) ~= "string" then + error("Unable to register effect: description is not a string") + end + local pdef = {} + pdef.description = def.description + if not def.icon then + pdef.icon = modname.."_effect_"..name..".png" + else + pdef.icon = def.icon + end + pdef.get_tt = def.get_tt + pdef.res_condition = def.res_condition + pdef.on_start = def.on_start + pdef.on_load = def.on_load + pdef.on_step = def.on_step + pdef.on_hit_timer = def.on_hit_timer + pdef.on_end = def.on_end + pdef.on_save_effect = def.on_save_effect + if not def.particle_color then + pdef.particle_color = "#3000EE" + else + pdef.particle_color = def.particle_color + end + if def.uses_factor then + pdef.uses_factor = true + local l1 = def.lvl1_factor or 1 + local l2 = def.lvl2_factor or 2*l1 + if l1 < l2 then + pdef.level_to_factor = generate_linear_lvl_to_fac(l1, l2) + pdef.factor_to_level = generate_linear_fac_to_lvl(l1, l2) + pdef.inv_factor = false + elseif l1 > l2 then + pdef.level_to_factor = generate_rational_lvl_to_fac(l1, l2) + pdef.factor_to_level = generate_rational_fac_to_lvl(l1, l2) + pdef.inv_factor = true + else + error("Can't extrapolate levels from lvl1 and lvl2 bearing the same factor") + end + else + pdef.uses_factor = false + end + if def.on_hit_timer then + if def.timer_uses_factor then + if not def.uses_factor then error("Uses factor but does not use factor?") end + pdef.timer_uses_factor = true + else + if not def.hit_timer_step then error("If hit_timer does not use factor, hit_timer_step must be defined") end + pdef.timer_uses_factor = false + pdef.hit_timer_step = def.hit_timer_step + end + end + if def.damage_modifier then + mcl_damage.register_modifier( + generate_modifier_func(name, def.damage_modifier, def.modifier_func, def.dmg_mod_is_type), + def.modifier_priority or -50 + ) + end + registered_effects[name] = pdef + EF[name] = {} + item_speed_effects[name] = def.affects_item_speed +end + +mcl_potions.register_effect({ + name = "invisibility", + description = S("Invisiblity"), + get_tt = function(factor) + return S("body is invisible") + end, + on_start = function(object, factor) + mcl_potions.make_invisible(object, true) + end, + on_load = function(object, factor) + mcl_potions.make_invisible(object, true) + end, + on_end = function(object) + mcl_potions.make_invisible(object, false) + end, + particle_color = "#7F8392", + uses_factor = false, +}) + +mcl_potions.register_effect({ + name = "poison", + description = S("Poison"), + get_tt = function(factor) + return S("-1 HP / @1 s", factor) + end, + res_condition = function(object) + local entity = object:get_luaentity() + return (entity and (entity.harmed_by_heal or string.find(entity.name, "spider"))) + end, + on_hit_timer = function(object, factor, duration) + if mcl_util.get_hp(object) - 1 > 0 then + mcl_util.deal_damage(object, 1, {type = "magic"}) + end + end, + particle_color = "#4E9331", + uses_factor = true, + lvl1_factor = 1.25, + lvl2_factor = 0.6, + timer_uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "regeneration", + description = S("Regeneration"), + get_tt = function(factor) + return S("+1 HP / @1 s", factor) + end, + res_condition = function(object) + local entity = object:get_luaentity() + return (entity and entity.harmed_by_heal) + end, + on_hit_timer = function(object, factor, duration) + local entity = object:get_luaentity() + if object:is_player() then + object:set_hp(math.min(object:get_properties().hp_max or 20, object:get_hp() + 1), { type = "set_hp", other = "regeneration" }) + elseif entity and entity.is_mob then + entity.health = math.min(entity.hp_max, entity.health + 1) + end + end, + particle_color = "#CD5CAB", + uses_factor = true, + lvl1_factor = 2.5, + lvl2_factor = 1.25, + timer_uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "strength", + description = S("Strength"), + get_tt = function(factor) + return S("+@1% melee damage", 100*(factor-1)) + end, + particle_color = "#932423", + uses_factor = true, + lvl1_factor = 1.3, + lvl2_factor = 1.6, +}) + +mcl_potions.register_effect({ + name = "weakness", + description = S("Weakness"), + get_tt = function(factor) + return S("-@1% melee damage", 100*(1-factor)) + end, + particle_color = "#485D48", + uses_factor = true, + lvl1_factor = 0.8, + lvl2_factor = 0.6, +}) + +-- implementation of strength and weakness effects +-- mobs have this implemented in mcl_mobs/combat.lua in mob_class:on_punch() +mcl_damage.register_modifier(function(object, damage, reason) + if reason.direct and reason.direct == reason.source then + local hitter = reason.direct + local strength = EF.strength[hitter] + local weakness = EF.weakness[hitter] + if not strength and not weakness then return end + local str_fac = strength and strength.factor or 1 + local weak_fac = weakness and weakness.factor or 1 + return damage * str_fac * weak_fac + end +end, 0) + +mcl_potions.register_effect({ + name = "water_breathing", + description = S("Water Breathing"), + get_tt = function(factor) + return S("limitless breathing under water") + end, + res_condition = function(object) + return (not object:is_player()) -- TODO add support for breath setting for mobs + end, + on_step = function(dtime, object, factor, duration) + if object:get_breath() then + hb.hide_hudbar(object, "breath") + if object:get_breath() < 10 then object:set_breath(10) end + end + end, + particle_color = "#2E5299", + uses_factor = false, +}) + +mcl_potions.register_effect({ + name = "dolphin_grace", + description = S("Dolphin's Grace"), + get_tt = function(factor) + return S("swimming gracefully") + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_hit_timer = function(object, factor, duration) + local node = minetest.get_node_or_nil(object:get_pos()) + if node and minetest.registered_nodes[node.name] + and minetest.get_item_group(node.name, "liquid") ~= 0 then + playerphysics.add_physics_factor(object, "speed", "mcl_potions:dolphin", 2) + else + playerphysics.remove_physics_factor(object, "speed", "mcl_potions:dolphin", 2) + end + end, + particle_color = "#6AABFD", + uses_factor = false, + timer_uses_factor = false, + hit_timer_step = 1, +}) + +mcl_potions.register_effect({ + name = "leaping", + description = S("Leaping"), + get_tt = function(factor) + if factor > 0 then return S("+@1% jumping power", math.floor(factor*100)) end + return S("-@1% jumping power", math.floor(-factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_start = function(object, factor) + playerphysics.add_physics_factor(object, "jump", "mcl_potions:leaping", 1+factor) + end, + on_end = function(object) + playerphysics.remove_physics_factor(object, "jump", "mcl_potions:leaping") + end, + particle_color = "#22FF4C", + uses_factor = true, + lvl1_factor = 0.5, + lvl2_factor = 1, +}) + +mcl_potions.register_effect({ + name = "slow_falling", + description = S("Slow Falling"), + get_tt = function(factor) + return S("decreases gravity effects") + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_start = function(object, factor) + playerphysics.add_physics_factor(object, "gravity", "mcl_potions:slow_falling", 0.5) + end, + on_step = function(dtime, object, factor, duration) + local vel = object:get_velocity() + if not vel then return end + vel = vel.y + if vel < -3 then object:add_velocity(vector.new(0,-3-vel,0)) end + end, + on_end = function(object) + playerphysics.remove_physics_factor(object, "gravity", "mcl_potions:slow_falling") + end, + particle_color = "#ACCCFF", +}) + +mcl_potions.register_effect({ + name = "swiftness", + description = S("Swiftness"), + get_tt = function(factor) + return S("+@1% running speed", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_start = function(object, factor) + playerphysics.add_physics_factor(object, "speed", "mcl_potions:swiftness", 1+factor) + end, + on_end = function(object) + playerphysics.remove_physics_factor(object, "speed", "mcl_potions:swiftness") + end, + particle_color = "#7CAFC6", + uses_factor = true, + lvl1_factor = 0.2, + lvl2_factor = 0.4, +}) + +mcl_potions.register_effect({ + name = "slowness", + description = S("Slowness"), + get_tt = function(factor) + return S("-@1% running speed", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_start = function(object, factor) + playerphysics.add_physics_factor(object, "speed", "mcl_potions:slowness", 1-factor) + end, + on_end = function(object) + playerphysics.remove_physics_factor(object, "speed", "mcl_potions:slowness") + end, + particle_color = "#5A6C81", + uses_factor = true, + lvl1_factor = 0.15, + lvl2_factor = 0.3, +}) + +mcl_potions.register_effect({ + name = "levitation", + description = S("Levitation"), + get_tt = function(factor) + return S("moves body upwards at @1 nodes/s", factor) + end, + on_step = function(dtime, object, factor, duration) + local vel = object:get_velocity() + if not vel then return end + vel = vel.y + if vel 0.6 then EF.darkness[object].flashdir = false end + flash = EF.darkness[object].flashdir and (flash + dtime) or (flash - dtime) + object:set_sky({fog = { + fog_start = flash, + }}) + EF.darkness[object].flash = flash + else + object:set_sky({fog = { + fog_start = 0.9, + }}) + end + mcl_weather.skycolor.update_sky_color({object}) + end, + on_end = function(object) + local meta = object:get_meta() + if not meta then return end + meta:set_int("darkness", 0) + mcl_weather.skycolor.update_sky_color({object}) + object:set_sky({fog = { + fog_distance = -1, + fog_start = -1, + }}) + end, + particle_color = "#000000", + uses_factor = true, + lvl1_factor = 30, + lvl2_factor = 20, +}) + +local GLOW_DISTANCE = 30 +local CLOSE_GLOW_LIMIT = 3 +local MIN_GLOW_SCALE = 1 +local MAX_GLOW_SCALE = 4 +local SCALE_DIFF = MAX_GLOW_SCALE - MIN_GLOW_SCALE +local SCALE_FACTOR = (GLOW_DISTANCE - CLOSE_GLOW_LIMIT) / SCALE_DIFF +local abs = math.abs +mcl_potions.register_effect({ + name = "glowing", + description = S("Glowing"), + get_tt = function(factor) + return S("more visible at all times") + end, + on_start = function(object, factor) + EF.glowing[object].waypoints = {} + end, + on_step = function(dtime, object, factor, duration) + local pos = object:get_pos() + if not pos then return end + local x, y, z = pos.x, pos.y, pos.z + for _, player in pairs(minetest.get_connected_players()) do + local pp = player:get_pos() + if pp and player ~= object then + local hud_id = EF.glowing[object].waypoints[player] + if abs(pp.x-x) < GLOW_DISTANCE and abs(pp.y-y) < GLOW_DISTANCE + and abs(pp.z-z) < GLOW_DISTANCE then + local distance = vector.distance(pos, pp) + local scale + if distance <= CLOSE_GLOW_LIMIT then scale = MAX_GLOW_SCALE + elseif distance >= GLOW_DISTANCE then scale = MIN_GLOW_SCALE + else scale = (GLOW_DISTANCE - distance) / SCALE_FACTOR + MIN_GLOW_SCALE end + if hud_id then + player:hud_change(hud_id, "world_pos", pos) + player:hud_change(hud_id, "scale", {x = scale, y = scale}) + else + EF.glowing[object].waypoints[player] = player:hud_add({ + hud_elem_type = "image_waypoint", + position = {x = 0.5, y = 0.5}, + scale = {x = scale, y = scale}, + text = "mcl_potions_glow_waypoint.png", + alignment = {x = 0, y = -1}, + world_pos = pos, + }) + end + elseif hud_id then + player:hud_remove(hud_id) + EF.glowing[object].waypoints[player] = nil + end + end + end + end, + on_end = function(object) + for player, hud_id in pairs(EF.glowing[object].waypoints) do + if player:get_pos() then player:hud_remove(hud_id) end + end + end, + on_save_effect = function(object) + for player, hud_id in pairs(EF.glowing[object].waypoints) do + if player:get_pos() then player:hud_remove(hud_id) end + end + EF.glowing[object].waypoints = {} + end, + particle_color = "#FFFF77", + uses_factor = false, +}) + +mcl_potions.register_effect({ + name = "health_boost", + description = S("Health Boost"), + get_tt = function(factor) + return S("HP increased by @1", factor) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob HP modifier API? + end, + on_start = function(object, factor) + object:set_properties({hp_max = minetest.PLAYER_MAX_HP_DEFAULT+factor}) + end, + on_end = function(object) + object:set_properties({hp_max = minetest.PLAYER_MAX_HP_DEFAULT}) + end, + particle_color = "#FF2222", + uses_factor = true, + lvl1_factor = 4, + lvl2_factor = 8, +}) + +mcl_potions.register_effect({ + name = "absorption", + description = S("Absorption"), + get_tt = function(factor) + return S("absorbs up to @1 incoming damage", factor) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO dmg modifiers don't work for mobs + end, + on_start = function(object, factor) + hb.change_hudbar(object, "absorption", factor, (math.floor(factor/20-0.05)+1)*20) + EF.absorption[object].absorb = factor + end, + on_load = function(object, factor) + minetest.after(0, function() hb.change_hudbar(object, "absorption", nil, (math.floor(factor/20-0.05)+1)*20) end) + end, + on_step = function(dtime, object, factor, duration) + hb.change_hudbar(object, "absorption", EF.absorption[object].absorb) + end, + on_end = function(object) + hb.change_hudbar(object, "absorption", 0) + end, + particle_color = "#B59500", + uses_factor = true, + lvl1_factor = 4, + lvl2_factor = 8, + damage_modifier = "", + modifier_func = function(damage, effect_vals) + local absorb = effect_vals.absorb + local carryover = 0 + if absorb > damage then + effect_vals.absorb = absorb - damage + else + carryover = damage - absorb + effect_vals.absorb = 0 + end + return carryover + end, +}) + +mcl_potions.register_effect({ + name = "fire_resistance", + description = S("Fire Resistance"), + get_tt = function(factor) + return S("resistance to fire damage") + end, + res_condition = function(object) + return (not object:is_player()) -- TODO dmg modifiers don't work for mobs + end, + particle_color = "#E49A3A", + uses_factor = false, + damage_modifier = "is_fire", +}) + +mcl_potions.register_effect({ + name = "resistance", + description = S("Resistance"), + get_tt = function(factor) + return S("resist @1% of incoming damage", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO dmg modifiers don't work for mobs + end, + particle_color = "#2552A5", + uses_factor = true, + lvl1_factor = 0.2, + lvl2_factor = 0.4, + damage_modifier = "", + modifier_func = function(damage, effect_vals) + return damage - (effect_vals.factor)*damage + end, +}) + +mcl_potions.register_effect({ + name = "luck", + description = S("Luck"), + particle_color = "#7BFF42", + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_start = function(object, factor) + mcl_luck.apply_luck_modifier(object:get_player_name(), "mcl_potions:luck", factor) + end, + on_load = function(object, factor) + mcl_luck.apply_luck_modifier(object:get_player_name(), "mcl_potions:luck", factor) + end, + on_end = function(object) + mcl_luck.remove_luck_modifier(object:get_player_name(), "mcl_potions:luck") + end, + uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "bad_luck", + description = S("Bad Luck"), + particle_color = "#887343", + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_start = function(object, factor) + mcl_luck.apply_luck_modifier(object:get_player_name(), "mcl_potions:bad_luck", -factor) + end, + on_load = function(object, factor) + mcl_luck.apply_luck_modifier(object:get_player_name(), "mcl_potions:bad_luck", -factor) + end, + on_end = function(object) + mcl_luck.remove_luck_modifier(object:get_player_name(), "mcl_potions:bad_luck") + end, + uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "bad_omen", + description = S("Bad Omen"), + get_tt = function(factor) + return S("danger is imminent") + end, + particle_color = "#472331", + uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "hero_of_village", + description = S("Hero of the Village"), + particle_color = "#006D2A", +}) + +mcl_potions.register_effect({ + name = "withering", + description = S("Withering"), + get_tt = function(factor) + return S("-1 HP / @1 s, can kill", factor) + end, + res_condition = function(object) + local entity = object:get_luaentity() + return (entity and string.find(entity.name, "wither")) + end, + on_hit_timer = function(object, factor, duration) + if object:is_player() or object:get_luaentity() then + mcl_util.deal_damage(object, 1, {type = "magic"}) + end + end, + particle_color = "#292929", + uses_factor = true, + lvl1_factor = 2, + lvl2_factor = 1, + timer_uses_factor = true, +}) + +mcl_potions.register_effect({ + name = "frost", + description = S("Frost"), + get_tt = function(factor) + return S("-1 HP / 1 s, can kill, -@1% running speed", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob physics factor API + end, + on_start = function(object, factor) + mcl_burning.extinguish(object) + playerphysics.add_physics_factor(object, "speed", "mcl_potions:frost", 1-factor) + if EF.frost[object].vignette then return end + EF.frost[object].vignette = object:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + text = "mcl_potions_frost_hud.png", + z_index = -400 + }) + end, + on_load = function(object, factor) + EF.frost[object].vignette = object:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + text = "mcl_potions_frost_hud.png", + z_index = -400 + }) + end, + on_hit_timer = function(object, factor, duration) + if object:is_player() or object:get_luaentity() then + mcl_util.deal_damage(object, 1, {type = "magic"}) + end + end, + on_end = function(object) + playerphysics.remove_physics_factor(object, "speed", "mcl_potions:frost") + if not EF.frost[object] then return end + object:hud_remove(EF.frost[object].vignette) + end, + particle_color = "#5B7DAA", + uses_factor = true, + lvl1_factor = 0.1, + lvl2_factor = 0.2, + timer_uses_factor = false, + hit_timer_step = 1, + damage_modifier = "is_fire", + modifier_func = function(damage, effect_vals) + effect_vals.timer = effect_vals.dur + return 0 + end, +}) + +mcl_potions.register_effect({ + name = "blindness", + description = "Blindness", + get_tt = function(factor) + return S("impaired sight") + end, + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_start = function(object, factor) + EF.blindness[object].vignette = object:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + text = "mcl_potions_blindness_hud.png", + z_index = -401 + }) + mcl_fovapi.apply_modifier(object, "mcl_potions:blindness") + end, + on_load = function(object, factor) + EF.blindness[object].vignette = object:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + text = "mcl_potions_blindness_hud.png", + z_index = -401 + }) + mcl_fovapi.apply_modifier(object, "mcl_potions:blindness") + end, + on_end = function(object) + mcl_fovapi.remove_modifier(object, "mcl_potions:blindness") + if not EF.blindness[object] then return end + object:hud_remove(EF.blindness[object].vignette) + end, + particle_color = "#686868", + uses_factor = false, +}) +mcl_fovapi.register_modifier({ + name = "mcl_potions:blindness", + fov_factor = 0.6, + time = 1, +}) + +mcl_potions.register_effect({ + name = "nausea", + description = S("Nausea"), + get_tt = function(factor) + return S("not feeling very well...").."\n"..S("frequency: @1 / 1 s", factor) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_start = function(object, factor) + object:set_lighting({ + saturation = -1.0, + }) + end, + on_hit_timer = function(object, factor, duration) + if EF.nausea[object].high then + mcl_fovapi.remove_modifier(object, "mcl_potions:nausea_high", factor) + mcl_fovapi.apply_modifier(object, "mcl_potions:nausea_low", factor) + EF.nausea[object].high = false + else + mcl_fovapi.apply_modifier(object, "mcl_potions:nausea_high", factor) + mcl_fovapi.remove_modifier(object, "mcl_potions:nausea_low", factor) + EF.nausea[object].high = true + end + end, + on_end = function(object) + object:set_lighting({ + saturation = 1.0, + }) + mcl_fovapi.remove_modifier(object, "mcl_potions:nausea_high") + mcl_fovapi.remove_modifier(object, "mcl_potions:nausea_low") + end, + particle_color = "#60AA30", + uses_factor = true, + lvl1_factor = 2, + lvl2_factor = 1, + timer_uses_factor = true, +}) +mcl_fovapi.register_modifier({ + name = "mcl_potions:nausea_high", + fov_factor = 2.2, + time = 1, +}) +mcl_fovapi.register_modifier({ + name = "mcl_potions:nausea_low", + fov_factor = 0.2, + time = 1, +}) + +mcl_potions.register_effect({ + name = "food_poisoning", + description = S("Food Poisoning"), + get_tt = function(factor) + return S("exhausts by @1 per second", factor) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_start = function(object, factor) + hb.change_hudbar(object, "hunger", nil, nil, "mcl_hunger_icon_foodpoison.png", nil, "mcl_hunger_bar_foodpoison.png") + if mcl_hunger.debug then + hb.change_hudbar(object, "exhaustion", nil, nil, nil, nil, "mcl_hunger_bar_foodpoison.png") + end + end, + on_load = function(object, factor) -- TODO refactor and add hunger bar modifier API + hb.change_hudbar(object, "hunger", nil, nil, "mcl_hunger_icon_foodpoison.png", nil, "mcl_hunger_bar_foodpoison.png") + if mcl_hunger.debug then + hb.change_hudbar(object, "exhaustion", nil, nil, nil, nil, "mcl_hunger_bar_foodpoison.png") + end + end, + on_step = function(dtime, object, factor, duration) + mcl_hunger.exhaust(object:get_player_name(), dtime*factor) + end, + on_end = function(object) + mcl_hunger.reset_bars_poison_hunger(object) + end, + particle_color = "#83A061", + uses_factor = true, + lvl1_factor = 100, + lvl2_factor = 200, +}) + +mcl_potions.register_effect({ + name = "saturation", + description = S("Saturation"), + get_tt = function(factor) + return S("saturates by @1 per second", factor) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO what should it do for mobs? + end, + on_step = function(dtime, object, factor, duration) + mcl_hunger.set_hunger(object, math.min(mcl_hunger.get_hunger(object)+dtime*factor, 20)) + mcl_hunger.saturate(object:get_player_name(), dtime*factor) + end, + particle_color = "#CEAE29", + uses_factor = true, +}) + +-- constants relevant for effects altering mining and attack speed +local LONGEST_MINING_TIME = 300 +local LONGEST_PUNCH_INTERVAL = 10 +mcl_potions.LONGEST_MINING_TIME = LONGEST_MINING_TIME +mcl_potions.LONGEST_PUNCH_INTERVAL = LONGEST_PUNCH_INTERVAL + +function mcl_potions.apply_haste_fatigue(toolcaps, h_fac, f_fac) + if f_fac == 0 then + local fpi = toolcaps.full_punch_interval + toolcaps.full_punch_interval = fpi > LONGEST_PUNCH_INTERVAL and fpi or LONGEST_PUNCH_INTERVAL + else + toolcaps.full_punch_interval = toolcaps.full_punch_interval / (1+h_fac) / f_fac + end + for name, group in pairs(toolcaps.groupcaps) do + local t = group.times + for i=1, #t do + if f_fac == 0 then + t[i] = t[i] > LONGEST_MINING_TIME and t[i] or LONGEST_MINING_TIME + else + local old_time = t[i] + t[i] = t[i] / (1+h_fac) / f_fac + if old_time < LONGEST_MINING_TIME and t[i] > LONGEST_MINING_TIME then + t[i] = LONGEST_MINING_TIME + end + end + end + end + return toolcaps +end + +function mcl_potions.hf_update_internal(hand, object) + -- TODO add a check for creative mode? + local meta = hand:get_meta() + local h_fac = mcl_potions.get_total_haste(object) + local f_fac = mcl_potions.get_total_fatigue(object) + local toolcaps = hand:get_tool_capabilities() + meta:set_tool_capabilities(mcl_potions.apply_haste_fatigue(toolcaps, h_fac, f_fac)) + return hand +end + +local function haste_fatigue_hand_update(object) + local inventory = object:get_inventory() + if not inventory or inventory:get_size("hand") < 1 then return end + local hand = inventory:get_stack("hand", 1) + inventory:set_stack("hand", 1, mcl_potions.hf_update_internal(hand, object)) +end + +mcl_potions.register_effect({ + name = "haste", + description = S("Haste"), + get_tt = function(factor) + return S("+@1% mining and attack speed", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob API support + end, + on_start = haste_fatigue_hand_update, + after_end = function(object) + haste_fatigue_hand_update(object) + mcl_potions._reset_haste_fatigue_item_meta(object) + end, + particle_color = "#FFFF00", + uses_factor = true, + lvl1_factor = 0.2, + lvl2_factor = 0.4, + affects_item_speed = {factor_is_positive = true}, +}) + +mcl_potions.register_effect({ + name = "fatigue", + description = S("Fatigue"), + get_tt = function(factor) + return S("-@1% mining and attack speed", math.floor((1-factor)*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob API support + end, + on_start = haste_fatigue_hand_update, + after_end = function(object) + haste_fatigue_hand_update(object) + mcl_potions._reset_haste_fatigue_item_meta(object) + end, + particle_color = "#64643D", + uses_factor = true, + lvl1_factor = 0.3, + lvl2_factor = 0.09, + affects_item_speed = {}, +}) + +mcl_potions.register_effect({ + name = "conduit_power", + description = S("Conduit Power"), + get_tt = function(factor) + return S("+@1% mining and attack speed in water").."\n"..S("limitless breathing under water", math.floor(factor*100)) + end, + res_condition = function(object) + return (not object:is_player()) -- TODO needs mob API support + end, + on_start = haste_fatigue_hand_update, + on_step = function(dtime, object, factor, duration) + if not object:is_player() then return end + local node = minetest.get_node_or_nil(object:get_pos()) + if node and minetest.registered_nodes[node.name] + and minetest.get_item_group(node.name, "liquid") ~= 0 + and minetest.get_item_group(node.name, "water") ~= 0 then + EF.conduit_power[object].blocked = nil + if object:get_breath() then + hb.hide_hudbar(object, "breath") + if object:get_breath() < 10 then object:set_breath(10) end + end + -- TODO implement improved underwater vision with this effect + else + EF.conduit_power[object].blocked = true + end + end, + after_end = function(object) + haste_fatigue_hand_update(object) + mcl_potions._reset_haste_fatigue_item_meta(object) + end, + particle_color = "#1FB1BA", + uses_factor = true, + lvl1_factor = 0.2, + lvl2_factor = 0.4, + affects_item_speed = {factor_is_positive = true}, +}) + +-- implementation of haste and fatigue effects +function mcl_potions.update_haste_and_fatigue(player) + if mcl_gamemode.get_gamemode(player) == "creative" then return end + local item = player:get_wielded_item() + local meta = item:get_meta() + local item_haste = meta:get_float("mcl_potions:haste") + local item_fatig = 1 - meta:get_float("mcl_potions:fatigue") + local h_fac = mcl_potions.get_total_haste(player) + local f_fac = mcl_potions.get_total_fatigue(player) + if item_haste ~= h_fac or item_fatig ~= f_fac then + if h_fac ~= 0 then meta:set_float("mcl_potions:haste", h_fac) + else meta:set_string("mcl_potions:haste", "") end + if f_fac ~= 1 then meta:set_float("mcl_potions:fatigue", 1 - f_fac) + else meta:set_string("mcl_potions:fatigue", "") end + meta:set_tool_capabilities() + meta:set_string("groupcaps_hash","") + mcl_enchanting.update_groupcaps(item) + if h_fac == 0 and f_fac == 1 then + player:set_wielded_item(item) + return + end + local toolcaps = item:get_tool_capabilities() + meta:set_tool_capabilities(mcl_potions.apply_haste_fatigue(toolcaps, h_fac, f_fac)) + player:set_wielded_item(item) + end + haste_fatigue_hand_update(player, h_fac, f_fac) +end +minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) + mcl_potions.update_haste_and_fatigue(puncher) +end) +minetest.register_on_punchplayer(function(player, hitter) + if not hitter:is_player() then return end -- TODO implement haste and fatigue support for mobs? + mcl_potions.update_haste_and_fatigue(hitter) +end) +-- update when hitting mob implemented in mcl_mobs/combat.lua + + + +-- ██╗░░░██╗██████╗░██████╗░░█████╗░████████╗███████╗ +-- ██║░░░██║██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██╔════╝ +-- ██║░░░██║██████╔╝██║░░██║███████║░░░██║░░░█████╗░░ +-- ██║░░░██║██╔═══╝░██║░░██║██╔══██║░░░██║░░░██╔══╝░░ +-- ╚██████╔╝██║░░░░░██████╦╝██║░░██║░░░██║░░░███████╗ +-- ░╚═════╝░╚═╝░░░░░╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝ +-- +-- ██╗░░██╗██╗░░░██╗██████╗░ +-- ██║░░██║██║░░░██║██╔══██╗ +-- ███████║██║░░░██║██║░░██║ +-- ██╔══██║██║░░░██║██║░░██║ +-- ██║░░██║╚██████╔╝██████╦╝ +-- ╚═╝░░╚═╝░╚═════╝░╚═════╝░ + +hb.register_hudbar("absorption", 0xFFFFFF, S("Absorption"), {bar = "[fill:2x16:#B59500", icon = "mcl_potions_icon_absorb.png"}, 0, 0, 0, false) + +local hp_hudbar_modifiers = {} + +-- API - registers a HP hudbar modifier +-- required parameters in def: +-- predicate - function(player) - returns true if player fulfills the requirements (eg. has the effects) for the hudbar look +-- icon - string - name of the icon to which the modifier should change the HP hudbar heart +-- priority - signed int - lower gets checked first, and first fulfilled predicate applies its modifier +function mcl_potions.register_hp_hudbar_modifier(def) + if type(def.predicate) ~= "function" then error("Predicate must be a function") end + if not def.icon then error("No icon provided") end + if not def.priority then error("No priority provided") end + table.insert(hp_hudbar_modifiers, { + predicate = def.predicate, + icon = def.icon, + priority = def.priority, + }) + table.sort(hp_hudbar_modifiers, function(a, b) return a.priority <= b.priority end) +end + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.withering[player] and EF.regeneration[player] then return true end + end, + icon = "mcl_potions_icon_regen_wither.png", + priority = -30, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.withering[player] then return true end + end, + icon = "mcl_potions_icon_wither.png", + priority = -20, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.poison[player] and EF.regeneration[player] then return true end + end, + icon = "hbhunger_icon_regen_poison.png", + priority = -10, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.poison[player] then return true end + end, + icon = "hbhunger_icon_health_poison.png", + priority = 0, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.frost[player] and EF.regeneration[player] then return true end + end, + icon = "mcl_potions_icon_regen_frost.png", + priority = 10, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.frost[player] then return true end + end, + icon = "mcl_potions_icon_frost.png", + priority = 20, +}) + +mcl_potions.register_hp_hudbar_modifier({ + predicate = function(player) + if EF.regeneration[player] then return true end + end, + icon = "hudbars_icon_regenerate.png", + priority = 30, +}) + +local function potions_set_hudbar(player) + for _, mod in pairs(hp_hudbar_modifiers) do + if mod.predicate(player) then + hb.change_hudbar(player, "health", nil, nil, mod.icon, nil, "hudbars_bar_health.png") + return + end + end + hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_health.png", nil, "hudbars_bar_health.png") end local icon_ids = {} -local function potions_set_hudbar(player) - - if EF.poisoned[player] and EF.regenerating[player] then - hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_regen_poison.png", nil, "hudbars_bar_health.png") - elseif EF.poisoned[player] then - hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hudbars_bar_health.png") - elseif EF.regenerating[player] then - hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_regenerate.png", nil, "hudbars_bar_health.png") - else - hb.change_hudbar(player, "health", nil, nil, "hudbars_icon_health.png", nil, "hudbars_bar_health.png") - end - -end - local function potions_init_icons(player) local name = player:get_player_name() icon_ids[name] = {} for e=1, EFFECT_TYPES do local x = -52 * e - 2 - local id = player:hud_add({ + local id = {} + id.img = player:hud_add({ hud_elem_type = "image", text = "blank.png", position = { x = 1, y = 0 }, @@ -46,8 +1236,31 @@ local function potions_init_icons(player) alignment = { x = 1, y = 1 }, z_index = 100, }) + id.label = player:hud_add({ + hud_elem_type = "text", + text = "", + position = { x = 1, y = 0 }, + offset = { x = x+22, y = 50 }, + scale = { x = 50, y = 15 }, + alignment = { x = 0, y = 1 }, + z_index = 100, + style = 1, + number = 0xFFFFFF, + }) + id.timestamp = player:hud_add({ + hud_elem_type = "text", + text = "", + position = { x = 1, y = 0 }, + offset = { x = x+22, y = 65 }, + scale = { x = 50, y = 15 }, + alignment = { x = 0, y = 1 }, + z_index = 100, + style = 1, + number = 0xFFFFFF, + }) table.insert(icon_ids[name], id) end + hb.init_hudbar(player, "absorption") end local function potions_set_icons(player) @@ -58,30 +1271,49 @@ local function potions_set_icons(player) local active_effects = {} for effect_name, effect in pairs(EF) do if effect[player] then - table.insert(active_effects, effect_name) + active_effects[effect_name] = effect[player] end end - for i=1, EFFECT_TYPES do - local icon = icon_ids[name][i] - local effect_name = active_effects[i] - if effect_name == "swift" and EF.swift[player].is_slow then - effect_name = "slow" - end - if effect_name == nil then - player:hud_change(icon, "text", "blank.png") - else - player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png^[resize:128x128") + local i = 1 + for effect_name, def in pairs(registered_effects) do + local icon = icon_ids[name][i].img + local label = icon_ids[name][i].label + local timestamp = icon_ids[name][i].timestamp + local vals = active_effects[effect_name] + if vals then + player:hud_change(icon, "text", def.icon .. "^[resize:128x128") + if def.uses_factor then + local level = def.factor_to_level(vals.factor) + if level > 3000 or level == math.huge then level = "∞" + elseif level < 0 then level = "???" + elseif level == 0 then level = "0" + else level = mcl_util.to_roman(level) end + player:hud_change(label, "text", level) + else + player:hud_change(label, "text", "") + end + if vals.dur == math.huge then + player:hud_change(timestamp, "text", "∞") + else + local dur = math.round(vals.dur-vals.timer) + player:hud_change(timestamp, "text", math.floor(dur/60)..string.format(":%02d",math.floor(dur % 60))) + end + EF[effect_name][player].hud_index = i + i = i + 1 end end - + while i < EFFECT_TYPES do + player:hud_change(icon_ids[name][i].img, "text", "blank.png") + player:hud_change(icon_ids[name][i].label, "text", "") + player:hud_change(icon_ids[name][i].timestamp, "text", "") + i = i + 1 + end end local function potions_set_hud(player) - potions_set_hudbar(player) potions_set_icons(player) - end @@ -99,288 +1331,54 @@ end -- ╚█████╔╝██║░░██║███████╗╚█████╔╝██║░╚██╗███████╗██║░░██║ -- ░╚════╝░╚═╝░░╚═╝╚══════╝░╚════╝░╚═╝░░╚═╝╚══════╝╚═╝░░╚═╝ -local is_player, entity, meta - minetest.register_globalstep(function(dtime) + for name, effect in pairs(registered_effects) do + for object, vals in pairs(EF[name]) do + if vals.dur ~= math.huge then EF[name][object].timer = vals.timer + dtime end - -- Check for invisible players - for player, vals in pairs(EF.invisible) do - - EF.invisible[player].timer = EF.invisible[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#7F8392") end - - if EF.invisible[player].timer >= EF.invisible[player].dur then - mcl_potions.make_invisible(player, false) - EF.invisible[player] = nil - if player:is_player() then - meta = player:get_meta() - meta:set_string("_is_invisible", minetest.serialize(EF.invisible[player])) + if object:get_pos() and not vals.no_particles then mcl_potions._add_spawner(object, effect.particle_color) end + if effect.on_step then effect.on_step(dtime, object, vals.factor, vals.dur) end + if effect.on_hit_timer then + EF[name][object].hit_timer = (vals.hit_timer or 0) + dtime + if EF[name][object].hit_timer >= vals.step then + effect.on_hit_timer(object, vals.factor, vals.dur) + if EF[name][object] then EF[name][object].hit_timer = 0 end + end end - potions_set_hud(player) + if not object or not EF[name][object] or EF[name][object].timer >= vals.dur or not object:get_pos() then + if effect.on_end then effect.on_end(object) end + EF[name][object] = nil + if effect.after_end then effect.after_end(object) end + if object:is_player() then + meta = object:get_meta() + meta:set_string("mcl_potions:_EF_"..name, "") + potions_set_hud(object) + else + local ent = object:get_luaentity() + if ent and ent._mcl_potions then + ent._mcl_potions["_EF_"..name] = nil + end + end + elseif object:is_player() then + if vals.dur == math.huge then + object:hud_change(icon_ids[object:get_player_name()][vals.hud_index].timestamp, + "text", "∞") + else + local dur = math.round(vals.dur-vals.timer) + object:hud_change(icon_ids[object:get_player_name()][vals.hud_index].timestamp, + "text", math.floor(dur/60)..string.format(":%02d",math.floor(dur % 60))) + end + else + local ent = object:get_luaentity() + if ent and ent._mcl_potions then + ent._mcl_potions["_EF_"..name] = EF[name][object] + end + end end - end - - -- Check for poisoned players - for player, vals in pairs(EF.poisoned) do - - is_player = player:is_player() - entity = player:get_luaentity() - - EF.poisoned[player].timer = EF.poisoned[player].timer + dtime - EF.poisoned[player].hit_timer = (EF.poisoned[player].hit_timer or 0) + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#4E9331") end - - if EF.poisoned[player].hit_timer >= EF.poisoned[player].step then - if mcl_util.get_hp(player) - 1 > 0 then - mcl_util.deal_damage(player, 1, {type = "magic"}) - end - EF.poisoned[player].hit_timer = 0 - end - - if EF.poisoned[player] and EF.poisoned[player].timer >= EF.poisoned[player].dur then - EF.poisoned[player] = nil - if is_player then - meta = player:get_meta() - meta:set_string("_is_poisoned", minetest.serialize(EF.poisoned[player])) - potions_set_hud(player) - end - end - - end - - -- Check for regnerating players - for player, vals in pairs(EF.regenerating) do - - is_player = player:is_player() - entity = player:get_luaentity() - - EF.regenerating[player].timer = EF.regenerating[player].timer + dtime - EF.regenerating[player].heal_timer = (EF.regenerating[player].heal_timer or 0) + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#CD5CAB") end - - if EF.regenerating[player].heal_timer >= EF.regenerating[player].step then - - if is_player then - player:set_hp(math.min(player:get_properties().hp_max or 20, player:get_hp() + 1), { type = "set_hp", other = "regeneration" }) - EF.regenerating[player].heal_timer = 0 - elseif entity and entity.is_mob then - entity.health = math.min(entity.hp_max, entity.health + 1) - EF.regenerating[player].heal_timer = 0 - else -- stop regenerating if not a player or mob - EF.regenerating[player] = nil - end - - end - - if EF.regenerating[player] and EF.regenerating[player].timer >= EF.regenerating[player].dur then - EF.regenerating[player] = nil - if is_player then - meta = player:get_meta() - meta:set_string("_is_regenerating", minetest.serialize(EF.regenerating[player])) - potions_set_hud(player) - end - end - - end - - -- Check for water breathing players - for player, vals in pairs(EF.water_breathing) do - - if player:is_player() then - - EF.water_breathing[player].timer = EF.water_breathing[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#2E5299") end - - if player:get_breath() then - hb.hide_hudbar(player, "breath") - if player:get_breath() < 10 then player:set_breath(10) end - end - - if EF.water_breathing[player].timer >= EF.water_breathing[player].dur then - meta = player:get_meta() - meta:set_string("_is_water_breathing", minetest.serialize(EF.water_breathing[player])) - EF.water_breathing[player] = nil - end - potions_set_hud(player) - - else - EF.water_breathing[player] = nil - end - - end - - -- Check for leaping players - for player, vals in pairs(EF.leaping) do - - if player:is_player() then - - EF.leaping[player].timer = EF.leaping[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#22FF4C") end - - if EF.leaping[player].timer >= EF.leaping[player].dur then - playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping") - EF.leaping[player] = nil - meta = player:get_meta() - meta:set_string("_is_leaping", minetest.serialize(EF.leaping[player])) - end - potions_set_hud(player) - - else - EF.leaping[player] = nil - end - - end - - -- Check for swift players - for player, vals in pairs(EF.swift) do - - if player:is_player() then - - EF.swift[player].timer = EF.swift[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#7CAFC6") end - - if EF.swift[player].timer >= EF.swift[player].dur then - playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness") - EF.swift[player] = nil - meta = player:get_meta() - meta:set_string("_is_swift", minetest.serialize(EF.swift[player])) - end - potions_set_hud(player) - - else - EF.swift[player] = nil - end - - end - - -- Check for Night Vision equipped players - for player, vals in pairs(EF.night_vision) do - - if player:is_player() then - - EF.night_vision[player].timer = EF.night_vision[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#1F1FA1") end - - if EF.night_vision[player].timer >= EF.night_vision[player].dur then - EF.night_vision[player] = nil - meta = player:get_meta() - meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player])) - meta:set_int("night_vision", 0) - end - mcl_weather.skycolor.update_sky_color({player}) - potions_set_hud(player) - - else - EF.night_vision[player] = nil - end - - end - - -- Check for Fire Proof players - for player, vals in pairs(EF.fire_proof) do - - if player:is_player() then - - player = player or player:get_luaentity() - - EF.fire_proof[player].timer = EF.fire_proof[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#E49A3A") end - - if EF.fire_proof[player].timer >= EF.fire_proof[player].dur then - EF.fire_proof[player] = nil - meta = player:get_meta() - meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player])) - end - potions_set_hud(player) - - else - EF.fire_proof[player] = nil - end - - end - - -- Check for Weak players - for player, vals in pairs(EF.weak) do - - if player:is_player() then - - EF.weak[player].timer = EF.weak[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#484D48") end - - if EF.weak[player].timer >= EF.weak[player].dur then - EF.weak[player] = nil - meta = player:get_meta() - meta:set_string("_is_weak", minetest.serialize(EF.weak[player])) - end - - else - EF.weak[player] = nil - end - - end - - -- Check for Strong players - for player, vals in pairs(EF.strong) do - - if player:is_player() then - - EF.strong[player].timer = EF.strong[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#932423") end - - if EF.strong[player].timer >= EF.strong[player].dur then - EF.strong[player] = nil - meta = player:get_meta() - meta:set_string("_is_strong", minetest.serialize(EF.strong[player])) - end - - else - EF.strong[player] = nil - end - - end - - -- Check for Bad Omen - for player, vals in pairs(EF.bad_omen) do - - is_player = player:is_player() - - EF.bad_omen[player].timer = EF.bad_omen[player].timer + dtime - - if player:get_pos() then mcl_potions._add_spawner(player, "#0b6138") end - - if EF.bad_omen[player] and EF.bad_omen[player].timer >= EF.bad_omen[player].dur then - EF.bad_omen[player] = nil - if is_player then - meta = player:get_meta() - meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player])) - potions_set_hud(player) - end - end - - end - end) --- Prevent damage to player with Fire Resistance enabled -mcl_damage.register_modifier(function(obj, damage, reason) - if EF.fire_proof[obj] and not reason.flags.bypasses_magic and reason.flags.is_fire then - return 0 - end -end, -50) - - -- ███████╗███████╗███████╗███████╗░█████╗░████████╗ -- ██╔════╝██╔════╝██╔════╝██╔════╝██╔══██╗╚══██╔══╝ @@ -396,163 +1394,253 @@ end, -50) -- ███████╗╚█████╔╝██║░░██║██████╔╝██╔╝░░░██████╔╝██║░░██║░░╚██╔╝░░███████╗ -- ╚══════╝░╚════╝░╚═╝░░╚═╝╚═════╝░╚═╝░░░░╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝ -function mcl_potions._clear_cached_player_data(player) - EF.invisible[player] = nil - EF.poisoned[player] = nil - EF.regenerating[player] = nil - EF.strong[player] = nil - EF.weak[player] = nil - EF.water_breathing[player] = nil - EF.leaping[player] = nil - EF.swift[player] = nil - EF.night_vision[player] = nil - EF.fire_proof[player] = nil - EF.bad_omen[player] = nil +function mcl_potions._reset_haste_fatigue_item_meta(player) + local inv = player:get_inventory() + if not inv then return end + local lists = inv:get_lists() + for _, list in pairs(lists) do + for _, item in pairs(list) do + local meta = item:get_meta() + meta:set_string("mcl_potions:haste", "") + meta:set_string("mcl_potions:fatigue", "") + meta:set_tool_capabilities() + meta:set_string("groupcaps_hash","") + mcl_enchanting.update_groupcaps(item) + end + end + inv:set_lists(lists) +end +mcl_gamemode.register_on_gamemode_change(mcl_potions._reset_haste_fatigue_item_meta) - meta = player:get_meta() +function mcl_potions._clear_cached_effect_data(object) + for name, effect in pairs(EF) do + effect[object] = nil + end + if not object:is_player() then return end + local meta = object:get_meta() meta:set_int("night_vision", 0) end -function mcl_potions._reset_player_effects(player, set_hud) - - if not player:is_player() then - return +function mcl_potions._reset_effects(object, set_hud) + local set_hud = set_hud + if not object:is_player() then + set_hud = false end - mcl_potions.make_invisible(player, false) + local removed_effects = {} + for name, effect in pairs(registered_effects) do + if EF[name][object] and effect.on_end then effect.on_end(object) end + if effect.after_end then table.insert(removed_effects, effect.after_end) end + end - playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping") + mcl_potions._clear_cached_effect_data(object) - playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness") - - mcl_weather.skycolor.update_sky_color({player}) - - mcl_potions._clear_cached_player_data(player) + for i=1, #removed_effects do + removed_effects[i](object) + end if set_hud ~= false then - potions_set_hud(player) + potions_set_hud(object) end end function mcl_potions._save_player_effects(player) - if not player:is_player() then return end - meta = player:get_meta() - - meta:set_string("_is_invisible", minetest.serialize(EF.invisible[player])) - meta:set_string("_is_poisoned", minetest.serialize(EF.poisoned[player])) - meta:set_string("_is_regenerating", minetest.serialize(EF.regenerating[player])) - meta:set_string("_is_strong", minetest.serialize(EF.strong[player])) - meta:set_string("_is_weak", minetest.serialize(EF.weak[player])) - meta:set_string("_is_water_breathing", minetest.serialize(EF.water_breathing[player])) - meta:set_string("_is_leaping", minetest.serialize(EF.leaping[player])) - meta:set_string("_is_swift", minetest.serialize(EF.swift[player])) - meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player])) - meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player])) - meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player])) + local meta = player:get_meta() + for name, effect in pairs(registered_effects) do + if effect.on_save_effect and EF[name][player] then effect.on_save_effect(player) end + meta:set_string("mcl_potions:_EF_"..name, minetest.serialize(EF[name][player])) + end end function mcl_potions._load_player_effects(player) - if not player:is_player() then return end - meta = player:get_meta() + local meta = player:get_meta() - if minetest.deserialize(meta:get_string("_is_invisible")) then - EF.invisible[player] = minetest.deserialize(meta:get_string("_is_invisible")) - mcl_potions.make_invisible(player, true) + -- handle legacy meta strings + local legacy_invisible = minetest.deserialize(meta:get_string("_is_invisible")) + local legacy_poisoned = minetest.deserialize(meta:get_string("_is_poisoned")) + local legacy_regenerating = minetest.deserialize(meta:get_string("_is_regenerating")) + local legacy_strong = minetest.deserialize(meta:get_string("_is_strong")) + local legacy_weak = minetest.deserialize(meta:get_string("_is_weak")) + local legacy_water_breathing = minetest.deserialize(meta:get_string("_is_water_breathing")) + local legacy_leaping = minetest.deserialize(meta:get_string("_is_leaping")) + local legacy_swift = minetest.deserialize(meta:get_string("_is_swift")) + local legacy_night_vision = minetest.deserialize(meta:get_string("_is_cat")) + local legacy_fireproof = minetest.deserialize(meta:get_string("_is_fire_proof")) + local legacy_bad_omen = minetest.deserialize(meta:get_string("_has_bad_omen")) + local legacy_withering = minetest.deserialize(meta:get_string("_is_withering")) + if legacy_invisible then + EF.invisibility[player] = legacy_invisible + meta:set_string("_is_invisible", "") + end + if legacy_poisoned then + EF.poison[player] = legacy_poisoned + meta:set_string("_is_poisoned", "") + end + if legacy_regenerating then + EF.regeneration[player] = legacy_regenerating + meta:set_string("_is_regenerating", "") + end + if legacy_strong then + EF.strength[player] = legacy_strong + meta:set_string("_is_strong", "") + end + if legacy_weak then + EF.weakness[player] = legacy_weak + meta:set_string("_is_weak", "") + end + if legacy_water_breathing then + EF.water_breathing[player] = legacy_water_breating + meta:set_string("_is_water_breating", "") + end + if legacy_leaping then + EF.leaping[player] = legacy_leaping + meta:set_string("_is_leaping", "") + end + if legacy_swift then + EF.swiftness[player] = legacy_swift + meta:set_string("_is_swift", "") + end + if legacy_night_vision then + EF.night_vision[player] = legacy_night_vision + meta:set_string("_is_cat", "") + end + if legacy_fireproof then + EF.fire_resistance[player] = legacy_fireproof + meta:set_string("_is_fire_proof", "") + end + if legacy_bad_omen then + EF.bad_omen[player] = legacy_bad_omen + meta:set_string("_has_bad_omen", "") + end + if legacy_withering then + EF.withering[player] = legacy_withering + meta:set_string("_is_withering", "") end - if minetest.deserialize(meta:get_string("_is_poisoned")) then - EF.poisoned[player] = minetest.deserialize(meta:get_string("_is_poisoned")) + -- new API effects + on_load for loaded legacy effects + for name, effect in pairs(registered_effects) do + local loaded = minetest.deserialize(meta:get_string("mcl_potions:_EF_"..name)) + if loaded then + EF[name][player] = loaded + end + if EF[name][player] then -- this is needed because of legacy effects loaded separately + if effect.uses_factor and type(EF[name][player].factor) ~= "number" then + EF[name][player].factor = effect.level_to_factor(1) + end + if effect.on_load then + effect.on_load(player, EF[name][player].factor) + end + end end - - if minetest.deserialize(meta:get_string("_is_regenerating")) then - EF.regenerating[player] = minetest.deserialize(meta:get_string("_is_regenerating")) - end - - if minetest.deserialize(meta:get_string("_is_strong")) then - EF.strong[player] = minetest.deserialize(meta:get_string("_is_strong")) - end - - if minetest.deserialize(meta:get_string("_is_weak")) then - EF.weak[player] = minetest.deserialize(meta:get_string("_is_weak")) - end - - if minetest.deserialize(meta:get_string("_is_water_breathing")) then - EF.water_breathing[player] = minetest.deserialize(meta:get_string("_is_water_breathing")) - end - - if minetest.deserialize(meta:get_string("_is_leaping")) then - EF.leaping[player] = minetest.deserialize(meta:get_string("_is_leaping")) - end - - if minetest.deserialize(meta:get_string("_is_swift")) then - EF.swift[player] = minetest.deserialize(meta:get_string("_is_swift")) - end - - if minetest.deserialize(meta:get_string("_is_cat")) then - EF.night_vision[player] = minetest.deserialize(meta:get_string("_is_cat")) - end - - if minetest.deserialize(meta:get_string("_is_fire_proof")) then - EF.fire_proof[player] = minetest.deserialize(meta:get_string("_is_fire_proof")) - end - - if minetest.deserialize(meta:get_string("_has_bad_omen")) then - EF.bad_omen[player] = minetest.deserialize(meta:get_string("_has_bad_omen")) - end - end --- Returns true if player has given effect -function mcl_potions.player_has_effect(player, effect_name) +function mcl_potions._load_entity_effects(entity) + if not entity or not entity._mcl_potions or entity._mcl_potions == {} then + return + end + local object = entity.object + if not object or not object:get_pos() then return end + for name, effect in pairs(registered_effects) do + local loaded = entity._mcl_potions["_EF_"..name] + if loaded then + EF[name][object] = loaded + if effect.uses_factor and not loaded.factor then + EF[name][object].factor = effect.level_to_factor(1) + end + if effect.on_load then + effect.on_load(object, EF[name][object].factor) + end + end + end +end + +-- Returns true if object has given effect +function mcl_potions.has_effect(object, effect_name) if not EF[effect_name] then return false end - return EF[effect_name][player] ~= nil + return EF[effect_name][object] ~= nil end -function mcl_potions.player_get_effect(player, effect_name) - if not EF[effect_name] or not EF[effect_name][player] then +function mcl_potions.get_effect(object, effect_name) + if not EF[effect_name] or not EF[effect_name][object] then return false end - return EF[effect_name][player] + return EF[effect_name][object] end -function mcl_potions.player_clear_effect(player,effect) - EF[effect][player] = nil - potions_set_icons(player) +function mcl_potions.get_effect_level(object, effect_name) + if not EF[effect_name] then return end + local effect = EF[effect_name][object] + if not effect then return 0 end + if not registered_effects[effect_name].uses_factor then return 1 end + return registered_effects[effect_name].factor_to_level(effect.factor) +end + +function mcl_potions.get_total_haste(object) + local accum_factor = 1 + for name, def in pairs(item_speed_effects) do + if EF[name][object] and not EF[name][object].blocked then + local factor = EF[name][object].factor + if def.factor_is_positive then factor = factor + 1 end + if factor > 1 then accum_factor = accum_factor * factor end + end + end + return accum_factor - 1 +end + +function mcl_potions.get_total_fatigue(object) + local accum_factor = 1 + for name, def in pairs(item_speed_effects) do + if EF[name][object] and not EF[name][object].blocked then + local factor = EF[name][object].factor + if def.factor_is_positive then factor = factor + 1 end + if factor <= 0 then return 0 end + if factor < 1 then accum_factor = accum_factor * factor end + end + end + return accum_factor +end + +function mcl_potions.clear_effect(object, effect) + if not EF[effect] then + minetest.log("warning", "[mcl_potions] Tried to remove an effect that is not registered: " .. dump(effect)) + return false + end + local def = registered_effects[effect] + if EF[effect][object] then + if def.on_end then def.on_end(object) end + EF[effect][object] = nil + if def.after_end then def.after_end(object) end + end + if not object:is_player() then return end + potions_set_hud(object) end minetest.register_on_leaveplayer( function(player) mcl_potions._save_player_effects(player) - mcl_potions._clear_cached_player_data(player) -- clearout the buffer to prevent looking for a player not there + mcl_potions._clear_cached_effect_data(player) -- clear the buffer to prevent looking for a player not there icon_ids[player:get_player_name()] = nil end) minetest.register_on_dieplayer( function(player) - mcl_potions._reset_player_effects(player) + mcl_potions._reset_effects(player) potions_set_hud(player) end) minetest.register_on_joinplayer( function(player) - mcl_potions._reset_player_effects(player, false) -- make sure there are no wierd holdover effects + mcl_potions._reset_effects(player, false) -- make sure there are no weird holdover effects mcl_potions._load_player_effects(player) + mcl_potions._reset_haste_fatigue_item_meta(player) potions_init_icons(player) - -- .after required because player:hud_change doesn't work when called - -- in same tick as player:hud_add - -- (see ) - -- FIXME: Remove minetest.after - minetest.after(3, function(player) - if player and player:is_player() then - potions_set_hud(player) - end - end, player) + potions_set_hud(player) end) minetest.register_on_shutdown(function() @@ -560,10 +1648,8 @@ minetest.register_on_shutdown(function() for _,player in pairs(minetest.get_connected_players()) do mcl_potions._save_player_effects(player) end - end) - -- ░██████╗██╗░░░██╗██████╗░██████╗░░█████╗░██████╗░████████╗██╗███╗░░██╗░██████╗░ -- ██╔════╝██║░░░██║██╔══██╗██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝██║████╗░██║██╔════╝░ -- ╚█████╗░██║░░░██║██████╔╝██████╔╝██║░░██║██████╔╝░░░██║░░░██║██╔██╗██║██║░░██╗░ @@ -612,16 +1698,16 @@ function mcl_potions.make_invisible(obj_ref, hide) else if hide then local luaentity = obj_ref:get_luaentity() - EF.invisible[obj_ref].old_size = luaentity.visual_size + EF.invisibility[obj_ref].old_size = luaentity.visual_size obj_ref:set_properties({ visual_size = { x = 0, y = 0 } }) else - obj_ref:set_properties({ visual_size = EF.invisible[obj_ref].old_size }) + obj_ref:set_properties({ visual_size = EF.invisibility[obj_ref].old_size }) end end end -function mcl_potions._use_potion(item, obj, color) +function mcl_potions._use_potion(obj, color) local d = 0.1 local pos = obj:get_pos() minetest.sound_play("mcl_potions_drinking", {pos = pos, max_hear_distance = 6, gain = 1}) @@ -690,16 +1776,97 @@ end -- ██║░░░░░╚██████╔╝██║░╚███║╚█████╔╝░░░██║░░░██║╚█████╔╝██║░╚███║██████╔╝ -- ╚═╝░░░░░░╚═════╝░╚═╝░░╚══╝░╚════╝░░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═════╝░ +local registered_res_predicates = {} +-- API +-- This is supposed to add custom resistance functions independent of effects +-- E.g. some entity could be resistant to all (or some) effects under specific conditions +-- predicate - function(object, effect_name) - return true if resists effect +function mcl_potions.register_generic_resistance_predicate(predicate) + if type(predicate) == "function" then + table.insert(registered_res_predicates, predicate) + else + error("Attempted to register non-function as a predicate") + end +end -function mcl_potions.healing_func(player, hp) +local function target_valid(object, name) + if not object or object:get_hp() <= 0 then return false end - local obj = player:get_luaentity() - - if player:get_hp() == 0 then - return + -- Don't apply effects to anything other than players and entities that have mcl_potions support + -- but are not bosses + local entity = object:get_luaentity() + if not object:is_player() and (not entity or entity.is_boss or not entity._mcl_potions) then + return false end - if obj and obj.harmed_by_heal then hp = -hp end + -- Check resistances + for i=1, #registered_res_predicates do + if registered_res_predicates[i](object, name) then return false end + end + + if not (registered_effects[name].res_condition + and registered_effects[name].res_condition(object)) then return true end +end + +function mcl_potions.give_effect(name, object, factor, duration, no_particles) + local edef = registered_effects[name] + if not edef or not target_valid(object, name) then return false end + if not EF[name][object] then + local vals = {dur = duration, timer = 0, no_particles = no_particles} + if edef.uses_factor then vals.factor = factor end + if edef.on_hit_timer then + if edef.timer_uses_factor then vals.step = factor + else vals.step = edef.hit_timer_step end + end + if duration == "INF" then + vals.dur = math.huge + end + EF[name][object] = vals + if edef.on_start then edef.on_start(object, factor) end + else + local present = EF[name][object] + present.no_particles = no_particles + if not edef.uses_factor or (edef.uses_factor and + (not edef.inv_factor and factor >= present.factor + or edef.inv_factor and factor <= present.factor)) then + present.dur = math.max(duration, present.dur - present.timer) + present.timer = 0 + if edef.uses_factor then + present.factor = factor + if edef.timer_uses_factor then present.step = factor end + if edef.on_start then edef.on_start(object, factor) end + end + if duration == "INF" then + present.dur = math.huge + end + else + return false + end + end + + if object:is_player() then potions_set_hud(object) end + + return true +end + +function mcl_potions.give_effect_by_level(name, object, level, duration, no_particles) + if level == 0 then return false end + if not registered_effects[name] then + minetest.log("warning", "[mcl_potions] Trying to give unknown effect "..tostring(name)) + return false + end + if not registered_effects[name].uses_factor then + return mcl_potions.give_effect(name, object, 0, duration, no_particles) + end + local factor = registered_effects[name].level_to_factor(level) + return mcl_potions.give_effect(name, object, factor, duration, no_particles) +end + +function mcl_potions.healing_func(object, hp) + if not object or object:get_hp() <= 0 then return false end + local ent = object:get_luaentity() + + if ent and ent.harmed_by_heal then hp = -hp end if hp > 0 then -- at least 1 HP @@ -707,10 +1874,10 @@ function mcl_potions.healing_func(player, hp) hp = 1 end - if obj and obj.is_mob then - obj.health = math.max(obj.health + hp, obj.hp_max) - elseif player:is_player() then - player:set_hp(math.min(player:get_hp() + hp, player:get_properties().hp_max), { type = "set_hp", other = "healing" }) + if ent and ent.is_mob then + ent.health = math.min(ent.health + hp, ent.hp_max) + elseif object:is_player() then + object:set_hp(math.min(object:get_hp() + hp, object:get_properties().hp_max), { type = "set_hp", other = "healing" }) end elseif hp < 0 then @@ -718,258 +1885,63 @@ function mcl_potions.healing_func(player, hp) hp = -1 end - mcl_util.deal_damage(player, -hp, {type = "magic"}) + mcl_util.deal_damage(object, -hp, {type = "magic"}) end - end -function mcl_potions.swiftness_func(player, factor, duration) - - if not player:get_meta() then - return false - end - - if not EF.swift[player] then - - EF.swift[player] = {dur = duration, timer = 0, is_slow = factor < 1} - playerphysics.add_physics_factor(player, "speed", "mcl_potions:swiftness", factor) - - else - - local victim = EF.swift[player] - - playerphysics.add_physics_factor(player, "speed", "mcl_potions:swiftness", factor) - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - victim.is_slow = factor < 1 - - end - - if player:is_player() then - potions_set_icons(player) - end - +function mcl_potions.strength_func(object, factor, duration) + return mcl_potions.give_effect("strength", object, factor, duration) +end +function mcl_potions.leaping_func(object, factor, duration) + return mcl_potions.give_effect("leaping", object, factor, duration) +end +function mcl_potions.weakness_func(object, factor, duration) + return mcl_potions.give_effect("weakness", object, factor, duration) +end +function mcl_potions.swiftness_func(object, factor, duration) + return mcl_potions.give_effect("swiftness", object, factor, duration) +end +function mcl_potions.slowness_func(object, factor, duration) + return mcl_potions.give_effect("slowness", object, factor, duration) end -function mcl_potions.leaping_func(player, factor, duration) - - if not player:get_meta() then - return false - end - - if not EF.leaping[player] then - - EF.leaping[player] = {dur = duration, timer = 0} - playerphysics.add_physics_factor(player, "jump", "mcl_potions:leaping", factor) - - else - - local victim = EF.leaping[player] - - playerphysics.add_physics_factor(player, "jump", "mcl_potions:leaping", factor) - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - +function mcl_potions.withering_func(object, factor, duration) + return mcl_potions.give_effect("withering", object, factor, duration) end -function mcl_potions.weakness_func(player, factor, duration) - - if not EF.weak[player] then - - EF.weak[player] = {dur = duration, timer = 0, factor = factor} - - else - - local victim = EF.weak[player] - - victim.factor = factor - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - +function mcl_potions.poison_func(object, factor, duration) + return mcl_potions.give_effect("poison", object, factor, duration) end -function mcl_potions.strength_func(player, factor, duration) - - if not EF.strong[player] then - - EF.strong[player] = {dur = duration, timer = 0, factor = factor} - - else - - local victim = EF.strong[player] - - victim.factor = factor - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - +function mcl_potions.regeneration_func(object, factor, duration) + return mcl_potions.give_effect("regeneration", object, factor, duration) end -function mcl_potions.poison_func(player, factor, duration) - - if not EF.poisoned[player] then - - EF.poisoned[player] = {step = factor, dur = duration, timer = 0} - - else - - local victim = EF.poisoned[player] - - victim.step = math.min(victim.step, factor) - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_hud(player) - end +function mcl_potions.invisiblility_func(object, null, duration) + return mcl_potions.give_effect("invisibility", object, null, duration) +end +function mcl_potions.water_breathing_func(object, null, duration) + return mcl_potions.give_effect("water_breathing", object, null, duration) end -function mcl_potions.regeneration_func(player, factor, duration) - - if not EF.regenerating[player] then - - EF.regenerating[player] = {step = factor, dur = duration, timer = 0} - - else - - local victim = EF.regenerating[player] - - victim.step = math.min(victim.step, factor) - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_hud(player) - end - +function mcl_potions.fire_resistance_func(object, null, duration) + return mcl_potions.give_effect("fire_resistance", object, null, duration) end -function mcl_potions.invisiblility_func(player, null, duration) - - if not EF.invisible[player] then - - EF.invisible[player] = {dur = duration, timer = 0} - mcl_potions.make_invisible(player, true) - - else - - local victim = EF.invisible[player] - - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - -end - -function mcl_potions.water_breathing_func(player, null, duration) - - if not EF.water_breathing[player] then - - EF.water_breathing[player] = {dur = duration, timer = 0} - - else - - local victim = EF.water_breathing[player] - - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - -end - - -function mcl_potions.fire_resistance_func(player, null, duration) - - if not EF.fire_proof[player] then - - EF.fire_proof[player] = {dur = duration, timer = 0} - - else - - local victim = EF.fire_proof[player] - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - if player:is_player() then - potions_set_icons(player) - end - -end - - -function mcl_potions.night_vision_func(player, null, duration) - - meta = player:get_meta() - if not EF.night_vision[player] then - - EF.night_vision[player] = {dur = duration, timer = 0} - - else - - local victim = EF.night_vision[player] - - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - - end - - is_player = player:is_player() - if is_player then - meta:set_int("night_vision", 1) - else - return -- Do not attempt to set night_vision on mobs - end - mcl_weather.skycolor.update_sky_color({player}) - - if player:is_player() then - potions_set_icons(player) - end - +function mcl_potions.night_vision_func(object, null, duration) + return mcl_potions.give_effect("night_vision", object, null, duration) end function mcl_potions._extinguish_nearby_fire(pos, radius) local epos = {x=pos.x, y=pos.y+0.5, z=pos.z} local dnode = minetest.get_node({x=pos.x,y=pos.y-0.5,z=pos.z}) - if minetest.get_item_group(dnode.name, "fire") ~= 0 then + if minetest.get_item_group(dnode.name, "fire") ~= 0 or minetest.get_item_group(dnode.name, "lit_campfire") ~= 0 then epos.y = pos.y - 0.5 end local exting = false @@ -989,6 +1961,11 @@ function mcl_potions._extinguish_nearby_fire(pos, radius) minetest.sound_play("fire_extinguish_flame", {pos = tpos, gain = 0.25, max_hear_distance = 16}, true) minetest.remove_node(tpos) exting = true + elseif minetest.get_item_group(node.name, "lit_campfire") ~= 0 then + minetest.sound_play("fire_extinguish_flame", {pos = tpos, gain = 0.25, max_hear_distance = 16}, true) + local def = minetest.registered_nodes[node.name] + minetest.set_node(tpos, {name = def._mcl_campfires_smothered_form, param2 = node.param2}) + exting = true end end -- Has radius: lingering, extinguish all nodes in area @@ -996,27 +1973,22 @@ function mcl_potions._extinguish_nearby_fire(pos, radius) local nodes = minetest.find_nodes_in_area( {x=epos.x-radius,y=epos.y,z=epos.z-radius}, {x=epos.x+radius,y=epos.y,z=epos.z+radius}, - {"group:fire"}) + {"group:fire", "group:lit_campfire"}) for n=1, #nodes do + local node = minetest.get_node(nodes[n]) minetest.sound_play("fire_extinguish_flame", {pos = nodes[n], gain = 0.25, max_hear_distance = 16}, true) - minetest.remove_node(nodes[n]) + if minetest.get_item_group(node.name, "fire") ~= 0 then + minetest.remove_node(nodes[n]) + elseif minetest.get_item_group(node.name, "lit_campfire") ~= 0 then + local def = minetest.registered_nodes[node.name] + minetest.set_node(nodes[n], {name = def._mcl_campfires_smothered_form, param2 = node.param2}) + end exting = true end end return exting end -function mcl_potions.bad_omen_func(player, factor, duration) - if not EF.bad_omen[player] then - EF.bad_omen[player] = {dur = duration, timer = 0, factor = factor} - else - local victim = EF.bad_omen[player] - victim.dur = math.max(duration, victim.dur - victim.timer) - victim.timer = 0 - victim.factor = factor - end - - if player:is_player() then - potions_set_icons(player) - end +function mcl_potions.bad_omen_func(object, factor, duration) + mcl_potions.give_effect("bad_omen", object, factor, duration) end diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index 2ea7e2879..446f6ef16 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -8,14 +8,18 @@ mcl_potions = {} -- duration effects of glowstone are a time factor of 1/2 -- splash potion duration effects are reduced by a factor of 3/4 -mcl_potions.II_FACTOR = 2 +mcl_potions.POTENT_FACTOR = 2 mcl_potions.PLUS_FACTOR = 8/3 +mcl_potions.INV_FACTOR = 0.50 mcl_potions.DURATION = 180 -mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR -mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR +mcl_potions.DURATION_INV = mcl_potions.DURATION * mcl_potions.INV_FACTOR +mcl_potions.DURATION_POISON = 45 + +mcl_potions.II_FACTOR = mcl_potions.POTENT_FACTOR -- TODO remove at some point +mcl_potions.DURATION_PLUS = mcl_potions.DURATION * mcl_potions.PLUS_FACTOR -- TODO remove at some point +mcl_potions.DURATION_2 = mcl_potions.DURATION / mcl_potions.II_FACTOR -- TODO remove at some point -mcl_potions.INV_FACTOR = 0.50 mcl_potions.SPLASH_FACTOR = 0.75 mcl_potions.LINGERING_FACTOR = 0.25 @@ -25,6 +29,7 @@ dofile(modpath .. "/splash.lua") dofile(modpath .. "/lingering.lua") dofile(modpath .. "/tipped_arrow.lua") dofile(modpath .. "/potions.lua") +local potions = mcl_potions.registered_potions minetest.register_craftitem("mcl_potions:fermented_spider_eye", { description = S("Fermented Spider Eye"), @@ -190,7 +195,7 @@ local function set_node_empty_bottle(itemstack, placer, pointed_thing, newitemst -- play sound minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - -- + -- if minetest.is_creative_enabled(placer:get_player_name()) then return itemstack else @@ -256,7 +261,7 @@ minetest.register_craftitem("mcl_potions:water", { stack_max = 1, inventory_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_dispense = dispense_water_bottle, _dispense_into_walkable = true, @@ -273,7 +278,7 @@ minetest.register_craftitem("mcl_potions:river_water", { stack_max = 1, inventory_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_dispense = dispense_water_bottle, _dispense_into_walkable = true, @@ -332,9 +337,28 @@ minetest.register_craft({ }) + +local output_table = { } + +-- API +-- registers a potion that can be combined with multiple ingredients for different outcomes +-- out_table contains the recipes for those outcomes +function mcl_potions.register_ingredient_potion(input, out_table) + if output_table[input] then + error("Attempt to register the same ingredient twice!") + end + if type(input) ~= "string" then + error("Invalid argument! input must be a string") + end + if type(out_table) ~= "table" then + error("Invalid argument! out_table must be a table") + end + output_table[input] = out_table +end + local water_table = { ["mcl_nether:nether_wart_item"] = "mcl_potions:awkward", - -- ["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness", + ["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness", ["mcl_potions:speckled_melon"] = "mcl_potions:mundane", ["mcl_core:sugar"] = "mcl_potions:mundane", ["mcl_mobitems:magma_cream"] = "mcl_potions:mundane", @@ -346,126 +370,284 @@ local water_table = { ["mcl_nether:glowstone_dust"] = "mcl_potions:thick", ["mcl_mobitems:gunpowder"] = "mcl_potions:water_splash" } +-- API +-- register a potion recipe brewed from water +function mcl_potions.register_water_brew(ingr, potion) + if water_table[ingr] then + error("Attempt to register the same ingredient twice!") + end + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") + end + if type(potion) ~= "string" then + error("Invalid argument! potion must be a string") + end + water_table[ingr] = potion +end +mcl_potions.register_ingredient_potion("mcl_potions:river_water", water_table) +mcl_potions.register_ingredient_potion("mcl_potions:water", water_table) local awkward_table = { ["mcl_potions:speckled_melon"] = "mcl_potions:healing", ["mcl_farming:carrot_item_gold"] = "mcl_potions:night_vision", ["mcl_core:sugar"] = "mcl_potions:swiftness", ["mcl_mobitems:magma_cream"] = "mcl_potions:fire_resistance", - -- ["mcl_mobitems:blaze_powder"] = "mcl_potions:strength", + ["mcl_mobitems:blaze_powder"] = "mcl_potions:strength", ["mcl_fishing:pufferfish_raw"] = "mcl_potions:water_breathing", ["mcl_mobitems:ghast_tear"] = "mcl_potions:regeneration", ["mcl_mobitems:spider_eye"] = "mcl_potions:poison", + ["mcl_flowers:wither_rose"] = "mcl_potions:withering", ["mcl_mobitems:rabbit_foot"] = "mcl_potions:leaping", + + ["mcl_flowers:fourleaf_clover"] = "mcl_potions:luck", + ["mcl_farming:potato_item_poison"] = "mcl_potions:nausea", + ["mcl_mobitems:spectre_membrane"] = "mcl_potions:slow_falling", + ["mcl_core:apple_gold"] = "mcl_potions:resistance", + ["mcl_mobitems:aery_charge"] = "mcl_potions:haste", + ["mcl_mobitems:crystalline_drop"] = "mcl_potions:absorption", + ["mcl_mobitems:earthen_ash"] = "mcl_potions:stone_cloak", + ["mcl_mobitems:shiny_ice_crystal"] = "mcl_potions:frost", + + -- TODO darkness - sculk? } +-- API +-- register a potion recipe brewed from awkward potion +function mcl_potions.register_awkward_brew(ingr, potion) + if awkward_table[ingr] then + error("Attempt to register the same ingredient twice!") + end + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") + end + if type(potion) ~= "string" then + error("Invalid argument! potion must be a string") + end + awkward_table[ingr] = potion +end +mcl_potions.register_ingredient_potion("mcl_potions:awkward", awkward_table) -local output_table = { - ["mcl_potions:river_water"] = water_table, - ["mcl_potions:water"] = water_table, - ["mcl_potions:awkward"] = awkward_table, +local mundane_table = { + ["mcl_potions:fermented_spider_eye"] = "mcl_potions:weakness", } - - -local enhancement_table = {} -local extension_table = {} -local potions = {} - -for i, potion in ipairs({"healing","harming","swiftness","slowness", - "leaping","poison","regeneration","invisibility","fire_resistance", - -- "weakness","strength", - "water_breathing","night_vision"}) do - - table.insert(potions, potion) - - if potion ~= "invisibility" and potion ~= "night_vision" and potion ~= "weakness" and potion ~= "water_breathing" and potion ~= "fire_resistance" then - enhancement_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_2" - enhancement_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_2_splash" - table.insert(potions, potion.."_2") +-- API +-- register a potion recipe brewed from mundane potion +function mcl_potions.register_mundane_brew(ingr, potion) + if mundane_table[ingr] then + error("Attempt to register the same ingredient twice!") end - - if potion ~= "healing" and potion ~= "harming" then - extension_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_plus_splash" - extension_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_plus" - table.insert(potions, potion.."_plus") + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") end - + if type(potion) ~= "string" then + error("Invalid argument! potion must be a string") + end + mundane_table[ingr] = potion end +mcl_potions.register_ingredient_potion("mcl_potions:mundane", mundane_table) -for i, potion in ipairs({"awkward", "mundane", "thick", "water"}) do - table.insert(potions, potion) +local thick_table = { + ["mcl_crimson:shroomlight"] = "mcl_potions:glowing", + ["mcl_mobitems:nether_star"] = "mcl_potions:ominous", + ["mcl_mobitems:ink_sac"] = "mcl_potions:blindness", + ["mcl_farming:carrot_item_gold"] = "mcl_potions:saturation", +} +-- API +-- register a potion recipe brewed from thick potion +function mcl_potions.register_thick_brew(ingr, potion) + if thick_table[ingr] then + error("Attempt to register the same ingredient twice!") + end + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") + end + if type(potion) ~= "string" then + error("Invalid argument! potion must be a string") + end + thick_table[ingr] = potion end +mcl_potions.register_ingredient_potion("mcl_potions:thick", thick_table) +local mod_table = { } + +-- API +-- registers a brewing recipe altering the potion using a table +-- this is supposed to substitute one item with another +function mcl_potions.register_table_modifier(ingr, modifier) + if mod_table[ingr] then + error("Attempt to register the same ingredient twice!") + end + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") + end + if type(modifier) ~= "table" then + error("Invalid argument! modifier must be a table") + end + mod_table[ingr] = modifier +end + local inversion_table = { ["mcl_potions:healing"] = "mcl_potions:harming", - ["mcl_potions:healing_2"] = "mcl_potions:harming_2", ["mcl_potions:swiftness"] = "mcl_potions:slowness", - ["mcl_potions:swiftness_plus"] = "mcl_potions:slowness_plus", ["mcl_potions:leaping"] = "mcl_potions:slowness", - ["mcl_potions:leaping_plus"] = "mcl_potions:slowness_plus", ["mcl_potions:night_vision"] = "mcl_potions:invisibility", - ["mcl_potions:night_vision_plus"] = "mcl_potions:invisibility_plus", ["mcl_potions:poison"] = "mcl_potions:harming", - ["mcl_potions:poison_2"] = "mcl_potions:harming_2", - ["mcl_potions:healing_splash"] = "mcl_potions:harming_splash", - ["mcl_potions:healing_2_splash"] = "mcl_potions:harming_2_splash", - ["mcl_potions:swiftness_splash"] = "mcl_potions:slowness_splash", - ["mcl_potions:swiftness_plus_splash"] = "mcl_potions:slowness_plus_splash", - ["mcl_potions:leaping_splash"] = "mcl_potions:slowness_splash", - ["mcl_potions:leaping_plus_splash"] = "mcl_potions:slowness_plus_splash", - ["mcl_potions:night_vision_splash"] = "mcl_potions:invisibility_splash", - ["mcl_potions:night_vision_plus_splash"] = "mcl_potions:invisibility_plus_splash", - ["mcl_potions:poison_splash"] = "mcl_potions:harming_splash", - ["mcl_potions:poison_2_splash"] = "mcl_potions:harming_2_splash", + ["mcl_potions:luck"] = "mcl_potions:bad_luck", + ["mcl_potions:haste"] = "mcl_potions:fatigue", + ["mcl_potions:saturation"] = "mcl_potions:food_poisoning", + ["mcl_potions:slow_falling"] = "mcl_potions:levitation", + ["mcl_potions:absorption"] = "mcl_potions:health_boost", + ["mcl_potions:glowing"] = "mcl_potions:darkness", -- TODO remove after adding a direct recipe? } - +-- API +function mcl_potions.register_inversion_recipe(input, output) + if inversion_table[input] then + error("Attempt to register the same input twice!") + end + if type(input) ~= "string" then + error("Invalid argument! input must be a string") + end + if type(output) ~= "string" then + error("Invalid argument! output must be a string") + end + inversion_table[input] = output +end +local function fill_inversion_table() -- autofills with splash and lingering inversion recipes + local filling_table = { } + for input, output in pairs(inversion_table) do + if potions[input].has_splash and potions[output].has_splash then + filling_table[input.."_splash"] = output .. "_splash" + if potions[input].has_lingering and potions[output].has_lingering then + filling_table[input.."_lingering"] = output .. "_lingering" + end + end + end + table.update(inversion_table, filling_table) + mcl_potions.register_table_modifier("mcl_potions:fermented_spider_eye", inversion_table) +end +minetest.register_on_mods_loaded(fill_inversion_table) local splash_table = {} local lingering_table = {} +for potion, def in pairs(potions) do + if def.has_splash then + splash_table[potion] = potion.."_splash" + if def.has_lingering then + lingering_table[potion.."_splash"] = potion.."_lingering" + end + end +end +mcl_potions.register_table_modifier("mcl_mobitems:gunpowder", splash_table) +mcl_potions.register_table_modifier("mcl_potions:dragon_breath", lingering_table) -for i, potion in ipairs(potions) do - splash_table["mcl_potions:"..potion] = "mcl_potions:"..potion.."_splash" - lingering_table["mcl_potions:"..potion.."_splash"] = "mcl_potions:"..potion.."_lingering" + +local meta_mod_table = { } + +-- API +-- registers a brewing recipe altering the potion using a function +-- this is supposed to be a recipe that changes metadata only +function mcl_potions.register_meta_modifier(ingr, mod_func) + if meta_mod_table[ingr] then + error("Attempt to register the same ingredient twice!") + end + if type(ingr) ~= "string" then + error("Invalid argument! ingr must be a string") + end + if type(mod_func) ~= "function" then + error("Invalid argument! mod_func must be a function") + end + meta_mod_table[ingr] = mod_func end +local function extend_dur(potionstack) + local def = potions[potionstack:get_name()] + if not def then return false end + if not def.has_plus then return false end -- bail out if can't be extended + local potionstack = ItemStack(potionstack) + local meta = potionstack:get_meta() + local potent = meta:get_int("mcl_potions:potion_potent") + local plus = meta:get_int("mcl_potions:potion_plus") + if plus == 0 then + if potent ~= 0 then + meta:set_int("mcl_potions:potion_potent", 0) + end + meta:set_int("mcl_potions:potion_plus", def._default_extend_level) + tt.reload_itemstack_description(potionstack) + return potionstack + end + return false +end +mcl_potions.register_meta_modifier("mesecons:wire_00000000_off", extend_dur) -local mod_table = { - ["mesecons:wire_00000000_off"] = extension_table, - ["mcl_potions:fermented_spider_eye"] = inversion_table, - ["mcl_nether:glowstone_dust"] = enhancement_table, - ["mcl_mobitems:gunpowder"] = splash_table, - ["mcl_potions:dragon_breath"] = lingering_table, -} +local function enhance_pow(potionstack) + local def = potions[potionstack:get_name()] + if not def then return false end + if not def.has_potent then return false end -- bail out if has no potent variant + local potionstack = ItemStack(potionstack) + local meta = potionstack:get_meta() + local potent = meta:get_int("mcl_potions:potion_potent") + local plus = meta:get_int("mcl_potions:potion_plus") + if potent == 0 then + if plus ~= 0 then + meta:set_int("mcl_potions:potion_plus", 0) + end + meta:set_int("mcl_potions:potion_potent", def._default_potent_level-1) + tt.reload_itemstack_description(potionstack) + return potionstack + end + return false +end +mcl_potions.register_meta_modifier("mcl_nether:glowstone_dust", enhance_pow) --- Compare two ingredients for compatable alchemy + +-- Find an alchemical recipe for given ingredient and potion +-- returns outcome function mcl_potions.get_alchemy(ingr, pot) - if output_table[pot] then + local brew_selector = output_table[pot:get_name()] + if brew_selector and brew_selector[ingr] then + local meta = pot:get_meta():to_table() + local alchemy = ItemStack(brew_selector[ingr]) + local metaref = alchemy:get_meta() + metaref:from_table(meta) + tt.reload_itemstack_description(alchemy) + return alchemy + end - local brew_table = output_table[pot] - - if brew_table[ingr] then - return brew_table[ingr] + brew_selector = mod_table[ingr] + if brew_selector then + local brew = brew_selector[pot:get_name()] + if brew then + local meta = pot:get_meta():to_table() + local alchemy = ItemStack(brew) + local metaref = alchemy:get_meta() + metaref:from_table(meta) + tt.reload_itemstack_description(alchemy) + return alchemy end end - if mod_table[ingr] then - - local brew_table = mod_table[ingr] - - if brew_table[pot] then - return brew_table[pot] - end - + if meta_mod_table[ingr] then + local brew_func = meta_mod_table[ingr] + if brew_func then return brew_func(pot) end end return false end +-- give withering to players in a wither rose +local etime = 0 +minetest.register_globalstep(function(dtime) + etime = dtime + etime + if etime < 0.5 then return end + etime = 0 + for _,pl in pairs(minetest.get_connected_players()) do + local npos = vector.offset(pl:get_pos(), 0, 0.2, 0) + local n = minetest.get_node(npos) + if n.name == "mcl_flowers:wither_rose" then mcl_potions.withering_func(pl, 1, 2) end + end +end) + mcl_wip.register_wip_item("mcl_potions:night_vision") -mcl_wip.register_wip_item("mcl_potions:night_vision_plus") mcl_wip.register_wip_item("mcl_potions:night_vision_splash") -mcl_wip.register_wip_item("mcl_potions:night_vision_plus_splash") mcl_wip.register_wip_item("mcl_potions:night_vision_lingering") -mcl_wip.register_wip_item("mcl_potions:night_vision_plus_lingering") mcl_wip.register_wip_item("mcl_potions:night_vision_arrow") -mcl_wip.register_wip_item("mcl_potions:night_vision_plus_arrow") \ No newline at end of file diff --git a/mods/ITEMS/mcl_potions/lingering.lua b/mods/ITEMS/mcl_potions/lingering.lua index 17088ad13..20ed84850 100644 --- a/mods/ITEMS/mcl_potions/lingering.lua +++ b/mods/ITEMS/mcl_potions/lingering.lua @@ -11,8 +11,8 @@ end local lingering_effect_at = {} -local function add_lingering_effect(pos, color, def, is_water, instant) - lingering_effect_at[pos] = {color = color, timer = 30, def = def, is_water = is_water} +local function add_lingering_effect(pos, color, def, is_water, potency, plus) + lingering_effect_at[pos] = {color = color, timer = 30, def = def, is_water = is_water, potency = potency, plus = plus} end local function linger_particles(pos, d, texture, color) @@ -55,23 +55,56 @@ minetest.register_globalstep(function(dtime) end linger_particles(pos, d, texture, vals.color) - -- Extinguish fire if water bottle - if vals.is_water then - if mcl_potions._extinguish_nearby_fire(pos, d) then - vals.timer = vals.timer - 3.25 - end +-- -- Extinguish fire if water bottle +-- if vals.is_water then +-- if mcl_potions._extinguish_nearby_fire(pos, d) then +-- vals.timer = vals.timer - 3.25 +-- end +-- end + + if vals.def.while_lingering and vals.def.while_lingering(pos, d, vals.potency+1) then + vals.timer = vals.timer - 3.25 end -- Affect players and mobs for _, obj in pairs(minetest.get_objects_inside_radius(pos, d)) do local entity = obj:get_luaentity() - if obj:is_player() or entity.is_mob then + if obj:is_player() or entity and entity.is_mob then + local applied = false + if vals.def._effect_list then + local ef_level + local dur + for name, details in pairs(vals.def._effect_list) do + if details.uses_level then + ef_level = details.level + details.level_scaling * (vals.potency) + else + ef_level = details.level + end + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, vals.plus) + if vals.potency>0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, vals.potency) + end + dur = dur * mcl_potions.LINGERING_FACTOR + else + dur = details.dur + end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end + if mcl_potions.give_effect_by_level(name, obj, ef_level, dur) then + applied = true + end + end + end - vals.def.potion_fun(obj) - -- TODO: Apply timer penalty only if the potion effect was acutally applied - vals.timer = vals.timer - 3.25 + if vals.def.custom_effect + and vals.def.custom_effect(obj, (vals.potency+1) * mcl_potions.LINGERING_FACTOR, plus) then + applied = true + end + if applied then vals.timer = vals.timer - 3.25 end end end @@ -87,31 +120,44 @@ end) function mcl_potions.register_lingering(name, descr, color, def) - local id = "mcl_potions:"..name.."_lingering" - local longdesc = def.longdesc + local longdesc = def._longdesc if not def.no_effect then - longdesc = S("A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.") + longdesc = S("A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect or set of effects, possibly repeatedly.") if def.longdesc then - longdesc = longdesc .. "\n" .. def.longdesc + longdesc = longdesc .. "\n" .. def._longdesc end end + local groups = {brewitem=1, bottle=1, ling_potion=1, _mcl_potion=1} + if def.nocreative then groups.not_in_creative_inventory = 1 end minetest.register_craftitem(id, { description = descr, - _tt_help = def.tt, + _tt_help = def._tt, + _dynamic_tt = def._dynamic_tt, _doc_items_longdesc = longdesc, _doc_items_usagehelp = S("Use the “Punch” key to throw it."), + stack_max = def.stack_max, + _effect_list = def._effect_list, + uses_level = def.uses_level, + has_potent = def.has_potent, + has_plus = def.has_plus, + _default_potent_level = def._default_potent_level, + _default_extend_level = def._default_extend_level, inventory_image = lingering_image(color), - groups = {brewitem=1, not_in_creative_inventory=0}, + groups = groups, on_use = function(item, placer, pointed_thing) local velocity = 10 local dir = placer:get_look_dir(); local pos = placer:getpos(); minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying") - obj:setvelocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity}) - obj:setacceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3}) - obj:get_luaentity()._thrower = placer:get_player_name() + obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity}) + obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3}) + local ent = obj:get_luaentity() + ent._thrower = placer:get_player_name() + ent._potency = item:get_meta():get_int("mcl_potions:potion_potent") + ent._plus = item:get_meta():get_int("mcl_potions:potion_plus") + ent._effect_list = def._effect_list if not minetest.is_creative_enabled(placer:get_player_name()) then item:take_item() end @@ -126,6 +172,10 @@ function mcl_potions.register_lingering(name, descr, color, def) local velocity = 22 obj:set_velocity({x=dropdir.x*velocity,y=dropdir.y*velocity,z=dropdir.z*velocity}) obj:set_acceleration({x=dropdir.x*-3, y=-9.8, z=dropdir.z*-3}) + local ent = obj:get_luaentity() + ent._potency = stack:get_meta():get_int("mcl_potions:potion_potent") + ent._plus = stack:get_meta():get_int("mcl_potions:potion_plus") + ent._effect_list = def._effect_list end }) @@ -148,7 +198,9 @@ function mcl_potions.register_lingering(name, descr, color, def) end if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and g == 0 or mcl_potions.is_obj_hit(self, pos) then minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) - add_lingering_effect(pos, color, def, name == "water") + local potency = self._potency or 0 + local plus = self._plus or 0 + add_lingering_effect(pos, color, def, name == "water", potency, plus) local texture if name == "water" then texture = "mcl_particles_droplet_bottle.png" @@ -160,9 +212,7 @@ function mcl_potions.register_lingering(name, descr, color, def) end end linger_particles(pos, d, texture, color) - if name == "water" then - mcl_potions._extinguish_nearby_fire(pos, d) - end + if def.on_splash then def.on_splash(pos, potency+1) end self.object:remove() end end, diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr index 1547a36c0..a9106e92a 100644 --- a/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr @@ -1,27 +1,283 @@ # textdomain: mcl_potions - []= [] +Invisibility=Invisibilité +body is invisible=le corps est invisible -Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)=Ajoutez-vous un effet de statut. Arguments: : nom de l'effet de statut, par ex. poison. : durée en secondes. : multiplicateur de force d'effet (1 @ = 100%) +Poison=Poison +-1 HP / @1 s=-1 PV / @1 s + +Regeneration=Régénération ++1 HP / @1 s=+1 PV / @1 s + +Strength=Force ++@1% melee damage=+@1% dégâts de mêlée + +Weakness=Faiblesse +-@1% melee damage=-@1% dégâts de mêlée + +Water Breathing=Respiration aquatique +limitless breathing under water=respiration illimitée sous l'eau + +Dolphin's Grace=Grâce du dauphin +swimming gracefully=nage gracieuse + +Leaping=Saut ++@1% jumping power=+@1% puissance de saut +-@1% jumping power=-@1% puissance de saut + +Slow Falling=Chute lente +decreases gravity effects=diminue les effets de la gravité + +Swiftness=Rapidité ++@1% running speed=+@1% vitesse de course + +Slowness=Lenteur +-@1% running speed=-@1% vitesse de course + +Levitation=Lévitation +moves body upwards at @1 nodes/s=déplace le corps vers le haut à @1 nœuds/s + +Night Vision=Vision nocturne +improved vision during the night=améliore la vision durant la nuit + +Darkness=Obscurité +surrounded by darkness=entouré d'obscurité +not seeing anything beyond @1 nodes=ne vois rien au-delà de @1 nœuds + +Glowing=Surbrillance +more visible at all times=plus visible en permanence + +Health Boost=Bonus de santé +HP increased by @1=PV augmentés de @1 + +Absorption=Absorption +absorbs up to @1 incoming damage=absorbe jusqu'à @1 dégâts reçus + +Fire Resistance=Résistance au feu +resistance to fire damage=resistance aux dégâts du feu + +Resistance=Résistance +resist @1% of incoming damage=résiste à @1% des dégâts reçus + +Luck=Chance + +Bad Luck=Malchance + +Bad Omen=Mauvais présage +danger is imminent=un danger est imminent + +Hero of the Village=Héros du village + +Withering=Dépérissement +-1 HP / @1 s, can kill=-1 PV / @1 s, peut tuer + +Frost=Gel +-1 HP / 1 s, can kill, -@1% running speed=-1 PV / @1 s, peut tuer, -@1% vitesse de course + +Blindness=Cécité +impaired sight=déficience visuelle + +Nausea=Nausée +not feeling very well...=ne se sent pas très bien +frequency: @1 / 1 s=fréquence : @1 / 1 s + +Food Poisoning=Intoxication alimentaire +exhausts by @1 per second=s'épuise de @1 par seconde + +Saturation=Saturation +saturates by @1 per second=sature de @1 par seconde + +Haste=Célérité ++@1% mining and attack speed=+@1% de vitesse d'attaque et de minage + +Fatigue=Fatigue +-@1% mining and attack speed=-@1% de vitesse d'attaque et de minage + +Conduit Power=Force de conduit ++@1% mining and attack speed in water=+@1% de vitesse d'attaque et de minage sous l'eau + + +|heal|list|clear|remove |INF [] [] [NOPART]=|heal|list|clear|remove |INF [] [] [NOPART] + +Add a status effect to yourself. Arguments: : name of status effect. Passing "list" as effect name lists available effects. Passing "heal" as effect name heals (or harms) by amount designed by the next parameter. Passing "clear" as effect name removes all effects. Passing "remove" as effect name removes the effect named by the next parameter. : duration in seconds. Passing "INF" as duration makes the effect infinite. (: amount of healing when the effect is "heal", passing a negative value subtracts health. : name of a status effect to be removed when using "remove" as the previous parameter.) : effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. : effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect.=Ajoute un effet de statut à vous-même. Arguments : : nom de l'effet de statut. Utiliser "list" comme nom d'effet liste les effets disponibles. Utiliser "heal" comme nom d'effet soigne (ou blesse) d'un nombre défini par le paramètre suivant. Utiliser "clear" comme nom d'effet enleve tous les effets. Utiliser "remove" comme nom d'effet enlève l'effet nommé dans le paramètre suivant. : durée en secondes. Utiliser "INF" comme durée rends l'effet infini. ( : quantité de soin lorsque l'effet est "heal", utiliser une valeur négative enlève de la santé. : nom de l'effet de statut à enlever lors de l'utilisation de "remove" comme paramètre précédent.) : détermine la puissance de l'effet, un niveau plus élevé se traduit par un effet plus puissant pour les effets qui dépendent du niveau (aucun changement pour les autres effets), défaut à 1, utiliser F pour utiliser un facteur de bas niveau à la place. : effet modificateur de force, peut avoir différentes significations en fonction de l'effet, pas de changement pour les effets qui ne dépendent pas du niveau/facteur. NOPART à la fin signifie qu'aucune particule ne sera affichée pour cet effet. + +Missing effect parameter!=Paramètre d'effet manquant ! +Missing or invalid heal amount parameter!=Paramètre de quantité de soin manquant ou invalide ! +Player @1 healed by @2 HP.=Joueur @1 soigné de @2 PV. +Player @1 harmed by @2 HP.=Joueur @1 blessé de @2 PV. +Effects cleared for player @1=Effets effacés pour le joueur @1 +Removed effect @1 from player @2=Effet @1 enlevé pour le joueur @2 +@1 is not an available status effect.=@1 n'est pas un effet de statut disponible. +Missing or invalid duration parameter!=Paramètre de durée manquant ou invalide ! +Invalid level parameter!=Paramètre de niveau invalide ! +Missing or invalid factor parameter when level is F!=Paramètre de facteur manquant ou invalide quand le niveau est F! + +@1 effect given to player @2 for @3 seconds with factor of @4.=Effet @1 donné au joueur @2 pour @3 seconds avec un facteur de @4. +@1 effect given to player @2 for @3 seconds.=Effet @1 donné au joueur @2 pour @3 seconds. +Giving effect @1 to player @2 failed.=L'attribution de l'effet @1 au joueur @2 a échoué. +@1 effect on level @2 given to player @3 for @4 seconds.=Effet @1 de niveau @2 donné au joueur @3 pendant @4 secondes. + + +A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.=Une potion jetable qui se brisera à l'impact, où elle donne à tous les joueurs et créatures proches un effet de statut ou un ensemble d'effets de statut. +Use the “Punch” key to throw it.=Utilisez la touche "Frapper" pour la lancer. + + +A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect or set of effects, possibly repeatedly.=Une potion jetable qui se brisera à l'impact, où elle crée un nuage magique qui persiste pendant un moment. Tout joueur ou mob à l'intérieur du nuage recevra l'effet de la potion ou un ensemble d'effets, peut-être à plusieurs reprises. + + +This particular arrow is tipped and will give an effect when it hits a player or mob.=Cette flèche particulière est enchantée et donnera un effet lorsqu'elle touche un joueur ou un mob. + + +Use the “Place” key to drink it.=Utilisez la touche "Utiliser" pour la boire. +Drinking a potion gives you a particular effect or set of effects.=Boire une potion vous donne un effet particulier ou un ensemble d'effets. + +@1 Potion @2=@1 potion @2 +@1 Potion=Potion @1 +Potion @1=Potion @1 +Strange Potion=Potion étrange + +Splash @1=@1 jetable +Lingering @1=@1 persistante +@1 Arrow @2=@1 flèche @2 +@1 Arrow=Flèche @1 +Arrow @1=Flèche @1 +Strange Tipped Arrow=Flèche à pointe étrange + +Mighty=puissante +of Trolling=de trollage + +Dragon's Breath=Souffle du dragon +This item is used in brewing and can be combined with splash potions to create lingering potions.=Cet objet est utilisé dans le brassage et peut être combiné avec des potions jetables pour créer des potions persistantes. + +Awkward=étrange +No effect=Aucun effet +Has an awkward taste and is used for brewing potions.=A un goût étrange et est utilisée pour préparer des potions. + +Mundane=banale +Has a terrible taste and is not really useful for brewing potions.=A un goût terrible et n'est pas vraiment utile pour préparer des potions. + +Thick=épaisse +Has a bitter taste and may be useful for brewing potions.=A un goût amer et peut être utile pour préparer des potions. + +of Healing=de guérison ++@1 HP=+@1 PV +Instantly heals.=Guérit instantanément + +of Harming=de dégâts +-@1 HP=-@1 PV +Instantly deals damage.=Inflige des dégâts instantanément. + +of Night Vision=de vision nocturne +Increases the perceived brightness of light under a dark sky.=Augmente la luminosité de la lumière perçue sous un ciel sombre. + +of Swiftness=de rapidité +Increases walking speed.=Augmente la vitesse de marche. + +of Slowness=de lenteur +Decreases walking speed.=Diminue la vitesse de marche. + +of Leaping=de saut +Increases jump strength.=Augmente la force de saut. + +of Withering=de dépérissement +Applies the withering effect which deals damage at a regular interval and can kill.=Applique l'effet de dépérissement qui inflige des dégâts à intervalles réguliers et peut tuer. + +of Poison=de poison +Applies the poison effect which deals damage at a regular interval.=Applique l'effet de poison qui inflige des dégâts à intervalles réguliers. + +of Regeneration=de régénération +Regenerates health over time.=Régénère la santé au fil du temps. + +of Invisibility=d'invisibilité +Grants invisibility.=Confère l'invisibilité. + +of Water Breathing=de respiration aquatique +Grants limitless breath underwater.=Confère une respiration illimitée sous l'eau. + +of Fire Resistance=de résistance au feu +Grants immunity to damage from heat sources like fire.=Confère une immunité aux dégâts causés par des sources de chaleur comme le feu. + +of Strength=de force +Increases attack power.=Augmente la puissance d'attaque. + +of Weakness=de faiblesse +Decreases attack power.=Diminue la puissance d'attaque. + +of Slow Falling=de chute lente +Instead of falling, you descend gracefully.=Au lieu de tomber, vous descendez avec grâce. + +of Levitation=de lévitation +Floats body slowly upwards.=Le corps flotte lentement vers le haut. + +of Darkness=d'obscurité +Surrounds with darkness.=Entoure d'obscurité. + +of Glowing=de surbrillance +Highlights for others to see.=Mise en valeur pour que les autres voient. + +of Health Boost=de bonus de santé +Increases health.=Augmente la santé. + +of Absorption=d'absorption +Absorbs some incoming damage.=Absorbe les dégâts reçus. + +of Resistance=de résistance +Decreases damage taken.=Diminue les dégâts subis. + +of Stone Cloak=de manteau de pierre +Decreases damage taken at the cost of speed.=Diminue les dégâts subis au détriment de la vitesse. + +of Luck=de chance +Increases luck.=Augmente la chance. + +of Bad Luck=de malchance +Decreases luck.=Diminue la chance. + +of Frost=de gel +Freezes...=Gèle... + +of Blindness=de cécité +Impairs sight.=Altére la vue. + +of Nausea=de nausée +Disintegrates senses.=Désintègre les sens. + +of Food Poisoning=d'intoxication alimentaire +Moves bowels too fast.=Déplace les intestins trop rapidement. + +of Saturation=de saturation +Satisfies hunger.=Satisfait la faim. + +of Haste=de célérité +Increases digging and attack speed.=Augmente la vitesse de creusage et d'attaque. + +of Fatigue=de fatigue +Decreases digging and attack speed.=Diminue la vitesse de creusage et d'attaque. + +Ominous=funeste +Attracts danger.=Attire le danger. + +Unknown Potion=Potion inconnue +Right-click to identify=Clic droit pour identifier +Unknown Tipped Arrow=Flèche à pointe inconnue + + +Fermented Spider Eye=Oeil d'araignée fermenté +Try different combinations to create potions.=Essayez différentes combinaisons pour créer des potions. -Missing effect parameter!=Paramètre d'effet manquant! -Missing or invalid duration parameter!=Paramètre durée manquant ou invalide! -Invalid factor parameter!=Paramètre facteur invalide! -@1 is not an available status effect.=@1 n'est pas un effet disponible. -Fermented Spider Eye=Œil d'araignée fermenté Glass Bottle=Bouteille en verre Liquid container=Récipient de liquide -A glass bottle is used as a container for liquids and can be used to collect water directly.=Une bouteille en verre est utilisée comme récipient pour les liquides et peut être utilisée pour collecter l'eau directement. +A glass bottle is used as a container for liquids and can be used to collect water directly.=Une bouteille en verre est utilisée comme récipient pour les liquides et peut être utilisée pour recueillir l'eau directement. -To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Pour collecter l'eau, poser la sur un chaudron avec de l'eau (qui enlève un niveau d'eau) ou toute source d'eau (qui n'enlève pas d'eau). +To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Pour récolter l'eau, utilisez la sur un chaudron avec de l'eau (qui enlève un niveau d'eau) ou toute source d'eau (qui n'enlève pas d'eau). Water Bottle=Bouteille d'eau -Water bottles can be used to fill cauldrons. Drinking water has no effect.=Les bouteilles d'eau peuvent être utilisées pour remplir les chaudrons. L'eau potable n'a aucun effet. +Water bottles can be used to fill cauldrons. Drinking water has no effect.=Les bouteilles d'eau peuvent être utilisées pour remplir les chaudrons. Boire l'eau n'a aucun effet. Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=Utilisez la touche "Utiliser" pour boire. Placez cet article sur un chaudron pour verser l'eau dans le chaudron. River Water Bottle=Bouteille d'eau de rivière -River water bottles can be used to fill cauldrons. Drinking it has no effect.=Les bouteilles d'eau de rivière peuvent être utilisées pour remplir les chaudrons. Le boire n'a aucun effet. +River water bottles can be used to fill cauldrons. Drinking it has no effect.=Les bouteilles d'eau de rivière peuvent être utilisées pour remplir les chaudrons. La boire n'a aucun effet. Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=Utilisez la touche "Utiliser" pour boire. Placez cet objet sur un chaudron pour verser l'eau de la rivière dans le chaudron. @@ -37,79 +293,3 @@ A throwable water bottle that will shatter on impact, where it creates a cloud o Glistering Melon=Melon étincelant This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=Ce melon brillant est plein de minuscules pépites d'or et serait bien dans un cadre d'objet. Il n'est pas comestible et n'est utile à rien d'autre. - -A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.=Une potion jetable qui se brisera à l'impact, où elle crée un nuage magique qui persiste pendant un moment. Tout joueur ou mob à l'intérieur du nuage recevra l'effet de la potion, peut-être à plusieurs reprises. - -Use the “Punch” key to throw it.=Utilisez la touche "Frapper" pour le lancer. -Use the “Place” key to drink it.=Utilisez la touche "Utiliser" pour le boire. -Drinking a potion gives you a particular effect.=Boire une potion vous donne un effet particulier. -1 HP/@1s | @2=1 PV/@1s | @2 -@1 HP=@1 PV -@1 Potion=Potion @1 -Splash @1 Potion=Potion @1 jetable -Lingering @1 Potion=Potion @1 persistante -Arrow of @1=Flêche de @1 - II= II - IV= IV -@1 Potion@2=@1 Potion@2 -Splash @1@2 Potion=Potion @1@2 jetable -Lingering @1@2 Potion=Potion @1@2 persistante -Arrow of @1@2=Flêche de @1@2 -@1 + Potion=@1 + Potion -Splash @1 + Potion=Potion @1 + jetable -Lingering @1 + Potion=Potion @1 + persistante -Arrow of @1 +=Flêche de @1 + -Awkward Potion=Potion étrange -Awkward Splash Potion=Potion étrange jetable -Awkward Lingering Potion=Potion étrange persistante -Has an awkward taste and is used for brewing potions.=A un goût étrange et est utilisé pour préparer des potions. -Mundane Potion=Potion banale -Mundane Splash Potion=Potion banale jetable -Mundane Lingering Potion=Potion banale persistante -Has a terrible taste and is not useful for brewing potions.=A un goût terrible et n'est pas utile pour préparer des potions. -Thick Potion=Potion épaisse -Thick Splash Potion=Potion épaisse jetable -Thick Lingering Potion=Potion épaisse persistante -Has a bitter taste and is not useful for brewing potions.=A un goût amer et n'est pas utile pour préparer des potions. -Dragon's Breath=Souffle du dragon - -This item is used in brewing and can be combined with splash potions to create lingering potions.=Cet objet est utilisé dans le brassage et peut être combiné avec des potions d'éclaboussures pour créer des potions persistantes. - -Healing=Guérison -+4 HP=+4 PV -+8 HP=+8 PV -Instantly heals.=Guérit instantanément. -Harming=Dégâts --6 HP=-6 PV --12 HP=-12 PV -Instantly deals damage.=Donne des dégâts instantanément. -Night Vision=Vision Nocturne -Increases the perceived brightness of light under a dark sky.=Augmente la luminosité perçue de la lumière sous un ciel sombre. -Swiftness=Rapidité -Increases walking speed.=Augmente la vitesse de marche. -Slowness=Lenteur -Decreases walking speed.=Diminue la vitesse de marche. -Leaping=Saut -Increases jump strength.=Augmente la force de saut. -Poison=Poison -Applies the poison effect which deals damage at a regular interval.=Applique l'effet de poison qui inflige des dégâts à intervalle régulier. -Regeneration=Régénération -Regenerates health over time.=Régénère la santé au fil du temps. -Invisibility=Invisibilité -Grants invisibility.=Accorde l'invisibilité. -Water Breathing=Respiration aquatique -Grants limitless breath underwater.=Donne une respiration illimitée sous l'eau. -Fire Resistance=Résistance au feu -Grants immunity to damage from heat sources like fire.=Confère une immunité aux dégâts causés par des sources de chaleur comme le feu. -Weakness=Faiblesse -Weakness +=Faiblesse + -Strength=Force -Strength II=Force II -Strength +=Force + -Try different combinations to create potions.=Essayez différentes combinaisons pour créer des potions. -No effect=Aucun effet - -A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Une potion jetable qui se brisera à l'impact, où elle donne à tous les joueurs et créatures proches un effet de statut. - -This particular arrow is tipped and will give an effect when it hits a player or mob.=Cette flèche particulière est enchantée et donnera un effet lorsqu'elle touche un joueur ou un mob. - diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr index abf61d4d3..db835bd9e 100644 --- a/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr @@ -1,115 +1,294 @@ # textdomain: mcl_potions - []= [] +Invisibility=Niewidzialność +body is invisible=ciało jest niewidzialne + +Poison=Trucizna +-1 HP / @1 s=-1 PŻ / @1 s + +Regeneration=Regeneracja ++1 HP / @1 s=+1 PŻ / @1 s + +Strength=Siła ++@1% melee damage=+@1% obrażeń w walce wręcz + +Weakness=Osłabienie +-@1% melee damage=-@1% obrażeń w walce wręcz + +Water Breathing=Oddychanie pod Wodą +limitless breathing under water=nieograniczone oddychanie pod wodą + +Dolphin's Grace=Gracja Delfina +swimming gracefully=pływanie z gracją + +Leaping=Zwiększony Skok ++@1% jumping power=+@1% siły skoku +-@1% jumping power=-@1% siły skoku + +Slow Falling=Powolne Opadanie +decreases gravity effects=zmniejsza skutki grawitacji + +Swiftness=Szybkość ++@1% running speed=+@1% prędkości w biegu + +Slowness=Spowolnienie +-@1% running speed=-@1% prędkości w biegu + +Levitation=Lewitacja +moves body upwards at @1 nodes/s=porusza ciało w górę z prędkością @1 bloków/s + +Night Vision=Noktowizja +improved vision during the night=poprawione widzenie w nocy + +Darkness=Ciemność +surrounded by darkness=otoczony ciemnością +not seeing anything beyond @1 nodes=nie widzi nic poza @1 blokami + +Glowing=Blask +more visible at all times=bardziej widoczny przez cały czas + +Health Boost=Zwiększone Zdrowie +HP increased by @1=PŻ zwiększone o @1 + +Absorption=Absorpcja +absorbs up to @1 incoming damage=pochłania do @1 otrzymywanych obrażeń + +Fire Resistance=Odporność na Ogień +resistance to fire damage=odporność na szkody od ognia + +Resistance=Odporność +resist @1% of incoming damage=zmniejsza otrzymywane obrażenia o @1% + +Luck=Szczęście + +Bad Luck=Pech + +Bad Omen=Zły Omen +danger is imminent=zagrożenie jest blisko + +Hero of the Village=Bohater Wioski + +Withering=Obumieranie +-1 HP / @1 s, can kill=-1 PŻ / @1 s, może zabić + +Frost=Mróz +-1 HP / 1 s, can kill, -@1% running speed=-1 PŻ / 1 s, może zabić, -@1% prędkości w biegu + +Blindness=Ślepota +impaired sight=upośledzony wzrok + +Nausea=Nudności +not feeling very well...=nie czuje się zbyt dobrze +frequency: @1 / 1 s=częstotliwość: @1 / 1 s + +Food Poisoning=Zatrucie Pokarmowe +exhausts by @1 per second=wyczerpuje o @1 na sekundę + +Saturation=Nasycenie +saturates by @1 per second=nasyca o @1 na sekundę + +Haste=Pośpiech ++@1% mining and attack speed=+@1% prędkości kopania i ataku + +Fatigue=Zmęczenie +-@1% mining and attack speed=-@1% prędkości kopania i ataku + +Conduit Power=Moc Przewodni ++@1% mining and attack speed in water=+@1% prędkości kopania i ataku w wodzie + + +|heal|list|clear|remove |INF [] [] [NOPART]=|heal|list|clear|remove |INF [] [] [NOPART] + +Add a status effect to yourself. Arguments: : name of status effect. Passing "list" as effect name lists available effects. Passing "heal" as effect name heals (or harms) by amount designed by the next parameter. Passing "clear" as effect name removes all effects. Passing "remove" as effect name removes the effect named by the next parameter. : duration in seconds. Passing "INF" as duration makes the effect infinite. (: amount of healing when the effect is "heal", passing a negative value subtracts health. : name of a status effect to be removed when using "remove" as the previous parameter.) : effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. : effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect.=Nadaj efekt statusu dla samego siebie. Argumenty: : nazwa efektu statusu (po angielsku). Przekazanie "list" jako nazwa efektu wypisuje dostępne nazwy efektów. Przekazanie "heal" jako nazwa efektu leczy (albo krzywdzi) o ilość określoną następnym parametrem. Przekazanie "clear" jako nazwy efektu usuwa wszystkie efekty. Przekazanie "remove" jako nazwy efektu usuwa efekt określony następnym parametrem. : czas trwania w sekundach. Przekazanie "INF" jako czas trwania czyni efekt nieskończonym. (: ilość leczenia kiedy ID-efektu to "heal", przekazanie liczby ujemnej zabiera zdrowie. : nazwa efektu statusu do usunięcia używając "remove" jako poprzedniego parametru.) : wyznacznik siły efektu, wyższy poziom skutkuje potężniejszym efektem prze efektach zależnych od poziomu (brak zmiany przy pozostałych), domyślnie 1, przekaż F żeby użyć niskopoziomowego współczynnika zamiast poziomu. : modyfikator siły efektu, może oznaczać różne rzeczy dla różnych efektów, nie wpływa na efekty, które nie zależą od poziomu/współczynnika. NOPART na końcu oznacza, że cząsteczki nie będą wyświetlane wokół ciebie dla tego efektu. + +Missing effect parameter!=Brakujący ID efektu! +Missing or invalid heal amount parameter!=Brakująca lub niewłaściwa ilość leczenia! +Player @1 healed by @2 HP.=Gracz @1 wyleczony o @2 PŻ. +Player @1 harmed by @2 HP.=Gracz @1 skrzywdzony o @2 PŻ. +Effects cleared for player @1=Efekty wyczyszczone dla gracza @1 +Removed effect @1 from player @2=Usunięto efekt @1 z gracza @2 +@1 is not an available status effect.=@1 nie jest dostępnym efektem. +Missing or invalid duration parameter!=Brakujący lub niewłaściwy czas trwania! +Invalid level parameter!=Niewłaściwy parametr poziomu! +Missing or invalid factor parameter when level is F!=Brakujący lub niewłaściwy współczynnik kiedy poziom to F! + +@1 effect given to player @2 for @3 seconds with factor of @4.=Efekt @1 nadany dla gracza @2 na @3 sekund ze współczynnikiem @4. +@1 effect given to player @2 for @3 seconds.=Efekt @1 nadany dla gracza @2 na #3 sekund. +Giving effect @1 to player @2 failed.=Nadawanie efektu @1 dla gracza @2 nie powiodło się. +@1 effect on level @2 given to player @3 for @4 seconds.=Efekt @1 na poziomie @2 nadany dla gracza @3 na @4 sekund. + + +A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.=Mikstura, którą można rzucić, a rozbije się przy uderzeniu, wystawiając wszystkich pobliskich graczy i moby na skutki jej działania. +Use the “Punch” key to throw it.=Użyj przycisku "Uderz" by rzucić. + + +A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect or set of effects, possibly repeatedly.=Mikstura, którą można rzucić, a roztrzaska się przy uderzeniu, tworząc magiczne opary pozostające przez chwilę na ziemi. Jakikolwiek gracz lub mob wewnątrz oparów będzie wystawiony na skutki mikstury, być może wielokrotnie. + + +This particular arrow is tipped and will give an effect when it hits a player or mob.=Czubek tej strzały jest zanurzony w miksturze, co wystawi jej cel na skutki jej działania. + + +Use the “Place” key to drink it.=Użyj przycisku "Postaw" by wypić. +Drinking a potion gives you a particular effect or set of effects.=Wypicie mikstury wywoła u ciebie określone skutki. + +@1 Potion @2=@1 Mikstura @2 +@1 Potion=@1 Mikstura +Potion @1=Mikstura @1 +Strange Potion=Dziwna Mikstura + +Splash @1=Miotana @1 +Lingering @1=Trwała @1 +@1 Arrow @2=@1 Strzała @2 +@1 Arrow=@1 Strzała +Arrow @1=Strzała @1 +Strange Tipped Arrow=Strzała z Dziwnym Grotem + +Mighty=Potężna +of Trolling=Trollowania + +Dragon's Breath=Oddech Smoka +This item is used in brewing and can be combined with splash potions to create lingering potions.=Ten przedmiot jest używany przy warzeniu i może zostać dodany do miotanych mikstur, aby uczynić je trwałymi. + +Awkward=Klarowna +No effect=Brak efektu +Has an awkward taste and is used for brewing potions.=Ma dziwny smak i jest używana do warzenia mikstur. + +Mundane=Mdła +Has a terrible taste and is not really useful for brewing potions.=Ma ohydny smak i nie jest zbyt użyteczna przy warzeniu mikstur. + +Thick=Gęsta +Has a bitter taste and may be useful for brewing potions.=Ma cierpki smak i może być użyteczna przy warzeniu mikstur. + +of Healing=Leczenia ++@1 HP=+@1 PŻ +Instantly heals.=Natychmiast leczy. + +of Harming=Krzywdy +-@1 HP=-@1 PŻ +Instantly deals damage.=Natychmiast zadaje obrażenia. + +of Night Vision=Noktowizji +Increases the perceived brightness of light under a dark sky.=Zwiększa postrzeganą jasność przy ciemnym niebie. + +of Swiftness=Szybkości +Increases walking speed.=Zwiększa prędkość ruchu. + +of Slowness=Spowolnienia +Decreases walking speed.=Zmniejsza prędkość ruchu. + +of Leaping=Zwiększonego Skoku +Increases jump strength.=Zwiększa siłę skoku. + +of Withering=Obumierania +Applies the withering effect which deals damage at a regular interval and can kill.=Zadaje efekt obumierania, zadający obrażenia w regularnych odstępach czasu i mogący zabić. + +of Poison=Trucizny +Applies the poison effect which deals damage at a regular interval.=Zadaje efekt trucizny, zadający obrażenia w regularnych odstępach czasu. + +of Regeneration=Regeneracji +Regenerates health over time.=Regeneruje życie z upływem czasu. + +of Invisibility=Niewidzialności +Grants invisibility.=Daje niewidzialność. + +of Water Breathing=Oddychania pod Wodą +Grants limitless breath underwater.=Daje nieograniczony oddech pod wodą. + +of Fire Resistance=Odporności na Ogień +Grants immunity to damage from heat sources like fire.=Daje odporność na obrażenia od źródeł ciepła takich jak ogień. + +of Strength=Siły +Increases attack power.=Zwiększa siłę ataku. + +of Weakness=Osłabienia +Decreases attack power.=Zmniejsza siłę ataku. + +of Slow Falling=Powolnego Opadania +Instead of falling, you descend gracefully.=Zamiast spadać, zstępujesz delikatnie. + +of Levitation=Lewitacji +Floats body slowly upwards.=Ciało powoli dryfuje w górę. + +of Darkness=Ciemności +Surrounds with darkness.=Otacza ciemnością. + +of Glowing=Blasku +Highlights for others to see.=Podświetla dla innych do dostrzeżenia. + +of Health Boost=Zwiększonego Zdrowia +Increases health.=Zwiększa zdrowie. + +of Absorption=Absorpcji +Absorbs some incoming damage.=Pochłania trochę otrzymywanych obrażeń. + +of Resistance=Odporności +Decreases damage taken.=Zmniejsza otrzymywane obrażenia. + +of Stone Cloak=Kamiennego Płaszcza +Decreases damage taken at the cost of speed.=Zmniejsza otrzymywane obrażenia kosztem prędkości. + +of Luck=Szczęścia +Increases luck.=Zwiększa szczęście. + +of Bad Luck=Pecha +Decreases luck.=Zmniejsza szczęście. + +of Frost=Mrozu +Freezes...=Zamraża... + +of Blindness=Ślepoty +Impairs sight.=Upośledza wzrok. + +of Nausea=Nudności +Disintegrates senses.=Dezintegruje zmysły. + +of Food Poisoning=Zatrucia Pokarmowego +Moves bowels too fast.=Porusza jelitami zbyt szybko. + +of Saturation=Nasycenia +Satisfies hunger.=Zaspokaja głód. + +of Haste=Pośpiechu +Increases digging and attack speed.=Zwiększa prędkość kopania i ataku. + +of Fatigue=Zmęczenia +Decreases digging and attack speed.=Zmniejsza prędkość kopania i ataku. + +Ominous=Złowieszcza +Attracts danger.=Przyciąga zagrożenie. + +Unknown Potion=Nieznana Mikstura +Right-click to identify=Kliknij prawym przyciskiem myszy, aby zidentyfikować +Unknown Tipped Arrow=Strzała z Nieznanym Grotem -Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)=Dodaj status na siebie. Argumenty: : nazwa efektu statusu, np. trucizna. : czas trwania w sekundach. : czynnik siły efektu (1 @= 100%) -Missing effect parameter!=Brak parametru efektu! -Missing or invalid duration parameter!=Brak lub nieprawidłowy parametr czasu trwania! -Invalid factor parameter!=Nieprawidłowy parametr czynnika! -@1 is not an available status effect.=@1 nie jest dostępnym efektem statusu. Fermented Spider Eye=Fermentowane oko pająka +Try different combinations to create potions.=Wypróbuj różne kombinacje, by stworzyć mikstury. + Glass Bottle=Szklana butelka -Liquid container=Pojemnik na płyn +Liquid container=Zbiornik na ciecz A glass bottle is used as a container for liquids and can be used to collect water directly.=Szklana butelka jest używana jako pojemnik na płyny i może być wykorzystana bezpośrednio do pozyskiwania wody. - To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Aby pozyskać wodę użyj jej na kotle z wodą (co usunie jeden poziom wody) lub jakimkolwiek źródle wody (co nie usunie wody). Water Bottle=Butelka wody -Water bottles can be used to fill cauldrons. Drinking water has no effect.=Butelka wody może być wykorzystana do napełniania kotłów. Picie wody nie ma żadnych efektów. +Water bottles can be used to fill cauldrons. Drinking water has no effect.=Butelka wody może być wykorzystana do napełniania kotłów. Picie wody nie ma żadnych skutków. Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=Użyj przycisku do stawiania aby pić. Postaw ten przedmiot na kotle aby wylać wodę do kotła. River Water Bottle=Butelka wody rzecznej -River water bottles can be used to fill cauldrons. Drinking it has no effect.=Butelka wody rzecznej może być wykorzystana do napełniania kotłów. Picie jej nie ma żadnego efektu. +River water bottles can be used to fill cauldrons. Drinking it has no effect.=Butelka wody rzecznej może być wykorzystana do napełniania kotłów. Picie jej nie ma żadnego skutku. Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=Użyj przycisku do stawiania aby pić. Postaw ten przedmiot na kotle aby wylać wodę rzeczną do kotła. Splash Water Bottle=Miotana butelka wody Extinguishes fire and hurts some mobs=Gasi ogień i rani niektóre moby -A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucać i roztrzaska się przy uderzeniu, gdzie ugasi ogień i rani moby podatne na wodę. +A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Butelka wody, którą można rzucić, a roztrzaska się przy uderzeniu, gdzie ugasi ogień i zrani moby podatne na wodę. Lingering Water Bottle=Trwała miotana butelka wody -A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucać i roztrzaska się przy uderzeniu tworząc opary wody pozostające przez chwilę na ziemi. Opary te gaszą ogień i ranią moby podatne na wodę. +A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Butelka wody którą można rzucić, a roztrzaska się przy uderzeniu, tworząc opary wody pozostające przez chwilę na ziemi. Opary te gaszą ogień i ranią moby podatne na wodę. Glistering Melon=Błyszczący arbuz This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=Ten błyszczący arbuz jest pełen tycich odłamków złota i wygląda ładnie w ramkach na przedmioty. Nie jest jadalny ani użyteczny do innych rzeczy. - -A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.=Mikstura którą można rzucać i roztrzaska się przy uderzeniu tworząc magiczne opary pozostające przez chwilę na ziemi. Jakikolwiek gracz lub mob wewnątrz oparów będzie wystawiony na efekt mikstury. - -Use the “Punch” key to throw it.=Użyj przycisku "Uderz" by rzucić. -Use the “Place” key to drink it.=Użyj przycisku "Postaw" by wypić. -Drinking a potion gives you a particular effect.=Wypicie mikstury sprawi, że będziesz wystawiona na jej efekty. -1 HP/@1s | @2=1 HP/@1s | @2 -@1 HP=@1 HP -@1 Potion=Mikstura @1 -Splash @1 Potion=Miotana mikstura @1 -Lingering @1 Potion=Trwała miotana mikstura @1 -Arrow of @1=Strzała @1 - II= II - IV= IV -@1 Potion@2=Mikstura @1@2 -Splash @1@2 Potion=Miotana mikstura @1@2 -Lingering @1@2 Potion=Trwała miotana mikstura @1@2 -Arrow of @1@2=Strzała @1@2 -@1 + Potion=Mikstura @1 + -Splash @1 + Potion=Miotana mikstura @1 + -Lingering @1 + Potion=Trwała miotana mikstura @1 + -Arrow of @1 +=Strzała @1 + -Awkward Potion=Klarowna mikstura -Awkward Splash Potion=Klarowna miotana mikstura -Awkward Lingering Potion=Klarowna trwała miotana mikstura -Has an awkward taste and is used for brewing potions.=Ma dziwny smak i jest użyteczna przy warzenia mikstur. -Mundane Potion=Mdła mikstura -Mundane Splash Potion=Mdła miotana mikstura -Mundane Lingering Potion=Mdła trwała miotana mikstura -Has a terrible taste and is not useful for brewing potions.=Ma ohydny smak i nie jest użyteczna przy warzenia mikstur. -Thick Potion=Gęsta mikstura -Thick Splash Potion=Gęsta miotana mikstura -Thick Lingering Potion=Gęsta trwała miotana mikstura -Has a bitter taste and is not useful for brewing potions.=Ma cierpki smak i nie jest użyteczna przy warzenia mikstur. -Dragon's Breath=Oddech smoka - -This item is used in brewing and can be combined with splash potions to create lingering potions.=Ten przedmiot jest używany przy warzeniu i może zostać dodany do miotanych mikstur aby uczynić je trwałymi. - -Healing=leczenia -+4 HP=+4 HP -+8 HP=+8 HP -Instantly heals.=Natychmiastowo leczy. -Harming=obrażeń --6 HP=-6 HP --12 HP=-12 HP -Instantly deals damage.=Natychmiastowo zadaje obrażenia. -Night Vision=widzenia w ciemności -Increases the perceived brightness of light under a dark sky.=Zwiększa postrzeganą jasność przy ciemnym niebie. -Swiftness=prędkości -Increases walking speed.=Zwiększa prędkość poruszania. -Slowness=spowolnienia -Decreases walking speed.=Zmniejsza prędkość poruszania. -Leaping=skakania -Increases jump strength.=Zwiększa siłę skoku. -Poison=trucizny -Applies the poison effect which deals damage at a regular interval.=Aplikuje efekt trucizny zadający obrażenia w regularnych odstępach czasu. -Regeneration=regeneracji -Regenerates health over time.=Regeneruje życie przez pewien czas. -Invisibility=niewidzialności -Grants invisibility.=Sprawia, że cel jest niewidzialny. -Water Breathing=oddychania pod wodą -Grants limitless breath underwater.=Sprawia, że cel może oddychać pod wodą. -Fire Resistance=odporności na ogień -Grants immunity to damage from heat sources like fire.=Sprawia, że cel jest odporny na obrażenia od źródeł ciepła takich jak ogień. -Weakness=słabości -Weakness +=słabości + -Strength=siły -Strength II=siły II -Strength +=siły + -Try different combinations to create potions.=Spróbuj innej kombinacji aby stworzyć miksturę. -No effect=Brak efektu - -A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Mikstura, którą można rzucić i rozbije się przy uderzeniu wystawiając wszystkich pobliskich graczy i moby na efekt jej działania. - -This particular arrow is tipped and will give an effect when it hits a player or mob.=Czubek tej strzały jest zanurzony w miksturze co wystawi jej cel na efekt jej działania. - diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr index 2bc4380ec..e97d89593 100644 --- a/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.ru.tr @@ -1,75 +1,75 @@ # textdomain: mcl_potions - []=<эффект> <длительность> [<фактор>] + []=<эффект> <длительность> [<сила>] -Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)=Добавляет вам эффект состояния. Параметры: <эффект> - название эффекта состояния, например, poison (отравление). <Длительность> - длительность в секундах. <Фактор> - коэффициент силы эффекта (1 @= 100%) +Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)=Добавляет вам эффект. Параметры: <эффект> - название эффекта , например, poison. <Длительность> - длительность в секундах. <Сила> - коэффициент силы эффекта (1 @= 100%) Missing effect parameter!=Отсутствует параметр эффекта! Missing or invalid duration parameter!=Отсутствует либо неправильно задан параметр длительности! -Invalid factor parameter!=Отсутствует параметр фактора! -@1 is not an available status effect.=@1 не является допустимым эффектом состояния. -Fermented Spider Eye=Прокисший паучий глаз -Glass Bottle=Стеклянная бутылка +Invalid factor parameter!=Отсутствует параметр силы! +@1 is not an available status effect.=@1 не является допустимым эффектом. +Fermented Spider Eye=Приготовленный паучий глаз +Glass Bottle=Пузырёк Liquid container=Контейнер для жидкостей -A glass bottle is used as a container for liquids and can be used to collect water directly.=Стеклянная бутылка используется для хранения жидкостей, её также можно использовать для сбора воды. +A glass bottle is used as a container for liquids and can be used to collect water directly.=Стеклянный пузырёк используется для хранения жидкостей, её также можно использовать для сбора воды. -To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Воду в бутылку можно набрать из котла с помощью команды [Использовать] (это уменьшает уровень воды в котле) или из другого источника (уровень которого не уменьшится). +To collect water, use it on a cauldron with water (which removes a level of water) or any water source (which removes no water).=Воду в пузырёк можно набрать из котла (это уменьшает уровень воды в котле) или из другого источника (уровень которого не уменьшится). -Water Bottle=Бутылка с водой -Water bottles can be used to fill cauldrons. Drinking water has no effect.=Бутылки с водой можно использовать для наполнения котлов. Выпивание воды не даст никакого эффекта. +Water Bottle=Пузырёк с водой +Water bottles can be used to fill cauldrons. Drinking water has no effect.=Пузырёк с водой можно использовать для наполнения котла. Выпивание воды не даст никакого эффекта. -Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=Используйте клавишу “Разместить”, чтобы выпить это. Поместите этот предмет на котёл, чтобы вылить воду в котёл. +Use the “Place” key to drink. Place this item on a cauldron to pour the water into the cauldron.=Используйте правую кнопку мыши, чтобы выпить. Используйте этот предмет на котле, чтобы вылить воду в котёл. -River Water Bottle=Бутылка с речной водой -River water bottles can be used to fill cauldrons. Drinking it has no effect.=Бутылки с речной водой можно использовать для наполнения котлов. Выпивание воды не даст никакого эффекта. +River Water Bottle=Пузырёк с речной водой +River water bottles can be used to fill cauldrons. Drinking it has no effect.=Пузырёк с речной водой можно использовать для наполнения котла. Выпивание воды не даст никакого эффекта. -Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=Используйте клавишу “Разместить”, чтобы выпить это. Поместите этот предмет на котёл, чтобы вылить речную воду в котёл. +Use the “Place” key to drink. Place this item on a cauldron to pour the river water into the cauldron.=Используйте правую кнопку мыши, чтобы выпить. Используйте этот предмет на котле, чтобы вылить речную воду в котёл. -Splash Water Bottle=Бутылка со взрывающейся водой +Splash Water Bottle=Взрывное зелье Extinguishes fire and hurts some mobs=Тушит огонь и ранит некоторых мобов -A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Бутылка с водой, которую можно метать. Она разбивается при ударе, тушит ближайший огонь и ранит мобов, уязвимых к воде. +A throwable water bottle that will shatter on impact, where it extinguishes nearby fire and hurts mobs that are vulnerable to water.=Пузырёк с водой, который можно метать. Он разбивается при ударе, тушит ближайший огонь и ранит мобов, уязвимых к воде. -Lingering Water Bottle=Бутылка с оседающей водой +Lingering Water Bottle=Туманное зелье -A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Бутылка с водой, которую можно метать. Она разбивается при ударе, образуя облако пара, которое оседает на землю через некоторое время. Это облако тушит огонь и ранит мобов, уязвимых к воде. +A throwable water bottle that will shatter on impact, where it creates a cloud of water vapor that lingers on the ground for a while. This cloud extinguishes fire and hurts mobs that are vulnerable to water.=Пузырёк с водой, который можно метать. Он разбивается при ударе, образуя облако пара, которое оседает на землю через некоторое время. Это облако тушит огонь и ранит мобов, уязвимых к воде. -Glistering Melon=Искрящаяся дыня +Glistering Melon=Сверкающий ломтик арбуза -This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=Искрящаяся дыня полна маленьких золотых самородков и может отлично смотреться в рамке. Она несъедобна и не годится больше ни для чего. +This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.=Сверкающий ломтик арбуза содержит в себе золотые самородки и может отлично смотреться в рамке. Ломтик не съедобен. A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.=Зелье, которое можно метать. При ударе оно разбивается, создавая волшебное облако, которое задерживается на некоторое время. Любой игрок или моб внутри облака получит эффект зелья, возможно, неоднократно. -Use the “Punch” key to throw it.=Нажмите [Ударить] для метания. -Use the “Place” key to drink it.=Нажмите [Разместить] для выпивания. -Drinking a potion gives you a particular effect.=Выпивание зелья даёт вам особый эффект. +Use the “Punch” key to throw it.=Нажмите [Ударить], чтобы бросить. +Use the “Place” key to drink it.=Нажмите [Использовать], чтобы выпить. +Drinking a potion gives you a particular effect.=Выпивание зелья даёт вам определённый эффект. 1 HP/@1s | @2=1 HP/@1с | @2 @1 HP=@1 HP @1 Potion=Зелье @1 -Splash @1 Potion=Взрывающееся зелье @1 -Lingering @1 Potion=Оседающее зелье @1 +Splash @1 Potion=Взрывное зелье @1 +Lingering @1 Potion=Туманное зелье @1 Arrow of @1=Стрела @1 II= II IV= IV @1 Potion@2=Зелье @1 @2 -Splash @1@2 Potion=Взрывающееся зелье @1@2 -Lingering @1@2 Potion=Оседающее зелье @1@2 +Splash @1@2 Potion=Взрывное зелье @1@2 +Lingering @1@2 Potion=Туманное зелье @1@2 Arrow of @1@2=Стрела @1@2 @1 + Potion=Зелье @1+ -Splash @1 + Potion=Взрывающееся зелье @1+ -Lingering @1 + Potion=Оседающее зелье @1+ +Splash @1 + Potion=Взрывное зелье @1+ +Lingering @1 + Potion=Туманное зелье @1+ Arrow of @1 +=Стрела @1+ -Awkward Potion=Невкусное зелье -Awkward Splash Potion=Невкусное взрывающееся зелье -Awkward Lingering Potion=Невкусное оседающее зелье +Awkward Potion=Грубое зелье +Awkward Splash Potion=Взрывное грубое зелье +Awkward Lingering Potion=Туманное грубое зелье Has an awkward taste and is used for brewing potions.=Имеет неприятный вкус и используется для приготовления других зелий. -Mundane Potion=Успокоительное зелье -Mundane Splash Potion=Успокоительное взрывающееся зелье -Mundane Lingering Potion=Успокоительное оседающее зелье +Mundane Potion=Непримечательное зелье +Mundane Splash Potion=Взрывное непримечательное взрывное зелье +Mundane Lingering Potion=Туманное непримечательное зелье Has a terrible taste and is not useful for brewing potions.=Имеет отвратительный вкус и используется для приготовления других зелий. Thick Potion=Густое зелье -Thick Splash Potion=Густое взрывающееся зелье -Thick Lingering Potion=Густое оседающее зелье +Thick Splash Potion=Взрывное густое зелье +Thick Lingering Potion=Туманное густое зелье Has a bitter taste and is not useful for brewing potions.=Имеет горький вкус и используется для приготовления других зелий. Dragon's Breath=Дыхание дракона @@ -78,14 +78,14 @@ This item is used in brewing and can be combined with splash potions to create l Healing=исцеления +4 HP=+4 HP +8 HP=+8 HP -Instantly heals.=Лечит мгновенно +Instantly heals.=Мгновенно исцеляет. Harming=урона -6 HP=-6 HP -12 HP=-12 HP -Instantly deals damage.=Вызывает мгновенную смерть. +Instantly deals damage.=Наносит мгновенный урон. Night Vision=ночного зрения -Increases the perceived brightness of light under a dark sky.=Усиливает восприятие яркости освещения под тёмным небом. -Swiftness=ускорения +Increases the perceived brightness of light under a dark sky.=Усиливает восприятие яркости освещения в тёмных местах. +Swiftness=стремительности Increases walking speed.=Увеличивает скорость ходьбы Slowness=замедления Decreases walking speed.=Уменьшает скорость ходьбы @@ -93,24 +93,22 @@ Leaping=прыгучести Increases jump strength.=Увеличивает силу прыжка Poison=отравления Applies the poison effect which deals damage at a regular interval.=Наносит эффект яда, который вызывает урон через равные промежутки времени. -Regeneration=восстановления +Regeneration=регенерации Regenerates health over time.=Восстанавливает здоровье со временем. Invisibility=невидимости Grants invisibility.=Делает невидимым. Water Breathing=подводного дыхания -Grants limitless breath underwater.=Даёт возможность неограниченно дышать под водой. +Grants limitless breath underwater.=Даёт возможность дышать под водой. Fire Resistance=огнестойкости Grants immunity to damage from heat sources like fire.=Делает невосприимчивым к урону от источников тепла, например, от огня. -Weakness=Слабость -Weakness +=Слабость + -Strength=Сила -Strength II=Сила II -Strength +=Сила + +Weakness=слабости+ +Weakness +=слабости+ +Strength=силы +Strength II=силы II +Strength +=силы+ Try different combinations to create potions.=Пробуйте разные сочетания для приготовления зелий. -No effect=Не оказывает эффекта - -A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Зелье, которое можно метать. Оно разбивается при ударе и он дает всем ближайшим игрокам и мобам эффект состояния. - -This particular arrow is tipped and will give an effect when it hits a player or mob.=Эта необычная стрела с обработанным наконечником даёт эффект при попадании в игрока или моба. +No effect=без эффекта +A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Метательное зелье разобьется при столкновении и даст ближайшим игрокам и мобам эффект. +This particular arrow is tipped and will give an effect when it hits a player or mob.=Эта обмакнутая в зелье стрела даёт эффект при попадании в игрока или моба. diff --git a/mods/ITEMS/mcl_potions/locale/template.txt b/mods/ITEMS/mcl_potions/locale/template.txt index 1420dabee..39cd18f31 100644 --- a/mods/ITEMS/mcl_potions/locale/template.txt +++ b/mods/ITEMS/mcl_potions/locale/template.txt @@ -1,13 +1,269 @@ # textdomain: mcl_potions - []= +Invisibility= +body is invisible= -Add a status effect to yourself. Arguments: : name of status effect, e.g. poison. : duration in seconds. : effect strength multiplier (1 @= 100%)= +Poison= +-1 HP / @1 s= + +Regeneration= ++1 HP / @1 s= + +Strength= ++@1% melee damage= + +Weakness= +-@1% melee damage= + +Water Breathing= +limitless breathing under water= + +Dolphin's Grace= +swimming gracefully= + +Leaping= ++@1% jumping power= +-@1% jumping power= + +Slow Falling= +decreases gravity effects= + +Swiftness= ++@1% running speed= + +Slowness= +-@1% running speed= + +Levitation= +moves body upwards at @1 nodes/s= + +Night Vision= +improved vision during the night= + +Darkness= +surrounded by darkness= +not seeing anything beyond @1 nodes= + +Glowing= +more visible at all times= + +Health Boost= +HP increased by @1= + +Absorption= +absorbs up to @1 incoming damage= + +Fire Resistance= +resistance to fire damage= + +Resistance= +resist @1% of incoming damage= + +Luck= + +Bad Luck= + +Bad Omen= +danger is imminent= + +Hero of the Village= + +Withering= +-1 HP / @1 s, can kill= + +Frost= +-1 HP / 1 s, can kill, -@1% running speed= + +Blindness= +impaired sight= + +Nausea= +not feeling very well...= +frequency: @1 / 1 s= + +Food Poisoning= +exhausts by @1 per second= + +Saturation= +saturates by @1 per second= + +Haste= ++@1% mining and attack speed= + +Fatigue= +-@1% mining and attack speed= + +Conduit Power= ++@1% mining and attack speed in water= + + +|heal|list|clear|remove |INF [] [] [NOPART]= + +Add a status effect to yourself. Arguments: : name of status effect. Passing "list" as effect name lists available effects. Passing "heal" as effect name heals (or harms) by amount designed by the next parameter. Passing "clear" as effect name removes all effects. Passing "remove" as effect name removes the effect named by the next parameter. : duration in seconds. Passing "INF" as duration makes the effect infinite. (: amount of healing when the effect is "heal", passing a negative value subtracts health. : name of a status effect to be removed when using "remove" as the previous parameter.) : effect power determinant, bigger level results in more powerful effect for effects that depend on the level (no changes for other effects), defaults to 1, pass F to use low-level factor instead. : effect strength modifier, can mean different things depending on the effect, no changes for effects that do not depend on level/factor. NOPART at the end means no particles will be shown for this effect.= Missing effect parameter!= -Missing or invalid duration parameter!= -Invalid factor parameter!= +Missing or invalid heal amount parameter!= +Player @1 healed by @2 HP.= +Player @1 harmed by @2 HP.= +Effects cleared for player @1= +Removed effect @1 from player @2= @1 is not an available status effect.= +Missing or invalid duration parameter!= +Invalid level parameter!= +Missing or invalid factor parameter when level is F!= + +@1 effect given to player @2 for @3 seconds with factor of @4.= +@1 effect given to player @2 for @3 seconds.= +Giving effect @1 to player @2 failed.= +@1 effect on level @2 given to player @3 for @4 seconds.= + + +A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.= +Use the “Punch” key to throw it.= + + +A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect or set of effects, possibly repeatedly.= + + +This particular arrow is tipped and will give an effect when it hits a player or mob.= + + +Use the “Place” key to drink it.= +Drinking a potion gives you a particular effect or set of effects.= + +@1 Potion @2= +@1 Potion= +Potion @1= +Strange Potion= + +Splash @1= +Lingering @1= +@1 Arrow @2= +@1 Arrow= +Arrow @1= +Strange Tipped Arrow= + +Mighty= +of Trolling= + +Dragon's Breath= +This item is used in brewing and can be combined with splash potions to create lingering potions.= + +Awkward= +No effect= +Has an awkward taste and is used for brewing potions.= + +Mundane= +Has a terrible taste and is not really useful for brewing potions.= + +Thick= +Has a bitter taste and may be useful for brewing potions.= + +of Healing= ++@1 HP= +Instantly heals.= + +of Harming= +-@1 HP= +Instantly deals damage.= + +of Night Vision= +Increases the perceived brightness of light under a dark sky.= + +of Swiftness= +Increases walking speed.= + +of Slowness= +Decreases walking speed.= + +of Leaping= +Increases jump strength.= + +of Withering= +Applies the withering effect which deals damage at a regular interval and can kill.= + +of Poison= +Applies the poison effect which deals damage at a regular interval.= + +of Regeneration= +Regenerates health over time.= + +of Invisibility= +Grants invisibility.= + +of Water Breathing= +Grants limitless breath underwater.= + +of Fire Resistance= +Grants immunity to damage from heat sources like fire.= + +of Strength= +Increases attack power.= + +of Weakness= +Decreases attack power.= + +of Slow Falling= +Instead of falling, you descend gracefully.= + +of Levitation= +Floats body slowly upwards.= + +of Darkness= +Surrounds with darkness.= + +of Glowing= +Highlights for others to see.= + +of Health Boost= +Increases health.= + +of Absorption= +Absorbs some incoming damage.= + +of Resistance= +Decreases damage taken.= + +of Stone Cloak= +Decreases damage taken at the cost of speed.= + +of Luck= +Increases luck.= + +of Bad Luck= +Decreases luck.= + +of Frost= +Freezes...= + +of Blindness= +Impairs sight.= + +of Nausea= +Disintegrates senses.= + +of Food Poisoning= +Moves bowels too fast.= + +of Saturation= +Satisfies hunger.= + +of Haste= +Increases digging and attack speed.= + +of Fatigue= +Decreases digging and attack speed.= + +Ominous= +Attracts danger.= + +Unknown Potion= +Right-click to identify= +Unknown Tipped Arrow= + + Fermented Spider Eye= +Try different combinations to create potions.= + Glass Bottle= Liquid container= @@ -37,79 +293,3 @@ A throwable water bottle that will shatter on impact, where it creates a cloud o Glistering Melon= This shiny melon is full of tiny gold nuggets and would be nice in an item frame. It isn't edible and not useful for anything else.= - -A throwable potion that will shatter on impact, where it creates a magic cloud that lingers around for a while. Any player or mob inside the cloud will receive the potion's effect, possibly repeatedly.= - -Use the “Punch” key to throw it.= -Use the “Place” key to drink it.= -Drinking a potion gives you a particular effect.= -1 HP/@1s | @2= -@1 HP= -@1 Potion= -Splash @1 Potion= -Lingering @1 Potion= -Arrow of @1= - II= - IV= -@1 Potion@2= -Splash @1@2 Potion= -Lingering @1@2 Potion= -Arrow of @1@2= -@1 + Potion= -Splash @1 + Potion= -Lingering @1 + Potion= -Arrow of @1 += -Awkward Potion= -Awkward Splash Potion= -Awkward Lingering Potion= -Has an awkward taste and is used for brewing potions.= -Mundane Potion= -Mundane Splash Potion= -Mundane Lingering Potion= -Has a terrible taste and is not useful for brewing potions.= -Thick Potion= -Thick Splash Potion= -Thick Lingering Potion= -Has a bitter taste and is not useful for brewing potions.= -Dragon's Breath= - -This item is used in brewing and can be combined with splash potions to create lingering potions.= - -Healing= -+4 HP= -+8 HP= -Instantly heals.= -Harming= --6 HP= --12 HP= -Instantly deals damage.= -Night Vision= -Increases the perceived brightness of light under a dark sky.= -Swiftness= -Increases walking speed.= -Slowness= -Decreases walking speed.= -Leaping= -Increases jump strength.= -Poison= -Applies the poison effect which deals damage at a regular interval.= -Regeneration= -Regenerates health over time.= -Invisibility= -Grants invisibility.= -Water Breathing= -Grants limitless breath underwater.= -Fire Resistance= -Grants immunity to damage from heat sources like fire.= -Weakness= -Weakness += -Strength= -Strength II= -Strength += -Try different combinations to create potions.= -No effect= - -A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.= - -This particular arrow is tipped and will give an effect when it hits a player or mob.= - diff --git a/mods/ITEMS/mcl_potions/mod.conf b/mods/ITEMS/mcl_potions/mod.conf index bcb6d8ad3..91280a607 100644 --- a/mods/ITEMS/mcl_potions/mod.conf +++ b/mods/ITEMS/mcl_potions/mod.conf @@ -1,2 +1,2 @@ name = mcl_potions -depends = mcl_core, mcl_farming, mcl_mobitems, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip +depends = mcl_core, mcl_farming, mcl_flowers, mcl_mobitems, mcl_mobs, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip diff --git a/mods/ITEMS/mcl_potions/potions.lua b/mods/ITEMS/mcl_potions/potions.lua index 3d89d1d40..af8a63e68 100644 --- a/mods/ITEMS/mcl_potions/potions.lua +++ b/mods/ITEMS/mcl_potions/potions.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator(minetest.get_current_modname()) ---local brewhelp = S("Try different combinations to create potions.") + +mcl_potions.registered_potions = {} +-- shorthand +local registered_potions = mcl_potions.registered_potions local function potion_image(colorstring, opacity) if not opacity then @@ -9,7 +12,7 @@ local function potion_image(colorstring, opacity) end local how_to_drink = S("Use the “Place” key to drink it.") -local potion_intro = S("Drinking a potion gives you a particular effect.") +local potion_intro = S("Drinking a potion gives you a particular effect or set of effects.") local function time_string(dur) if not dur then @@ -45,344 +48,297 @@ end -- ╚═╝░░░░░░╚════╝░░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═════╝░ -function return_on_use(def, effect, dur) - return function (itemstack, user, pointed_thing) +local function generate_on_use(effects, color, on_use, custom_effect) + return function(itemstack, user, pointed_thing) if pointed_thing.type == "node" then if user and not user:get_player_control().sneak then - -- Use pointed node's on_rightclick function first, if present local node = minetest.get_node(pointed_thing.under) - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack end end elseif pointed_thing.type == "object" then return itemstack end - def.on_use(user, effect, dur) - local old_name, old_count = itemstack:get_name(), itemstack:get_count() - itemstack = minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) - if old_name ~= itemstack:get_name() or old_count ~= itemstack:get_count() then - mcl_potions._use_potion(itemstack, user, def.color) + -- Wrapper for handling mcl_hunger delayed eating + local player_name = user:get_player_name() + mcl_hunger.eat_internal[player_name]._custom_itemstack = itemstack -- Used as comparison to make sure the custom wrapper executes only when the same item is eaten + mcl_hunger.eat_internal[player_name]._custom_var = { + user = user, + effects = effects, + on_use = on_use, + custom_effect = custom_effect, + } + mcl_hunger.eat_internal[player_name]._custom_func = function(itemstack, user, effects, on_use, custom_effect) + local potency = itemstack:get_meta():get_int("mcl_potions:potion_potent") + local plus = itemstack:get_meta():get_int("mcl_potions:potion_plus") + local ef_level + local dur + for name, details in pairs(effects) do + if details.uses_level then + ef_level = details.level + details.level_scaling * (potency) + else + ef_level = details.level + end + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) + if potency>0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency) + end + else + dur = details.dur + end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(user, name) + end + mcl_potions.give_effect_by_level(name, user, ef_level, dur) + end + + if on_use then on_use(user, potency+1) end + if custom_effect then custom_effect(user, potency+1, plus) end end + mcl_hunger.eat_internal[player_name]._custom_wrapper = function(player_name) + mcl_hunger.eat_internal[player_name]._custom_func( + mcl_hunger.eat_internal[player_name]._custom_itemstack, + mcl_hunger.eat_internal[player_name]._custom_var.user, + mcl_hunger.eat_internal[player_name]._custom_var.effects, + mcl_hunger.eat_internal[player_name]._custom_var.on_use, + mcl_hunger.eat_internal[player_name]._custom_var.custom_effect + ) + end + + itemstack = minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) + if itemstack then mcl_potions._use_potion(user, color) end + return itemstack end end - -local function register_potion(def) - - local dur = mcl_potions.DURATION - - if def.is_inv then - dur = dur * mcl_potions.INV_FACTOR +-- API - registers a potion +-- required parameters in def: +-- name - string - potion name in code +-- optional parameters in def: +-- desc_prefix - translated string - part of visible potion name, comes before the word "Potion" +-- desc_suffix - translated string - part of visible potion name, comes after the word "Potion" +-- _tt - translated string - custom tooltip text +-- _dynamic_tt - function(level) - returns custom tooltip text dependent on potion level +-- _longdesc - translated string - text for in-game documentation +-- stack_max - int - max stack size - defaults to 1 +-- image - string - name of a custom texture of the potion icon +-- color - string - colorstring for potion icon when image is not defined - defaults to #0000FF +-- groups - table - item groups definition for the regular potion, not splash or lingering - +-- - must contain _mcl_potion=1 for tooltip to include dynamic_tt and effects +-- - defaults to {brewitem=1, food=3, can_eat_when_full=1, _mcl_potion=1} +-- nocreative - bool - adds a not_in_creative_inventory=1 group - defaults to false +-- _effect_list - table - all the effects dealt by the potion in the format of tables +-- -- the name of each sub-table should be a name of a registered effect, and fields can be the following: +-- -- -- uses_level - bool - whether the level of the potion affects the level of the effect - +-- -- -- - defaults to the uses_factor field of the effect definition +-- -- -- level - int - used as the effect level if uses_level is false and for lvl1 potions - defaults to 1 +-- -- -- level_scaling - int - used as the number of effect levels added per potion level - defaults to 1 - +-- -- -- - this has no effect if uses_level is false +-- -- -- dur - float - duration of the effect in seconds - defaults to mcl_potions.DURATION +-- -- -- dur_variable - bool - whether variants of the potion should have the length of this effect changed - +-- -- -- - defaults to true +-- -- -- - if at least one effect has this set to true, the potion has a "plus" variant +-- -- -- effect_stacks - bool - whether the effect stacks - defaults to false +-- uses_level - bool - whether the potion should come at different levels - +-- - defaults to true if uses_level is true for at least one effect, else false +-- drinkable - bool - defaults to true +-- has_splash - bool - defaults to true +-- has_lingering - bool - defaults to true +-- has_arrow - bool - defaults to false +-- has_potent - bool - whether there is a potent (e.g. II) variant - defaults to the value of uses_level +-- default_potent_level - int - potion level used for the default potent variant - defaults to 2 +-- default_extend_level - int - extention level (amount of +) used for the default extended variant - defaults to 1 +-- custom_on_use - function(user, level) - called when the potion is drunk, returns true on success +-- custom_effect - function(object, level, plus) - called when the potion effects are applied, returns true on success +-- custom_splash_effect - function(pos, level) - called when the splash potion explodes, returns true on success +-- custom_linger_effect - function(pos, radius, level) - called on the lingering potion step, returns true on success +function mcl_potions.register_potion(def) + local modname = minetest.get_current_modname() + local name = def.name + if name == nil then + error("Unable to register potion: name is nil") end - if def.name == "poison" or def.name == "regeneration" then - dur = 45 + if type(name) ~= "string" then + error("Unable to register potion: name is not a string") end - - local on_use = nil - - if def.on_use then - on_use = return_on_use(def, def.effect, dur) - end - - local function get_tt(tt, effect, dur) - local _tt - if effect and def.is_dur then - _tt = perc_string(effect).." | "..time_string(dur) - if def.name == "poison" or def.name == "regeneration" then - _tt = S("1 HP/@1s | @2", effect, time_string(dur)) - end - elseif def.name == "healing" or def.name == "harming" then - _tt = S("@1 HP", effect) - else - _tt = tt or time_string(dur) or S("No effect") - end - return _tt - end - - local function get_splash_fun(effect, sp_dur) - if def.is_dur then - return function(player, redx) def.on_use(player, effect, sp_dur*redx) end - elseif def.effect then - return function(player, redx) def.on_use(player, effect*redx, sp_dur) end - end - -- covers case of no effect (water, awkward, mundane) - return function() end - end - - local function get_lingering_fun(effect, ling_dur) - if def.is_dur then - return function(player) def.on_use(player, effect, ling_dur) end - elseif def.effect then - return function(player) def.on_use(player, effect*0.5, ling_dur) end - end - -- covers case of no effect (water, awkward, mundane) - return function() end - end - - local function get_arrow_fun(effect, dur) - if def.is_dur then - return function(player) def.on_use(player, effect, dur) end - elseif def.effect then - return function(player) def.on_use(player, effect, dur) end - end - -- covers case of no effect (water, awkward, mundane) - return function() end - end - - local desc - if not def.no_potion then - if def.description_potion then - desc = def.description_potion - else - desc = S("@1 Potion", def.description) - end + local pdef = {} + if def.desc_prefix and def.desc_suffix then + pdef.description = S("@1 Potion @2", def.desc_prefix, def.desc_suffix) + elseif def.desc_prefix then + pdef.description = S("@1 Potion", def.desc_prefix) + elseif def.desc_suffix then + pdef.description = S("Potion @1", def.desc_suffix) else - desc = def.description + pdef.description = S("Strange Potion") end + pdef._tt_help = def._tt + pdef._dynamic_tt = def._dynamic_tt local potion_longdesc = def._longdesc - if not def.no_effect then + if def._effect_list then potion_longdesc = potion_intro .. "\n" .. def._longdesc end - local potion_usagehelp - local basic_potion_tt - if def.name ~= "dragon_breath" then - potion_usagehelp = how_to_drink - basic_potion_tt = get_tt(def._tt, def.effect, dur) - end + pdef._doc_items_longdesc = potion_longdesc + if def.drinkable ~= false then pdef._doc_items_usagehelp = how_to_drink end + pdef.stack_max = def.stack_max or 1 + local color = def.color or "#0000FF" + pdef.inventory_image = def.image or potion_image(color) + pdef.wield_image = pdef.inventory_image + pdef.groups = def.groups or {brewitem=1, food=3, can_eat_when_full=1, _mcl_potion=1} + if def.nocreative then pdef.groups.not_in_creative_inventory = 1 end - minetest.register_craftitem("mcl_potions:"..def.name, { - description = desc, - _tt_help = basic_potion_tt, - _doc_items_longdesc = potion_longdesc, - _doc_items_usagehelp = potion_usagehelp, - stack_max = def.stack_max or 1, - inventory_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 }, - on_place = on_use, - on_secondary_use = on_use, - }) - - -- Register Splash and Lingering - local splash_dur = dur * mcl_potions.SPLASH_FACTOR - local ling_dur = dur * mcl_potions.LINGERING_FACTOR - - local splash_def = { - tt = get_tt(def._tt, def.effect, splash_dur), - longdesc = def._longdesc, - potion_fun = get_splash_fun(def.effect, splash_dur), - no_effect = def.no_effect, - instant = def.instant, - } - - local ling_def - if def.name == "healing" or def.name == "harming" then - ling_def = { - tt = get_tt(def._tt, def.effect*mcl_potions.LINGERING_FACTOR, ling_dur), - longdesc = def._longdesc, - potion_fun = get_lingering_fun(def.effect*mcl_potions.LINGERING_FACTOR, ling_dur), - no_effect = def.no_effect, - instant = def.instant, - } - else - ling_def = { - tt = get_tt(def._tt, def.effect, ling_dur), - longdesc = def._longdesc, - potion_fun = get_lingering_fun(def.effect, ling_dur), - no_effect = def.no_effect, - instant = def.instant, - } - end - - local arrow_def = { - tt = get_tt(def._tt, def.effect, dur/8.), - longdesc = def._longdesc, - potion_fun = get_arrow_fun(def.effect, dur/8.), - no_effect = def.no_effect, - instant = def.instant, - } - - if def.color and not def.no_throwable then - local desc - if def.description_splash then - desc = def.description_splash - else - desc = S("Splash @1 Potion", def.description) - end - mcl_potions.register_splash(def.name, desc, def.color, splash_def) - if def.description_lingering then - desc = def.description_lingering - else - desc = S("Lingering @1 Potion", def.description) - end - mcl_potions.register_lingering(def.name, desc, def.color, ling_def) - if not def.no_arrow then - mcl_potions.register_arrow(def.name, S("Arrow of @1", def.description), def.color, arrow_def) - end - end - - if def.is_II then - - local desc_mod = S(" II") - - local effect_II - if def.name == "healing" or def.name == "harming" then - effect_II = def.effect*mcl_potions.II_FACTOR - elseif def.name == "poison" or def.name == "regeneration" then - effect_II = 1.2 - else - effect_II = def.effect^mcl_potions.II_FACTOR - end - - local dur_2 = dur / mcl_potions.II_FACTOR - if def.name == "poison" then dur_2 = dur_2 - 1 end - - if def.name == "slowness" then - dur_2 = 20 - effect_II = 0.40 - desc_mod = S(" IV") - end - - on_use = return_on_use(def, effect_II, dur_2) - - minetest.register_craftitem("mcl_potions:"..def.name.."_2", { - description = S("@1 Potion@2", def.description, desc_mod), - _tt_help = get_tt(def._tt_2, effect_II, dur_2), - _doc_items_longdesc = potion_longdesc, - _doc_items_usagehelp = potion_usagehelp, - stack_max = def.stack_max or 1, - inventory_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}, - on_place = on_use, - on_secondary_use = on_use, - }) - - -- Register Splash and Lingering - local splash_dur_2 = dur_2 * mcl_potions.SPLASH_FACTOR - local ling_dur_2 = dur_2 * mcl_potions.LINGERING_FACTOR - - local splash_def_2 - if def.name == "healing" then - splash_def_2 = { - tt = get_tt(def._tt_2, 7, splash_dur_2), - longdesc = def._longdesc, - potion_fun = get_splash_fun(7, splash_dur_2), - no_effect = def.no_effect, - instant = def.instant, - } - else - splash_def_2 = { - tt = get_tt(def._tt_2, effect_II, splash_dur_2), - longdesc = def._longdesc, - potion_fun = get_splash_fun(effect_II, splash_dur_2), - no_effect = def.no_effect, - instant = def.instant, - } - end - - - local ling_def_2 - if def.name == "healing" or def.name == "harming" then - ling_def_2 = { - tt = get_tt(def._tt_2, effect_II*mcl_potions.LINGERING_FACTOR, ling_dur_2), - longdesc = def._longdesc, - potion_fun = get_lingering_fun(effect_II*mcl_potions.LINGERING_FACTOR, ling_dur_2), - no_effect = def.no_effect, - instant = def.instant, - } - else - ling_def_2 = { - tt = get_tt(def._tt_2, effect_II, ling_dur_2), - longdesc = def._longdesc, - potion_fun = get_lingering_fun(effect_II, ling_dur_2), - no_effect = def.no_effect, - instant = def.instant, - } - end - - local arrow_def_2 = { - tt = get_tt(def._tt_2, effect_II, dur_2/8.), - longdesc = def._longdesc, - potion_fun = get_arrow_fun(effect_II, dur_2/8.), - no_effect = def.no_effect, - instant = def.instant, - } - - if def.color and not def.no_throwable then - mcl_potions.register_splash(def.name.."_2", S("Splash @1@2 Potion", def.description, desc_mod), def.color, splash_def_2) - mcl_potions.register_lingering(def.name.."_2", S("Lingering @1@2 Potion", def.description, desc_mod), def.color, ling_def_2) - if not def.no_arrow then - mcl_potions.register_arrow(def.name.."_2", S("Arrow of @1@2", def.description, desc_mod), def.color, arrow_def_2) + pdef._effect_list = {} + local effect + local uses_level = false + local has_plus = false + if def._effect_list then + for name, details in pairs(def._effect_list) do + effect = mcl_potions.registered_effects[name] + if effect then + local ulvl + if details.uses_level ~= nil then ulvl = details.uses_level + else ulvl = effect.uses_factor end + if ulvl then uses_level = true end + local durvar = true + if details.dur_variable ~= nil then durvar = details.dur_variable end + if durvar then has_plus = true end + pdef._effect_list[name] = { + uses_level = ulvl, + level = details.level or 1, + level_scaling = details.level_scaling or 1, + dur = details.dur or mcl_potions.DURATION, + dur_variable = durvar, + effect_stacks = details.effect_stacks and true or false + } + else + error("Unable to register potion: effect not registered") end end + end + if def.uses_level ~= nil then uses_level = def.uses_level end + pdef.uses_level = uses_level + if def.has_potent ~= nil then pdef.has_potent = def.has_potent + else pdef.has_potent = uses_level end + pdef._default_potent_level = def.default_potent_level or 2 + pdef._default_extend_level = def.default_extend_level or 1 + pdef.has_plus = has_plus + local on_use + if def.drinkable ~= false then + on_use = generate_on_use(pdef._effect_list, color, def.custom_on_use, def.custom_effect) + end + pdef.on_place = on_use + pdef.on_secondary_use = on_use + local internal_def = table.copy(pdef) + minetest.register_craftitem(modname..":"..name, pdef) + + if def.has_splash or def.has_splash == nil then + local splash_desc = S("Splash @1", pdef.description) + local sdef = {} + sdef._tt = def._tt + sdef._dynamic_tt = def._dynamic_tt + sdef._longdesc = def._longdesc + sdef.nocreative = def.nocreative + sdef.stack_max = pdef.stack_max + sdef._effect_list = pdef._effect_list + sdef.uses_level = uses_level + sdef.has_potent = pdef.has_potent + sdef.has_plus = has_plus + sdef._default_potent_level = pdef._default_potent_level + sdef._default_extend_level = pdef._default_extend_level + sdef.custom_effect = def.custom_effect + sdef.on_splash = def.custom_splash_effect + if not def._effect_list then sdef.instant = true end + mcl_potions.register_splash(name, splash_desc, color, sdef) + internal_def.has_splash = true end - if def.is_plus then - - local dur_pl = dur * mcl_potions.PLUS_FACTOR - if def.name == "poison" or def.name == "regeneration" then - dur_pl = 90 - end - - on_use = return_on_use(def, def.effect, dur_pl) - - minetest.register_craftitem("mcl_potions:"..def.name.."_plus", { - description = S("@1 + Potion", def.description), - _tt_help = get_tt(def._tt_plus, def.effect, dur_pl), - _doc_items_longdesc = potion_longdesc, - _doc_items_usagehelp = potion_usagehelp, - stack_max = 1, - inventory_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}, - on_place = on_use, - on_secondary_use = on_use, - }) - - -- Register Splash - local splash_dur_pl = dur_pl * mcl_potions.SPLASH_FACTOR - local ling_dur_pl = dur_pl * mcl_potions.LINGERING_FACTOR - - local splash_def_pl = { - tt = get_tt(def._tt_plus, def.effect, splash_dur_pl), - longdesc = def._longdesc, - potion_fun = get_splash_fun(def.effect, splash_dur_pl), - no_effect = def.no_effect, - instant = def.instant, - } - local ling_def_pl = { - tt = get_tt(def._tt_plus, def.effect, ling_dur_pl), - longdesc = def._longdesc, - potion_fun = get_lingering_fun(def.effect, ling_dur_pl), - no_effect = def.no_effect, - instant = def.instant, - } - local arrow_def_pl = { - tt = get_tt(def._tt_pl, def.effect, dur_pl/8.), - longdesc = def._longdesc, - potion_fun = get_arrow_fun(def.effect, dur_pl/8.), - no_effect = def.no_effect, - instant = def.instant, - } - if def.color and not def.no_throwable then - mcl_potions.register_splash(def.name.."_plus", S("Splash @1 + Potion", def.description), def.color, splash_def_pl) - mcl_potions.register_lingering(def.name.."_plus", S("Lingering @1 + Potion", def.description), def.color, ling_def_pl) - if not def.no_arrow then - mcl_potions.register_arrow(def.name.."_plus", S("Arrow of @1 +", def.description), def.color, arrow_def_pl) - end - end - + if def.has_lingering or def.has_lingering == nil then + local ling_desc = S("Lingering @1", pdef.description) + local ldef = {} + ldef._tt = def._tt + ldef._dynamic_tt = def._dynamic_tt + ldef._longdesc = def._longdesc + ldef.nocreative = def.nocreative + ldef.stack_max = pdef.stack_max + ldef._effect_list = pdef._effect_list + ldef.uses_level = uses_level + ldef.has_potent = pdef.has_potent + ldef.has_plus = has_plus + ldef._default_potent_level = pdef._default_potent_level + ldef._default_extend_level = pdef._default_extend_level + ldef.custom_effect = def.custom_effect + ldef.on_splash = def.custom_splash_effect + ldef.while_lingering = def.custom_linger_effect + if not def._effect_list then ldef.instant = true end + mcl_potions.register_lingering(name, ling_desc, color, ldef) + internal_def.has_lingering = true end + if def.has_arrow then + local arr_desc + if def.desc_prefix and def.desc_suffix then + arr_desc = S("@1 Arrow @2", def.desc_prefix, def.desc_suffix) + elseif def.desc_prefix then + arr_desc = S("@1 Arrow", def.desc_prefix) + elseif def.desc_suffix then + arr_desc = S("Arrow @1", def.desc_suffix) + else + arr_desc = S("Strange Tipped Arrow") + end + local adef = {} + adef._tt = def._tt + adef._dynamic_tt = def._dynamic_tt + adef._longdesc = def._longdesc + adef.nocreative = def.nocreative + adef._effect_list = pdef._effect_list + adef.uses_level = uses_level + adef.has_potent = pdef.has_potent + adef.has_plus = has_plus + adef._default_potent_level = pdef._default_potent_level + adef._default_extend_level = pdef._default_extend_level + adef.custom_effect = def.custom_effect + if not def._effect_list then adef.instant = true end + mcl_potions.register_arrow(name, arr_desc, color, adef) + internal_def.has_arrow = true + end + + mcl_potions.registered_potions[modname..":"..name] = internal_def end +mcl_potions.register_potion({ + name = "trolling", + desc_prefix = S("Mighty"), + desc_suffix = S("of Trolling"), + _tt = "trololo", + _dynamic_tt = function(level) + return "trolololoooololo" + end, + _longdesc = "Trolololololo", + stack_max = 2, + color = "#00AA00", + nocreative = true, + _effect_list = { + night_vision = {}, + strength = {}, + swiftness = { + uses_level = false, + level = 2, + }, + poison = { + dur = 10, + }, + }, + default_potent_level = 5, + default_extend_level = 3, + custom_splash_effect = mcl_potions._extinguish_nearby_fire, + has_arrow = true, +}) + + -- ██████╗░░█████╗░████████╗██╗░█████╗░███╗░░██╗ -- ██╔══██╗██╔══██╗╚══██╔══╝██║██╔══██╗████╗░██║ @@ -399,330 +355,527 @@ end -- ╚═════╝░╚══════╝╚═╝░░░░░╚═╝╚═╝░░╚══╝╚═╝░░░╚═╝░░░╚═╝░╚════╝░╚═╝░░╚══╝╚═════╝░ -local awkward_def = { +minetest.register_craftitem("mcl_potions:dragon_breath", { + description = S("Dragon's Breath"), + _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", + groups = { brewitem = 1, bottle = 1 }, + stack_max = 64, +}) + +mcl_potions.register_potion({ name = "awkward", - description_potion = S("Awkward Potion"), - description_splash = S("Awkward Splash Potion"), - description_lingering = S("Awkward Lingering Potion"), - no_arrow = true, - no_effect = true, + desc_prefix = S("Awkward"), _tt = S("No effect"), _longdesc = S("Has an awkward taste and is used for brewing potions."), color = "#0000FF", - groups = {brewitem=1, food=3, can_eat_when_full=1}, - on_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), -} +}) -local mundane_def = { +mcl_potions.register_potion({ name = "mundane", - description_potion = S("Mundane Potion"), - description_splash = S("Mundane Splash Potion"), - description_lingering = S("Mundane Lingering Potion"), - no_arrow = true, - no_effect = true, + desc_prefix = S("Mundane"), _tt = S("No effect"), - _longdesc = S("Has a terrible taste and is not useful for brewing potions."), + _longdesc = S("Has a terrible taste and is not really useful for brewing potions."), color = "#0000FF", - on_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), -} +}) -local thick_def = { +mcl_potions.register_potion({ name = "thick", - description_potion = S("Thick Potion"), - description_splash = S("Thick Splash Potion"), - description_lingering = S("Thick Lingering Potion"), - no_arrow = true, - no_effect = true, + desc_prefix = S("Thick"), _tt = S("No effect"), - _longdesc = S("Has a bitter taste and is not useful for brewing potions."), + _longdesc = S("Has a bitter taste and may be useful for brewing potions."), color = "#0000FF", - on_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), -} +}) -local dragon_breath_def = { - name = "dragon_breath", - description = S("Dragon's Breath"), - no_arrow = true, - no_potion = true, - no_throwable = true, - no_effect = true, - _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", - groups = { brewitem = 1 }, - on_use = nil, - stack_max = 64, -} - -local healing_def = { +mcl_potions.register_potion({ name = "healing", - description = S("Healing"), - _tt = S("+4 HP"), - _tt_2 = S("+8 HP"), + desc_suffix = S("of Healing"), + _dynamic_tt = function(level) + return S("+@1 HP", 4 * level) + end, _longdesc = S("Instantly heals."), color = "#F82423", - effect = 4, - instant = true, - on_use = mcl_potions.healing_func, - is_II = true, -} + uses_level = true, + has_arrow = true, + custom_effect = function(object, level) + return mcl_potions.healing_func(object, 4 * level) + end, +}) - -local harming_def = { +mcl_potions.register_potion({ name = "harming", - description = S("Harming"), - _tt = S("-6 HP"), - _tt_II = S("-12 HP"), + desc_suffix = S("of Harming"), + _dynamic_tt = function(level) + return S("-@1 HP", 6 * level) + end, _longdesc = S("Instantly deals damage."), color = "#430A09", - effect = -6, - instant = true, - on_use = mcl_potions.healing_func, - is_II = true, - is_inv = true, -} + uses_level = true, + has_arrow = true, + custom_effect = function(object, level) + return mcl_potions.healing_func(object, -6 * level) + end, +}) -local night_vision_def = { +mcl_potions.register_potion({ name = "night_vision", - description = S("Night Vision"), + desc_suffix = S("of Night Vision"), _tt = nil, _longdesc = S("Increases the perceived brightness of light under a dark sky."), color = "#1F1FA1", - effect = nil, - is_dur = true, - on_use = mcl_potions.night_vision_func, - is_plus = true, -} + _effect_list = { + night_vision = {}, + }, + has_arrow = true, +}) -local swiftness_def = { +mcl_potions.register_potion({ name = "swiftness", - description = S("Swiftness"), + desc_suffix = S("of Swiftness"), _tt = nil, _longdesc = S("Increases walking speed."), color = "#7CAFC6", - effect = 1.2, - is_dur = true, - on_use = mcl_potions.swiftness_func, - is_II = true, - is_plus = true, -} + _effect_list = { + swiftness = {}, + }, + has_arrow = true, +}) -local slowness_def = { +mcl_potions.register_potion({ name = "slowness", - description = S("Slowness"), + desc_suffix = S("of Slowness"), _tt = nil, _longdesc = S("Decreases walking speed."), color = "#5A6C81", - effect = 0.85, - is_dur = true, - on_use = mcl_potions.swiftness_func, - is_II = true, - is_plus = true, - is_inv = true, -} + _effect_list = { + slowness = {dur=mcl_potions.DURATION_INV}, + }, + default_potent_level = 4, + has_arrow = true, +}) -local leaping_def = { +mcl_potions.register_potion({ name = "leaping", - description = S("Leaping"), + desc_suffix = S("of Leaping"), _tt = nil, _longdesc = S("Increases jump strength."), color = "#22FF4C", - effect = 1.15, - is_dur = true, - on_use = mcl_potions.leaping_func, - is_II = true, - is_plus = true, -} + _effect_list = { + leaping = {}, + }, + has_arrow = true, +}) -local poison_def = { +mcl_potions.register_potion({ + name = "withering", + desc_suffix = S("of Withering"), + _tt = nil, + _longdesc = S("Applies the withering effect which deals damage at a regular interval and can kill."), + color = "#292929", + _effect_list = { + withering = {dur=mcl_potions.DURATION_POISON}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ name = "poison", - description = S("Poison"), + desc_suffix = S("of Poison"), _tt = nil, _longdesc = S("Applies the poison effect which deals damage at a regular interval."), color = "#4E9331", - effect = 2.5, - is_dur = true, - on_use = mcl_potions.poison_func, - is_II = true, - is_plus = true, - is_inv = true, -} + _effect_list = { + poison = {dur=mcl_potions.DURATION_POISON}, + }, + has_arrow = true, +}) -local regeneration_def = { +mcl_potions.register_potion({ name = "regeneration", - description = S("Regeneration"), + desc_suffix = S("of Regeneration"), _tt = nil, _longdesc = S("Regenerates health over time."), color = "#CD5CAB", - effect = 2.5, - is_dur = true, - on_use = mcl_potions.regeneration_func, - is_II = true, - is_plus = true, -} + _effect_list = { + regeneration = {dur=mcl_potions.DURATION_POISON}, + }, + has_arrow = true, +}) -local invisibility_def = { +mcl_potions.register_potion({ name = "invisibility", - description = S("Invisibility"), + desc_suffix = S("of Invisibility"), _tt = nil, _longdesc = S("Grants invisibility."), color = "#7F8392", - is_dur = true, - on_use = mcl_potions.invisiblility_func, - is_plus = true, -} + _effect_list = { + invisibility = {}, + }, + has_arrow = true, +}) -local water_breathing_def = { +mcl_potions.register_potion({ name = "water_breathing", - description = S("Water Breathing"), + desc_suffix = S("of Water Breathing"), _tt = nil, _longdesc = S("Grants limitless breath underwater."), color = "#2E5299", - is_dur = true, - on_use = mcl_potions.water_breathing_func, - is_plus = true, -} + _effect_list = { + water_breathing = {}, + }, + has_arrow = true, +}) -local fire_resistance_def = { +mcl_potions.register_potion({ name = "fire_resistance", - description = S("Fire Resistance"), + desc_suffix = S("of Fire Resistance"), _tt = nil, _longdesc = S("Grants immunity to damage from heat sources like fire."), color = "#E49A3A", - is_dur = true, - on_use = mcl_potions.fire_resistance_func, - is_plus = true, + _effect_list = { + fire_resistance = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "strength", + desc_suffix = S("of Strength"), + _tt = nil, + _longdesc = S("Increases attack power."), + color = "#932423", + _effect_list = { + strength = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "weakness", + desc_suffix = S("of Weakness"), + _tt = nil, + _longdesc = S("Decreases attack power."), + color = "#484D48", + _effect_list = { + weakness = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "slow_falling", + desc_suffix = S("of Slow Falling"), + _tt = nil, + _longdesc = S("Instead of falling, you descend gracefully."), + color = "#ACCCFF", + _effect_list = { + slow_falling = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "levitation", + desc_suffix = S("of Levitation"), + _tt = nil, + _longdesc = S("Floats body slowly upwards."), + color = "#420E7E", + _effect_list = { + levitation = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "darkness", + desc_suffix = S("of Darkness"), + _tt = nil, + _longdesc = S("Surrounds with darkness."), + color = "#000000", + _effect_list = { + darkness = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "glowing", + desc_suffix = S("of Glowing"), + _tt = nil, + _longdesc = S("Highlights for others to see."), + color = "#FFFF77", + _effect_list = { + glowing = {}, + }, + has_arrow = false, -- TODO add a spectral arrow instead (in mcl_bows?) +}) + +mcl_potions.register_potion({ + name = "health_boost", + desc_suffix = S("of Health Boost"), + _tt = nil, + _longdesc = S("Increases health."), + color = "#BE1919", + _effect_list = { + health_boost = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "absorption", + desc_suffix = S("of Absorption"), + _tt = nil, + _longdesc = S("Absorbs some incoming damage."), + color = "#B59500", + _effect_list = { + absorption = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "resistance", + desc_suffix = S("of Resistance"), + _tt = nil, + _longdesc = S("Decreases damage taken."), + color = "#2552A5", + _effect_list = { + resistance = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "stone_cloak", + desc_suffix = S("of Stone Cloak"), + _tt = nil, + _longdesc = S("Decreases damage taken at the cost of speed."), + color = "#255235", + _effect_list = { + resistance = { + level = 3, + dur = 20, + }, + slowness = { + level = 4, + level_scaling = 2, + dur = 20, + }, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "luck", + desc_suffix = S("of Luck"), + _tt = nil, + _longdesc = S("Increases luck."), + color = "#7BFF42", + _effect_list = { + luck = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "bad_luck", + desc_suffix = S("of Bad Luck"), + _tt = nil, + _longdesc = S("Decreases luck."), + color = "#887343", + _effect_list = { + bad_luck = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "frost", + desc_suffix = S("of Frost"), + _tt = nil, + _longdesc = S("Freezes..."), + color = "#5B7DAA", + _effect_list = { + frost = { + dur = mcl_potions.DURATION_POISON, + effect_stacks = true, + }, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "blindness", + desc_suffix = S("of Blindness"), + _tt = nil, + _longdesc = S("Impairs sight."), + color = "#586868", + _effect_list = { + blindness = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "nausea", + desc_suffix = S("of Nausea"), + _tt = nil, + _longdesc = S("Disintegrates senses."), + color = "#715C7F", + _effect_list = { + nausea = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "food_poisoning", + desc_suffix = S("of Food Poisoning"), + _tt = nil, + _longdesc = S("Moves bowels too fast."), + color = "#83A061", + _effect_list = { + food_poisoning = { + dur = mcl_potions.DURATION_POISON, + effect_stacks = true, + }, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "saturation", + desc_suffix = S("of Saturation"), + _tt = nil, + _longdesc = S("Satisfies hunger."), + color = "#CEAE29", + _effect_list = { + saturation = {dur=mcl_potions.DURATION_POISON}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "haste", + desc_suffix = S("of Haste"), + _tt = nil, + _longdesc = S("Increases digging and attack speed."), + color = "#FFFF00", + _effect_list = { + haste = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "fatigue", + desc_suffix = S("of Fatigue"), + _tt = nil, + _longdesc = S("Decreases digging and attack speed."), + color = "#64643D", + _effect_list = { + fatigue = {}, + }, + has_arrow = true, +}) + +mcl_potions.register_potion({ + name = "ominous", + desc_prefix = S("Ominous"), + _tt = nil, + _longdesc = S("Attracts danger."), + image = table.concat({ + "(mcl_potions_potion_overlay.png^[colorize:red:100)", + "^mcl_potions_splash_overlay.png^[colorize:black:100", + "^mcl_potions_potion_bottle.png", + }), + _effect_list = { + bad_omen = {dur = 6000}, + }, + has_splash = false, + has_lingering = false, +}) + + + + +-- COMPAT CODE +local function replace_legacy_potion(itemstack) + local name = itemstack:get_name() + local suffix = "" + local bare_name = name:match("^(.+)_splash$") + if bare_name then + suffix = "_splash" + else + bare_name = name:match("^(.+)_lingering$") + if bare_name then + suffix = "_lingering" + else + bare_name = name:match("^(.+)_arrow$") + if bare_name then + suffix = "_arrow" + else + bare_name = name + end + end + end + local new_name = bare_name:match("^(.+)_plus$") + local new_stack + if new_name then + new_stack = ItemStack(new_name..suffix) + new_stack:get_meta():set_int("mcl_potions:potion_plus", + registered_potions[new_name]._default_extend_level) + new_stack:set_count(itemstack:get_count()) + tt.reload_itemstack_description(new_stack) + end + new_name = bare_name:match("^(.+)_2$") + if new_name then + new_stack = ItemStack(new_name..suffix) + new_stack:get_meta():set_int("mcl_potions:potion_potent", + registered_potions[new_name]._default_potent_level-1) + new_stack:set_count(itemstack:get_count()) + tt.reload_itemstack_description(new_stack) + end + return new_stack +end +local compat = "mcl_potions:compat_potion" +local compat_arrow = "mcl_potions:compat_arrow" +local compat_def = { + description = S("Unknown Potion") .. "\n" .. minetest.colorize("#ff0", S("Right-click to identify")), + image = "mcl_potions_potion_overlay.png^[colorize:#00F:127^mcl_potions_potion_bottle.png^vl_unknown.png", + groups = {not_in_creative_inventory = 1}, + on_secondary_use = replace_legacy_potion, + on_place = replace_legacy_potion, +} +local compat_arrow_def = { + description = S("Unknown Tipped Arrow") .. "\n" .. minetest.colorize("#ff0", S("Right-click to identify")), + image = "mcl_bows_arrow_inv.png^(mcl_potions_arrow_inv.png^[colorize:#FFF:100)^vl_unknown.png", + groups = {not_in_creative_inventory = 1}, + on_secondary_use = replace_legacy_potion, + on_place = replace_legacy_potion, +} +minetest.register_craftitem(compat, compat_def) +minetest.register_craftitem(compat_arrow, compat_arrow_def) + +local old_potions_plus = { + "fire_resistance", "water_breathing", "invisibility", "regeneration", "poison", + "withering", "leaping", "slowness", "swiftness", "night_vision" +} +local old_potions_2 = { + "healing", "harming", "swiftness", "slowness", "leaping", + "withering", "poison", "regeneration" } - - -local defs = { awkward_def, mundane_def, thick_def, dragon_breath_def, - healing_def, harming_def, night_vision_def, swiftness_def, - slowness_def, leaping_def, poison_def, regeneration_def, - invisibility_def, water_breathing_def, fire_resistance_def} - -for _, def in ipairs(defs) do - register_potion(def) +for _, name in pairs(old_potions_2) do + minetest.register_craftitem("mcl_potions:" .. name .. "_2", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_2_splash", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_2_lingering", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_2_arrow", compat_arrow_def) +end +for _, name in pairs(old_potions_plus) do + minetest.register_craftitem("mcl_potions:" .. name .. "_plus", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_plus_splash", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_plus_lingering", compat_def) + minetest.register_craftitem("mcl_potions:" .. name .. "_plus_arrow", compat_arrow_def) end - - - - --- minetest.register_craftitem("mcl_potions:weakness", { --- description = S("Weakness"), --- _tt_help = TODO, --- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#484D48"), --- inventory_image = potion_image("#484D48"), --- groups = { brewitem=1, food=3, can_eat_when_full=1 }, --- stack_max = 1, --- --- on_place = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, -4, mcl_potions.DURATION*mcl_potions.INV_FACTOR) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#484D48") --- return itemstack --- end, --- --- on_secondary_use = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, -4, mcl_potions.DURATION*mcl_potions.INV_FACTOR) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#484D48") --- return itemstack --- end --- }) --- --- minetest.register_craftitem("mcl_potions:weakness_plus", { --- description = S("Weakness +"), --- _tt_help = TODO, --- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#484D48"), --- inventory_image = potion_image("#484D48"), --- groups = { brewitem=1, food=3, can_eat_when_full=1 }, --- stack_max = 1, --- --- on_place = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, -4, mcl_potions.DURATION_2*mcl_potions.INV_FACTOR) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#484D48") --- return itemstack --- end, --- --- on_secondary_use = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, -4, mcl_potions.DURATION_2*mcl_potions.INV_FACTOR) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#484D48") --- return itemstack --- end --- }) --- --- minetest.register_craftitem("mcl_potions:strength", { --- description = S("Strength"), --- _tt_help = TODO, --- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#932423"), --- inventory_image = potion_image("#932423"), --- groups = { brewitem=1, food=3, can_eat_when_full=1 }, --- stack_max = 1, --- --- on_place = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 3, mcl_potions.DURATION) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end, --- --- on_secondary_use = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 3, mcl_potions.DURATION) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end --- }) --- --- minetest.register_craftitem("mcl_potions:strength_2", { --- description = S("Strength II"), --- _tt_help = TODO, --- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#932423"), --- inventory_image = potion_image("#932423"), --- groups = { brewitem=1, food=3, can_eat_when_full=1 }, --- stack_max = 1, --- --- on_place = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 6, mcl_potions.DURATION_2) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end, --- --- on_secondary_use = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 6, mcl_potions.DURATION_2) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end --- }) --- --- minetest.register_craftitem("mcl_potions:strength_plus", { --- description = S("Strength +"), --- _tt_help = TODO, --- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#932423"), --- inventory_image = potion_image("#932423"), --- groups = { brewitem=1, food=3, can_eat_when_full=1 }, --- stack_max = 1, --- --- on_place = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 3, mcl_potions.DURATION_PLUS) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end, --- --- on_secondary_use = function(itemstack, user, pointed_thing) --- mcl_potions.weakness_func(user, 3, mcl_potions.DURATION_PLUS) --- minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) --- mcl_potions._use_potion(itemstack, user, "#932423") --- return itemstack --- end --- }) diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index 730796952..591bb30e4 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -13,20 +13,30 @@ end function mcl_potions.register_splash(name, descr, color, def) local id = "mcl_potions:"..name.."_splash" - local longdesc = def.longdesc + local longdesc = def._longdesc if not def.no_effect then - longdesc = S("A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.") - if def.longdesc then - longdesc = longdesc .. "\n" .. def.longdesc + longdesc = S("A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect or a set of status effects.") + if def._longdesc then + longdesc = longdesc .. "\n" .. def._longdesc end end + local groups = {brewitem=1, bottle=1, splash_potion=1, _mcl_potion=1} + if def.nocreative then groups.not_in_creative_inventory = 1 end minetest.register_craftitem(id, { description = descr, - _tt_help = def.tt, + _tt_help = def._tt, + _dynamic_tt = def._dynamic_tt, _doc_items_longdesc = longdesc, _doc_items_usagehelp = S("Use the “Punch” key to throw it."), + stack_max = def.stack_max, + _effect_list = def._effect_list, + uses_level = def.uses_level, + has_potent = def.has_potent, + has_plus = def.has_plus, + _default_potent_level = def._default_potent_level, + _default_extend_level = def._default_extend_level, inventory_image = splash_image(color), - groups = {brewitem=1, not_in_creative_inventory=0}, + groups = groups, on_use = function(item, placer, pointed_thing) local velocity = 10 local dir = placer:get_look_dir(); @@ -35,7 +45,11 @@ function mcl_potions.register_splash(name, descr, color, def) local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying") obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity}) obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3}) - obj:get_luaentity()._thrower = placer:get_player_name() + local ent = obj:get_luaentity() + ent._thrower = placer:get_player_name() + ent._potency = item:get_meta():get_int("mcl_potions:potion_potent") + ent._plus = item:get_meta():get_int("mcl_potions:potion_plus") + ent._effect_list = def._effect_list if not minetest.is_creative_enabled(placer:get_player_name()) then item:take_item() end @@ -50,6 +64,10 @@ function mcl_potions.register_splash(name, descr, color, def) local velocity = 22 obj:set_velocity({x=dropdir.x*velocity,y=dropdir.y*velocity,z=dropdir.z*velocity}) obj:set_acceleration({x=dropdir.x*-3, y=-9.8, z=dropdir.z*-3}) + local ent = obj:get_luaentity() + ent._potency = stack:get_meta():get_int("mcl_potions:potion_potent") + ent._plus = stack:get_meta():get_int("mcl_potions:potion_plus") + ent._effect_list = def._effect_list end }) @@ -103,24 +121,58 @@ function mcl_potions.register_splash(name, descr, color, def) texture = texture.."^[colorize:"..color..":127" }) - if name == "water" then - mcl_potions._extinguish_nearby_fire(pos) - end - self.object:remove() + local potency = self._potency or 0 + local plus = self._plus or 0 + + if def.on_splash then def.on_splash(pos, potency+1) end for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do local entity = obj:get_luaentity() - if obj:is_player() or entity.is_mob then + if obj:is_player() or entity and entity.is_mob then local pos2 = obj:get_pos() local rad = math.floor(math.sqrt((pos2.x-pos.x)^2 + (pos2.y-pos.y)^2 + (pos2.z-pos.z)^2)) - if rad > 0 then - def.potion_fun(obj, redux_map[rad]) - else - def.potion_fun(obj, 1) + + if def._effect_list then + local ef_level + local dur + for name, details in pairs(def._effect_list) do + if details.uses_level then + ef_level = details.level + details.level_scaling * (potency) + else + ef_level = details.level + end + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) + if potency>0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency) + end + dur = dur * mcl_potions.SPLASH_FACTOR + else + dur = details.dur + end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end + if rad > 0 then + mcl_potions.give_effect_by_level(name, obj, ef_level, redux_map[rad]*dur) + else + mcl_potions.give_effect_by_level(name, obj, ef_level, dur) + end + end + end + + if def.custom_effect then + local power = (potency+1) * mcl_potions.SPLASH_FACTOR + if rad > 0 then + def.custom_effect(obj, redux_map[rad] * power, plus) + else + def.custom_effect(obj, power, plus) + end end end end + self.object:remove() end end, diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index 53a37705e..1833e7169 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -37,16 +37,26 @@ local arrow_tt = minetest.registered_items["mcl_bows:arrow"]._tt_help or "" function mcl_potions.register_arrow(name, desc, color, def) - local longdesc = def.longdesc or "" + local longdesc = def._longdesc or "" + local tt = def._tt or "" + local groups = {ammo=1, ammo_bow=1, brewitem=1, _mcl_potion=1} + if def.nocreative then groups.not_in_creative_inventory = 1 end minetest.register_craftitem("mcl_potions:"..name.."_arrow", { description = desc, - _tt_help = arrow_tt .. "\n" .. def.tt, + _tt_help = arrow_tt .. "\n" .. tt, + _dynamic_tt = def._dynamic_tt, _doc_items_longdesc = arrow_longdesc .. "\n" .. S("This particular arrow is tipped and will give an effect when it hits a player or mob.") .. "\n" .. longdesc, _doc_items_usagehelp = how_to_shoot, + _effect_list = def._effect_list, + uses_level = def.uses_level, + has_potent = def.has_potent, + has_plus = def.has_plus, + _default_potent_level = def._default_potent_level, + _default_extend_level = def._default_extend_level, inventory_image = "mcl_bows_arrow_inv.png^(mcl_potions_arrow_inv.png^[colorize:"..color..":100)", - groups = { ammo=1, ammo_bow=1, brewitem=1}, + groups = groups, _on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir) -- Shoot arrow local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) @@ -264,21 +274,72 @@ function mcl_potions.register_arrow(name, desc, color, def) end end + local potency = self._potency or 0 + local plus = self._plus or 0 + -- Punch target object but avoid hurting enderman. if lua then - if lua.name ~= "mobs_mc:enderman" then + if lua.name ~= "mobs_mc:rover" then obj:punch(self.object, 1.0, { full_punch_interval=1.0, damage_groups={fleshy=self._damage}, }, nil) - def.potion_fun(obj) + if def._effect_list then + local ef_level + local dur + for name, details in pairs(def._effect_list) do + if details.uses_level then + ef_level = details.level + details.level_scaling * (potency) + else + ef_level = details.level + end + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) + if potency>0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency) + end + else + dur = details.dur + end + dur = dur * mcl_potions.SPLASH_FACTOR + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end + mcl_potions.give_effect_by_level(name, obj, ef_level, dur) + end + end + if def.custom_effect then def.custom_effect(obj, potency+1, plus) end end else obj:punch(self.object, 1.0, { full_punch_interval=1.0, damage_groups={fleshy=self._damage}, }, nil) - def.potion_fun(obj) + if def._effect_list then + local ef_level + local dur + for name, details in pairs(def._effect_list) do + if details.uses_level then + ef_level = details.level + details.level_scaling * (potency) + else + ef_level = details.level + end + if details.dur_variable then + dur = details.dur * math.pow(mcl_potions.PLUS_FACTOR, plus) + if potency>0 and details.uses_level then + dur = dur / math.pow(mcl_potions.POTENT_FACTOR, potency) + end + else + dur = details.dur + end + dur = dur * mcl_potions.SPLASH_FACTOR + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end + mcl_potions.give_effect_by_level(name, obj, ef_level, dur) + end + end + if def.custom_effect then def.custom_effect(obj, potency+1, plus) end end if is_player then diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.pt_BR.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.pt_BR.tr new file mode 100644 index 000000000..810557d4a --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.pt_BR.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=Ferro Cru +Raw Gold=Ouro Cru +Raw iron. Mine an iron ore to get it.=Ferro cru. Minere um minério de ferro para obtê-lo. +Raw gold. Mine a gold ore to get it.=Ouro cru. Minere um minério de ouro para obtê-lo. +Block of Raw Iron=Bloco de Ferro Cru +Block of Raw Gold=Bloco de Ouro Cru +A block of raw iron is mostly a decorative block but also useful as a compact storage of raw iron.=Um bloco de ferro cru é majoritariamente um bloco decorativo mas também útil como um armazenamento compacto de ferro cru. +A block of raw gold is mostly a decorative block but also useful as a compact storage of raw gold.=Um bloco de ouro cru é majoritariamente um bloco decorativo mas também útil como um armazenamento compacto de ouro cru. diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ru.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ru.tr new file mode 100644 index 000000000..0b31319b9 --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ru.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=Необработанное железо +Raw Gold=Необработанное золото +Raw iron. Mine an iron ore to get it.=Необработанное железо. Добудьте железную руду, чтобы получить это. +Raw gold. Mine a gold ore to get it.=Необработанное золото. Добудьте золотую руду, чтобы получить это. +Block of Raw Iron=Блок необработанного железа +Block of Raw Gold=Блок необработанного золота +A block of raw iron is mostly a decorative block but also useful as a compact storage of raw iron.=Блок необработанного железа. Декоративный блок, но также подходит для компактного хранения необработанного железа. +A block of raw gold is mostly a decorative block but also useful as a compact storage of raw gold.=Блок необработанного золота. Декоративный блок, но также подходит для компактного хранения необработанного золота. \ No newline at end of file diff --git a/mods/ITEMS/mcl_sculk/init.lua b/mods/ITEMS/mcl_sculk/init.lua index b2ef04152..4af60178e 100644 --- a/mods/ITEMS/mcl_sculk/init.lua +++ b/mods/ITEMS/mcl_sculk/init.lua @@ -215,9 +215,23 @@ minetest.register_node("mcl_sculk:vein", { type = "wallmounted", }, groups = { - handy = 1, axey = 1, shearsy = 1, swordy = 1, deco_block = 1, - dig_by_piston = 1, destroy_by_lava_flow = 1, sculk = 1, dig_by_water = 1, + handy = 1, + axey = 1, + shearsy = 1, + swordy = 1, + deco_block = 1, + dig_by_piston = 1, + destroy_by_lava_flow = 1, + sculk = 1, + dig_by_water = 1, + ladder = 1 }, + after_destruct = function(pos, old) + mcl_core.update_trapdoor(pos, "destruct") + end, + after_place_node = function(pos) + mcl_core.update_trapdoor(pos, "place") + end, sounds = sounds, drop = "", _mcl_shears_drop = true, diff --git a/mods/ITEMS/mcl_sculk/locale/mcl_sculk.pt_BR.tr b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.pt_BR.tr new file mode 100644 index 000000000..bbafc5c76 --- /dev/null +++ b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.pt_BR.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_sculk +Sculk=Sculk +Sculk Vein=Veio Sculk +Sculk vein.=Veio sculk. +Sculk Catalyst=Catalizador Sculk +Sculk Sensor=Sensor Sculk +Sculk Shrieker=Emissor Sculk diff --git a/mods/ITEMS/mcl_sculk/locale/mcl_sculk.ru.tr b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.ru.tr new file mode 100644 index 000000000..df3a4a792 --- /dev/null +++ b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.ru.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_sculk +Sculk=Скалк +Sculk Vein=Скалк-жила +Sculk vein.=Скалк-жила +Sculk Catalyst=Скалк-катализатор +Sculk Sensor=Скалк-сенсор +Sculk Shrieker=Скалк-крикун \ No newline at end of file diff --git a/mods/ITEMS/mcl_shepherd/init.lua b/mods/ITEMS/mcl_shepherd/init.lua new file mode 100644 index 000000000..d06b02f93 --- /dev/null +++ b/mods/ITEMS/mcl_shepherd/init.lua @@ -0,0 +1,91 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + + +minetest.register_tool("mcl_shepherd:shepherd_staff", { + description = S("Shepherd Staff"), + _doc_items_longdesc = S(""), + _doc_items_usagehelp = S(""), + inventory_image = "mcl_tool_shepherd_staff.png", + wield_scale = 1.3*mcl_vars.tool_wield_scale, + stack_max = 1, + groups = { weapon=1, tool=1, staff=1, enchantability=-1 }, + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=1, + damage_groups = {fleshy=2}, + punch_attack_uses = 45, + }, + sound = { breaks = "default_tool_breaks" }, + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 1, level = 1, uses = 60 }, + swordy_cobweb = { speed = 1, level = 1, uses = 60 } + }, + _mcl_not_consumable = true, +}) + +if mcl_util.is_it_christmas() then + minetest.register_globalstep(function(dtime) + local time = minetest.get_timeofday() + if time < 0.005 or time > 0.995 then + for _, player in pairs(minetest.get_connected_players()) do + local meta = player:get_meta() + local sp = meta:get_int("mcl_shepherd:special") + if sp == 0 and player:get_wielded_item():get_definition().groups.staff then + local has_sheep = false + for _, obj in pairs(minetest.get_objects_inside_radius(player:get_pos(), 3)) do + local ent = obj:get_luaentity() + if ent and ent.name == "mobs_mc:sheep" then + has_sheep = true + break + end + end + if has_sheep then + minetest.sound_play( + {name="shepherd-midnight", gain=3, pitch=1.0}, + {to_player=player:get_player_name(), gain=1.0, fade=0.0, pitch=1.0}, + false + ) + meta:set_int("mcl_shepherd:special", 1) + mcl_weather.skycolor.update_sky_color({player}) + minetest.after(45, function(name) + local player = minetest.get_player_by_name(name) + if not player then return end + local meta = player:get_meta() + meta:set_int("mcl_shepherd:special", 0) + mcl_weather.skycolor.update_sky_color({player}) + end, player:get_player_name()) + end + end + end + end + end) + minetest.register_on_joinplayer(function(player) + local meta = player:get_meta() + meta:set_int("mcl_shepherd:special", 0) + end) +end + +minetest.register_craft({ + output = "mcl_shepherd:shepherd_staff", + recipe = { + {"","","mcl_core:stick"}, + {"","mcl_core:stick",""}, + {"mcl_core:stick","",""}, + } +}) +minetest.register_craft({ + output = "mcl_shepherd:shepherd_staff", + recipe = { + {"mcl_core:stick", "", ""}, + {"", "mcl_core:stick", ""}, + {"","","mcl_core:stick"}, + } +}) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_shepherd:shepherd_staff", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_shepherd/mod.conf b/mods/ITEMS/mcl_shepherd/mod.conf new file mode 100644 index 000000000..972e324d0 --- /dev/null +++ b/mods/ITEMS/mcl_shepherd/mod.conf @@ -0,0 +1,4 @@ +name = mcl_shepherd +author = Herowl +depends = mcl_core, mobs_mc, mcl_util +optional_depends = doc diff --git a/mods/ITEMS/mcl_shepherd/sounds/shepherd-midnight.ogg b/mods/ITEMS/mcl_shepherd/sounds/shepherd-midnight.ogg new file mode 100644 index 000000000..ddd6a4e90 Binary files /dev/null and b/mods/ITEMS/mcl_shepherd/sounds/shepherd-midnight.ogg differ diff --git a/mods/ITEMS/mcl_shields/init.lua b/mods/ITEMS/mcl_shields/init.lua index fa7714366..6edee7e89 100644 --- a/mods/ITEMS/mcl_shields/init.lua +++ b/mods/ITEMS/mcl_shields/init.lua @@ -112,16 +112,18 @@ end function mcl_shields.is_blocking(obj) if not obj:is_player() then return end - local blocking = mcl_shields.players[obj].blocking - if blocking <= 0 then - return - end + if mcl_shields.players[obj] then + local blocking = mcl_shields.players[obj].blocking + if blocking <= 0 then + return + end - local shieldstack = obj:get_wielded_item() - if blocking == 1 then - shieldstack = obj:get_inventory():get_stack("offhand", 1) + local shieldstack = obj:get_wielded_item() + if blocking == 1 then + shieldstack = obj:get_inventory():get_stack("offhand", 1) + end + return blocking, shieldstack end - return blocking, shieldstack end mcl_damage.register_modifier(function(obj, damage, reason) diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.pt_BR.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.pt_BR.tr new file mode 100644 index 000000000..1f3c3f09e --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.pt_BR.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Escudo +A shield is a tool used for protecting the player against attacks.=Um escudo é uma ferramenta usada para a proteção do jogador contra ataques. +White Shield=Escudo Branco +Grey Shield=Escudo Cinza +Light Grey Shield=Escudo Cinza Claro +Black Shield=Escudo Preto +Red Shield=Escudo Vermelho +Yellow Shield=Escudo Amarelo +Green Shield=Escudo Verde +Cyan Shield=Escudo Ciano +Blue Shield=Escudo Azul +Magenta Shield=Escudo Magenta +Orange Shield=Escudo Laranja +Purple Shield=Escudo Roxo +Brown Shield=Escudo Marrom +Pink Shield=Escudo Rosa +Lime Shield=Escudo Lima +Light Blue Shield=Escudo Azul Claro diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.ru.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.ru.tr new file mode 100644 index 000000000..bd99547d0 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.ru.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Щит +A shield is a tool used for protecting the player against attacks.=Щит это инструмент, используемый для защиты игрока от атак. +White Shield=Белый щит +Grey Shield=Серый щит +Light Grey Shield=Светло-серый щит +Black Shield=Чёрный щит +Red Shield=Красный щит +Yellow Shield=Жёлтый щит +Green Shield=Зелёный щит +Cyan Shield=Бирюзовый щит +Blue Shield=Синий щит +Magenta Shield=Сиреневый щит +Orange Shield=Оранжевый щит +Purple Shield=Фиолетовый щит +Brown Shield=Коричневый щит +Pink Shield=Розовый щит +Lime Shield=Лаймовый щит +Light Blue Shield=Голубой щит diff --git a/mods/ITEMS/mcl_signs/README.txt b/mods/ITEMS/mcl_signs/README.txt index e4fbead8a..4f7825b79 100644 --- a/mods/ITEMS/mcl_signs/README.txt +++ b/mods/ITEMS/mcl_signs/README.txt @@ -1,8 +1,8 @@ --- -# Mineclone2-Signs +# VoxeLibre Signs --- -A reworking of MineClone 2's mcl_signs to be colorable and made to glow. Requires Minetest and Mineclone2. +A reworking of VoxeLibre's mcl_signs to be colorable and made to glow. Requires Minetest and VoxeLibre. --- Created by Michieal (FaerRaven) @ DateTime: 10/14/22 4:05 PM @@ -23,7 +23,7 @@ License of code and font: MIT License Font source: 04.jp.org, some modifications and additions were made (added support for Latin-1 Supplement) Original font license text states: “YOU MAY USE THEM AS YOU LIKE” (in about.gif file distributed with the font) -License of textures: See README.md in top directory of MineClone 2, with the exception of the following: +License of textures: See README.md in top directory of VoxeLibre, with the exception of the following: default_sign.png, default_sign_dark.png, default_sign_greyscale.png, mcl_signs_sign_dark.png, mcl_signs_sign_greyscale.png are licensed as follows: Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) (https://creativecommons.org/licenses/by-sa/4.0/). @@ -36,9 +36,9 @@ Models author: 22i. Source: https://github.com/22i/amc -Mineclone 2 source code: -https://git.minetest.land/MineClone2/MineClone2 +VoxeLibre source code: +https://git.minetest.land/VoxeLibre/VoxeLibre --- NOTE: This MODule requires Glow Squids in order for all features to work 100% correctly. Glow Squids are currently -in review by the MineClone 2 Team, and should be available soon after this initial release of the new signs. \ No newline at end of file +in review by the VoxeLibre Team, and should be available soon after this initial release of the new signs. diff --git a/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt index e98741137..e5a3878f0 100644 --- a/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt +++ b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt @@ -115,8 +115,8 @@ they get your sign (x3). automatically exist as part of the signs' package. You won't have to change any of your code, it'll just be more functional. :) -* if you have suggestions, comments, etc., please contact me on MineClone 2's Discord server. +* if you have suggestions, comments, etc., please contact me on VoxeLibre's Discord server. And that... is all there is to it! --- written by Michieal. \ No newline at end of file +-- written by Michieal. diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.pt_BR.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.pt_BR.tr new file mode 100644 index 000000000..08d67d573 --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.pt_BR.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_signs +Sign=Placa +Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=Placas podem ser escritas e vêm em duas variantes: Placa de parede e placa de poste. Placas podem ser posicionadas na parte superior e nas laterais de outros blocos, mas não abaixo deles. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=Depois de posicionar a placa, você pode escrever qualquer coisa nela. Você tem 4 linhas de texto com 15 caracteres em cada linha; qualquer coisa além desses limites será perdido. Nem todos os caracteres são suportados. O texto não pode ser alterado uma vez que esse foi escrito; você terá que quebrar e posicionar a placa novamente. Pode ser colorida e pode brilhar. +Enter sign text:=Insira o texto da placa: +Maximum line length: 15=Comprimento máximo da linha: 15 +Maximum lines: 4=Máximo de linhas: 4 +Done=Feito +Can be written=Pode ser escrito +Oak Sign=Placa de Carvalho +Birch Sign=Placa de Bétula +Spruce Sign=Placa de Pinheiro +Dark Oak Sign=Placa de Carvalho Escuro +Jungle Sign=Placa da Selva +Acacia Sign=Placa de Acácia +Mangrove Sign=Placa de Mangue +Warped Hyphae Sign=Placa de Hifas Distorcidas +Crimson Hyphae Sign=Placa de Hifas Carmesim +Bamboo Sign=Placa de Bambu diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr index 279bde614..6e81a7614 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr @@ -1,18 +1,19 @@ # textdomain: mcl_signs Sign=Табличка -Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=На табличках можно писать. Таблички бывают двух видов: настенные и отдельно стоящие. Таблички можно размещать на верхушках и сторонах блоков, но не под блоками. -After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=После установки таблички вы можете написать на ней что-то. Вам доступны 4 строки текста, до 15 символов в каждой; всё, что вы напишете сверх лимита, потеряется. Поддерживаются не все символы. Текст нельзя изменить. Чтобы изменить его, вам придётся сломать табличку и подписать её снова. Можно раскрасить и заставить светиться. -Enter sign text:=Текст на табличке: +Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.=На табличках можно писать. Таблички бывают двух видов: настенные и стоящие отдельно. Таблички можно размещать сверху и сбоку на блоках, но не под блоками. +After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.=После установки таблички вы можете написать на ней что-нибудь. Вам доступны 4 строки текста, до 15 символов в каждой; всё, что вы напишете сверх лимита, потеряется. Поддерживаются не все символы. Текст на уже подписанной табличке нельзя изменить. Чтобы изменить его, вам придётся сломать табличку и подписать её снова. Может быть окрашена и подствечена. +Enter sign text:=Введите текст таблички: Maximum line length: 15=Максимальная длина строки: 15 Maximum lines: 4=Максимум строк: 4 Done=Готово -Can be written=Может быть подписана -Oak Sign=Дубовый знак -Birch Sign=Березовый знак -Spruce Sign=Ель Знак -Dark Oak Sign=Знак темного дуба -Jungle Sign=Знак джунглей -Acacia Sign=Знак акации -Mangrove Sign=Знак мангровых зарослей -Warped Hyphae Sign=Знак искривленных гиф -Crimson Hyphae Sign=Багровый знак гиф +Can be written=Можно написать текст +Oak Sign=Дубовая табличка +Birch Sign=Березовая табличка +Spruce Sign=Еловая табличка +Dark Oak Sign=Табличка из тёмного дуба +Jungle Sign=Табличка из тропического дерева +Acacia Sign=Акациевая табличка +Mangrove Sign=Мангровая табличка +Warped Hyphae Sign=Искаженная табличка +Crimson Hyphae Sign=Багровая табличка +Bamboo Sign=Бамбуковая табличка \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/signs_api.lua b/mods/ITEMS/mcl_signs/signs_api.lua index 7ada6a646..45064077a 100644 --- a/mods/ITEMS/mcl_signs/signs_api.lua +++ b/mods/ITEMS/mcl_signs/signs_api.lua @@ -4,10 +4,7 @@ --- DateTime: 10/14/22 4:05 PM --- ---local logging = minetest.settings:get_bool("mcl_logging_mcl_signs",true) - local DEBUG = minetest.settings:get_bool("mcl_logging_mcl_signs", false) -- special debug setting. - if DEBUG then minetest.log("action", "[mcl_signs] Signs API Loading") end @@ -85,7 +82,7 @@ end mcl_signs = {} -- GLOBALS -mcl_signs.sign_groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, attached_node = 1, dig_by_piston = 1, flammable = -1 } +mcl_signs.sign_groups = { handy = 1, axey = 1, deco_block = 1, material_wood = 1, attached_node = 1, flammable = -1 } --- colors used for wools. mcl_signs.mcl_wool_colors = { unicolor_white = "#FFFFFF", @@ -115,9 +112,6 @@ mcl_signs.registered_signs = {} mcl_signs.registered_signs.wall_signs = {} mcl_signs.registered_signs.standing_signs = {} mcl_signs.registered_signs.hanging_signs = {} -- unused. prepping for future use. --- DEFINE SIGN BASE TYPES -mcl_signs.wall_standard = {} -- initialize -mcl_signs.standing_standard = {} -- initialize function mcl_signs.build_signs_info() local n = 23 / 56 - 1 / 128 -- some required magic number from the original code. @@ -141,37 +135,110 @@ function mcl_signs.build_signs_info() end --- wall signs' & hanging signs' base (definition) -mcl_signs.wall_standard = { - description = S("Sign"), - _tt_help = S("Can be written"), - _doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them."), - _doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow."), - inventory_image = "mcl_signs_default_sign.png", - walkable = false, - is_ground_content = false, - wield_image = "mcl_signs_default_sign.png", - node_placement_prediction = "", - paramtype = "light", - sunlight_propagates = true, - paramtype2 = "wallmounted", - drawtype = "mesh", - mesh = "mcl_signs_signonwallmount.obj", - selection_box = { type = "wallmounted", wall_side = { -0.5, -7 / 28, -0.5, -23 / 56, 7 / 28, 0.5 } }, - tiles = { "mcl_signs_sign.png" }, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - groups = mcl_signs.sign_groups, +-- DEFINE SIGN BASE TYPES +local common_definition = { + _mcl_hardness = 1, + _mcl_blast_resistance = 1, stack_max = 16, sounds = node_sounds, + groups = mcl_signs.sign_groups, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + drawtype = "mesh", + paramtype = "light", + tiles = { "mcl_signs_sign.png" }, + sunlight_propagates = true, + walkable = false, + is_ground_content = false, - on_timer = function(pos) + on_rightclick = function (pos, node, clicker, itemstack, pointed_thing) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Right Click event.") + end + + -- make sure player is clicking + if not clicker or not clicker:is_player() then + return + end + + local item = clicker:get_wielded_item() + local iname = item:get_name() + + local protected = mcl_util.check_position_protection(pos, clicker) + + if node and not protected then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Right Click event on valid node.") + end + + -- handle glow from glow_ink_sac *first* + if (iname == "mcl_mobitems:glow_ink_sac") then + clicker:set_wielded_item(item) + local success = mcl_signs:glow_sign(pos) + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow Success.") + end + itemstack:take_item() + end + return + end + + -- check the wielded item to make sure that it is a dye. + local txt_color = mcl_signs:get_color_for_sign(iname) + if txt_color ~= "false" then + clicker:set_wielded_item(item) + local success = mcl_signs:color_sign(pos, txt_color) + -- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow. + if (iname == "mcl_dye:black") then + success = mcl_signs:glow_sign(pos, true) + if success and DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Glow removal Success.") + end + end + if success then + if DEBUG then + minetest.log("verbose", "[mcl_signs] Sign Color Success.") + end + itemstack:take_item() + end + return + end + + -- No modifier item in hand, open the sign for edition + local old_text = minetest.get_meta(pos):get_string("text") + mcl_signs:show_formspec(clicker, pos, old_text) + end + end, + + on_destruct = function(pos) + mcl_signs:destruct_sign(pos) + end, + + -- Not Useless Code. this force updates the sign. + on_punch = function(pos, node, puncher) + mcl_signs:update_sign(pos) + end, +} + +-- wall signs' & hanging signs' base (definition) +mcl_signs.wall_standard = table.copy(common_definition) +mcl_signs.wall_standard.description = S("Sign") +mcl_signs.wall_standard._tt_help = S("Can be written") +mcl_signs.wall_standard._doc_items_longdesc = S("Signs can be written and come in two variants: Wall sign and sign on a sign post. Signs can be placed on the top and the sides of other blocks, but not below them.") +mcl_signs.wall_standard._doc_items_usagehelp = S("After placing the sign, you can write something on it. You have 4 lines of text with up to 15 characters for each line; anything beyond these limits is lost. Not all characters are supported. The text can not be changed once it has been written; you have to break and place the sign again. Can be colored and made to glow.") +mcl_signs.wall_standard.inventory_image = "mcl_signs_default_sign.png" +mcl_signs.wall_standard.wield_image = "mcl_signs_default_sign.png" +mcl_signs.wall_standard.node_placement_prediction = "" +mcl_signs.wall_standard.paramtype2 = "wallmounted" +mcl_signs.wall_standard.mesh = "mcl_signs_signonwallmount.obj" +mcl_signs.wall_standard.selection_box = { type = "wallmounted", wall_side = { -0.5, -7 / 28, -0.5, -23 / 56, 7 / 28, 0.5 } } +mcl_signs.wall_standard.on_timer = function(pos) -- fix for /ClearObjects mcl_signs:update_sign(pos) -- note: update_sign decides to keep the timer running based on if there is text. -- This prevents every sign from having a timer, when not needed. - end, - - on_place = function(itemstack, placer, pointed_thing) + end +mcl_signs.wall_standard.on_place = function(itemstack, placer, pointed_thing) local above = pointed_thing.above local under = pointed_thing.under @@ -192,9 +259,6 @@ mcl_signs.wall_standard = { end local wdir = minetest.dir_to_wallmounted(dir) - - --local placer_pos = placer:get_pos() - local fdir = minetest.dir_to_facedir(dir) local sign_info @@ -272,18 +336,10 @@ mcl_signs.wall_standard = { minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - mcl_signs:show_formspec(placer, place_pos) + mcl_signs:show_formspec(placer, place_pos, "") return itemstack - end, - on_destruct = function(pos) - mcl_signs:destruct_sign(pos) - end, - - -- Not Useless Code. force updates the sign. - on_punch = function(pos, node, puncher) - mcl_signs:update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) + end +mcl_signs.wall_standard.on_rotate = function(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then local r = screwdriver.rotate.wallmounted(pos, node, mode) node.param2 = r @@ -293,105 +349,21 @@ mcl_signs.wall_standard = { else return false end - end, - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if DEBUG then - minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event.") - end + end - -- make sure player is clicking - if not clicker or not clicker:is_player() then - return - end - local item = clicker:get_wielded_item() - local iname = item:get_name() - - local protected = mcl_util.check_position_protection(pos, clicker) - - if node and not protected then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Wall_Sign Right Click event on valid node.") - end - - -- handle glow from glow_ink_sac *first* - if (iname == "mcl_mobitems:glow_ink_sac") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow Success.") - end - itemstack:take_item() - end - return - end - - -- "mcl_dye:black" is a special case: it makes the sign's lettering black AND removes glow. - if (iname == "mcl_dye:black") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos, true) - mcl_signs:color_sign(pos, mcl_colors.BLACK) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow removal Success.") - end - - itemstack:take_item() - end - return - end - - -- check the wielded item to make sure that it is a dye. - local txt_color = mcl_signs:get_color_for_sign(iname) - if txt_color ~= "false" then - clicker:set_wielded_item(item) - local success = mcl_signs:color_sign(pos, txt_color) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Color Success.") - end - itemstack:take_item() - end - end - end - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} -- standing sign base (definition) -mcl_signs.standing_standard = { - paramtype = "light", - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - sunlight_propagates = true, - walkable = false, - is_ground_content = false, - paramtype2 = "facedir", - drawtype = "mesh", - mesh = "mcl_signs_sign.obj", - selection_box = { type = "fixed", fixed = { -0.2, -0.5, -0.2, 0.2, 0.5, 0.2 } }, - tiles = { "mcl_signs_sign.png" }, - groups = mcl_signs.sign_groups, - drop = "mcl_signs:wall_sign", - stack_max = 16, - sounds = node_sounds, - - on_destruct = function(pos) - mcl_signs:destruct_sign(pos) - end, - - on_timer = function(pos) +mcl_signs.standing_standard = table.copy(common_definition) +mcl_signs.standing_standard.paramtype2 = "facedir" +mcl_signs.standing_standard.mesh = "mcl_signs_sign.obj" +mcl_signs.standing_standard.selection_box = { type = "fixed", fixed = { -0.2, -0.5, -0.2, 0.2, 0.5, 0.2 } } +mcl_signs.standing_standard.drop = "mcl_signs:wall_sign" +mcl_signs.standing_standard.on_timer = function(pos) -- fix for /ClearObjects mcl_signs:update_sign(pos) minetest.get_node_timer(pos):start(40.0) - end, - - -- Not Useless Code. this force updates the sign. - on_punch = function(pos, node, puncher) - mcl_signs:update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) + end +mcl_signs.standing_standard.on_rotate = function(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then node.name = "mcl_signs:standing_sign22_5" minetest.swap_node(pos, node) @@ -400,60 +372,7 @@ mcl_signs.standing_standard = { end mcl_signs:update_sign(pos, nil, nil, true) return true - end, - - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - - if DEBUG then - minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event.") - end - - -- make sure player is clicking - if not clicker or not clicker:is_player() then - return - end - - local item = clicker:get_wielded_item() - local iname = item:get_name() - - local protected = mcl_util.check_position_protection(pos, clicker) - - if node and not protected then - -- handle glow from glow_ink_sac *first* - if DEBUG then - minetest.log("verbose", "[mcl_signs] Standing_Sign Right Click event on valid node.") - end - - if (iname == "mcl_mobitems:glow_ink_sac") then - clicker:set_wielded_item(item) - local success = mcl_signs:glow_sign(pos) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Glow Success.") - end - itemstack:take_item() - end - return - end - - -- check the wielded item to make sure that it is a dye. - local txt_color = mcl_signs:get_color_for_sign(iname) - if txt_color ~= "false" then - clicker:set_wielded_item(item) - local success = mcl_signs:color_sign(pos, txt_color) - if success then - if DEBUG then - minetest.log("verbose", "[mcl_signs] Sign Color Success.") - end - itemstack:take_item() - end - end - end - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} + end -- HELPER FUNCTIONS' VARIABLES local sign_glow = 6 @@ -663,7 +582,7 @@ function mcl_signs.register_sign (modname, color, _name, ttsign) minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - mcl_signs:show_formspec(placer, place_pos) + mcl_signs:show_formspec(placer, place_pos, "") return itemstack end @@ -764,6 +683,15 @@ function mcl_signs.register_sign (modname, color, _name, ttsign) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + + -- register as unpushable + if minetest.get_modpath("mesecons_mvps") then + mesecon.register_mvps_stopper("mcl_signs:wall_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign22_5" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign45" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign67_5" .. _name) + end end --- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign, @@ -907,7 +835,7 @@ function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - mcl_signs:show_formspec(placer, place_pos) + mcl_signs:show_formspec(placer, place_pos, "") return itemstack end minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) @@ -1002,6 +930,14 @@ function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + -- register as unpushable + if minetest.get_modpath("mesecons_mvps") then + mesecon.register_mvps_stopper("mcl_signs:wall_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign22_5" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign45" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign67_5" .. _name) + end end --- Override an existing sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. @@ -1135,7 +1071,7 @@ function mcl_signs.reregister_sign (modname, color, _name, ttsign) minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - mcl_signs:show_formspec(placer, place_pos) + mcl_signs:show_formspec(placer, place_pos, "") return itemstack end @@ -1234,6 +1170,15 @@ function mcl_signs.reregister_sign (modname, color, _name, ttsign) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign22_5" .. _name, 1 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + + -- register as unpushable + if minetest.get_modpath("mesecons_mvps") then + mesecon.register_mvps_stopper("mcl_signs:wall_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign22_5" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign45" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign67_5" .. _name) + end end --- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign, @@ -1375,7 +1320,7 @@ function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, invento minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) - mcl_signs:show_formspec(placer, place_pos) + mcl_signs:show_formspec(placer, place_pos, "") return itemstack end minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) @@ -1469,6 +1414,14 @@ function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, invento table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign45" .. _name, 2 }) table.insert(mcl_signs.standing_rotation_levels, { "mcl_signs:standing_sign67_5" .. _name, 3 }) + -- register as unpushable + if minetest.get_modpath("mesecons_mvps") then + mesecon.register_mvps_stopper("mcl_signs:wall_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign22_5" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign45" .. _name) + mesecon.register_mvps_stopper("mcl_signs:standing_sign67_5" .. _name) + end end --- Usage: Call this with the mod's name, the wood's item string (for the planks), and with the sign's suffix. @@ -1849,7 +1802,7 @@ function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) return false end local text = meta:get_string("text", "") - if fields and (text == "" and fields.text) then + if fields and fields.text then meta:set_string("text", fields.text) text = fields.text end @@ -2006,11 +1959,13 @@ function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) end -function mcl_signs:show_formspec(player, pos) +function mcl_signs:show_formspec(player, pos, old_text) minetest.show_formspec( player:get_player_name(), "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z, - "size[6,3]textarea[0.25,0.25;6,1.5;text;" .. F(S("Enter sign text:")) .. ";]label[0,1.5;" .. F(S("Maximum line length: 15")) .. "\n" .. F(S("Maximum lines: 4")) .. "]button_exit[0,2.5;6,1;submit;" .. F(S("Done")) .. "]" + "size[6,3]textarea[0.25,0.25;6,1.5;text;" .. F(S("Enter sign text:")) .. ";".. F(old_text) .. "]" .. + "label[0,1.5;" .. F(S("Maximum line length: 15")) .. + "\n" .. F(S("Maximum lines: 4")) .. "]button_exit[0,2.5;6,1;submit;" .. F(S("Done")) .. "]" ) end diff --git a/mods/ITEMS/mcl_smithing_table/init.lua b/mods/ITEMS/mcl_smithing_table/init.lua old mode 100644 new mode 100755 index dbb6c620f..1294c2c52 --- a/mods/ITEMS/mcl_smithing_table/init.lua +++ b/mods/ITEMS/mcl_smithing_table/init.lua @@ -1,12 +1,14 @@ ---[[ -By EliasFleckenstein03 and Code-Sploit -]] +-- By EliasFleckenstein03 and Code-Sploit local S = minetest.get_translator("mcl_smithing_table") +local F = minetest.formspec_escape +local C = minetest.colorize + mcl_smithing_table = {} -- Function to upgrade diamond tool/armor to netherite tool/armor -function mcl_smithing_table.upgrade_item(itemstack) +---@param itemstack ItemStack +function mcl_smithing_table.upgrade_item_netherite(itemstack) local def = itemstack:get_definition() if not def or not def._mcl_upgradable then @@ -20,6 +22,7 @@ function mcl_smithing_table.upgrade_item(itemstack) end itemstack:set_name(upgrade_item) + mcl_armor.reload_trim_inv_image(itemstack) -- Reload the ToolTips of the tool @@ -29,34 +32,106 @@ function mcl_smithing_table.upgrade_item(itemstack) return itemstack end --- Badly copied over from mcl_anvils --- ToDo: Make better formspec +local formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", -local formspec = "size[9,9]" .. - "background[-0.19,-0.25;9.41,9.49;mcl_smithing_table_inventory.png]".. - "label[0,4.0;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Inventory"))) .. "]" .. - "list[current_player;main;0,4.5;9,3;9]" .. - mcl_formspec.get_itemslot_bg(0,4.5,9,3) .. - "list[current_player;main;0,7.74;9,1;]" .. - mcl_formspec.get_itemslot_bg(0,7.74,9,1) .. - "list[context;diamond_item;1,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(1,2.5,1,1) .. - "list[context;netherite;4,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(4,2.5,1,1) .. - "list[context;upgraded_item;8,2.5;1,1;]" .. - mcl_formspec.get_itemslot_bg(8,2.5,1,1) .. - "label[3,0.1;" .. minetest.formspec_escape(minetest.colorize(mcl_colors.DARK_GRAY, S("Upgrade Gear"))) .. "]" .. - "listring[context;output]".. - "listring[current_player;main]".. - "listring[context;input]".. - "listring[current_player;main]" + "label[4.125,0.375;" .. F(C(mcl_formspec.label_color, S("Upgrade Gear"))) .. "]", + "image[0.875,0.375;1.75,1.75;mcl_smithing_table_inventory_hammer.png]", + + mcl_formspec.get_itemslot_bg_v4(1.625, 2.6, 1, 1), + "list[context;upgrade_item;1.625,2.6;1,1;]", + + "image[3.125,2.6;1,1;mcl_anvils_inventory_cross.png]", + + mcl_formspec.get_itemslot_bg_v4(4.75, 2.6, 1, 1), + "list[context;mineral;4.75,2.6;1,1;]", + + mcl_formspec.get_itemslot_bg_v4(6, 2.6, 1, 1), + mcl_formspec.get_itemslot_bg_v4(6, 2.6, 1, 1, 0, "mcl_smithing_table_inventory_trim_bg.png"), + "list[context;template;6,2.6;1,1;]", + + "image[7,2.6;2,1;mcl_anvils_inventory_arrow.png]", + + mcl_formspec.get_itemslot_bg_v4(9.125, 2.6, 1, 1), + "list[context;upgraded_item;9.125,2.6;1,1;]", + + -- Player 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;]", + + -- Listrings + + "listring[context;upgrade_item]", + "listring[current_player;main]", + "listring[context;mineral]", + "listring[current_player;main]", + "listring[context;upgraded_item]", + "listring[current_player;main]", + "listring[current_player;main]", + "listring[context;upgrade_item]", +}) + +local smithing_materials = { + ["mcl_nether:netherite_ingot"] = "netherite", + ["mcl_core:diamond"] = "diamond", + ["mcl_core:lapis"] = "lapis", + ["mcl_amethyst:amethyst_shard"] = "amethyst", + ["mesecons:wire_00000000_off"] = "redstone", + ["mcl_core:iron_ingot"] = "iron", + ["mcl_core:gold_ingot"] = "gold", + ["mcl_copper:copper_ingot"] = "copper", + ["mcl_core:emerald"] = "emerald", + ["mcl_nether:quartz"] = "quartz" +} + +local achievement_trims = { + ["mcl_armor:spire"] = true, + ["mcl_armor:snout"] = true, + ["mcl_armor:rib"] = true, + ["mcl_armor:ward"] = true, + ["mcl_armor:silence"] = true, + ["mcl_armor:vex"] = true, + ["mcl_armor:tide"] = true, + ["mcl_armor:wayfinder"] = true +} + +function mcl_smithing_table.upgrade_trimmed(itemstack, color_mineral, template) + --get information required + local material_name = color_mineral:get_name() + material_name = smithing_materials[material_name] + + local overlay = template:get_name():gsub("mcl_armor:","") + + --trimming process + mcl_armor.trim(itemstack, overlay, material_name) + tt.reload_itemstack_description(itemstack) + + return itemstack +end + +function mcl_smithing_table.is_smithing_mineral(itemname) + return smithing_materials[itemname] ~= nil +end + +---@param pos Vector local function reset_upgraded_item(pos) local inv = minetest.get_meta(pos):get_inventory() local upgraded_item + local original_itemname = inv:get_stack("upgrade_item", 1):get_name() + local template_present = inv:get_stack("template",1):get_name() ~= "" + local is_armor = original_itemname:find("mcl_armor:") ~= nil + local is_trimmed = original_itemname:find("_trimmed") ~= nil - if inv:get_stack("netherite", 1):get_name() == "mcl_nether:netherite_ingot" then - upgraded_item = mcl_smithing_table.upgrade_item(inv:get_stack("diamond_item", 1)) + if inv:get_stack("mineral", 1):get_name() == "mcl_nether:netherite_ingot" and not template_present then + upgraded_item = mcl_smithing_table.upgrade_item_netherite(inv:get_stack("upgrade_item", 1)) + elseif template_present and is_armor and not is_trimmed and mcl_smithing_table.is_smithing_mineral(inv:get_stack("mineral", 1):get_name()) then + upgraded_item = mcl_smithing_table.upgrade_trimmed(inv:get_stack("upgrade_item", 1),inv:get_stack("mineral", 1),inv:get_stack("template", 1)) end inv:set_stack("upgraded_item", 1, upgraded_item) @@ -66,8 +141,7 @@ minetest.register_node("mcl_smithing_table:table", { description = S("Smithing table"), -- ToDo: Add _doc_items_longdesc and _doc_items_usagehelp - stack_max = 64, - groups = {pickaxey = 2, deco_block = 1}, + groups = { pickaxey = 2, deco_block = 1 }, tiles = { "mcl_smithing_table_top.png", @@ -86,13 +160,27 @@ minetest.register_node("mcl_smithing_table:table", { local inv = meta:get_inventory() - inv:set_size("diamond_item", 1) - inv:set_size("netherite", 1) + inv:set_size("upgrade_item", 1) + inv:set_size("mineral", 1) + inv:set_size("template",1) inv:set_size("upgraded_item", 1) end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) - if listname == "diamond_item" and mcl_smithing_table.upgrade_item(stack) or listname == "netherite" and stack:get_name() == "mcl_nether:netherite_ingot" then + local stackname = stack:get_name() + local def = stack:get_definition() + if + listname == "upgrade_item" + and def._mcl_armor_element -- allow any armor piece to go in (in case the player wants to trim them) + and not mcl_armor.trims.blacklisted[stackname] + or def._mcl_upgradable -- for diamond tools + + or listname == "mineral" + and mcl_smithing_table.is_smithing_mineral(stackname) + + or listname == "template" + and string.find(stackname, "mcl_armor") + then return stack:get_count() end @@ -107,26 +195,51 @@ minetest.register_node("mcl_smithing_table:table", { on_metadata_inventory_take = function(pos, listname, index, stack, player) local inv = minetest.get_meta(pos):get_inventory() - + local function take_item(listname) local itemstack = inv:get_stack(listname, 1) itemstack:take_item() inv:set_stack(listname, 1, itemstack) end - + if listname == "upgraded_item" then - take_item("diamond_item") - take_item("netherite") - -- ToDo: make epic sound - minetest.sound_play("mcl_smithing_table_upgrade", {pos = pos, max_hear_distance = 16}) - end - if listname == "upgraded_item" then + minetest.sound_play("mcl_smithing_table_upgrade", { pos = pos, max_hear_distance = 16 }) + if stack:get_name() == "mcl_farming:hoe_netherite" then awards.unlock(player:get_player_name(), "mcl:seriousDedication") + elseif mcl_armor.is_trimmed(stack) then + local template_name = inv:get_stack("template", 1):get_name() + local playername = player:get_player_name() + awards.unlock(playername, "mcl:trim") + + if not awards.players[playername].unlocked["mcl:lots_of_trimming"] and achievement_trims[template_name] then + local meta = player:get_meta() + local used_achievement_trims = minetest.deserialize(meta:get_string("mcl_smithing_table:achievement_trims")) or {} + if not used_achievement_trims[template_name] then + used_achievement_trims[template_name] = true + end + + local used_all = true + for name, _ in pairs(achievement_trims) do + if not used_achievement_trims[name] then + used_all = false + break + end + end + + if used_all then + awards.unlock(playername, "mcl:lots_of_trimming") + else + meta:set_string("mcl_smithing_table:achievement_trims", minetest.serialize(used_achievement_trims)) + end + end end + + take_item("upgrade_item") + take_item("mineral") + take_item("template") end - reset_upgraded_item(pos) end, @@ -138,8 +251,19 @@ minetest.register_node("mcl_smithing_table:table", { minetest.register_craft({ output = "mcl_smithing_table:table", recipe = { - {"mcl_core:iron_ingot", "mcl_core:iron_ingot", ""}, - {"group:wood", "group:wood", ""}, - {"group:wood", "group:wood", ""} - } + { "mcl_core:iron_ingot", "mcl_core:iron_ingot", "" }, + { "group:wood", "group:wood", "" }, + { "group:wood", "group:wood", "" } + }, }) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_smithing_table:table", + burntime = 15, +}) + +-- this is the exact same as mcl_smithing_table.upgrade_item_netherite , in case something relies on the old function +function mcl_smithing_table.upgrade_item(itemstack) + return mcl_smithing_table.upgrade_item_netherite(itemstack) +end diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.pt_BR.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.pt_BR.tr new file mode 100644 index 000000000..5c42b2488 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_smithing_table +Inventory=Inventário +Upgrade Gear=Atualizar Equipamento +Smithing table=Mesa de Ferraria diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ru.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ru.tr new file mode 100644 index 000000000..808643f9c --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_smithing_table +Inventory=Инвентарь +Upgrade Gear=Улучшить +Smithing table=Кузнечный стол \ No newline at end of file diff --git a/mods/ITEMS/mcl_smithing_table/mod.conf b/mods/ITEMS/mcl_smithing_table/mod.conf index aee93fa65..6a7ea5286 100644 --- a/mods/ITEMS/mcl_smithing_table/mod.conf +++ b/mods/ITEMS/mcl_smithing_table/mod.conf @@ -1,2 +1,2 @@ name = mcl_smithing_table -depends = mcl_colors, mcl_formspec +depends = mcl_colors, mcl_formspec, mcl_armor, mcl_anvils diff --git a/mods/ITEMS/mcl_smoker/README.md b/mods/ITEMS/mcl_smoker/README.md index 895a8dd81..cfe244e59 100644 --- a/mods/ITEMS/mcl_smoker/README.md +++ b/mods/ITEMS/mcl_smoker/README.md @@ -1,5 +1,5 @@ -Smoker for MineClone 2. -Heavily based on Minetest Game (default/furnace.lua) and the MineClone 2 Furnaces. +Smoker for VoxeLibre. +Heavily based on Minetest Game (default/furnace.lua) and the VoxeLibre Furnaces. License of source code ---------------------- @@ -10,4 +10,4 @@ MCl 2 Furances modified by PrairieWind. License of media ---------------- -See the main MineClone 2 README.md file. +See the main VoxeLibre README.md file. diff --git a/mods/ITEMS/mcl_smoker/init.lua b/mods/ITEMS/mcl_smoker/init.lua index 4a4cfca15..787d0c429 100644 --- a/mods/ITEMS/mcl_smoker/init.lua +++ b/mods/ITEMS/mcl_smoker/init.lua @@ -1,5 +1,6 @@ - local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize +local F = minetest.formspec_escape local LIGHT_ACTIVE_FURNACE = 13 @@ -8,60 +9,82 @@ local LIGHT_ACTIVE_FURNACE = 13 -- local function active_formspec(fuel_percent, item_percent) - return "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Smoker"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png^[lowpart:".. - (100-fuel_percent)..":default_furnace_fire_fg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[lowpart:".. - (item_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. - -- Craft guide button temporarily removed due to Minetest bug. - -- TODO: Add it back when the Minetest bug is fixed. - --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. - --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + return table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Smoker"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png^[lowpart:" .. + (100 - fuel_percent) .. ":default_furnace_fire_fg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[lowpart:" .. + (item_percent) .. ":gui_furnace_arrow_fg.png^[transformR270]", + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + + -- Craft guide button temporarily removed due to Minetest bug. + -- TODO: Add it back when the Minetest bug is fixed. + --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. + --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", + }) end -local inactive_formspec = "size[9,8.75]".. - "label[0,4;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]".. - "list[current_player;main;0,4.5;9,3;9]".. - mcl_formspec.get_itemslot_bg(0,4.5,9,3).. - "list[current_player;main;0,7.74;9,1;]".. - mcl_formspec.get_itemslot_bg(0,7.74,9,1).. - "label[2.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Smoker"))).."]".. - "list[context;src;2.75,0.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[context;fuel;2.75,2.5;1,1;]".. - mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[context;dst;5.75,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(5.75,1.5,1,1).. - "image[2.75,1.5;1,1;default_furnace_fire_bg.png]".. - "image[4.1,1.5;1.5,1;gui_furnace_arrow_bg.png^[transformR270]".. +local inactive_formspec = table.concat({ + "formspec_version[4]", + "size[11.75,10.425]", + "label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Smoker"))) .. "]", + mcl_formspec.get_itemslot_bg_v4(3.5, 0.75, 1, 1), + "list[context;src;3.5,0.75;1,1;]", + + "image[3.5,2;1,1;default_furnace_fire_bg.png]", + + mcl_formspec.get_itemslot_bg_v4(3.5, 3.25, 1, 1), + "list[context;fuel;3.5,3.25;1,1;]", + + "image[5.25,2;1.5,1;gui_furnace_arrow_bg.png^[transformR270]", + + mcl_formspec.get_itemslot_bg_v4(7.875, 2, 1, 1, 0.2), + "list[context;dst;7.875,2;1,1;]", + + "label[0.375,4.7;" .. F(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;]", + -- Craft guide button temporarily removed due to Minetest bug. -- TODO: Add it back when the Minetest bug is fixed. --"image_button[8,0;1,1;craftguide_book.png;craftguide;]".. --"tooltip[craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[context;dst]".. - "listring[current_player;main]".. - "listring[context;src]".. - "listring[current_player;main]".. - "listring[context;fuel]".. - "listring[current_player;main]" + + "listring[context;dst]", + "listring[current_player;main]", + "listring[context;src]", + "listring[current_player;main]", + "listring[context;fuel]", + "listring[current_player;main]", +}) + local receive_fields = function(pos, formname, fields, sender) if fields.craftguide then @@ -71,7 +94,7 @@ end local function give_xp(pos, player) local meta = minetest.get_meta(pos) - local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2),-1.95) + local dir = vector.divide(minetest.facedir_to_dir(minetest.get_node(pos).param2), -1.95) local xp = meta:get_int("xp") if xp > 0 then if player then @@ -98,7 +121,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) -- Test stack with size 1 because we burn one fuel at a time local teststack = ItemStack(stack) teststack:set_count(1) - local output, decremented_input = minetest.get_craft_result({method="fuel", width=1, items={teststack}}) + local output, decremented_input = minetest.get_craft_result({ method = "fuel", width = 1, items = { teststack } }) if output.time ~= 0 then -- Only allow to place 1 item if fuel get replaced by recipe. -- This is the case for lava buckets. @@ -292,7 +315,7 @@ local function smoker_node_timer(pos, elapsed) -- Check if we have cookable content: cookable local aftercooked - cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist}) + cooked, aftercooked = minetest.get_craft_result({ method = "cooking", width = 1, items = srclist }) cookable = minetest.get_item_group(inv:get_stack("src", 1):get_name(), "smoker_cookable") == 1 if cookable then -- Successful cooking requires space in dst slot and time @@ -310,7 +333,7 @@ local function smoker_node_timer(pos, elapsed) if cookable and not active then -- We need to get new fuel local afterfuel - fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist}) + fuel, afterfuel = minetest.get_craft_result({ method = "fuel", width = 1, items = fuellist }) if fuel.time == 0 then -- No valid fuel in fuel list -- stop @@ -343,7 +366,7 @@ local function smoker_node_timer(pos, elapsed) srclist = inv:get_list("src") src_time = 0 - meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count + meta:set_int("xp", meta:get_int("xp") + 1) -- ToDo give each recipe an idividial XP count end end @@ -390,9 +413,9 @@ local function smoker_node_timer(pos, elapsed) meta:set_float("fuel_time", fuel_time) meta:set_float("src_time", src_time) if srclist then - meta:set_string("src_item", src_item) + meta:set_string("src_item", src_item) else - meta:set_string("src_item", "") + meta:set_string("src_item", "") end meta:set_string("formspec", formspec) @@ -415,13 +438,14 @@ end minetest.register_node("mcl_smoker:smoker", { description = S("Smoker"), _tt_help = S("Cooks food faster than furnace"), - _doc_items_longdesc = S("Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace."), + _doc_items_longdesc = S( + "Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace."), _doc_items_usagehelp = - S("Use the smoker to open the furnace menu.").."\n".. - S("Place a furnace fuel in the lower slot and the source material in the upper slot.").."\n".. - S("The smoker will slowly use its fuel to smelt the item.").."\n".. - S("The result will be placed into the output slot at the right side.").."\n".. - S("Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn."), + S("Use the smoker to open the furnace menu.") .. "\n" .. + S("Place a furnace fuel in the lower slot and the source material in the upper slot.") .. "\n" .. + S("The smoker will slowly use its fuel to smelt the item.") .. "\n" .. + S("The result will be placed into the output slot at the right side.") .. "\n" .. + S("Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn."), _doc_items_hidden = false, tiles = { "smoker_top.png", "smoker_bottom.png", @@ -429,7 +453,7 @@ minetest.register_node("mcl_smoker:smoker", { "smoker_side.png", "smoker_front.png" }, 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, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -439,10 +463,14 @@ minetest.register_node("mcl_smoker:smoker", { local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { + x = pos.x + math.random(0, 10) / 10 - 0.5, + y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 + } minetest.add_item(p, stack) end end @@ -491,6 +519,11 @@ minetest.register_node("mcl_smoker:smoker", { _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, 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", { @@ -499,14 +532,16 @@ minetest.register_node("mcl_smoker:smoker_active", { tiles = { "smoker_top.png", "smoker_bottom.png", "smoker_side.png", "smoker_side.png", - "smoker_side.png", {name = "smoker_front_on.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48}}, + "smoker_side.png", { + name = "smoker_front_on.png", + animation = { type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 48 } + }, }, paramtype2 = "facedir", paramtype = "light", light_source = LIGHT_ACTIVE_FURNACE, 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, sounds = mcl_sounds.node_sound_stone_defaults(), on_timer = smoker_node_timer, @@ -516,10 +551,14 @@ minetest.register_node("mcl_smoker:smoker_active", { local meta2 = meta meta:from_table(oldmetadata) local inv = meta:get_inventory() - for _, listname in ipairs({"src", "dst", "fuel"}) do + for _, listname in ipairs({ "src", "dst", "fuel" }) do local stack = inv:get_stack(listname, 1) if not stack:is_empty() then - local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} + local p = { + x = pos.x + math.random(0, 10) / 10 - 0.5, + y = pos.y, + z = pos.z + math.random(0, 10) / 10 - 0.5 + } minetest.add_item(p, stack) end end @@ -545,14 +584,16 @@ minetest.register_node("mcl_smoker:smoker_active", { _mcl_hardness = 3.5, on_rotate = on_rotate, 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({ output = "mcl_smoker:smoker", recipe = { - { "", "group:tree", "" }, + { "", "group:tree", "" }, { "group:tree", "mcl_furnaces:furnace", "group:tree" }, - { "", "group:tree", "" }, + { "", "group:tree", "" }, } }) @@ -564,7 +605,7 @@ end minetest.register_lbm({ label = "Active smoker flame particles", name = "mcl_smoker:flames", - nodenames = {"mcl_smoker:smoker_active"}, + nodenames = { "mcl_smoker:smoker_active" }, run_at_every_load = true, action = function(pos, node) spawn_flames(pos, node.param2) diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.pt_BR.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.pt_BR.tr new file mode 100644 index 000000000..4820d01bf --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_smoker +Inventory=Inventário +Smoker=Defumador +Cooks food faster than furnace=Cozinha comida mais rápido que a fornalha +Use the smoker to open the furnace menu.=Use o defumador para abrir o menu de fornalha. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Posicione um combustível de fornalha no slot mais abaixo e o material fonte no slot mais acima. +The smoker will slowly use its fuel to smelt the item.=O defumador usará seu combustível lentamente para cozinhar o item. +The result will be placed into the output slot at the right side.=O resultado será posicionado no slot de saída no lado direito. +Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn.=Use o livro de receitas para ver quais comidas você pode cozinhar, quais combustíveis você pode usar e por quanto tempo irá queimar. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Defumadores cozinham muitos itens, principalmente comidas cruas, em comida cozida, mas duas vezes mais rápido que uma fornalha normal. +Burning Smoker=Defumador Ativo diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ru.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ru.tr new file mode 100644 index 000000000..e65998e64 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ru.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_smoker +Inventory=Инвентарь +Smoker=Коптильня +Cooks food faster than furnace=Готовит еду быстрее чем обычная печь +Use the smoker to open the furnace menu.=Используйте коптильню, чтобы открыть меню печи. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Положите топливо в нижний слот и материал в верхний. +The smoker will slowly use its fuel to smelt the item.=Коптильня будет медленно использовать топливо для переплавки предмета. +The result will be placed into the output slot at the right side.=Результат будет помещен в выходной слот с правой стороны. +Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn.=Используйте книгу рецептов, чтобы увидеть какие еду можно приготовить, что можно использовать как топливо и как долго оно будет гореть. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Коптильня готовит некоторые предметы, в основном сырую еду в приготовленную, но в два раза быстрее чем обычная печь. +Burning Smoker=Горящая коптильня diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index e9755479b..87f40e3ae 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -155,7 +155,7 @@ minetest.register_node("mcl_sponges:sponge_wet", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, hoey=1, building_block=1}, + groups = {handy=1, hoey=1, waterlogged = 1, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, @@ -175,7 +175,7 @@ if minetest.get_modpath("mclx_core") then buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, waterlogged = 1, building_block=1}, on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.fr.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.fr.tr index 58dd74bee..34cbd8578 100644 --- a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.fr.tr +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.fr.tr @@ -2,9 +2,9 @@ Sponge=Éponge Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=Les éponges sont des blocs qui éliminent l'eau autour d'eux lorsqu'ils sont placés ou entrent en contact avec l'eau, la transformant en une éponge humide. Waterlogged Sponge=Éponge gorgée d'eau -A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=Une éponge gorgée d'eau peut être séchée dans le four pour la transformer en éponge (sèche). Lorsqu'il y a un seau vide dans la fente de combustible d'un four, l'eau se déversera dans le seau. +A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=Une éponge gorgée d'eau peut être séchée dans le four pour la transformer en éponge (sèche). Lorsqu'il y a un seau vide dans la fente de combustible du four, l'eau se déversera dans le seau. Riverwaterlogged Sponge=Éponge gorgée d'eau de rivière -This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=Il s'agit d'une éponge trempée d'eau de rivière. Elle peut être séché dans le four pour le transformer en éponge (sèche). Lorsqu'il y a un seau vide dans la fente de combustible du four, l'eau de la rivière se déversera dans le seau. +This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=Il s'agit d'une éponge trempée d'eau de rivière. Elle peut être séchée dans le four pour la transformer en éponge (sèche). Lorsqu'il y a un seau vide dans la fente de combustible du four, l'eau de la rivière se déversera dans le seau. A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=Une éponge devient gorgée d'eau de rivière (au lieu d'être gorgée d'eau) si elle aspire plus d'eau de rivière que d'eau (normale). Removes water on contact=Élimine l'eau au contact -Can be dried in furnace=Peut être séché au four +Can be dried in furnace=Peut être séchée au four diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pt_BR.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pt_BR.tr new file mode 100644 index 000000000..e6a857347 --- /dev/null +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_sponges +Sponge=Esponja +Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=Esponjas são blocos aos quais removem água ao seu redor quando elas são posicionadas ou entram em contato com a água, se transfomando em uma esponja molhada. +Waterlogged Sponge=Esponja Alagada +A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=Uma esponja alagada pode ser seca na fornalha para se tornar uma esponja (seca). Quando tem um balde vazio no slot de combustível da fornalha, a água irá se depositar dentro do balde. +Riverwaterlogged Sponge=Esponja Alagada em Rio +This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=Esta é uma esponja encharcada com água do rio. Uma esponja alagada em rio pode ser seca na fornalha para se tornar uma esponja (seca). Quando tem um balde vazio no slot de combustível da fornalha, a água de rio irá se depositar dentro do balde. +A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=A esponja se torna alagada em rio (em vez de alagada) se esta sugar mais água de rio do que água (normal). +Removes water on contact=Remove água por contato +Can be dried in furnace=Pode ser secada na fornalha diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ru.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ru.tr index c3b1749d6..b323abc70 100644 --- a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ru.tr +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ru.tr @@ -1,10 +1,10 @@ # textdomain: mcl_sponges Sponge=Губка -Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=Губки это блоки, которые убирают воду вокруг себя, превращаясь в намокшие губки. -Waterlogged Sponge=Намокшая губка -A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=Намокшая губка может быть высушена в печи, тогда она превратится обратно в (сухую) губку. Если поставить пустое ведро в топливный отсек печи, это ведро наполнится водой. +Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=Губка это блок, который убирает воду вокруг себя, превращаясь в мокрую губку. +Waterlogged Sponge=Мокрая губка +A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of a furnace, the water will pour into the bucket.=Мокрая губка может быть высушена в печи, тогда она превратится обратно в сухую губку. Если поставить пустое ведро в топливный отсек печи, это ведро наполнится водой. Riverwaterlogged Sponge=Губка с речной водой -This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=Это губка, пропитанная речной водой. Она может быть высушена в печи, тогда она превратится обратно в (сухую) губку. Если поставить пустое ведро в топливный отсек печи, это ведро наполнится речной водой. -A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=Губка становится губкой с речной водой, если она втягивает в себя больше речной воды, чем обыкновенной. -Removes water on contact=Убирает воду при контакте +This is a sponge soaking wet with river water. It can be dried in the furnace to turn it into (dry) sponge. When there's an empty bucket in the fuel slot of the furnace, the river water will pour into the bucket.=Это губка, пропитанная речной водой. Она может быть высушена в печи, тогда она превратится обратно в сухую губку. Если поставить пустое ведро в топливный отсек печи, это ведро наполнится речной водой. +A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=Губка становится мокрой губкой с речной водой, если она втягивает в себя больше речной воды, чем обыкновенной. +Removes water on contact=Убирает воду вблизи Can be dried in furnace=Может быть просушена в печи diff --git a/mods/ITEMS/mcl_spyglass/init.lua b/mods/ITEMS/mcl_spyglass/init.lua index fa1a82339..afa7adaf4 100644 --- a/mods/ITEMS/mcl_spyglass/init.lua +++ b/mods/ITEMS/mcl_spyglass/init.lua @@ -17,6 +17,15 @@ minetest.register_craft({ } }) +mcl_fovapi.register_modifier({ + name = "spyglass", + fov_factor = 8, + time = 0.1, + reset_time = 0, + is_multiplier = false, + exclusive = true, +}) + local spyglass_scope = {} local function add_scope(player) @@ -29,6 +38,12 @@ local function add_scope(player) text = "mcl_spyglass_scope.png", }) player:hud_set_flags({wielditem = false}) + if mcl_util.is_it_christmas() then + local time = minetest.get_timeofday() + if (time < 0.01 or time > 0.99) and player:get_look_vertical() < -1.335 then + player:set_moon({texture = "mcl_moon_special.png"}) + end + end end end @@ -37,25 +52,31 @@ local function remove_scope(player) player:hud_remove(spyglass_scope[player]) spyglass_scope[player] = nil player:hud_set_flags({wielditem = true}) - player:set_fov(86.1) + mcl_fovapi.remove_modifier(player, "spyglass") -- use the api to remove the FOV effect. + -- old code: player:set_fov(86.1) end end controls.register_on_press(function(player, key) - if key ~= "RMB" then return end - add_scope(player) + if key ~= "RMB" and key ~= "zoom" then return end + if spyglass_scope[player] == nil then + add_scope(player) + end end) controls.register_on_release(function(player, key, time) - if key ~= "RMB" then return end + if key ~= "RMB" and key ~= "zoom" then return end + local ctrl = player:get_player_control() + if key == "RMB" and ctrl.zoom or key == "zoom" and ctrl.place then return end remove_scope(player) end) controls.register_on_hold(function(player, key, time) - if key ~= "RMB" then return end + if key ~= "RMB" and key ~= "zoom" then return end local wielditem = player:get_wielded_item() if wielditem:get_name() == "mcl_spyglass:spyglass" then - player:set_fov(8, false, 0.1) + mcl_fovapi.apply_modifier(player, "spyglass") -- apply the FOV effect. + -- old code: player:set_fov(8, false, 0.1) if spyglass_scope[player] == nil then add_scope(player) end diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.pt_BR.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.pt_BR.tr new file mode 100644 index 000000000..60d730206 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=Luneta +A spyglass is an item that can be used for zooming in on specific locations.=Uma luneta é um item que pode ser usado para dar zoom em uma localidade especifica. diff --git a/mods/ITEMS/mcl_spyglass/mod.conf b/mods/ITEMS/mcl_spyglass/mod.conf index c13b281e1..6a78e86a5 100644 --- a/mods/ITEMS/mcl_spyglass/mod.conf +++ b/mods/ITEMS/mcl_spyglass/mod.conf @@ -1,4 +1,4 @@ name = mcl_spyglass author = NO11 description = This mod adds a spyglass, which is an item that can be used for zooming in on specific locations. -depends = mcl_core, controls +depends = mcl_core, controls, mcl_fovapi diff --git a/mods/ITEMS/mcl_stairs/README.txt b/mods/ITEMS/mcl_stairs/README.txt index 9607b5d00..0c6ad9b20 100644 --- a/mods/ITEMS/mcl_stairs/README.txt +++ b/mods/ITEMS/mcl_stairs/README.txt @@ -1,4 +1,4 @@ -MineClone 2 mod: mcl_stairs +VoxeLibre mod: mcl_stairs ========================= Forked from stairs mod in Minetest Game 0.4.16. See license.txt for license information. diff --git a/mods/ITEMS/mcl_stairs/api.lua b/mods/ITEMS/mcl_stairs/api.lua index 6167d7e06..bebe7ba99 100644 --- a/mods/ITEMS/mcl_stairs/api.lua +++ b/mods/ITEMS/mcl_stairs/api.lua @@ -173,6 +173,9 @@ function mcl_stairs.register_stair(subname, recipeitem, groups, images, descript {recipeitem, recipeitem, recipeitem}, }, }) + + -- Stonecutter recipe + mcl_stonecutter.register_recipe(recipeitem, "mcl_stairs:stair_".. subname) end 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 -- Help alias for the upper slab diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ru.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ru.tr index 10d470fce..4441cc016 100644 --- a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ru.tr +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ru.tr @@ -1,101 +1,104 @@ # textdomain: mcl_stairs -Stairs are useful to reach higher places by walking over them; jumping is not required. Placing stairs in a corner pattern will create corner stairs. Stairs placed on the ceiling or at the upper half of the side of a block will be placed upside down.=Ступеньки полезны, чтобы подниматься к высоким местам, идя по ним; прыжки при этом не требуются. Размещение ступенек по углам будет создавать угловые ступеньки. Ступеньки, устанавливаемые на потолке или в верхней половине боковой части блока, будет перевёрнуты вверх ногами. +Stairs are useful to reach higher places by walking over them; jumping is not required. Placing stairs in a corner pattern will create corner stairs. Stairs placed on the ceiling or at the upper half of the side of a block will be placed upside down.=Ступени нужны для подъема; по ним можно идти, прыгать не обязательно. Размещение ступенек на углах будет создавать угловые ступени. Ступени, устанавливаемые на потолке или на верхней половине боковой части блока, будет перевёрнуты вверх ногами. Double @1=Двойная @1 Slabs are half as high as their full block counterparts and occupy either the lower or upper part of a block, depending on how it was placed. Slabs can be easily stepped on without needing to jump. When a slab is placed on another slab of the same type, a double slab is created.=Плиты в два раза ниже, чем их блочные аналоги, и занимают либо нижнюю, либо верхнюю часть блока, в зависимости от того, как они размещались. На плиты можно легко подниматься без необходимости прыгать. Когда плита помещается на другую плиту того же типа, создается двойная плита. Upper @1=Верхняя @1 Double slabs are full blocks which are created by placing two slabs of the same kind on each other.=Двойные плиты это целые блоки, которые создаются путем размещения двух плит одного вида друг на друге. -Oak Wood Stairs=Дубовые ступеньки +Oak Wood Stairs=Дубовые ступени Oak Wood Slab=Дубовая плита Double Oak Wood Slab=Двойная дубовая плита -Jungle Wood Stairs=Ступеньки из дерева джунглей -Jungle Wood Slab=Плита из дерева джунглей -Double Jungle Wood Slab=Двойная плита из дерева джунглей -Acacia Wood Stairs=Ступеньки из акации -Acacia Wood Slab=Плита из акации -Double Acacia Wood Slab=Двойная плита из акации -Spruce Wood Stairs=Еловые ступеньки +Jungle Wood Stairs=Ступени из тропического дерева +Jungle Wood Slab=Плита из тропического дерева +Double Jungle Wood Slab=Двойная плита из тропического дерева +Acacia Wood Stairs=Акациевые ступени +Acacia Wood Slab=Акациевая плита +Double Acacia Wood Slab=Двойная акациевая плита +Spruce Wood Stairs=Еловые ступени Spruce Wood Slab=Еловая плита Double Spruce Wood Slab=Двойная еловая плита -Birch Wood Stairs=Берёзовые ступеньки +Birch Wood Stairs=Берёзовые ступени Birch Wood Slab=Берёзовая плита Double Birch Wood Slab=Двойная берёзовая плита -Dark Oak Wood Stairs=Ступеньки из тёмного дуба +Dark Oak Wood Stairs=Ступени из тёмного дуба Dark Oak Wood Slab=Плита из тёмного дуба Double Dark Oak Wood Slab=Двойная плита из тёмного дуба -Stone Stairs=Каменные ступеньки +Stone Stairs=Каменные ступени Stone Slab=Каменная плита Double Stone Slab=Двойная каменная плита -Polished Stone Slab=Плита из гладкого камня -Double Polished Stone Slab=Двойная плита из гладкого камня -Andesite Stairs=Андезитовые ступеньки +Polished Stone Slab=Плита из полированного камня +Double Polished Stone Slab=Двойная плита из полированного камня +Andesite Stairs=Андезитовые ступени Andesite Slab=Андезитовая плита Double Andesite Slab=Двойная андезитовая плита -Granite Stairs=Гранитные ступеньки +Granite Stairs=Гранитные ступени Granite Slab=Гранитная плита Double Granite Slab=Двойная гранитная плита -Diorite Stairs=Диоритовые ступеньки +Diorite Stairs=Диоритовые ступени Diorite Slab=Диоритовая плита Double Diorite Slab=Двойная диоритовая плита -Cobblestone Stairs=Ступеньки из булыжника +Cobblestone Stairs=Ступени из булыжника Cobblestone Slab=Плита из булыжника Double Cobblestone Slab=Двойная плита из булыжника -Mossy Cobblestone Stairs=Ступеньки из мшистого булыжника -Mossy Cobblestone Slab=Плита из мшистого булыжника -Double Mossy Cobblestone Slab=Двойная плита из мшистого булыжника -Brick Stairs=Кирпичные ступеньки +Mossy Cobblestone Stairs=Ступени из замшелого булыжника +Mossy Cobblestone Slab=Плита из замшелого булыжника +Double Mossy Cobblestone Slab=Двойная плита из замшелого булыжника +Brick Stairs=Кирпичные ступени Brick Slab=Кирпичная плита Double Brick Slab=Двойная кирпичная плита -Sandstone Stairs=Ступеньки из песчаника +Sandstone Stairs=Ступени из песчаника Sandstone Slab=Плита из песчаника Double Sandstone Slab=Двойная плита из песчаника -Smooth Sandstone Stairs=Ступеньки из гладкого песчаника +Smooth Sandstone Stairs=Ступени из гладкого песчаника Smooth Sandstone Slab=Плита из гладкого песчаника Double Smooth Sandstone Slab=Двойная плита из гладкого песчаника -Red Sandstone Stairs=Ступеньки из красного песчаника +Red Sandstone Stairs=Ступени из красного песчаника Red Sandstone Slab=Плита из красного песчаника Double Red Sandstone Slab=Двойная плита из красного песчаника -Smooth Red Sandstone Stairs=Ступеньки из гладкого красного песчаника +Smooth Red Sandstone Stairs=Ступени из гладкого красного песчаника Smooth Red Sandstone Slab=Плита из гладкого красного песчаника Double Smooth Red Sandstone Slab=Двойная плита из гладкого красного песчаника -Stone Bricks Stairs=Ступеньки из каменных блоков -Stone Bricks Slab=Плита из каменных блоков -Double Stone Bricks Slab=Двойная плита из каменных блоков -Quartz Stairs=Кварцевые ступеньки +Stone Bricks Stairs=Ступени из каменных кирпичей +Stone Bricks Slab=Плита из каменных кирпичей +Double Stone Bricks Slab=Двойная плита из каменных кирпичей +Quartz Stairs=Кварцевые ступени Quartz Slab=Кварцевая плита Double Quartz Slab=Двойная кварцевая плита -Smooth Quartz Stairs=Ступеньки из гладкого кварца +Smooth Quartz Stairs=Ступени из гладкого кварца Smooth Quartz Slab=Плита из гладкого кварца Double Smooth Quartz Slab=Двойная плита из гладкого кварца -Nether Brick Stairs=Ступеньки из адского кирпича +Nether Brick Stairs=Ступени из адского кирпича Nether Brick Slab=Плита из адского кирпича Double Nether Brick Slab=Двойная плита из адского кирпича -Red Nether Brick Stairs=Ступеньки из красного адского кирпича +Red Nether Brick Stairs=Ступени из красного адского кирпича Red Nether Brick Slab=Плита из красного адского кирпича Double Red Nether Brick Slab=Двойная из красного адского кирпича -End Stone Brick Stairs=Ступеньки из камня Предела -End Stone Brick Slab=Плита из камня Предела -Double End Stone Brick Slab=Двойная плита из камня Предела -Purpur Stairs=Пурпурные ступеньки +End Stone Brick Stairs=Ступени из камня Края +End Stone Brick Slab=Плита из камня Края +Double End Stone Brick Slab=Двойная плита из камня Края +Purpur Stairs=Пурпурные ступени Purpur Slab=Пурпурная плита Double Purpur Slab=Двойная пурпурная плита -Prismarine Stairs=Призмариновые ступеньки +Prismarine Stairs=Призмариновые ступени Prismarine Slab=Призмариновая плита Double Prismarine Slab=Двойная призмариновая плита -Prismarine Brick Stairs=Ступеньки из призмаринового кирпича +Prismarine Brick Stairs=Ступени из призмаринового кирпича Prismarine Brick Slab=Плита из призмаринового кирпича Double Prismarine Brick Slab=Двойная плита из призмаринового кирпича -Dark Prismarine Stairs=Ступеньки из тёмного призмарина +Dark Prismarine Stairs=Ступени из тёмного призмарина Dark Prismarine Slab=Плита из тёмного призмарина Double Dark Prismarine Slab=Двойная плита из тёмного призмарина -Polished Andesite Slab=Плита из гладкого андезита -Double Polished Andesite Slab=Двойная плита из гладкого андезита -Polished Andesite Stairs=Ступеньки из гладкого андезита -Polished Granite Slab=Плита из гладкого гранита -Double Polished Granite Slab=Двойная плита из гладкого гранита -Polished Granite Stairs=Ступеньки из гладкого гранита -Polished Diorite Slab=Плита из гладкого диорита -Double Polished Diorite Slab=Двойная плита из гладкого диорита -Polished Diorite Stairs=Ступеньки из гладкого диорита -Mossy Stone Brick Stairs=Ступеньки из мшистого каменного блока -Mossy Stone Brick Slab=Плита из мшистого каменного блока -Double Mossy Stone Brick Slab=Двойная плита из мшистого каменного блока +Polished Andesite Slab=Плита из полированного андезита +Double Polished Andesite Slab=Двойная плита из полированного андезита +Polished Andesite Stairs=Ступени из полированного андезита +Polished Granite Slab=Плита из полированного гранита +Double Polished Granite Slab=Двойная плита из полированного гранита +Polished Granite Stairs=Ступени из полированного гранита +Polished Diorite Slab=Плита из полированного диорита +Double Polished Diorite Slab=Двойная плита из полированного диорита +Polished Diorite Stairs=Ступени из полированного диорита +Mossy Stone Brick Stairs=Ступени из замшелых каменных кирпичей +Mossy Stone Brick Slab=Плита из замшелых каменных кирпичей +Double Mossy Stone Brick Slab=Двойная плита из замшелых каменных кирпичей +Mud Brick Stair=Саманные ступени +Mud Brick Slab=Саманная плита +Double Mud Brick Slab=Двойная саманная плита \ No newline at end of file diff --git a/mods/ITEMS/mcl_stairs/mod.conf b/mods/ITEMS/mcl_stairs/mod.conf index 2fb3180b2..b3e0e2aa7 100644 --- a/mods/ITEMS/mcl_stairs/mod.conf +++ b/mods/ITEMS/mcl_stairs/mod.conf @@ -1,2 +1,2 @@ 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 diff --git a/mods/ITEMS/mcl_stairs/register.lua b/mods/ITEMS/mcl_stairs/register.lua index eee4c5dc2..b59880e48 100644 --- a/mods/ITEMS/mcl_stairs/register.lua +++ b/mods/ITEMS/mcl_stairs/register.lua @@ -30,7 +30,18 @@ for w=1, #woods do wood[5]) 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", {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, 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_and_slab_simple("granite", "mcl_core:granite", S("Granite Stairs"), S("Granite Slab"), S("Double Granite Slab")) -mcl_stairs.register_stair_and_slab_simple("diorite", "mcl_core:diorite", S("Diorite Stairs"), S("Diorite Slab"), S("Double Diorite Slab")) +mcl_stairs.register_stair("andesite", "mcl_core:andesite", + {pickaxey=1, material_stone=1}, + {"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_and_slab_simple("mossycobble", "mcl_core:mossycobble", S("Mossy Cobblestone Stairs"), S("Mossy Cobblestone Slab"), S("Double Mossy Cobblestone Slab")) +mcl_stairs.register_stair("granite", "mcl_core:granite", + {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("Diorite 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}, {"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"}, S("Sandstone Stairs"), mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, 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}, {"mcl_core_sandstone_top.png", "mcl_core_sandstone_bottom.png", "mcl_core_sandstone_normal.png"}, S("Sandstone Slab"), mcl_sounds.node_sound_stone_defaults(), 6, 2, 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}, {"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"}, S("Red Sandstone Stairs"), mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, 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}, {"mcl_core_red_sandstone_top.png", "mcl_core_red_sandstone_bottom.png", "mcl_core_red_sandstone_normal.png"}, S("Red Sandstone Slab"), mcl_sounds.node_sound_stone_defaults(), 6, 2, 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 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, 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}, {"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"}, S("Quartz Stairs"), mcl_sounds.node_sound_stone_defaults(), 0.8, 0.8, 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}, {"mcl_nether_quartz_block_top.png", "mcl_nether_quartz_block_bottom.png", "mcl_nether_quartz_block_side.png"}, S("Quartz Slab"), mcl_sounds.node_sound_stone_defaults(), 6, 2, 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", {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, 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}, {"mcl_end_purpur_block.png"}, S("Purpur Stairs"), mcl_sounds.node_sound_stone_defaults(), 6, 1.5, 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}, {"mcl_end_purpur_block.png"}, S("Purpur Slab"), mcl_sounds.node_sound_stone_defaults(), 6, 2, 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_and_slab_simple("prismarine_dark", "mcl_ocean:prismarine_dark", S("Dark Prismarine Stairs"), S("Dark Prismarine Slab"), S("Double Dark Prismarine Slab")) +mcl_stairs.register_stair("prismarine_dark", "mcl_ocean:prismarine_dark", + {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", {pickaxey=1}, diff --git a/mods/ITEMS/mcl_starting_inventory/README.txt b/mods/ITEMS/mcl_starting_inventory/README.txt index 126504b04..5f350b268 100644 --- a/mods/ITEMS/mcl_starting_inventory/README.txt +++ b/mods/ITEMS/mcl_starting_inventory/README.txt @@ -1,4 +1,4 @@ -Mcl_starting_inventory, adapted for Mineclone 2 by Michieal. +Mcl_starting_inventory, adapted for VoxeLibre by Michieal. Based on: Minetest Game mod: give_initial_stuff diff --git a/mods/ITEMS/mcl_stonecutter/README.md b/mods/ITEMS/mcl_stonecutter/README.md index c6316a5a2..a0c89a8ec 100644 --- a/mods/ITEMS/mcl_stonecutter/README.md +++ b/mods/ITEMS/mcl_stonecutter/README.md @@ -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. +### 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 --------------- -See the main MineClone 2 README.md file. -Author: PrairieWind +See the main VoxeLibre README.md file. +Author: PrairieWind, ChrisPHP, cora, Herowl, AFCMS License of media ---------------- diff --git a/mods/ITEMS/mcl_stonecutter/init.lua b/mods/ITEMS/mcl_stonecutter/init.lua index e75884990..0b2f6f166 100644 --- a/mods/ITEMS/mcl_stonecutter/init.lua +++ b/mods/ITEMS/mcl_stonecutter/init.lua @@ -2,10 +2,373 @@ --||||| STONECUTTER ||||| --||||||||||||||||||||||| --- TO-DO: --- * Add GUI +-- The stonecutter is implemented just like the crafting table, meaning the node doesn't have any state. +-- 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> +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 + if not mcl_stonecutter.registered_recipes[input][o] then + mcl_stonecutter.register_recipe(input, o, c * count) + end + end + end + + for i, recipes in pairs(mcl_stonecutter.registered_recipes) do + for name, c in pairs(recipes) do + if name == input and not mcl_stonecutter.registered_recipes[i][output] 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 +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", { description = S("Stone Cutter"), @@ -16,36 +379,45 @@ minetest.register_node("mcl_stonecutter:stonecutter", { "mcl_stonecutter_bottom.png", "mcl_stonecutter_side.png", "mcl_stonecutter_side.png", - {name="mcl_stonecutter_saw.png", - animation={ - type="vertical_frames", - aspect_w=16, - aspect_h=16, - length=1 - }}, - {name="mcl_stonecutter_saw.png", - animation={ - type="vertical_frames", - aspect_w=16, - aspect_h=16, - length=1 - }} + { + name = "mcl_stonecutter_saw.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1 + } + }, + { + name = "mcl_stonecutter_saw.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.15 + } + } }, use_texture_alpha = "clip", drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", - groups = { pickaxey=1, material_stone=1 }, + groups = { pickaxey = 1, material_stone = 1 }, node_box = { type = "fixed", fixed = { - {-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.5, -0.5, -0.5, 0.5, 0.0625, 0.5 }, -- NodeBox1 + { -0.4375, 0.0625, 0, 0.4375, 0.5, 0 }, -- NodeBox2 } }, _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, 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({ diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.de.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.de.tr new file mode 100644 index 000000000..852a78406 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.de.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=Steinsäge +Used to cut stone like materials.=Wird zum Schneiden von steinähnlichen Materialien verwendet. +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=Steinsägen stellen Treppen und Platten aus steinähnlichen Materialien her. Diese sind auch der Arbeitsplatz für den Steinmetz-Dorfbewohner. diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.pt_BR.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.pt_BR.tr new file mode 100644 index 000000000..7b52a2507 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=Cortador de Pedras +Used to cut stone like materials.=Usado para cortar materiais rochosos. +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=Cortadores de pedras são usados para criar certas escadas e lajes a partir de materiais rochosos. Também é a estação de trabalho do aldeão pedreiro. diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ru.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ru.tr new file mode 100644 index 000000000..65fcdff81 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=Камнерез +Used to cut stone like materials.=Используется для резьбы каменных материалов +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=Камнерез используется для создания ступеней и плит из каменных материалов. Также является рабочим местов жителя каменщика. diff --git a/mods/ITEMS/mcl_stonecutter/mod.conf b/mods/ITEMS/mcl_stonecutter/mod.conf index d9781e474..01cf2a75f 100644 --- a/mods/ITEMS/mcl_stonecutter/mod.conf +++ b/mods/ITEMS/mcl_stonecutter/mod.conf @@ -1,4 +1,4 @@ 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. -depends = mcl_sounds +depends = mcl_sounds, mcl_util diff --git a/mods/ITEMS/mcl_sus_stew/README.md b/mods/ITEMS/mcl_sus_stew/README.md index 374d80b92..ce9bb1b42 100644 --- a/mods/ITEMS/mcl_sus_stew/README.md +++ b/mods/ITEMS/mcl_sus_stew/README.md @@ -1,3 +1,3 @@ # mcl_sus_stew -This Mod adds Suspicious Stews for Mineclone \ No newline at end of file +This Mod adds Suspicious Stews to VoxeLibre diff --git a/mods/ITEMS/mcl_sus_stew/init.lua b/mods/ITEMS/mcl_sus_stew/init.lua index cfb294532..8a88027ae 100644 --- a/mods/ITEMS/mcl_sus_stew/init.lua +++ b/mods/ITEMS/mcl_sus_stew/init.lua @@ -1,46 +1,69 @@ +local S = minetest.get_translator(minetest.get_current_modname()) -- ____________________________ ---_________________________________________/ Variables & Functions \_________ +--_________________________________________/ Variables & Functions \_________ local eat = minetest.item_eat(6, "mcl_core:bowl") --6 hunger points, player receives mcl_core:bowl after eating local flower_effect = { [ "mcl_flowers:allium" ] = "fire_resistance", + [ "mcl_flowers:azure_bluet" ] = "blindness", [ "mcl_flowers:lily_of_the_valley" ] = "poison", - [ "mcl_flowers:blue_orchid" ] = "hunger", - [ "mcl_flowers:dandelion" ] = "hunger", + [ "mcl_flowers:blue_orchid" ] = "saturation", + [ "mcl_flowers:dandelion" ] = "saturation", [ "mcl_flowers:cornflower" ] = "jump", [ "mcl_flowers:oxeye_daisy" ] = "regeneration", - [ "mcl_flowers:poppy" ] = "night_vision" + [ "mcl_flowers:poppy" ] = "night_vision", + [ "mcl_flowers:wither_rose" ] = "withering", + [ "mcl_flowers:tulip_orange" ] = "weakness", + [ "mcl_flowers:tulip_pink" ] = "weakness", + [ "mcl_flowers:tulip_red" ] = "weakness", + [ "mcl_flowers:tulip_white" ] = "weakness", } local effects = { [ "fire_resistance" ] = function(itemstack, placer, pointed_thing) - mcl_potions.fire_resistance_func(placer, 1, 4) - return eat(itemstack, placer, pointed_thing) - end, - [ "poison" ] = function(itemstack, placer, pointed_thing) - mcl_potions.poison_func(placer, 1, 12) + mcl_potions.give_effect("fire_resistance", placer, 1, 4) return eat(itemstack, placer, pointed_thing) end, - [ "hunger" ] = function(itemstack, placer, pointed_thing, player) - mcl_hunger.item_eat(6, "mcl_core:bowl", 3.5, 0, 100) + [ "blindness" ] = function(itemstack, placer, pointed_thing) + mcl_potions.give_effect("blindness", placer, 1, 8) + return eat(itemstack, placer, pointed_thing) + end, + + [ "poison" ] = function(itemstack, placer, pointed_thing) + mcl_potions.give_effect_by_level("poison", placer, 1, 12) + return eat(itemstack, placer, pointed_thing) + end, + + [ "saturation" ] = function(itemstack, placer, pointed_thing, player) + mcl_potions.give_effect_by_level("saturation", placer, 1, 0.5) return eat(itemstack, placer, pointed_thing) end, ["jump"] = function(itemstack, placer, pointed_thing) - mcl_potions.leaping_func(placer, 1, 6) + mcl_potions.give_effect_by_level("leaping", placer, 1, 6) return eat(itemstack, placer, pointed_thing) end, ["regeneration"] = function(itemstack, placer, pointed_thing) - mcl_potions.regeneration_func(placer, 1, 8) + mcl_potions.give_effect_by_level("regeneration", placer, 1, 8) + return eat(itemstack, placer, pointed_thing) + end, + + ["withering"] = function(itemstack, placer, pointed_thing) + mcl_potions.give_effect_by_level("withering", placer, 1, 8) + return eat(itemstack, placer, pointed_thing) + end, + + ["weakness"] = function(itemstack, placer, pointed_thing) + mcl_potions.give_effect_by_level("weakness", placer, 1, 9) return eat(itemstack, placer, pointed_thing) end, ["night_vision"] = function(itemstack, placer, pointed_thing) - mcl_potions.night_vision_func(placer, 1, 5) + mcl_potions.give_effect("night_vision", placer, 1, 5) return eat(itemstack, placer, pointed_thing) end, } @@ -52,17 +75,75 @@ local function get_random_effect() return effects[keys[math.random(#keys)]] end -local function eat_stew(itemstack, placer, pointed_thing) +local function eat_stew(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + if user and not user:get_player_control().sneak then + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + end + end + end + elseif pointed_thing.type == "object" then + return itemstack + end + local e = itemstack:get_meta():get_string("effect") local f = effects[e] if not f then f = get_random_effect() end - if f(itemstack,placer,pointed_thing) then + if f(itemstack, user, pointed_thing) then return "mcl_core:bowl" end end +local function eat_stew_delayed(itemstack, user, pointed_thing) + + if pointed_thing.type == "node" then + if user and not user:get_player_control().sneak then + -- Use pointed node's on_rightclick function first, if present + local node = minetest.get_node(pointed_thing.under) + if user and not user:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + end + end + end + elseif pointed_thing.type == "object" then + return itemstack + end + + -- Wrapper for handling mcl_hunger delayed eating + local name = user:get_player_name() + mcl_hunger.eat_internal[name]._custom_itemstack = itemstack -- Used as comparison to make sure the custom wrapper executes only when the same item is eaten + mcl_hunger.eat_internal[name]._custom_var = { + itemstack = itemstack, + user = user, + pointed_thing = pointed_thing, + } + mcl_hunger.eat_internal[name]._custom_func = eat_stew + mcl_hunger.eat_internal[name]._custom_wrapper = function(name) + + mcl_hunger.eat_internal[name]._custom_func( + mcl_hunger.eat_internal[name]._custom_var.itemstack, + mcl_hunger.eat_internal[name]._custom_var.user, + mcl_hunger.eat_internal[name]._custom_var.pointed_thing + ) + + local user = mcl_hunger.eat_internal[name]._custom_var.user + + minetest.after(0, function() + user:get_inventory():set_stack("main", user:get_wield_index(), "mcl_core:bowl") + end) + end + + mcl_hunger.eat_internal[name]._custom_do_delayed = true -- Only _custom_wrapper will be executed after holding RMB or LMB within a specified delay + --minetest.do_item_eat(0, "mcl_core:bowl", itemstack, user, pointed_thing) +end + minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) if itemstack:get_name() ~= "mcl_sus_stew:stew" then return end for f,e in pairs(flower_effect) do @@ -78,11 +159,13 @@ end) -- ________________________ --_________________________________________/ Item Regestration \_________________ minetest.register_craftitem("mcl_sus_stew:stew",{ - description = "Suspicious Stew", + description = S("Suspicious Stew"), inventory_image = "sus_stew.png", stack_max = 1, - on_place = eat_stew, - on_secondary_use = eat_stew, + --on_place = eat_stew, + --on_secondary_use = eat_stew, + on_place = eat_stew_delayed, + on_secondary_use = eat_stew_delayed, groups = { food = 2, eatable = 4, can_eat_when_full = 1, not_in_creative_inventory=1,}, _mcl_saturation = 7.2, }) diff --git a/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.fr.tr b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.fr.tr new file mode 100644 index 000000000..bc6ad5b88 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.fr.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_sus_stew +Suspicious Stew=Soupe suspecte diff --git a/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.pt_BR.tr b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.pt_BR.tr new file mode 100644 index 000000000..ece9c8301 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_sus_stew +Suspicious Stew=Ensopado Suspeito diff --git a/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.ru.tr b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.ru.tr new file mode 100644 index 000000000..9ae7d2cab --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/locale/mcl_sus_stew.ru.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_sus_stew +Suspicious Stew=Подозрительный суп diff --git a/mods/ITEMS/mcl_sus_stew/locale/template.txt b/mods/ITEMS/mcl_sus_stew/locale/template.txt new file mode 100644 index 000000000..5a69365e2 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain: mcl_sus_stew +Suspicious Stew= diff --git a/mods/ITEMS/mcl_throwing/README.md b/mods/ITEMS/mcl_throwing/README.md index a1ad06a8e..fe5069536 100644 --- a/mods/ITEMS/mcl_throwing/README.md +++ b/mods/ITEMS/mcl_throwing/README.md @@ -1,6 +1,6 @@ # `mcl_throwing` -It's a MineClone 2 mod containing throwable items like snowballs. +It's a VoxeLibre mod containing throwable items like snowballs. ## License of code @@ -29,4 +29,4 @@ It's a MineClone 2 mod containing throwable items like snowballs. - Source: - Original title: `Arrow002.wav` (file was edited) -- Everything else: See MineClone 2 license infos +- Everything else: See VoxeLibre license infos diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pt_BR.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pt_BR.tr new file mode 100644 index 000000000..8cdaff4d5 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pt_BR.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_throwing +@1 used the ender pearl too often.=@1 usou a pérola do ender muitas vezes. +Use the punch key to throw.=Use o botão de soco para arremessar. +Snowball=Bola de Neve +Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing.=Bolas de neve podem ser arremessadas ou lançadas a partir de um ejetor por diversão. Atingir coisas com bolas de neve não fará coisa alguma. +Egg=Ovo +Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg.=Ovos podem ser arremessados ou lançados a partir de um ejetor e quebra no impacto. Existe uma pequena chance de 1 ou até 4 pintinhos aparecerem desse ovo. +Ender Pearl=Pérola do Ender +An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points.=Uma pérola do ender é um item ao qual pode ser usado para teleporte ao custo de saúde. Pode ser arremessada e teleporta o arremessador para seu local de impacto quando acerta um bloco sólido ou uma planta. Cada teleporte machuca o usuário em 5 pontos de dano. +Throwable=Arremesaável +Chance to hatch chicks when broken=Chance de eclodir pintinhos quando quebrado +Teleports you on impact for cost of 5 HP=Teleporta você no impacto ao custo de 5 HP diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ru.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ru.tr index 7670f729c..a58f8da92 100644 --- a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ru.tr +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ru.tr @@ -1,12 +1,12 @@ # textdomain: mcl_throwing -@1 used the ender pearl too often.=@1 использовал(а) жемчужину Предела слишком часто. -Use the punch key to throw.=Используй клавишу удара для броска. +@1 used the ender pearl too often.=@1 использовал(а) жемчуг Края слишком часто. +Use the punch key to throw.=Используйте клавишу удара для броска. Snowball=Снежок -Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing.=Снежки можно бросать или запускать из диспенсера для веселья. Попадание снежком в кого-либо ни к чему не приводит. +Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing.=Снежки можно бросать или запускать из раздатчика для веселья. Попадание снежком в кого-либо ничего не делает. Egg=Яйцо -Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg.=Яйца можно бросать или запускать из диспенсера, они ломаются при ударе. Есть небольшой шанс вылупления 1 или даже 4 цыплят из яйца. -Ender Pearl=Жемчужина Предела -An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points.=Жемчужина Предела это предмет, который можно использовать для телепортации за счёт единиц вашего здоровья. Его можно бросить, и это телепортирует бросившего в место удара, когда он попадает в сплошной блок или растение. Каждая телепортация ранит пользователя на 5 очков здоровья (HP). +Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg.=Яйца можно бросать или запускать из раздатчика, они ломаются при столкновении. Есть небольшой шанс вылупления 1 или даже 4 цыплят из яйца. +Ender Pearl=Жемчуг Края +An ender pearl is an item which can be used for teleportation at the cost of health. It can be thrown and teleport the thrower to its impact location when it hits a solid block or a plant. Each teleportation hurts the user by 5 hit points.=Жемчуг Края это предмет, который можно использовать для телепортации за счёт единиц вашего здоровья. Его можно бросить, и это телепортирует бросившего в то место, куда упадает жемчуг. Каждая телепортация ранит игрока на 5 очков здоровья. Throwable=Можно бросать Chance to hatch chicks when broken=Шанс вылупления цыплят при разбитии -Teleports you on impact for cost of 5 HP=Телепортирует вас при ударе за счёт 5 HP +Teleports you on impact for cost of 5 HP=Телепортирует вас; урон 5 HP от столкновения diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua index 43dedd33b..3a91a18b9 100644 --- a/mods/ITEMS/mcl_throwing/register.lua +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -293,7 +293,7 @@ minetest.register_craftitem("mcl_throwing:snowball", { _doc_items_longdesc = S("Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing."), _doc_items_usagehelp = how_to_throw, inventory_image = "mcl_throwing_snowball.png", - stack_max = 16, + stack_max = 64, groups = { weapon_ranged = 1 }, on_use = mcl_throwing.get_player_throw_function("mcl_throwing:snowball_entity"), _on_dispense = mcl_throwing.dispense_function, @@ -306,7 +306,7 @@ minetest.register_craftitem("mcl_throwing:egg", { _doc_items_longdesc = S("Eggs can be thrown or launched from a dispenser and breaks on impact. There is a small chance that 1 or even 4 chicks will pop out of the egg."), _doc_items_usagehelp = how_to_throw, inventory_image = "mcl_throwing_egg.png", - stack_max = 16, + stack_max = 64, on_use = mcl_throwing.get_player_throw_function("mcl_throwing:egg_entity"), _on_dispense = mcl_throwing.dispense_function, groups = { craftitem = 1 }, diff --git a/mods/ITEMS/mcl_tnt/README.txt b/mods/ITEMS/mcl_tnt/README.txt index 5b1c10798..9528b7993 100644 --- a/mods/ITEMS/mcl_tnt/README.txt +++ b/mods/ITEMS/mcl_tnt/README.txt @@ -1,5 +1,5 @@ === TNT mod for Minetest === -by PilzAdam. HEAVILY modified for MineClone 2. +by PilzAdam. HEAVILY modified for VoxeLibre. Introduction: This mod adds TNT. TNT is a tool to help the player in mining. diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pt_BR.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pt_BR.tr new file mode 100644 index 000000000..739d1414b --- /dev/null +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_tnt +@1 was caught in an explosion.=@1 foi pego(a) em uma explosão. +TNT=TNT +An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=Um artefato explosivo. Quando explode, machuca seres vivos e destrói blocos a sua volta. A TNT tem um raio de explosão de @1. Com pouca chance, blocos talvez dropem como um item (como se fosse minerado) ao invés de ser destruido. A TNT pode ser acesa por ferramentas explosões, fogo, lava e sinais de redstone. +An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals.= +Place the TNT and ignite it with one of the methods above. Quickly get in safe distance. The TNT will start to be affected by gravity and explodes in 4 seconds.= Posicione a TNT e acenda-a com um dos métodos acima. Rapidamente mantenha uma distância segura. A TNT começará a ser afetada pela gravidade e explodirá em 4 segundos. +Ignited by tools, explosions, fire, lava, redstone power=Acesa por ferramentas, explosões, fogo, lava, carga de redstone +Explosion radius: @1=Raio de explosão: @1 diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ru.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ru.tr index 9724c7552..366c92cd2 100644 --- a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ru.tr +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ru.tr @@ -1,8 +1,8 @@ # textdomain: mcl_tnt -@1 was caught in an explosion.=@1 попал в радиус действия взрыва. -TNT=Тротил -An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=Взрывное устройство. Когда оно взрывается, то причиняет вред живым существам и разрушает блоки вокруг себя. Тротил имеет радиус взрыва @1. С небольшой вероятностью блоки могут выпадать в качестве предметов (как при добыче), а не уничтожаться. Тротил может быть подорван инструментами, взрывами, огнём, лавой и сигналами редстоуна. -An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=Взрывное устройство. Когда оно взрывается, то причиняет вред живым существам и разрушает блоки вокруг себя. Тротил имеет радиус взрыва @1. Тротил может быть подорван инструментами, взрывами, огнём, лавой и сигналами редстоуна. -Place the TNT and ignite it with one of the methods above. Quickly get in safe distance. The TNT will start to be affected by gravity and explodes in 4 seconds.=Разместите тротил, зажгите его одним из методов, описанных выше. Отбегите на безопасное расстояние. Тротил начнет подвергаться воздействию силы тяжести и взорвётся через 4 секунды. -Ignited by tools, explosions, fire, lava, redstone power=Зажигается инструментами, взрывами, огнём, лавой, энергией редстоуна +@1 was caught in an explosion.=@1 попал(а) под взрыв. +TNT=ТНТ +An explosive device. When it explodes, it will hurt living beings and destroy blocks around it. TNT has an explosion radius of @1. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=Взрывчатка. Когда она взрывается, то причиняет вред живым существам и разрушает блоки вокруг себя. ТНТ имеет радиус взрыва @1. С небольшой вероятностью блоки могут выпадать в качестве предметов (как при добыче), а не уничтожаться. ТНТ может быть подорван инструментами, взрывом, огнём, лавой и сигналом редстоуна. +An explosive device. When it explodes, it will hurt living beings. TNT has an explosion radius of @1. TNT can be ignited by tools, explosions, fire, lava and redstone signals.=Взрывчатка. Когда она взрывается, то причиняет вред живым существам. ТНТ имеет радиус взрыва @1. ТНТ может быть подорван инструментами, взрывом, огнём, лавой и сигналом редстоуна. +Place the TNT and ignite it with one of the methods above. Quickly get in safe distance. The TNT will start to be affected by gravity and explodes in 4 seconds.=Разместите ТНТ, зажгите его одним из методов, описанных выше. Отбегите на безопасное расстояние. ТНТ начнет подвергаться воздействию силы тяжести и взорвётся через 4 секунды. +Ignited by tools, explosions, fire, lava, redstone power=Зажигается инструментами, взрывом, огнём, лавой, сигналом редстоуна Explosion radius: @1=Радиус взрыва: @1 diff --git a/mods/ITEMS/mcl_tools/README.md b/mods/ITEMS/mcl_tools/README.md index 8089da923..5a3b5bda3 100644 --- a/mods/ITEMS/mcl_tools/README.md +++ b/mods/ITEMS/mcl_tools/README.md @@ -1,4 +1,4 @@ -This mod adds tools for MineClone 2. +This mod adds tools for VoxeLibre. ## Credits @@ -7,4 +7,4 @@ This mod adds tools for MineClone 2. * Source: Other files: -See main MineClone 2 README. +See main VoxeLibre README. diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 5f96fa3fa..266adc6fc 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -165,12 +165,13 @@ local make_grass_path = function(itemstack, placer, pointed_thing) end end - -- Only make grass path if tool used on side or top of target node + -- Only make or remove grass path if tool used on side or top of target node if pointed_thing.above.y < pointed_thing.under.y then return itemstack end - if (minetest.get_item_group(node.name, "path_creation_possible") == 1) then +-- Remove grass paths + if (minetest.get_item_group(node.name, "path_remove_possible") == 1) and placer:get_player_control().sneak then local above = table.copy(pointed_thing.under) above.y = above.y + 1 if minetest.get_node(above).name == "air" then @@ -185,9 +186,34 @@ local make_grass_path = function(itemstack, placer, pointed_thing) local wear = mcl_autogroup.get_wear(toolname, "shovely") if wear then itemstack:add_wear(wear) + tt.reload_itemstack_description(itemstack) -- update tooltip end end - minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) + minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above, max_hear_distance = 16}, true) + minetest.swap_node(pointed_thing.under, {name="mcl_core:dirt"}) + end + end + +-- Make grass paths + if (minetest.get_item_group(node.name, "path_creation_possible") == 1) and not placer:get_player_control().sneak then + local above = table.copy(pointed_thing.under) + above.y = above.y + 1 + if minetest.get_node(above).name == "air" then + if minetest.is_protected(pointed_thing.under, placer:get_player_name()) then + minetest.record_protection_violation(pointed_thing.under, placer:get_player_name()) + return itemstack + end + + if not minetest.is_creative_enabled(placer:get_player_name()) then + -- Add wear (as if digging a shovely node) + local toolname = itemstack:get_name() + local wear = mcl_autogroup.get_wear(toolname, "shovely") + if wear then + itemstack:add_wear(wear) + tt.reload_itemstack_description(itemstack) -- update tooltip + end + end + minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above, max_hear_distance = 16}, true) minetest.swap_node(pointed_thing.under, {name="mcl_core:grass_path"}) end end @@ -216,6 +242,7 @@ if minetest.get_modpath("mcl_farming") then local wear = mcl_autogroup.get_wear(toolname, "shearsy") if wear then itemstack:add_wear(wear) + tt.reload_itemstack_description(itemstack) -- update tooltip end end @@ -396,6 +423,7 @@ local function make_stripped_trunk(itemstack, placer, pointed_thing) local wear = mcl_autogroup.get_wear(toolname, "axey") if wear then itemstack:add_wear(wear) + tt.reload_itemstack_description(itemstack) -- update tooltip end end end @@ -661,7 +689,7 @@ minetest.register_tool("mcl_tools:shears", { inventory_image = "default_tool_shears.png", wield_image = "default_tool_shears.png", stack_max = 1, - groups = { tool=1, shears=1, dig_speed_class=4, }, + groups = { tool=1, shears=1, dig_speed_class=4, enchantability=-1, }, tool_capabilities = { full_punch_interval = 0.5, max_drop_level=1, diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.pt_BR.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.pt_BR.tr new file mode 100644 index 000000000..a16b7868d --- /dev/null +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.pt_BR.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_tools +You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=Você usa sua mão nua sempre que não estiver segurando qualquer item. Com sua mão você pode minerar a maioria dos blocos, porém esse é o método mais lento e apenas os blocos mais fracos vão render seus drops úteis. A mão também dá o mínimo de dano quando soca. Usar a mão é muitas vezes o último recurso, uma vez que ferramentas de mineração apropriadas e armas são muito melhores. +When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.=Quando você estiver segurando um item o qual não é uma ferramenta de mineração ou uma arma, este se comportará como se fosse a mão quando você começa a minerar ou socar. +In Creative Mode, the hand is able to break all blocks instantly.=No Modo Criativo, a mão é capaz de quebrar todos os blocos instantaneamente. +Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Picaretas são ferramentas de mineração para minerar blocos duros, como rochas. Uma picareta também pode ser usada como arma, mas é bastante ineficiente. +An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.=Um machado é sua ferramenta preferida para cortar árvores, blocos de madeira e outros blocos. Machados também dão muito dano, mas são bastante lentos. +Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.=Espadas são excelentes no combate corpo a corpo, já que são rápidas, dão muito dano e podem suportar inúmeras batalhas. Espadas também podem ser usadas para cortar alguns blocos específicos, como as teias. +Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=Pás são ferramentas para cavar blocos grossos, como as terras, areias e cascalho. Também podem ser usadas para transformar blocos de grama em caminhos de grama. Pás podem ser usadas como armas, mas são muito fracas. +To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.=Para transformar um bloco de grama em um caminho de grama, segure a pá na sua mão, então use (clique com o botão direito) no topo ou lados de um bloco de grama. Isso só funcionará quando houver ar sobre o bloco de grama. +Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.=Tesouras são ferramentas para tosquear ovelhas e para minerar alguns tipos de blocos específicos. Tesouras são uma ferramenta de mineração especial e podem ser usadas para obter o item original da grama, folhas e blocos semelhantes que requerem corte. +To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=Para tosquear ovelhas ou escavar abóboras, use a tecla "posicionar" neles. Rostos podem ser escavados na lateral das abóboras. Minerar funciona como de costume, porém os drops são diferentes para alguns blocos específicos. +Wooden Pickaxe=Picareta de Madeira +Stone Pickaxe=Picareta de Pedra +Iron Pickaxe=Picareta de Ferro +Golden Pickaxe=Picareta de Ouro +Diamond Pickaxe=Picareta de Diamante +Netherite Pickaxe=Picareta de Netherite +Wooden Shovel=Pá de Madeira +Stone Shovel=Pá de Pedra +Iron Shovel=Pá de Ferro +Golden Shovel=Pá de Ouro +Diamond Shovel=Pá de Diamante +Netherite Shovel=Pá de Netherite +Wooden Axe=Machado de Madeira +Stone Axe=Machado de Pedra +Iron Axe=Machado de Ferro +Golden Axe=Machado de Ouro +Diamond Axe=Machado de Diamante +Netherite Axe=Machado de Netherite +Wooden Sword=Espada de Madeira +Stone Sword=Espada de Pedra +Iron Sword=Espada de Ferro +Golden Sword=Espada de Ouro +Diamond Sword=Espada de Diamante +Netherite Sword=Espada de Netherite +Shears=Tesoura diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr index e82fa15ef..c19e368fc 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.ru.tr @@ -1,32 +1,36 @@ # textdomain: mcl_tools -You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=Вы используете пустую руку, если не держите в ней никакого предмета. Пустой рукой вашей стороны вы можете добывать большинство блоков, но это самый медленный метод, который позволит добыть что-то полезное только из самых слабых блоков Рука также наносит небольшой урон при ударе. Использование пустой руки часто является последним средством, поскольку гораздо предпочтительнее использовать правильные подобранные инструменты и оружие. -When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.=Когда вы держите предмет, не являющийся инструментом майнинга или оружием, то при майнинге или ударах он будет вести себя так, как если бы это была пустая рука. -In Creative Mode, the hand is able to break all blocks instantly.=В творческом режиме пустая рука мгновенно ломает любой блок. -Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Кирка это инструмент для добычи тяжёлых блоков - камней и т. п. Кирка также может использоваться в качестве оружия, но не особо эффективного. -An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.=Топор это ваш лучший выбор для рубки деревьев, деревянных и других блоков. Топор также причиняет высокий урон, но бьёт довольно медленно. -Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.=Меч это оружие ближнего боя, он быстр, он наносит высокий урон и может выдержать множество битв. Меч также можно использовать для разрубания специфических блоков, например, паутины. -Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=Лопата - инструмент для выкапывания заборных блоков, таких как грязь, песок и гравий. Их также можно использовать, чтобы превращать блоки травы в тропинки. Лопату можно использовать и в качестве оружия, но очень слабого. -To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.=Чтобы превратить блок травы в тропинку, кликните правой по верхней его стороне, держа лопату в руке. Это сработает, только если над блоком травы есть воздух. -Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.=Ножницы это инструмент для стрижки овец, ими также можно добыть несколько других блоков. Ножницы это специальный инструмент, которым можно добывать оригинальные предметы травы, листьев и тому подобных, требующих стрижки. -To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=Чтобы остричь овцу или вырезать безликую тыкву, нажмите клавишу “Разместить” на вашей цели. Лица могут быть вырезаны только на сторонах безликих тыкв. Добыча работает как обычно, но полученные предметы будут различаться для нескольких разных блоков. +You use your bare hand whenever you are not wielding any item. With your hand you can mine most blocks, but this is the slowest method and only the weakest blocks will yield their useful drop. The hand also deals minor damage by punching. Using the hand is often a last resort, as proper mining tools and weapons are much better.=Вы используете руку, если не держите в ней никакого предмета. Пустой рукой вы можете добывать большинство блоков, но это самый медленный метод, который позволит добыть что-то полезное только из самых слабых блоков. Рука также наносит небольшой урон при ударе. Использование руки часто является последним средством, поскольку гораздо предпочтительнее использовать правильные подобранные инструменты и оружие. +When you are wielding an item which is not a mining tool or a weapon, it will behave as if it were the hand when you start mining or punching.=Когда вы держите предмет, не являющийся инструментом добычи или оружием, то при добыче или ударах он будет вести себя так, как если бы это была пустая рука. +In Creative Mode, the hand is able to break all blocks instantly.=В творческом режиме рука мгновенно ломает любой блок. +Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Кирка это инструмент для добычи твёрдых блоков - камней и т. п. Кирка также может использоваться в качестве оружия, но не особо эффективного. +An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.=Топор это лучший выбор для рубки деревьев, деревянных и подобных блоков. Топор также причиняет высокий урон, но бьёт довольно медленно. +Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.=Меч это оружие ближнего боя, он быстр, наносит высокий урон и может выдержать множество сражений. Меч также можно использовать для разрубания специфических блоков, например, паутины. +Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.=Лопата - инструмент для выкапывания рыхлых блоков, таких как земля, песок и гравий. Лопату также можно использовать, чтобы превращать дёрн в тропинки. Лопату можно использовать и в качестве оружия, но очень слабого. +To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.=Чтобы превратить блок дёрна в тропинку, кликните правой кнопкой мыши по его верхней стороне, держа лопату в руке. Это сработает, только если над блоком травы есть воздух. +Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.=Ножницы это инструмент для стрижки овец, но ими также можно добыть несколько блоков. Ножницы это специальный инструмент, которым можно добывать траву, листьея и тому подобные. +To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.=Чтобы остричь овцу или вырезать тыкву, нажмите правую кнопку мыши на вашей цели. Лица могут быть вырезаны только по бокам тыквы. Добывание работает как обычно, но полученные предметы будут различаться для нескольких разных блоков. Wooden Pickaxe=Деревянная кирка Stone Pickaxe=Каменная кирка Iron Pickaxe=Железная кирка Golden Pickaxe=Золотая кирка Diamond Pickaxe=Алмазная кирка +Netherite Pickaxe=Незеритовая кирка Wooden Shovel=Деревянная лопата Stone Shovel=Каменная лопата Iron Shovel=Железная лопата Golden Shovel=Золотая лопата Diamond Shovel=Алмазная лопата +Netherite Shovel=Незеритовая лопата Wooden Axe=Деревянный топор Stone Axe=Каменный топор Iron Axe=Железный топор Golden Axe=Золотой топор Diamond Axe=Алмазный топор +Netherite Axe=Незеритовый топор Wooden Sword=Деревянный меч Stone Sword=Каменный меч Iron Sword=Железный меч Golden Sword=Золотой меч Diamond Sword=Алмазный меч +Netherite Sword=Незеритовый меч Shears=Ножницы diff --git a/mods/ITEMS/mcl_torches/README.txt b/mods/ITEMS/mcl_torches/README.txt index a1dd8eb77..e1e03dcac 100644 --- a/mods/ITEMS/mcl_torches/README.txt +++ b/mods/ITEMS/mcl_torches/README.txt @@ -20,7 +20,7 @@ nodes. Conversion from the wallmounted style is done through an LBM. Torches is meant for minetest-0.4.14, and does not directly support older minetest releases. You'll need a recent git, or nightly build. -Changes for MineClone: +Changes for VoxeLibre: ~~~~~~~~~~~~~~~~~~~~~~ - Torch does not generate light when wielding - Torch drops when near water diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.pt_BR.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.pt_BR.tr new file mode 100644 index 000000000..fc49b3a0f --- /dev/null +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_torches +Torch=Tocha +Torches are light sources which can be placed at the side or on the top of most blocks.=Tochas são fontes de luz as quais podem ser posicionadas nas laterais ou na parte superior de muitos blocos. diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.ru.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.ru.tr index c3812eaad..a10f21acb 100644 --- a/mods/ITEMS/mcl_torches/locale/mcl_torches.ru.tr +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.ru.tr @@ -1,3 +1,3 @@ # textdomain: mcl_torches Torch=Факел -Torches are light sources which can be placed at the side or on the top of most blocks.=Факелы это источники света, которые можно вешать на стены или ставить на верхние части большинства блоков. +Torches are light sources which can be placed at the side or on the top of most blocks.=Факел это источник света, который можно поставить на большинство блоков сверху или сбоку. \ No newline at end of file diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.pt_BR.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.pt_BR.tr new file mode 100644 index 000000000..c7ab1f3eb --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=Totem da Imortalidade +A totem of undying is a rare artifact which may safe you from certain death.=Um totem da imortalidade é um artefato raro ao qual pode segurar você contra certas mortes. +The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=O totem apenas funciona enquanto você o segura em sua mão. Se você receber um dano fatal, você será salvo da morte e receberá uma segunda chance com 1 HP. Porém, o totem é destruído no processo. +Protects you from death while wielding it=Proteje você da morte enquanto você segura-o diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr index d293efe01..e381e283d 100644 --- a/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr @@ -1,5 +1,5 @@ # textdomain: mcl_totems Totem of Undying=Тотем бессмертия -A totem of undying is a rare artifact which may safe you from certain death.=Тотем бессмертия это редкий артефакт, способный спасти вас от смерти. +A totem of undying is a rare artifact which may safe you from certain death.=Тотем бессмертия это редкий артефакт способный спасти вас от смерти. The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Тотем работает только когда вы держите его в руке. Если вы получаете смертельный урон, вы спасаетесь от смерти и получаете второй шанс с 1 HP. Однако тотем при этом уничтожается. -Protects you from death while wielding it=Защищает вас от смерти, пока вы владеете им +Protects you from death while wielding it=Защищает вас от смерти пока вы держите его diff --git a/mods/ITEMS/mcl_walls/API.md b/mods/ITEMS/mcl_walls/API.md index e6956ac47..63621ade1 100644 --- a/mods/ITEMS/mcl_walls/API.md +++ b/mods/ITEMS/mcl_walls/API.md @@ -1,8 +1,8 @@ -# API for MineClone 2 walls +# API for VoxeLibre walls -This API allows you to add more walls (like the cobblestone wall) to MineClone 2. +This API allows you to add more walls (like the cobblestone wall) to VoxeLibre. -## `mcl_walls.register_wall(nodename, description, craft_material, tiles, invtex, groups, sounds)` +## `mcl_walls.register_wall(nodename, description, craft_material, tiles, invtex, groups, sounds, hardness, blast_resistance)` Adds a new wall type. This is optimized for stone-based walls, but other materials are theoretically possible, too. @@ -25,6 +25,8 @@ If `craft_material` is not `nil` it also adds a crafting recipe of the following * `inventory_image`: Inventory image (optional if `source` is set) * `groups`: Base group memberships (optional, default is `{pickaxey=1}`) * `sounds`: Sound table (optional, by default default uses stone sounds) +* `hardness`: Hardness of node (optional, default matches `source` node or fallback value 2) +* `blast_resistance`: Blast resistance of node (optional, default matches `source` node or fallback value 6) The following groups will automatically be added to the nodes (where applicable), you do not need to add them to the `groups` table: diff --git a/mods/ITEMS/mcl_walls/init.lua b/mods/ITEMS/mcl_walls/init.lua index 14b512ffd..09a35b549 100644 --- a/mods/ITEMS/mcl_walls/init.lua +++ b/mods/ITEMS/mcl_walls/init.lua @@ -97,8 +97,10 @@ local full_blocks = { * inventory_image: Inventory image (optional) * groups: Base group memberships (optional, default is {pickaxey=1}) * sounds: Sound table (optional, default is stone) +* hardness: Hardness of node (optional, default matches `source` node or fallback value 2) +* blast_resistance: Blast resistance of node (optional, default matches `source` node or fallback value 6) ]] -function mcl_walls.register_wall(nodename, description, source, tiles, inventory_image, groups, sounds) +function mcl_walls.register_wall(nodename, description, source, tiles, inventory_image, groups, sounds, hardness, blast_resistance) local base_groups = groups if not base_groups then @@ -112,15 +114,29 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory local main_node_groups = table.copy(base_groups) main_node_groups.deco_block = 1 - -- TODO: Stop hardcoding blast resistance - - if not sounds then - sounds = mcl_sounds.node_sound_stone_defaults() - end - - if (not tiles) and source then - if minetest.registered_nodes[source] then - tiles = minetest.registered_nodes[source].tiles + if source then + -- Default values from `source` node + if not hardness then + hardness = minetest.registered_nodes[source]._mcl_hardness + end + if not blast_resistance then + blast_resistance = minetest.registered_nodes[source]._mcl_blast_resistance + end + if not sounds then + sounds = minetest.registered_nodes[source].sounds + end + if not tiles then + if minetest.registered_nodes[source] then + tiles = minetest.registered_nodes[source].tiles + end + end + else + -- Fallback in case no `source` given + if not hardness then + hardness = 2 + end + if not blast_resistance then + blast_resistance = 6 end end @@ -169,8 +185,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = take }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help @@ -197,8 +213,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = {pillar, full_blocks[1]} }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help if minetest.get_modpath("doc") then @@ -223,8 +239,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = {pillar, full_blocks[2]} }, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) -- Add entry alias for the Help if minetest.get_modpath("doc") then @@ -255,8 +271,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory collisionbox = {-0.2, 0, -0.2, 0.2, 1.4, 0.2}, on_construct = update_wall, sounds = sounds, - _mcl_blast_resistance = 6, - _mcl_hardness = 2, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, }) if source then minetest.register_craft({ @@ -266,6 +282,8 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory {source, source, source}, } }) + + mcl_stonecutter.register_recipe(source, nodename) end end diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.pt_BR.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.pt_BR.tr new file mode 100644 index 000000000..8d06a55d1 --- /dev/null +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.pt_BR.tr @@ -0,0 +1,17 @@ +# textdomain: mcl_walls +A piece of wall. It cannot be jumped over with a simple jump. When multiple of these are placed to next to each other, they will automatically build a nice wall structure.=Um pedaço de muro. Não pode ser pulado com um pulo simples. Quando muitos desses são posicionados próximos uns aos outros, vão construir automaticamente uma bela estrutura de muro. +Cobblestone Wall=Muro de Pedregulho +Mossy Cobblestone Wall=Muro de Pedregulho Musgoso +Andesite Wall=Muro de Andesito +Granite Wall=Muro de Granito +Diorite Wall=Muro de Diorito +Brick Wall=Muro de Tijolos +Sandstone Wall=Muro de Arenito +Red Sandstone Wall=Muro de Arenito Vermelho +Stone Brick Wall=Muro de Tijolos de Pedra +Mossy Stone Brick Wall=Muro de Tijolos de Pedra Musgosos +Prismarine Wall=Muro de Prismarinho +End Stone Brick Wall=Muro de Tijolos de Pedra do End +Nether Brick Wall=Muro de Tijolos do Nether +Red Nether Brick Wall=Muro de Tijolos Vermelhos do Nether +Mud Brick Wall=Muro de Tijolos de Barro diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.ru.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.ru.tr index deb0fa289..57654101f 100644 --- a/mods/ITEMS/mcl_walls/locale/mcl_walls.ru.tr +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.ru.tr @@ -1,16 +1,17 @@ # textdomain: mcl_walls -A piece of wall. It cannot be jumped over with a simple jump. When multiple of these are placed to next to each other, they will automatically build a nice wall structure.=Часть стены. Её нельзя перепрыгнуть простым прыжком. Когда несколько из них будут расположены рядом друг с другом, они автоматически создадут хорошую структуру стены. +A piece of wall. It cannot be jumped over with a simple jump. When multiple of these are placed to next to each other, they will automatically build a nice wall structure.=Часть стены. Её нельзя перепрыгнуть. Когда несколько блоков стены расположены по соседству, они визуально соединяются друг с другом в структуру. Cobblestone Wall=Стена из булыжника -Mossy Cobblestone Wall=Стена из мшистого булыжника +Mossy Cobblestone Wall=Стена из замшелого булыжника Andesite Wall=Андезитовая стена Granite Wall=Гранитная стена Diorite Wall=Диоритовая стена Brick Wall=Кирпичная стена Sandstone Wall=Стена из песчаника Red Sandstone Wall=Стена из красного песчаника -Stone Brick Wall=Стена из каменного блока -Mossy Stone Brick Wall=Стена из мшистого каменного блока +Stone Brick Wall=Стена из каменных кирпичей +Mossy Stone Brick Wall=Стена из замшелого каменного блока Prismarine Wall=Призмариновая стена -End Stone Brick Wall=Стена из камня Предела +End Stone Brick Wall=Стена из кирпичей Края Nether Brick Wall=Стена из адского кирпича -Red Nether Brick Wall=Стена из красного адского кирпича +Red Nether Brick Wall=Стена из адского красного кирпича +Mud Brick Wall=Стена из саманных кирпичей \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/mod.conf b/mods/ITEMS/mcl_walls/mod.conf index b6b221007..b099e4c1d 100644 --- a/mods/ITEMS/mcl_walls/mod.conf +++ b/mods/ITEMS/mcl_walls/mod.conf @@ -1,3 +1,3 @@ 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 diff --git a/mods/ITEMS/mcl_walls/register.lua b/mods/ITEMS/mcl_walls/register.lua index 96a1b9b9f..c2859935e 100644 --- a/mods/ITEMS/mcl_walls/register.lua +++ b/mods/ITEMS/mcl_walls/register.lua @@ -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: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:mudbrick", S("Mud Brick Wall"), "mcl_mud:mud_bricks") \ No newline at end of file +mcl_walls.register_wall("mcl_walls:mudbrick", S("Mud Brick Wall"), "mcl_mud:mud_bricks") diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.fr.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.fr.tr index 6b93eab08..fc89dd1ff 100644 --- a/mods/ITEMS/mcl_wool/locale/mcl_wool.fr.tr +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.fr.tr @@ -1,37 +1,37 @@ # textdomain: mcl_wool Wool=Laine Carpet=Tapis -White Wool=Laine Blanche -White Carpet=Tapis Blanc -Grey Wool=Laine Grise -Grey Carpet=Tapis Gris -Light Grey Wool=Laine Gris Clair -Light Grey Carpet=Tapis Gris Clair -Black Wool=Laine Noire -Black Carpet=Tapis Noir -Red Wool=Laine Rouge -Red Carpet=Tapis Rouge -Yellow Wool=Laine Jaune -Yellow Carpet=Tapis Jaune -Green Wool=Laine Verte -Green Carpet=Tapis Vert -Cyan Wool=Lain Cyan -Cyan Carpet=Tapis Cyan -Blue Wool=Laine Bleue -Blue Carpet=Tapis Bleu -Magenta Wool=Laine Magenta -Magenta Carpet=Tapis Magenta -Orange Wool=Laine Orange -Orange Carpet=Tapis Orange -Purple Wool=Laine Violette -Purple Carpet=Tapis Violet -Brown Wool=Laine Marron -Brown Carpet=Tapis Marron -Pink Wool=Laine Rose -Pink Carpet=Tapis Rose -Lime Wool=Laine Vert Clair -Lime Carpet=Tapis Vert Clair -Light Blue Wool=Laine Bleu Clair -Light Blue Carpet=Tapis Bleu Clair +White Wool=Laine blanche +White Carpet=Tapis blanc +Grey Wool=Laine grise +Grey Carpet=Tapis gris +Light Grey Wool=Laine gris clair +Light Grey Carpet=Tapis gris clair +Black Wool=Laine noire +Black Carpet=Tapis noir +Red Wool=Laine rouge +Red Carpet=Tapis rouge +Yellow Wool=Laine jaune +Yellow Carpet=Tapis jaune +Green Wool=Laine verte +Green Carpet=Tapis vert +Cyan Wool=Lain cyan +Cyan Carpet=Tapis cyan +Blue Wool=Laine bleue +Blue Carpet=Tapis bleu +Magenta Wool=Laine magenta +Magenta Carpet=Tapis magenta +Orange Wool=Laine orange +Orange Carpet=Tapis orange +Purple Wool=Laine violette +Purple Carpet=Tapis violet +Brown Wool=Laine marron +Brown Carpet=Tapis marron +Pink Wool=Laine rose +Pink Carpet=Tapis rose +Lime Wool=Laine vert clair +Lime Carpet=Tapis vert clair +Light Blue Wool=Laine bleu clair +Light Blue Carpet=Tapis bleu clair Wool is a decorative block which comes in many different colors.=La laine est un bloc décoratif disponible en différentes couleurs. Carpets are thin floor covers which come in many different colors.=Les tapis sont des revêtements de sol minces qui viennent dans de nombreuses couleurs différentes. diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.pt_BR.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.pt_BR.tr new file mode 100644 index 000000000..3ae9a6ce3 --- /dev/null +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.pt_BR.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_wool +Wool=Lã +Carpet=Carpete +White Wool=Lã Branco +White Carpet=Carpete Branco +Grey Wool=Lã Cinza +Grey Carpet=Carpete Cinza +Light Grey Wool=Lã Cinza Claro +Light Grey Carpet=Carpete Cinza Claro +Black Wool=Lã Preto +Black Carpet=Carpete Preto +Red Wool=Lã Vermelho +Red Carpet=Carpete Vermelho +Yellow Wool=Lã Amarelo +Yellow Carpet=Carpete Amarelo +Green Wool=Lã Verde +Green Carpet=Carpete Verde +Cyan Wool=Lã Ciano +Cyan Carpet=Carpete Ciano +Blue Wool=Lã Azul +Blue Carpet=Carpete Azul +Magenta Wool=Lã Magenta +Magenta Carpet=Carpete Magenta +Orange Wool=Lã Laranja +Orange Carpet=Carpete Laranja +Purple Wool=Lã Roxo +Purple Carpet=Carpete Roxo +Brown Wool=Lã Marrom +Brown Carpet=Carpete Marrom +Pink Wool=Lã Rosa +Pink Carpet=Carpete Rosa +Lime Wool=Lã Lima +Lime Carpet=Carpete Lima +Light Blue Wool=Lã Azul Claro +Light Blue Carpet=Carpete Azul Claro +Wool is a decorative block which comes in many different colors.=Lã é um bloco decorativo ao qual vêm em várias cores diferentes. +Carpets are thin floor covers which come in many different colors.=Carpetes são coberturas finas para o piso aos quais vêm em diferentes cores. diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.ru.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.ru.tr index 6b05812a2..1a6a3ad37 100644 --- a/mods/ITEMS/mcl_wool/locale/mcl_wool.ru.tr +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.ru.tr @@ -15,23 +15,23 @@ Yellow Wool=Жёлтая шерсть Yellow Carpet=Жёлтый ковёр Green Wool=Зелёная шерсть Green Carpet=Зелёный ковёр -Cyan Wool=Голубая шерсть -Cyan Carpet=Голубой ковёр +Cyan Wool=Бирюзовая шерсть +Cyan Carpet=Бирюзовый ковёр Blue Wool=Синяя шерсть Blue Carpet=Синий ковёр -Magenta Wool=Фиолетовая шерсть -Magenta Carpet=Фиолетовый ковёр +Magenta Wool=Сиреневая шерсть +Magenta Carpet=Сиреневый ковёр Orange Wool=Оранжевая шерсть Orange Carpet=Оранжевый ковёр -Purple Wool=Пурпурная шерсть -Purple Carpet=Пурпурный ковёр +Purple Wool=Фиолетовая шерсть +Purple Carpet=Фиолетовый ковёр Brown Wool=Коричневая шерсть Brown Carpet=Коричневый ковёр Pink Wool=Розовая шерсть Pink Carpet=Розовый ковёр -Lime Wool=Зелёная лаймовая шерсть -Lime Carpet=Зелёный лаймовый ковёр -Light Blue Wool=Светло-голубая шерсть -Light Blue Carpet=Светло-голубой ковёр +Lime Wool=Лаймовая шерсть +Lime Carpet=Лаймовый ковёр +Light Blue Wool=Голубая шерсть +Light Blue Carpet=Голубой ковёр Wool is a decorative block which comes in many different colors.=Шерсть это декоративный блок, который может быть разных цветов. Carpets are thin floor covers which come in many different colors.=Ковры это тонкие напольные покрытия, которые бывают разных цветов. diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.pt_BR.tr b/mods/ITEMS/mclx_core/locale/mclx_core.pt_BR.tr new file mode 100644 index 000000000..a6a8552c0 --- /dev/null +++ b/mods/ITEMS/mclx_core/locale/mclx_core.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mclx_core +River Water Source=Fonte de Água de Rio +River water has the same properties as water, but has a reduced flowing distance and is not renewable.=Água de rio têm as mesmas propriedades da água, mas tem uma distância de escoamento reduzido e não é renovável. +River Water=Água de Rio +Flowing River Water=Água Corrente de Rio diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.ru.tr b/mods/ITEMS/mclx_core/locale/mclx_core.ru.tr index 1f3155b58..3435b945a 100644 --- a/mods/ITEMS/mclx_core/locale/mclx_core.ru.tr +++ b/mods/ITEMS/mclx_core/locale/mclx_core.ru.tr @@ -1,5 +1,5 @@ # textdomain: mclx_core River Water Source=Источник речной воды -River water has the same properties as water, but has a reduced flowing distance and is not renewable.=Речная вода имеет все свойства простой воды, но течёт не так далеко и не возобновляется. +River water has the same properties as water, but has a reduced flowing distance and is not renewable.=Речная вода имеет все свойства обычной воды, но течёт не так далеко и не возобновляема. River Water=Речная вода Flowing River Water=Текущая речная вода diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.pt_BR.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.pt_BR.tr new file mode 100644 index 000000000..6de63f21d --- /dev/null +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mclx_fences +Red Nether Brick Fence=Cerca de Tijolos Vermelhos do Nether +Red Nether Brick Fence Gate=Portão de Tijolos Vermelhos do Nether +Nether Brick Fence Gate=Portão de Tijolos do Nether diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.ru.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.ru.tr index 146fb4dd7..32874b9e0 100644 --- a/mods/ITEMS/mclx_fences/locale/mclx_fences.ru.tr +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.ru.tr @@ -1,4 +1,4 @@ # textdomain: mclx_fences Red Nether Brick Fence=Забор из красного адского кирпича -Red Nether Brick Fence Gate=Ворота из красного адского кирпича -Nether Brick Fence Gate=Ворота из адского кирпича +Red Nether Brick Fence Gate=Калитка из красного адского кирпича +Nether Brick Fence Gate=Калитка из адского кирпича diff --git a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ru.tr b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ru.tr index 7dca54dd1..d5f973cde 100644 --- a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ru.tr +++ b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ru.tr @@ -1,82 +1,82 @@ # textdomain: mclx_stairs -Oak Bark Stairs=Ступеньки из дубовой коры +Oak Bark Stairs=Ступени из дубовой коры Oak Bark Slab=Плита из дубовой коры Double Oak Bark Slab=Двойная плита из дубовой коры -Acacia Bark Stairs=Ступеньки из коры акации -Acacia Bark Slab=Плита из коры акации -Double Acacia Bark Slab=Двойная плита из коры акации -Spruce Bark Stairs=Ступеньки из еловой коры +Acacia Bark Stairs=Ступени из акациевой коры +Acacia Bark Slab=Плита из акациевой коры +Double Acacia Bark Slab=Двойная плита из акациевой коры +Spruce Bark Stairs=Ступени из еловой коры Spruce Bark Slab=Плита из еловой коры Double Spruce Bark Slab=Двойная плита из еловой коры -Birch Bark Stairs=Ступеньки из берёзовой коры +Birch Bark Stairs=Ступени из берёзовой коры Birch Bark Slab=Плита из берёзовой коры Double Birch Bark Slab=Двойная плита из берёзовой коры -Jungle Bark Stairs=Ступеньки из коры дерева джунглей -Jungle Bark Slab=Плита из коры дерева джунглей -Double Jungle Bark Slab=Двойная плита из коры дерева джунглей -Dark Oak Bark Stairs=Ступеньки из коры тёмного дуба +Jungle Bark Stairs=Ступени из коры тропического дерева +Jungle Bark Slab=Плита из коры тропического дерева +Double Jungle Bark Slab=Двойная плита из коры тропического дерева +Dark Oak Bark Stairs=Ступени из коры тёмного дуба Dark Oak Bark Slab=Плита из коры тёмного дуба Double Dark Oak Bark Slab=Двойная плита из коры тёмного дуба -Lapis Lazuli Slab=Ляпис-лазурная плита -Double Lapis Lazuli Slab=Двойная ляпис-лазурная плита -Lapis Lazuli Stairs=Ляпис-лазурные ступеньки +Lapis Lazuli Slab=Лазуритовая плита +Double Lapis Lazuli Slab=Двойная лазуритовая плита +Lapis Lazuli Stairs=Лазуритовые ступени Slab of Gold=Золотая плита Double Slab of Gold=Двойная золотая плита -Stairs of Gold=Золотые ступеньки +Stairs of Gold=Золотые ступени Slab of Iron=Железная плита Double Slab of Iron=Двойная железная плита -Stairs of Iron=Железные ступеньки -Cracked Stone Brick Stairs=Ступеньки из треснутого камня -Cracked Stone Brick Slab=Плита из треснутого камня -Double Cracked Stone Brick Slab=Двойная плита из треснутого камня -White Concrete Stairs=Белые бетонные ступеньки -White Concrete Slab=Белая бетонная панель -Double White Concrete Slab=Белая двойная бетонная панель -Grey Concrete Stairs=Серые бетонные ступеньки -Grey Concrete Slab=Серая бетонная панель -Double Grey Concrete Slab=Серая двойная бетонная панель -Light Grey Concrete Stairs=Светло-серые бетонные ступеньки -Light Grey Concrete Slab=Светло-серая бетонная панель -Double Light Grey Concrete Slab=Светло-серая двойная бетонная панель -Black Concrete Stairs=Чёрные бетонные ступеньки -Black Concrete Slab=Чёрная бетонная панель -Double Black Concrete Slab=Черная двойная бетонная панель -Red Concrete Stairs=Красные бетонные ступеньки -Red Concrete Slab=Красная бетонная панель -Double Red Concrete Slab=Красная двойная бетонная панель -Yellow Concrete Stairs=Жёлтые бетонные ступеньки -Yellow Concrete Slab=Жёлтая бетонная панель -Double Yellow Concrete Slab=Жёлтая двойная бетонная панель -Green Concrete Stairs=Зелёные бетонные ступеньки -Green Concrete Slab=Зелёная бетонная панель -Double Green Concrete Slab=Зелёная двойная бетонная панель -Cyan Concrete Stairs=Голубые бетонные ступеньки -Cyan Concrete Slab=Голубая бетонная панель -Double Cyan Concrete Slab=Голубая двойная бетонная панель -Blue Concrete Stairs=Синие бетонные ступеньки -Blue Concrete Slab=Синяя бетонная панель -Double Blue Concrete Slab=Синяя двойная бетонная панель -Magenta Concrete Stairs=Фиолетовые бетонные ступеньки -Magenta Concrete Slab=Фиолетовая бетонная панель -Double Magenta Concrete Slab=Фиолетовая двойная бетонная панель -Orange Concrete Stairs=Оранжевые бетонные ступеньки -Orange Concrete Slab=Оранжевая бетонная панель -Double Orange Concrete Slab=Оранжевая двойная бетонная панель -Purple Concrete Stairs=Пурпурные бетонные ступеньки -Purple Concrete Slab=Пурпурная бетонная панель -Double Purple Concrete Slab=Пурпурная двойная бетонная панель -Brown Concrete Stairs=Коричневые бетонные ступеньки -Brown Concrete Slab=Коричневая бетонная панель -Double Brown Concrete Slab=Коричневая двойная бетонная панель -Pink Concrete Stairs=Розовые бетонные ступеньки -Pink Concrete Slab=Розовая бетонная панель -Double Pink Concrete Slab=Розовая двойная бетонная панель -Lime Concrete Stairs=Зелёные лаймовые бетонные ступеньки -Lime Concrete Slab=Зелёная лаймовая бетонная панель -Double Lime Concrete Slab=Зелёная лаймовая двойная бетонная панель -Light Blue Concrete Stairs=Светло-голубые бетонные ступеньки -Light Blue Concrete Slab=Светло-голубая бетонная панель -Double Light Blue Concrete Slab=Светло-голубая двойная бетонная панель -Concrete Slab=Бетонная панель -Double Concrete Slab=Двойная бетонная панель -Concrete Stairs=Бетонные ступеньки +Stairs of Iron=Железные ступени +Cracked Stone Brick Stairs=Ступени из потрескавшихся каменных кирпичей +Cracked Stone Brick Slab=Плита из потрескавшихся каменных кирпичей +Double Cracked Stone Brick Slab=Двойная плита из потрескавшихся каменных кирпичей +White Concrete Stairs=Белые бетонные ступени +White Concrete Slab=Белая бетонная плита +Double White Concrete Slab=Двойная белая бетонная плита +Grey Concrete Stairs=Серые бетонные ступени +Grey Concrete Slab=Серая бетонная плита +Double Grey Concrete Slab=Двойная серая бетонная плита +Light Grey Concrete Stairs=Светло-серые бетонные ступени +Light Grey Concrete Slab=Светло-серая бетонная плита +Double Light Grey Concrete Slab=Двойная светло-серая бетонная плита +Black Concrete Stairs=Чёрные бетонные ступени +Black Concrete Slab=Чёрная бетонная плита +Double Black Concrete Slab=Двойная чёрная бетонная плита +Red Concrete Stairs=Красные бетонные ступени +Red Concrete Slab=Красная бетонная плита +Double Red Concrete Slab=Двойная красная бетонная плита +Yellow Concrete Stairs=Жёлтые бетонные ступени +Yellow Concrete Slab=Жёлтая бетонная плита +Double Yellow Concrete Slab=Двойная жёлтая бетонная плита +Green Concrete Stairs=Зелёные бетонные ступени +Green Concrete Slab=Зелёная бетонная плита +Double Green Concrete Slab=Двойная зелёная бетонная плита +Cyan Concrete Stairs=Бирюзовые бетонные ступени +Cyan Concrete Slab=Бирюзоваябетонная плита +Double Cyan Concrete Slab=Двойная бирюзовая бетонная плита +Blue Concrete Stairs=Синие бетонные ступени +Blue Concrete Slab=Синяя бетонная плита +Double Blue Concrete Slab=Двойная синяя бетонная плита +Magenta Concrete Stairs=Сиреневые бетонные ступени +Magenta Concrete Slab=Сиреневая бетонная плита +Double Magenta Concrete Slab=Двойная сиреневая бетонная плита +Orange Concrete Stairs=Оранжевые бетонные ступени +Orange Concrete Slab=Оранжевая бетонная плита +Double Orange Concrete Slab=Двойная оранжевая бетонная плита +Purple Concrete Stairs=Фиолетовые бетонные ступени +Purple Concrete Slab=Фиолетовая бетонная плита +Double Purple Concrete Slab=Двойная фиолетовая бетонная плита +Brown Concrete Stairs=Коричневые бетонные ступени +Brown Concrete Slab=Коричневая бетонная плита +Double Brown Concrete Slab=Двойная коричневая бетонная плита +Pink Concrete Stairs=Розовые бетонные ступени +Pink Concrete Slab=Розовая бетонная плита +Double Pink Concrete Slab=Двойная розовая бетонная плита +Lime Concrete Stairs=Лаймовые бетонные ступени +Lime Concrete Slab=Лаймовая бетонная плита +Double Lime Concrete Slab=Двойная лаймовая бетонная плита +Light Blue Concrete Stairs=Голубые бетонные ступени +Light Blue Concrete Slab=Голубая бетонная плита +Double Light Blue Concrete Slab=Двойная голубая бетонная плита +Concrete Slab=Бетонная плита +Double Concrete Slab=Двойная бетонная плита +Concrete Stairs=Бетонные ступени diff --git a/mods/ITEMS/screwdriver/API.md b/mods/ITEMS/screwdriver/API.md index 0c17ee683..c5371cf01 100644 --- a/mods/ITEMS/screwdriver/API.md +++ b/mods/ITEMS/screwdriver/API.md @@ -17,11 +17,11 @@ To use it, add the `on_rotate` function to the node definition. it but to indicate that changed have already been made (so the screwdriver will wear out) * use `on_rotate = false` to always disallow rotation * use `on_rotate = screwdriver.rotate_simple` to allow only face rotation - * use `on_rotate = screwdriver.rotate_3way` (MineClone 2 extension) for pillar-like nodes that should only have 3 possible orientations) + * use `on_rotate = screwdriver.rotate_3way` (VoxeLibre extension) for pillar-like nodes that should only have 3 possible orientations) -`after_rotate(pos)` (MineClone 2 extension) +`after_rotate(pos)` (VoxeLibre extension) Called after the rotation has been completed diff --git a/mods/ITEMS/screwdriver/README.md b/mods/ITEMS/screwdriver/README.md index 7237c8471..0e315ba1f 100644 --- a/mods/ITEMS/screwdriver/README.md +++ b/mods/ITEMS/screwdriver/README.md @@ -1,4 +1,4 @@ -MineClone 2 mod: screwdriver +VoxeLibre mod: screwdriver ============================ See license.txt for license information. diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.pt_BR.tr b/mods/ITEMS/screwdriver/locale/screwdriver.pt_BR.tr new file mode 100644 index 000000000..feb7ac77b --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain: screwdriver +Screwdriver=Chave de Fenda diff --git a/mods/ITEMS/vl_hollow_logs/API.md b/mods/ITEMS/vl_hollow_logs/API.md new file mode 100644 index 000000000..58055515a --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/API.md @@ -0,0 +1,28 @@ +# ```vl_hollow_logs``` + +This mod registers hollow logs derived from normal logs. +Hollow logs mostly have a decorative function, but some of them can be used in recipes. Changes may appear soon. + +## Functions: +### ```vl_hollow_logs.register_hollow_log(defs)``` +This is the function that registers the hollow trunk. +For a hollow log to be registered, the defs parameter must be a table that contains up to 5 values, which are, in this order, the itemstring of the hollow log, the itemstring of the stripped hollow log, the description of the hollow log, the description of the stripped hollow log and, optionally, a boolean to inform whether this trunk is NOT flammable. If the hollow log is defined as flammable, it becomes part of the hollow_log_flammable group, which allows the log to be used as fuel for furnaces and also allows it to be an ingredient for chacoal. + +Examples: +```lua +-- Flammable +{"tree", "stripped_oak", "Hollow Oak Log", "Stripped Hollow Oak Log"} + +-- Not flammable +{"crimson_hyphae", "stripped_crimson_hyphae", "Hollow Crimson Stem", "Stripped Hollow Crimson Stem", true} +``` +### ```vl_hollow_logs.register_craft(material, result)``` + +This function records the crafting recipe for a hollow log based on its non-hollow variant. +This function also defines a recipe for the stonecutter. The material and result parameters must be, respectively, the complete itemstring of the source material and the (partial) itemstring of the result. See the following examples: + +```lua +vl_hollow_logs.register_craft("mcl_core:tree", "tree") + +vl_hollow_logs.register_craft("mcl_crimson:stripped_crimson_hyphae", "stripped_crimson_hyphae") +``` diff --git a/mods/ITEMS/vl_hollow_logs/init.lua b/mods/ITEMS/vl_hollow_logs/init.lua new file mode 100644 index 000000000..5d2ff4151 --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/init.lua @@ -0,0 +1,112 @@ +local modpath = minetest.get_modpath(minetest.get_current_modname()) +local S = minetest.get_translator(minetest.get_current_modname()) + +vl_hollow_logs = {} +--- Function to register a hollow log. See API.md to learn how to use this function. +---@param defs table {name:string, stripped_name>string, desc:string, stripped_desc:string, not_flammable:boolean|nil} +function vl_hollow_logs.register_hollow_log(defs) + if not defs or #defs < 4 then + error("Incomplete definition provided") + end + + for i = 1, 4 do + if type(defs[i]) ~= "string" then + error("defs["..i.."] must be a string") + end + end + if defs[5] and type(defs[5]) ~= "boolean" then + error("defs[5] must be a boolean if present") + end + + local modname = minetest.get_current_modname() + + if #defs > 5 then + minetest.log("warning", "[vl_hollow_logs] unused vars passed, dumping the table") + minetest.log("warning", "from mod " .. modname .. ": " .. dump(defs)) + end + + local name = defs[1] + local stripped_name = defs[2] + local desc = defs[3] + local stripped_desc = defs[4] + + local collisionbox = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, -0.375}, + {-0.5, -0.5, -0.5, -0.375, 0.5, 0.5}, + {0.375, -0.5, -0.5, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0.375, 0.5, 0.5, 0.5}, + } + } + + local groups = {axey = 1, building_block = 1, handy = 1, hollow_log = 1} + + if not defs[5] then + table.update(groups, {fire_encouragement = 5, fire_flammability = 5, flammable = 2, hollow_log_burnable = 1}) + end + + minetest.register_node(modname .. ":"..name.."_hollow", { + collision_box = collisionbox, + description = S(desc), + drawtype = "mesh", + groups = groups, + mesh = "vl_hollow_logs_log.obj", + on_place = mcl_util.rotate_axis, + paramtype = "light", + paramtype2 = "facedir", + use_texture_alpha = "clip", + sounds = mcl_sounds.node_sound_wood_defaults(), + sunlight_propagates = true, + tiles = {modname .. "_"..name..".png"}, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = modname .. ":stripped_"..name.."_hollow" + }) + + minetest.register_node(modname .. ":"..stripped_name.."_hollow", { + collision_box = collisionbox, + description = S(stripped_desc), + drawtype = "mesh", + groups = groups, + mesh = "vl_hollow_logs_log.obj", + on_place = mcl_util.rotate_axis, + paramtype = "light", + paramtype2 = "facedir", + use_texture_alpha = "clip", + sounds = mcl_sounds.node_sound_wood_defaults(), + sunlight_propagates = true, + tiles = {modname .. "_stripped_"..name..".png"}, + _mcl_blast_resistance = 2, + _mcl_hardness = 2 + }) +end + +vl_hollow_logs.logs = { + {"acaciatree", "stripped_acacia", "Hollow Acacia Log", "Stripped Hollow Acacia Log"}, + {"birchtree", "stripped_birch", "Hollow Birch Log", "Stripped Hollow Birch Log"}, + {"darktree", "stripped_dark_oak", "Hollow Dark Oak Log", "Stripped Hollow Dark Oak Log"}, + {"jungletree", "stripped_jungle", "Hollow Jungle Log", "Stripped Hollow Jungle Log"}, + {"sprucetree", "stripped_spruce", "Hollow Spruce Log", "Stripped Hollow Spruce Log"}, + {"tree", "stripped_oak", "Hollow Oak Log", "Stripped Hollow Oak Log"} +} + + +if minetest.get_modpath("mcl_cherry_blossom") then + table.insert(vl_hollow_logs.logs, {"cherrytree", "stripped_cherrytree", "Hollow Cherry Log", "Stripped Hollow Cherry Log"}) +end + +if minetest.get_modpath("mcl_mangrove") then + table.insert(vl_hollow_logs.logs, {"mangrove_tree", "mangrove_stripped", "Hollow Mangrove Log", "Stripped Hollow Mangrove Log"}) +end + +if minetest.get_modpath("mcl_crimson") then + table.insert(vl_hollow_logs.logs, {"crimson_hyphae", "stripped_crimson_hyphae", "Hollow Crimson Stem", "Stripped Hollow Crimson Stem", true}) + table.insert(vl_hollow_logs.logs, {"warped_hyphae", "stripped_warped_hyphae", "Hollow Warped Stem", "Stripped Hollow Warped Stem", true}) +end + +for _, defs in pairs(vl_hollow_logs.logs) do + vl_hollow_logs.register_hollow_log(defs) +end + +dofile(modpath.."/recipes.lua") diff --git a/mods/ITEMS/vl_hollow_logs/locale/template.txt b/mods/ITEMS/vl_hollow_logs/locale/template.txt new file mode 100644 index 000000000..a8498e23d --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/locale/template.txt @@ -0,0 +1,21 @@ +# textdomain: mcl_hollow_logs +Hollow Acacia Log= +Hollow Birch Log= +Hollow Cherry Log= +Hollow Dark Oak Log= +Hollow Jungle Log= +Hollow Mangrove Log= +Hollow Oak Log= +Hollow Spruce Log= +Hollow Crimson Stem= +Hollow Warped Stem= +Stripped Hollow Acacia Log= +Stripped Hollow Birch Log= +Stripped Hollow Cherry Log= +Stripped Hollow Dark Oak Log= +Stripped Hollow Jungle Log= +Stripped Hollow Mangrove Log= +Stripped Hollow Oak Log= +Stripped Hollow Spruce Log= +Stripped Hollow Crimson Stem= +Stripped Hollow Warped Stem= diff --git a/mods/ITEMS/vl_hollow_logs/locale/vl_hollow_logs.pt_BR.tr b/mods/ITEMS/vl_hollow_logs/locale/vl_hollow_logs.pt_BR.tr new file mode 100644 index 000000000..171a5a613 --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/locale/vl_hollow_logs.pt_BR.tr @@ -0,0 +1,21 @@ +# textdomain: mcl_hollow_logs +Hollow Acacia Log=Tronco Oco de Acácia +Hollow Birch Log=Tronco Oco de Bétula +Hollow Cherry Log=Tronco Oco de Cerejeira +Hollow Dark Oak Log=Tronco Oco de Carvalho Escuro +Hollow Jungle Log=Tronco Oco da Selva +Hollow Mangrove Log=Tronco Oco de Mangue +Hollow Oak Log=Tronco Oco de Carvalho +Hollow Spruce Log=Tronco Oco de Pinheiro +Hollow Crimson Stem=Caule Oco Carmesim +Hollow Warped Stem=Caule Oco Distorcido +Stripped Hollow Acacia Log=Tronco Oco Descascado de Acácia +Stripped Hollow Birch Log=Tronco Oco Descascado de Bétula +Stripped Hollow Cherry Log=Tronco Oco Descascado de Cerejeira +Stripped Hollow Dark Oak Log=Tronco Oco Descascado de Carvalho Escuro +Stripped Hollow Jungle Log=Tronco Oco Descascado da Selva +Stripped Hollow Mangrove Log=Tronco Oco Descascado de Mangue +Stripped Hollow Oak Log=Tronco Oco Descascado de Carvalho +Stripped Hollow Spruce Log=Tronco Oco Descascado de Pinheiro +Stripped Hollow Crimson Stem=Caule Oco Descascado Carmesim +Stripped Hollow Warped Stem=Caule Oco Descascado Distorcido diff --git a/mods/ITEMS/vl_hollow_logs/mod.conf b/mods/ITEMS/vl_hollow_logs/mod.conf new file mode 100644 index 000000000..b9fb65754 --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/mod.conf @@ -0,0 +1,4 @@ +name = vl_hollow_logs +depends = mcl_core, mcl_sounds, mcl_util +optional_depends = mcl_cherry_blossom, mcl_crimson, mcl_mangrove +author = JoseDouglas26 diff --git a/mods/ITEMS/vl_hollow_logs/models/vl_hollow_logs_log.obj b/mods/ITEMS/vl_hollow_logs/models/vl_hollow_logs_log.obj new file mode 100644 index 000000000..c254512e3 --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/models/vl_hollow_logs_log.obj @@ -0,0 +1,54 @@ +# Blender 3.6.7 +# www.blender.org +o hollow_log +v -0.312500 -0.500000 0.312500 +v -0.312500 0.500000 0.312500 +v -0.312500 -0.500000 -0.312500 +v -0.312500 0.500000 -0.312500 +v 0.312500 -0.500000 0.312500 +v 0.312500 0.500000 0.312500 +v 0.312500 -0.500000 -0.312500 +v 0.312500 0.500000 -0.312500 +v -0.500000 -0.500000 -0.500000 +v -0.500000 -0.500000 0.500000 +v -0.500000 0.500000 0.500000 +v -0.500000 0.500000 -0.500000 +v 0.500000 -0.500000 -0.500000 +v 0.500000 0.500000 -0.500000 +v 0.500000 -0.500000 0.500000 +v 0.500000 0.500000 0.500000 +vn -1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vt 0.380952 0.000000 +vt 0.380952 1.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.619048 0.000000 +vt 0.619048 1.000000 +vt 0.928571 0.187500 +vt 0.928571 0.812500 +vt 1.000000 1.000000 +vt 1.000000 -0.000000 +vt 0.690476 0.187500 +vt 0.690476 0.812500 +s 0 +f 10/1/1 11/2/1 12/3/1 9/4/1 +f 9/1/2 12/2/2 14/3/2 13/4/2 +f 13/1/3 14/2/3 16/3/3 15/4/3 +f 15/1/4 16/2/4 11/3/4 10/4/4 +f 7/5/4 8/6/4 4/2/4 3/1/4 +f 5/5/1 6/6/1 8/2/1 7/1/1 +f 3/7/5 1/8/5 10/9/5 9/10/5 +f 2/8/6 4/7/6 12/10/6 11/9/6 +f 7/11/5 3/7/5 9/10/5 13/5/5 +f 4/7/6 8/11/6 14/5/6 12/10/6 +f 5/12/5 7/11/5 13/5/5 15/6/5 +f 8/11/6 6/12/6 16/6/6 14/5/6 +f 1/8/5 5/12/5 15/6/5 10/9/5 +f 6/12/6 2/8/6 11/9/6 16/6/6 +f 3/5/3 4/6/3 2/2/3 1/1/3 +f 1/5/2 2/6/2 6/2/2 5/1/2 diff --git a/mods/ITEMS/vl_hollow_logs/recipes.lua b/mods/ITEMS/vl_hollow_logs/recipes.lua new file mode 100644 index 000000000..0eaa5732f --- /dev/null +++ b/mods/ITEMS/vl_hollow_logs/recipes.lua @@ -0,0 +1,48 @@ +function vl_hollow_logs.register_craft(material, result) + minetest.register_craft({ + output = "vl_hollow_logs:"..result.."_hollow 4", + recipe = { + {"", material, ""}, + {material, "", material}, + {"", material, ""} + }, + type = "shaped" + }) + + mcl_stonecutter.register_recipe(material, "vl_hollow_logs:"..result.."_hollow", 1) +end + +for _, defs in pairs(vl_hollow_logs.logs) do + local mod, material, stripped_material + local name = defs[1] + local stripped_name = defs[2] + + if name:find("cherry") then + mod = "mcl_cherry_blossom:" + elseif name:find("mangrove") then + mod = "mcl_mangrove:" + elseif name:find("hyphae") then + mod = "mcl_crimson:" + else + mod = "mcl_core:" + end + + material = mod..name + stripped_material = mod..stripped_name + + vl_hollow_logs.register_craft(material, name) + vl_hollow_logs.register_craft(stripped_material, stripped_name) +end + +minetest.register_craft({ + burntime = 10, + recipe = "group:hollow_log_burnable", + type = "fuel", +}) + +minetest.register_craft({ + cooktime = 5, + output = "mcl_core:charcoal_lump", + recipe = "group:hollow_log_burnable", + type = "cooking" +}) diff --git a/mods/ITEMS/xpanes/locale/xpanes.ru.tr b/mods/ITEMS/xpanes/locale/xpanes.ru.tr index 47702516d..0102c73df 100644 --- a/mods/ITEMS/xpanes/locale/xpanes.ru.tr +++ b/mods/ITEMS/xpanes/locale/xpanes.ru.tr @@ -1,23 +1,23 @@ # textdomain: xpanes Glass panes are thin layers of glass which neatly connect to their neighbors as you build them.=Стеклянные панели это тонкие стёкла, которые аккуратно присоединяются к соседним блокам, когда вы устанавливаете их. -Stained glass panes are thin layers of stained glass which neatly connect to their neighbors as you build them. They come in many different colors.=Витражи это тонкие стёкла, которые аккуратно присоединяются к соседним блокам, когда вы устанавливаете их. Они могут быть разных цветов. -Iron Bars=Железные слитки -Iron bars neatly connect to their neighbors as you build them.=Железные слитки аккуратно присоединяются к соседним блокам, когда вы устанавливаете их. +Stained glass panes are thin layers of stained glass which neatly connect to their neighbors as you build them. They come in many different colors.=Окрашенная стеклянная панель это тонкое стёкло, которое аккуратно присоединяется к соседним блокам, когда вы устанавливаете его. Может быть разных цветов. +Iron Bars=Железная решётка +Iron bars neatly connect to their neighbors as you build them.=Железная решётка аккуратно присоединяется к соседним блокам, когда вы устанавливаете её. Glass Pane=Стеклянная панель -Stained Glass Pane=Витраж -Red Stained Glass Pane=Красный витраж -Green Stained Glass Pane=Зелёный витраж -Blue Stained Glass Pane=Синий витраж -Light Blue Stained Glass Pane=Светло-голубой витраж -Black Stained Glass Pane=Чёрный витраж -White Stained Glass Pane=Белый витраж -Yellow Stained Glass Pane=Жёлтый витраж -Brown Stained Glass Pane=Коричневый витраж -Orange Stained Glass Pane=Оранжевый витраж -Pink Stained Glass Pane=Розовый витраж -Grey Stained Glass Pane=Серый витраж -Lime Stained Glass Pane=Зелёный лаймовый витраж -Light Grey Stained Glass Pane=Светло-серый витраж -Magenta Stained Glass Pane=Фиолетовый витраж -Purple Stained Glass Pane=Пурпурный витраж -Cyan Stained Glass Pane=Голубой витраж +Stained Glass Pane=Цветное стекло +Red Stained Glass Pane=Красная стеклянная панель +Green Stained Glass Pane=Зелёная стеклянная панель +Blue Stained Glass Pane=Синяя стеклянная панель +Light Blue Stained Glass Pane=Голубая стеклянная панель +Black Stained Glass Pane=Чёрная стеклянная панель +White Stained Glass Pane=Белая стеклянная панель +Yellow Stained Glass Pane=Жёлтая стеклянная панель +Brown Stained Glass Pane=Коричневая стеклянная панель +Orange Stained Glass Pane=Оранжевая стеклянная панель +Pink Stained Glass Pane=Розовая стеклянная панель +Grey Stained Glass Pane=Серая стеклянная панель +Lime Stained Glass Pane=Лаймовая стеклянная панель +Light Grey Stained Glass Pane=Светло-серая стеклянная панель +Magenta Stained Glass Pane=Сиреневая стеклянная панель +Purple Stained Glass Pane=Фиолетовая стеклянная панель +Cyan Stained Glass Pane=Бирюзовая стеклянная панель \ No newline at end of file diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index d42720d26..b3b825071 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -5186,7 +5186,7 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = "mcl_farming:melon", - biomes = {"Jungle"}, + biomes = {"Jungle", "BambooJungle"}, }) minetest.register_decoration({ deco_type = "simple", @@ -5203,7 +5203,7 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = "mcl_farming:melon", - biomes = {"JungleM"}, + biomes = {"JungleM", "BambooJungleM"}, }) minetest.register_decoration({ deco_type = "simple", @@ -5220,7 +5220,7 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = "mcl_farming:melon", - biomes = {"JungleEdge", "JungleEdgeM"}, + biomes = {"JungleEdge", "JungleEdgeM", "BambooJungleEdge", "BambooJungleEdgeM"}, }) -- Lots of melons in Jungle Edge M @@ -5260,6 +5260,7 @@ local function register_decorations() }, y_min = 1, y_max = mcl_vars.mg_overworld_max, + biomes = {"ExtremeHills", "ExtremeHillsM", "ExtremeHills+", "Taiga", "MegaTaiga", "MegaSpruceTaiga", "Plains", "SunflowerPlains", "Swampland", "MangroveSwamp"}, }) -- Grasses and ferns @@ -5589,7 +5590,7 @@ local function register_decorations() num_spawn_by = 1, }) end - local function register_flower(name, biomes, seed, is_in_flower_forest) + local function register_flower(name, biomes, seed, is_in_flower_forest, custom_rarity_mod) if is_in_flower_forest == nil then is_in_flower_forest = true end @@ -5599,7 +5600,7 @@ local function register_decorations() place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 16, noise_params = { - offset = 0.0008, + offset = 0.0008 + (custom_rarity_mod or 0), scale = 0.006, spread = {x = 100, y = 100, z = 100}, seed = seed, @@ -5651,6 +5652,9 @@ local function register_decorations() register_flower("lily_of_the_valley", nil, 325) register_flower("cornflower", flower_biomes2, 486) + + register_flower("clover", flower_biomes1, 3, false, 0.04) + register_flower("fourleaf_clover", flower_biomes1, 13, false, -0.002) end -- Decorations in non-Overworld dimensions diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index c115c35c3..479052d2c 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -406,13 +406,16 @@ local function dungeons_nodes(minp, maxp, blockseed) local pr = PseudoRandom(blockseed) for a=1, attempts do local dim = dungeonsizes[pr:next(1, #dungeonsizes)] - local x = pr:next(minp.x, maxp.x-dim.x-1) - local y = pr:next(ymin , ymax -dim.y-1) - local z = pr:next(minp.z, maxp.z-dim.z-1) - local p1 = {x=x,y=y,z=z} - local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} - minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) - emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr}) + + if ymin <= ymax - dim.y - 1 then + local x = pr:next(minp.x, maxp.x-dim.x-1) + local y = pr:next(ymin , ymax -dim.y-1) + local z = pr:next(minp.z, maxp.z-dim.z-1) + local p1 = {x=x,y=y,z=z} + local p2 = {x = x+dim.x+1, y = y+dim.y+1, z = z+dim.z+1} + minetest.log("verbose","[mcl_dungeons] size=" ..minetest.pos_to_string(dim) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + emerge_area(p1, p2, ecb_spawn_dungeon, {p1=p1, p2=p2, dim=dim, pr=pr}) + end end end diff --git a/mods/MAPGEN/mcl_end_island/init.lua b/mods/MAPGEN/mcl_end_island/init.lua index 434c3c6ef..46c841beb 100644 --- a/mods/MAPGEN/mcl_end_island/init.lua +++ b/mods/MAPGEN/mcl_end_island/init.lua @@ -34,7 +34,7 @@ end, function(minp,maxp,blockseed) table.shuffle(nn) if nn and #nn > 0 then for i=1,pr:next(1,math.min(5,#nn)) do - minetest.add_entity(vector.offset(nn[i],0,1,0),"mobs_mc:enderman") + minetest.add_entity(vector.offset(nn[i],0,1,0),"mobs_mc:rover") end end end, 15, true) diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index c3eef6a26..dfea4f3ce 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -358,7 +358,7 @@ local function world_structure(vm, data, data2, emin, emax, area, minp, maxp, bl -- [[ THE NETHER: mcl_vars.mg_nether_min mcl_vars.mg_nether_max ]] - -- The Air on the Nether roof, https://git.minetest.land/MineClone2/MineClone2/issues/1186 + -- The Air on the Nether roof, https://git.minetest.land/VoxeLibre/VoxeLibre/issues/1186 lvm_used = set_layers(data, area, c_air , nil, mcl_vars.mg_nether_max +1, mcl_vars.mg_nether_max + 128 , minp, maxp, lvm_used, pr) -- The Void above the Nether below the End: lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_nether_max + 128 +1, mcl_vars.mg_end_min -1, minp, maxp, lvm_used, pr) diff --git a/mods/MAPGEN/mcl_mapgen_core/ores.lua b/mods/MAPGEN/mcl_mapgen_core/ores.lua index 403c0333d..3eeaefef8 100644 --- a/mods/MAPGEN/mcl_mapgen_core/ores.lua +++ b/mods/MAPGEN/mcl_mapgen_core/ores.lua @@ -128,27 +128,6 @@ minetest.register_ore({ }) -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_deepslate:deepslate", - wherein = { "mcl_core:stone" }, - clust_scarcity = 200, - clust_num_ores = 100, - clust_size = 10, - y_min = deepslate_min, - y_max = deepslate_max, - noise_params = { - offset = 0, - scale = 1, - spread = { x = 250, y = 250, z = 250 }, - seed = 12345, - octaves = 3, - persist = 0.6, - lacunarity = 2, - flags = "defaults", - } -}) - minetest.register_ore({ ore_type = "blob", ore = "mcl_deepslate:tuff", @@ -173,6 +152,27 @@ minetest.register_ore({ -- DEEPSLATE if minetest.settings:get_bool("mcl_generate_deepslate", true) then + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_deepslate:deepslate", + wherein = { "mcl_core:stone" }, + clust_scarcity = 200, + clust_num_ores = 100, + clust_size = 10, + y_min = deepslate_min, + y_max = deepslate_max, + noise_params = { + offset = 0, + scale = 1, + spread = { x = 250, y = 250, z = 250 }, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } + }) + minetest.register_ore({ ore_type = "scatter", ore = "mcl_deepslate:infested_deepslate", diff --git a/mods/MAPGEN/mcl_nether_fortresses/init.lua b/mods/MAPGEN/mcl_nether_fortresses/init.lua index b736ff133..84823d106 100644 --- a/mods/MAPGEN/mcl_nether_fortresses/init.lua +++ b/mods/MAPGEN/mcl_nether_fortresses/init.lua @@ -188,6 +188,7 @@ mcl_structures.register_structure("nether_bulwark",{ stacks_max = 1, items = { { itemstring = "mcl_compass:lodestone" }, + { itemstring = "mcl_armor:rib" }, } }} }, diff --git a/mods/MAPGEN/mcl_structures/desert_temple.lua b/mods/MAPGEN/mcl_structures/desert_temple.lua index 75c170ab1..74ae20d37 100644 --- a/mods/MAPGEN/mcl_structures/desert_temple.lua +++ b/mods/MAPGEN/mcl_structures/desert_temple.lua @@ -69,6 +69,7 @@ mcl_structures.register_structure("desert_temple",{ { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5, }, { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + { itemstring = "mcl_armor:dune", weight = 20, amount_min = 2, amount_max = 2}, } }, { diff --git a/mods/MAPGEN/mcl_structures/end_city.lua b/mods/MAPGEN/mcl_structures/end_city.lua index 5f432a0eb..e40f90c21 100644 --- a/mods/MAPGEN/mcl_structures/end_city.lua +++ b/mods/MAPGEN/mcl_structures/end_city.lua @@ -58,6 +58,7 @@ mcl_structures.register_structure("end_shipwreck",{ { itemstring = "mcl_core:diamond", weight = 3, amount_min = 2, amount_max = 7 }, { itemstring = "mcl_mobitems:saddle", weight = 3, }, { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_armor:spire", amount_min = 1, amount_max = 1 }, { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, diff --git a/mods/MAPGEN/mcl_structures/jungle_temple.lua b/mods/MAPGEN/mcl_structures/jungle_temple.lua index 843dec04d..ed7067c6c 100644 --- a/mods/MAPGEN/mcl_structures/jungle_temple.lua +++ b/mods/MAPGEN/mcl_structures/jungle_temple.lua @@ -38,6 +38,7 @@ mcl_structures.register_structure("jungle_temple",{ { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + { itemstring = "mcl_armor:wild", amount_min = 1, amount_max = 1, }, } }} } diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.pt_BR.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.pt_BR.tr new file mode 100644 index 000000000..557cf4c21 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.pt_BR.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_structures +Generate a pre-defined structure near your position.=Gera uma estrutura pré-definida próximo a sua posição. +Structure placed.=Estrutura posicionada. +Village built. WARNING: Villages are experimental and might have bugs.=Aldeia construída. AVISO: Aldeias são experimentais e podem conter bugs. +Error: No structure type given. Please use “/spawnstruct ”.=Erro: Nenhum tipo de estrutura fornecido. Por favor use “/spawnstruct ”. +Error: Unknown structure type. Please use “/spawnstruct ”.=Erro: Tipo desconhecido de estrutura. Por favor use “/spawnstruct ”. +Use /help spawnstruct to see a list of avaiable types.= Use /help spawnstruct para ver uma lista dos tipos disponíveis. diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.ru.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ru.tr index 248de695c..21186c96a 100644 --- a/mods/MAPGEN/mcl_structures/locale/mcl_structures.ru.tr +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ru.tr @@ -1,7 +1,7 @@ # textdomain: mcl_structures -Generate a pre-defined structure near your position.=Генерирует поблизости заранее определённое строение. -Structure placed.=Строение размещено. +Generate a pre-defined structure near your position.=Генерирует поблизости заранее определённую структуру. +Structure placed.=Структура размещена. Village built. WARNING: Villages are experimental and might have bugs.=Деревня построена. ВНИМАНИЕ: Деревни экспериментальны и могут содержать ошибки. -Error: No structure type given. Please use “/spawnstruct ”.=Ошибка: Не задан тип строения. Пожалуйста, используйте “/spawnstruct <тип>”. -Error: Unknown structure type. Please use “/spawnstruct ”.=Ошибка: Неизвестный тип строения. Пожалуйста, используйте “/spawnstruct <тип>”. +Error: No structure type given. Please use “/spawnstruct ”.=Ошибка: Не задан тип структуры. Пожалуйста, используйте “/spawnstruct <тип>”. +Error: Unknown structure type. Please use “/spawnstruct ”.=Ошибка: Неизвестный тип структуы. Пожалуйста, используйте “/spawnstruct <тип>”. Use /help spawnstruct to see a list of avaiable types.=Используйте /help spawnstruct, чтобы увидеть список доступных типов. diff --git a/mods/MAPGEN/mcl_structures/pillager_outpost.lua b/mods/MAPGEN/mcl_structures/pillager_outpost.lua index 53652d4fb..dfee8fae3 100644 --- a/mods/MAPGEN/mcl_structures/pillager_outpost.lua +++ b/mods/MAPGEN/mcl_structures/pillager_outpost.lua @@ -44,6 +44,7 @@ mcl_structures.register_structure("pillager_outpost",{ { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:sentry"}, } }, { diff --git a/mods/MAPGEN/mcl_structures/ruined_portal.lua b/mods/MAPGEN/mcl_structures/ruined_portal.lua index 0f7df6686..ef8c806ca 100644 --- a/mods/MAPGEN/mcl_structures/ruined_portal.lua +++ b/mods/MAPGEN/mcl_structures/ruined_portal.lua @@ -12,7 +12,7 @@ end local def = { place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:grass_block","group:sand","group:grass_block_snow","mcl_core:snow"}, - fill_ratio = 0.01, + fill_ratio = 0.006, flags = "place_center_x, place_center_z, all_floors", solid_ground = true, make_foundation = true, diff --git a/mods/MAPGEN/mcl_structures/shipwrecks.lua b/mods/MAPGEN/mcl_structures/shipwrecks.lua index a9c48e0b5..134b99517 100644 --- a/mods/MAPGEN/mcl_structures/shipwrecks.lua +++ b/mods/MAPGEN/mcl_structures/shipwrecks.lua @@ -166,7 +166,7 @@ mcl_structures.register_structure("shipwreck",{ { itemstring = "mcl_clock:clock", weight = 1, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_compass:compass", weight = 1, amount_min = 1, amount_max = 1 }, { itemstring = "mcl_maps:empty_map", weight = 1, amount_min = 1, amount_max = 1 }, - + { itemstring = "mcl_armor:coast", weight = 20, amount_min = 2, amount_max = 2}, } }, } diff --git a/mods/MAPGEN/mcl_structures/woodland_mansion.lua b/mods/MAPGEN/mcl_structures/woodland_mansion.lua index 5429e4892..15e9167fc 100644 --- a/mods/MAPGEN/mcl_structures/woodland_mansion.lua +++ b/mods/MAPGEN/mcl_structures/woodland_mansion.lua @@ -63,6 +63,7 @@ mcl_structures.register_structure("woodland_cabin",{ { itemstring = "mcl_armor:chestplate_chain", weight = 1, }, { itemstring = "mcl_armor:chestplate_diamond", weight = 1, }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + { itemstring = "mcl_armor:vex", amount_max = 1, }, } }} } diff --git a/mods/MAPGEN/mcl_villages/README.txt b/mods/MAPGEN/mcl_villages/README.txt index b266a131a..4a4927051 100644 --- a/mods/MAPGEN/mcl_villages/README.txt +++ b/mods/MAPGEN/mcl_villages/README.txt @@ -1,6 +1,6 @@ MCL_Villages: ============================ -A fork of Rochambeau's "Settlements" mod converted for use in MineClone2. +A fork of Rochambeau's "Settlements" mod converted for use in VoxeLibre. -------------- Using the mod: @@ -16,7 +16,7 @@ MCL2 Credits: Code forked from: https://github.com/MysticTempest/settlements/tree/mcl_villages Commit: e24b4be ================================================================================ -Basic conversion of Settlements mod for compatibility with MineClone2, plus new schematics: MysticTempest +Basic conversion of Settlements mod for compatibility with VoxeLibre, plus new schematics: MysticTempest Seed-based Village Generation, multi-threading, bugfixes: kay27 @@ -40,6 +40,6 @@ Credits: -------------- This mod is based on "ruins" by BlockMen -Completely new schematics for MineClone2: +Completely new schematics for VoxeLibre: MysticTempest - CC-BY-SA 4.0 diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 0cb0712b5..6662f6bd1 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -128,6 +128,10 @@ if minetest.is_creative_enabled("") then -- build ssettlement on_place = function(itemstack, placer, pointed_thing) if not pointed_thing.under then return end + if not minetest.check_player_privs(placer, "server") then + minetest.chat_send_player(placer:get_player_name(), S("Placement denied. You need the “server” privilege to place villages.")) + return + end local minp = vector.subtract( pointed_thing.under, half_map_chunk_size) local maxp = vector.add( pointed_thing.under, half_map_chunk_size) build_a_settlement(minp, maxp, math.random(0,32767)) diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.de.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.de.tr new file mode 100644 index 000000000..6a8f1f681 --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.de.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=Dorfziegel aus gemeißeltem Stein +mcl_villages build tool=mcl_villages Konstruktionswerkzeug +Placement denied. You need the “server” privilege to place villages.=Platzierung verweigert. Sie benötigen das "server" Privileg, um Dörfer zu platzieren. \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr index b648cd36c..af1d0ab49 100644 --- a/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr @@ -1,3 +1,4 @@ # textdomain: mcl_villages Chiseled Stone Village Bricks=Pierre sculptée du village -mcl_villages build tool=outil de construction de mcl_villages \ No newline at end of file +mcl_villages build tool=outil de construction de mcl_villages +Placement denied. You need the “server” privilege to place villages.=Placement refusé. Vous devez disposer du privilège "server" pour placer des villages. \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr index 4d0e4794f..6a63a577d 100644 --- a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr @@ -1,3 +1,4 @@ # textdomain: mcl_villages Chiseled Stone Village Bricks=模様入り石村レンガ -mcl_villages build tool=mcl_villages 構築ツール \ No newline at end of file +mcl_villages build tool=mcl_villages 構築ツール +Placement denied. You need the “server” privilege to place villages.=配置が拒否されました。村の配置には「server」権限が必要です。 \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.pt_BR.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.pt_BR.tr new file mode 100644 index 000000000..bded6250d --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.pt_BR.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=Tijolos de Aldeia de Pedra Cinzelada +mcl_villages build tool=ferramenta de construção mcl_villages diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr index 467f31121..021bd78f1 100644 --- a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr @@ -1,2 +1,4 @@ # textdomain: mcl_villages -Chiseled Stone Village Bricks=Точёный каменный блок из деревни +Chiseled Stone Village Bricks=Резные деревенские каменные кирпичи +mcl_villages build tool=Инструмент постройки деревни +Placement denied. You need the “server” privilege to place villages.=Размещение запрещено. Для размещения деревень необходима привилегия "server". \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/template.txt b/mods/MAPGEN/mcl_villages/locale/template.txt index 464daea9b..c410f4837 100644 --- a/mods/MAPGEN/mcl_villages/locale/template.txt +++ b/mods/MAPGEN/mcl_villages/locale/template.txt @@ -1,3 +1,4 @@ # textdomain: mcl_villages Chiseled Stone Village Bricks= -mcl_villages build tool= \ No newline at end of file +mcl_villages build tool= +Placement denied. You need the “server” privilege to place villages.= \ No newline at end of file diff --git a/mods/MAPGEN/tsm_railcorridors/README.md b/mods/MAPGEN/tsm_railcorridors/README.md index de9df489e..3b839573c 100644 --- a/mods/MAPGEN/tsm_railcorridors/README.md +++ b/mods/MAPGEN/tsm_railcorridors/README.md @@ -1,5 +1,5 @@ # Railway corridors [`tsm_railcorridors`] -MineClone 2 adaption. NO TREASURER SUPPORT! +VoxeLibre adaption. NO TREASURER SUPPORT! * Current version 0.14.0 diff --git a/mods/MISC/findbiome/locale/findbiome.pt_BR.tr b/mods/MISC/findbiome/locale/findbiome.pt_BR.tr new file mode 100644 index 000000000..5e9e3a6cb --- /dev/null +++ b/mods/MISC/findbiome/locale/findbiome.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: findbiome +Find and teleport to biome=Encontra e teleporta para um bioma += +No player.=Nenhum jogador. +Biome does not exist!=Bioma não existe! +Biome found at @1.=Bioma encontrado em @1. +No biome found!=Nenhum bioma encontrado! +List all biomes=Lista de todos os biomas +No biomes.=Nenhum bioma. +Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Não suportado. O mod "biomeinfo" é necessário para o suporte da mapgen v6! diff --git a/mods/MISC/findbiome/locale/findbiome.ru.tr b/mods/MISC/findbiome/locale/findbiome.ru.tr index c37371820..98f2be522 100644 --- a/mods/MISC/findbiome/locale/findbiome.ru.tr +++ b/mods/MISC/findbiome/locale/findbiome.ru.tr @@ -7,4 +7,4 @@ Biome found at @1.=Биом найден в @1. No biome found!=Биом не найден! List all biomes=Список всех биомов No biomes.=Нет биомов. -Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Не поддерживается. Для поддержки мэпгена v6 требуется мод “biomeinfo”! +Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Не поддерживается. Для поддержки мапгена v6 требуется мод “biomeinfo”! diff --git a/mods/MISC/mcl_commands/alias.lua b/mods/MISC/mcl_commands/alias.lua index 5c9ee9f3c..2c700408b 100644 --- a/mods/MISC/mcl_commands/alias.lua +++ b/mods/MISC/mcl_commands/alias.lua @@ -18,7 +18,7 @@ if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then register_chatcommand_alias("tell", "msg") register_chatcommand_alias("w", "msg") register_chatcommand_alias("tp", "teleport") - rename_chatcommand("clear", "clearinv") + register_chatcommand_alias("clearinventory", "clearinv") minetest.register_chatcommand("banlist", { 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()) end, }) -end \ No newline at end of file + + 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 diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.pt_BR.tr b/mods/MISC/mcl_commands/locale/mcl_commands.pt_BR.tr new file mode 100644 index 000000000..5a2688d67 --- /dev/null +++ b/mods/MISC/mcl_commands/locale/mcl_commands.pt_BR.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_commands +Players can't be killed right now, damage has been disabled.=Jogadores não podem ser mortos agora, dano foi desabilitado. +Player @1 does not exist.=Jogador @1 não existe. +You are already dead=Você já está morto +@1 is already dead=@1 já está morto +@1 committed suicide.=@1 cometeu suícidio. +@1 was killed by @2.=@1 foi morto(a) por @2. +[]=[] +Kill player or yourself=Mata jogadores ou você mesmo +Can use /say=Pode usar /say += +Send a message to every player=Envia uma mensagem para todos os jogadores +Invalid usage, see /help say.=Uso inválido, veja /help say. +,, = ,, +Set node at given position=Define um node na posição dada +Invalid node=Node inválido +@1 spawned.=@1 nasceu. +Invalid parameters (see /help setblock)=Parâmetros inválidos (veja /help setblock) +List bans=Lista banimentos +Ban list: @1=Lista de banimento: @1 +Show who is logged on=Mostra quem está logado +Displays the world seed=Mostra a semente do mundo +Only peaceful mobs allowed!=Apenas mobs pacíficos permitidos! diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr b/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr index 77ff7d4f9..09cd4a049 100644 --- a/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr +++ b/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr @@ -1,6 +1,6 @@ # textdomain: mcl_commands Players can't be killed right now, damage has been disabled.=Игроки не могут быть убиты прямо сейчас, урон отключён. -Player @1 does not exist.=Игрок @1 не существует. +Player @1 does not exist.=Игрока @1 не существует. You are already dead=Вы уже мертвы @1 is already dead=@1 уже мертв(а) @1 committed suicide.=@1 совершил(а) самоубийство. @@ -17,7 +17,7 @@ Invalid node=Неправильный блок @1 spawned.=@1 возродился(ась). Invalid parameters (see /help setblock)=Недопустимые параметры (см. /help setblock) List bans=Список банов -Ban list: @1=Бан-лист: @1 -Show who is logged on=Показывает, кто подключён -Displays the world seed=Показывает значение зерна мира +Ban list: @1=Список банов: @1 +Show who is logged on=Показывает игроков в сети +Displays the world seed=Показать значение зерна мира Only peaceful mobs allowed!=Разрешены только мирные сущности! diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.pt_BR.tr b/mods/MISC/mcl_privs/locale/mcl_privs.pt_BR.tr new file mode 100644 index 000000000..fe57673f4 --- /dev/null +++ b/mods/MISC/mcl_privs/locale/mcl_privs.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_privs +Can place and use advanced blocks like mob spawners, command blocks and barriers.=Pode posicionar e usar blocos avançados como geradores de mobs, blocos de comandos e barreiras. diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr b/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr index 678ebf4e0..6e301d3dc 100644 --- a/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr +++ b/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr @@ -1,2 +1,2 @@ # textdomain: mcl_privs -Can place and use advanced blocks like mob spawners, command blocks and barriers.=Позволяет размещать и использовать продвинутые блоки, такие как порождатели существ, блоки команд и барьеры. \ No newline at end of file +Can place and use advanced blocks like mob spawners, command blocks and barriers.=Позволяет размещать и использовать продвинутые блоки, такие как спаунеры мобов, командные блоки и барьеры. \ No newline at end of file diff --git a/mods/MISC/mcl_wip/locale/mcl_wip.pt_BR.tr b/mods/MISC/mcl_wip/locale/mcl_wip.pt_BR.tr new file mode 100644 index 000000000..9a30f5466 --- /dev/null +++ b/mods/MISC/mcl_wip/locale/mcl_wip.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_wip +# WIP means “Work in Progress” +(WIP)=(Trabalho em progresso) +(Temporary)=(Temporário) diff --git a/mods/PLAYER/mcl_criticals/init.lua b/mods/PLAYER/mcl_criticals/init.lua index 27d09abb2..d30647004 100644 --- a/mods/PLAYER/mcl_criticals/init.lua +++ b/mods/PLAYER/mcl_criticals/init.lua @@ -23,8 +23,32 @@ mcl_damage.register_modifier(function(obj, damage, reason) texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", }) minetest.sound_play("mcl_criticals_hit", {object = obj}) - -- the minecraft wiki is actually wrong about a crit dealing 150% damage, see minecraft source code - return damage + math.random(0, math.floor(damage * 1.5 + 2)) + local crit_mod + local CRIT_MIN = 1.5 + local CRIT_DIFF = 1 + if hitter:is_player() then + local luck = mcl_luck.get_luck(hitter:get_player_name()) + if luck ~= 0 then + local a, d + if luck > 0 then + d = -0.5 + a = d - math.abs(luck) + elseif luck < 0 then + a = -0.5 + d = a - math.abs(luck) + else + minetest.log("warning", "[mcl_criticals] luck is not a number") -- this technically can't happen, but want to catch such cases + end + if a then + local x = math.random() + crit_mod = CRIT_DIFF * (a * x) / (d - luck * x) + CRIT_MIN + end + end + end + if not crit_mod then + crit_mod = math.random(CRIT_MIN, CRIT_MIN + CRIT_DIFF) + end + return damage * crit_mod end end end, -100) diff --git a/mods/PLAYER/mcl_criticals/mod.conf b/mods/PLAYER/mcl_criticals/mod.conf index 5b0b91330..0ae588aa6 100644 --- a/mods/PLAYER/mcl_criticals/mod.conf +++ b/mods/PLAYER/mcl_criticals/mod.conf @@ -1,2 +1,2 @@ name = mcl_criticals -depends = mcl_damage +depends = mcl_damage, mcl_luck diff --git a/mods/PLAYER/mcl_fovapi/api.md b/mods/PLAYER/mcl_fovapi/api.md new file mode 100644 index 000000000..d4a9cb1fb --- /dev/null +++ b/mods/PLAYER/mcl_fovapi/api.md @@ -0,0 +1,82 @@ +### FOV API + + +* [FOV API](#fov-api) + * [Description](#description) + * [Troubleshooting](#troubleshooting) + * [Modifier Definition](#modifier-definition-) + * [Global MCL_FOVAPI Tables](#global-mclfovapi-tables) + * [Namespaces](#namespaces) + * [Functions](#functions) + + +#### Description +This API defines and applies different Field Of View effects to players via MODIFIERS. + +#### Troubleshooting +In the `init.lua` file for this module, there is a `DEBUG` variable at the top that will turn on logging. +Use it to see what is going on. + +#### Modifier Definition +```lua +def = { + name = name, + fov_factor = fov_factor, + time = time, + reset_time = reset_time, + is_multiplier = is_multiplier, + exclusive = exclusive, + on_start = on_start, + on_end = on_end, +} +``` +* Name: The name of the Modifier, used to identify the specific modifier. Case sensitive. +* FOV Factor: A float value defining the FOV to apply. Can be an absolute or percentage, depending on Exclusive and + Is_Multiplier. +* Time: A float value defining the number of seconds to take when applying the FOV Factor. + Used to smoothly move between FOVs. Use 0 for an immediate FOV Shift. (Transition time.) +* Reset Time: A float value defining the number of seconds to take when removing the FOV Factor. + Used to smoothly move between FOVs. Use 0 for an immediate FOV Shift. (Reset transition time.) + Defaults to `time` if not defined. +* Is Multiplier: A bool value used to specify if the FOV Factor is an absolute FOV value or if it should be a percentage + of the current FOV. Defaults to `true` if not defined. +* Exclusive: A bool value used to specify whether the modifier will override all other FOV modifiers. An example of this + is how the spy glass sets the FOV to be a specific value regardless of any other FOV effects applied. Defaults to + `false` if not defined. +* On Start: the `on_start` is a callback function `on_start(player)` that is called if defined. The parameter `player` + is a ref to the player that had the modifier applied. Called from `mcl_fovapi.apply_modifier` immediately after + the FOV Modifier has been applied. +* On End: the `on_end` is a callback function `on_end(player)` that is called if defined. The parameter `player` + is a ref to the player that had the modifier applied. Called from `mcl_fovapi.remove_modifier` immediately after + the FOV Modifier has been removed. + +Note: passing incorrect values in the definition will have unintended consequences. + +#### Global MCL_FOVAPI Tables +There are three tables that are accessible via the API. They are `registered_modifiers` and `applied_modifiers`. + +`mcl_fovapi.registered_modifiers` has the definitions of all the registered FOV Modifiers. Indexed by Modifier Name. +And, `mcl_fovapi.applied_modifiers` is indexed by the Player Name. It contains the names of all the modifiers applied to the +player. + +#### Namespaces +`mcl_fovapi` is the default API Namespace. + +#### Functions +`mcl_fovapi.register_modifier(def)` + +Used to register a new FOV Modifier for use. Must be called before applying said modifier to a player. +See Modifier Definition for what the parameters are. + +`mcl_fovapi.apply_modifier(player, modifier_name)` + +Used to apply a registered FOV modifier to a player. Takes a reference to the player and the modifier's name (string). + +`mcl_fovapi.remove_modifier(player, modifier_name)` + +Used to remove a specific FOV modifier from a Player. Takes a reference to the player and the modifier's name (string). +Removed immediately. + +`mcl_fovapi.remove_all_modifiers(player)` + +Used to remove all FOV modifiers from a Player. Takes a reference to the Player. FOV change is instantaneous. diff --git a/mods/PLAYER/mcl_fovapi/init.lua b/mods/PLAYER/mcl_fovapi/init.lua new file mode 100644 index 000000000..43dcfe403 --- /dev/null +++ b/mods/PLAYER/mcl_fovapi/init.lua @@ -0,0 +1,234 @@ +--- +--- Copyright 2023, Michieal. +--- License: GPL3. (Default Mineclone2 License) +--- Created by michieal. +--- DateTime: 12/2/23 5:47 AM +--- + +-- Locals (and cached) +local DEBUG = false -- debug constant for troubleshooting. +local pairs = pairs + +-- Globals +mcl_fovapi = {} + +mcl_fovapi.registered_modifiers = {} +mcl_fovapi.applied_modifiers = {} + +minetest.register_on_joinplayer(function(player) + local player_name = player:get_player_name() + + -- initialization + mcl_fovapi.applied_modifiers[player_name] = {} +end) +minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + + -- handle clean up + mcl_fovapi.applied_modifiers[player_name] = nil +end) + +function mcl_fovapi.register_modifier(def) + if type(def.name) ~= "string" then + error("Modifier name must be a string") + end + if type(def.fov_factor) ~= "number" then + error("FOV factor must be a number") + end + if type(def.time) ~= "number" then + error("Transition time must be a number") + end + if def.reset_time ~= nil and type(def.reset_time) ~= "number" then + error("Reset time, if provided, must be a number") + end + + if def.on_start ~= nil and type(def.on_start) ~= "function" then + error("Callback on_start must be a function") + end + if def.on_end ~= nil and type(def.on_end) ~= "function" then + error("Callback on_end must be a function") + end + + local mdef = {} + + mdef.fov_factor = def.fov_factor + mdef.time = def.time + mdef.reset_time = def.reset_time or def.time + + if def.is_multiplier == false then mdef.is_multiplier = false + else mdef.is_multiplier = true end + if def.exclusive == true then mdef.exclusive = true + else mdef.exclusive = false end + + mdef.on_start = def.on_start + mdef.on_end = def.on_end + + if DEBUG then + minetest.log("FOV::Modifier Definition Registered:\n" .. dump(def)) + end + + mcl_fovapi.registered_modifiers[def.name] = mdef + +end + +minetest.register_on_respawnplayer(function(player) + mcl_fovapi.remove_all_modifiers(player) +end) + +function mcl_fovapi.apply_modifier(player, modifier_name, time_override) + if not player or not modifier_name then + return + end + if mcl_fovapi.registered_modifiers[modifier_name] == nil then + return + end + local player_name = player:get_player_name() + if mcl_fovapi.applied_modifiers and mcl_fovapi.applied_modifiers[player_name] and mcl_fovapi.applied_modifiers[player_name][modifier_name] then + return + end + + for k, _ in pairs(mcl_fovapi.applied_modifiers[player_name]) do + if mcl_fovapi.registered_modifiers[k].exclusive == true then return end + end + + local modifier = mcl_fovapi.registered_modifiers[modifier_name] + if modifier.on_start then + modifier.on_start(player) + end + + mcl_fovapi.applied_modifiers[player_name][modifier_name] = true -- set the applied to be true. + + if DEBUG then + minetest.log("FOV::Player Applied Modifiers :" .. dump(mcl_fovapi.applied_modifiers[player_name])) + end + + if DEBUG then + minetest.log("FOV::Modifier applied to player:" .. player_name .. " modifier: " .. modifier_name) + end + + local time = time_override or modifier.time + -- modifier apply code. + if modifier.exclusive == true then + -- if exclusive, reset the player's fov, and apply the new fov. + if modifier.is_multiplier then + player:set_fov(0, false, 0) + end + player:set_fov(modifier.fov_factor, modifier.is_multiplier, time) + else + -- not exclusive? let's apply it in the mix. + local fov_factor, is_mult = player:get_fov() + if fov_factor == 0 then + fov_factor = 1 + is_mult = true + end + if modifier.is_multiplier or is_mult then + fov_factor = fov_factor * modifier.fov_factor + else + fov_factor = (fov_factor + modifier.fov_factor) / 2 + end + if modifier.is_multiplier and is_mult then + player:set_fov(fov_factor, true, time) + else + player:set_fov(fov_factor, false, time) + end + end + +end + +function mcl_fovapi.remove_modifier(player, modifier_name, time_override) + if not player or not modifier_name then + return + end + + local player_name = player:get_player_name() + if not mcl_fovapi.applied_modifiers[player_name] + or not mcl_fovapi.applied_modifiers[player_name][modifier_name] then + return + end + + if DEBUG then + minetest.log("FOV::Player: " .. player_name .. " modifier: " .. modifier_name .. "removed.") + end + + mcl_fovapi.applied_modifiers[player_name][modifier_name] = nil + local modifier = mcl_fovapi.registered_modifiers[modifier_name] + + -- check for other fov modifiers, and set them up, or reset to default. + + local applied = {} + for k, _ in pairs(mcl_fovapi.applied_modifiers[player_name]) do + applied[k] = mcl_fovapi.registered_modifiers[k] + end + + local time = time_override or modifier.reset_time + local elem = next + if elem(applied) == nil then + player:set_fov(0, false, time) + return + end + local exc = false + for k, _ in pairs(applied) do + if applied[k].exclusive == true then + exc = applied[k] + break + end + end + + -- handle exclusives. + if exc ~= false then + player:set_fov(exc.fov_factor, exc.is_multiplier, 0) -- we want this to be immediate. + else + -- handle normal fov modifiers. + local fov_factor = 1 + local non_multiplier_added = false + for _, x in pairs(applied) do + if not x.is_multiplier then + if non_multiplier_added then + fov_factor = (fov_factor + x.fov_factor) / 2 + else + non_multiplier_added = true + fov_factor = fov_factor * x.fov_factor + end + else + fov_factor = fov_factor * x.fov_factor + end + end + player:set_fov(fov_factor, not non_multiplier_added, time) + end + + if mcl_fovapi.registered_modifiers[modifier_name].on_end then + mcl_fovapi.registered_modifiers[modifier_name].on_end(player) + end +end + +function mcl_fovapi.remove_all_modifiers(player) + if not player then + return + end + + local player_name = player:get_player_name() + if DEBUG then + minetest.log("FOV::Player: " .. player_name .. " modifiers have been reset.") + end + + for name, x in pairs(mcl_fovapi.applied_modifiers[player_name]) do + x = nil + if mcl_fovapi.registered_modifiers[name].on_end then + mcl_fovapi.registered_modifiers[name].on_end(player) + end + end + + player:set_fov(0, false, 0) +end + +--[[ +Notes: +set_fov(fov, is_multiplier, transition_time): Sets player's FOV + + fov: FOV value. + is_multiplier: Set to true if the FOV value is a multiplier. Defaults to false. + transition_time: If defined, enables smooth FOV transition. Interpreted as the time (in seconds) to reach target FOV. + If set to 0, FOV change is instantaneous. Defaults to 0. + Set fov to 0 to clear FOV override. + +--]] diff --git a/mods/PLAYER/mcl_fovapi/mod.conf b/mods/PLAYER/mcl_fovapi/mod.conf new file mode 100644 index 000000000..3aff902a1 --- /dev/null +++ b/mods/PLAYER/mcl_fovapi/mod.conf @@ -0,0 +1,3 @@ +name = mcl_fovapi +author = Michieal, Herowl +description = An API for handling FOV changes. diff --git a/mods/PLAYER/mcl_gamemode/API.md b/mods/PLAYER/mcl_gamemode/API.md new file mode 100644 index 000000000..24651301e --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/API.md @@ -0,0 +1,27 @@ +# `mcl_gamemode` + +## `mcl_gamemode.gamemodes` + +List of availlable gamemodes. + +Currently `{"survival", "creative"}` + +## `mcl_gamemode.get_gamemode(player)` + +Get the player's gamemode. + +Returns "survival" or "creative". + +## `mcl_gamemode.set_gamemode(player, gamemode)` + +Set the player's gamemode. + +gamemode: "survival" or "creative" + +## `mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode))` + +Register a function that will be called when `mcl_gamemode.set_gamemode` is called. + +## `mcl_gamemode.registered_on_gamemode_change` + +Map of registered on_gamemode_change. diff --git a/mods/PLAYER/mcl_gamemode/init.lua b/mods/PLAYER/mcl_gamemode/init.lua new file mode 100644 index 000000000..a43a9c1ff --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/init.lua @@ -0,0 +1,84 @@ +local S = minetest.get_translator("mcl_gamemode") + +mcl_gamemode = {} + +mcl_gamemode.gamemodes = { + "survival", + "creative", +} + +---@param n any +---@param h table +---@return boolean +local function in_table(n, h) + for k, v in pairs(h) do + if v == n then return true end + end + return false +end + +---@type fun(player: mt.PlayerObjectRef, old_gamemode: '"survival"'|'"creative"', new_gamemode: '"survival"'|'"creative"')[] +mcl_gamemode.registered_on_gamemode_change = {} + +---@param func fun(player: mt.PlayerObjectRef, old_gamemode: '"survival"'|'"creative"', new_gamemode: '"survival"'|'"creative"') +function mcl_gamemode.register_on_gamemode_change(func) + table.insert(mcl_gamemode.registered_on_gamemode_change, func) +end + +---@param player mt.PlayerObjectRef +---@param gamemode '"survival"'|'"creative"' +function mcl_gamemode.set_gamemode(player, gamemode) + local meta = player:get_meta() + local old_gamemode = meta:get_string("gamemode") + meta:set_string("gamemode", gamemode) + for _, f in ipairs(mcl_gamemode.registered_on_gamemode_change) do + f(player, old_gamemode, gamemode) + end +end + +local mt_is_creative_enabled = minetest.is_creative_enabled + +---@param player mt.PlayerObjectRef +---@return '"survival"'|'"creative"' +function mcl_gamemode.get_gamemode(player) + if mt_is_creative_enabled(player:get_player_name()) then + return "creative" + end + return player:get_meta():get_string("gamemode") +end + +function minetest.is_creative_enabled(name) + if mt_is_creative_enabled(name) then return true end + if not name then return false end + local p = minetest.get_player_by_name(name) + if p then + return p:get_meta():get_string("gamemode") == "creative" + end + return false +end + +minetest.register_chatcommand("gamemode", { + params = S("[] []"), + description = S("Change gamemode (survival/creative) for yourself or player"), + privs = { server = true }, + func = function(n, param) + -- Full input validation ( just for @erlehmann <3 ) + local p = minetest.get_player_by_name(n) + local args = param:split(" ") + if args[2] ~= nil then + p = minetest.get_player_by_name(args[2]) + end + if not p then + return false, S("Player not online") + end + if args[1] ~= nil and not in_table(args[1], mcl_gamemode.gamemodes) then + return false, S("Gamemode " .. args[1] .. " does not exist.") + elseif args[1] ~= nil then + mcl_gamemode.set_gamemode(p, args[1]) + end + --Result message - show effective game mode + local gm = p:get_meta():get_string("gamemode") + if gm == "" then gm = mcl_gamemode.gamemodes[1] end + return true, S("Gamemode for player ") .. n .. S(": " .. gm) + end +}) diff --git a/mods/PLAYER/mcl_gamemode/mod.conf b/mods/PLAYER/mcl_gamemode/mod.conf new file mode 100644 index 000000000..03eade707 --- /dev/null +++ b/mods/PLAYER/mcl_gamemode/mod.conf @@ -0,0 +1 @@ +name = mcl_gamemode \ No newline at end of file diff --git a/mods/PLAYER/mcl_hunger/API.md b/mods/PLAYER/mcl_hunger/API.md index 57d158c48..85f2dc580 100644 --- a/mods/PLAYER/mcl_hunger/API.md +++ b/mods/PLAYER/mcl_hunger/API.md @@ -3,7 +3,7 @@ This API information is not complete yet. The mod API is still pretty much unofficial; this mod is mostly seen as standalone for now. -This may change in the future development of MineClone 2. Hopefully. +This may change in the future development of VoxeLibre. Hopefully. ## Mod state The hunger mechanic is disabled when damage is disabled diff --git a/mods/PLAYER/mcl_hunger/README.md b/mods/PLAYER/mcl_hunger/README.md index 47a7fce8c..f72b7f0cf 100644 --- a/mods/PLAYER/mcl_hunger/README.md +++ b/mods/PLAYER/mcl_hunger/README.md @@ -1,4 +1,4 @@ -# Hunger for MineClone 2 [`mcl_hunger`] +# Hunger for VoxeLibre [`mcl_hunger`] * Forked from `hbhunger`, version: 0.5.2 @@ -39,7 +39,7 @@ This mod is free software. * License: [LGPL v2.1](https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html) * Author: by Wuzzy (2015-2016) -* Forked from `hbhunger` for MineClone 2. `hbhunger` in turn was forked from the “Better HUD +* Forked from `hbhunger` for VoxeLibre. `hbhunger` in turn was forked from the “Better HUD (and hunger)” mod by BlockMen (2013-2015), most code comes from this mod. ### Textures and sounds diff --git a/mods/PLAYER/mcl_hunger/changelog.txt b/mods/PLAYER/mcl_hunger/changelog.txt index a56dbcb89..8eb370e94 100644 --- a/mods/PLAYER/mcl_hunger/changelog.txt +++ b/mods/PLAYER/mcl_hunger/changelog.txt @@ -49,3 +49,7 @@ Initial release - Fix mod not working with both intllib and mod security enabled - Add missing screenshot - Rewrite README and use Markdown format + +0.6.0 +----- +- Add eating delay diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index d9a6fd5fe..2c29e1939 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -38,7 +38,26 @@ function minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, poi local can_eat_when_full = creative or (mcl_hunger.active == false) or minetest.get_item_group(itemstack:get_name(), "can_eat_when_full") == 1 -- Don't allow eating when player has full hunger bar (some exceptional items apply) - if can_eat_when_full or (mcl_hunger.get_hunger(user) < 20) then + if not no_eat_delay and not mcl_hunger.eat_internal[name].is_eating and not mcl_hunger.eat_internal[name].do_item_eat and (can_eat_when_full or (mcl_hunger.get_hunger(user) < 20)) then + local itemname = itemstack:get_name() + table.update(mcl_hunger.eat_internal[name], { + is_eating = true, + is_eating_no_padding = true, + itemname = itemname, + item_definition = minetest.registered_items[itemname], + hp_change = hp_change, + replace_with_item = replace_with_item, + itemstack = itemstack, + user = user, + pointed_thing = pointed_thing + }) + elseif (mcl_hunger.eat_internal[name].do_item_eat or no_eat_delay) and (can_eat_when_full or (mcl_hunger.get_hunger(user) < 20)) then + if mcl_hunger.eat_internal[name]._custom_itemstack and + mcl_hunger.eat_internal[name]._custom_wrapper and + mcl_hunger.eat_internal[name]._custom_itemstack == itemstack then + + mcl_hunger.eat_internal[name]._custom_wrapper(name) + end itemstack = mcl_hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing) for _, callback in pairs(minetest.registered_on_item_eats) do local result = callback(hp_change, replace_with_item, itemstack, user, pointed_thing, old_itemstack) @@ -47,6 +66,7 @@ function minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, poi end end mcl_hunger.last_eat[name] = os.time() + user:get_inventory():set_stack("main", user:get_wield_index(), itemstack) end end @@ -79,42 +99,6 @@ function mcl_hunger.reset_bars_poison_hunger(player) end end --- Poison player -local function poisonp(tick, time, time_left, damage, exhaustion, name) - if not mcl_hunger.active then - return - end - local player = minetest.get_player_by_name(name) - -- First check if player is still there - if not player then - return - end - -- Abort if food poisonings have been stopped - if mcl_hunger.poison_hunger[name] == 0 then - return - end - time_left = time_left + tick - if time_left < time then - minetest.after(tick, poisonp, tick, time, time_left, damage, exhaustion, name) - else - if exhaustion > 0 then - mcl_hunger.poison_hunger [name] = mcl_hunger.poison_hunger[name] - 1 - end - if mcl_hunger.poison_hunger[name] <= 0 then - mcl_hunger.reset_bars_poison_hunger(player) - end - end - - -- Deal damage and exhaust player - -- TODO: Introduce fatal poison at higher difficulties - if player:get_hp()-damage > 0 then - mcl_util.deal_damage(player, damage, {type = "hunger"}) - end - - mcl_hunger.exhaust(name, exhaustion) - -end - local poisonrandomizer = PseudoRandom(os.time()) function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poison, exhaust, poisonchance, sound) @@ -129,49 +113,9 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso --local hp = user:get_hp() local pos = user:get_pos() - -- player height - pos.y = pos.y + 1.5 - local foodtype = minetest.get_item_group(itemname, "food") - if foodtype == 3 then - -- Item is a drink, only play drinking sound (no particle) - minetest.sound_play("survival_thirst_drink", { - max_hear_distance = 12, - gain = 1.0, - pitch = 1 + math.random(-10, 10)*0.005, - object = user, - }, true) - else - -- Assume the item is a food - -- Add eat particle effect and sound - local def = minetest.registered_items[itemname] - local texture = def.inventory_image - if not texture or texture == "" then - texture = def.wield_image - end - -- Special item definition field: _food_particles - -- If false, force item to not spawn any food partiles when eaten - if def._food_particles ~= false and texture and texture ~= "" then - local v = user:get_velocity() or user:get_player_velocity() - for i = 0, math.min(math.max(8, hunger_change*2), 25) do - minetest.add_particle({ - pos = { x = pos.x, y = pos.y, z = pos.z }, - velocity = vector.add(v, { x = math.random(-1, 1), y = math.random(1, 2), z = math.random(-1, 1) }), - acceleration = { x = 0, y = math.random(-9, -5), z = 0 }, - expirationtime = 1, - size = math.random(1, 2), - collisiondetection = true, - vertical = false, - texture = "[combine:3x3:" .. -i .. "," .. -i .. "=" .. texture, - }) - end - end - minetest.sound_play("mcl_hunger_bite", { - max_hear_distance = 12, - gain = 1.0, - pitch = 1 + math.random(-10, 10)*0.005, - object = user, - }, true) - end + local def = minetest.registered_items[itemname] + + mcl_hunger.eat_effects(user, itemname, pos, hunger_change, def) if mcl_hunger.active and hunger_change then -- Add saturation (must be defined in item table) @@ -206,15 +150,8 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso do_poison = true end if do_poison then - -- Set food poison bars - if exhaust and exhaust > 0 then - hb.change_hudbar(user, "hunger", nil, nil, "mcl_hunger_icon_foodpoison.png", nil, "mcl_hunger_bar_foodpoison.png") - if mcl_hunger.debug then - hb.change_hudbar(user, "exhaustion", nil, nil, nil, nil, "mcl_hunger_bar_foodpoison.png") - end - mcl_hunger.poison_hunger[name] = mcl_hunger.poison_hunger[name] + 1 - end - poisonp(1, poisontime, 0, poison, exhaust, user:get_player_name()) + local level = mcl_potions.get_effect_level(user, "food_poisoning") + mcl_potions.give_effect_by_level("food_poisoning", user, level+exhaust, poisontime) end end @@ -226,6 +163,61 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso end end +function mcl_hunger.eat_effects(user, itemname, pos, hunger_change, item_def, pitch) + if user and itemname and pos and hunger_change and item_def then + local name = user:get_player_name() + if mcl_hunger.eat_internal[name] and mcl_hunger.eat_internal[name].do_item_eat then + pitch = 0.95 + end + local def = item_def + -- player height + pos.y = pos.y + 1.5 + local foodtype = minetest.get_item_group(itemname, "food") + if foodtype == 3 then + -- Item is a drink, only play drinking sound (no particle) + minetest.sound_play("survival_thirst_drink", { + max_hear_distance = 12, + gain = 1.0, + pitch = pitch or 1 + math.random(-10, 10)*0.005, + object = user, + }, true) + else + -- Assume the item is a food + -- Add eat particle effect and sound + --local def = minetest.registered_items[itemname] + local texture = def.inventory_image + if not texture or texture == "" then + texture = def.wield_image + end + -- Special item definition field: _food_particles + -- If false, force item to not spawn any food partiles when eaten + if def._food_particles ~= false and texture and texture ~= "" then + local v = user:get_velocity() or user:get_player_velocity() + for i = 0, math.min(math.max(8, hunger_change*2), 25) do + minetest.add_particle({ + pos = { x = pos.x, y = pos.y, z = pos.z }, + velocity = vector.add(v, { x = math.random(-1, 1), y = math.random(1, 2), z = math.random(-1, 1) }), + acceleration = { x = 0, y = math.random(-9, -5), z = 0 }, + expirationtime = 1, + size = math.random(1, 2), + collisiondetection = true, + vertical = false, + texture = "[combine:3x3:" .. -i .. "," .. -i .. "=" .. texture, + }) + end + end + minetest.sound_play("mcl_hunger_bite", { + max_hear_distance = 12, + gain = 1.0, + pitch = pitch or 1 + math.random(-10, 10)*0.005, + object = user, + }, true) + end + else + return false + end +end + if mcl_hunger.active then -- player-action based hunger changes minetest.register_on_dignode(function(pos, oldnode, player) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 321139c5f..03cd2a0a3 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -30,6 +30,10 @@ mcl_hunger.EXHAUST_REGEN = 6000 -- Regenerate 1 HP mcl_hunger.EXHAUST_HUNGER = 5 -- Hunger status effect at base level. mcl_hunger.EXHAUST_LVL = 4000 -- at what exhaustion player saturation gets lowered +mcl_hunger.EATING_DELAY = tonumber(minetest.settings:get("mcl_eating_delay")) or 1.61 +mcl_hunger.EATING_WALK_SPEED = tonumber(minetest.settings:get("movement_speed_crouch")) / tonumber(minetest.settings:get("movement_speed_walk")) +mcl_hunger.EATING_TOUCHSCREEN_DELAY_PADDING = 0.75 + mcl_hunger.SATURATION_INIT = 5 -- Initial saturation for new/respawning players -- Debug Mode. If enabled, saturation and exhaustion are shown as well. @@ -39,6 +43,56 @@ mcl_hunger.debug = false -- Cooldown timers for each player, to force a short delay between consuming 2 food items mcl_hunger.last_eat = {} +-- Is player eating API +function mcl_hunger.is_eating(name) + local result + if name then + if type(name) ~= "string" then + name = name:get_player_name() + end + result = mcl_hunger.eat_internal[name].is_eating_no_padding + end + return result +end + +-- Variables for each player, to handle delayed eating +mcl_hunger.eat_internal = {} +mcl_hunger.eat_anim_hud = {} + +-- Set per player internal variables for delayed eating +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + + mcl_hunger.eat_internal[name] = { + is_eating = false, + is_eating_no_padding = false, + itemname = nil, + item_definition = nil, + hp_change = nil, + replace_with_item = nil, + itemstack = nil, + user = nil, + pointed_thing = nil, + pitch = nil, + do_item_eat = false, + _custom_itemstack = nil, -- Used as comparison to make sure _custom_wrapper only executes when the same item is eaten + _custom_var = {}, -- Variables that can be used by _custom_var and _custom_wrapper + _custom_func = nil, -- Can be executed by _custom_wrapper + _custom_wrapper = nil, -- Will execute alongside minetest.do_item_eat if not empty and _custom_itemstack is equal to current player itemstack + _custom_do_delayed = false, -- If true, then will execute only _custom_wrapper after holding RMB or LMB within a delay specified by mcl_hunger.EATING_DELAY (Use to bypass minetest.do_item_eat entirely) + } + playerphysics.remove_physics_factor(player, "speed", "mcl_hunger:eating_speed") + player:hud_set_flags({wielditem = true}) +end) + +-- Clear when player leaves +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + + mcl_hunger.eat_internal[name] = nil + mcl_hunger.eat_anim_hud[name] = nil +end) + dofile(modpath.."/api.lua") dofile(modpath.."/hunger.lua") dofile(modpath.."/register_foods.lua") @@ -69,11 +123,21 @@ mcl_hunger.poison_hunger = {} -- food poisoning, increasing hunger -- HUD local function init_hud(player) + local name = player:get_player_name() hb.init_hudbar(player, "hunger", mcl_hunger.get_hunger(player)) if mcl_hunger.debug then hb.init_hudbar(player, "saturation", mcl_hunger.get_saturation(player), mcl_hunger.get_hunger(player)) hb.init_hudbar(player, "exhaustion", mcl_hunger.get_exhaustion(player)) end + mcl_hunger.eat_anim_hud[name] = player:hud_add({ + hud_elem_type = "image", + text = "blank.png", + position = {x = 0.5, y = 1}, + scale = {x = -25, y = -45}, + alignment = {x = 0, y = -1}, + offset = {x = 0, y = -30}, + z_index = -200, + }) end -- HUD updating functions for Debug Mode. No-op if not in Debug Mode @@ -138,6 +202,37 @@ minetest.register_on_player_hpchange(function(player, hp_change) end) local food_tick_timers = {} -- one food_tick_timer per player, keys are the player-objects +local eat_start_timers = {} +local eat_tick_timers = {} +local eat_effects_cooldown = {} + +local function clear_eat_internal_and_timers(player, player_name) + playerphysics.remove_physics_factor(player, "speed", "mcl_hunger:eating_speed") + player:hud_set_flags({wielditem = true}) + player:hud_change(mcl_hunger.eat_anim_hud[player_name], "text", "blank.png") + mcl_hunger.eat_internal[player_name] = { + is_eating = false, + is_eating_no_padding = false, + itemname = nil, + item_definition = nil, + hp_change = nil, + replace_with_item = nil, + itemstack = nil, + user = nil, + pointed_thing = nil, + pitch = nil, + do_item_eat = false, + _custom_itemstack = nil, + _custom_var = {}, + _custom_func = nil, + _custom_wrapper = nil, + _custom_do_delayed = false, + } + eat_start_timers[player] = 0 + eat_tick_timers[player] = 0 + eat_effects_cooldown[player] = 0 +end + minetest.register_globalstep(function(dtime) for _,player in pairs(minetest.get_connected_players()) do @@ -146,18 +241,19 @@ minetest.register_globalstep(function(dtime) local food_level = mcl_hunger.get_hunger(player) local food_saturation_level = mcl_hunger.get_saturation(player) local player_health = player:get_hp() + local max_tick_timer = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 0.5 - if food_tick_timer > 4.0 then + if food_tick_timer > 4 then food_tick_timer = 0 -- let hunger work always - if player_health > 0 and player_health <= 20 then + if player_health > 0 then --mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_HUNGER) -- later for hunger status effect mcl_hunger.update_exhaustion_hud(player) end if food_level >= 18 then -- slow regeneration - if player_health > 0 and player_health < 20 then + if player_health > 0 and player_health < player:get_properties().hp_max then player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) mcl_hunger.update_exhaustion_hud(player) @@ -173,8 +269,8 @@ minetest.register_globalstep(function(dtime) end end - elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level > 0 then -- fast regeneration - if player_health > 0 and player_health < 20 then + 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 < player:get_properties().hp_max then food_tick_timer = 0 player:set_hp(player_health+1) mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) @@ -183,6 +279,118 @@ minetest.register_globalstep(function(dtime) end food_tick_timers[player] = food_tick_timer -- update food_tick_timer table + + -- Eating delay code + if mcl_hunger.eat_internal[player_name] and mcl_hunger.eat_internal[player_name].is_eating or mcl_hunger.eat_internal[player_name]._custom_do_delayed then + mcl_hunger.eat_internal[player_name].is_eating = true + mcl_hunger.eat_internal[player_name].is_eating_no_padding = true + + local control = player:get_player_control() + local inv = player:get_inventory() + local current_itemstack = player:get_wielded_item() + + if not eat_start_timers[player] then + eat_start_timers[player] = 0 + end + + eat_start_timers[player] = eat_start_timers[player] + dtime + + if not eat_tick_timers[player] then + eat_tick_timers[player] = 0 + end + + if not eat_effects_cooldown[player] then + eat_effects_cooldown[player] = 0 + end + + if not mcl_hunger.eat_internal[player_name].pitch then + mcl_hunger.eat_internal[player_name].pitch = 1 + math.random(-10, 10)*0.005 + end + + -- check if holding RMB (or LMB as workaround for touchscreen) + if (current_itemstack == mcl_hunger.eat_internal[player_name].itemstack or current_itemstack == mcl_hunger.eat_internal[player_name]._custom_itemstack) and (control.RMB or control.LMB) then + eat_tick_timers[player] = eat_tick_timers[player] + dtime + eat_effects_cooldown[player] = eat_effects_cooldown[player] + dtime + + playerphysics.add_physics_factor(player, "speed", "mcl_hunger:eating_speed", mcl_hunger.EATING_WALK_SPEED) + + player:hud_set_flags({wielditem = false}) + local itemstackdef = current_itemstack:get_definition() + local wield_image = itemstackdef.wield_image + if not wield_image or wield_image == "" then wield_image = itemstackdef.inventory_image end + player:hud_change(mcl_hunger.eat_anim_hud[player_name], "text", wield_image) + player:hud_change(mcl_hunger.eat_anim_hud[player_name], "offset", {x = 0, y = 50*math.sin(10*eat_tick_timers[player]+math.random())-50}) + + if eat_effects_cooldown[player] > 0.2 then + eat_effects_cooldown[player] = 0 + + if not mcl_hunger.eat_internal[player_name].user then + mcl_hunger.eat_internal[player_name].user = player + end + + if not mcl_hunger.eat_internal[player_name].itemname then + mcl_hunger.eat_internal[player_name].itemname = current_itemstack:get_name() + end + + if not mcl_hunger.eat_internal[player_name].hp_change then + mcl_hunger.eat_internal[player_name].hp_change = 0 + end + + local pos = player:get_pos() + local itemname = mcl_hunger.eat_internal[player_name].itemname + local def = minetest.registered_items[itemname] + + mcl_hunger.eat_effects( + mcl_hunger.eat_internal[player_name].user, + mcl_hunger.eat_internal[player_name].itemname, + pos, + mcl_hunger.eat_internal[player_name].hp_change, + def, + mcl_hunger.eat_internal[player_name].pitch + ) + end + + -- check if eating delay is over + if eat_tick_timers[player] >= mcl_hunger.EATING_DELAY then + + if not mcl_hunger.eat_internal[player_name]._custom_do_delayed then + mcl_hunger.eat_internal[player_name].do_item_eat = true + + minetest.do_item_eat( + mcl_hunger.eat_internal[player_name].hp_change, + mcl_hunger.eat_internal[player_name].replace_with_item, + mcl_hunger.eat_internal[player_name].itemstack, + mcl_hunger.eat_internal[player_name].user, + mcl_hunger.eat_internal[player_name].pointed_thing + ) + + -- bypass minetest.do_item_eat and only execute _custom_wrapper + elseif mcl_hunger.eat_internal[player_name]._custom_itemstack and + mcl_hunger.eat_internal[player_name]._custom_wrapper and + mcl_hunger.eat_internal[player_name]._custom_itemstack == current_itemstack then + + mcl_hunger.eat_internal[player_name]._custom_wrapper(player_name) + + player:get_inventory():set_stack("main", player:get_wield_index(), itemstack) + end + + clear_eat_internal_and_timers(player, player_name) + end + + elseif eat_start_timers[player] and eat_start_timers[player] > 0.2 then + playerphysics.remove_physics_factor(player, "speed", "mcl_hunger:eating_speed") + player:hud_set_flags({wielditem = true}) + player:hud_change(mcl_hunger.eat_anim_hud[player_name], "text", "blank.png") + mcl_hunger.eat_internal[player_name].is_eating_no_padding = false + + elseif eat_start_timers[player] and eat_start_timers[player] > mcl_hunger.EATING_TOUCHSCREEN_DELAY_PADDING then + clear_eat_internal_and_timers(player, player_name) + end + end + + if eat_start_timers[player] and eat_start_timers[player] > mcl_hunger.EATING_DELAY + mcl_hunger.EATING_TOUCHSCREEN_DELAY_PADDING then + clear_eat_internal_and_timers(player, player_name) + end end end) diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pt_BR.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pt_BR.tr new file mode 100644 index 000000000..c48a93090 --- /dev/null +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_hunger +@1 succumbed to the poison.=@1 sucumbiu ao veneno. +Food=Comida +Saturation=Saturação +%s: %.1f/%d=%s: %.1f/%d +Exhaust.=Cansado. +%s: %d/%d=%s: %d/%d +@1 starved to death.=@1 morreu de fome. diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ru.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ru.tr index a91a4db75..bc0b33a67 100644 --- a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ru.tr +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ru.tr @@ -1,8 +1,8 @@ # textdomain: mcl_hunger @1 succumbed to the poison.=@1 умер(ла) от яда. -Food=Продукт +Food=Еда Saturation=Насыщение %s: %.1f/%d=%s: %.1f/%d -Exhaust.=Истощ. +Exhaust.=Истощение %s: %d/%d=%s: %d/%d @1 starved to death.=@1 умер(ла) от голода. diff --git a/mods/PLAYER/mcl_hunger/register_foods.lua b/mods/PLAYER/mcl_hunger/register_foods.lua index a68dde1c1..ee33e9332 100644 --- a/mods/PLAYER/mcl_hunger/register_foods.lua +++ b/mods/PLAYER/mcl_hunger/register_foods.lua @@ -1,7 +1,7 @@ -- Apply food poisoning effect as long there are no real status effect. --- TODO: Remove this when food poisoning a status effect in mcl_potions. +-- TODO: Sanitize this now that Food Poisoning is now an effect in mcl_potions -- Normal poison damage is set to 0 because it's handled elsewhere. -mcl_hunger.register_food("mcl_mobitems:rotten_flesh", 4, "", 30, 0, 100, 80) -mcl_hunger.register_food("mcl_mobitems:chicken", 2, "", 30, 0, 100, 30) -mcl_hunger.register_food("mcl_fishing:pufferfish_raw", 1, "", 15, 0, 300) +mcl_hunger.register_food("mcl_mobitems:rotten_flesh", 4, "", 30, 0, 1, 80) +mcl_hunger.register_food("mcl_mobitems:chicken", 2, "", 30, 0, 1, 30) +mcl_hunger.register_food("mcl_fishing:pufferfish_raw", 1, "", 15, 0, 3) diff --git a/mods/PLAYER/mcl_luck/init.lua b/mods/PLAYER/mcl_luck/init.lua new file mode 100644 index 000000000..275cea52f --- /dev/null +++ b/mods/PLAYER/mcl_luck/init.lua @@ -0,0 +1,33 @@ +mcl_luck = {} + +-- table indexed by player name +-- each entry for each player contains list of modifiers applied to the player +-- modifiers are listed by their name (defined when applying them) +-- all modifiers are dynamic (they are removed when the player leaves game and on server shutdown) +local applied_luck = {} + +function mcl_luck.apply_luck_modifier(player_name, modifier_name, amount) + applied_luck[player_name][modifier_name] = amount +end + +function mcl_luck.remove_luck_modifier(player_name, modifier_name) + applied_luck[player_name][modifier_name] = nil +end + +function mcl_luck.get_luck(player_name) + local luck = 0 + for _, amount in pairs(applied_luck[player_name]) do + luck = luck + amount + end + return luck +end + +minetest.register_on_joinplayer(function(player) + local player_name = player:get_player_name() + applied_luck[player_name] = {} +end) + +minetest.register_on_leaveplayer(function(player) + local player_name = player:get_player_name() + applied_luck[player_name] = nil +end) diff --git a/mods/PLAYER/mcl_luck/mod.conf b/mods/PLAYER/mcl_luck/mod.conf new file mode 100644 index 000000000..395c888bb --- /dev/null +++ b/mods/PLAYER/mcl_luck/mod.conf @@ -0,0 +1,3 @@ +name = mcl_luck +author = Herowl +description = An API for handling luck, it can be polled by random events. diff --git a/mods/PLAYER/mcl_meshhand/README.md b/mods/PLAYER/mcl_meshhand/README.md index 2c796ff32..89d53f484 100644 --- a/mods/PLAYER/mcl_meshhand/README.md +++ b/mods/PLAYER/mcl_meshhand/README.md @@ -1,4 +1,4 @@ -Mesh hand mod for MineClone 2. +Mesh hand mod for VoxeLibre. This mod uses a better-looking mesh for the wieldhand and applies the player skin texture to it. diff --git a/mods/PLAYER/mcl_meshhand/init.lua b/mods/PLAYER/mcl_meshhand/init.lua index a28efd502..44eb3e2b9 100644 --- a/mods/PLAYER/mcl_meshhand/init.lua +++ b/mods/PLAYER/mcl_meshhand/init.lua @@ -76,25 +76,32 @@ else end function mcl_meshhand.update_player(player) + local hand if mcl_skins_enabled then local node_id = mcl_skins.get_node_id_by_player(player) - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:" .. node_id) + hand = ItemStack("mcl_meshhand:" .. node_id) else local creative = minetest.is_creative_enabled(player:get_player_name()) - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand" .. (creative and "_crea" or "_surv")) + hand = ItemStack("mcl_meshhand:hand" .. (creative and "_crea" or "_surv")) end + if not mcl_potions then player:get_inventory():set_stack("hand", 1, hand) end + player:get_inventory():set_stack("hand", 1, mcl_potions.hf_update_internal(hand, player)) end +minetest.register_on_joinplayer(function(player) + player:get_inventory():set_size("hand", 1) +end) + +mcl_gamemode.register_on_gamemode_change(function(player) + mcl_meshhand.update_player(player) +end) + if mcl_skins_enabled then mcl_player.register_on_visual_change(mcl_meshhand.update_player) else minetest.register_on_joinplayer(mcl_meshhand.update_player) end -minetest.register_on_joinplayer(function(player) - player:get_inventory():set_size("hand", 1) -end) - -- This is needed to deal damage when punching mobs -- with random items in hand in survival mode minetest.override_item("", { diff --git a/mods/PLAYER/mcl_meshhand/mod.conf b/mods/PLAYER/mcl_meshhand/mod.conf index 687932514..fd10c259c 100644 --- a/mods/PLAYER/mcl_meshhand/mod.conf +++ b/mods/PLAYER/mcl_meshhand/mod.conf @@ -1,5 +1,5 @@ name = mcl_meshhand author = jordan4ibanez description = Applies the player skin texture to the hand. -depends = mcl_tools, mcl_player +depends = mcl_tools, mcl_player, mcl_gamemode optional_depends = mcl_skins, mcl_custom_skins diff --git a/mods/PLAYER/mcl_music/locale/mcl_music.fr.tr b/mods/PLAYER/mcl_music/locale/mcl_music.fr.tr new file mode 100644 index 000000000..3b5a684d5 --- /dev/null +++ b/mods/PLAYER/mcl_music/locale/mcl_music.fr.tr @@ -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 diff --git a/mods/PLAYER/mcl_music/locale/mcl_music.pt_BR.tr b/mods/PLAYER/mcl_music/locale/mcl_music.pt_BR.tr new file mode 100644 index 000000000..8e6f062b1 --- /dev/null +++ b/mods/PLAYER/mcl_music/locale/mcl_music.pt_BR.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_music +You need the debug privilege in order to turn ingame music on or off for somebody else!=Você precisa do privilégio debug para poder ligar ou desligar a música para alguém! +Couldn't find player @1!=O jogador @1 não pôde ser localizado! +Set music for @1 to: @2=Definida música @1 para: @2 +Turns music for yourself or another player on or off.=Liga ou desliga a música para você ou outro jogador. +on=ligado +off=desligado diff --git a/mods/PLAYER/mcl_music/locale/mcl_music.ru.tr b/mods/PLAYER/mcl_music/locale/mcl_music.ru.tr new file mode 100644 index 000000000..acdb7678d --- /dev/null +++ b/mods/PLAYER/mcl_music/locale/mcl_music.ru.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_music +You need the debug privilege in order to turn ingame music on or off for somebody else!=Вам нужна привилегия “debug”, чтобы переключать внутриигровую музыку для кого-то другого! +Couldn't find player @1!=Игрок @1 не найден! +Set music for @1 to: @2=Установить музыку для @1 на: +Turns music for yourself or another player on or off.=Включить или выключить музыку для себе или другого игрока. +on=вкл +off=выкл \ No newline at end of file diff --git a/mods/PLAYER/mcl_player/README.txt b/mods/PLAYER/mcl_player/README.txt index 637a25684..91d919a9e 100644 --- a/mods/PLAYER/mcl_player/README.txt +++ b/mods/PLAYER/mcl_player/README.txt @@ -1,4 +1,4 @@ -MineClone 2 mod: mcl_player +VoxeLibre mod: mcl_player ========================== Adds the 3D player model, taken from Minetest Game 0.4.16. @@ -21,4 +21,4 @@ Authors of media files MirceaKitsune (CC BY-SA 3.0): character.b3d -Textures: See main MineClone 2 README.md file. +Textures: See main VoxeLibre README.md file. diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 084fe48a1..164e0083b 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -1,3 +1,4 @@ +local string = string local sf = string.format -- Minetest 0.4 mod: player @@ -11,15 +12,16 @@ local animation_blend = 0 local function get_mouse_button(player) local controls = player:get_player_control() local get_wielded_item_name = player:get_wielded_item():get_name() - if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") and - not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then + if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and + not string.find(get_wielded_item_name, "mcl_bows:crossbow") and + not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then return true else return false end end -mcl_player.registered_player_models = { } +mcl_player.registered_player_models = {} -- Local for speed. local models = mcl_player.registered_player_models @@ -36,9 +38,19 @@ local player_sneak = {} local player_visible = {} mcl_player.player_attached = {} +local function get_player_textures(name) + local textures = player_textures[name] + if textures then return textures end + + local textures = { "character.png", "blank.png", "blank.png" } + player_textures[name] = textures + return textures + +end + function mcl_player.player_get_animation(player) local name = player:get_player_name() - local textures = player_textures[name] + local textures = get_player_textures(name) if not player_visible[name] then textures = table.copy(textures) @@ -49,7 +61,7 @@ function mcl_player.player_get_animation(player) model = player_model[name], textures = textures, animation = player_anim[name], - visibility = player_visibility[name] + visibility = player_visible[name] } end @@ -61,7 +73,7 @@ end local function update_player_textures(player) local name = player:get_player_name() - local textures = player_textures[name] + local textures = get_player_textures(name) if not player_visible[name] then textures = table.copy(textures) @@ -94,7 +106,7 @@ function mcl_player.player_set_model(player, model_name) player:set_properties({ mesh = model_name, visual = "mesh", - visual_size = model.visual_size or {x=1, y=1}, + visual_size = model.visual_size or { x = 1, y = 1 }, damage_texture_modifier = "^[colorize:red:130", }) update_player_textures(player) @@ -123,21 +135,36 @@ end function mcl_player.player_set_skin(player, texture) local name = player:get_player_name() - player_textures[name][1] = texture + local textures = get_player_textures(name) + textures[1] = texture update_player_textures(player) end +function mcl_player.player_get_skin(player) + local name = player:get_player_name() + local textures = get_player_textures(name) + return textures[1] +end + function mcl_player.player_set_armor(player, texture) local name = player:get_player_name() - player_textures[name][2] = texture + local textures = get_player_textures(name) + textures[2] = texture update_player_textures(player) end +---@param player mt.PlayerObjectRef +---@param x number +---@param y number +---@param w number +---@param h number +---@param fsname string +---@return string function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) local name = player:get_player_name() local model = player_model[name] local anim = models[model].animations[player_anim[name]] - local textures = player_textures[name] + local textures = get_player_textures(name) if not player_visible[name] then textures = table.copy(textures) textures[1] = "blank.png" @@ -165,9 +192,10 @@ minetest.register_on_joinplayer(function(player) local name = player:get_player_name() mcl_player.player_attached[name] = false player_visible[name] = true - player_textures[name] = {"character.png", "blank.png", "blank.png"} + get_player_textures(name) + --player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30) - player:set_fov(86.1) -- see >>> +-- player:set_fov(86.1) -- see >>> end) minetest.register_on_leaveplayer(function(player) @@ -218,14 +246,24 @@ minetest.register_globalstep(function(dtime) -- Apply animations based on what the player is doing if player:get_hp() == 0 then player_set_animation(player, "die") + elseif player:get_meta():get_int("mcl_damage:damage_animation") > 0 then + player_set_animation(player, "walk", animation_speed_mod) + local name = player:get_player_name() + minetest.after(0.5, function() + local player = minetest.get_player_by_name(name) + if not player then return end + player:get_meta():set_int("mcl_damage:damage_animation", 0) + end) elseif mcl_playerplus.elytra[player] and mcl_playerplus.elytra[player].active then - player_set_animation(player, "stand") + elseif walking and velocity.x > 0.35 - or walking and velocity.x < -0.35 - or walking and velocity.z > 0.35 - or walking and velocity.z < -0.35 then + or walking and velocity.x < -0.35 + or walking and velocity.z > 0.35 + or walking and velocity.z < -0.35 then local wielded_itemname = player:get_wielded_item():get_name() - local no_arm_moving = string.find(wielded_itemname, "mcl_bows:bow") or mcl_shields.wielding_shield(player, 1) or mcl_shields.wielding_shield(player, 2) + local no_arm_moving = string.find(wielded_itemname, "mcl_bows:bow") or + mcl_shields.wielding_shield(player, 1) or + mcl_shields.wielding_shield(player, 2) if player_sneak[name] ~= controls.sneak then player_anim[name] = nil player_sneak[name] = controls.sneak @@ -234,7 +272,8 @@ minetest.register_globalstep(function(dtime) player_set_animation(player, "swim_walk_mine", animation_speed_mod) elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) - elseif no_arm_moving and controls.RMB and controls.sneak or string.find(wielded_itemname, "mcl_bows:crossbow_") and controls.sneak then + elseif no_arm_moving and controls.RMB and controls.sneak or + string.find(wielded_itemname, "mcl_bows:crossbow_") and controls.sneak then player_set_animation(player, "bow_sneak", animation_speed_mod) elseif no_arm_moving and controls.RMB or string.find(wielded_itemname, "mcl_bows:crossbow_") then player_set_animation(player, "bow_walk", animation_speed_mod) diff --git a/mods/PLAYER/mcl_playerinfo/README.md b/mods/PLAYER/mcl_playerinfo/README.md index fe5ac0a42..42bed0b78 100644 --- a/mods/PLAYER/mcl_playerinfo/README.md +++ b/mods/PLAYER/mcl_playerinfo/README.md @@ -1,4 +1,4 @@ -# PlayerInfo mod for MineClone 2 +# PlayerInfo mod for VoxeLibre This is a helper mod for other mod to query the nodes around the player. diff --git a/mods/PLAYER/mcl_playerplus/README.md b/mods/PLAYER/mcl_playerplus/README.md index e51d086fb..40801bfdd 100644 --- a/mods/PLAYER/mcl_playerplus/README.md +++ b/mods/PLAYER/mcl_playerplus/README.md @@ -1,4 +1,4 @@ -# PlayerPlus mod for MineClone 2 +# PlayerPlus mod for VoxeLibre ## Features diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 69cb00d07..646030202 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -154,27 +154,27 @@ end local player_props_elytra = { collisionbox = { -0.35, 0, -0.35, 0.35, 0.8, 0.35 }, - eye_height = 0.5, + eye_height = 0.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_riding = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.5, + eye_height = 1.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_sneaking = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.35, + eye_height = 1.45, nametag_color = { r = 225, b = 225, a = 0, g = 225 } } local player_props_swimming = { collisionbox = { -0.312, 0, -0.312, 0.312, 0.8, 0.312 }, - eye_height = 0.5, + eye_height = 0.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } local player_props_normal = { collisionbox = { -0.312, 0, -0.312, 0.312, 1.8, 0.312 }, - eye_height = 1.5, + eye_height = 1.6, nametag_color = { r = 225, b = 225, a = 225, g = 225 } } @@ -366,7 +366,7 @@ minetest.register_globalstep(function(dtime) set_properties(player, player_props_elytra) -- control body bone when flying - local body_rot = vector.new((75 - degrees(dir_to_pitch(player_velocity))), -player_vel_yaw + yaw, 0) + local body_rot = vector.new(degrees(dir_to_pitch(player_velocity)) + 110, -player_vel_yaw + yaw, 180) set_bone_pos(player, "Body_Control", nil, body_rot) elseif parent then set_properties(player, player_props_riding) @@ -657,11 +657,14 @@ end) -- set to blank on join (for 3rd party mods) minetest.register_on_joinplayer(function(player) local name = player:get_player_name() + local hp = player:get_hp() mcl_playerplus_internal[name] = { lastPos = nil, swimDistance = 0, jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly + last_damage = 0, + invul_timestamp = 0, } mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0} @@ -671,6 +674,11 @@ minetest.register_on_joinplayer(function(player) player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0)) player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3, 5.785, 0)) player:set_bone_position("Body_Control", vector.new(0, 6.75, 0)) + -- Respawn dead players on joining + if hp <= 0 then + player:respawn() + minetest.log("warning", name .. " joined the game with 0 hp and has been forced to respawn") + end end) -- clear when player leaves @@ -721,6 +729,48 @@ mcl_damage.register_modifier(function(obj, damage, reason) end end, -200) +minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage) + -- attack reach limit + if hitter and hitter:is_player() then + local player_pos = player:get_pos() + local hitter_pos = hitter:get_pos() + if vector.distance(player_pos, hitter_pos) > 3 then + damage = 0 + return damage + end + end + -- damage invulnerability + if hitter then + local name = player:get_player_name() + local time_now = minetest.get_us_time() + local invul_timestamp = mcl_playerplus_internal[name].invul_timestamp + local time_diff = time_now - invul_timestamp + -- check for invulnerability time in microseconds (0.5 second) + if time_diff <= 500000 and time_diff >= 0 then + player:get_meta():set_int("mcl_damage:invulnerable", 1) + minetest.after(0.5, function() + local player = minetest.get_player_by_name(name) + if not player then return end + player:get_meta():set_int("mcl_damage:invulnerable", 0) + end) + damage = damage - mcl_playerplus_internal[name].last_damage + if damage < 0 then + damage = 0 + end + return damage + else + mcl_playerplus_internal[name].last_damage = damage + mcl_playerplus_internal[name].invul_timestamp = time_now + player:get_meta():set_int("mcl_damage:damage_animation", 1) + minetest.after(0.5, function() + local player = minetest.get_player_by_name(name) + if not player then return end + player:get_meta():set_int("mcl_damage:damage_animation", 0) + end) + end + end +end) + minetest.register_on_respawnplayer(function(player) local pos = player:get_pos() minetest.add_particlespawner({ diff --git a/mods/PLAYER/mcl_skins/README.md b/mods/PLAYER/mcl_skins/README.md index 303dcf424..b381c31a9 100644 --- a/mods/PLAYER/mcl_skins/README.md +++ b/mods/PLAYER/mcl_skins/README.md @@ -1,9 +1,9 @@ -# Mineclone Skins +# VoxeLibre Skins This mod allows advanced skin customization. Use the /skin command to open the skin configuration screen. -To include custom skins in MineClone2, please download [mcl_custom_skins](https://git.minetest.land/mineclone2/mcl_custom_skins) +To include custom skins in VoxeLibre, please download the [mcl_custom_skins](https://codeberg.org/MineClone2/mcl_custom_skins) mod. ## License Code under MIT license diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua index 706c08461..2128986e4 100644 --- a/mods/PLAYER/mcl_skins/edit_skin.lua +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -5,8 +5,8 @@ local EDIT_SKIN_KEY = -1 -- The key used for edit skin in the mcl_skins.simple_s mcl_skins = { simple_skins = {}, texture_to_simple_skin = {}, - item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear"}, - tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear"}, + item_names = {"base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear", "cape"}, + tab_names = {"skin", "template", "base", "headwear", "hair", "eye", "mouth", "top", "arm", "bottom", "footwear", "cape"}, tab_descriptions = { template = S("Templates"), arm = S("Arm size"), @@ -19,11 +19,13 @@ mcl_skins = { hair = S("Hairs"), headwear = S("Headwears"), skin = S("Skins"), + cape = S("Capes") }, + cape = {}, template1 = {}, -- Stores edit skin values for template1 template2 = {}, -- Stores edit skin values for template2 base = {}, -- List of base textures - + -- Base color is separate to keep the number of junk nodes registered in check base_color = {0xffeeb592, 0xffb47a57, 0xff8d471d}, color = { @@ -57,17 +59,75 @@ mcl_skins = { player_formspecs = {}, } +local player_skins = mcl_skins.player_skins + +local function get_player_skins(player) + local player_skins = player_skins[player] + if player_skins then return player_skins end + + local skin = player:get_meta():get_string("mcl_skins:skin") + if skin then + skin = minetest.deserialize(skin) + end + if skin then + if not mcl_skins.texture_to_simple_skin[skin.simple_skins_id] then + skin.simple_skins_id = nil + end + + mcl_skins.player_skins[player] = skin + else + if math.random() > 0.5 then + skin = table.copy(mcl_skins.template1) + else + skin = table.copy(mcl_skins.template2) + end + mcl_skins.player_skins[player] = skin + end + + mcl_skins.player_formspecs[player] = { + active_tab = "skin", + page_num = 1 + } + + if #mcl_skins.simple_skins > 0 then + local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id")) + if skin_id and mcl_skins.simple_skins[skin_id] then + local texture = mcl_skins.simple_skins[skin_id].texture + local player_skins = get_player_skins(player) + player_skins.simple_skins_id = texture + end + end + mcl_skins.save(player) + mcl_skins.update_player_skin(player) + + return mcl_skins.player_skins[player] +end + function mcl_skins.register_item(item) assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.") + + if item.type == "cape" then + local func = item.selector_func + + if type(func) == "string" then + func = loadstring(func)() + end + + table.insert(mcl_skins.cape, {name=item.name, selector_func=func, mask=item.mask}) + mcl_skins.masks[item.name] = item.mask + return + end + local texture = item.texture or "blank.png" + if item.template1 then mcl_skins.template1[item.type] = texture end - + if item.template2 then mcl_skins.template2[item.type] = texture end - + table.insert(mcl_skins[item.type], texture) mcl_skins.masks[texture] = item.mask mcl_skins.preview_rotations[texture] = item.preview_rotation @@ -143,11 +203,21 @@ function mcl_skins.update_player_skin(player) if not player then return end - - local skin = mcl_skins.player_skins[player] - mcl_player.player_set_skin(player, mcl_skins.compile_skin(skin)) - + local skin = get_player_skins(player) + local skinval = mcl_skins.compile_skin(skin) + + if not skin.cape then skin.cape = "blank.png" end + + if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" then + skinval = skinval:gsub("%^" .. skin.cape, "") + -- don't render the "normal" cape on players while wearing the elytra. + -- this is NOT used when the player puts an elytra on, see register.lua in mcl_armor for that. + -- this is used when a player joins or changes something regarding their skin. + end + + mcl_player.player_set_skin(player, skinval) + local slim_arms if skin.simple_skins_id then slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms @@ -160,39 +230,7 @@ end -- Load player skin on join minetest.register_on_joinplayer(function(player) - local skin = player:get_meta():get_string("mcl_skins:skin") - if skin then - skin = minetest.deserialize(skin) - end - if skin then - if not mcl_skins.texture_to_simple_skin[skin.simple_skins_id] then - skin.simple_skins_id = nil - end - - mcl_skins.player_skins[player] = skin - else - if math.random() > 0.5 then - skin = table.copy(mcl_skins.template1) - else - skin = table.copy(mcl_skins.template2) - end - mcl_skins.player_skins[player] = skin - end - - mcl_skins.player_formspecs[player] = { - active_tab = "skin", - page_num = 1 - } - - if #mcl_skins.simple_skins > 0 then - local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id")) - if skin_id and mcl_skins.simple_skins[skin_id] then - local texture = mcl_skins.simple_skins[skin_id].texture - mcl_skins.player_skins[player].simple_skins_id = texture - end - end - mcl_skins.save(player) - mcl_skins.update_player_skin(player) + get_player_skins(player) end) minetest.register_on_leaveplayer(function(player) @@ -200,9 +238,17 @@ minetest.register_on_leaveplayer(function(player) mcl_skins.player_formspecs[player] = nil end) -local function calculate_page_count(tab) +local function calculate_page_count(tab, player) if tab == "skin" then return math.ceil((#mcl_skins.simple_skins + 2) / 8) + elseif tab == "cape" then + local player_capes = 0 + for _, cape in pairs(mcl_skins.cape) do + if type(cape.selector_func) == "nil" or cape.selector_func(player) then + player_capes = player_capes + 1 + end + end + return math.ceil((player_capes + 1) / 5) -- add one so the player can select no cape as well elseif mcl_skins[tab] then return math.ceil(#mcl_skins[tab] / 16) end @@ -211,31 +257,31 @@ end function mcl_skins.show_formspec(player, active_tab, page_num) local formspec_data = mcl_skins.player_formspecs[player] - local skin = mcl_skins.player_skins[player] + local skin = get_player_skins(player) formspec_data.active_tab = active_tab - - local page_count = calculate_page_count(active_tab) + + local page_count = calculate_page_count(active_tab, player) if page_num < 1 then page_num = 1 end if page_num > page_count then page_num = page_count end formspec_data.page_num = page_num - + local formspec = "formspec_version[3]size[14.2,11]" - + for i, tab in pairs(mcl_skins.tab_names) do if tab == active_tab then formspec = formspec .. "style[" .. tab .. ";bgcolor=green]" end - + local y = 0.3 + (i - 1) * 0.8 formspec = formspec .. "style[" .. tab .. ";content_offset=16,0]" .. "button[0.3," .. y .. ";4,0.8;" .. tab .. ";" .. mcl_skins.tab_descriptions[tab] .. "]" .. - "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:11:" .. i - 1 .. "]" - + "image[0.4," .. y + 0.1 .. ";0.6,0.6;mcl_skins_icons.png^[verticalframe:12:" .. i - 1 .. "]" + if skin.simple_skins_id then break end end - + local slim_arms if skin.simple_skins_id then slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms @@ -249,6 +295,9 @@ function mcl_skins.show_formspec(player, active_tab, page_num) mcl_skins.compile_skin(skin) .. ",blank.png,blank.png;0,180;false;true;0,0]" + + local cape_tab = active_tab == "cape" + if active_tab == "skin" then local page_start = (page_num - 1) * 8 - 1 local page_end = math.min(page_start + 8 - 1, #mcl_skins.simple_skins) @@ -264,21 +313,21 @@ function mcl_skins.show_formspec(player, active_tab, page_num) } simple_skins_id = simple_skins_id or mcl_skins.simple_skins[EDIT_SKIN_KEY].texture - + for i = page_start, page_end do local skin = mcl_skins.simple_skins[i] local j = i - page_start - 1 local mesh = skin.slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" - + local x = 4.5 + (j + 1) % 4 * 1.6 local y = 0.3 + math.floor((j + 1) / 4) * 3.1 - + formspec = formspec .. "model[" .. x .. "," .. y .. ";1.5,3;player_mesh;" .. mesh .. ";" .. skin.texture .. ",blank.png,blank.png;0,180;false;true;0,0]" - + if simple_skins_id == skin.texture then formspec = formspec .. "style[" .. i .. @@ -288,7 +337,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,3;" .. i .. ";]" end - + if page_start == EDIT_SKIN_KEY then formspec = formspec .. "image[4.85,1;0.8,0.8;mcl_skins_button.png]" end @@ -303,16 +352,46 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "model[7.5,2;2,3;player_mesh;mcl_armor_character_female.b3d;" .. mcl_skins.compile_skin(mcl_skins.template2) .. ",blank.png,blank.png;0,180;false;true;0,0]" .. - + "button[7.5,5.2;2,0.8;template2;" .. S("Select") .. "]" - + + elseif cape_tab then + local possize = {{"6,2;1,2", "5.5,4.2;2,0.8"}, {"9,2;1,2","8.5,4.2;2,0.8"}, {"6,7;1,2","5.5,9.2;2,0.8"}, {"9,7;1,2","8.5,9.2;2,0.8"},{"12,7;1,2","11.5,9.2;2,0.8"}} + local player_capes = {} -- contains all capes the player is allowed to wear + for _, cape in pairs (mcl_skins.cape) do + if type(cape.selector_func) == "nil" or cape.selector_func(player) then + table.insert(player_capes, cape) + end + end + + local slot_offset = 0 + + if page_num == 1 then + formspec = formspec .. + "label[6,3;" .. S("(None)") .. "]".. + "button[5.5,4.2;2,0.8;nocape;" .. S("Select") .. "]" + slot_offset = 1 + end + + local array_start = page_num * 5 - 4 + local index_offset = page_num == 1 and 1 or 2 + + for slot = 1 + slot_offset, page_num ~= page_count and 5 or (#player_capes % 5 == 0 and 1 or #player_capes % 5) + slot_offset do + local cape = player_capes[array_start + slot - slot_offset - index_offset] + local pos = possize[slot] + + formspec = formspec .. + "image[" .. possize[slot][1] .. ";" .. cape.name ..".png]".. + "button[" .. possize[slot][2] .. ";" .. cape.name ..";" .. S("Select") .. "]" + end + elseif mcl_skins[active_tab] then formspec = formspec .. "style_type[button;bgcolor=#00000000]" local textures = mcl_skins[active_tab] local page_start = (page_num - 1) * 16 + 1 local page_end = math.min(page_start + 16 - 1, #textures) - + for j = page_start, page_end do local i = j - page_start + 1 local texture = textures[j] @@ -323,21 +402,21 @@ function mcl_skins.show_formspec(player, active_tab, page_num) preview = preview .. "^(" .. mask .. "^[colorize:" .. color .. ":alpha)" end preview = preview .. "^" .. texture - + local mesh = "mcl_skins_head.obj" if active_tab == "top" then mesh = "mcl_skins_top.obj" elseif active_tab == "bottom" or active_tab == "footwear" then mesh = "mcl_skins_bottom.obj" end - + local rot_x = -10 local rot_y = 20 if mcl_skins.preview_rotations[texture] then rot_x = mcl_skins.preview_rotations[texture].x rot_y = mcl_skins.preview_rotations[texture].y end - + i = i - 1 local x = 4.5 + i % 4 * 1.6 local y = 0.3 + math.floor(i / 4) * 1.6 @@ -346,7 +425,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) ";1.5,1.5;" .. mesh .. ";" .. mesh .. ";" .. preview .. ";" .. rot_x .. "," .. rot_y .. ";false;false;0,0]" - + if skin[active_tab] == texture then formspec = formspec .. "style[" .. texture .. @@ -365,11 +444,11 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "button[" .. x .. ",0.3;1,1;arm;]" end - + if skin[active_tab .. "_color"] then local colors = mcl_skins.color if active_tab == "base" then colors = mcl_skins.base_color end - + local tab_color = active_tab .. "_color" local selected_color = skin[tab_color] for i, colorspec in pairs(colors) do @@ -381,7 +460,7 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "image_button[" .. x .. "," .. y .. ";0.8,0.8;blank.png^[noalpha^[colorize:" .. color .. ":alpha;" .. colorspec .. ";]" - + if selected_color == colorspec then formspec = formspec .. "style[" .. color .. @@ -389,9 +468,9 @@ function mcl_skins.show_formspec(player, active_tab, page_num) "bgimg_pressed=mcl_skins_select_overlay.png]" .. "button[" .. x .. "," .. y .. ";0.8,0.8;" .. color .. ";]" end - + end - + if not (active_tab == "base") then -- Bitwise Operations !?!?! local red = math.floor(selected_color / 0x10000) - 0xff00 @@ -400,39 +479,54 @@ function mcl_skins.show_formspec(player, active_tab, page_num) formspec = formspec .. "container[10.2,8]" .. "scrollbaroptions[min=0;max=255;smallstep=20]" .. - + "box[0.4,0;2.49,0.38;red]" .. "label[0.2,0.2;-]" .. "scrollbar[0.4,0;2.5,0.4;horizontal;red;" .. red .."]" .. "label[2.9,0.2;+]" .. - + "box[0.4,0.6;2.49,0.38;green]" .. "label[0.2,0.8;-]" .. "scrollbar[0.4,0.6;2.5,0.4;horizontal;green;" .. green .."]" .. "label[2.9,0.8;+]" .. - + "box[0.4,1.2;2.49,0.38;blue]" .. "label[0.2,1.4;-]" .. "scrollbar[0.4,1.2;2.5,0.4;horizontal;blue;" .. blue .. "]" .. "label[2.9,1.4;+]" .. - + "container_end[]" end end if page_num > 1 then - formspec = formspec .. - "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + if cape_tab then + formspec = formspec .. + "image_button[4.5,0.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + else + formspec = formspec .. + "image_button[4.5,6.7;1,1;mcl_skins_arrow.png^[transformFX;previous_page;]" + end end - + if page_num < page_count then - formspec = formspec .. - "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + if cape_tab then + formspec = formspec .. + "image_button[9.8,0.7;1,1;mcl_skins_arrow.png;next_page;]" + else + formspec = formspec .. + "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + end end - + if page_count > 1 then - formspec = formspec .. - "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" + if cape_tab then + formspec = formspec .. + "label[7.3,1.2;" .. page_num .. " / " .. page_count .. "]" + else + formspec = formspec .. + "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" + end end local player_name = player:get_player_name() @@ -456,7 +550,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) formspec_data.form_send_job:cancel() formspec_data.form_send_job = nil end - + if fields.quit then mcl_skins.save(player) return true @@ -472,18 +566,37 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.update_player_skin(player) mcl_skins.show_formspec(player, active_tab, page_num) return true + elseif fields.nocape then + local player_skins = get_player_skins(player) + player_skins.cape = "blank.png" + mcl_skins.update_player_skin(player) + mcl_armor.update(player) --update elytra cape + mcl_skins.show_formspec(player, active_tab, page_num) + return true + elseif active_tab == "cape" then + for cape_index = ((page_num - 1) * 5) + 1, math.min(#mcl_skins.cape, page_num * 5) do + local cape = mcl_skins.cape[cape_index] + if fields[cape.name] then + local player_skins = get_player_skins(player) + player_skins.cape = cape.mask -- the actual overlay image + mcl_skins.update_player_skin(player) + mcl_armor.update(player) --update elytra cape + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + end end - + for i, tab in pairs(mcl_skins.tab_names) do if fields[tab] then mcl_skins.show_formspec(player, tab, 1) return true end end - - local skin = mcl_skins.player_skins[player] + + local skin = get_player_skins(player) if not skin then return true end - + if fields.next_page then page_num = page_num + 1 mcl_skins.show_formspec(player, active_tab, page_num) @@ -493,7 +606,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + if active_tab == "arm" then if fields.thick_arms then skin.slim_arms = false @@ -504,7 +617,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + if skin[active_tab .. "_color"] and ( fields.red and fields.red:find("^CHG") or @@ -518,7 +631,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) red = tonumber(red) or 0 green = tonumber(green) or 0 blue = tonumber(blue) or 0 - + local color = 0xff000000 + red * 0x10000 + green * 0x100 + blue if color >= 0 and color <= 0xffffffff then -- We delay resedning the form because otherwise it will break dragging scrollbars @@ -533,7 +646,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) return true end end - + local field for f, value in pairs(fields) do if value == "" then @@ -541,7 +654,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) break end end - + if field and active_tab == "skin" then local index = tonumber(field) index = index and math.floor(index) or 0 @@ -556,7 +669,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end return true end - + -- See if field is a texture if field and mcl_skins[active_tab] and @@ -567,7 +680,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) mcl_skins.show_formspec(player, active_tab, page_num) return true end - + -- See if field is a color local number = tonumber(field) if number and skin[active_tab .. "_color"] then @@ -591,7 +704,7 @@ local function init() local json, error = minetest.parse_json(data) assert(json, error) f:close() - + for _, item in pairs(json) do mcl_skins.register_item(item) end @@ -600,12 +713,14 @@ local function init() mcl_skins.template1.top_color = 0xff993535 mcl_skins.template1.bottom_color = 0xff644939 mcl_skins.template1.slim_arms = false - + mcl_skins.template1.cape = "blank.png" + mcl_skins.template2.base_color = mcl_skins.base_color[1] mcl_skins.template2.hair_color = 0xff715d57 mcl_skins.template2.top_color = 0xff346840 mcl_skins.template2.bottom_color = 0xff383532 mcl_skins.template2.slim_arms = true + mcl_skins.template2.cape = "blank.png" mcl_skins.register_simple_skin({ index = 0, @@ -619,3 +734,9 @@ local function init() end init() + +if not minetest.settings:get_bool("mcl_keepInventory", false) then + minetest.register_on_respawnplayer(function(player) + mcl_skins.update_player_skin(player) -- ensures players have their cape again after dying with an elytra + end) +end diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json index dc7afbfe1..1c0b106e9 100644 --- a/mods/PLAYER/mcl_skins/list.json +++ b/mods/PLAYER/mcl_skins/list.json @@ -263,5 +263,29 @@ "mask": "mcl_skins_base_1_mask.png", "template1": true, "template2": true + }, + { + "type": "cape", + "name": "mtcape", + "mask": "mtcape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "slimecape", + "mask": "slimecape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "ghastcape", + "mask": "ghastcape_body.png", + "selector_func" : null + }, + { + "type": "cape", + "name": "mclcape", + "mask": "mclcape_body.png", + "selector_func" : null } ] diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.pt_BR.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.pt_BR.tr new file mode 100644 index 000000000..db1de34d1 --- /dev/null +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.pt_BR.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_skins +Skins=Skins +Templates=Modelos +Arm size=Tamanho do Braço +Bases=Bases +Footwears=Calçados +Eyes=Olhos +Mouths=Bocas +Bottoms=Inferiores +Tops=Superiores +Hairs=Cabelos +Headwears=Acessórios +Open skin configuration screen.=Abrir tela de configuração de skin. +Select=Selecionar diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr index fda9330d6..96c97dc31 100644 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr @@ -1,6 +1,6 @@ # textdomain: mcl_skins -Skins=Облики -Templates=Образцы +Skins=Скины +Templates=Шаблоны Arm size=Толщина рук Bases=Цвета кожи Footwears=Обувь @@ -10,5 +10,5 @@ Bottoms=Ноги Tops=Туловища Hairs=Причёски Headwears=Головные уборы -Open skin configuration screen.=Открыть экран настройки облика. +Open skin configuration screen.=Открыть настройки скина. Select=Выбрать diff --git a/mods/PLAYER/mcl_skins/locale/template.txt b/mods/PLAYER/mcl_skins/locale/template.txt index c39d4066d..96160e2d8 100644 --- a/mods/PLAYER/mcl_skins/locale/template.txt +++ b/mods/PLAYER/mcl_skins/locale/template.txt @@ -11,4 +11,5 @@ Tops= Hairs= Headwears= Open skin configuration screen.= -Select= \ No newline at end of file +Select= +Capes= diff --git a/mods/PLAYER/mcl_skins/textures/README.txt b/mods/PLAYER/mcl_skins/textures/README.txt index 8b50278d3..381d8d6dc 100644 --- a/mods/PLAYER/mcl_skins/textures/README.txt +++ b/mods/PLAYER/mcl_skins/textures/README.txt @@ -1,3 +1,3 @@ To add custom skins to the game, please use the mcl_custom_skins mod. Download it from https://git.minetest.land/mineclone2/mcl_custom_skins -Support for adding custom skins to mcl_skins will be removed in a future MineClone2 release. +Support for adding custom skins to mcl_skins will be removed in a future VoxeLibre release. diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index eb0208dcb..89ededeed 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -76,6 +76,7 @@ local node_search_list = local success = storage:get_int("mcl_spawn_success")==1 local searched = (storage:get_int("mcl_spawn_searched")==1) or mg_name == "v6" or mg_name == "singlenode" or minetest.settings:get("static_spawnpoint") +local return_spawn = minetest.settings:get_bool("mcl_return_spawn", true) local wsp = minetest.string_to_pos(storage:get_string("mcl_spawn_world_spawn_point")) or {} -- world spawn position local check = storage:get_int("mcl_spawn_check") or 0 local cp = minetest.string_to_pos(storage:get_string("mcl_spawn_cp")) or {x=start_pos.x, y=start_pos.y, z=start_pos.z} @@ -498,7 +499,7 @@ function mcl_spawn.get_player_spawn_pos(player) if(string.match(checknode.name, "mcl_beds:respawn_anchor_charged_")) then local charge_level = tonumber(string.sub(checknode.name, -1)) - if not charge_level then + if not charge_level and return_spawn then minetest.log("warning","could not get level of players respawn anchor, sending him back to spawn!") player:get_meta():set_string("mcl_beds:spawn", "") minetest.chat_send_player(player:get_player_name(), S("Couldn't get level of your respawn anchor!")) @@ -510,10 +511,12 @@ function mcl_spawn.get_player_spawn_pos(player) minetest.set_node(checkpos, {name="mcl_beds:respawn_anchor"}) return checkpos, false end - else + elseif return_spawn then player:get_meta():set_string("mcl_beds:spawn", "") minetest.chat_send_player(player:get_player_name(), S("Your spawn bed was missing or blocked, and you had no charged respawn anchor!")) return mcl_spawn.get_world_spawn_pos(), false + else + return checkpos, false end end end diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.pt_BR.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.pt_BR.tr new file mode 100644 index 000000000..414f10b9f --- /dev/null +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_spawn +New respawn position set!=Nova posição de renascimento definida! +Respawn position cleared!=Posição de renascimento limpa! +Couldn't get level of your respawn anchor!=Não foi possível nivelar sua âncora de renascimento! +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=Sua cama está faltando ou foi bloqueada, e você não carregou sua âncora de renascimento. diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ru.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ru.tr index eec1bcd65..35d0b07c2 100644 --- a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ru.tr +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ru.tr @@ -1,4 +1,5 @@ # textdomain: mcl_spawn New respawn position set!=Задана новая точка возрождения! Respawn position cleared!=Точка возрождения удалена! -Your spawn bed was missing or blocked.=Точка вашего возрождения не задана либо заблокирована. +Couldn't get level of your respawn anchor!=Невозможно получить уровень вашего якоря возрождения! +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=Ваша кровать пропала или заблокирована, и у вас нет заряженного якоря возрождения! \ No newline at end of file diff --git a/mods/PLAYER/mcl_sprint/README.md b/mods/PLAYER/mcl_sprint/README.md index f9f45d442..671e04b71 100644 --- a/mods/PLAYER/mcl_sprint/README.md +++ b/mods/PLAYER/mcl_sprint/README.md @@ -1,4 +1,4 @@ -# Sprint Mod for MineClone 2 +# Sprint Mod for VoxeLibre Forked from [sprint] by GunshipPenguin ## Description diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 7449ad18c..3d9ef984c 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -64,40 +64,24 @@ local function cancelClientSprinting(name) players[name].clientSprint = false end +mcl_fovapi.register_modifier({ + name = "sprint", + fov_factor = 1.1, + time = 0.15, + is_multiplier = true, +}) + local function setSprinting(playerName, sprinting) --Sets the state of a player (0=stopped/moving, 1=sprinting) if not sprinting and not mcl_sprint.is_sprinting(playerName) then return end local player = minetest.get_player_by_name(playerName) - local controls = player:get_player_control() if players[playerName] then players[playerName].sprinting = sprinting - local fov_old = players[playerName].fov - local fov_new = fov_old - local fade_time = .15 - if sprinting == true - or controls.RMB - and string.find(player:get_wielded_item():get_name(), "mcl_bows:bow") - and player:get_wielded_item():get_name() ~= "mcl_bows:bow" then - if sprinting == true then - fov_new = math.min(players[playerName].fov + 0.05, 1.2) - else - fov_new = .7 - players[playerName].fade_time = .3 - end - if sprinting == true then - playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) - end - elseif sprinting == false - and player:get_wielded_item():get_name() ~= "mcl_bows:bow_0" - and player:get_wielded_item():get_name() ~= "mcl_bows:bow_1" - and player:get_wielded_item():get_name() ~= "mcl_bows:bow_2" then - fov_new = math.max(players[playerName].fov - 0.05, 1.0) - if sprinting == false then - playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") - end - end - if fov_new ~= fov_old then - players[playerName].fov = fov_new - player:set_fov(fov_new, true, fade_time) + if sprinting then + playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) + mcl_fovapi.apply_modifier(player, "sprint") + else + playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") + mcl_fovapi.remove_modifier(player, "sprint") end return true end diff --git a/mods/PLAYER/mcl_sprint/mod.conf b/mods/PLAYER/mcl_sprint/mod.conf index 0d20f80a3..b8bc02698 100644 --- a/mods/PLAYER/mcl_sprint/mod.conf +++ b/mods/PLAYER/mcl_sprint/mod.conf @@ -1,4 +1,5 @@ name = mcl_sprint author = GunshipPenguin -description = Allows the player to sprint by pressing the “Use” key (default: E). -depends = mcl_playerinfo, playerphysics, mcl_hunger +description = Allows the player to sprint by pressing the “AUX” key (default: E). +depends = mcl_playerinfo, playerphysics, mcl_hunger, mcl_fovapi +optional = mcl_bows diff --git a/releasenotes/0_85-the_fire_and_stone_release.md b/releasenotes/0_85-the_fire_and_stone_release.md new file mode 100644 index 000000000..3e45fee4e --- /dev/null +++ b/releasenotes/0_85-the_fire_and_stone_release.md @@ -0,0 +1,108 @@ +## 0.85 – The Fire and Stone release + +### Contributors +#### New maintainer +* Herowl + +#### New contributors +* Codiac +* DinoNuggies4665 +* basxto +* Morik666 +* Eliy21 +* mdk +* pepebotella +* Alessandra Lozoya +* VanicGame +* ThePython10110 +* Araca +* Montandalar +* mim +* Dark +* ChrisPHP +* thunder1035 +* Isaac Dennis +* ADLON +* Sab Pyrope +* Bakawun + +### Mobs improvements +Creeper received some adjustments, should be smarter, but easier to avoid if you're quick. Axolotl on the other hand won't eat your sheep anymore. + +Wither received a massive rework by Herowl, complete with custom attacks. Make sure to check him out, especially if you're up for a challenge. + +Iron Golem received some AI changes by our new contributor, Codiac, which should prevent him getting lost so much. + +Another rework done by Codiac was a change of how mob spawning takes light level into account. It should now be easier to prevent hostile spawns by lighting areas up, among other things. + +### Stonecutter functionality +Stonecutter finally received its functionality! Thanks to the work done by ChrisPHP, Herowl and AFCMS you can now cut every kind of stone into slabs, stairs, and decorated variants with unprecedented ease. + +### Campfire update +Another node that received a large update is the campfire, as well as the soul version. Thanks to the great work of PrairieWind, DinoNuggies4665, thunder1035, Wbjitscool, & AncientMariner, you can now cook items on them, and see it being done! + +### Combat rebalancing +Combat should feel better than ever before with changes by Eliy21 and Herowl! Knockback is stronger and more visible, every hit causes a short window of damage resistance, critical hits are more stable, hunger-based health regeneration works slightly differently... check it out! + +### Armor trims +You can now decorate your armor with colorful gems and metals on the smithing table thanks to the work of chmodsayshello. + +### Path undoing +Welcome our very own feature, path undoing! Brought to you by SmokeyDope and Herowl, you can now convert paths back to dirt by shift+right-clicking them with a shovel. + +### Formspec refactoring +Various GUI formspecs were updated in a massive rework by AFCMS to the newer version, as well as given new features. This includes survival and creative inventories (survival inventory got API allowing adding multiple tabs), as well as nodes like chests, furnaces, dispensers and hoppers. + +### Hopper reimplementation +Speaking of hoppers, our new contributor, Morik666, did an amazing job implementing a new API for hoppers, allowing to add various ways for other nodes to interact with the hoppers, including the nodes added by mods. + +### Pistons fixes +Pistons now work better thanks to seventeenthShulker, who fixed many bugs related to them. Sadly, even with these changes and the aforementioned hopper changes, not all mechanisms work as they should due to engine limitations that we are yet to make workarounds for. + +### Translations updated +* Brazilian Portuguese by Isaac Dennis +* Russian by ADLON & Sab Pyrope +* French by 3raven +* Spanish by megustanlosfrijoles + +### Other changes +* Texture names moving away from "`default_`" prefix – Liquid textures – by FossFanatic +* Cherry wood items fixes – by PrairieWind, 3raven, & MrRar +* Bamboo placing bug fixed – by seventeenthShulker +* Multishot enchantment fixed – by seventeenthShulker +* Missing textures added – by Wbjitscool +* Typo fixes – by pepebotella, Nicu, basxto, & mdk +* Villager trades update – by Alessandra Lozoya & Codiac +* Internal refactoring – by MrRar +* Banners' colors and texture adjustements – by VanicGame +* Copper crafting recipes fixes – by basxto & ThePython10110 +* Enchanting fixes – by Codiac & Araca +* Mob floating improvements – by Codiac +* Ruined portal spawn fix – by SmokeyDope +* Barrels sound fix – by SmokeyDope +* New settings added – by Eliy21 +* Trapdoors climbing update – by Dehydrate6684 +* Blast resistance fixes – by seventeenthShulker +* Documentation fixes – by Montandalar, mim, & the developer team +* Player eye height raising – by Dark +* Craft guide searching fix – by Araca +* Boat passenger fixes – by Eliy21 +* Duplication bug fixed – by Herowl +* Nodes now drop properly when tool breaks while digging – by Herowl +* Sleeping HUD – by chmodsayshello +* Pumpkin group – by rudzik8 +* Fixed /clear being unclear and dangerous – by Herowl +* Fixed players sometimes being stuck dead even on relog – by Eliy21 +* Restricted access to the village builder tool to server privs - by Eliy21 +* Fixed horse equipment drops - by Bakawun + +### Special thanks +* For extensive testing – to Michieal + +### Crashes fixed +* Unknown nodes and callbacks related crash – by MrRar +* Campfire and bamboo related crash – by Michieal +* Unknown nodes related crash – by pepebotella +* Minetest vector code related crash – by AncientMariner +* Waterlogged roots and kelp related crash – by Michieal + diff --git a/releasenotes/0_86-the_another_look_release.md b/releasenotes/0_86-the_another_look_release.md new file mode 100644 index 000000000..330fbf97c --- /dev/null +++ b/releasenotes/0_86-the_another_look_release.md @@ -0,0 +1,50 @@ +## 0.86 – The Another Look release + +### Contributors +#### New contributors +* JoseDouglas26 +* Zasco + +### FOV API +Field of Vision control now goes through a new API using a modifier system, made by Michieal and Herowl. With these changes, sprint, bow drawing and spyglass should alter the FOV properly, as well as take into account the FOV set in Minetest settings. This also paves the way to more mechanics changing FOV in future updates. + +### Mob improvements +Shulker received an update by Bakawun (pulling some of the Mineclonia changes by cora). Animation usage got some fixes, and bullets are now slower but homing. Also it's fire rate is now variable. + +With the shulker update, other mobs (including those from mods) can now have homing bullets added with ease, as well as do custom things after each attack (like change the fire rate, which shulker now does). + +Slimes and Magma Cubes got rebalanced by Herowl, to make them work better with the player attack reach changes from the previous update (0.85 – Fire and Stone). + +Vexes and Evokers got some changes and fixes by Herowl to make them more manageable to fight while still being formidable enemies. + +### Shepherd functionality +A shepherd staff was added by Herowl, which allows you to lead your sheep without the risk of them eating the item you're luring them with. It can also serve as a weak weapon (to defend your sheep, of course). You can now collect sheep easier while travelling. Remember to take care of your sheep, also at night, and especially during the Christmastide. Speaking of Christmas, I've heard something changed about the moon. If you have trouble noticing that, maybe use the dedicated tools to take a closer look up. + +### Sunflower update +Sunflower now has a custom mesh by JoseDouglas26 (with minor tweaks from Herowl), which means it looks better and is oriented towards East properly. Thanks to the changes, it is also easier to make more mesh-based tall flowers in the future. + +### Animation updates +Animations of Stonecutter and Campfires were made more dynamic by Wbjitscool. + +### Mapgen settings +The setting disabling deepslate generation now works properly thanks to Zasco. + +### Translation updates +* Spanish by megustanlosfrijoles +* Brazilian Portuguese by JoseDouglas26 +* Syntax fixes in various translation-related files by megustanlosfrijoles + +### Crash fixes +* Villager trading UI crash by JoseDouglas26 +* Piston related crash by cora + +## 0.86.1 hotfix +* Implemented a fix to a graphical glitch regression introduced in release 0.86, which had been fixed but wasn't loaded into the tag. +* Added a workaround to enable mobile players to use bows, crossbows and spyglasses by using zoom key (they can't *hold* `place`). +(both fixes by Herowl) + +## 0.86.2 hotfix +* Implemented refactorization of player-related combat code by Eliy21. This fixes a critical bug which can cause players to become invulnerable indefinitely. +* Optimized some textures for size. +* Fixed XP orbs breaking randomly (by Herowl). +* Fixed a cryptic error message (by Herowl). diff --git a/releasenotes/0_87-the_prismatic_release.md b/releasenotes/0_87-the_prismatic_release.md new file mode 100644 index 000000000..54de6928d --- /dev/null +++ b/releasenotes/0_87-the_prismatic_release.md @@ -0,0 +1,199 @@ +## 0.87 – The Prismatic release + +### Contributors +#### New Developers +* rudzik8 +* teknomunk + +#### New Contributors +* PrWalterB +* michaljmalinowski +* nixnoxus +* Potiron +* Tuxilio +* Impulse +* Doods +* SOS-Games +* Bram +* qoheniac +* WillConker + +### Game rename +Based on months of collecting suggestions, analysis and vetting of possible names, community voting and discussion between developers, the rename of the game has reached its conclusion! The project has been renamed to **VoxeLibre**. + +Along with this, a documentation update has been conducted by Herowl, teknomunk and rudzik8. Make sure to check out the updated Contributing Guidelines! + +### Potions and Effects redo +After more than half a year of work, it is finally here! The whole system has been rewritten from the ground up by Herowl. New effects, potions and brewing recipes have been added. Potion tooltips have been reworked. In the HUD you can now see more information about what effects you have at the moment, including level and duration. Beacon has also received more effects and is now quite functional. + +A few new items to be used as brewing ingredients have been added. For now you can obtain them from fishing and trading with villagers. Those items will be made obtainable from other sources and will get more uses, hopefully in the next release. The functionality of some effects is not complete and they are also not obtainable yet (hero of the village and conduit power). + +Some of the old potions and tipped arrows don't work with the new API and have to be converted. To avoid constant rechecking of all inventories, they have been bound to placeholder definitions. What this means is that if you notice weird potions or arrows marked with question marks, you will have to right-click them to run the conversion. A small price to pay for less lag, right? + +Improved support of mobs by the effects and potions, including effects being properly saved on mobs. Despite that, some effects still don't work with mobs, because the mobs' code doesn't support them properly: + +* the following effects don't work with mobs at all: water breathing, dolphin's grace, leaping, swiftness, slowness, slow falling, night vision, darkness, frost, health boost, absorption, fire resistance, resistance, luck, bad luck, blindness, nausea, food poisoning, saturation, haste, fatigue, conduit power +* the following effects should work with mobs: invisibility, regeneration, poison, withering, strength, weakness, levitation, glowing +* the following effects have no effect on mobs (but can be applied with the API): bad omen, hero of the village + +While not everything is available in game, a great API (documented in the module) has been exposed for modders, allowing adding new effects and potions. Potions can now have all sorts of custom effects and multiple effects at once. Effects and potions can now have indefinitely many levels and potentially infinite duration, available with the `/effect` command and the modding API. Effects can still (and even more so than before!) be fine-tuned with factors and abnormal levels, which can sometimes give unexpected results, but it's all left up to modders. + +### Nether Portals rewrite +Another large rework! Thanks to emptyshore, portals to (and from) the Nether now work better than ever, connecting properly to each other. They shouldn't cause unwelcome surprises either, stranding you where you never expected to go, and shouldn't teleport you up into the skies. + +### Mob spawning system +An update by Bakawun improved the mob spawning, optimizing it and making the randomness work better, as well as properly taking into account set spawn chances. This update also changed the mob spawn chances and ratios. + +Another improvement to the system was made by teknomunk, who wrote a new system for spawn position calculation. This enables overhead spawning, among other things allowing for some mob farms to work. + +Also, light and height checking of Slimes has been fixed by Codiac, so they should no longer spawn in large numbers in inappropriate places. + +### Mob improvements +Not only did mob spawning get improved, but mobs themselves did too. + +Rover is a new mob, replacing the enderman. Along with this rework by Herowl and teknomunk, node picking code was refactored and generalized, paving the way for more mobs visibly holding actual items in the future. + +Stalker is another new mob, replacing the creeper. This rework completed by Herowl contains a new camouflage mechanic and otherwise a new look at a well-known concept. + +Ghast received a great update by Bakawun and Herowl. Its hitbox should now work properly, and deflecting the fireballs should work properly again too. Also the achievement for killing a Ghast with a ghast fireball should now be granted properly. + +Sounds for Hoglin/Zoglin, Piglin and skeletons have been updated by Bakawun and should now be used properly. + +Strider received a few fixes by nixnoxus. Breeding, attracting and riding should now work. + +### Eating animation +Eating is no longer instant in survival mode, but delayed instead with the new system designed by Eliy21. + +To signify it properly, Herowl added an animation visible in the first-person mode. + +### New blocks +* Colored End Rod variants by Herowl. +* Colored Redstone Lamps by Herowl. +* Glazed Terracotta Pillars by Potiron. +* Compressed Cobblestone by SmokeyDope. +* Clovers and Four-leaf Clovers by Herowl. +* Hollow logs by JoseDouglas26 and Herowl + +### Capes +Thanks to the changes by chmodsayshello and rudzik8, you can now pick a cape in the character skin customization UI. Thanks for the "Minetest" cape texture to QwertyDragon. + +### Colored leather armor +Leather armor can now be colored (and washed) thanks to AFCMS and Herowl. Aside of the crafting recipes, this added a command and a modding API for this. + +### Cherry blossom particles +The particles of the cherry blossom, which fall from the cherry leaves, have been vastly improved by Wbjitscool and Herowl. Plant some cherry trees and behold the new animation and the wind direction changing 3 times a game day. + +### Signs text editing +Now you can edit the text on signs by right-clicking ("place") on a sign placed in the world, all thanks to Araca. + +### Tool durability tooltips +Yet another feature from Araca, tooltips for tools (and weapons) will now display how much durability they have remaining. Now you have more precise info than just the wearbar! + +### Creative inventory fixes +Items can't be moved around in the creative inventory, tabs there have proper tooltips and searching works on Android with Minetest 5.8+ – all thanks to rudzik8. + +### Help UI – Mobs section +A "Mobs" section added to the Help UI by SOS-Games. Translations may be missing. + +### Texture pack converter +One of our tools, the Python script allowing conversion of Minecraft resource packs (texture-wise) to the Minetest format to work with our game, has received a great update by Impulse and Doods. It should now work with packs from newer versions, but keep in mind that not everything can be automated and the packs may still require some manual fixes (and additions, if you want to cover all of our own features that have no equivalents in Minecraft). + +### New Translation +* Occitan by PrWalterB + +### Translation updates +* Spanish by megustanlosfrijoles +* French by syl +* Polish by Herowl +* German by Tuxilio, Herowl and qoheniac +* Syntax fixes in translation files by megustanlosfrijoles + +### Other changes +* Melon and pumpkin generation – by michaljmalinowski +* Golden rails accelerate carts properly – by nixnoxus +* Elytra Animation works again – by MrRar +* Mobs aggro disabled when damage is disabled – by emptyshore +* Fortune enchantment on hoes works – by JoseDouglas26 +* Typo in pumpkin.lua fixed – by SmokeyDope +* Node rotation at placement improvements – by JoseDouglas26 +* Nylium reverting to netherrack – by JoseDouglas26 +* Hunger debug setting exposed properly – by SmokeyDope +* Nether vine placement fixes – by SmokeyDope +* Survival inventory tabs API fixes – by Impulse +* Cactus damaging mobs – by Eliy21 +* Sweet berry bush slowdown decreased – by Eliy21 +* Fixed scaffolding placement replacing other blocks without a trace – by JoseDouglas26 +* Nodes fireproofing and missing plank recipes added – by Doods +* End Rods now use a proper mesh model – by Herowl +* Piglin bartering improvements – by nixnoxus +* Hopper item movement improved – by teknomunk +* Partial item stack pickup – by teknomunk +* Bone meal node protection check – by CyberMango +* Undeclared variable usage fixed – by nixnoxus +* Biome check when spawning override (API, Skyblock support) – by AncientMariner +* Reimported tga_encoder as subtree (this allows support of some mods) – by Herowl +* Bed placement and destruction fixes – by teknomunk +* Item tooltip shouldn't be modified needlessly (this fixes some bugs causing items to not stack properly) – by Herowl +* Beds now properly ignore players in other dimensions – by nixnoxus +* Stray pixels in leather cap texture removed – by SmokeyDope +* Allow lecterns to be placed on sides of blocks – by JoseDouglas26 +* Fix warnings – by JoseDouglas26 +* Experience from trading – by nixnoxus +* Boats easier to destroy with punching – by Eliy21 +* Horse and Donkey animation fix – by Bakawun +* Villagers won't eat shulker boxes (independent of their food content) anymore – by teknomunk +* Beds now properly ignore players in the wrong dimensions when counting – by nixnoxus +* Shears now wear properly when harvesting comb from a beehive – by teknomunk +* Improved compatibility with mapgen mods – by Bram +* Item frame attachment fixed – by rudzik8 +* Stray pixels in sweet berry textures removed – by rudzik8 +* Warning related to milk bucket fixed – by teknomunk +* Seed is now logged when entering a world – by Nicu +* Startup warnings from mcl_stonecutter fixed – by Herowl +* Sleeping GUI improved – by Nicu +* Description capitalization fix – by syl + +### Special thanks +* To emptyshore, for the in-depth research and testing of the Mob Spawning System rework, as well as his aforementioned Nether Portals system rework. + +### Crash fixes +* Damage animation related crash – by Herowl +* Shields-related crash – by Impulse +* Elytra-related crash – by Herowl +* Damage animation and player invulnerability related crash – by Eliy21 +* Rocket explosion related crash – by Herowl +* New game load crash – by AncientMariner +* XP orbs related crash – by teknomunk +* Ghast fireball related crash – by Araca +* Crash related to server restart while a player is dead – by teknomunk +* Crashes related to the new effects API – by teknomunk and Herowl + +## 0.87.1 hotfix +* Fixed crash when shooting potions from a dispenser – by teknomunk +* Fixed crash related to custom mobspawners – by teknomunk +* Fixed beacon crash – by teknomunk +* Fixed eye of ender crash – by Herowl +* Fixed Stalker texture generation – by teknomunk +* Correctly refresh enchanted tool capabilities – by teknomunk +* Fixed creative inventory misbehaving – by Herowl +* Fixed variable definition in mob spawning code – by teknomunk +* Updated documentation – by Herowl and teknomunk +* Increased stack size for snowballs and eggs – by JoseDouglas26 + +## 0.87.2 hotfix +* Zombie texture improvements – by SmokeyDope +* Wrong name of diorite stairs fixed – by qoheniac +* Fixed flint and steel wearing down when not placing fire – by JoseDouglas26 and WillConker +* Fixed brewing stands' rotation – by JoseDouglas26 and WillConker +* Fixed beacon formspec – by teknomunk +* Made all hollow logs breakable properly – by teknomunk +* Instructions on how to eat added to the help menu – by teknomunk +* Potion conversion fixed – by Herowl +* Fixed some node names – by seventeenthShulker +* Fixed anvil and craftguide formspecs on mobile – by Herowl +* Fixed effect loading – by Herowl +* Fixed crash while fighting wither – by teknomunk +* Fixed crash when bonemealing sweet berry bushes – by teknomunk +* Fixed some mob conversion crashes – by teknomunk +* Fixed crash related to the frost walker enchantment – by WillConker +* Fixed some mob-related crashes – by Herowl diff --git a/settingtypes.txt b/settingtypes.txt index c5d5d32c1..ac3399498 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -51,6 +51,9 @@ mcl_disabled_events (Disabled events) string # This setting is only read at startup. enable_bed_respawn (Respawn at bed) bool true +#If enabled, players respawn at world spawn if bed is destroyed or respawn anchor has no charge. +mcl_return_spawn (Return to spawn if no bed) bool true + # How many players have to sleep to skip the night, in percent. # Setting to 0 will mean 1 player is always enough to skip the night. Setting above 100 will prevent skipping the night. # 100 by default. @@ -70,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. 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. # Recommended for new players and for a spoiler-free gameplay experience. # If disabled, all recipes will be shown. @@ -92,6 +98,17 @@ mcl_creative_dig_speed (Creative mode dig speed) float 0.2 # If enabled the hunger mechanic will be active mcl_enable_hunger (Hunger mechanic) bool true +# Enables hunger debug +mcl_hunger_debug (Hunger debug) bool false + +# Health regeneration delay when hunger bar is full +# Default: 0.5 s +mcl_health_regen_delay (Health regen delay) float 0.5 0 + +# Eating delay while holding right-click +# Default: 1.61 s +mcl_eating_delay (Eating delay) float 1.61 0 + [Mobs] # If enabled, mobs will spawn naturally. This does not affect # affect mob spawners. @@ -163,6 +180,24 @@ mcl_mob_cap_axolotl (Mob cap axolotl) int 5 0 1024 #Maximum amount of ambient mobs that will spawn near a player (default:15) mcl_mob_cap_ambient (Mob cap ambient mobs) int 15 0 1024 +#Maximum amount of wither bosses on the loaded mapchunks in the overworld that allows spawning withers in the overworld (default:3) +wither_cap_overworld (Wither cap overworld) int 3 0 2048 + +#Maximum amount of wither bosses on the loaded mapchunks in the nether that allows spawning withers in the nether (default:10) +wither_cap_nether (Wither cap nether) int 10 0 2048 + +#Maximum amount of wither bosses on the loaded mapchunks in the end that allows spawning withers in the end (default:5) +wither_cap_end (Wither cap end) int 5 0 2048 + +#Should wither follow the player who spawned him around +wither_follow_spawner (Wither following his spawner) bool false + +#Should wither strafe while in combat +wither_strafes (Wither strafes) bool true + +#Wither anti-troll measures (escaping when stuck in a block, despawning when spawner goes offline, teleporting after the spawner). When this is OFF, wither_follow_spawner has no effect. +wither_anti_troll_measures (Wither anti-troll measures) bool false + #Display mob icons in inventory instead of mc-like spawn eggs mcl_old_spawn_icons (Old spawn icons instead of eggs) bool false @@ -173,6 +208,19 @@ mcl_mob_active_range (Active mob range) int 48 0 256 # Zombie siege raid (default:false) mcl_raids_zombie_siege (Zombie siege raid) bool false +# Use MC 1.18+ light levels to control monster spawning. +# Disable to use older mob specific light levels. +mcl_mobs_modern_lighting (Use MC 1.18+ light rules for spawning) bool true + +# These only take effect if mcl_mobs_modern_lighting is enabled +# Light levels greater than these block mobs spawning +# See https://minecraft.fandom.com/wiki/Light#Internal_light_level +mcl_mobs_nether_threshold (Artificial light threshold to stop spawns in the Nether) int 11 0 14 +mcl_mobs_end_threshold (Artificial light threshold to stop spawns in the End) int 0 0 14 +mcl_mobs_overworld_threshold (Artificial light threshold to stop monster spawns in the Overworld) int 0 0 14 +mcl_mobs_overworld_sky_threshold (Skylight threshold to stop monster spawns in the Overworld) int 7 0 14 +mcl_mobs_overworld_passive_threshold (Combined light threshold to stop animal and npc spawns in the Overworld) int 7 0 14 + [Audio] # Enable flame sound. flame_sound (Flame sound) bool true @@ -256,6 +304,10 @@ fix_doubleplants (Mcimport double plant fixes) bool true # Allow players to create Minecraft-like maps. enable_real_maps (Enable Real Maps) bool true +# Enable workarounds for faulty mob navigation. +# Hack 1: teleport golems home if they are very far from home +mcl_mob_allow_nav_hacks (Mob navigation hacks) bool false + [Additional Features] # Enable Bookshelf inventories mcl_bookshelf_inventories (Enable bookshelf inventories) bool true diff --git a/textures/awards_ui_icon.png b/textures/awards_ui_icon.png index c8163008f..dbc532121 100644 Binary files a/textures/awards_ui_icon.png and b/textures/awards_ui_icon.png differ diff --git a/textures/boots_trim.png b/textures/boots_trim.png new file mode 100644 index 000000000..20a91a7fe Binary files /dev/null and b/textures/boots_trim.png differ diff --git a/textures/chestplate_trim.png b/textures/chestplate_trim.png new file mode 100644 index 000000000..e0d028e6d Binary files /dev/null and b/textures/chestplate_trim.png differ diff --git a/textures/coast_armor_trim_smithing_template.png b/textures/coast_armor_trim_smithing_template.png new file mode 100644 index 000000000..2701244fc Binary files /dev/null and b/textures/coast_armor_trim_smithing_template.png differ diff --git a/textures/coast_boots.png b/textures/coast_boots.png new file mode 100644 index 000000000..5782e80e0 Binary files /dev/null and b/textures/coast_boots.png differ diff --git a/textures/coast_chestplate.png b/textures/coast_chestplate.png new file mode 100644 index 000000000..2e61579b8 Binary files /dev/null and b/textures/coast_chestplate.png differ diff --git a/textures/coast_helmet.png b/textures/coast_helmet.png new file mode 100644 index 000000000..d82e237ea Binary files /dev/null and b/textures/coast_helmet.png differ diff --git a/textures/coast_leggings.png b/textures/coast_leggings.png new file mode 100644 index 000000000..a5d6c1c35 Binary files /dev/null and b/textures/coast_leggings.png differ diff --git a/textures/crafting_formspec_arrow.png b/textures/crafting_formspec_arrow.png new file mode 100644 index 000000000..2663c091d Binary files /dev/null and b/textures/crafting_formspec_arrow.png differ diff --git a/textures/crafting_inventory_creative.png b/textures/crafting_inventory_creative.png deleted file mode 100644 index 43664452b..000000000 Binary files a/textures/crafting_inventory_creative.png and /dev/null differ diff --git a/textures/crafting_inventory_creative_survival.png b/textures/crafting_inventory_creative_survival.png deleted file mode 100644 index ad53b5f4f..000000000 Binary files a/textures/crafting_inventory_creative_survival.png and /dev/null differ diff --git a/textures/credits_bg.png b/textures/credits_bg.png index 280f29def..9ca12390b 100644 Binary files a/textures/credits_bg.png and b/textures/credits_bg.png differ diff --git a/textures/doc_basics_craft_groups_1.png b/textures/doc_basics_craft_groups_1.png index 4093c50b1..d7fe37d0d 100644 Binary files a/textures/doc_basics_craft_groups_1.png and b/textures/doc_basics_craft_groups_1.png differ diff --git a/textures/doc_basics_craft_groups_2.png b/textures/doc_basics_craft_groups_2.png index a70bdde42..292eb8259 100644 Binary files a/textures/doc_basics_craft_groups_2.png and b/textures/doc_basics_craft_groups_2.png differ diff --git a/textures/doc_basics_craft_groups_3.png b/textures/doc_basics_craft_groups_3.png index 60a568be0..d912a344e 100644 Binary files a/textures/doc_basics_craft_groups_3.png and b/textures/doc_basics_craft_groups_3.png differ diff --git a/textures/doc_basics_gameplay_moontest.png b/textures/doc_basics_gameplay_moontest.png index 82350d8cc..bbface652 100644 Binary files a/textures/doc_basics_gameplay_moontest.png and b/textures/doc_basics_gameplay_moontest.png differ diff --git a/textures/doc_basics_gameplay_mtg_2.png b/textures/doc_basics_gameplay_mtg_2.png index 68c8a5063..803e66af3 100644 Binary files a/textures/doc_basics_gameplay_mtg_2.png and b/textures/doc_basics_gameplay_mtg_2.png differ diff --git a/textures/doc_basics_hotbar.png b/textures/doc_basics_hotbar.png index 6a8f82ffc..810b841f7 100644 Binary files a/textures/doc_basics_hotbar.png and b/textures/doc_basics_hotbar.png differ diff --git a/textures/doc_basics_hotbar_relations.png b/textures/doc_basics_hotbar_relations.png index b63943880..a5f0fb71a 100644 Binary files a/textures/doc_basics_hotbar_relations.png and b/textures/doc_basics_hotbar_relations.png differ diff --git a/textures/doc_basics_items_dropped.png b/textures/doc_basics_items_dropped.png index 2d4b92450..488f7c279 100644 Binary files a/textures/doc_basics_items_dropped.png and b/textures/doc_basics_items_dropped.png differ diff --git a/textures/doc_basics_light_test.png b/textures/doc_basics_light_test.png index 9b4a24f5a..8a8dd14a0 100644 Binary files a/textures/doc_basics_light_test.png and b/textures/doc_basics_light_test.png differ diff --git a/textures/doc_basics_light_torch.png b/textures/doc_basics_light_torch.png index 0fc840595..4296d97a9 100644 Binary files a/textures/doc_basics_light_torch.png and b/textures/doc_basics_light_torch.png differ diff --git a/textures/doc_basics_liquids_nonrenewable.png b/textures/doc_basics_liquids_nonrenewable.png index f38bbb316..c345b05b1 100644 Binary files a/textures/doc_basics_liquids_nonrenewable.png and b/textures/doc_basics_liquids_nonrenewable.png differ diff --git a/textures/doc_basics_liquids_renewable_1.png b/textures/doc_basics_liquids_renewable_1.png index 67691081e..99f99f914 100644 Binary files a/textures/doc_basics_liquids_renewable_1.png and b/textures/doc_basics_liquids_renewable_1.png differ diff --git a/textures/doc_basics_liquids_renewable_2.png b/textures/doc_basics_liquids_renewable_2.png index 63a5cea1b..d8c252bba 100644 Binary files a/textures/doc_basics_liquids_renewable_2.png and b/textures/doc_basics_liquids_renewable_2.png differ diff --git a/textures/doc_basics_minimap_map.png b/textures/doc_basics_minimap_map.png index 63f4a9bac..779211a06 100644 Binary files a/textures/doc_basics_minimap_map.png and b/textures/doc_basics_minimap_map.png differ diff --git a/textures/doc_basics_minimap_round.png b/textures/doc_basics_minimap_round.png index 4f6753dac..0e09ba1fb 100644 Binary files a/textures/doc_basics_minimap_round.png and b/textures/doc_basics_minimap_round.png differ diff --git a/textures/doc_basics_players_lott.png b/textures/doc_basics_players_lott.png index 13419b8e8..509c3f3ff 100644 Binary files a/textures/doc_basics_players_lott.png and b/textures/doc_basics_players_lott.png differ diff --git a/textures/doc_basics_players_sam.png b/textures/doc_basics_players_sam.png index 4281ca588..4a1350bcf 100644 Binary files a/textures/doc_basics_players_sam.png and b/textures/doc_basics_players_sam.png differ diff --git a/textures/doc_basics_pointing.png b/textures/doc_basics_pointing.png index dda1580f1..da30c11ff 100644 Binary files a/textures/doc_basics_pointing.png and b/textures/doc_basics_pointing.png differ diff --git a/textures/doc_basics_sneak.png b/textures/doc_basics_sneak.png index bcde6ce52..8f32a8297 100644 Binary files a/textures/doc_basics_sneak.png and b/textures/doc_basics_sneak.png differ diff --git a/textures/dune_armor_trim_smithing_template.png b/textures/dune_armor_trim_smithing_template.png new file mode 100644 index 000000000..a816e88fd Binary files /dev/null and b/textures/dune_armor_trim_smithing_template.png differ diff --git a/textures/dune_boots.png b/textures/dune_boots.png new file mode 100644 index 000000000..776dbdceb Binary files /dev/null and b/textures/dune_boots.png differ diff --git a/textures/dune_chestplate.png b/textures/dune_chestplate.png new file mode 100644 index 000000000..2edc91c74 Binary files /dev/null and b/textures/dune_chestplate.png differ diff --git a/textures/dune_helmet.png b/textures/dune_helmet.png new file mode 100644 index 000000000..8aa90b25f Binary files /dev/null and b/textures/dune_helmet.png differ diff --git a/textures/dune_leggings.png b/textures/dune_leggings.png new file mode 100644 index 000000000..d40e2b42c Binary files /dev/null and b/textures/dune_leggings.png differ diff --git a/textures/eye_armor_trim_smithing_template.png b/textures/eye_armor_trim_smithing_template.png new file mode 100644 index 000000000..a9d78dee8 Binary files /dev/null and b/textures/eye_armor_trim_smithing_template.png differ diff --git a/textures/eye_boots.png b/textures/eye_boots.png new file mode 100644 index 000000000..4e1db557a Binary files /dev/null and b/textures/eye_boots.png differ diff --git a/textures/eye_chestplate.png b/textures/eye_chestplate.png new file mode 100644 index 000000000..71bb0fa7b Binary files /dev/null and b/textures/eye_chestplate.png differ diff --git a/textures/eye_helmet.png b/textures/eye_helmet.png new file mode 100644 index 000000000..7c049b086 Binary files /dev/null and b/textures/eye_helmet.png differ diff --git a/textures/eye_leggings.png b/textures/eye_leggings.png new file mode 100644 index 000000000..64fc3192b Binary files /dev/null and b/textures/eye_leggings.png differ diff --git a/textures/ghastcape.png b/textures/ghastcape.png new file mode 100644 index 000000000..6f6df86c3 Binary files /dev/null and b/textures/ghastcape.png differ diff --git a/textures/ghastcape_body.png b/textures/ghastcape_body.png new file mode 100644 index 000000000..51bb46478 Binary files /dev/null and b/textures/ghastcape_body.png differ diff --git a/textures/ghastcape_elytra.png b/textures/ghastcape_elytra.png new file mode 100644 index 000000000..d05fe46a5 Binary files /dev/null and b/textures/ghastcape_elytra.png differ diff --git a/textures/grindstone_gui_9.png b/textures/grindstone_gui_9.png new file mode 100644 index 000000000..b2fffcb56 Binary files /dev/null and b/textures/grindstone_gui_9.png differ diff --git a/textures/helmet_trim.png b/textures/helmet_trim.png new file mode 100644 index 000000000..74ec7eb9e Binary files /dev/null and b/textures/helmet_trim.png differ diff --git a/textures/leggings_trim.png b/textures/leggings_trim.png new file mode 100644 index 000000000..8c22023a7 Binary files /dev/null and b/textures/leggings_trim.png differ diff --git a/textures/mcl_anvils_inventory_arrow.png b/textures/mcl_anvils_inventory_arrow.png new file mode 100644 index 000000000..722d6f636 Binary files /dev/null and b/textures/mcl_anvils_inventory_arrow.png differ diff --git a/textures/mcl_anvils_inventory_cross.png b/textures/mcl_anvils_inventory_cross.png new file mode 100644 index 000000000..ec13632ca Binary files /dev/null and b/textures/mcl_anvils_inventory_cross.png differ diff --git a/textures/mcl_anvils_inventory_hammer.png b/textures/mcl_anvils_inventory_hammer.png new file mode 100644 index 000000000..66c1f5f91 Binary files /dev/null and b/textures/mcl_anvils_inventory_hammer.png differ diff --git a/textures/mcl_armor_helmet_leather.png b/textures/mcl_armor_helmet_leather.png index a84a3f5c2..bbbfea6aa 100644 Binary files a/textures/mcl_armor_helmet_leather.png and b/textures/mcl_armor_helmet_leather.png differ diff --git a/textures/mcl_banners_banner_base.png b/textures/mcl_banners_banner_base.png index 3ccd92564..b7824f0ec 100644 Binary files a/textures/mcl_banners_banner_base.png and b/textures/mcl_banners_banner_base.png differ diff --git a/textures/mcl_boats_cherry_boat.png b/textures/mcl_boats_cherry_boat.png index 118baddfd..bbece2201 100644 Binary files a/textures/mcl_boats_cherry_boat.png and b/textures/mcl_boats_cherry_boat.png differ diff --git a/textures/mcl_boats_cherry_chest_boat.png b/textures/mcl_boats_cherry_chest_boat.png index 8bc3725e6..b38bb0af0 100644 Binary files a/textures/mcl_boats_cherry_chest_boat.png and b/textures/mcl_boats_cherry_chest_boat.png differ diff --git a/textures/mcl_book_book_empty_slot.png b/textures/mcl_book_book_empty_slot.png new file mode 100644 index 000000000..e6a50bd9e Binary files /dev/null and b/textures/mcl_book_book_empty_slot.png differ diff --git a/textures/mcl_campfires_campfire_fire.png b/textures/mcl_campfires_campfire_fire.png index 3894744c6..f0cab90e5 100644 Binary files a/textures/mcl_campfires_campfire_fire.png and b/textures/mcl_campfires_campfire_fire.png differ diff --git a/textures/mcl_campfires_campfire_log_lit.png b/textures/mcl_campfires_campfire_log_lit.png index 117e78369..ced6ae132 100644 Binary files a/textures/mcl_campfires_campfire_log_lit.png and b/textures/mcl_campfires_campfire_log_lit.png differ diff --git a/textures/mcl_campfires_fire1.png b/textures/mcl_campfires_fire1.png deleted file mode 100644 index 2956e2e7c..000000000 Binary files a/textures/mcl_campfires_fire1.png and /dev/null differ diff --git a/textures/mcl_campfires_log.png b/textures/mcl_campfires_log.png index 62de149a0..ef00b587f 100644 Binary files a/textures/mcl_campfires_log.png and b/textures/mcl_campfires_log.png differ diff --git a/textures/mcl_campfires_particle_1.png b/textures/mcl_campfires_particle_1.png new file mode 100644 index 000000000..c7f77ea7e Binary files /dev/null and b/textures/mcl_campfires_particle_1.png differ diff --git a/textures/mcl_campfires_particle_10.png b/textures/mcl_campfires_particle_10.png new file mode 100644 index 000000000..5e840de62 Binary files /dev/null and b/textures/mcl_campfires_particle_10.png differ diff --git a/textures/mcl_campfires_particle_11.png b/textures/mcl_campfires_particle_11.png new file mode 100644 index 000000000..ab2f3070e Binary files /dev/null and b/textures/mcl_campfires_particle_11.png differ diff --git a/textures/mcl_campfires_particle_12.png b/textures/mcl_campfires_particle_12.png new file mode 100644 index 000000000..64314e1e5 Binary files /dev/null and b/textures/mcl_campfires_particle_12.png differ diff --git a/textures/mcl_campfires_particle_2.png b/textures/mcl_campfires_particle_2.png new file mode 100644 index 000000000..b4a8e23f5 Binary files /dev/null and b/textures/mcl_campfires_particle_2.png differ diff --git a/textures/mcl_campfires_particle_3.png b/textures/mcl_campfires_particle_3.png new file mode 100644 index 000000000..3eaa22691 Binary files /dev/null and b/textures/mcl_campfires_particle_3.png differ diff --git a/textures/mcl_campfires_particle_4.png b/textures/mcl_campfires_particle_4.png new file mode 100644 index 000000000..38e704428 Binary files /dev/null and b/textures/mcl_campfires_particle_4.png differ diff --git a/textures/mcl_campfires_particle_5.png b/textures/mcl_campfires_particle_5.png new file mode 100644 index 000000000..720bee935 Binary files /dev/null and b/textures/mcl_campfires_particle_5.png differ diff --git a/textures/mcl_campfires_particle_6.png b/textures/mcl_campfires_particle_6.png new file mode 100644 index 000000000..b3d8ce542 Binary files /dev/null and b/textures/mcl_campfires_particle_6.png differ diff --git a/textures/mcl_campfires_particle_7.png b/textures/mcl_campfires_particle_7.png new file mode 100644 index 000000000..c9b14d56c Binary files /dev/null and b/textures/mcl_campfires_particle_7.png differ diff --git a/textures/mcl_campfires_particle_8.png b/textures/mcl_campfires_particle_8.png new file mode 100644 index 000000000..efe168d2e Binary files /dev/null and b/textures/mcl_campfires_particle_8.png differ diff --git a/textures/mcl_campfires_particle_9.png b/textures/mcl_campfires_particle_9.png new file mode 100644 index 000000000..07eb465e3 Binary files /dev/null and b/textures/mcl_campfires_particle_9.png differ diff --git a/textures/mcl_campfires_soul_campfire_fire.png b/textures/mcl_campfires_soul_campfire_fire.png index 0f5580e5c..1f87329c0 100644 Binary files a/textures/mcl_campfires_soul_campfire_fire.png and b/textures/mcl_campfires_soul_campfire_fire.png differ diff --git a/textures/mcl_campfires_soul_campfire_log_lit.png b/textures/mcl_campfires_soul_campfire_log_lit.png index aa7459bf5..e9b9a9a66 100644 Binary files a/textures/mcl_campfires_soul_campfire_log_lit.png and b/textures/mcl_campfires_soul_campfire_log_lit.png differ diff --git a/textures/mcl_cherry_blossom_particle.png b/textures/mcl_cherry_blossom_particle.png deleted file mode 100644 index eabdb097c..000000000 Binary files a/textures/mcl_cherry_blossom_particle.png and /dev/null differ diff --git a/textures/mcl_cherry_blossom_particle_1.png b/textures/mcl_cherry_blossom_particle_1.png new file mode 100644 index 000000000..0b789e071 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_1.png differ diff --git a/textures/mcl_cherry_blossom_particle_10.png b/textures/mcl_cherry_blossom_particle_10.png new file mode 100644 index 000000000..a040a3922 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_10.png differ diff --git a/textures/mcl_cherry_blossom_particle_11.png b/textures/mcl_cherry_blossom_particle_11.png new file mode 100644 index 000000000..a86531ff6 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_11.png differ diff --git a/textures/mcl_cherry_blossom_particle_12.png b/textures/mcl_cherry_blossom_particle_12.png new file mode 100644 index 000000000..462798e6d Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_12.png differ diff --git a/textures/mcl_cherry_blossom_particle_2.png b/textures/mcl_cherry_blossom_particle_2.png new file mode 100644 index 000000000..e646513e0 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_2.png differ diff --git a/textures/mcl_cherry_blossom_particle_3.png b/textures/mcl_cherry_blossom_particle_3.png new file mode 100644 index 000000000..391355f83 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_3.png differ diff --git a/textures/mcl_cherry_blossom_particle_4.png b/textures/mcl_cherry_blossom_particle_4.png new file mode 100644 index 000000000..f0440ff1c Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_4.png differ diff --git a/textures/mcl_cherry_blossom_particle_5.png b/textures/mcl_cherry_blossom_particle_5.png new file mode 100644 index 000000000..a56829576 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_5.png differ diff --git a/textures/mcl_cherry_blossom_particle_6.png b/textures/mcl_cherry_blossom_particle_6.png new file mode 100644 index 000000000..9f7def63b Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_6.png differ diff --git a/textures/mcl_cherry_blossom_particle_7.png b/textures/mcl_cherry_blossom_particle_7.png new file mode 100644 index 000000000..bce32f796 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_7.png differ diff --git a/textures/mcl_cherry_blossom_particle_8.png b/textures/mcl_cherry_blossom_particle_8.png new file mode 100644 index 000000000..b7965c74e Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_8.png differ diff --git a/textures/mcl_cherry_blossom_particle_9.png b/textures/mcl_cherry_blossom_particle_9.png new file mode 100644 index 000000000..00817db16 Binary files /dev/null and b/textures/mcl_cherry_blossom_particle_9.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_cyan.png b/textures/mcl_colorblocks_glazed_terracotta_cyan.png index 6289015a6..e2c832bc0 100644 Binary files a/textures/mcl_colorblocks_glazed_terracotta_cyan.png and b/textures/mcl_colorblocks_glazed_terracotta_cyan.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_magenta.png b/textures/mcl_colorblocks_glazed_terracotta_magenta.png index 0673eab67..9f193f201 100644 Binary files a/textures/mcl_colorblocks_glazed_terracotta_magenta.png and b/textures/mcl_colorblocks_glazed_terracotta_magenta.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_black.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_black.png new file mode 100644 index 000000000..452bc39bd Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_black.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_blue.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_blue.png new file mode 100644 index 000000000..9de2e2200 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_blue.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_brown.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_brown.png new file mode 100644 index 000000000..d4df11cf9 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_brown.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_cyan.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_cyan.png new file mode 100644 index 000000000..47f8bb367 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_cyan.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_green.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_green.png new file mode 100644 index 000000000..232a77416 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_green.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_grey.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_grey.png new file mode 100644 index 000000000..8dcf1f987 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_grey.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_light_blue.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_light_blue.png new file mode 100644 index 000000000..eff4344e0 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_light_blue.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_lime.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_lime.png new file mode 100644 index 000000000..d4bab81c2 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_lime.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_magenta.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_magenta.png new file mode 100644 index 000000000..4c9228120 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_magenta.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_orange.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_orange.png new file mode 100644 index 000000000..4289f0856 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_orange.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_pink.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_pink.png new file mode 100644 index 000000000..8e6f6cfa9 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_pink.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_purple.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_purple.png new file mode 100644 index 000000000..3af4b4adc Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_purple.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_red.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_red.png new file mode 100644 index 000000000..b2b39aa0d Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_red.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_silver.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_silver.png new file mode 100644 index 000000000..c10b29a28 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_silver.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_white.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_white.png new file mode 100644 index 000000000..92247711e Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_white.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_side_yellow.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_yellow.png new file mode 100644 index 000000000..a43acb01d Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_side_yellow.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_black.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_black.png new file mode 100644 index 000000000..9dbc97d5f Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_black.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_blue.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_blue.png new file mode 100644 index 000000000..230c1ab97 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_blue.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_brown.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_brown.png new file mode 100644 index 000000000..586be7499 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_brown.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_cyan.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_cyan.png new file mode 100644 index 000000000..1da77f75f Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_cyan.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_green.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_green.png new file mode 100644 index 000000000..bd88f8192 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_green.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_grey.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_grey.png new file mode 100644 index 000000000..4a505edd8 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_grey.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_light_blue.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_light_blue.png new file mode 100644 index 000000000..9fa80bc27 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_light_blue.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_lime.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_lime.png new file mode 100644 index 000000000..fde7b2b79 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_lime.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_magenta.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_magenta.png new file mode 100644 index 000000000..9e42f9169 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_magenta.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_orange.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_orange.png new file mode 100644 index 000000000..12c78b38c Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_orange.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_pink.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_pink.png new file mode 100644 index 000000000..792f5c6b2 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_pink.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_purple.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_purple.png new file mode 100644 index 000000000..be323dc85 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_purple.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_red.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_red.png new file mode 100644 index 000000000..8ef07d159 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_red.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_silver.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_silver.png new file mode 100644 index 000000000..24814be79 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_silver.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_white.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_white.png new file mode 100644 index 000000000..e86c4cd99 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_white.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pillar_top_yellow.png b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_yellow.png new file mode 100644 index 000000000..f1311ef2b Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pillar_top_yellow.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_silver.png b/textures/mcl_colorblocks_glazed_terracotta_silver.png index c634af477..4dabc5cfe 100644 Binary files a/textures/mcl_colorblocks_glazed_terracotta_silver.png and b/textures/mcl_colorblocks_glazed_terracotta_silver.png differ diff --git a/textures/default_lava_flowing_animated.png b/textures/mcl_core_lava_flow_animation.png similarity index 100% rename from textures/default_lava_flowing_animated.png rename to textures/mcl_core_lava_flow_animation.png diff --git a/textures/default_lava_source_animated.png b/textures/mcl_core_lava_source_animation.png similarity index 100% rename from textures/default_lava_source_animated.png rename to textures/mcl_core_lava_source_animation.png diff --git a/textures/default_water_flowing_animated.png b/textures/mcl_core_water_flow_animation.png similarity index 100% rename from textures/default_water_flowing_animated.png rename to textures/mcl_core_water_flow_animation.png diff --git a/textures/default_water_source_animated.png b/textures/mcl_core_water_source_animation.png similarity index 100% rename from textures/default_water_source_animated.png rename to textures/mcl_core_water_source_animation.png diff --git a/textures/mcl_end_end_rod.png b/textures/mcl_end_end_rod.png new file mode 100644 index 000000000..5e5907a01 Binary files /dev/null and b/textures/mcl_end_end_rod.png differ diff --git a/textures/mcl_end_end_rod_bottom.png b/textures/mcl_end_end_rod_bottom.png deleted file mode 100644 index fc814a63b..000000000 Binary files a/textures/mcl_end_end_rod_bottom.png and /dev/null differ diff --git a/textures/mcl_end_end_rod_mask.png b/textures/mcl_end_end_rod_mask.png new file mode 100644 index 000000000..a108a6a10 Binary files /dev/null and b/textures/mcl_end_end_rod_mask.png differ diff --git a/textures/mcl_end_end_rod_side.png b/textures/mcl_end_end_rod_side.png deleted file mode 100644 index b6a9fdf97..000000000 Binary files a/textures/mcl_end_end_rod_side.png and /dev/null differ diff --git a/textures/mcl_end_end_rod_top.png b/textures/mcl_end_end_rod_top.png deleted file mode 100644 index 1485a8a26..000000000 Binary files a/textures/mcl_end_end_rod_top.png and /dev/null differ diff --git a/textures/mcl_farming_sweet_berry.png b/textures/mcl_farming_sweet_berry.png index f6a4c1db6..86a69bbf2 100644 Binary files a/textures/mcl_farming_sweet_berry.png and b/textures/mcl_farming_sweet_berry.png differ diff --git a/textures/mcl_farming_sweet_berry_bush_0.png b/textures/mcl_farming_sweet_berry_bush_0.png index 2d9a7eed8..2ba1d6c7e 100644 Binary files a/textures/mcl_farming_sweet_berry_bush_0.png and b/textures/mcl_farming_sweet_berry_bush_0.png differ diff --git a/textures/mcl_farming_sweet_berry_bush_1.png b/textures/mcl_farming_sweet_berry_bush_1.png index ecbd5f4cf..82c94bd72 100644 Binary files a/textures/mcl_farming_sweet_berry_bush_1.png and b/textures/mcl_farming_sweet_berry_bush_1.png differ diff --git a/textures/mcl_farming_sweet_berry_bush_2.png b/textures/mcl_farming_sweet_berry_bush_2.png index e452fe42b..94d215e56 100644 Binary files a/textures/mcl_farming_sweet_berry_bush_2.png and b/textures/mcl_farming_sweet_berry_bush_2.png differ diff --git a/textures/mcl_farming_sweet_berry_bush_3.png b/textures/mcl_farming_sweet_berry_bush_3.png index 0748e09c8..2e1cf9b0b 100644 Binary files a/textures/mcl_farming_sweet_berry_bush_3.png and b/textures/mcl_farming_sweet_berry_bush_3.png differ diff --git a/textures/mcl_flowers_clover.png b/textures/mcl_flowers_clover.png new file mode 100644 index 000000000..cdfc928d3 Binary files /dev/null and b/textures/mcl_flowers_clover.png differ diff --git a/textures/mcl_flowers_clover_inv.png b/textures/mcl_flowers_clover_inv.png new file mode 100644 index 000000000..033211b22 Binary files /dev/null and b/textures/mcl_flowers_clover_inv.png differ diff --git a/textures/mcl_flowers_fourleaf_clover.png b/textures/mcl_flowers_fourleaf_clover.png new file mode 100644 index 000000000..7b2087cf7 Binary files /dev/null and b/textures/mcl_flowers_fourleaf_clover.png differ diff --git a/textures/mcl_flowers_fourleaf_clover_inv.png b/textures/mcl_flowers_fourleaf_clover_inv.png new file mode 100644 index 000000000..1fe32362f Binary files /dev/null and b/textures/mcl_flowers_fourleaf_clover_inv.png differ diff --git a/textures/mcl_heads_stalker.png b/textures/mcl_heads_stalker.png new file mode 100644 index 000000000..79978bb45 Binary files /dev/null and b/textures/mcl_heads_stalker.png differ diff --git a/textures/mcl_heads_zombie.png b/textures/mcl_heads_zombie.png index 251f95fec..6a08fa1e3 100644 Binary files a/textures/mcl_heads_zombie.png and b/textures/mcl_heads_zombie.png differ diff --git a/textures/mcl_inventory_background9.png b/textures/mcl_inventory_background9.png new file mode 100644 index 000000000..171b78575 Binary files /dev/null and b/textures/mcl_inventory_background9.png differ diff --git a/textures/mcl_lightstone_mask.png b/textures/mcl_lightstone_mask.png new file mode 100644 index 000000000..caf35b44d Binary files /dev/null and b/textures/mcl_lightstone_mask.png differ diff --git a/textures/mcl_moon_special.png b/textures/mcl_moon_special.png new file mode 100644 index 000000000..2f742e966 Binary files /dev/null and b/textures/mcl_moon_special.png differ diff --git a/textures/mcl_potions_blindness_hud.png b/textures/mcl_potions_blindness_hud.png new file mode 100644 index 000000000..ac5be885b Binary files /dev/null and b/textures/mcl_potions_blindness_hud.png differ diff --git a/textures/mcl_potions_effect_absorption.png b/textures/mcl_potions_effect_absorption.png new file mode 100644 index 000000000..114f64e2d Binary files /dev/null and b/textures/mcl_potions_effect_absorption.png differ diff --git a/textures/mcl_potions_effect_bad_luck.png b/textures/mcl_potions_effect_bad_luck.png new file mode 100644 index 000000000..f950d489f Binary files /dev/null and b/textures/mcl_potions_effect_bad_luck.png differ diff --git a/textures/mcl_potions_effect_bad_omen.png b/textures/mcl_potions_effect_bad_omen.png index 4293aed22..e652e6c5c 100644 Binary files a/textures/mcl_potions_effect_bad_omen.png and b/textures/mcl_potions_effect_bad_omen.png differ diff --git a/textures/mcl_potions_effect_blindness.png b/textures/mcl_potions_effect_blindness.png new file mode 100644 index 000000000..b7f7d7340 Binary files /dev/null and b/textures/mcl_potions_effect_blindness.png differ diff --git a/textures/mcl_potions_effect_conduit_power.png b/textures/mcl_potions_effect_conduit_power.png new file mode 100644 index 000000000..a25536907 Binary files /dev/null and b/textures/mcl_potions_effect_conduit_power.png differ diff --git a/textures/mcl_potions_effect_darkness.png b/textures/mcl_potions_effect_darkness.png new file mode 100644 index 000000000..fc72daeb0 Binary files /dev/null and b/textures/mcl_potions_effect_darkness.png differ diff --git a/textures/mcl_potions_effect_dolphin_grace.png b/textures/mcl_potions_effect_dolphin_grace.png new file mode 100644 index 000000000..ac640819d Binary files /dev/null and b/textures/mcl_potions_effect_dolphin_grace.png differ diff --git a/textures/mcl_potions_effect_fatigue.png b/textures/mcl_potions_effect_fatigue.png new file mode 100644 index 000000000..13b724c2a Binary files /dev/null and b/textures/mcl_potions_effect_fatigue.png differ diff --git a/textures/mcl_potions_effect_fire_proof.png b/textures/mcl_potions_effect_fire_proof.png deleted file mode 100644 index effbefaa4..000000000 Binary files a/textures/mcl_potions_effect_fire_proof.png and /dev/null differ diff --git a/textures/mcl_potions_effect_fire_resistance.png b/textures/mcl_potions_effect_fire_resistance.png new file mode 100644 index 000000000..3be85391d Binary files /dev/null and b/textures/mcl_potions_effect_fire_resistance.png differ diff --git a/textures/mcl_potions_effect_food_poisoning.png b/textures/mcl_potions_effect_food_poisoning.png index f29be56a5..8fb969e6e 100644 Binary files a/textures/mcl_potions_effect_food_poisoning.png and b/textures/mcl_potions_effect_food_poisoning.png differ diff --git a/textures/mcl_potions_effect_frost.png b/textures/mcl_potions_effect_frost.png new file mode 100644 index 000000000..6a008d25c Binary files /dev/null and b/textures/mcl_potions_effect_frost.png differ diff --git a/textures/mcl_potions_effect_glowing.png b/textures/mcl_potions_effect_glowing.png new file mode 100644 index 000000000..83cd8b969 Binary files /dev/null and b/textures/mcl_potions_effect_glowing.png differ diff --git a/textures/mcl_potions_effect_haste.png b/textures/mcl_potions_effect_haste.png new file mode 100644 index 000000000..54dd34740 Binary files /dev/null and b/textures/mcl_potions_effect_haste.png differ diff --git a/textures/mcl_potions_effect_health_boost.png b/textures/mcl_potions_effect_health_boost.png new file mode 100644 index 000000000..a20ae5ccc Binary files /dev/null and b/textures/mcl_potions_effect_health_boost.png differ diff --git a/textures/mcl_potions_effect_hero_of_village.png b/textures/mcl_potions_effect_hero_of_village.png new file mode 100644 index 000000000..c0462a40f Binary files /dev/null and b/textures/mcl_potions_effect_hero_of_village.png differ diff --git a/textures/mcl_potions_effect_invisibility.png b/textures/mcl_potions_effect_invisibility.png new file mode 100644 index 000000000..138111efa Binary files /dev/null and b/textures/mcl_potions_effect_invisibility.png differ diff --git a/textures/mcl_potions_effect_invisible.png b/textures/mcl_potions_effect_invisible.png deleted file mode 100644 index db0afb575..000000000 Binary files a/textures/mcl_potions_effect_invisible.png and /dev/null differ diff --git a/textures/mcl_potions_effect_leaping.png b/textures/mcl_potions_effect_leaping.png index 8fbf25ae8..3b9d5500e 100644 Binary files a/textures/mcl_potions_effect_leaping.png and b/textures/mcl_potions_effect_leaping.png differ diff --git a/textures/mcl_potions_effect_levitation.png b/textures/mcl_potions_effect_levitation.png new file mode 100644 index 000000000..ca8b6db1d Binary files /dev/null and b/textures/mcl_potions_effect_levitation.png differ diff --git a/textures/mcl_potions_effect_luck.png b/textures/mcl_potions_effect_luck.png new file mode 100644 index 000000000..46df46a03 Binary files /dev/null and b/textures/mcl_potions_effect_luck.png differ diff --git a/textures/mcl_potions_effect_nausea.png b/textures/mcl_potions_effect_nausea.png new file mode 100644 index 000000000..1b291ee49 Binary files /dev/null and b/textures/mcl_potions_effect_nausea.png differ diff --git a/textures/mcl_potions_effect_night_vision.png b/textures/mcl_potions_effect_night_vision.png index f4263968a..e5d7f1a2d 100644 Binary files a/textures/mcl_potions_effect_night_vision.png and b/textures/mcl_potions_effect_night_vision.png differ diff --git a/textures/mcl_potions_effect_poison.png b/textures/mcl_potions_effect_poison.png new file mode 100644 index 000000000..014b4314c Binary files /dev/null and b/textures/mcl_potions_effect_poison.png differ diff --git a/textures/mcl_potions_effect_poisoned.png b/textures/mcl_potions_effect_poisoned.png deleted file mode 100644 index 9d8cd5815..000000000 Binary files a/textures/mcl_potions_effect_poisoned.png and /dev/null differ diff --git a/textures/mcl_potions_effect_regenerating.png b/textures/mcl_potions_effect_regenerating.png deleted file mode 100644 index dfb82bba9..000000000 Binary files a/textures/mcl_potions_effect_regenerating.png and /dev/null differ diff --git a/textures/mcl_potions_effect_regeneration.png b/textures/mcl_potions_effect_regeneration.png new file mode 100644 index 000000000..1c5b7d502 Binary files /dev/null and b/textures/mcl_potions_effect_regeneration.png differ diff --git a/textures/mcl_potions_effect_resistance.png b/textures/mcl_potions_effect_resistance.png new file mode 100644 index 000000000..e81acfd45 Binary files /dev/null and b/textures/mcl_potions_effect_resistance.png differ diff --git a/textures/mcl_potions_effect_saturation.png b/textures/mcl_potions_effect_saturation.png new file mode 100644 index 000000000..13bbd41e8 Binary files /dev/null and b/textures/mcl_potions_effect_saturation.png differ diff --git a/textures/mcl_potions_effect_slow.png b/textures/mcl_potions_effect_slow.png deleted file mode 100644 index 464d270a9..000000000 Binary files a/textures/mcl_potions_effect_slow.png and /dev/null differ diff --git a/textures/mcl_potions_effect_slow_falling.png b/textures/mcl_potions_effect_slow_falling.png new file mode 100644 index 000000000..5e82afc91 Binary files /dev/null and b/textures/mcl_potions_effect_slow_falling.png differ diff --git a/textures/mcl_potions_effect_slowness.png b/textures/mcl_potions_effect_slowness.png new file mode 100644 index 000000000..eafff9d35 Binary files /dev/null and b/textures/mcl_potions_effect_slowness.png differ diff --git a/textures/mcl_potions_effect_strength.png b/textures/mcl_potions_effect_strength.png new file mode 100644 index 000000000..54da79ed0 Binary files /dev/null and b/textures/mcl_potions_effect_strength.png differ diff --git a/textures/mcl_potions_effect_strong.png b/textures/mcl_potions_effect_strong.png deleted file mode 100644 index 515b5777a..000000000 Binary files a/textures/mcl_potions_effect_strong.png and /dev/null differ diff --git a/textures/mcl_potions_effect_swift.png b/textures/mcl_potions_effect_swift.png deleted file mode 100644 index cf9e4b95c..000000000 Binary files a/textures/mcl_potions_effect_swift.png and /dev/null differ diff --git a/textures/mcl_potions_effect_swiftness.png b/textures/mcl_potions_effect_swiftness.png new file mode 100644 index 000000000..cf5d6b4d9 Binary files /dev/null and b/textures/mcl_potions_effect_swiftness.png differ diff --git a/textures/mcl_potions_effect_water_breathing.png b/textures/mcl_potions_effect_water_breathing.png index 3ced75eba..80a1054f7 100644 Binary files a/textures/mcl_potions_effect_water_breathing.png and b/textures/mcl_potions_effect_water_breathing.png differ diff --git a/textures/mcl_potions_effect_weak.png b/textures/mcl_potions_effect_weak.png deleted file mode 100644 index 398c161ab..000000000 Binary files a/textures/mcl_potions_effect_weak.png and /dev/null differ diff --git a/textures/mcl_potions_effect_weakness.png b/textures/mcl_potions_effect_weakness.png new file mode 100644 index 000000000..62c2e3e12 Binary files /dev/null and b/textures/mcl_potions_effect_weakness.png differ diff --git a/textures/mcl_potions_effect_withering.png b/textures/mcl_potions_effect_withering.png new file mode 100644 index 000000000..eed626c6b Binary files /dev/null and b/textures/mcl_potions_effect_withering.png differ diff --git a/textures/mcl_potions_frost_hud.png b/textures/mcl_potions_frost_hud.png new file mode 100644 index 000000000..282c713f1 Binary files /dev/null and b/textures/mcl_potions_frost_hud.png differ diff --git a/textures/mcl_potions_glow_waypoint.png b/textures/mcl_potions_glow_waypoint.png new file mode 100644 index 000000000..1e5afedfb Binary files /dev/null and b/textures/mcl_potions_glow_waypoint.png differ diff --git a/textures/mcl_potions_icon_absorb.png b/textures/mcl_potions_icon_absorb.png new file mode 100644 index 000000000..f1f671f6b Binary files /dev/null and b/textures/mcl_potions_icon_absorb.png differ diff --git a/textures/mcl_potions_icon_frost.png b/textures/mcl_potions_icon_frost.png new file mode 100644 index 000000000..f9edd0d7c Binary files /dev/null and b/textures/mcl_potions_icon_frost.png differ diff --git a/textures/mcl_potions_icon_regen_frost.png b/textures/mcl_potions_icon_regen_frost.png new file mode 100644 index 000000000..0a604ec55 Binary files /dev/null and b/textures/mcl_potions_icon_regen_frost.png differ diff --git a/textures/mcl_potions_icon_regen_wither.png b/textures/mcl_potions_icon_regen_wither.png new file mode 100644 index 000000000..14c6acdad Binary files /dev/null and b/textures/mcl_potions_icon_regen_wither.png differ diff --git a/textures/mcl_potions_icon_wither.png b/textures/mcl_potions_icon_wither.png new file mode 100644 index 000000000..7ccf394b9 Binary files /dev/null and b/textures/mcl_potions_icon_wither.png differ diff --git a/textures/mcl_skins_icons.png b/textures/mcl_skins_icons.png index f0e7e93d8..a67fc58c1 100644 Binary files a/textures/mcl_skins_icons.png and b/textures/mcl_skins_icons.png differ diff --git a/textures/mcl_smithing_table_bottom.png b/textures/mcl_smithing_table_bottom.png index d44c0773e..cca0ebf14 100644 Binary files a/textures/mcl_smithing_table_bottom.png and b/textures/mcl_smithing_table_bottom.png differ diff --git a/textures/mcl_smithing_table_front.png b/textures/mcl_smithing_table_front.png index bdf52e354..eef16e6aa 100644 Binary files a/textures/mcl_smithing_table_front.png and b/textures/mcl_smithing_table_front.png differ diff --git a/textures/mcl_smithing_table_inventory_hammer.png b/textures/mcl_smithing_table_inventory_hammer.png new file mode 100644 index 000000000..48a21e97d Binary files /dev/null and b/textures/mcl_smithing_table_inventory_hammer.png differ diff --git a/textures/mcl_smithing_table_inventory_trim_bg.png b/textures/mcl_smithing_table_inventory_trim_bg.png new file mode 100644 index 000000000..da1e8178e Binary files /dev/null and b/textures/mcl_smithing_table_inventory_trim_bg.png differ diff --git a/textures/mcl_smithing_table_side.png b/textures/mcl_smithing_table_side.png index fbc1a9a23..d93a7906c 100644 Binary files a/textures/mcl_smithing_table_side.png and b/textures/mcl_smithing_table_side.png differ diff --git a/textures/mcl_smithing_table_top.png b/textures/mcl_smithing_table_top.png index 63c6aea35..be7abee62 100644 Binary files a/textures/mcl_smithing_table_top.png and b/textures/mcl_smithing_table_top.png differ diff --git a/textures/mcl_tool_shepherd_staff.png b/textures/mcl_tool_shepherd_staff.png new file mode 100644 index 000000000..1345a4c49 Binary files /dev/null and b/textures/mcl_tool_shepherd_staff.png differ diff --git a/textures/mclcape.png b/textures/mclcape.png new file mode 100644 index 000000000..0e8a4b9a5 Binary files /dev/null and b/textures/mclcape.png differ diff --git a/textures/mclcape_body.png b/textures/mclcape_body.png new file mode 100644 index 000000000..9332de221 Binary files /dev/null and b/textures/mclcape_body.png differ diff --git a/textures/mclcape_elytra.png b/textures/mclcape_elytra.png new file mode 100644 index 000000000..405501456 Binary files /dev/null and b/textures/mclcape_elytra.png differ diff --git a/textures/mineclone2_icon.png b/textures/mineclone2_icon.png deleted file mode 100644 index d2a1554a6..000000000 Binary files a/textures/mineclone2_icon.png and /dev/null differ diff --git a/textures/mineclone2_logo.png b/textures/mineclone2_logo.png deleted file mode 100644 index d3e01733d..000000000 Binary files a/textures/mineclone2_logo.png and /dev/null differ diff --git a/textures/mobs_mc_llama_gray.png b/textures/mobs_mc_llama_gray.png index a4d2a7685..f590198f1 100644 Binary files a/textures/mobs_mc_llama_gray.png and b/textures/mobs_mc_llama_gray.png differ diff --git a/textures/mobs_mc_llama_white.png b/textures/mobs_mc_llama_white.png index 6eae4b41d..bab3a8cef 100644 Binary files a/textures/mobs_mc_llama_white.png and b/textures/mobs_mc_llama_white.png differ diff --git a/textures/mobs_mc_wither_projectile.png b/textures/mobs_mc_wither_projectile.png new file mode 100644 index 000000000..381a0ff8f Binary files /dev/null and b/textures/mobs_mc_wither_projectile.png differ diff --git a/textures/mobs_mc_wither_projectile_strong.png b/textures/mobs_mc_wither_projectile_strong.png new file mode 100644 index 000000000..4e4c38f73 Binary files /dev/null and b/textures/mobs_mc_wither_projectile_strong.png differ diff --git a/textures/mobs_mc_zombie.png b/textures/mobs_mc_zombie.png index ef85701e8..f4b9276ff 100644 Binary files a/textures/mobs_mc_zombie.png and b/textures/mobs_mc_zombie.png differ diff --git a/textures/mtcape.png b/textures/mtcape.png new file mode 100644 index 000000000..119e12f55 Binary files /dev/null and b/textures/mtcape.png differ diff --git a/textures/mtcape_body.png b/textures/mtcape_body.png new file mode 100644 index 000000000..3e36d3971 Binary files /dev/null and b/textures/mtcape_body.png differ diff --git a/textures/mtcape_elytra.png b/textures/mtcape_elytra.png new file mode 100644 index 000000000..441e22ec1 Binary files /dev/null and b/textures/mtcape_elytra.png differ diff --git a/textures/rib_armor_trim_smithing_template.png b/textures/rib_armor_trim_smithing_template.png new file mode 100644 index 000000000..92ab067ea Binary files /dev/null and b/textures/rib_armor_trim_smithing_template.png differ diff --git a/textures/rib_boots.png b/textures/rib_boots.png new file mode 100644 index 000000000..4549b077e Binary files /dev/null and b/textures/rib_boots.png differ diff --git a/textures/rib_chestplate.png b/textures/rib_chestplate.png new file mode 100644 index 000000000..a9a78e8b3 Binary files /dev/null and b/textures/rib_chestplate.png differ diff --git a/textures/rib_helmet.png b/textures/rib_helmet.png new file mode 100644 index 000000000..315c070c9 Binary files /dev/null and b/textures/rib_helmet.png differ diff --git a/textures/rib_leggings.png b/textures/rib_leggings.png new file mode 100644 index 000000000..bbff3fb8c Binary files /dev/null and b/textures/rib_leggings.png differ diff --git a/textures/sentry_armor_trim_smithing_template.png b/textures/sentry_armor_trim_smithing_template.png new file mode 100644 index 000000000..2e967e86c Binary files /dev/null and b/textures/sentry_armor_trim_smithing_template.png differ diff --git a/textures/sentry_boots.png b/textures/sentry_boots.png new file mode 100644 index 000000000..9296361bb Binary files /dev/null and b/textures/sentry_boots.png differ diff --git a/textures/sentry_chestplate.png b/textures/sentry_chestplate.png new file mode 100644 index 000000000..f09d70404 Binary files /dev/null and b/textures/sentry_chestplate.png differ diff --git a/textures/sentry_helmet.png b/textures/sentry_helmet.png new file mode 100644 index 000000000..4e2fa9937 Binary files /dev/null and b/textures/sentry_helmet.png differ diff --git a/textures/sentry_leggings.png b/textures/sentry_leggings.png new file mode 100644 index 000000000..80ca3a453 Binary files /dev/null and b/textures/sentry_leggings.png differ diff --git a/textures/silence_armor_trim_smithing_template.png b/textures/silence_armor_trim_smithing_template.png new file mode 100644 index 000000000..f2e26bd5d Binary files /dev/null and b/textures/silence_armor_trim_smithing_template.png differ diff --git a/textures/silence_boots.png b/textures/silence_boots.png new file mode 100644 index 000000000..ce751e8db Binary files /dev/null and b/textures/silence_boots.png differ diff --git a/textures/silence_chestplate.png b/textures/silence_chestplate.png new file mode 100644 index 000000000..b10986e68 Binary files /dev/null and b/textures/silence_chestplate.png differ diff --git a/textures/silence_helmet.png b/textures/silence_helmet.png new file mode 100644 index 000000000..1adfb6aff Binary files /dev/null and b/textures/silence_helmet.png differ diff --git a/textures/silence_leggings.png b/textures/silence_leggings.png new file mode 100644 index 000000000..83b18c856 Binary files /dev/null and b/textures/silence_leggings.png differ diff --git a/textures/slimecape.png b/textures/slimecape.png new file mode 100644 index 000000000..d6492723d Binary files /dev/null and b/textures/slimecape.png differ diff --git a/textures/slimecape_body.png b/textures/slimecape_body.png new file mode 100644 index 000000000..9b89d6a6c Binary files /dev/null and b/textures/slimecape_body.png differ diff --git a/textures/slimecape_elytra.png b/textures/slimecape_elytra.png new file mode 100644 index 000000000..f3b979a74 Binary files /dev/null and b/textures/slimecape_elytra.png differ diff --git a/textures/snout_armor_trim_smithing_template.png b/textures/snout_armor_trim_smithing_template.png new file mode 100644 index 000000000..35d413d5b Binary files /dev/null and b/textures/snout_armor_trim_smithing_template.png differ diff --git a/textures/snout_boots.png b/textures/snout_boots.png new file mode 100644 index 000000000..e863989bf Binary files /dev/null and b/textures/snout_boots.png differ diff --git a/textures/snout_chestplate.png b/textures/snout_chestplate.png new file mode 100644 index 000000000..6106a0e4d Binary files /dev/null and b/textures/snout_chestplate.png differ diff --git a/textures/snout_helmet.png b/textures/snout_helmet.png new file mode 100644 index 000000000..a25297dac Binary files /dev/null and b/textures/snout_helmet.png differ diff --git a/textures/snout_leggings.png b/textures/snout_leggings.png new file mode 100644 index 000000000..1ff74f4a3 Binary files /dev/null and b/textures/snout_leggings.png differ diff --git a/textures/spire_armor_trim_smithing_template.png b/textures/spire_armor_trim_smithing_template.png new file mode 100644 index 000000000..d51dc5b7e Binary files /dev/null and b/textures/spire_armor_trim_smithing_template.png differ diff --git a/textures/spire_boots.png b/textures/spire_boots.png new file mode 100644 index 000000000..a0f5d0c1d Binary files /dev/null and b/textures/spire_boots.png differ diff --git a/textures/spire_chestplate.png b/textures/spire_chestplate.png new file mode 100644 index 000000000..baafb6137 Binary files /dev/null and b/textures/spire_chestplate.png differ diff --git a/textures/spire_helmet.png b/textures/spire_helmet.png new file mode 100644 index 000000000..3f70baf8f Binary files /dev/null and b/textures/spire_helmet.png differ diff --git a/textures/spire_leggings.png b/textures/spire_leggings.png new file mode 100644 index 000000000..5e397d14a Binary files /dev/null and b/textures/spire_leggings.png differ diff --git a/textures/tide_armor_trim_smithing_template.png b/textures/tide_armor_trim_smithing_template.png new file mode 100644 index 000000000..cf456d279 Binary files /dev/null and b/textures/tide_armor_trim_smithing_template.png differ diff --git a/textures/tide_boots.png b/textures/tide_boots.png new file mode 100644 index 000000000..dc1930f49 Binary files /dev/null and b/textures/tide_boots.png differ diff --git a/textures/tide_chestplate.png b/textures/tide_chestplate.png new file mode 100644 index 000000000..ae5a219cc Binary files /dev/null and b/textures/tide_chestplate.png differ diff --git a/textures/tide_helmet.png b/textures/tide_helmet.png new file mode 100644 index 000000000..4e08461ca Binary files /dev/null and b/textures/tide_helmet.png differ diff --git a/textures/tide_leggings.png b/textures/tide_leggings.png new file mode 100644 index 000000000..8b9ec043f Binary files /dev/null and b/textures/tide_leggings.png differ diff --git a/textures/vex_armor_trim_smithing_template.png b/textures/vex_armor_trim_smithing_template.png new file mode 100644 index 000000000..ec077551b Binary files /dev/null and b/textures/vex_armor_trim_smithing_template.png differ diff --git a/textures/vex_boots.png b/textures/vex_boots.png new file mode 100644 index 000000000..2180fbe77 Binary files /dev/null and b/textures/vex_boots.png differ diff --git a/textures/vex_chestplate.png b/textures/vex_chestplate.png new file mode 100644 index 000000000..77ab1e0f6 Binary files /dev/null and b/textures/vex_chestplate.png differ diff --git a/textures/vex_helmet.png b/textures/vex_helmet.png new file mode 100644 index 000000000..613af3dec Binary files /dev/null and b/textures/vex_helmet.png differ diff --git a/textures/vex_leggings.png b/textures/vex_leggings.png new file mode 100644 index 000000000..d7e179a22 Binary files /dev/null and b/textures/vex_leggings.png differ diff --git a/textures/vl_hollow_logs_acaciatree.png b/textures/vl_hollow_logs_acaciatree.png new file mode 100644 index 000000000..f41412827 Binary files /dev/null and b/textures/vl_hollow_logs_acaciatree.png differ diff --git a/textures/vl_hollow_logs_birchtree.png b/textures/vl_hollow_logs_birchtree.png new file mode 100644 index 000000000..5ead6b211 Binary files /dev/null and b/textures/vl_hollow_logs_birchtree.png differ diff --git a/textures/vl_hollow_logs_cherrytree.png b/textures/vl_hollow_logs_cherrytree.png new file mode 100644 index 000000000..83da0e779 Binary files /dev/null and b/textures/vl_hollow_logs_cherrytree.png differ diff --git a/textures/vl_hollow_logs_crimson_hyphae.png b/textures/vl_hollow_logs_crimson_hyphae.png new file mode 100644 index 000000000..1ee1ec0f3 Binary files /dev/null and b/textures/vl_hollow_logs_crimson_hyphae.png differ diff --git a/textures/vl_hollow_logs_darktree.png b/textures/vl_hollow_logs_darktree.png new file mode 100644 index 000000000..0b3bfd79c Binary files /dev/null and b/textures/vl_hollow_logs_darktree.png differ diff --git a/textures/vl_hollow_logs_jungletree.png b/textures/vl_hollow_logs_jungletree.png new file mode 100644 index 000000000..d6dde6e4c Binary files /dev/null and b/textures/vl_hollow_logs_jungletree.png differ diff --git a/textures/vl_hollow_logs_mangrove_tree.png b/textures/vl_hollow_logs_mangrove_tree.png new file mode 100644 index 000000000..4a2a33db1 Binary files /dev/null and b/textures/vl_hollow_logs_mangrove_tree.png differ diff --git a/textures/vl_hollow_logs_sprucetree.png b/textures/vl_hollow_logs_sprucetree.png new file mode 100644 index 000000000..48b7e39fe Binary files /dev/null and b/textures/vl_hollow_logs_sprucetree.png differ diff --git a/textures/vl_hollow_logs_stripped_acaciatree.png b/textures/vl_hollow_logs_stripped_acaciatree.png new file mode 100644 index 000000000..b4047e2e6 Binary files /dev/null and b/textures/vl_hollow_logs_stripped_acaciatree.png differ diff --git a/textures/vl_hollow_logs_stripped_birchtree.png b/textures/vl_hollow_logs_stripped_birchtree.png new file mode 100644 index 000000000..e2fd7ac8a Binary files /dev/null and b/textures/vl_hollow_logs_stripped_birchtree.png differ diff --git a/textures/vl_hollow_logs_stripped_cherrytree.png b/textures/vl_hollow_logs_stripped_cherrytree.png new file mode 100644 index 000000000..50154931e Binary files /dev/null and b/textures/vl_hollow_logs_stripped_cherrytree.png differ diff --git a/textures/vl_hollow_logs_stripped_crimson_hyphae.png b/textures/vl_hollow_logs_stripped_crimson_hyphae.png new file mode 100644 index 000000000..9466797a9 Binary files /dev/null and b/textures/vl_hollow_logs_stripped_crimson_hyphae.png differ diff --git a/textures/vl_hollow_logs_stripped_darktree.png b/textures/vl_hollow_logs_stripped_darktree.png new file mode 100644 index 000000000..c8c5ed113 Binary files /dev/null and b/textures/vl_hollow_logs_stripped_darktree.png differ diff --git a/textures/vl_hollow_logs_stripped_jungletree.png b/textures/vl_hollow_logs_stripped_jungletree.png new file mode 100644 index 000000000..3d49d879c Binary files /dev/null and b/textures/vl_hollow_logs_stripped_jungletree.png differ diff --git a/textures/vl_hollow_logs_stripped_mangrove_tree.png b/textures/vl_hollow_logs_stripped_mangrove_tree.png new file mode 100644 index 000000000..232b41a8a Binary files /dev/null and b/textures/vl_hollow_logs_stripped_mangrove_tree.png differ diff --git a/textures/vl_hollow_logs_stripped_sprucetree.png b/textures/vl_hollow_logs_stripped_sprucetree.png new file mode 100644 index 000000000..b49d5280a Binary files /dev/null and b/textures/vl_hollow_logs_stripped_sprucetree.png differ diff --git a/textures/vl_hollow_logs_stripped_tree.png b/textures/vl_hollow_logs_stripped_tree.png new file mode 100644 index 000000000..81cc52d8b Binary files /dev/null and b/textures/vl_hollow_logs_stripped_tree.png differ diff --git a/textures/vl_hollow_logs_stripped_warped_hyphae.png b/textures/vl_hollow_logs_stripped_warped_hyphae.png new file mode 100644 index 000000000..fb3cce08b Binary files /dev/null and b/textures/vl_hollow_logs_stripped_warped_hyphae.png differ diff --git a/textures/vl_hollow_logs_tree.png b/textures/vl_hollow_logs_tree.png new file mode 100644 index 000000000..ddd6864e9 Binary files /dev/null and b/textures/vl_hollow_logs_tree.png differ diff --git a/textures/vl_hollow_logs_warped_hyphae.png b/textures/vl_hollow_logs_warped_hyphae.png new file mode 100644 index 000000000..c80930740 Binary files /dev/null and b/textures/vl_hollow_logs_warped_hyphae.png differ diff --git a/textures/vl_mobitems_aery_charge.png b/textures/vl_mobitems_aery_charge.png new file mode 100644 index 000000000..51608d922 Binary files /dev/null and b/textures/vl_mobitems_aery_charge.png differ diff --git a/textures/vl_mobitems_crystalline_drop.png b/textures/vl_mobitems_crystalline_drop.png new file mode 100644 index 000000000..42ecb6d6d Binary files /dev/null and b/textures/vl_mobitems_crystalline_drop.png differ diff --git a/textures/vl_mobitems_earthen_ash.png b/textures/vl_mobitems_earthen_ash.png new file mode 100644 index 000000000..63fd28bbf Binary files /dev/null and b/textures/vl_mobitems_earthen_ash.png differ diff --git a/textures/vl_mobitems_ice_crystal.png b/textures/vl_mobitems_ice_crystal.png new file mode 100644 index 000000000..a3138545f Binary files /dev/null and b/textures/vl_mobitems_ice_crystal.png differ diff --git a/textures/vl_mobitems_spectre_membrane.png b/textures/vl_mobitems_spectre_membrane.png new file mode 100644 index 000000000..0819e7532 Binary files /dev/null and b/textures/vl_mobitems_spectre_membrane.png differ diff --git a/textures/vl_mobs_rover.png b/textures/vl_mobs_rover.png new file mode 100644 index 000000000..6bda2ca0f Binary files /dev/null and b/textures/vl_mobs_rover.png differ diff --git a/textures/vl_mobs_rover_face.png b/textures/vl_mobs_rover_face.png new file mode 100644 index 000000000..d4b6bba9a Binary files /dev/null and b/textures/vl_mobs_rover_face.png differ diff --git a/textures/vl_mobs_rover_face_angry.png b/textures/vl_mobs_rover_face_angry.png new file mode 100644 index 000000000..a6ea6dd27 Binary files /dev/null and b/textures/vl_mobs_rover_face_angry.png differ diff --git a/textures/vl_mobs_stalker_overlay.png b/textures/vl_mobs_stalker_overlay.png new file mode 100644 index 000000000..9a9897665 Binary files /dev/null and b/textures/vl_mobs_stalker_overlay.png differ diff --git a/textures/vl_mobs_stalker_overlay_angry.png b/textures/vl_mobs_stalker_overlay_angry.png new file mode 100644 index 000000000..473ad7b7f Binary files /dev/null and b/textures/vl_mobs_stalker_overlay_angry.png differ diff --git a/textures/vl_stalker_default.png b/textures/vl_stalker_default.png new file mode 100644 index 000000000..fbffb4cdf Binary files /dev/null and b/textures/vl_stalker_default.png differ diff --git a/textures/vl_stalker_overloaded_aura.png b/textures/vl_stalker_overloaded_aura.png new file mode 100644 index 000000000..8deb059d2 Binary files /dev/null and b/textures/vl_stalker_overloaded_aura.png differ diff --git a/textures/vl_unknown.png b/textures/vl_unknown.png new file mode 100644 index 000000000..279a4cdb0 Binary files /dev/null and b/textures/vl_unknown.png differ diff --git a/textures/voxelibre_icon.png b/textures/voxelibre_icon.png new file mode 100644 index 000000000..433532678 Binary files /dev/null and b/textures/voxelibre_icon.png differ diff --git a/textures/voxelibre_logo.png b/textures/voxelibre_logo.png new file mode 100644 index 000000000..69aa42d5b Binary files /dev/null and b/textures/voxelibre_logo.png differ diff --git a/textures/ward_armor_trim_smithing_template.png b/textures/ward_armor_trim_smithing_template.png new file mode 100644 index 000000000..0cb227c9d Binary files /dev/null and b/textures/ward_armor_trim_smithing_template.png differ diff --git a/textures/ward_boots.png b/textures/ward_boots.png new file mode 100644 index 000000000..2918e54e5 Binary files /dev/null and b/textures/ward_boots.png differ diff --git a/textures/ward_chestplate.png b/textures/ward_chestplate.png new file mode 100644 index 000000000..5767435a0 Binary files /dev/null and b/textures/ward_chestplate.png differ diff --git a/textures/ward_helmet.png b/textures/ward_helmet.png new file mode 100644 index 000000000..02e57103c Binary files /dev/null and b/textures/ward_helmet.png differ diff --git a/textures/ward_leggings.png b/textures/ward_leggings.png new file mode 100644 index 000000000..b25ca08ef Binary files /dev/null and b/textures/ward_leggings.png differ diff --git a/textures/wayfinder_armor_trim_smithing_template.png b/textures/wayfinder_armor_trim_smithing_template.png new file mode 100644 index 000000000..40cc6781e Binary files /dev/null and b/textures/wayfinder_armor_trim_smithing_template.png differ diff --git a/textures/wayfinder_boots.png b/textures/wayfinder_boots.png new file mode 100644 index 000000000..219b88541 Binary files /dev/null and b/textures/wayfinder_boots.png differ diff --git a/textures/wayfinder_chestplate.png b/textures/wayfinder_chestplate.png new file mode 100644 index 000000000..edc41ceb2 Binary files /dev/null and b/textures/wayfinder_chestplate.png differ diff --git a/textures/wayfinder_helmet.png b/textures/wayfinder_helmet.png new file mode 100644 index 000000000..273becbb2 Binary files /dev/null and b/textures/wayfinder_helmet.png differ diff --git a/textures/wayfinder_leggings.png b/textures/wayfinder_leggings.png new file mode 100644 index 000000000..17ef46484 Binary files /dev/null and b/textures/wayfinder_leggings.png differ diff --git a/textures/wild_armor_trim_smithing_template.png b/textures/wild_armor_trim_smithing_template.png new file mode 100644 index 000000000..1d3ba516c Binary files /dev/null and b/textures/wild_armor_trim_smithing_template.png differ diff --git a/textures/wild_boots.png b/textures/wild_boots.png new file mode 100644 index 000000000..dc05d4ee3 Binary files /dev/null and b/textures/wild_boots.png differ diff --git a/textures/wild_chestplate.png b/textures/wild_chestplate.png new file mode 100644 index 000000000..6eca1628c Binary files /dev/null and b/textures/wild_chestplate.png differ diff --git a/textures/wild_helmet.png b/textures/wild_helmet.png new file mode 100644 index 000000000..866ef67de Binary files /dev/null and b/textures/wild_helmet.png differ diff --git a/textures/wild_leggings.png b/textures/wild_leggings.png new file mode 100644 index 000000000..f4657ab13 Binary files /dev/null and b/textures/wild_leggings.png differ diff --git a/tools/Conversion_Table.csv b/tools/Conversion_Table.csv index 9dc50dc7a..8c338c3c7 100644 --- a/tools/Conversion_Table.csv +++ b/tools/Conversion_Table.csv @@ -1,976 +1,1425 @@ -Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? -/assets/minecraft/textures/particle,particles.png,/mods/CORE/mcl_particles/textures,mcl_particles_bubble.png,0,16,8,8,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_hbarmor/textures,hbarmor_icon.png,34,9,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_hbarmor/textures,hbarmor_bgicon.png,16,9,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/hudbars/textures,hudbars_icon_health.png,52,0,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/hudbars/textures,hudbars_bgicon_health.png,16,0,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/hudbars/textures,hudbars_icon_breath.png,16,18,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_base_textures/textures,heart.png,52,0,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/HUD/mcl_base_textures/textures,bubble.png,16,18,9,9,0,0,y -/assets/minecraft/textures/items,bucket_empty.png,/mods/ITEMS/mcl_buckets/textures,bucket.png,,,,,,, -/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,bucket_water.png,,,,,,, -/assets/minecraft/textures/items,bucket_water.png,/mods/ITEMS/mcl_buckets/textures,bucket_river_water.png,,,,,,, -/assets/minecraft/textures/items,bucket_lava.png,/mods/ITEMS/mcl_buckets/textures,mcl_buckets_lava_bucket.png,,,,,,, -/assets/minecraft/textures/items,item_frame.png,/mods/ITEMS/mcl_itemframes/textures,mcl_itemframes_item_frame.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_base.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_base.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_top_damaged_0.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_top_damaged_0.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_top_damaged_1.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_top_damaged_1.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_top_damaged_2.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_top_damaged_2.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_base.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_side.png,,,,,,, -/assets/minecraft/textures/blocks,anvil_side.png,/mods/ITEMS/mcl_anvils/textures,mcl_anvils_anvil_side.png,,,,,,, -/assets/minecraft/textures/items,name_tag.png,/mods/ENTITIES/mcl_mobs/textures,mobs_nametag.png,,,,,,, -/assets/minecraft/textures/gui,icons.png,/mods/ENTITIES/mobs/textures,mobs_blood.png,16,0,9,9,0,0,y -/assets/minecraft/textures/blocks,itemframe_background.png,/mods/ITEMS/mcl_itemframes/textures,mcl_itemframes_itemframe_background.png,,,,,,, -/assets/minecraft/textures/items,bed.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_red.png,,,,,,, -/assets/minecraft/textures/items,acacia_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_acacia_boat.png,,,,,,, -/assets/minecraft/textures/items,oak_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_oak_boat.png,,,,,,, -/assets/minecraft/textures/items,spruce_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_spruce_boat.png,,,,,,, -/assets/minecraft/textures/items,dark_oak_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_dark_oak_boat.png,,,,,,, -/assets/minecraft/textures/items,jungle_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_jungle_boat.png,,,,,,, -/assets/minecraft/textures/items,birch_boat.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_birch_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_acacia.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_acacia_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_oak.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_oak_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_darkoak.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_dark_oak_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_spruce.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_spruce_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_birch.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_birch_boat.png,,,,,,, -/assets/minecraft/textures/entity/boat,boat_jungle.png,/mods/ENTITIES/mcl_boats/textures,mcl_boats_texture_jungle_boat.png,,,,,,, -/assets/minecraft/textures/items,book_normal.png,/mods/ITEMS/mcl_books/textures,default_book.png,,,,,,, -/assets/minecraft/textures/blocks,bookshelf.png,/mods/ITEMS/mcl_books/textures,default_bookshelf.png,,,,,,, -/assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_books/textures,mcl_books_bookshelf_top.png,,,,,,, -/assets/minecraft/textures/blocks,bookshelf_top.png,/mods/ITEMS/mcl_books/textures,mcl_books_bookshelf_top.png,,,,,,, -/assets/minecraft/textures/items,book_writable.png,/mods/ITEMS/mcl_books/textures,mcl_books_book_writable.png,,,,,,, -/assets/minecraft/textures/items,book_written.png,/mods/ITEMS/mcl_books/textures,mcl_books_book_written.png,,,,,,, -/assets/minecraft/textures/items,cake.png,/mods/ITEMS/mcl_cake/textures,cake.png,,,,,,, -/assets/minecraft/textures/blocks,cake_bottom.png,/mods/ITEMS/mcl_cake/textures,cake_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,cake_top.png,/mods/ITEMS/mcl_cake/textures,cake_top.png,,,,,,, -/assets/minecraft/textures/blocks,cake_side.png,/mods/ITEMS/mcl_cake/textures,cake_side.png,,,,,,, -/assets/minecraft/textures/blocks,cake_inner.png,/mods/ITEMS/mcl_cake/textures,cake_inner.png,,,,,,, -/assets/minecraft/textures/items,cauldron.png,/mods/ITEMS/mcl_cauldrons/textures,mcl_cauldrons_cauldron.png,,,,,,, -/assets/minecraft/textures/blocks,cauldron_bottom.png,/mods/ITEMS/mcl_cauldrons/textures,mcl_cauldrons_cauldron_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,cauldron_top.png,/mods/ITEMS/mcl_cauldrons/textures,mcl_cauldrons_cauldron_top.png,,,,,,, -/assets/minecraft/textures/blocks,cauldron_side.png,/mods/ITEMS/mcl_cauldrons/textures,mcl_cauldrons_cauldron_side.png,,,,,,, -/assets/minecraft/textures/blocks,cauldron_inner.png,/mods/ITEMS/mcl_cauldrons/textures,mcl_cauldrons_cauldron_inner.png,,,,,,, -/assets/minecraft/textures/blocks,cocoa_stage_0.png,/mods/ITEMS/mcl_cocoas/textures,mcl_cocoas_cocoa_stage_0.png,,,,,,,y -/assets/minecraft/textures/blocks,cocoa_stage_1.png,/mods/ITEMS/mcl_cocoas/textures,mcl_cocoas_cocoa_stage_1.png,,,,,,,y -/assets/minecraft/textures/blocks,cocoa_stage_2.png,/mods/ITEMS/mcl_cocoas/textures,mcl_cocoas_cocoa_stage_2.png,,,,,,,y -/assets/minecraft/textures/blocks,hardened_clay.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_black.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_black.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_blue.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_blue.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_brown.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_brown.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_cyan.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_gray.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_grey.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_green.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_green.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_light_blue.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_lime.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_lime.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_magenta.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_orange.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_orange.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_pink.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_pink.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_purple.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_purple.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_red.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_red.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_silver.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_silver.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_white.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_white.png,,,,,,, -/assets/minecraft/textures/blocks,hardened_clay_stained_yellow.png,/mods/ITEMS/mcl_colorblocks/textures,hardened_clay_stained_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_black.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_black.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_blue.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_brown.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_brown.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_cyan.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_gray.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_grey.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_green.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_green.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_light_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_lime.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_lime.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_magenta.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_orange.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_orange.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_pink.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_pink.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_purple.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_purple.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_red.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_red.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_silver.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_silver.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_white.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_white.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_yellow.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_black.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_black.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_blue.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_brown.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_brown.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_cyan.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_gray.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_grey.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_green.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_green.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_light_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_lime.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_lime.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_magenta.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_orange.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_orange.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_pink.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_pink.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_purple.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_purple.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_red.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_red.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_silver.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_silver.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_white.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_white.png,,,,,,, -/assets/minecraft/textures/blocks,concrete_powder_yellow.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_concrete_powder_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_black.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_black.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_brown.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_brown.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_cyan.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_gray.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_grey.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_green.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_green.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_light_blue.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_lime.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_lime.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_magenta.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_orange.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_orange.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_pink.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_pink.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_purple.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_purple.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_red.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_red.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_silver.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_silver.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_white.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_white.png,,,,,,, -/assets/minecraft/textures/blocks,glazed_terracotta_yellow.png,/mods/ITEMS/mcl_colorblocks/textures,mcl_colorblocks_glazed_terracotta_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_oak.png,/mods/ITEMS/mcl_core/textures,default_sapling.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_acacia.png,/mods/ITEMS/mcl_core/textures,default_acacia_sapling.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_spruce.png,/mods/ITEMS/mcl_core/textures,mcl_core_sapling_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_jungle.png,/mods/ITEMS/mcl_core/textures,default_junglesapling.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_roofed_oak.png,/mods/ITEMS/mcl_core/textures,mcl_core_sapling_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,sapling_birch.png,/mods/ITEMS/mcl_core/textures,mcl_core_sapling_birch.png,,,,,,, -/assets/minecraft/textures/items,apple.png,/mods/ITEMS/mcl_core/textures,default_apple.png,,,,,,, -/assets/minecraft/textures/items,apple_golden.png,/mods/ITEMS/mcl_core/textures,mcl_core_apple_golden.png,,,,,,, -/assets/minecraft/textures/blocks,brick.png,/mods/ITEMS/mcl_core/textures,default_brick.png,,,,,,, -/assets/minecraft/textures/blocks,cactus_side.png,/mods/ITEMS/mcl_core/textures,mcl_core_cactus_side.png,,,,,,, -/assets/minecraft/textures/blocks,cactus_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_cactus_top.png,,,,,,, -/assets/minecraft/textures/blocks,cactus_bottom.png,/mods/ITEMS/mcl_core/textures,mcl_core_cactus_bottom.png,,,,,,, -/assets/minecraft/textures/items,brick.png,/mods/ITEMS/mcl_core/textures,default_clay_brick.png,,,,,,, -/assets/minecraft/textures/items,clay_ball.png,/mods/ITEMS/mcl_core/textures,default_clay_lump.png,,,,,,, -/assets/minecraft/textures/blocks,clay.png,/mods/ITEMS/mcl_core/textures,default_clay.png,,,,,,, -/assets/minecraft/textures/blocks,coal_block.png,/mods/ITEMS/mcl_core/textures,default_coal_block.png,,,,,,, -/assets/minecraft/textures/items,coal.png,/mods/ITEMS/mcl_core/textures,default_coal_lump.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone.png,/mods/ITEMS/mcl_core/textures,default_cobble.png,,,,,,, -/assets/minecraft/textures/blocks,diamond_block.png,/mods/ITEMS/mcl_core/textures,default_diamond_block.png,,,,,,, -/assets/minecraft/textures/items,diamond.png,/mods/ITEMS/mcl_core/textures,default_diamond.png,,,,,,, -/assets/minecraft/textures/blocks,dirt.png,/mods/ITEMS/mcl_core/textures,default_dirt.png,,,,,,, -/assets/minecraft/textures/blocks,deadbush.png,/mods/ITEMS/mcl_core/textures,default_dry_shrub.png,,,,,,, -/assets/minecraft/textures/blocks,log_acacia.png,/mods/ITEMS/mcl_core/textures,default_acacia_tree.png,,,,,,, -/assets/minecraft/textures/blocks,log_acacia_top.png,/mods/ITEMS/mcl_core/textures,default_acacia_tree_top.png,,,,,,, -/assets/minecraft/textures/blocks,planks_acacia.png,/mods/ITEMS/mcl_core/textures,default_acacia_wood.png,,,,,,, -/assets/minecraft/textures/items,flint.png,/mods/ITEMS/mcl_core/textures,default_flint.png,,,,,,, -/assets/minecraft/textures/blocks,glass.png,/mods/ITEMS/mcl_core/textures,default_glass.png,,,,,,, -/assets/minecraft/textures/blocks,glass_black.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_black.png,,,,,,, -/assets/minecraft/textures/blocks,glass_blue.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glass_brown.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_brown.png,,,,,,, -/assets/minecraft/textures/blocks,glass_cyan.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,glass_gray.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_gray.png,,,,,,, -/assets/minecraft/textures/blocks,glass_green.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_green.png,,,,,,, -/assets/minecraft/textures/blocks,glass_light_blue.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glass_lime.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_lime.png,,,,,,, -/assets/minecraft/textures/blocks,glass_magenta.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,glass_orange.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_orange.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pink.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_pink.png,,,,,,, -/assets/minecraft/textures/blocks,glass_purple.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_purple.png,,,,,,, -/assets/minecraft/textures/blocks,glass_red.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_red.png,,,,,,, -/assets/minecraft/textures/blocks,glass_silver.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_silver.png,,,,,,, -/assets/minecraft/textures/blocks,glass_white.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_white.png,,,,,,, -/assets/minecraft/textures/blocks,glass_yellow.png,/mods/ITEMS/mcl_core/textures,mcl_core_glass_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,gold_block.png,/mods/ITEMS/mcl_core/textures,default_gold_block.png,,,,,,, -/assets/minecraft/textures/blocks,gold_block.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_gold_block_slab.png,,,,,,, -/assets/minecraft/textures/items,gold_ingot.png,/mods/ITEMS/mcl_core/textures,default_gold_ingot.png,,,,,,, -/assets/minecraft/textures/blocks,grass_side.png,/mods/ITEMS/mcl_core/textures,default_grass_side.png,,,,,,, -/assets/minecraft/textures/blocks,gravel.png,/mods/ITEMS/mcl_core/textures,default_gravel.png,,,,,,, -/assets/minecraft/textures/blocks,ice.png,/mods/ITEMS/mcl_core/textures,default_ice.png,,,,,,, -/assets/minecraft/textures/blocks,log_jungle.png,/mods/ITEMS/mcl_core/textures,default_jungletree.png,,,,,,, -/assets/minecraft/textures/blocks,log_jungle_top.png,/mods/ITEMS/mcl_core/textures,default_jungletree_top.png,,,,,,, -/assets/minecraft/textures/blocks,planks_jungle.png,/mods/ITEMS/mcl_core/textures,default_junglewood.png,,,,,,, -/assets/minecraft/textures/blocks,ladder.png,/mods/ITEMS/mcl_core/textures,default_ladder.png,,,,,,, -/assets/minecraft/textures/blocks,lava_still.png,/mods/ITEMS/mcl_core/textures,default_lava_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,lava_flow.png,/mods/ITEMS/mcl_core/textures,default_lava_flowing_animated.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone_mossy.png,/mods/ITEMS/mcl_core/textures,default_mossycobble.png,,,,,,, -/assets/minecraft/textures/blocks,obsidian.png,/mods/ITEMS/mcl_core/textures,default_obsidian.png,,,,,,, -/assets/minecraft/textures/items,paper.png,/mods/ITEMS/mcl_core/textures,default_paper.png,,,,,,, -/assets/minecraft/textures/blocks,reeds.png,/mods/ITEMS/mcl_core/textures,mcl_core_papyrus.png,,,,,,, -/assets/minecraft/textures/blocks,sand.png,/mods/ITEMS/mcl_core/textures,default_sand.png,,,,,,, -/assets/minecraft/textures/blocks,snow.png,/mods/ITEMS/mcl_core/textures,default_snow.png,,,,,,, -/assets/minecraft/textures/blocks,iron_block.png,/mods/ITEMS/mcl_core/textures,default_steel_block.png,,,,,,, -/assets/minecraft/textures/blocks,iron_block.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_iron_block_slab.png,,,,,,, -/assets/minecraft/textures/items,iron_ingot.png,/mods/ITEMS/mcl_core/textures,default_steel_ingot.png,,,,,,, -/assets/minecraft/textures/items,stick.png,/mods/ITEMS/mcl_core/textures,default_stick.png,,,,,,, -/assets/minecraft/textures/blocks,stonebrick.png,/mods/ITEMS/mcl_core/textures,default_stone_brick.png,,,,,,, -/assets/minecraft/textures/blocks,stone.png,/mods/ITEMS/mcl_core/textures,default_stone.png,,,,,,, -/assets/minecraft/textures/blocks,log_oak.png,/mods/ITEMS/mcl_core/textures,default_tree.png,,,,,,, -/assets/minecraft/textures/blocks,log_oak_top.png,/mods/ITEMS/mcl_core/textures,default_tree_top.png,,,,,,, -/assets/minecraft/textures/blocks,water_still.png,/mods/ITEMS/mcl_core/textures,default_water_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_flow.png,/mods/ITEMS/mcl_core/textures,default_water_flowing_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_still.png,/mods/ITEMS/mcl_core/textures,default_river_water_source_animated.png,,,,,,, -/assets/minecraft/textures/blocks,water_flow.png,/mods/ITEMS/mcl_core/textures,default_river_water_flowing_animated.png,,,,,,, -/assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_core/textures,default_wood.png,,,,,,, -/assets/minecraft/textures/blocks,stone_andesite.png,/mods/ITEMS/mcl_core/textures,mcl_core_andesite.png,,,,,,, -/assets/minecraft/textures/blocks,stone_andesite_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_andesite_smooth.png,,,,,,, -/assets/minecraft/textures/blocks,stone_andesite_smooth.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_andesite_smooth_slab.png,,,,,,, -/assets/minecraft/textures/items,barrier.png,/mods/ITEMS/mcl_core/textures,mcl_core_barrier.png,,,,,,, -/assets/minecraft/textures/blocks,bedrock.png,/mods/ITEMS/mcl_core/textures,mcl_core_bedrock.png,,,,,,, -/assets/minecraft/textures/blocks,bone_block_side.png,/mods/ITEMS/mcl_core/textures,mcl_core_bone_block_side.png,,,,,,, -/assets/minecraft/textures/blocks,bone_block_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_bone_block_top.png,,,,,,, -/assets/minecraft/textures/items,bowl.png,/mods/ITEMS/mcl_core/textures,mcl_core_bowl.png,,,,,,, -/assets/minecraft/textures/blocks,cactus_bottom.png,/mods/ITEMS/mcl_core/textures,mcl_core_cactus_bottom.png,,,,,,, -/assets/minecraft/textures/items,charcoal.png,/mods/ITEMS/mcl_core/textures,mcl_core_charcoal.png,,,,,,, -/assets/minecraft/textures/blocks,coal_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_coal_ore.png,,,,,,, -/assets/minecraft/textures/blocks,coarse_dirt.png,/mods/ITEMS/mcl_core/textures,mcl_core_coarse_dirt.png,,,,,,, -/assets/minecraft/textures/blocks,diamond_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_diamond_ore.png,,,,,,, -/assets/minecraft/textures/blocks,stone_diorite.png,/mods/ITEMS/mcl_core/textures,mcl_core_diorite.png,,,,,,, -/assets/minecraft/textures/blocks,stone_diorite_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_diorite_smooth.png,,,,,,, -/assets/minecraft/textures/blocks,stone_diorite_smooth.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_diorite_smooth_slab.png,,,,,,, -/assets/minecraft/textures/blocks,dirt_podzol_side.png,/mods/ITEMS/mcl_core/textures,mcl_core_dirt_podzol_side.png,,,,,,, -/assets/minecraft/textures/blocks,dirt_podzol_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_dirt_podzol_top.png,,,,,,, -/assets/minecraft/textures/blocks,emerald_block.png,/mods/ITEMS/mcl_core/textures,mcl_core_emerald_block.png,,,,,,, -/assets/minecraft/textures/blocks,emerald_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_emerald_ore.png,,,,,,, -/assets/minecraft/textures/items,emerald.png,/mods/ITEMS/mcl_core/textures,mcl_core_emerald.png,,,,,,, -/assets/minecraft/textures/blocks,frosted_ice_0.png,/mods/ITEMS/mcl_core/textures,mcl_core_frosted_ice_0.png,,,,,,, -/assets/minecraft/textures/blocks,frosted_ice_1.png,/mods/ITEMS/mcl_core/textures,mcl_core_frosted_ice_1.png,,,,,,, -/assets/minecraft/textures/blocks,frosted_ice_2.png,/mods/ITEMS/mcl_core/textures,mcl_core_frosted_ice_2.png,,,,,,, -/assets/minecraft/textures/blocks,frosted_ice_3.png,/mods/ITEMS/mcl_core/textures,mcl_core_frosted_ice_3.png,,,,,,, -/assets/minecraft/textures/items,gold_nugget.png,/mods/ITEMS/mcl_core/textures,mcl_core_gold_nugget.png,,,,,,, -/assets/minecraft/textures/blocks,gold_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_gold_ore.png,,,,,,, -/assets/minecraft/textures/blocks,stone_granite.png,/mods/ITEMS/mcl_core/textures,mcl_core_granite.png,,,,,,, -/assets/minecraft/textures/blocks,stone_granite_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_granite_smooth.png,,,,,,, -/assets/minecraft/textures/blocks,stone_granite_smooth.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_granite_smooth_slab.png,,,,,,, -/assets/minecraft/textures/blocks,grass_path_side.png,/mods/ITEMS/mcl_core/textures,mcl_core_grass_path_side.png,,,,,,, -/assets/minecraft/textures/blocks,grass_path_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_grass_path_top.png,,,,,,, -/assets/minecraft/textures/blocks,grass_side_snowed.png,/mods/ITEMS/mcl_core/textures,mcl_core_grass_side_snowed.png,,,,,,, -/assets/minecraft/textures/blocks,ice_packed.png,/mods/ITEMS/mcl_core/textures,mcl_core_ice_packed.png,,,,,,, -/assets/minecraft/textures/items,iron_nugget.png,/mods/ITEMS/mcl_core/textures,mcl_core_iron_nugget.png,,,,,,, -/assets/minecraft/textures/blocks,iron_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_iron_ore.png,,,,,,, -/assets/minecraft/textures/blocks,lapis_block.png,/mods/ITEMS/mcl_core/textures,mcl_core_lapis_block.png,,,,,,, -/assets/minecraft/textures/blocks,lapis_block.png,/mods/ITEMS/mclx_stairs/textures,mcl_stairs_lapis_block_slab.png,,,,,,, -/assets/minecraft/textures/blocks,lapis_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_lapis_ore.png,,,,,,, -/assets/minecraft/textures/blocks,log_big_oak.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,log_big_oak_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_big_oak_top.png,,,,,,, -/assets/minecraft/textures/blocks,log_birch.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_birch.png,,,,,,, -/assets/minecraft/textures/blocks,log_birch_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_birch_top.png,,,,,,, -/assets/minecraft/textures/blocks,log_spruce.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,log_spruce_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_log_spruce_top.png,,,,,,, -/assets/minecraft/textures/blocks,mycelium_side.png,/mods/ITEMS/mcl_core/textures,mcl_core_mycelium_side.png,,,,,,, -/assets/minecraft/textures/blocks,mycelium_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_mycelium_top.png,,,,,,, -/assets/minecraft/textures/blocks,planks_big_oak.png,/mods/ITEMS/mcl_core/textures,mcl_core_planks_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,planks_birch.png,/mods/ITEMS/mcl_core/textures,mcl_core_planks_birch.png,,,,,,, -/assets/minecraft/textures/blocks,planks_spruce.png,/mods/ITEMS/mcl_core/textures,mcl_core_planks_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,red_sand.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sand.png,,,,,,, -/assets/minecraft/textures/blocks,red_sandstone_bottom.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sandstone_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,red_sandstone_carved.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sandstone_carved.png,,,,,,, -/assets/minecraft/textures/blocks,red_sandstone_normal.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sandstone_normal.png,,,,,,, -/assets/minecraft/textures/blocks,red_sandstone_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sandstone_smooth.png,,,,,,, -/assets/minecraft/textures/blocks,red_sandstone_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_red_sandstone_top.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_ore.png,/mods/ITEMS/mcl_core/textures,mcl_core_redstone_ore.png,,,,,,, -/assets/minecraft/textures/items,reeds.png,/mods/ITEMS/mcl_core/textures,mcl_core_reeds.png,,,,,,, -/assets/minecraft/textures/blocks,sandstone_bottom.png,/mods/ITEMS/mcl_core/textures,mcl_core_sandstone_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,sandstone_carved.png,/mods/ITEMS/mcl_core/textures,mcl_core_sandstone_carved.png,,,,,,, -/assets/minecraft/textures/blocks,sandstone_normal.png,/mods/ITEMS/mcl_core/textures,mcl_core_sandstone_normal.png,,,,,,, -/assets/minecraft/textures/blocks,sandstone_smooth.png,/mods/ITEMS/mcl_core/textures,mcl_core_sandstone_smooth.png,,,,,,, -/assets/minecraft/textures/blocks,sandstone_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_sandstone_top.png,,,,,,, -/assets/minecraft/textures/blocks,slime.png,/mods/ITEMS/mcl_core/textures,mcl_core_slime.png,,,,,,, -/assets/minecraft/textures/blocks,stonebrick_carved.png,/mods/ITEMS/mcl_core/textures,mcl_core_stonebrick_carved.png,,,,,,, -/assets/minecraft/textures/blocks,stonebrick_cracked.png,/mods/ITEMS/mcl_core/textures,mcl_core_stonebrick_cracked.png,,,,,,, -/assets/minecraft/textures/blocks,stonebrick_mossy.png,/mods/ITEMS/mcl_core/textures,mcl_core_stonebrick_mossy.png,,,,,,, -/assets/minecraft/textures/items,sugar.png,/mods/ITEMS/mcl_core/textures,mcl_core_sugar.png,,,,,,, -/assets/minecraft/textures/blocks,web.png,/mods/ITEMS/mcl_core/textures,mcl_core_web.png,,,,,,, -/assets/minecraft/textures/blocks,crafting_table_front.png,/mods/ITEMS/mcl_crafting_table/textures,crafting_workbench_front.png,,,,,,, -/assets/minecraft/textures/blocks,crafting_table_side.png,/mods/ITEMS/mcl_crafting_table/textures,crafting_workbench_side.png,,,,,,, -/assets/minecraft/textures/blocks,crafting_table_top.png,/mods/ITEMS/mcl_crafting_table/textures,crafting_workbench_top.png,,,,,,, -/assets/minecraft/textures/blocks,door_acacia_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_acacia_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_acacia_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_acacia_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_acacia_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_acacia_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_acacia_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_acacia_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_birch_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_birch_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_birch_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_birch_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_birch_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_birch_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_birch_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_birch_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_dark_oak_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_dark_oak_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_dark_oak_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_dark_oak_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_dark_oak_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_dark_oak_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_dark_oak_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_dark_oak_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_iron_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_iron_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_iron_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_iron_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_iron_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_iron_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_iron_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_iron_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_jungle_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_jungle_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_jungle_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_jungle_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_jungle_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_jungle_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_jungle_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_jungle_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_spruce_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_spruce_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_spruce_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_spruce_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_spruce_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_spruce_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_spruce_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_spruce_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_wood_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_wood_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_wood_lower.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_wood_side_lower.png,,,,,,, -/assets/minecraft/textures/blocks,door_wood_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_wood_upper.png,,,,,,, -/assets/minecraft/textures/blocks,door_wood_upper.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_wood_side_upper.png,,,,,,, -/assets/minecraft/textures/blocks,trapdoor.png,/mods/ITEMS/mcl_doors/textures,doors_trapdoor.png,,,,,,, -/assets/minecraft/textures/blocks,trapdoor.png,/mods/ITEMS/mcl_doors/textures,doors_trapdoor_side.png,,,,,,, -/assets/minecraft/textures/blocks,iron_trapdoor.png,/mods/ITEMS/mcl_doors/textures,doors_trapdoor_steel.png,,,,,,, -/assets/minecraft/textures/blocks,iron_trapdoor.png,/mods/ITEMS/mcl_doors/textures,doors_trapdoor_steel_side.png,,,,,,, -/assets/minecraft/textures/items,door_acacia.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_acacia.png,,,,,,, -/assets/minecraft/textures/items,door_birch.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_birch.png,,,,,,, -/assets/minecraft/textures/items,door_dark_oak.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_dark_oak.png,,,,,,, -/assets/minecraft/textures/items,door_jungle.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_jungle.png,,,,,,, -/assets/minecraft/textures/items,door_spruce.png,/mods/ITEMS/mcl_doors/textures,mcl_doors_door_spruce.png,,,,,,, -/assets/minecraft/textures/items,door_wood.png,/mods/ITEMS/mcl_doors/textures,doors_item_wood.png,,,,,,, -/assets/minecraft/textures/items,door_iron.png,/mods/ITEMS/mcl_doors/textures,doors_item_steel.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_black.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_black.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_blue.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_blue.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_brown.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_brown.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_cyan.png,/mods/ITEMS/mcl_dye/textures,dye_cyan.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_gray.png,/mods/ITEMS/mcl_dye/textures,dye_dark_grey.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_green.png,/mods/ITEMS/mcl_dye/textures,dye_dark_green.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_light_blue.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_light_blue.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_lime.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_lime.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_magenta.png,/mods/ITEMS/mcl_dye/textures,dye_magenta.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_orange.png,/mods/ITEMS/mcl_dye/textures,dye_orange.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_pink.png,/mods/ITEMS/mcl_dye/textures,dye_pink.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_purple.png,/mods/ITEMS/mcl_dye/textures,dye_violet.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_red.png,/mods/ITEMS/mcl_dye/textures,dye_red.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_silver.png,/mods/ITEMS/mcl_dye/textures,dye_grey.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_white.png,/mods/ITEMS/mcl_dye/textures,mcl_dye_white.png,,,,,,, -/assets/minecraft/textures/items,dye_powder_yellow.png,/mods/ITEMS/mcl_dye/textures,dye_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,chorus_flower_dead.png,/mods/ITEMS/mcl_end/textures,mcl_end_chorus_flower_dead.png,,,,,,, -/assets/minecraft/textures/blocks,chorus_flower.png,/mods/ITEMS/mcl_end/textures,mcl_end_chorus_flower.png,,,,,,, -/assets/minecraft/textures/items,chorus_fruit.png,/mods/ITEMS/mcl_end/textures,mcl_end_chorus_fruit.png,,,,,,, -/assets/minecraft/textures/items,chorus_fruit_popped.png,/mods/ITEMS/mcl_end/textures,mcl_end_chorus_fruit_popped.png,,,,,,, -/assets/minecraft/textures/blocks,chorus_plant.png,/mods/ITEMS/mcl_end/textures,mcl_end_chorus_plant.png,,,,,,, -/assets/minecraft/textures/blocks,dragon_egg.png,/mods/ITEMS/mcl_end/textures,mcl_end_dragon_egg.png,,,,,,, -/assets/minecraft/textures/blocks,end_bricks.png,/mods/ITEMS/mcl_end/textures,mcl_end_end_bricks.png,,,,,,, -/assets/minecraft/textures/items,ender_eye.png,/mods/ITEMS/mcl_end/textures,mcl_end_ender_eye.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_eye.png,/mods/ITEMS/mcl_end/textures,mcl_end_endframe_eye.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_side.png,/mods/ITEMS/mcl_end/textures,mcl_end_endframe_side.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_top.png,/mods/ITEMS/mcl_end/textures,mcl_end_endframe_top.png,,,,,,, -/assets/minecraft/textures/blocks,end_stone.png,/mods/ITEMS/mcl_end/textures,mcl_end_end_stone.png,,,,,,, -/assets/minecraft/textures/items,end_crystal.png,/mods/ITEMS/mcl_end/textures,mcl_end_crystal_item.png,,,,,,, -/assets/minecraft/textures/entity/endercrystal,endercrystal.png,/mods/ITEMS/mcl_end/textures,mcl_end_crystal.png,,,,,,, -/assets/minecraft/textures/blocks,purpur_block.png,/mods/ITEMS/mcl_end/textures,mcl_end_purpur_block.png,,,,,,, -/assets/minecraft/textures/blocks,purpur_pillar.png,/mods/ITEMS/mcl_end/textures,mcl_end_purpur_pillar.png,,,,,,, -/assets/minecraft/textures/blocks,purpur_pillar_top.png,/mods/ITEMS/mcl_end/textures,mcl_end_purpur_pillar_top.png,,,,,,, -/assets/minecraft/textures/blocks,potatoes_stage_0.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_potatoes_stage_0.png,,,,,,, -/assets/minecraft/textures/blocks,potatoes_stage_1.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_potatoes_stage_1.png,,,,,,, -/assets/minecraft/textures/blocks,potatoes_stage_2.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_potatoes_stage_2.png,,,,,,, -/assets/minecraft/textures/blocks,potatoes_stage_3.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_potatoes_stage_3.png,,,,,,, -/assets/minecraft/textures/items,pumpkin_pie.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_pumpkin_pie.png,,,,,,, -/assets/minecraft/textures/items,bread.png,/mods/ITEMS/mcl_farming/textures,farming_bread.png,,,,,,, -/assets/minecraft/textures/blocks,carrots_stage_0.png,/mods/ITEMS/mcl_farming/textures,farming_carrot_1.png,,,,,,, -/assets/minecraft/textures/blocks,carrots_stage_1.png,/mods/ITEMS/mcl_farming/textures,farming_carrot_2.png,,,,,,, -/assets/minecraft/textures/blocks,carrots_stage_2.png,/mods/ITEMS/mcl_farming/textures,farming_carrot_3.png,,,,,,, -/assets/minecraft/textures/blocks,carrots_stage_3.png,/mods/ITEMS/mcl_farming/textures,farming_carrot_4.png,,,,,,, -/assets/minecraft/textures/items,carrot_golden.png,/mods/ITEMS/mcl_farming/textures,farming_carrot_gold.png,,,,,,, -/assets/minecraft/textures/items,carrot.png,/mods/ITEMS/mcl_farming/textures,farming_carrot.png,,,,,,, -/assets/minecraft/textures/items,cookie.png,/mods/ITEMS/mcl_farming/textures,farming_cookie.png,,,,,,, -/assets/minecraft/textures/items,melon.png,/mods/ITEMS/mcl_farming/textures,farming_melon.png,,,,,,, -/assets/minecraft/textures/items,seeds_melon.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_melon_seeds.png,,,,,,, -/assets/minecraft/textures/blocks,melon_side.png,/mods/ITEMS/mcl_farming/textures,farming_melon_side.png,,,,,,, -/assets/minecraft/textures/blocks,melon_top.png,/mods/ITEMS/mcl_farming/textures,farming_melon_top.png,,,,,,, -/assets/minecraft/textures/items,potato_baked.png,/mods/ITEMS/mcl_farming/textures,farming_potato_baked.png,,,,,,, -/assets/minecraft/textures/items,potato.png,/mods/ITEMS/mcl_farming/textures,farming_potato.png,,,,,,, -/assets/minecraft/textures/items,potato_poisonous.png,/mods/ITEMS/mcl_farming/textures,farming_potato_poison.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_face_on.png,/mods/ITEMS/mcl_farming/textures,farming_pumpkin_face_light.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_face_off.png,/mods/ITEMS/mcl_farming/textures,farming_pumpkin_face.png,,,,,,, -/assets/minecraft/textures/items,seeds_pumpkin.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_pumpkin_seeds.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_side.png,/mods/ITEMS/mcl_farming/textures,farming_pumpkin_side.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_top.png,/mods/ITEMS/mcl_farming/textures,farming_pumpkin_top.png,,,,,,, -/assets/minecraft/textures/blocks,farmland_dry.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_farmland_dry.png,,,,,,, -/assets/minecraft/textures/blocks,farmland_wet.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_farmland_wet.png,,,,,,, -/assets/minecraft/textures/items,diamond_hoe.png,/mods/ITEMS/mcl_farming/textures,farming_tool_diamondhoe.png,,,,,,, -/assets/minecraft/textures/items,gold_hoe.png,/mods/ITEMS/mcl_farming/textures,farming_tool_goldhoe.png,,,,,,, -/assets/minecraft/textures/items,iron_hoe.png,/mods/ITEMS/mcl_farming/textures,farming_tool_steelhoe.png,,,,,,, -/assets/minecraft/textures/items,stone_hoe.png,/mods/ITEMS/mcl_farming/textures,farming_tool_stonehoe.png,,,,,,, -/assets/minecraft/textures/items,wood_hoe.png,/mods/ITEMS/mcl_farming/textures,farming_tool_woodhoe.png,,,,,,, -/assets/minecraft/textures/items,wheat.png,/mods/ITEMS/mcl_farming/textures,farming_wheat_harvested.png,,,,,,, -/assets/minecraft/textures/items,seeds_wheat.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_seeds.png,,,,,,, -/assets/minecraft/textures/blocks,beetroots_stage_0.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_0.png,,,,,,, -/assets/minecraft/textures/blocks,beetroots_stage_1.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_1.png,,,,,,, -/assets/minecraft/textures/blocks,beetroots_stage_2.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_2.png,,,,,,, -/assets/minecraft/textures/blocks,beetroots_stage_3.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_3.png,,,,,,, -/assets/minecraft/textures/items,beetroot.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot.png,,,,,,, -/assets/minecraft/textures/items,beetroot_seeds.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_seeds.png,,,,,,, -/assets/minecraft/textures/items,beetroot_soup.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_beetroot_soup.png,,,,,,, -/assets/minecraft/textures/blocks,hay_block_side.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_hayblock_side.png,,,,,,, -/assets/minecraft/textures/blocks,hay_block_top.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_hayblock_top.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_0.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_0.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_1.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_1.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_2.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_2.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_3.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_3.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_4.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_4.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_5.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_5.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_6.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_6.png,,,,,,, -/assets/minecraft/textures/blocks,wheat_stage_7.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_wheat_stage_7.png,,,,,,, -/assets/minecraft/textures/blocks,fire_layer_0.png,/mods/ITEMS/mcl_fire/textures,fire_basic_flame_animated.png,,,,,,, -/assets/minecraft/textures/blocks,fire_layer_0.png,/mods/ITEMS/mcl_fire/textures,mcl_burning_entity_flame_animated.png,,,,,,, -/assets/minecraft/textures/blocks,fire_layer_0.png,/mods/ITEMS/mcl_fire/textures,mcl_burning_hud_flame_animated.png,,,,,,, -/assets/minecraft/textures/blocks,fire_layer_0.png,/mods/ITEMS/mcl_fire/textures,fire_basic_flame.png,0,0,16,16,0,0,y -/assets/minecraft/textures/items,fireball.png,/mods/ITEMS/mcl_fire/textures,mcl_fire_fire_charge.png,,,,,,, -/assets/minecraft/textures/items,flint_and_steel.png,/mods/ITEMS/mcl_fire/textures,mcl_fire_flint_and_steel.png,,,,,,, -/assets/minecraft/textures/items,fish_clownfish_raw.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_clownfish_raw.png,,,,,,, -/assets/minecraft/textures/items,fish_cod_cooked.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_fish_cooked.png,,,,,,, -/assets/minecraft/textures/items,fishing_rod_uncast.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_fishing_rod.png,,,,,,, -/assets/minecraft/textures/items,fish_cod_raw.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_fish_raw.png,,,,,,, -/assets/minecraft/textures/items,fish_pufferfish_raw.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_pufferfish_raw.png,,,,,,, -/assets/minecraft/textures/items,fish_salmon_cooked.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_salmon_cooked.png,,,,,,, -/assets/minecraft/textures/items,fish_salmon_raw.png,/mods/ITEMS/mcl_fishing/textures,mcl_fishing_salmon_raw.png,,,,,,, -/assets/minecraft/textures/blocks,flower_allium.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_allium.png,,,,,,, -/assets/minecraft/textures/blocks,flower_houstonia.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_azure_bluet.png,,,,,,, -/assets/minecraft/textures/blocks,flower_blue_orchid.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_blue_orchid.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_paeonia_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_paeonia_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_paeonia_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_paeonia_top.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_rose_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_rose_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_rose_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_rose_top.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_sunflower_back.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_sunflower_back.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_sunflower_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_sunflower_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_sunflower_front.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_sunflower_front.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_sunflower_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_sunflower_top.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_syringa_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_syringa_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_syringa_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_syringa_top.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_grass_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_grass_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_grass_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_grass_top.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_fern_bottom.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_fern_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,double_plant_fern_top.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_double_plant_fern_top.png,,,,,,, -/assets/minecraft/textures/blocks,tallgrass.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_tallgrass.png,,,,,,, -/assets/minecraft/textures/blocks,fern.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_fern.png,,,,,,, -/assets/minecraft/textures/blocks,flower_oxeye_daisy.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_oxeye_daisy.png,,,,,,, -/assets/minecraft/textures/blocks,flower_rose.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_poppy.png,,,,,,, -/assets/minecraft/textures/blocks,flower_tulip_pink.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_tulip_pink.png,,,,,,, -/assets/minecraft/textures/blocks,flower_tulip_red.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_tulip_red.png,,,,,,, -/assets/minecraft/textures/blocks,flower_tulip_white.png,/mods/ITEMS/mcl_flowers/textures,mcl_flowers_tulip_white.png,,,,,,, -/assets/minecraft/textures/blocks,flower_dandelion.png,/mods/ITEMS/mcl_flowers/textures,flowers_dandelion_yellow.png,,,,,,, -/assets/minecraft/textures/blocks,flower_tulip_orange.png,/mods/ITEMS/mcl_flowers/textures,flowers_tulip.png,,,,,,, -/assets/minecraft/textures/blocks,furnace_front_off.png,/mods/ITEMS/mcl_furnaces/textures,default_furnace_front.png,,,,,,, -/assets/minecraft/textures/blocks,furnace_front_on.png,/mods/ITEMS/mcl_furnaces/textures,default_furnace_front_active.png,,,,,,, -/assets/minecraft/textures/blocks,furnace_side.png,/mods/ITEMS/mcl_furnaces/textures,default_furnace_side.png,,,,,,, -/assets/minecraft/textures/blocks,furnace_top.png,/mods/ITEMS/mcl_furnaces/textures,default_furnace_top.png,,,,,,, -/assets/minecraft/textures/blocks,furnace_top.png,/mods/ITEMS/mcl_furnaces/textures,default_furnace_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,hopper_inside.png,/mods/ITEMS/mcl_hoppers/textures,mcl_hoppers_hopper_inside.png,,,,,,, -/assets/minecraft/textures/blocks,hopper_outside.png,/mods/ITEMS/mcl_hoppers/textures,mcl_hoppers_hopper_outside.png,,,,,,, -/assets/minecraft/textures/blocks,hopper_top.png,/mods/ITEMS/mcl_hoppers/textures,mcl_hoppers_hopper_top.png,,,,,,, -/assets/minecraft/textures/items,hopper.png,/mods/ITEMS/mcl_hoppers/textures,mcl_hoppers_item.png,,,,,,, -/assets/minecraft/textures/items,record_11.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_11.png,,,,,,, -/assets/minecraft/textures/items,record_13.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_13.png,,,,,,, -/assets/minecraft/textures/items,record_blocks.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_blocks.png,,,,,,, -/assets/minecraft/textures/items,record_cat.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_cat.png,,,,,,, -/assets/minecraft/textures/items,record_chirp.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_chirp.png,,,,,,, -/assets/minecraft/textures/items,record_far.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_far.png,,,,,,, -/assets/minecraft/textures/items,record_mall.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_mall.png,,,,,,, -/assets/minecraft/textures/items,record_mellohi.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_mellohi.png,,,,,,, -/assets/minecraft/textures/items,record_stal.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_stal.png,,,,,,, -/assets/minecraft/textures/items,record_strad.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_strad.png,,,,,,, -/assets/minecraft/textures/items,record_wait.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_wait.png,,,,,,, -/assets/minecraft/textures/items,record_ward.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_record_ward.png,,,,,,, -/assets/minecraft/textures/blocks,jukebox_side.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_side.png,,,,,,, -/assets/minecraft/textures/blocks,jukebox_top.png,/mods/ITEMS/mcl_jukebox/textures,mcl_jukebox_top.png,,,,,,, -/assets/minecraft/textures/items,map_empty.png,/mods/ITEMS/mcl_maps/textures,mcl_maps_map_empty.png,,,,,,, -/assets/minecraft/textures/items,map_filled_markings.png,/mods/ITEMS/mcl_maps/textures,mcl_maps_map_filled_markings.png,,,,,,, -/assets/minecraft/textures/items,map_filled.png,/mods/ITEMS/mcl_maps/textures,mcl_maps_map_filled.png,,,,,,, -/assets/minecraft/textures/blocks,rail_golden.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_golden.png,,,,,,, -/assets/minecraft/textures/blocks,rail_golden_powered.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_golden_powered.png,,,,,,, -/assets/minecraft/textures/blocks,rail_normal_turned.png,/mods/ENTITIES/mcl_minecarts/textures,default_rail_curved.png,,,,,,, -/assets/minecraft/textures/blocks,rail_normal.png,/mods/ENTITIES/mcl_minecarts/textures,default_rail.png,,,,,,, -/assets/minecraft/textures/blocks,rail_detector.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_detector.png,,,,,,, -/assets/minecraft/textures/blocks,rail_detector_powered.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_detector_powered.png,,,,,,, -/assets/minecraft/textures/blocks,rail_activator.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_activator.png,,,,,,, -/assets/minecraft/textures/blocks,rail_activator_powered.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_rail_activator_powered.png,,,,,,, -/assets/minecraft/textures/items,minecart_normal.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_normal.png,,,,,,, -/assets/minecraft/textures/items,minecart_chest.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_chest.png,,,,,,, -/assets/minecraft/textures/items,minecart_tnt.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_tnt.png,,,,,,, -/assets/minecraft/textures/items,minecart_command_block.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_command_block.png,,,,,,, -/assets/minecraft/textures/items,minecart_furnace.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_furnace.png,,,,,,, -/assets/minecraft/textures/items,minecart_hopper.png,/mods/ENTITIES/mcl_minecarts/textures,mcl_minecarts_minecart_hopper.png,,,,,,, -/assets/minecraft/textures/items,gunpowder.png,/mods/ITEMS/mcl_mobitems/textures,default_gunpowder.png,,,,,,, -/assets/minecraft/textures/items,beef_cooked.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_beef_cooked.png,,,,,,, -/assets/minecraft/textures/items,beef_raw.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_beef_raw.png,,,,,,, -/assets/minecraft/textures/items,blaze_powder.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_blaze_powder.png,,,,,,, -/assets/minecraft/textures/items,blaze_rod.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_blaze_rod.png,,,,,,, -/assets/minecraft/textures/items,bone.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_bone.png,,,,,,, -/assets/minecraft/textures/items,bucket_milk.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_bucket_milk.png,,,,,,, -/assets/minecraft/textures/items,carrot_on_a_stick.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_carrot_on_a_stick.png,,,,,,, -/assets/minecraft/textures/items,chicken_cooked.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_chicken_cooked.png,,,,,,, -/assets/minecraft/textures/items,chicken_raw.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_chicken_raw.png,,,,,,, -/assets/minecraft/textures/items,feather.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_feather.png,,,,,,, -/assets/minecraft/textures/items,ghast_tear.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_ghast_tear.png,,,,,,, -/assets/minecraft/textures/items,leather.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_leather.png,,,,,,, -/assets/minecraft/textures/items,magma_cream.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_magma_cream.png,,,,,,, -/assets/minecraft/textures/items,mutton_cooked.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_mutton_cooked.png,,,,,,, -/assets/minecraft/textures/items,mutton_raw.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_mutton_raw.png,,,,,,, -/assets/minecraft/textures/items,nether_star.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_nether_star.png,,,,,,, -/assets/minecraft/textures/items,porkchop_cooked.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_porkchop_cooked.png,,,,,,, -/assets/minecraft/textures/items,porkchop_raw.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_porkchop_raw.png,,,,,,, -/assets/minecraft/textures/items,rabbit_cooked.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rabbit_cooked.png,,,,,,, -/assets/minecraft/textures/items,rabbit_foot.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rabbit_foot.png,,,,,,, -/assets/minecraft/textures/items,rabbit_hide.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rabbit_hide.png,,,,,,, -/assets/minecraft/textures/items,rabbit_raw.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rabbit_raw.png,,,,,,, -/assets/minecraft/textures/items,rabbit_stew.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rabbit_stew.png,,,,,,, -/assets/minecraft/textures/items,rotten_flesh.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_rotten_flesh.png,,,,,,, -/assets/minecraft/textures/items,saddle.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_saddle.png,,,,,,, -/assets/minecraft/textures/items,shulker_shell.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_shulker_shell.png,,,,,,, -/assets/minecraft/textures/items,slimeball.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_slimeball.png,,,,,,, -/assets/minecraft/textures/items,spider_eye.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_spider_eye.png,,,,,,, -/assets/minecraft/textures/items,string.png,/mods/ITEMS/mcl_mobitems/textures,mcl_mobitems_string.png,,,,,,, -/assets/minecraft/textures/blocks,mob_spawner.png,/mods/ITEMS/mcl_mobspawners/textures,mob_spawner.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_brown.png,/mods/ITEMS/mcl_mushrooms/textures,farming_mushroom_brown.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_red.png,/mods/ITEMS/mcl_mushrooms/textures,farming_mushroom_red.png,,,,,,, -/assets/minecraft/textures/items,mushroom_stew.png,/mods/ITEMS/mcl_mushrooms/textures,farming_mushroom_stew.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_block_inside.png,/mods/ITEMS/mcl_mushrooms/textures,mcl_mushrooms_mushroom_block_inside.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_block_skin_brown.png,/mods/ITEMS/mcl_mushrooms/textures,mcl_mushrooms_mushroom_block_skin_brown.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_block_skin_red.png,/mods/ITEMS/mcl_mushrooms/textures,mcl_mushrooms_mushroom_block_skin_red.png,,,,,,, -/assets/minecraft/textures/blocks,mushroom_block_skin_stem.png,/mods/ITEMS/mcl_mushrooms/textures,mcl_mushrooms_mushroom_block_skin_stem.png,,,,,,, -/assets/minecraft/textures/items,glowstone_dust.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_glowstone_dust.png,,,,,,, -/assets/minecraft/textures/blocks,glowstone.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_glowstone.png,,,,,,, -/assets/minecraft/textures/blocks,magma.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_magma.png,,,,,,, -/assets/minecraft/textures/blocks,nether_brick.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_brick.png,,,,,,, -/assets/minecraft/textures/items,netherbrick.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_netherbrick.png,,,,,,, -/assets/minecraft/textures/blocks,netherrack.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_netherrack.png,,,,,,, -/assets/minecraft/textures/blocks,nether_wart_block.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_wart_block.png,,,,,,, -/assets/minecraft/textures/items,nether_wart.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_wart.png,,,,,,, -/assets/minecraft/textures/blocks,nether_wart_stage_0.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_wart_stage_0.png,,,,,,, -/assets/minecraft/textures/blocks,nether_wart_stage_1.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_wart_stage_1.png,,,,,,, -/assets/minecraft/textures/blocks,nether_wart_stage_2.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_nether_wart_stage_2.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_bottom.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_block_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_side.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_block_side.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_top.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_block_top.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_chiseled.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_chiseled_side.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_chiseled_top.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_chiseled_top.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_ore.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_ore.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_lines.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_pillar_side.png,,,,,,, -/assets/minecraft/textures/blocks,quartz_block_lines_top.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz_pillar_top.png,,,,,,, -/assets/minecraft/textures/items,quartz.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_quartz.png,,,,,,, -/assets/minecraft/textures/blocks,red_nether_brick.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_red_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,soul_sand.png,/mods/ITEMS/mcl_nether/textures,mcl_nether_soul_sand.png,,,,,,, -/assets/minecraft/textures/blocks,prismarine_rough.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_prismarine_anim.png,,,,,,, -/assets/minecraft/textures/blocks,prismarine_bricks.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_prismarine_bricks.png,,,,,,, -/assets/minecraft/textures/items,prismarine_crystals.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_prismarine_crystals.png,,,,,,, -/assets/minecraft/textures/blocks,prismarine_dark.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_prismarine_dark.png,,,,,,, -/assets/minecraft/textures/items,prismarine_shard.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_prismarine_shard.png,,,,,,, -/assets/minecraft/textures/blocks,sea_lantern.png,/mods/ITEMS/mcl_ocean/textures,mcl_ocean_sea_lantern.png,,,,,,, -/assets/minecraft/textures/items,dragon_breath.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_dragon_breath.png,,,,,,, -/assets/minecraft/textures/items,melon_speckled.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_melon_speckled.png,,,,,,, -/assets/minecraft/textures/items,potion_bottle_empty.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_potion_bottle.png,,,,,,, -/assets/minecraft/textures/items,potion_bottle_splash.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_splash_bottle.png,,,,,,, -/assets/minecraft/textures/items,potion_bottle_lingering.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_lingering_bottle.png,,,,,,, -/assets/minecraft/textures/items,potion_overlay.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_potion_overlay.png,,,,,,, -/assets/minecraft/textures/items,potion_overlay.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_splash_overlay.png,,,,,,, -/assets/minecraft/textures/items,spider_eye_fermented.png,/mods/ITEMS/mcl_potions/textures,mcl_potions_spider_eye_fermented.png,,,,,,, -/assets/minecraft/textures/blocks,sponge.png,/mods/ITEMS/mcl_sponges/textures,mcl_sponges_sponge.png,,,,,,, -/assets/minecraft/textures/blocks,sponge_wet.png,/mods/ITEMS/mcl_sponges/textures,mcl_sponges_sponge_wet.png,,,,,,, -/assets/minecraft/textures/blocks,sponge_wet.png,/mods/ITEMS/mcl_sponges/textures,mcl_sponges_sponge_wet_river_water.png,,,,,,, -/assets/minecraft/textures/blocks,stone_slab_side.png,/mods/ITEMS/mcl_stairs/textures,mcl_stairs_stone_slab_side.png,,,,,,, -/assets/minecraft/textures/blocks,stone_slab_top.png,/mods/ITEMS/mcl_stairs/textures,mcl_stairs_stone_slab_top.png,,,,,,, -/assets/minecraft/textures/items,arrow.png,/mods/ITEMS/mcl_bows/textures,mcl_bows_arrow_inv.png,,,,,,, -/assets/minecraft/textures/items,bow_pulling_0.png,/mods/ITEMS/mcl_bows/textures,mcl_bows_bow_0.png,,,,,,, -/assets/minecraft/textures/items,bow_pulling_1.png,/mods/ITEMS/mcl_bows/textures,mcl_bows_bow_1.png,,,,,,, -/assets/minecraft/textures/items,bow_pulling_2.png,/mods/ITEMS/mcl_bows/textures,mcl_bows_bow_2.png,,,,,,, -/assets/minecraft/textures/items,bow_standby.png,/mods/ITEMS/mcl_bows/textures,mcl_bows_bow.png,,,,,,, -/assets/minecraft/textures/items,egg.png,/mods/ITEMS/mcl_throwing/textures,mcl_throwing_egg.png,,,,,,, -/assets/minecraft/textures/items,ender_pearl.png,/mods/ITEMS/mcl_throwing/textures,mcl_throwing_ender_pearl.png,,,,,,, -/assets/minecraft/textures/items,snowball.png,/mods/ITEMS/mcl_throwing/textures,mcl_throwing_snowball.png,,,,,,, -/assets/minecraft/textures/blocks,tnt_bottom.png,/mods/ITEMS/mcl_tnt/textures,default_tnt_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,tnt_side.png,/mods/ITEMS/mcl_tnt/textures,default_tnt_side.png,,,,,,, -/assets/minecraft/textures/blocks,tnt_top.png,/mods/ITEMS/mcl_tnt/textures,default_tnt_top.png,,,,,,, -/assets/minecraft/textures/items,diamond_axe.png,/mods/ITEMS/mcl_tools/textures,default_tool_diamondaxe.png,,,,,,, -/assets/minecraft/textures/items,diamond_pickaxe.png,/mods/ITEMS/mcl_tools/textures,default_tool_diamondpick.png,,,,,,, -/assets/minecraft/textures/items,diamond_shovel.png,/mods/ITEMS/mcl_tools/textures,default_tool_diamondshovel.png,,,,,,, -/assets/minecraft/textures/items,diamond_sword.png,/mods/ITEMS/mcl_tools/textures,default_tool_diamondsword.png,,,,,,, -/assets/minecraft/textures/items,gold_axe.png,/mods/ITEMS/mcl_tools/textures,default_tool_goldaxe.png,,,,,,, -/assets/minecraft/textures/items,gold_pickaxe.png,/mods/ITEMS/mcl_tools/textures,default_tool_goldpick.png,,,,,,, -/assets/minecraft/textures/items,gold_shovel.png,/mods/ITEMS/mcl_tools/textures,default_tool_goldshovel.png,,,,,,, -/assets/minecraft/textures/items,gold_sword.png,/mods/ITEMS/mcl_tools/textures,default_tool_goldsword.png,,,,,,, -/assets/minecraft/textures/items,shears.png,/mods/ITEMS/mcl_tools/textures,default_tool_shears.png,,,,,,, -/assets/minecraft/textures/items,iron_axe.png,/mods/ITEMS/mcl_tools/textures,default_tool_steelaxe.png,,,,,,, -/assets/minecraft/textures/items,iron_pickaxe.png,/mods/ITEMS/mcl_tools/textures,default_tool_steelpick.png,,,,,,, -/assets/minecraft/textures/items,iron_shovel.png,/mods/ITEMS/mcl_tools/textures,default_tool_steelshovel.png,,,,,,, -/assets/minecraft/textures/items,iron_sword.png,/mods/ITEMS/mcl_tools/textures,default_tool_steelsword.png,,,,,,, -/assets/minecraft/textures/items,stone_axe.png,/mods/ITEMS/mcl_tools/textures,default_tool_stoneaxe.png,,,,,,, -/assets/minecraft/textures/items,stone_pickaxe.png,/mods/ITEMS/mcl_tools/textures,default_tool_stonepick.png,,,,,,, -/assets/minecraft/textures/items,stone_shovel.png,/mods/ITEMS/mcl_tools/textures,default_tool_stoneshovel.png,,,,,,, -/assets/minecraft/textures/items,stone_sword.png,/mods/ITEMS/mcl_tools/textures,default_tool_stonesword.png,,,,,,, -/assets/minecraft/textures/items,wood_axe.png,/mods/ITEMS/mcl_tools/textures,default_tool_woodaxe.png,,,,,,, -/assets/minecraft/textures/items,wood_pickaxe.png,/mods/ITEMS/mcl_tools/textures,default_tool_woodpick.png,,,,,,, -/assets/minecraft/textures/items,wood_shovel.png,/mods/ITEMS/mcl_tools/textures,default_tool_woodshovel.png,,,,,,, -/assets/minecraft/textures/items,wood_sword.png,/mods/ITEMS/mcl_tools/textures,default_tool_woodsword.png,,,,,,, -/assets/minecraft/textures/blocks,torch_on.png,/mods/ITEMS/mcl_torches/textures,default_torch_on_floor_animated.png,,,,,,, -/assets/minecraft/textures/blocks,torch_on.png,/mods/ITEMS/mcl_torches/textures,default_torch_on_floor.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_black.png,/mods/ITEMS/mcl_wool/textures,wool_black.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_blue.png,/mods/ITEMS/mcl_wool/textures,wool_blue.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_brown.png,/mods/ITEMS/mcl_wool/textures,wool_brown.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_cyan.png,/mods/ITEMS/mcl_wool/textures,wool_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_gray.png,/mods/ITEMS/mcl_wool/textures,wool_dark_grey.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_green.png,/mods/ITEMS/mcl_wool/textures,wool_dark_green.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_silver.png,/mods/ITEMS/mcl_wool/textures,wool_grey.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_light_blue.png,/mods/ITEMS/mcl_wool/textures,mcl_wool_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_lime.png,/mods/ITEMS/mcl_wool/textures,mcl_wool_lime.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_magenta.png,/mods/ITEMS/mcl_wool/textures,wool_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_orange.png,/mods/ITEMS/mcl_wool/textures,wool_orange.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_pink.png,/mods/ITEMS/mcl_wool/textures,wool_pink.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_red.png,/mods/ITEMS/mcl_wool/textures,wool_red.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_purple.png,/mods/ITEMS/mcl_wool/textures,wool_violet.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_white.png,/mods/ITEMS/mcl_wool/textures,wool_white.png,,,,,,, -/assets/minecraft/textures/blocks,wool_colored_yellow.png,/mods/ITEMS/mcl_wool/textures,wool_yellow.png,,,,,,, -/assets/minecraft/textures/items,chainmail_boots.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_boots_chain.png,,,,,,, -/assets/minecraft/textures/items,diamond_boots.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_boots_diamond.png,,,,,,, -/assets/minecraft/textures/items,gold_boots.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_boots_gold.png,,,,,,, -/assets/minecraft/textures/items,iron_boots.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_boots_iron.png,,,,,,, -/assets/minecraft/textures/items,leather_boots.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_boots_leather.png,,,,,,, -/assets/minecraft/textures/items,chainmail_chestplate.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_chestplate_chain.png,,,,,,, -/assets/minecraft/textures/items,diamond_chestplate.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_chestplate_diamond.png,,,,,,, -/assets/minecraft/textures/items,gold_chestplate.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_chestplate_gold.png,,,,,,, -/assets/minecraft/textures/items,iron_chestplate.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_chestplate_iron.png,,,,,,, -/assets/minecraft/textures/items,leather_chestplate.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_chestplate_leather.png,,,,,,, -/assets/minecraft/textures/items,chainmail_helmet.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_helmet_chain.png,,,,,,, -/assets/minecraft/textures/items,diamond_helmet.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_helmet_diamond.png,,,,,,, -/assets/minecraft/textures/items,gold_helmet.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_helmet_gold.png,,,,,,, -/assets/minecraft/textures/items,iron_helmet.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_helmet_iron.png,,,,,,, -/assets/minecraft/textures/items,leather_helmet.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_helmet_leather.png,,,,,,, -/assets/minecraft/textures/items,chainmail_leggings.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_leggings_chain.png,,,,,,, -/assets/minecraft/textures/items,diamond_leggings.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_leggings_diamond.png,,,,,,, -/assets/minecraft/textures/items,gold_leggings.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_leggings_gold.png,,,,,,, -/assets/minecraft/textures/items,iron_leggings.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_leggings_iron.png,,,,,,, -/assets/minecraft/textures/items,leather_leggings.png,/mods/ITEMS/mcl_armor/textures,mcl_armor_inv_leggings_leather.png,,,,,,, -/assets/minecraft/textures/items,wooden_armorstand.png,/mods/ITEMS/mcl_armor_stand/textures,3d_armor_stand_item.png,,,,,,, -/assets/minecraft/textures/blocks,dispenser_front_horizontal.png,/mods/ITEMS/REDSTONE/mcl_dispensers/textures,mcl_dispensers_dispenser_front_horizontal.png,,,,,,, -/assets/minecraft/textures/blocks,dispenser_front_vertical.png,/mods/ITEMS/REDSTONE/mcl_dispensers/textures,mcl_dispensers_dispenser_front_vertical.png,,,,,,, -/assets/minecraft/textures/blocks,dropper_front_horizontal.png,/mods/ITEMS/REDSTONE/mcl_droppers/textures,mcl_droppers_dropper_front_horizontal.png,,,,,,, -/assets/minecraft/textures/blocks,dropper_front_vertical.png,/mods/ITEMS/REDSTONE/mcl_droppers/textures,mcl_droppers_dropper_front_vertical.png,,,,,,, -/assets/minecraft/textures/blocks,observer_back_lit.png,/mods/ITEMS/REDSTONE/mcl_observers/textures,mcl_observers_observer_back_lit.png,,,,,,, -/assets/minecraft/textures/blocks,observer_back.png,/mods/ITEMS/REDSTONE/mcl_observers/textures,mcl_observers_observer_back.png,,,,,,, -/assets/minecraft/textures/blocks,observer_front.png,/mods/ITEMS/REDSTONE/mcl_observers/textures,mcl_observers_observer_front.png,,,,,,, -/assets/minecraft/textures/blocks,observer_side.png,/mods/ITEMS/REDSTONE/mcl_observers/textures,mcl_observers_observer_side.png,,,,,,, -/assets/minecraft/textures/blocks,observer_top.png,/mods/ITEMS/REDSTONE/mcl_observers/textures,mcl_observers_observer_top.png,,,,,,, -/assets/minecraft/textures/items,redstone_dust.png,/mods/ITEMS/REDSTONE/mesecons_wires/textures,redstone_redstone_dust.png,,,,,,, -/assets/minecraft/textures/items,repeater.png,/mods/ITEMS/REDSTONE/mesecons_delayer/textures,mesecons_delayer_item.png,,,,,,, -/assets/minecraft/textures/items,comparator.png,/mods/ITEMS/REDSTONE/mcl_comparators/textures,mcl_comparators_item.png,,,,,,, -/assets/minecraft/textures/blocks,repeater_off.png,/mods/ITEMS/REDSTONE/mesecons_delayer/textures,mesecons_delayer_off.png,,,,,,, -/assets/minecraft/textures/blocks,repeater_on.png,/mods/ITEMS/REDSTONE/mesecons_delayer/textures,mesecons_delayer_on.png,,,,,,, -/assets/minecraft/textures/blocks,noteblock.png,/mods/ITEMS/REDSTONE/mesecons_noteblock/textures,mesecons_noteblock.png,,,,,,, -/assets/minecraft/textures/blocks,command_block_back.png,/mods/ITEMS/REDSTONE/mesecons_commandblock/textures,jeija_commandblock_off.png,,,,,,, -/assets/minecraft/textures/blocks,command_block_back.png,/mods/ITEMS/REDSTONE/mesecons_commandblock/textures,jeija_commandblock_on.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_lamp_off.png,/mods/ITEMS/REDSTONE/mesecons_lightstone/textures,jeija_lightstone_gray_off.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_lamp_on.png,/mods/ITEMS/REDSTONE/mesecons_lightstone/textures,jeija_lightstone_gray_on.png,,,,,,, -/assets/minecraft/textures/blocks,daylight_detector_inverted_top.png,/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures,jeija_solar_panel_inverted.png,,,,,,, -/assets/minecraft/textures/blocks,daylight_detector_top.png,/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures,jeija_solar_panel.png,,,,,,, -/assets/minecraft/textures/blocks,daylight_detector_side.png,/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures,jeija_solar_panel_side.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_torch_off.png,/mods/ITEMS/REDSTONE/mesecons_torch/textures,jeija_torches_off.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_torch_on.png,/mods/ITEMS/REDSTONE/mesecons_torch/textures,jeija_torches_on.png,,,,,,, -/assets/minecraft/textures/blocks,lever.png,/mods/ITEMS/REDSTONE/mesecons_walllever/textures,jeija_wall_lever.png,,,,,,, -/assets/minecraft/textures/blocks,piston_bottom.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_back.png,,,,,,, -/assets/minecraft/textures/blocks,piston_side.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,piston_inner.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_on_front.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_back.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_front.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_sticky.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_front_sticky.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_left.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_right.png,,,,,,, -/assets/minecraft/textures/blocks,piston_top_normal.png,/mods/ITEMS/REDSTONE/mesecons_pistons/textures,mesecons_piston_pusher_top.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_block.png,/mods/ITEMS/REDSTONE/mesecons_torch/textures,redstone_redstone_block.png,,,,,,, -/assets/minecraft/textures/items,sign.png,/mods/ITEMS/mcl_signs/textures,default_sign.png,,,,,,, -/assets/minecraft/textures/blocks,iron_bars.png,/mods/ITEMS/xpanes/textures,xpanes_pane_iron.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_black.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_black.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_blue.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_brown.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_brown.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_cyan.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_cyan.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_gray.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_gray.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_green.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_green.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_light_blue.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_light_blue.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_lime.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_lime.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_magenta.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_magenta.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_natural.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_orange.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_orange.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_pink.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_pink.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_purple.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_purple.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_red.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_red.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_silver.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_silver.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_white.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_white.png,,,,,,, -/assets/minecraft/textures/blocks,glass_pane_top_yellow.png,/mods/ITEMS/xpanes/textures,xpanes_top_glass_yellow.png,,,,,,, -/assets/minecraft/textures/items,totem.png,/mods/ENTITIES/mobs_mc/textures,mcl_totems_totem.png,,,,,,, -/assets/minecraft/textures/entity,bat.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_bat.png,,,,,,, -/assets/minecraft/textures/entity,blaze.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_blaze.png,,,,,,, -/assets/minecraft/textures/entity/cat,black.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cat_black.png,,,,,,, -/assets/minecraft/textures/entity/cat,ocelot.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cat_ocelot.png,,,,,,, -/assets/minecraft/textures/entity/cat,red.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cat_red.png,,,,,,, -/assets/minecraft/textures/entity/cat,siamese.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cat_siamese.png,,,,,,, -/assets/minecraft/textures/entity/spider,cave_spider.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cave_spider.png,,,,,,, -/assets/minecraft/textures/entity,chicken.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_chicken.png,,,,,,, -/assets/minecraft/textures/entity/cow,cow.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_cow.png,,,,,,, -/assets/minecraft/textures/entity/creeper,creeper.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_creeper.png,,,,,,, -/assets/minecraft/textures/items,diamond_horse_armor.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_diamond_horse_armor.png,,,,,,, -/assets/minecraft/textures/entity/horse,donkey.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_donkey.png,,,,,,, -/assets/minecraft/textures/entity/enderdragon,dragon.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_dragon.png,,,,,,, -/assets/minecraft/textures/entity/shulker,endergolem.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_endergolem.png,,,,,,, -/assets/minecraft/textures/entity/enderman,enderman_eyes.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_enderman_eyes.png,,,,,,, -/assets/minecraft/textures/entity/enderman,enderman.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_enderman.png,,,,,,, -/assets/minecraft/textures/entity,endermite.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_endermite.png,,,,,,, -/assets/minecraft/textures/entity/ghast,ghast.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_ghast.png,,,,,,, -/assets/minecraft/textures/items,gold_horse_armor.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_gold_horse_armor.png,,,,,,, -/assets/minecraft/textures/entity,guardian_elder.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_guardian_elder.png,,,,,,, -/assets/minecraft/textures/entity,guardian.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_guardian.png,,,,,,, -/assets/minecraft/textures/entity/horse/armor,horse_armor_diamond.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_armor_diamond.png,,,,,,, -/assets/minecraft/textures/entity/horse/armor,horse_armor_gold.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_armor_gold.png,,,,,,, -/assets/minecraft/textures/entity/horse/armor,horse_armor_iron.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_armor_iron.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_black.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_black.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_brown.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_brown.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_chestnut.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_chestnut.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_darkbrown.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_darkbrown.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_gray.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_gray.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_creamy.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_creamy.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_markings_blackdots.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_markings_blackdots.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_markings_whitedots.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_markings_whitedots.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_markings_whitefield.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_markings_whitefield.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_markings_white.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_markings_white.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_white.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_white.png,,,,,,, -/assets/minecraft/textures/entity/horse,horse_zombie.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_horse_zombie.png,,,,,,, -/assets/minecraft/textures/entity/zombie,husk.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_husk.png,,,,,,, -/assets/minecraft/textures/entity,iron_golem.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_iron_golem.png,,,,,,, -/assets/minecraft/textures/items,iron_horse_armor.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_iron_horse_armor.png,,,,,,, -/assets/minecraft/textures/entity/slime,magmacube.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_magmacube.png,,,,,,, -/assets/minecraft/textures/entity/cow,mooshroom.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_mooshroom.png,,,,,,, -/assets/minecraft/textures/entity/horse,mule.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_mule.png,,,,,,, -/assets/minecraft/textures/entity/pig,pig.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_pig.png,,,,,,, -/assets/minecraft/textures/entity/pig,pig_saddle.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_pig_saddle.png,,,,,,, -/assets/minecraft/textures/entity/bear,polarbear.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_polarbear.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,black.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_black.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,brown.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_brown.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,caerbannog.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_caerbannog.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,gold.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_gold.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,salt.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_salt.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,toast.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_toast.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,white.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_white.png,,,,,,, -/assets/minecraft/textures/entity/rabbit,white_splotched.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_rabbit_white_splotched.png,,,,,,, -/assets/minecraft/textures/entity/sheep,sheep_fur.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_sheep_fur.png,,,,,,, -/assets/minecraft/textures/entity/sheep,sheep.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_sheep.png,,,,,,, -/assets/minecraft/textures/entity/shulker,shulker_black.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_black.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_blue.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_blue.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_brown.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_brown.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_cyan.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_cyan.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_gray.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_gray.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_green.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_green.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_light_blue.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_light_blue.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_lime.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_lime.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_magenta.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_magenta.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_orange.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_orange.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_pink.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_pink.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_purple.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_purple.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_red.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_red.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_silver.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_silver.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_white.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_white.png,,,,,,,y -/assets/minecraft/textures/entity/shulker,shulker_yellow.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_shulker_yellow.png,,,,,,,y -/assets/minecraft/textures/entity,silverfish.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_silverfish.png,,,,,,, -/assets/minecraft/textures/entity/skeleton,skeleton.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_skeleton.png,,,,,,, -/assets/minecraft/textures/entity/slime,slime.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_slime.png,,,,,,, -/assets/minecraft/textures/entity,snowman.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_snowman.png,,,,,,, -/assets/minecraft/textures/entity,spider_eyes.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_spider_eyes.png,,,,,,, -/assets/minecraft/textures/entity/spider,spider.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_spider.png,,,,,,, -/assets/minecraft/textures/entity,squid.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_squid.png,,,,,,, -/assets/minecraft/textures/entity/skeleton,stray.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_stray.png,,,,,,, -/assets/minecraft/textures/entity/skeleton,stray_overlay.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_stray_overlay.png,,,,,,, -/assets/minecraft/textures/entity/villager,butcher.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager_butcher.png,,,,,,, -/assets/minecraft/textures/entity/villager,farmer.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager_farmer.png,,,,,,, -/assets/minecraft/textures/entity/villager,librarian.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager_librarian.png,,,,,,, -/assets/minecraft/textures/entity/villager,villager.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager.png,,,,,,, -/assets/minecraft/textures/entity/villager,priest.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager_priest.png,,,,,,, -/assets/minecraft/textures/entity/villager,smith.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_villager_smith.png,,,,,,, -/assets/minecraft/textures/entity/illager,vex.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_vex.png,,,,,,, -/assets/minecraft/textures/entity/illager,vex_charging.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_vex_charging.png,,,,,,, -/assets/minecraft/textures/entity/illager,vindicator.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_vindicator.png,,,,,,, -/assets/minecraft/textures/entity/illager,evoker.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_evoker.png,,,,,,, -/assets/minecraft/textures/entity/illager,illusionist.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_illusionist.png,,,,,,, -/assets/minecraft/textures/entity,witch.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_witch.png,,,,,,, -/assets/minecraft/textures/entity/wither,wither.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wither.png,,,,,,, -/assets/minecraft/textures/entity/skeleton,wither_skeleton.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wither_skeleton.png,,,,,,, -/assets/minecraft/textures/entity/wolf,wolf_angry.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wolf_angry.png,,,,,,, -/assets/minecraft/textures/entity/wolf,wolf_collar.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wolf_collar.png,,,,,,, -/assets/minecraft/textures/entity/wolf,wolf.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wolf.png,,,,,,, -/assets/minecraft/textures/entity/wolf,wolf_tame.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_wolf_tame.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_butcher.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_butcher.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_farmer.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_farmer.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_librarian.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_librarian.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_priest.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_priest.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_smith.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_smith.png,,,,,,, -/assets/minecraft/textures/entity/zombie_villager,zombie_villager.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_villager.png,,,,,,, -/assets/minecraft/textures/entity,zombie_pigman.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie_pigman.png,,,,,,, -/assets/minecraft/textures/entity/zombie,zombie.png,/mods/ENTITIES/mobs_mc/textures,mobs_mc_zombie.png,,,,,,, -/assets/minecraft/textures/gui,icons.png,/mods/PLAYER/mcl_hunger/textures,hbhunger_bgicon.png,16,27,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/PLAYER/mcl_hunger/textures,hbhunger_icon_health_poison.png,88,0,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/PLAYER/mcl_hunger/textures,hbhunger_icon.png,52,27,9,9,0,0,y -/assets/minecraft/textures/gui,icons.png,/mods/PLAYER/mcl_hunger/textures,mcl_hunger_icon_foodpoison.png,88,27,9,9,0,0,y -/assets/minecraft/textures/particle,particles.png,/mods/CORE/mcl_particles/textures,mcl_particles_smoke.png,56,0,8,8,0,0,y -/assets/minecraft/textures/blocks,shulker_top_black.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_black_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_blue.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_blue_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_brown.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_brown_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_cyan.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_cyan_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_gray.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_dark_grey_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_green.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_dark_green_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_light_blue.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_lightblue_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_lime.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_green_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_magenta.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_magenta_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_orange.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_orange_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_pink.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_pink_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_purple.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_violet_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_red.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_red_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_silver.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_grey_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_white.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_white_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/blocks,shulker_top_yellow.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_yellow_shulker_box_top.png,,,,,,,y -/assets/minecraft/textures/items,flower_pot.png,/mods/ITEMS/mcl_flowerpots/textures,mcl_flowerpots_flowerpot_inventory.png,,,,,,, -/assets/minecraft/textures/blocks,flower_pot.png,/mods/ITEMS/mcl_flowerpots/textures,mcl_flowerpots_flowerpot.png,,,,,,,y -/assets/minecraft/textures/gui,widgets.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_hotbar.png,0,0,182,22,0,0,y -/assets/minecraft/textures/gui,widgets.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_hotbar_selected.png,0,22,24,24,0,0,y -/assets/minecraft/textures/blocks,bed_feet_end.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_side_bottom_red.png,,,,,,, -/assets/minecraft/textures/blocks,bed_feet_side.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_side_bottom_r_red.png,,,,,,, -/assets/minecraft/textures/blocks,bed_feet_top.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_top_bottom_red.png,,,,,,, -/assets/minecraft/textures/blocks,bed_head_end.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_side_bottom_red.png,,,,,,, -/assets/minecraft/textures/blocks,bed_head_side.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_side_top_r_red.png,,,,,,, -/assets/minecraft/textures/blocks,bed_head_top.png,/mods/ITEMS/mcl_beds/textures,mcl_beds_bed_top_top_red.png,,,,,,, -/assets/minecraft/textures/items,compass_00.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_00.png,,,,,,, -/assets/minecraft/textures/items,compass_01.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_01.png,,,,,,, -/assets/minecraft/textures/items,compass_02.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_02.png,,,,,,, -/assets/minecraft/textures/items,compass_03.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_03.png,,,,,,, -/assets/minecraft/textures/items,compass_04.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_04.png,,,,,,, -/assets/minecraft/textures/items,compass_05.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_05.png,,,,,,, -/assets/minecraft/textures/items,compass_06.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_06.png,,,,,,, -/assets/minecraft/textures/items,compass_07.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_07.png,,,,,,, -/assets/minecraft/textures/items,compass_08.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_08.png,,,,,,, -/assets/minecraft/textures/items,compass_09.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_09.png,,,,,,, -/assets/minecraft/textures/items,compass_10.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_10.png,,,,,,, -/assets/minecraft/textures/items,compass_11.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_11.png,,,,,,, -/assets/minecraft/textures/items,compass_12.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_12.png,,,,,,, -/assets/minecraft/textures/items,compass_13.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_13.png,,,,,,, -/assets/minecraft/textures/items,compass_14.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_14.png,,,,,,, -/assets/minecraft/textures/items,compass_15.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_15.png,,,,,,, -/assets/minecraft/textures/items,compass_16.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_16.png,,,,,,, -/assets/minecraft/textures/items,compass_17.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_17.png,,,,,,, -/assets/minecraft/textures/items,compass_18.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_18.png,,,,,,, -/assets/minecraft/textures/items,compass_19.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_19.png,,,,,,, -/assets/minecraft/textures/items,compass_20.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_20.png,,,,,,, -/assets/minecraft/textures/items,compass_21.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_21.png,,,,,,, -/assets/minecraft/textures/items,compass_22.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_22.png,,,,,,, -/assets/minecraft/textures/items,compass_23.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_23.png,,,,,,, -/assets/minecraft/textures/items,compass_24.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_24.png,,,,,,, -/assets/minecraft/textures/items,compass_25.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_25.png,,,,,,, -/assets/minecraft/textures/items,compass_26.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_26.png,,,,,,, -/assets/minecraft/textures/items,compass_27.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_27.png,,,,,,, -/assets/minecraft/textures/items,compass_28.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_28.png,,,,,,, -/assets/minecraft/textures/items,compass_29.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_29.png,,,,,,, -/assets/minecraft/textures/items,compass_30.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_30.png,,,,,,, -/assets/minecraft/textures/items,compass_31.png,/mods/ITEMS/mcl_compass/textures,mcl_compass_compass_31.png,,,,,,, -/assets/minecraft/textures/items,clock_00.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_00.png,,,,,,, -/assets/minecraft/textures/items,clock_01.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_01.png,,,,,,, -/assets/minecraft/textures/items,clock_02.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_02.png,,,,,,, -/assets/minecraft/textures/items,clock_03.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_03.png,,,,,,, -/assets/minecraft/textures/items,clock_04.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_04.png,,,,,,, -/assets/minecraft/textures/items,clock_05.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_05.png,,,,,,, -/assets/minecraft/textures/items,clock_06.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_06.png,,,,,,, -/assets/minecraft/textures/items,clock_07.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_07.png,,,,,,, -/assets/minecraft/textures/items,clock_08.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_08.png,,,,,,, -/assets/minecraft/textures/items,clock_09.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_09.png,,,,,,, -/assets/minecraft/textures/items,clock_10.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_10.png,,,,,,, -/assets/minecraft/textures/items,clock_11.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_11.png,,,,,,, -/assets/minecraft/textures/items,clock_12.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_12.png,,,,,,, -/assets/minecraft/textures/items,clock_13.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_13.png,,,,,,, -/assets/minecraft/textures/items,clock_14.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_14.png,,,,,,, -/assets/minecraft/textures/items,clock_15.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_15.png,,,,,,, -/assets/minecraft/textures/items,clock_16.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_16.png,,,,,,, -/assets/minecraft/textures/items,clock_17.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_17.png,,,,,,, -/assets/minecraft/textures/items,clock_18.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_18.png,,,,,,, -/assets/minecraft/textures/items,clock_19.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_19.png,,,,,,, -/assets/minecraft/textures/items,clock_20.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_20.png,,,,,,, -/assets/minecraft/textures/items,clock_21.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_21.png,,,,,,, -/assets/minecraft/textures/items,clock_22.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_22.png,,,,,,, -/assets/minecraft/textures/items,clock_23.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_23.png,,,,,,, -/assets/minecraft/textures/items,clock_24.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_24.png,,,,,,, -/assets/minecraft/textures/items,clock_25.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_25.png,,,,,,, -/assets/minecraft/textures/items,clock_26.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_26.png,,,,,,, -/assets/minecraft/textures/items,clock_27.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_27.png,,,,,,, -/assets/minecraft/textures/items,clock_28.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_28.png,,,,,,, -/assets/minecraft/textures/items,clock_29.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_29.png,,,,,,, -/assets/minecraft/textures/items,clock_30.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_30.png,,,,,,, -/assets/minecraft/textures/items,clock_31.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_31.png,,,,,,, -/assets/minecraft/textures/items,clock_32.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_32.png,,,,,,, -/assets/minecraft/textures/items,clock_33.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_33.png,,,,,,, -/assets/minecraft/textures/items,clock_34.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_34.png,,,,,,, -/assets/minecraft/textures/items,clock_35.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_35.png,,,,,,, -/assets/minecraft/textures/items,clock_36.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_36.png,,,,,,, -/assets/minecraft/textures/items,clock_37.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_37.png,,,,,,, -/assets/minecraft/textures/items,clock_38.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_38.png,,,,,,, -/assets/minecraft/textures/items,clock_39.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_39.png,,,,,,, -/assets/minecraft/textures/items,clock_40.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_40.png,,,,,,, -/assets/minecraft/textures/items,clock_41.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_41.png,,,,,,, -/assets/minecraft/textures/items,clock_42.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_42.png,,,,,,, -/assets/minecraft/textures/items,clock_43.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_43.png,,,,,,, -/assets/minecraft/textures/items,clock_44.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_44.png,,,,,,, -/assets/minecraft/textures/items,clock_45.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_45.png,,,,,,, -/assets/minecraft/textures/items,clock_46.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_46.png,,,,,,, -/assets/minecraft/textures/items,clock_47.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_47.png,,,,,,, -/assets/minecraft/textures/items,clock_48.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_48.png,,,,,,, -/assets/minecraft/textures/items,clock_49.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_49.png,,,,,,, -/assets/minecraft/textures/items,clock_50.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_50.png,,,,,,, -/assets/minecraft/textures/items,clock_51.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_51.png,,,,,,, -/assets/minecraft/textures/items,clock_52.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_52.png,,,,,,, -/assets/minecraft/textures/items,clock_53.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_53.png,,,,,,, -/assets/minecraft/textures/items,clock_54.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_54.png,,,,,,, -/assets/minecraft/textures/items,clock_55.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_55.png,,,,,,, -/assets/minecraft/textures/items,clock_56.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_56.png,,,,,,, -/assets/minecraft/textures/items,clock_57.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_57.png,,,,,,, -/assets/minecraft/textures/items,clock_58.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_58.png,,,,,,, -/assets/minecraft/textures/items,clock_59.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_59.png,,,,,,, -/assets/minecraft/textures/items,clock_60.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_60.png,,,,,,, -/assets/minecraft/textures/items,clock_61.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_61.png,,,,,,, -/assets/minecraft/textures/items,clock_62.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_62.png,,,,,,, -/assets/minecraft/textures/items,clock_63.png,/mods/ITEMS/mcl_clock/textures,mcl_clock_clock_63.png,,,,,,, -/assets/minecraft/textures/items,empty_armor_slot_boots.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_empty_armor_slot_boots.png,,,,,,, -/assets/minecraft/textures/items,empty_armor_slot_chestplate.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_empty_armor_slot_chestplate.png,,,,,,, -/assets/minecraft/textures/items,empty_armor_slot_helmet.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_empty_armor_slot_helmet.png,,,,,,, -/assets/minecraft/textures/items,empty_armor_slot_leggings.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_empty_armor_slot_leggings.png,,,,,,, -/assets/minecraft/textures/items,empty_armor_slot_shield.png,/mods/HUD/mcl_inventory/textures,mcl_inventory_empty_armor_slot_shield.png,,,,,,, -/assets/minecraft/textures/items,knowledge_book.png,/mods/HELP/mcl_craftguide/textures,craftguide_book.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_dust_dot.png,/mods/ITEMS/REDSTONE/mesecons_wires/textures,redstone_redstone_dust_dot.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_dust_line0.png,/mods/ITEMS/REDSTONE/mesecons_wires/textures,redstone_redstone_dust_line0.png,,,,,,, -/assets/minecraft/textures/blocks,redstone_dust_line1.png,/mods/ITEMS/REDSTONE/mesecons_wires/textures,redstone_redstone_dust_line1.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_stem_connected.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_pumpkin_stem_connected.png,,,,,,, -/assets/minecraft/textures/blocks,melon_stem_connected.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_melon_stem_connected.png,,,,,,, -/assets/minecraft/textures/blocks,pumpkin_stem_disconnected.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_pumpkin_stem_disconnected.png,,,,,,, -/assets/minecraft/textures/blocks,melon_stem_disconnected.png,/mods/ITEMS/mcl_farming/textures,mcl_farming_melon_stem_disconnected.png,,,,,,, -/assets/minecraft/textures/blocks,planks_acacia.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_acacia.png,,,,,,, -/assets/minecraft/textures/blocks,planks_big_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,planks_birch.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_birch.png,,,,,,, -/assets/minecraft/textures/blocks,planks_jungle.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_jungle.png,,,,,,, -/assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_oak.png,,,,,,, -/assets/minecraft/textures/blocks,planks_spruce.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,planks_acacia.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_acacia.png,,,,,,, -/assets/minecraft/textures/blocks,planks_big_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,planks_birch.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_birch.png,,,,,,, -/assets/minecraft/textures/blocks,planks_jungle.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_jungle.png,,,,,,, -/assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_oak.png,,,,,,, -/assets/minecraft/textures/blocks,planks_spruce.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,nether_brick.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,fence_acacia.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_acacia.png,,,,,,, -/assets/minecraft/textures/blocks,fence_big_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,fence_birch.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_birch.png,,,,,,, -/assets/minecraft/textures/blocks,fence_jungle.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_jungle.png,,,,,,, -/assets/minecraft/textures/blocks,fence_nether_brick.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,fence_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_oak.png,,,,,,, -/assets/minecraft/textures/blocks,fence_spruce.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_spruce.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_acacia.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_acacia.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_big_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_big_oak.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_birch.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_birch.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_jungle.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_jungle.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_oak.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_oak.png,,,,,,, -/assets/minecraft/textures/blocks,fence_gate_spruce.png,/mods/ITEMS/mcl_fences/textures,mcl_fences_fence_gate_spruce.png,,,,,,, -/assets/minecraft/textures/entity,sign.png,/mods/ITEMS/mcl_signs/textures,mcl_signs_sign.png,,,,,,, -/assets/minecraft/textures/entity,banner_base.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_banner_base.png,,,,,,, -/assets/minecraft/textures/entity/banner,base.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_base.png,,,,,,, -/assets/minecraft/textures/blocks,planks_oak.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_fallback_wood.png,,,,,,, -/assets/minecraft/textures/items,banner_base.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_item_base.png,,,,,,, -/assets/minecraft/textures/items,banner_overlay.png,/mods/ITEMS/mcl_banners/textures,mcl_banners_item_overlay.png,,,,,,, -/assets/minecraft/textures/blocks,portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_portal.png,,,,,,, -/assets/minecraft/textures/entity,end_portal.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_end_portal.png,,,,,,, -/assets/minecraft/textures/environment,end_sky.png,/mods/PLAYER/mcl_playerplus/textures,mcl_playerplus_end_sky.png,,,,,,, -/assets/minecraft/textures/entity/chest,normal.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_normal.png,,,,,,, -/assets/minecraft/textures/entity/chest,normal_double.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_normal_double.png,,,,,,, -/assets/minecraft/textures/entity/chest,trapped.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_trapped.png,,,,,,, -/assets/minecraft/textures/entity/chest,trapped_double.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_trapped_double.png,,,,,,, -/assets/minecraft/textures/entity/chest,ender.png,/mods/ITEMS/mcl_chests/textures,mcl_chests_ender.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_top.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_endframe_top.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_side.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_endframe_side.png,,,,,,, -/assets/minecraft/textures/blocks,endframe_eye.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_endframe_eye.png,,,,,,, -/assets/minecraft/textures/blocks,end_stone.png,/mods/ITEMS/mcl_portals/textures,mcl_portals_endframe_bottom.png,,,,,,, -/assets/minecraft/textures/blocks,red_nether_brick.png,,mcl_fences_fence_red_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,red_nether_brick.png,,mcl_fences_fence_gate_red_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,nether_brick.png,,mcl_fences_fence_gate_nether_brick.png,,,,,,, -/assets/minecraft/textures/blocks,stonebrick_carved.png,,mcl_supplemental_stonebrick_carved_slab.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone.png,/mods/ITEMS/mcl_walls/textures,mcl_walls_cobble_wall_top.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone.png,/mods/ITEMS/mcl_walls/textures,mcl_walls_cobble_wall_side.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone_mossy.png,/mods/ITEMS/mcl_walls/textures,mcl_walls_cobble_mossy_wall_top.png,,,,,,, -/assets/minecraft/textures/blocks,cobblestone_mossy.png,/mods/ITEMS/mcl_walls/textures,mcl_walls_cobble_mossy_wall_side.png,,,,,,, -/assets/minecraft/textures/blocks,grass_top.png,/mods/ITEMS/mcl_core/textures,mcl_core_grass_block_top.png,,,,,,, -/assets/minecraft/textures/blocks,grass_side_overlay.png,/mods/ITEMS/mcl_core/textures,mcl_core_grass_block_side_overlay.png,,,,,,, -/assets/minecraft/textures/items,book_enchanted.png,/mods/ITEMS/mcl_enchanting/textures,mcl_enchanting_book_enchanted.png,,,,,,, -/assets/minecraft/textures/items,experience_bottle.png,/mods/HUD/mcl_experience/textures,mcl_experience_bottle.png,,,,,,, +Source path,Source file,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? +/assets/minecraft/textures/particle,particles.png,mcl_particles_bubble.png,0,16,8,8,0,0,y +/assets/minecraft/textures/gui,icons.png,hbarmor_icon.png,34,9,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hbarmor_bgicon.png,16,9,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hudbars_icon_health.png,52,0,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hudbars_bgicon_health.png,16,0,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hudbars_icon_breath.png,16,18,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,heart.png,52,0,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,bubble.png,16,18,9,9,0,0,y +/assets/minecraft/textures/item,bucket.png,mcl_buckets_bucket.png,,,,,,, +/assets/minecraft/textures/item,water_bucket.png,mcl_buckets_water_bucket.png,,,,,,, +/assets/minecraft/textures/item,water_bucket.png,mcl_buckets_river_water_bucket.png,,,,,,, +/assets/minecraft/textures/item,axolotl_bucket.png,mcl_buckets_axolotl_bucket.png,,,,,,, +/assets/minecraft/textures/item,cod_bucket.png,mcl_buckets_cod_bucket.png,,,,,,, +/assets/minecraft/textures/item,pufferfish_bucket.png,mcl_buckets_pufferfish_bucket.png,,,,,,, +/assets/minecraft/textures/item,salmon_bucket.png,mcl_buckets_salmon_bucket.png,,,,,,, +/assets/minecraft/textures/item,tropical_fish_bucket.png,mcl_buckets_tropical_fish_bucket.png,,,,,,, +/assets/minecraft/textures/item,lava_bucket.png,mcl_buckets_lava_bucket.png,,,,,,, +/assets/minecraft/textures/item,milk_bucket.png,mcl_mobitems_bucket_milk.png,,,,,,, +/assets/minecraft/textures/block,anvil.png,mcl_anvils_anvil_base.png,,,,,,, +/assets/minecraft/textures/block,anvil.png,mcl_anvils_anvil_side.png,,,,,,, +/assets/minecraft/textures/block,anvil_top.png,mcl_anvils_anvil_top_damaged_0.png,,,,,,, +/assets/minecraft/textures/block,chipped_anvil_top.png,mcl_anvils_anvil_top_damaged_1.png,,,,,,, +/assets/minecraft/textures/block,damaged_anvil_top.png,mcl_anvils_anvil_top_damaged_2.png,,,,,,, +/assets/minecraft/textures/item,name_tag.png,mobs_nametag.png,,,,,,, +/assets/minecraft/textures/gui,icons.png,mobs_blood.png,16,0,9,9,0,0,y +/assets/minecraft/textures/entity/bed,red.png,mcl_beds_bed_red.png,,,,,,, +/assets/minecraft/textures/item,acacia_boat.png,mcl_boats_acacia_boat.png,,,,,,, +/assets/minecraft/textures/item,oak_boat.png,mcl_boats_oak_boat.png,,,,,,, +/assets/minecraft/textures/item,spruce_boat.png,mcl_boats_spruce_boat.png,,,,,,, +/assets/minecraft/textures/item,dark_oak_boat.png,mcl_boats_dark_oak_boat.png,,,,,,, +/assets/minecraft/textures/item,jungle_boat.png,mcl_boats_jungle_boat.png,,,,,,, +/assets/minecraft/textures/item,birch_boat.png,mcl_boats_birch_boat.png,,,,,,, +/assets/minecraft/textures/item,cherry_boat.png,mcl_boats_cherry_boat.png,,,,,,, +/assets/minecraft/textures/item,mangrove_boat.png,mcl_boats_mangrove_boat.png,,,,,,, +/assets/minecraft/textures/item,acacia_chest_boat.png,mcl_boats_acacia_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,birch_chest_boat.png,mcl_boats_birch_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,cherry_chest_boat.png,mcl_boats_cherry_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,dark_oak_chest_boat.png,mcl_boats_dark_oak_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,jungle_chest_boat.png,mcl_boats_jungle_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,mangrove_chest_boat.png,mcl_boats_mangrove_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,oak_chest_boat.png,mcl_boats_oak_chest_boat.png,,,,,,, +/assets/minecraft/textures/item,spruce_chest_boat.png,mcl_boats_spruce_chest_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,acacia.png,mcl_boats_texture_acacia_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,oak.png,mcl_boats_texture_oak_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,dark_oak.png,mcl_boats_texture_dark_oak_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,spruce.png,mcl_boats_texture_spruce_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,birch.png,mcl_boats_texture_birch_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,jungle.png,mcl_boats_texture_jungle_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,mangrove.png,mcl_boats_texture_mangrove_boat.png,,,,,,, +/assets/minecraft/textures/entity/boat,cherry.png,mcl_boats_texture_cherry_boat.png,,,,,,, +/assets/minecraft/textures/block,enchanting_table_bottom.png,mcl_enchanting_table_bottom.png,,,,,,, +/assets/minecraft/textures/block,enchanting_table_side.png,mcl_enchanting_table_side.png,,,,,,, +/assets/minecraft/textures/block,enchanting_table_top.png,mcl_enchanting_table_top.png,,,,,,, +/assets/minecraft/textures/item,book.png,default_book.png,,,,,,, +/assets/minecraft/textures/block,bookshelf.png,default_bookshelf.png,,,,,,, +/assets/minecraft/textures/item,writable_book.png,mcl_books_book_writable.png,,,,,,, +/assets/minecraft/textures/item,written_book.png,mcl_books_book_written.png,,,,,,, +/assets/minecraft/textures/item,cake.png,cake.png,,,,,,, +/assets/minecraft/textures/block,cake_bottom.png,cake_bottom.png,,,,,,, +/assets/minecraft/textures/block,cake_top.png,cake_top.png,,,,,,, +/assets/minecraft/textures/block,cake_side.png,cake_side.png,,,,,,, +/assets/minecraft/textures/block,cake_inner.png,cake_inner.png,,,,,,, +/assets/minecraft/textures/item,cauldron.png,mcl_cauldrons_cauldron.png,,,,,,, +/assets/minecraft/textures/block,cauldron_bottom.png,mcl_cauldrons_cauldron_bottom.png,,,,,,, +/assets/minecraft/textures/block,cauldron_top.png,mcl_cauldrons_cauldron_top.png,,,,,,, +/assets/minecraft/textures/block,cauldron_side.png,mcl_cauldrons_cauldron_side.png,,,,,,, +/assets/minecraft/textures/block,cauldron_inner.png,mcl_cauldrons_cauldron_inner.png,,,,,,, +/assets/minecraft/textures/item,cocoa_beans.png,mcl_cocoas_cocoa_beans.png,,,,,,, +/assets/minecraft/textures/block,cocoa_stage0.png,mcl_cocoas_cocoa_stage_0.png,,,,,,, +/assets/minecraft/textures/block,cocoa_stage1.png,mcl_cocoas_cocoa_stage_1.png,,,,,,, +/assets/minecraft/textures/block,cocoa_stage2.png,mcl_cocoas_cocoa_stage_2.png,,,,,,, +/assets/minecraft/textures/block,terracotta.png,hardened_clay.png,,,,,,, +/assets/minecraft/textures/block,black_terracotta.png,hardened_clay_stained_black.png,,,,,,, +/assets/minecraft/textures/block,blue_terracotta.png,hardened_clay_stained_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_terracotta.png,hardened_clay_stained_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_terracotta.png,hardened_clay_stained_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_terracotta.png,hardened_clay_stained_grey.png,,,,,,, +/assets/minecraft/textures/block,green_terracotta.png,hardened_clay_stained_green.png,,,,,,, +/assets/minecraft/textures/block,light_blue_terracotta.png,hardened_clay_stained_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_terracotta.png,hardened_clay_stained_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_terracotta.png,hardened_clay_stained_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_terracotta.png,hardened_clay_stained_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_terracotta.png,hardened_clay_stained_pink.png,,,,,,, +/assets/minecraft/textures/block,purple_terracotta.png,hardened_clay_stained_purple.png,,,,,,, +/assets/minecraft/textures/block,red_terracotta.png,hardened_clay_stained_red.png,,,,,,, +/assets/minecraft/textures/block,light_gray_terracotta.png,hardened_clay_stained_silver.png,,,,,,, +/assets/minecraft/textures/block,white_terracotta.png,hardened_clay_stained_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_terracotta.png,hardened_clay_stained_yellow.png,,,,,,, +/assets/minecraft/textures/block,black_concrete.png,mcl_colorblocks_concrete_black.png,,,,,,, +/assets/minecraft/textures/block,blue_concrete.png,mcl_colorblocks_concrete_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_concrete.png,mcl_colorblocks_concrete_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_concrete.png,mcl_colorblocks_concrete_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_concrete.png,mcl_colorblocks_concrete_grey.png,,,,,,, +/assets/minecraft/textures/block,green_concrete.png,mcl_colorblocks_concrete_green.png,,,,,,, +/assets/minecraft/textures/block,light_blue_concrete.png,mcl_colorblocks_concrete_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_concrete.png,mcl_colorblocks_concrete_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_concrete.png,mcl_colorblocks_concrete_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_concrete.png,mcl_colorblocks_concrete_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_concrete.png,mcl_colorblocks_concrete_pink.png,,,,,,, +/assets/minecraft/textures/block,purple_concrete.png,mcl_colorblocks_concrete_purple.png,,,,,,, +/assets/minecraft/textures/block,red_concrete.png,mcl_colorblocks_concrete_red.png,,,,,,, +/assets/minecraft/textures/block,light_gray_concrete.png,mcl_colorblocks_concrete_silver.png,,,,,,, +/assets/minecraft/textures/block,white_concrete.png,mcl_colorblocks_concrete_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_concrete.png,mcl_colorblocks_concrete_yellow.png,,,,,,, +/assets/minecraft/textures/block,black_concrete_powder.png,mcl_colorblocks_concrete_powder_black.png,,,,,,, +/assets/minecraft/textures/block,blue_concrete_powder.png,mcl_colorblocks_concrete_powder_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_concrete_powder.png,mcl_colorblocks_concrete_powder_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_concrete_powder.png,mcl_colorblocks_concrete_powder_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_concrete_powder.png,mcl_colorblocks_concrete_powder_grey.png,,,,,,, +/assets/minecraft/textures/block,green_concrete_powder.png,mcl_colorblocks_concrete_powder_green.png,,,,,,, +/assets/minecraft/textures/block,light_blue_concrete_powder.png,mcl_colorblocks_concrete_powder_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_concrete_powder.png,mcl_colorblocks_concrete_powder_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_concrete_powder.png,mcl_colorblocks_concrete_powder_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_concrete_powder.png,mcl_colorblocks_concrete_powder_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_concrete_powder.png,mcl_colorblocks_concrete_powder_pink.png,,,,,,, +/assets/minecraft/textures/block,purple_concrete_powder.png,mcl_colorblocks_concrete_powder_purple.png,,,,,,, +/assets/minecraft/textures/block,red_concrete_powder.png,mcl_colorblocks_concrete_powder_red.png,,,,,,, +/assets/minecraft/textures/block,light_gray_concrete_powder.png,mcl_colorblocks_concrete_powder_silver.png,,,,,,, +/assets/minecraft/textures/block,white_concrete_powder.png,mcl_colorblocks_concrete_powder_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_concrete_powder.png,mcl_colorblocks_concrete_powder_yellow.png,,,,,,, +/assets/minecraft/textures/block,black_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_black.png,,,,,,, +/assets/minecraft/textures/block,blue_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_grey.png,,,,,,, +/assets/minecraft/textures/block,green_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_green.png,,,,,,, +/assets/minecraft/textures/block,light_blue_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_pink.png,,,,,,, +/assets/minecraft/textures/block,purple_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_purple.png,,,,,,, +/assets/minecraft/textures/block,red_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_red.png,,,,,,, +/assets/minecraft/textures/block,light_gray_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_silver.png,,,,,,, +/assets/minecraft/textures/block,white_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_glazed_terracotta.png,mcl_colorblocks_glazed_terracotta_yellow.png,,,,,,, +/assets/minecraft/textures/block,cherry_sapling.png,mcl_cherry_blossom_sapling.png,,,,,,, +/assets/minecraft/textures/block,oak_sapling.png,default_sapling.png,,,,,,, +/assets/minecraft/textures/block,acacia_sapling.png,default_acacia_sapling.png,,,,,,, +/assets/minecraft/textures/block,spruce_sapling.png,mcl_core_sapling_spruce.png,,,,,,, +/assets/minecraft/textures/block,jungle_sapling.png,default_junglesapling.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_sapling.png,mcl_core_sapling_big_oak.png,,,,,,, +/assets/minecraft/textures/block,birch_sapling.png,mcl_core_sapling_birch.png,,,,,,, +/assets/minecraft/textures/block,mangrove_propagule.png,mcl_mangrove_propagule.png,,,,,,, +/assets/minecraft/textures/block,mangrove_propagule_hanging.png,mcl_mangrove_propagule_hanging.png,,,,,,, +/assets/minecraft/textures/item,mangrove_propagule.png,mcl_mangrove_propagule_item.png,,,,,,, +/assets/minecraft/textures/block,crimson_fungus.png,mcl_crimson_crimson_fungus.png,,,,,,, +/assets/minecraft/textures/block,warped_fungus.png,mcl_crimson_warped_fungus.png,,,,,,, +/assets/minecraft/textures/item,bamboo.png,mcl_bamboo_bamboo_shoot.png,,,,,,, +/assets/minecraft/textures/item,apple.png,default_apple.png,,,,,,, +/assets/minecraft/textures/item,golden_apple.png,mcl_core_apple_golden.png,,,,,,, +/assets/minecraft/textures/block,bricks.png,default_brick.png,,,,,,, +/assets/minecraft/textures/block,cactus_side.png,mcl_core_cactus_side.png,,,,,,, +/assets/minecraft/textures/block,cactus_top.png,mcl_core_cactus_top.png,,,,,,, +/assets/minecraft/textures/block,cactus_bottom.png,mcl_core_cactus_bottom.png,,,,,,, +/assets/minecraft/textures/item,brick.png,default_clay_brick.png,,,,,,, +/assets/minecraft/textures/item,clay_ball.png,default_clay_lump.png,,,,,,, +/assets/minecraft/textures/block,clay.png,default_clay.png,,,,,,, +/assets/minecraft/textures/block,coal_block.png,default_coal_block.png,,,,,,, +/assets/minecraft/textures/item,coal.png,default_coal_lump.png,,,,,,, +/assets/minecraft/textures/block,cobblestone.png,default_cobble.png,,,,,,, +/assets/minecraft/textures/block,diamond_block.png,default_diamond_block.png,,,,,,, +/assets/minecraft/textures/item,diamond.png,default_diamond.png,,,,,,, +/assets/minecraft/textures/block,dirt.png,default_dirt.png,,,,,,, +/assets/minecraft/textures/block,dead_bush.png,default_dry_shrub.png,,,,,,, +/assets/minecraft/textures/item,flint.png,default_flint.png,,,,,,, +/assets/minecraft/textures/block,glass.png,default_glass.png,,,,,,, +/assets/minecraft/textures/block,black_stained_glass.png,mcl_core_glass_black.png,,,,,,, +/assets/minecraft/textures/block,blue_stained_glass.png,mcl_core_glass_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_stained_glass.png,mcl_core_glass_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_stained_glass.png,mcl_core_glass_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_stained_glass.png,mcl_core_glass_gray.png,,,,,,, +/assets/minecraft/textures/block,green_stained_glass.png,mcl_core_glass_green.png,,,,,,, +/assets/minecraft/textures/block,light_blue_stained_glass.png,mcl_core_glass_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_stained_glass.png,mcl_core_glass_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_stained_glass.png,mcl_core_glass_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_stained_glass.png,mcl_core_glass_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_stained_glass.png,mcl_core_glass_pink.png,,,,,,, +/assets/minecraft/textures/block,purple_stained_glass.png,mcl_core_glass_purple.png,,,,,,, +/assets/minecraft/textures/block,red_stained_glass.png,mcl_core_glass_red.png,,,,,,, +/assets/minecraft/textures/block,light_gray_stained_glass.png,mcl_core_glass_silver.png,,,,,,, +/assets/minecraft/textures/block,white_stained_glass.png,mcl_core_glass_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_stained_glass.png,mcl_core_glass_yellow.png,,,,,,, +/assets/minecraft/textures/block,gold_block.png,default_gold_block.png,,,,,,, +/assets/minecraft/textures/block,gold_block.png,mcl_stairs_gold_block_slab.png,,,,,,, +/assets/minecraft/textures/item,gold_ingot.png,default_gold_ingot.png,,,,,,, +/assets/minecraft/textures/item,gold_nugget.png,mcl_core_gold_nugget.png,,,,,,, +/assets/minecraft/textures/block,netherite_block.png,mcl_nether_netheriteblock.png,,,,,,, +/assets/minecraft/textures/item,netherite_ingot.png,mcl_nether_netherite_ingot.png,,,,,,, +/assets/minecraft/textures/item,netherite_scrap.png,mcl_nether_netherite_scrap.png,,,,,,, +/assets/minecraft/textures/block,gravel.png,default_gravel.png,,,,,,, +/assets/minecraft/textures/block,ice.png,default_ice.png,,,,,,, +/assets/minecraft/textures/block,ladder.png,default_ladder.png,,,,,,, +/assets/minecraft/textures/block,lava_still.png,mcl_core_lava_source_animation.png,,,,,,, +/assets/minecraft/textures/block,lava_flow.png,mcl_core_lava_flow_animation.png,,,,,,, +/assets/minecraft/textures/block,mossy_cobblestone.png,default_mossycobble.png,,,,,,, +/assets/minecraft/textures/block,obsidian.png,default_obsidian.png,,,,,,, +/assets/minecraft/textures/block,crying_obsidian.png,mcl_core_crying_obsidian.png,,,,,,, +/assets/minecraft/textures/item,paper.png,default_paper.png,,,,,,, +/assets/minecraft/textures/block,sugar_cane.png,mcl_core_papyrus.png,,,,,,, +/assets/minecraft/textures/block,sand.png,default_sand.png,,,,,,, +/assets/minecraft/textures/block,snow.png,default_snow.png,,,,,,, +/assets/minecraft/textures/block,iron_block.png,default_steel_block.png,,,,,,, +/assets/minecraft/textures/block,iron_block.png,mcl_stairs_iron_block_slab.png,,,,,,, +/assets/minecraft/textures/item,iron_ingot.png,default_steel_ingot.png,,,,,,, +/assets/minecraft/textures/item,stick.png,default_stick.png,,,,,,, +/assets/minecraft/textures/block,copper_block.png,mcl_copper_block.png,,,,,,, +/assets/minecraft/textures/block,cut_copper.png,mcl_copper_block_cut.png,,,,,,, +/assets/minecraft/textures/block,raw_copper_block.png,mcl_copper_block_raw.png,,,,,,, +/assets/minecraft/textures/block,exposed_copper.png,mcl_copper_exposed.png,,,,,,, +/assets/minecraft/textures/block,exposed_cut_copper.png,mcl_copper_exposed_cut.png,,,,,,, +/assets/minecraft/textures/item,copper_ingot.png,mcl_copper_ingot.png,,,,,,, +/assets/minecraft/textures/block,copper_ore.png,mcl_copper_ore.png,,,,,,, +/assets/minecraft/textures/block,oxidized_copper.png,mcl_copper_oxidized.png,,,,,,, +/assets/minecraft/textures/block,oxidized_cut_copper.png,mcl_copper_oxidized_cut.png,,,,,,, +/assets/minecraft/textures/item,raw_copper.png,mcl_copper_raw.png,,,,,,, +/assets/minecraft/textures/block,weathered_copper.png,mcl_copper_weathered.png,,,,,,, +/assets/minecraft/textures/block,weathered_cut_copper.png,mcl_copper_weathered_cut.png,,,,,,, +/assets/minecraft/textures/block,deepslate_copper_ore.png,mcl_deepslate_copper_ore.png,,,,,,, +/assets/minecraft/textures/block,stone_bricks.png,default_stone_brick.png,,,,,,, +/assets/minecraft/textures/block,stone.png,default_stone.png,,,,,,, +/assets/minecraft/textures/block,water_still.png,mcl_core_water_source_animation.png,,,,,,, +/assets/minecraft/textures/block,water_flow.png,mcl_core_water_flow_animation.png,,,,,,, +/assets/minecraft/textures/block,andesite.png,mcl_core_andesite.png,,,,,,, +/assets/minecraft/textures/block,polished_andesite.png,mcl_core_andesite_smooth.png,,,,,,, +/assets/minecraft/textures/block,polished_andesite.png,mcl_stairs_andesite_smooth_slab.png,,,,,,, +/assets/minecraft/textures/item,barrier.png,mcl_core_barrier.png,,,,,,, +/assets/minecraft/textures/block,bedrock.png,mcl_core_bedrock.png,,,,,,, +/assets/minecraft/textures/item,bone_meal.png,mcl_bone_meal_bone_meal.png,,,,,,, +/assets/minecraft/textures/item,bone.png,mcl_mobitems_bone.png,,,,,,, +/assets/minecraft/textures/block,bone_block_side.png,mcl_core_bone_block_side.png,,,,,,, +/assets/minecraft/textures/block,bone_block_top.png,mcl_core_bone_block_top.png,,,,,,, +/assets/minecraft/textures/item,bowl.png,mcl_core_bowl.png,,,,,,, +/assets/minecraft/textures/item,charcoal.png,mcl_core_charcoal.png,,,,,,, +/assets/minecraft/textures/block,coal_ore.png,mcl_core_coal_ore.png,,,,,,, +/assets/minecraft/textures/block,coarse_dirt.png,mcl_core_coarse_dirt.png,,,,,,, +/assets/minecraft/textures/block,diamond_ore.png,mcl_core_diamond_ore.png,,,,,,, +/assets/minecraft/textures/block,ancient_debris_side.png,mcl_nether_ancient_debris_side.png,,,,,,, +/assets/minecraft/textures/block,ancient_debris_top.png,mcl_nether_ancient_debris_top.png,,,,,,, +/assets/minecraft/textures/block,diorite.png,mcl_core_diorite.png,,,,,,, +/assets/minecraft/textures/block,polished_diorite.png,mcl_core_diorite_smooth.png,,,,,,, +/assets/minecraft/textures/block,polished_diorite.png,mcl_stairs_diorite_smooth_slab.png,,,,,,, +/assets/minecraft/textures/block,podzol_side.png,mcl_core_dirt_podzol_side.png,,,,,,, +/assets/minecraft/textures/block,podzol_top.png,mcl_core_dirt_podzol_top.png,,,,,,, +/assets/minecraft/textures/block,crimson_nylium.png,mcl_crimson_crimson_nylium.png,,,,,,, +/assets/minecraft/textures/block,crimson_nylium_side.png,mcl_crimson_crimson_nylium_side.png,,,,,,, +/assets/minecraft/textures/block,warped_nylium.png,mcl_crimson_warped_nylium.png,,,,,,, +/assets/minecraft/textures/block,warped_nylium_side.png,mcl_crimson_warped_nylium_side.png,,,,,,, +/assets/minecraft/textures/block,emerald_block.png,mcl_core_emerald_block.png,,,,,,, +/assets/minecraft/textures/block,emerald_ore.png,mcl_core_emerald_ore.png,,,,,,, +/assets/minecraft/textures/item,emerald.png,mcl_core_emerald.png,,,,,,, +/assets/minecraft/textures/block,frosted_ice_0.png,mcl_core_frosted_ice_0.png,,,,,,, +/assets/minecraft/textures/block,frosted_ice_1.png,mcl_core_frosted_ice_1.png,,,,,,, +/assets/minecraft/textures/block,frosted_ice_2.png,mcl_core_frosted_ice_2.png,,,,,,, +/assets/minecraft/textures/block,frosted_ice_3.png,mcl_core_frosted_ice_3.png,,,,,,, +/assets/minecraft/textures/item,raw_gold.png,mcl_raw_ores_raw_gold.png,,,,,,, +/assets/minecraft/textures/block,raw_gold_block.png,mcl_raw_ores_raw_gold_block.png,,,,,,, +/assets/minecraft/textures/block,gold_ore.png,mcl_core_gold_ore.png,,,,,,, +/assets/minecraft/textures/block,nether_gold_ore.png,mcl_nether_gold_ore.png,,,,,,, +/assets/minecraft/textures/block,granite.png,mcl_core_granite.png,,,,,,, +/assets/minecraft/textures/block,polished_granite.png,mcl_core_granite_smooth.png,,,,,,, +/assets/minecraft/textures/block,polished_granite.png,mcl_stairs_granite_smooth_slab.png,,,,,,, +/assets/minecraft/textures/block,dirt_path_side.png,mcl_core_grass_path_side.png,,,,,,, +/assets/minecraft/textures/block,dirt_path_top.png,mcl_core_grass_path_top.png,,,,,,, +/assets/minecraft/textures/block,grass_block_snow.png,mcl_core_grass_side_snowed.png,,,,,,, +/assets/minecraft/textures/block,grass_block_side.png,mcl_dirt_grass_shadow.png,,,,,,, +/assets/minecraft/textures/block,packed_ice.png,mcl_core_ice_packed.png,,,,,,, +/assets/minecraft/textures/block,raw_iron_block.png,mcl_raw_ores_raw_iron_block.png,,,,,,, +/assets/minecraft/textures/item,raw_iron.png,mcl_raw_ores_raw_iron.png,,,,,,, +/assets/minecraft/textures/item,iron_nugget.png,mcl_core_iron_nugget.png,,,,,,, +/assets/minecraft/textures/block,iron_ore.png,mcl_core_iron_ore.png,,,,,,, +/assets/minecraft/textures/block,lapis_block.png,mcl_core_lapis_block.png,,,,,,, +/assets/minecraft/textures/block,lapis_block.png,mcl_stairs_lapis_block_slab.png,,,,,,, +/assets/minecraft/textures/block,lapis_ore.png,mcl_core_lapis_ore.png,,,,,,, +/assets/minecraft/textures/item,lapis_lazuli.png,mcl_core_lapis.png,,,,,,, +/assets/minecraft/textures/block,bamboo_planks.png,mcl_bamboo_bamboo_plank.png,,,,,,, +/assets/minecraft/textures/block,bamboo_mosaic.png,mcl_bamboo_bamboo_plank_mosaic.png,,,,,,, +/assets/minecraft/textures/block,cherry_planks.png,mcl_cherry_blossom_planks.png,,,,,,, +/assets/minecraft/textures/block,acacia_planks.png,default_acacia_wood.png,,,,,,, +/assets/minecraft/textures/block,birch_planks.png,mcl_core_planks_birch.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_planks.png,mcl_core_planks_big_oak.png,,,,,,, +/assets/minecraft/textures/block,jungle_planks.png,default_junglewood.png,,,,,,, +/assets/minecraft/textures/block,oak_planks.png,default_wood.png,,,,,,, +/assets/minecraft/textures/block,spruce_planks.png,mcl_core_planks_spruce.png,,,,,,, +/assets/minecraft/textures/block,mangrove_planks.png,mcl_mangrove_planks.png,,,,,,, +/assets/minecraft/textures/block,crimson_planks.png,mcl_crimson_crimson_hyphae_wood.png,,,,,,, +/assets/minecraft/textures/block,warped_planks.png,mcl_crimson_warped_hyphae_wood.png,,,,,,, +/assets/minecraft/textures/block,bamboo_block.png,mcl_bamboo_bamboo_block.png,,,,,,, +/assets/minecraft/textures/block,bamboo_block_top.png,mcl_bamboo_bamboo_bottom.png,,,,,,, +/assets/minecraft/textures/block,cherry_log.png,mcl_cherry_blossom_log.png,,,,,,, +/assets/minecraft/textures/block,cherry_log_top.png,mcl_cherry_blossom_log_top.png,,,,,,, +/assets/minecraft/textures/block,acacia_log.png,default_acacia_tree.png,,,,,,, +/assets/minecraft/textures/block,acacia_log_top.png,default_acacia_tree_top.png,,,,,,, +/assets/minecraft/textures/block,birch_log.png,mcl_core_log_birch.png,,,,,,, +/assets/minecraft/textures/block,birch_log_top.png,mcl_core_log_birch_top.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_log.png,mcl_core_log_big_oak.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_log_top.png,mcl_core_log_big_oak_top.png,,,,,,, +/assets/minecraft/textures/block,jungle_log.png,default_jungletree.png,,,,,,, +/assets/minecraft/textures/block,jungle_log_top.png,default_jungletree_top.png,,,,,,, +/assets/minecraft/textures/block,oak_log.png,default_tree.png,,,,,,, +/assets/minecraft/textures/block,oak_log_top.png,default_tree_top.png,,,,,,, +/assets/minecraft/textures/block,spruce_log.png,mcl_core_log_spruce.png,,,,,,, +/assets/minecraft/textures/block,spruce_log_top.png,mcl_core_log_spruce_top.png,,,,,,, +/assets/minecraft/textures/block,mangrove_log.png,mcl_mangrove_log.png,,,,,,, +/assets/minecraft/textures/block,mangrove_log_top.png,mcl_mangrove_log_top.png,,,,,,, +/assets/minecraft/textures/block,crimson_stem_top.png,mcl_crimson_crimson_hyphae.png,,,,,,, +/assets/minecraft/textures/block,warped_stem_top.png,mcl_crimson_warped_hyphae.png,,,,,,, +/assets/minecraft/textures/block,stripped_bamboo_block.png,mcl_bamboo_bamboo_block_stripped.png,,,,,,, +/assets/minecraft/textures/block,stripped_bamboo_block_top.png,mcl_bamboo_bamboo_bottom_stripped.png,,,,,,, +/assets/minecraft/textures/block,stripped_cherry_log.png,mcl_cherry_blossom_log_stripped.png,,,,,,, +/assets/minecraft/textures/block,stripped_cherry_log_top.png,mcl_cherry_blossom_log_top_stripped.png,,,,,,, +/assets/minecraft/textures/block,stripped_acacia_log.png,mcl_core_stripped_acacia_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_acacia_log_top.png,mcl_core_stripped_acacia_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_birch_log.png,mcl_core_stripped_birch_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_birch_log_top.png,mcl_core_stripped_birch_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_dark_oak_log.png,mcl_core_stripped_dark_oak_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_dark_oak_log_top.png,mcl_core_stripped_dark_oak_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_jungle_log.png,mcl_core_stripped_jungle_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_jungle_log_top.png,mcl_core_stripped_jungle_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_oak_log.png,mcl_core_stripped_oak_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_oak_log_top.png,mcl_core_stripped_oak_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_spruce_log.png,mcl_core_stripped_spruce_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_spruce_log_top.png,mcl_core_stripped_spruce_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_mangrove_log.png,mcl_stripped_mangrove_log_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_mangrove_log_top.png,mcl_stripped_mangrove_log_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_crimson_stem.png,mcl_crimson_crimson_stem_stripped_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_crimson_stem_top.png,mcl_crimson_crimson_stem_stripped_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_crimson_stem.png,mcl_crimson_stripped_crimson_stem.png,,,,,,, +/assets/minecraft/textures/block,stripped_crimson_stem.png,mcl_crimson_stripped_crimson_stem_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_crimson_stem_top.png,mcl_crimson_stripped_crimson_stem_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_warped_stem.png,mcl_crimson_stripped_warped_stem.png,,,,,,, +/assets/minecraft/textures/block,stripped_warped_stem.png,mcl_crimson_stripped_warped_stem_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_warped_stem_top.png,mcl_crimson_stripped_warped_stem_top.png,,,,,,, +/assets/minecraft/textures/block,stripped_warped_stem.png,mcl_crimson_warped_stem_stripped_side.png,,,,,,, +/assets/minecraft/textures/block,stripped_warped_stem_top.png,mcl_crimson_warped_stem_stripped_top.png,,,,,,, +/assets/minecraft/textures/block,mycelium_side.png,mcl_core_mycelium_side.png,,,,,,, +/assets/minecraft/textures/block,mycelium_top.png,mcl_core_mycelium_top.png,,,,,,, +/assets/minecraft/textures/block,red_sand.png,mcl_core_red_sand.png,,,,,,, +/assets/minecraft/textures/block,red_sandstone_bottom.png,mcl_core_red_sandstone_bottom.png,,,,,,, +/assets/minecraft/textures/block,cut_red_sandstone.png,mcl_core_red_sandstone_smooth.png,,,,,,, +/assets/minecraft/textures/block,red_sandstone.png,mcl_core_red_sandstone_normal.png,,,,,,, +/assets/minecraft/textures/block,chiseled_red_sandstone.png,mcl_core_red_sandstone_carved.png,,,,,,, +/assets/minecraft/textures/block,red_sandstone_top.png,mcl_core_red_sandstone_top.png,,,,,,, +/assets/minecraft/textures/block,redstone_ore.png,mcl_core_redstone_ore.png,,,,,,, +/assets/minecraft/textures/item,sugar_cane.png,mcl_core_reeds.png,,,,,,, +/assets/minecraft/textures/block,sandstone_bottom.png,mcl_core_sandstone_bottom.png,,,,,,, +/assets/minecraft/textures/block,cut_sandstone.png,mcl_core_sandstone_smooth.png,,,,,,, +/assets/minecraft/textures/block,chiseled_sandstone.png,mcl_core_sandstone_carved.png,,,,,,, +/assets/minecraft/textures/block,sandstone.png,mcl_core_sandstone_normal.png,,,,,,, +/assets/minecraft/textures/block,sandstone_top.png,mcl_core_sandstone_top.png,,,,,,, +/assets/minecraft/textures/block,slime_block.png,mcl_core_slime.png,,,,,,, +/assets/minecraft/textures/block,smooth_stone.png,mcl_core_stonebrick_carved.png,,,,,,, +/assets/minecraft/textures/block,cracked_stone_bricks.png,mcl_core_stonebrick_cracked.png,,,,,,, +/assets/minecraft/textures/block,mossy_stone_bricks.png,mcl_core_stonebrick_mossy.png,,,,,,, +/assets/minecraft/textures/item,sugar.png,mcl_core_sugar.png,,,,,,, +/assets/minecraft/textures/block,cobweb.png,mcl_core_web.png,,,,,,, +/assets/minecraft/textures/block,crafting_table_front.png,crafting_workbench_front.png,,,,,,, +/assets/minecraft/textures/block,crafting_table_side.png,crafting_workbench_side.png,,,,,,, +/assets/minecraft/textures/block,crafting_table_top.png,crafting_workbench_top.png,,,,,,, +/assets/minecraft/textures/block,fletching_table_front.png,fletching_table_front.png,,,,,,, +/assets/minecraft/textures/block,fletching_table_side.png,fletching_table_side.png,,,,,,, +/assets/minecraft/textures/block,fletching_table_top.png,fletching_table_top.png,,,,,,, +/assets/minecraft/textures/block,cartography_table_side1.png,mcl_cartography_table_side1.png,,,,,,, +/assets/minecraft/textures/block,cartography_table_side2.png,mcl_cartography_table_side2.png,,,,,,, +/assets/minecraft/textures/block,cartography_table_side3.png,mcl_cartography_table_side3.png,,,,,,, +/assets/minecraft/textures/block,cartography_table_top.png,mcl_cartography_table_top.png,,,,,,, +/assets/minecraft/textures/block,composter_bottom.png,mcl_composter_bottom.png,,,,,,, +/assets/minecraft/textures/block,composter_compost.png,mcl_composter_compost.png,,,,,,, +/assets/minecraft/textures/block,composter_ready.png,mcl_composter_ready.png,,,,,,, +/assets/minecraft/textures/block,composter_side.png,mcl_composter_side.png,,,,,,, +/assets/minecraft/textures/block,composter_top.png,mcl_composter_top.png,,,,,,, +/assets/minecraft/textures/block,smithing_table_bottom.png,mcl_smithing_table_bottom.png,,,,,,, +/assets/minecraft/textures/block,smithing_table_front.png,mcl_smithing_table_front.png,,,,,,, +/assets/minecraft/textures/block,smithing_table_side.png,mcl_smithing_table_side.png,,,,,,, +/assets/minecraft/textures/block,smithing_table_top.png,mcl_smithing_table_top.png,,,,,,, +/assets/minecraft/textures/block,loom_bottom.png,loom_bottom.png,,,,,,, +/assets/minecraft/textures/block,loom_front.png,loom_front.png,,,,,,, +/assets/minecraft/textures/block,loom_side.png,loom_side.png,,,,,,, +/assets/minecraft/textures/block,loom_top.png,loom_top.png,,,,,,, +/assets/minecraft/textures/block,acacia_door_bottom.png,mcl_doors_door_acacia_lower.png,,,,,,, +/assets/minecraft/textures/block,acacia_door_top.png,mcl_doors_door_acacia_upper.png,,,,,,, +/assets/minecraft/textures/block,birch_door_bottom.png,mcl_doors_door_birch_lower.png,,,,,,, +/assets/minecraft/textures/block,birch_door_top.png,mcl_doors_door_birch_upper.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_door_bottom.png,mcl_doors_door_dark_oak_lower.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_door_top.png,mcl_doors_door_dark_oak_upper.png,,,,,,, +/assets/minecraft/textures/block,iron_door_bottom.png,mcl_doors_door_iron_lower.png,,,,,,, +/assets/minecraft/textures/block,iron_door_top.png,mcl_doors_door_iron_upper.png,,,,,,, +/assets/minecraft/textures/block,jungle_door_bottom.png,mcl_doors_door_jungle_lower.png,,,,,,, +/assets/minecraft/textures/block,jungle_door_top.png,mcl_doors_door_jungle_upper.png,,,,,,, +/assets/minecraft/textures/block,spruce_door_bottom.png,mcl_doors_door_spruce_lower.png,,,,,,, +/assets/minecraft/textures/block,spruce_door_top.png,mcl_doors_door_spruce_upper.png,,,,,,, +/assets/minecraft/textures/block,oak_door_bottom.png,mcl_doors_door_wood_lower.png,,,,,,, +/assets/minecraft/textures/block,oak_door_top.png,mcl_doors_door_wood_upper.png,,,,,,, +/assets/minecraft/textures/block,bamboo_door_bottom.png,mcl_bamboo_door_bottom.png,,,,,,, +/assets/minecraft/textures/block,bamboo_door_top.png,mcl_bamboo_door_top.png,,,,,,, +/assets/minecraft/textures/block,warped_door_bottom.png,mcl_crimson_warped_door_bottom.png,,,,,,, +/assets/minecraft/textures/block,warped_door_top.png,mcl_crimson_warped_door_top.png,,,,,,, +/assets/minecraft/textures/block,crimson_door_bottom.png,mcl_crimson_crimson_door_bottom.png,,,,,,, +/assets/minecraft/textures/block,crimson_door_top.png,mcl_crimson_crimson_door_top.png,,,,,,, +/assets/minecraft/textures/block,mangrove_door_bottom.png,mcl_mangrove_door_bottom.png,,,,,,, +/assets/minecraft/textures/block,mangrove_door_top.png,mcl_mangrove_door_top.png,,,,,,, +/assets/minecraft/textures/block,oak_trapdoor.png,doors_trapdoor.png,,,,,,, +/assets/minecraft/textures/block,cherry_trapdoor.png,mcl_cherry_blossom_trapdoor.png,,,,,,, +/assets/minecraft/textures/block,acacia_trapdoor.png,mcl_doors_trapdoor_acacia.png,,,,,,, +/assets/minecraft/textures/block,bamboo_trapdoor.png,mcl_bamboo_trapdoor_side.png,,,,,,, +/assets/minecraft/textures/block,birch_trapdoor.png,mcl_doors_trapdoor_birch.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_trapdoor.png,mcl_doors_trapdoor_dark_oak.png,,,,,,, +/assets/minecraft/textures/block,jungle_trapdoor.png,mcl_doors_trapdoor_jungle.png,,,,,,, +/assets/minecraft/textures/block,mangrove_trapdoor.png,mcl_mangrove_trapdoor.png,,,,,,, +/assets/minecraft/textures/block,spruce_trapdoor.png,mcl_doors_trapdoor_spruce.png,,,,,,, +/assets/minecraft/textures/block,crimson_trapdoor.png,mcl_crimson_crimson_trapdoor.png,,,,,,, +/assets/minecraft/textures/block,warped_trapdoor.png,mcl_crimson_warped_trapdoor.png,,,,,,, +/assets/minecraft/textures/block,iron_trapdoor.png,doors_trapdoor_steel.png,,,,,,, +/assets/minecraft/textures/item,acacia_door.png,mcl_doors_door_acacia.png,,,,,,, +/assets/minecraft/textures/item,birch_door.png,mcl_doors_door_birch.png,,,,,,, +/assets/minecraft/textures/item,dark_oak_door.png,mcl_doors_door_dark_oak.png,,,,,,, +/assets/minecraft/textures/item,jungle_door.png,mcl_doors_door_jungle.png,,,,,,, +/assets/minecraft/textures/item,spruce_door.png,mcl_doors_door_spruce.png,,,,,,, +/assets/minecraft/textures/item,oak_door.png,doors_item_wood.png,,,,,,, +/assets/minecraft/textures/item,mangrove_door.png,mcl_mangrove_doors.png,,,,,,, +/assets/minecraft/textures/item,crimson_door.png,mcl_crimson_crimson_door.png,,,,,,, +/assets/minecraft/textures/item,warped_door.png,mcl_crimson_warped_door.png,,,,,,, +/assets/minecraft/textures/item,iron_door.png,doors_item_steel.png,,,,,,, +/assets/minecraft/textures/item,bamboo_door.png,mcl_bamboo_door_wield.png,,,,,,, +/assets/minecraft/textures/item,black_dye.png,mcl_dye_black.png,,,,,,, +/assets/minecraft/textures/item,blue_dye.png,mcl_dye_blue.png,,,,,,, +/assets/minecraft/textures/item,brown_dye.png,mcl_dye_brown.png,,,,,,, +/assets/minecraft/textures/item,cyan_dye.png,mcl_dye_cyan.png,,,,,,, +/assets/minecraft/textures/item,gray_dye.png,mcl_dye_dark_grey.png,,,,,,, +/assets/minecraft/textures/item,green_dye.png,mcl_dye_dark_green.png,,,,,,, +/assets/minecraft/textures/item,light_blue_dye.png,mcl_dye_lightblue.png,,,,,,, +/assets/minecraft/textures/item,lime_dye.png,mcl_dye_lime.png,,,,,,, +/assets/minecraft/textures/item,magenta_dye.png,mcl_dye_magenta.png,,,,,,, +/assets/minecraft/textures/item,orange_dye.png,mcl_dye_orange.png,,,,,,, +/assets/minecraft/textures/item,pink_dye.png,mcl_dye_pink.png,,,,,,, +/assets/minecraft/textures/item,purple_dye.png,mcl_dye_violet.png,,,,,,, +/assets/minecraft/textures/item,red_dye.png,mcl_dye_red.png,,,,,,, +/assets/minecraft/textures/item,light_gray_dye.png,mcl_dye_grey.png,,,,,,, +/assets/minecraft/textures/item,white_dye.png,mcl_dye_white.png,,,,,,, +/assets/minecraft/textures/item,yellow_dye.png,mcl_dye_yellow.png,,,,,,, +/assets/minecraft/textures/block,chorus_flower_dead.png,mcl_end_chorus_flower_dead.png,,,,,,, +/assets/minecraft/textures/block,chorus_flower.png,mcl_end_chorus_flower.png,,,,,,, +/assets/minecraft/textures/item,chorus_fruit.png,mcl_end_chorus_fruit.png,,,,,,, +/assets/minecraft/textures/item,popped_chorus_fruit.png,mcl_end_chorus_fruit_popped.png,,,,,,, +/assets/minecraft/textures/block,chorus_plant.png,mcl_end_chorus_plant.png,,,,,,, +/assets/minecraft/textures/block,dragon_egg.png,mcl_end_dragon_egg.png,,,,,,, +/assets/minecraft/textures/block,end_stone_bricks.png,mcl_end_end_bricks.png,,,,,,, +/assets/minecraft/textures/item,ender_eye.png,mcl_end_ender_eye.png,,,,,,, +/assets/minecraft/textures/block,end_stone.png,mcl_end_end_stone.png,,,,,,, +/assets/minecraft/textures/item,end_crystal.png,mcl_end_crystal_item.png,,,,,,, +/assets/minecraft/textures/entity/end_crystal,end_crystal.png,mcl_end_crystal.png,,,,,,, +/assets/minecraft/textures/entity/end_crystal,end_crystal_beam.png,mcl_end_crystal_beam.png,,,,,,, +/assets/minecraft/textures/block,purpur_block.png,mcl_end_purpur_block.png,,,,,,, +/assets/minecraft/textures/block,purpur_pillar.png,mcl_end_purpur_pillar.png,,,,,,, +/assets/minecraft/textures/block,purpur_pillar_top.png,mcl_end_purpur_pillar_top.png,,,,,,, +/assets/minecraft/textures/block,potatoes_stage0.png,mcl_farming_potatoes_stage_0.png,,,,,,, +/assets/minecraft/textures/block,potatoes_stage1.png,mcl_farming_potatoes_stage_1.png,,,,,,, +/assets/minecraft/textures/block,potatoes_stage2.png,mcl_farming_potatoes_stage_2.png,,,,,,, +/assets/minecraft/textures/block,potatoes_stage3.png,mcl_farming_potatoes_stage_3.png,,,,,,, +/assets/minecraft/textures/item,bread.png,farming_bread.png,,,,,,, +/assets/minecraft/textures/block,carrots_stage0.png,farming_carrot_1.png,,,,,,, +/assets/minecraft/textures/block,carrots_stage1.png,farming_carrot_2.png,,,,,,, +/assets/minecraft/textures/block,carrots_stage2.png,farming_carrot_3.png,,,,,,, +/assets/minecraft/textures/block,carrots_stage3.png,farming_carrot_4.png,,,,,,, +/assets/minecraft/textures/item,golden_carrot.png,farming_carrot_gold.png,,,,,,, +/assets/minecraft/textures/item,carrot.png,farming_carrot.png,,,,,,, +/assets/minecraft/textures/item,cookie.png,farming_cookie.png,,,,,,, +/assets/minecraft/textures/item,melon_slice.png,farming_melon.png,,,,,,, +/assets/minecraft/textures/item,melon_seeds.png,mcl_farming_melon_seeds.png,,,,,,, +/assets/minecraft/textures/block,melon_side.png,farming_melon_side.png,,,,,,, +/assets/minecraft/textures/block,melon_top.png,farming_melon_top.png,,,,,,, +/assets/minecraft/textures/item,baked_potato.png,farming_potato_baked.png,,,,,,, +/assets/minecraft/textures/item,potato.png,farming_potato.png,,,,,,, +/assets/minecraft/textures/item,poisonous_potato.png,farming_potato_poison.png,,,,,,, +/assets/minecraft/textures/block,jack_o_lantern.png,farming_pumpkin_face_light.png,,,,,,, +/assets/minecraft/textures/block,carved_pumpkin.png,farming_pumpkin_face.png,,,,,,, +/assets/minecraft/textures/item,pumpkin_seeds.png,mcl_farming_pumpkin_seeds.png,,,,,,, +/assets/minecraft/textures/block,pumpkin_side.png,farming_pumpkin_side.png,,,,,,, +/assets/minecraft/textures/block,pumpkin_top.png,farming_pumpkin_top.png,,,,,,, +/assets/minecraft/textures/item,pumpkin_pie.png,mcl_farming_pumpkin_pie.png,,,,,,, +/assets/minecraft/textures/block,attached_pumpkin_stem.png,mcl_farming_pumpkin_stem_connected.png,,,,,,, +/assets/minecraft/textures/block,pumpkin_stem.png,mcl_farming_pumpkin_stem_disconnected.png,,,,,,, +/assets/minecraft/textures/misc,pumpkinblur.png,mcl_farming_pumpkin_hud.png,,,,,,, +/assets/minecraft/textures/block,sweet_berry_bush_stage0.png,mcl_farming_sweet_berry_bush_0.png,,,,,,, +/assets/minecraft/textures/block,sweet_berry_bush_stage1.png,mcl_farming_sweet_berry_bush_1.png,,,,,,, +/assets/minecraft/textures/block,sweet_berry_bush_stage2.png,mcl_farming_sweet_berry_bush_2.png,,,,,,, +/assets/minecraft/textures/block,sweet_berry_bush_stage3.png,mcl_farming_sweet_berry_bush_3.png,,,,,,, +/assets/minecraft/textures/item,sweet_berries.png,mcl_farming_sweet_berry.png,,,,,,, +/assets/minecraft/textures/block,farmland.png,mcl_farming_farmland_dry.png,,,,,,, +/assets/minecraft/textures/block,farmland_moist.png,mcl_farming_farmland_wet.png,,,,,,, +/assets/minecraft/textures/item,netherite_hoe.png,farming_tool_netheritehoe.png,,,,,,, +/assets/minecraft/textures/item,diamond_hoe.png,farming_tool_diamondhoe.png,,,,,,, +/assets/minecraft/textures/item,golden_hoe.png,farming_tool_goldhoe.png,,,,,,, +/assets/minecraft/textures/item,iron_hoe.png,farming_tool_steelhoe.png,,,,,,, +/assets/minecraft/textures/item,stone_hoe.png,farming_tool_stonehoe.png,,,,,,, +/assets/minecraft/textures/item,wooden_hoe.png,farming_tool_woodhoe.png,,,,,,, +/assets/minecraft/textures/item,wheat.png,farming_wheat_harvested.png,,,,,,, +/assets/minecraft/textures/item,wheat_seeds.png,mcl_farming_wheat_seeds.png,,,,,,, +/assets/minecraft/textures/block,beetroots_stage0.png,mcl_farming_beetroot_0.png,,,,,,, +/assets/minecraft/textures/block,beetroots_stage1.png,mcl_farming_beetroot_1.png,,,,,,, +/assets/minecraft/textures/block,beetroots_stage2.png,mcl_farming_beetroot_2.png,,,,,,, +/assets/minecraft/textures/block,beetroots_stage3.png,mcl_farming_beetroot_3.png,,,,,,, +/assets/minecraft/textures/item,beetroot.png,mcl_farming_beetroot.png,,,,,,, +/assets/minecraft/textures/item,beetroot_seeds.png,mcl_farming_beetroot_seeds.png,,,,,,, +/assets/minecraft/textures/item,beetroot_soup.png,mcl_farming_beetroot_soup.png,,,,,,, +/assets/minecraft/textures/block,hay_block_side.png,mcl_farming_hayblock_side.png,,,,,,, +/assets/minecraft/textures/block,hay_block_top.png,mcl_farming_hayblock_top.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage0.png,mcl_farming_wheat_stage_0.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage1.png,mcl_farming_wheat_stage_1.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage2.png,mcl_farming_wheat_stage_2.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage3.png,mcl_farming_wheat_stage_3.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage4.png,mcl_farming_wheat_stage_4.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage5.png,mcl_farming_wheat_stage_5.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage6.png,mcl_farming_wheat_stage_6.png,,,,,,, +/assets/minecraft/textures/block,wheat_stage7.png,mcl_farming_wheat_stage_7.png,,,,,,, +/assets/minecraft/textures/block,fire_0.png,fire_basic_flame_animated.png,,,,,,, +/assets/minecraft/textures/block,fire_0.png,fire_basic_flame.png,0,0,16,16,0,0,y +/assets/minecraft/textures/item,campfire.png,mcl_campfires_campfire_inv.png,,,,,,, +/assets/minecraft/textures/item,soul_campfire.png,mcl_campfires_soul_campfire_inv.png,,,,,,, +/assets/minecraft/textures/item,fire_charge.png,mcl_fire_fire_charge.png,,,,,,, +/assets/minecraft/textures/entity/enderdragon,dragon_fireball.png,mobs_mc_dragon_fireball.png,,,,,,, +/assets/minecraft/textures/item,flint_and_steel.png,mcl_fire_flint_and_steel.png,,,,,,, +/assets/minecraft/textures/item,tropical_fish.png,mcl_fishing_clownfish_raw.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a.png,extra_mobs_tropical_fish_a.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b.png,extra_mobs_tropical_fish_b.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_1.png,extra_mobs_tropical_fish_pattern_a_1.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_2.png,extra_mobs_tropical_fish_pattern_a_2.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_3.png,extra_mobs_tropical_fish_pattern_a_3.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_4.png,extra_mobs_tropical_fish_pattern_a_4.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_5.png,extra_mobs_tropical_fish_pattern_a_5.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_a_pattern_6.png,extra_mobs_tropical_fish_pattern_a_6.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_1.png,extra_mobs_tropical_fish_pattern_b_1.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_2.png,extra_mobs_tropical_fish_pattern_b_2.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_3.png,extra_mobs_tropical_fish_pattern_b_3.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_4.png,extra_mobs_tropical_fish_pattern_b_4.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_5.png,extra_mobs_tropical_fish_pattern_b_5.png,,,,,,, +/assets/minecraft/textures/entity/fish,tropical_b_pattern_6.png,extra_mobs_tropical_fish_pattern_b_6.png,,,,,,, +/assets/minecraft/textures/entity/axolotl,axolotl_blue.png,mobs_mc_axolotl_purple.png,,,,,,, +/assets/minecraft/textures/entity/axolotl,axolotl_cyan.png,mobs_mc_axolotl_white.png,,,,,,, +/assets/minecraft/textures/entity/axolotl,axolotl_gold.png,mobs_mc_axolotl_yellow.png,,,,,,, +/assets/minecraft/textures/entity/axolotl,axolotl_lucy.png,mobs_mc_axolotl_pink.png,,,,,,, +/assets/minecraft/textures/entity/axolotl,axolotl_wild.png,mobs_mc_axolotl_brown.png,,,,,,, +/assets/minecraft/textures/item,cooked_cod.png,mcl_fishing_fish_cooked.png,,,,,,, +/assets/minecraft/textures/item,fishing_rod.png,mcl_fishing_fishing_rod.png,,,,,,, +/assets/minecraft/textures/entity,fishing_hook.png,mcl_fishing_bobber.png,,,,,,, +/assets/minecraft/textures/item,cod.png,mcl_fishing_fish_raw.png,,,,,,, +/assets/minecraft/textures/item,pufferfish.png,mcl_fishing_pufferfish_raw.png,,,,,,, +/assets/minecraft/textures/item,cooked_salmon.png,mcl_fishing_salmon_cooked.png,,,,,,, +/assets/minecraft/textures/item,salmon.png,mcl_fishing_salmon_raw.png,,,,,,, +/assets/minecraft/textures/block,allium.png,mcl_flowers_allium.png,,,,,,, +/assets/minecraft/textures/block,azure_bluet.png,mcl_flowers_azure_bluet.png,,,,,,, +/assets/minecraft/textures/block,blue_orchid.png,mcl_flowers_blue_orchid.png,,,,,,, +/assets/minecraft/textures/block,peony_bottom.png,mcl_flowers_double_plant_paeonia_bottom.png,,,,,,, +/assets/minecraft/textures/block,peony_top.png,mcl_flowers_double_plant_paeonia_top.png,,,,,,, +/assets/minecraft/textures/block,rose_bush_bottom.png,mcl_flowers_double_plant_rose_bottom.png,,,,,,, +/assets/minecraft/textures/block,rose_bush_top.png,mcl_flowers_double_plant_rose_top.png,,,,,,, +/assets/minecraft/textures/block,sunflower_back.png,mcl_flowers_double_plant_sunflower_back.png,,,,,,, +/assets/minecraft/textures/block,sunflower_bottom.png,mcl_flowers_double_plant_sunflower_bottom.png,,,,,,, +/assets/minecraft/textures/block,sunflower_front.png,mcl_flowers_double_plant_sunflower_front.png,,,,,,, +/assets/minecraft/textures/block,sunflower_top.png,mcl_flowers_double_plant_sunflower_top.png,,,,,,, +/assets/minecraft/textures/block,lilac_bottom.png,mcl_flowers_double_plant_syringa_bottom.png,,,,,,, +/assets/minecraft/textures/block,lilac_top.png,mcl_flowers_double_plant_syringa_top.png,,,,,,, +/assets/minecraft/textures/block,cornflower.png,mcl_flowers_cornflower.png,,,,,,, +/assets/minecraft/textures/block,lily_of_the_valley.png,mcl_flowers_lily_of_the_valley.png,,,,,,, +/assets/minecraft/textures/block,wither_rose.png,mcl_flowers_wither_rose.png,,,,,,, +/assets/minecraft/textures/block,tall_grass_bottom.png,mcl_flowers_double_plant_grass_bottom.png,,,,,,, +/assets/minecraft/textures/block,tall_grass_top.png,mcl_flowers_double_plant_grass_top.png,,,,,,, +/assets/minecraft/textures/block,large_fern_bottom.png,mcl_flowers_double_plant_fern_bottom.png,,,,,,, +/assets/minecraft/textures/block,large_fern_top.png,mcl_flowers_double_plant_fern_top.png,,,,,,, +/assets/minecraft/textures/block,grass.png,mcl_flowers_tallgrass.png,,,,,,, +/assets/minecraft/textures/block,fern.png,mcl_flowers_fern.png,,,,,,, +/assets/minecraft/textures/block,oxeye_daisy.png,mcl_flowers_oxeye_daisy.png,,,,,,, +/assets/minecraft/textures/block,poppy.png,mcl_flowers_poppy.png,,,,,,, +/assets/minecraft/textures/block,pink_tulip.png,mcl_flowers_tulip_pink.png,,,,,,, +/assets/minecraft/textures/block,red_tulip.png,mcl_flowers_tulip_red.png,,,,,,, +/assets/minecraft/textures/block,white_tulip.png,mcl_flowers_tulip_white.png,,,,,,, +/assets/minecraft/textures/block,dandelion.png,flowers_dandelion_yellow.png,,,,,,, +/assets/minecraft/textures/block,orange_tulip.png,flowers_tulip.png,,,,,,, +/assets/minecraft/textures/block,furnace_front.png,default_furnace_front.png,,,,,,, +/assets/minecraft/textures/block,crimson_roots.png,mcl_crimson_crimson_roots.png,,,,,,, +/assets/minecraft/textures/block,warped_roots.png,mcl_crimson_warped_roots.png,,,,,,, +/assets/minecraft/textures/block,nether_sprouts.png,mcl_crimson_nether_sprouts.png,,,,,,, +/assets/minecraft/textures/block,weeping_vines_plant.png,mcl_crimson_weeping_vines.png,,,,,,, +/assets/minecraft/textures/block,twisting_vines.png,mcl_crimson_twisting_vines.png,,,,,,, +/assets/minecraft/textures/block,twisting_vines_plant.png,mcl_crimson_twisting_vines_plant.png,,,,,,, +/assets/minecraft/textures/block,shroomlight.png,mcl_crimson_shroomlight.png,,,,,,, +/assets/minecraft/textures/block,furnace_front_on.png,default_furnace_front_active.png,,,,,,, +/assets/minecraft/textures/block,furnace_side.png,default_furnace_side.png,,,,,,, +/assets/minecraft/textures/block,furnace_top.png,default_furnace_top.png,,,,,,, +/assets/minecraft/textures/block,furnace_top.png,default_furnace_bottom.png,,,,,,, +/assets/minecraft/textures/block,blast_furnace_front.png,blast_furnace_front.png,,,,,,, +/assets/minecraft/textures/block,blast_furnace_front_on.png,blast_furnace_front_on.png,,,,,,, +/assets/minecraft/textures/block,blast_furnace_side.png,blast_furnace_side.png,,,,,,, +/assets/minecraft/textures/block,blast_furnace_top.png,blast_furnace_top.png,,,,,,, +/assets/minecraft/textures/block,smoker_bottom.png,smoker_bottom.png,,,,,,, +/assets/minecraft/textures/block,smoker_front.png,smoker_front.png,,,,,,, +/assets/minecraft/textures/block,smoker_front_on.png,smoker_front_on.png,,,,,,, +/assets/minecraft/textures/block,smoker_side.png,smoker_side.png,,,,,,, +/assets/minecraft/textures/block,smoker_top.png,smoker_top.png,,,,,,, +/assets/minecraft/textures/block,hopper_inside.png,mcl_hoppers_hopper_inside.png,,,,,,, +/assets/minecraft/textures/block,hopper_outside.png,mcl_hoppers_hopper_outside.png,,,,,,, +/assets/minecraft/textures/block,hopper_top.png,mcl_hoppers_hopper_top.png,,,,,,, +/assets/minecraft/textures/item,hopper.png,mcl_hoppers_item.png,,,,,,, +/assets/minecraft/textures/item,music_disc_11.png,mcl_jukebox_record_11.png,,,,,,, +/assets/minecraft/textures/item,music_disc_13.png,mcl_jukebox_record_13.png,,,,,,, +/assets/minecraft/textures/item,music_disc_blocks.png,mcl_jukebox_record_blocks.png,,,,,,, +/assets/minecraft/textures/item,music_disc_cat.png,mcl_jukebox_record_cat.png,,,,,,, +/assets/minecraft/textures/item,music_disc_chirp.png,mcl_jukebox_record_chirp.png,,,,,,, +/assets/minecraft/textures/item,music_disc_far.png,mcl_jukebox_record_far.png,,,,,,, +/assets/minecraft/textures/item,music_disc_mall.png,mcl_jukebox_record_mall.png,,,,,,, +/assets/minecraft/textures/item,music_disc_mellohi.png,mcl_jukebox_record_mellohi.png,,,,,,, +/assets/minecraft/textures/item,music_disc_stal.png,mcl_jukebox_record_stal.png,,,,,,, +/assets/minecraft/textures/item,music_disc_strad.png,mcl_jukebox_record_strad.png,,,,,,, +/assets/minecraft/textures/item,music_disc_wait.png,mcl_jukebox_record_wait.png,,,,,,, +/assets/minecraft/textures/item,music_disc_ward.png,mcl_jukebox_record_ward.png,,,,,,, +/assets/minecraft/textures/block,jukebox_side.png,mcl_jukebox_side.png,,,,,,, +/assets/minecraft/textures/block,jukebox_top.png,mcl_jukebox_top.png,,,,,,, +/assets/minecraft/textures/item,map.png,mcl_maps_map_empty.png,,,,,,, +/assets/minecraft/textures/item,filled_map_markings.png,mcl_maps_map_filled_markings.png,,,,,,, +/assets/minecraft/textures/item,filled_map.png,mcl_maps_map_filled.png,,,,,,, +/assets/minecraft/textures/block,powered_rail.png,mcl_minecarts_rail_golden.png,,,,,,, +/assets/minecraft/textures/block,powered_rail_on.png,mcl_minecarts_rail_golden_powered.png,,,,,,, +/assets/minecraft/textures/block,rail_corner.png,default_rail_curved.png,,,,,,, +/assets/minecraft/textures/block,rail.png,default_rail.png,,,,,,, +/assets/minecraft/textures/block,detector_rail.png,mcl_minecarts_rail_detector.png,,,,,,, +/assets/minecraft/textures/block,detector_rail_on.png,mcl_minecarts_rail_detector_powered.png,,,,,,, +/assets/minecraft/textures/block,activator_rail.png,mcl_minecarts_rail_activator.png,,,,,,, +/assets/minecraft/textures/block,activator_rail_on.png,mcl_minecarts_rail_activator_powered.png,,,,,,, +/assets/minecraft/textures/item,minecart.png,mcl_minecarts_minecart_normal.png,,,,,,, +/assets/minecraft/textures/entity,minecart.png,mcl_minecarts_minecart.png,,,,,,, +/assets/minecraft/textures/item,chest_minecart.png,mcl_minecarts_minecart_chest.png,,,,,,, +/assets/minecraft/textures/item,tnt_minecart.png,mcl_minecarts_minecart_tnt.png,,,,,,, +/assets/minecraft/textures/item,command_block_minecart.png,mcl_minecarts_minecart_command_block.png,,,,,,, +/assets/minecraft/textures/item,furnace_minecart.png,mcl_minecarts_minecart_furnace.png,,,,,,, +/assets/minecraft/textures/item,hopper_minecart.png,mcl_minecarts_minecart_hopper.png,,,,,,, +/assets/minecraft/textures/item,gunpowder.png,default_gunpowder.png,,,,,,, +/assets/minecraft/textures/item,cooked_beef.png,mcl_mobitems_beef_cooked.png,,,,,,, +/assets/minecraft/textures/item,beef.png,mcl_mobitems_beef_raw.png,,,,,,, +/assets/minecraft/textures/item,blaze_powder.png,mcl_mobitems_blaze_powder.png,,,,,,, +/assets/minecraft/textures/item,blaze_rod.png,mcl_mobitems_blaze_rod.png,,,,,,, +/assets/minecraft/textures/item,carrot_on_a_stick.png,mcl_mobitems_carrot_on_a_stick.png,,,,,,, +/assets/minecraft/textures/item,cooked_chicken.png,mcl_mobitems_chicken_cooked.png,,,,,,, +/assets/minecraft/textures/item,chicken.png,mcl_mobitems_chicken_raw.png,,,,,,, +/assets/minecraft/textures/item,feather.png,mcl_mobitems_feather.png,,,,,,, +/assets/minecraft/textures/item,ghast_tear.png,mcl_mobitems_ghast_tear.png,,,,,,, +/assets/minecraft/textures/item,leather.png,mcl_mobitems_leather.png,,,,,,, +/assets/minecraft/textures/item,magma_cream.png,mcl_mobitems_magma_cream.png,,,,,,, +/assets/minecraft/textures/item,cooked_mutton.png,mcl_mobitems_mutton_cooked.png,,,,,,, +/assets/minecraft/textures/item,mutton.png,mcl_mobitems_mutton_raw.png,,,,,,, +/assets/minecraft/textures/item,nether_star.png,mcl_mobitems_nether_star.png,,,,,,, +/assets/minecraft/textures/item,cooked_porkchop.png,mcl_mobitems_porkchop_cooked.png,,,,,,, +/assets/minecraft/textures/item,porkchop.png,mcl_mobitems_porkchop_raw.png,,,,,,, +/assets/minecraft/textures/item,cooked_rabbit.png,mcl_mobitems_rabbit_cooked.png,,,,,,, +/assets/minecraft/textures/item,rabbit_foot.png,mcl_mobitems_rabbit_foot.png,,,,,,, +/assets/minecraft/textures/item,rabbit_hide.png,mcl_mobitems_rabbit_hide.png,,,,,,, +/assets/minecraft/textures/item,rabbit.png,mcl_mobitems_rabbit_raw.png,,,,,,, +/assets/minecraft/textures/item,rabbit_stew.png,mcl_mobitems_rabbit_stew.png,,,,,,, +/assets/minecraft/textures/item,suspicious_stew.png,sus_stew.png,,,,,,, +/assets/minecraft/textures/item,rotten_flesh.png,mcl_mobitems_rotten_flesh.png,,,,,,, +/assets/minecraft/textures/item,saddle.png,mcl_mobitems_saddle.png,,,,,,, +/assets/minecraft/textures/item,shulker_shell.png,mcl_mobitems_shulker_shell.png,,,,,,, +/assets/minecraft/textures/item,slime_ball.png,mcl_mobitems_slimeball.png,,,,,,, +/assets/minecraft/textures/item,spider_eye.png,mcl_mobitems_spider_eye.png,,,,,,, +/assets/minecraft/textures/item,string.png,mcl_mobitems_string.png,,,,,,, +/assets/minecraft/textures/item,glow_ink_sac.png,mcl_mobitems_glow_ink_sac.png,,,,,,, +/assets/minecraft/textures/item,heart_of_the_sea.png,mcl_mobitems_heart_of_the_sea.png,,,,,,, +/assets/minecraft/textures/item,ink_sac.png,mcl_mobitems_ink_sac.png,,,,,,, +/assets/minecraft/textures/item,iron_horse_armor.png,mcl_mobitems_iron_horse_armor.png,,,,,,, +/assets/minecraft/textures/item,nautilus_shell.png,mcl_mobitems_nautilus_shell.png,,,,,,, +/assets/minecraft/textures/item,warped_fungus_on_a_stick.png,mcl_mobitems_warped_fungus_on_a_stick.png,,,,,,, +/assets/minecraft/textures/item,golden_horse_armor.png,mcl_mobitems_gold_horse_armor.png,,,,,,, +/assets/minecraft/textures/item,diamond_horse_armor.png,mcl_mobitems_diamond_horse_armor.png,,,,,,, +/assets/minecraft/textures/item,diamond_horse_armor.png,mobs_mc_diamond_horse_armor.png,,,,,,, +/assets/minecraft/textures/block,spawner.png,mob_spawner.png,,,,,,, +/assets/minecraft/textures/block,brown_mushroom.png,farming_mushroom_brown.png,,,,,,, +/assets/minecraft/textures/block,red_mushroom.png,farming_mushroom_red.png,,,,,,, +/assets/minecraft/textures/item,mushroom_stew.png,farming_mushroom_stew.png,,,,,,, +/assets/minecraft/textures/block,mushroom_block_inside.png,mcl_mushrooms_mushroom_block_inside.png,,,,,,, +/assets/minecraft/textures/block,brown_mushroom_block.png,mcl_mushrooms_mushroom_block_skin_brown.png,,,,,,, +/assets/minecraft/textures/block,red_mushroom_block.png,mcl_mushrooms_mushroom_block_skin_red.png,,,,,,, +/assets/minecraft/textures/block,mushroom_stem.png,mcl_mushrooms_mushroom_block_skin_stem.png,,,,,,, +/assets/minecraft/textures/item,glowstone_dust.png,mcl_nether_glowstone_dust.png,,,,,,, +/assets/minecraft/textures/block,glowstone.png,mcl_nether_glowstone.png,,,,,,, +/assets/minecraft/textures/block,magma.png,mcl_nether_magma.png,,,,,,, +/assets/minecraft/textures/block,nether_bricks.png,mcl_nether_nether_brick.png,,,,,,, +/assets/minecraft/textures/item,nether_brick.png,mcl_nether_netherbrick.png,,,,,,, +/assets/minecraft/textures/block,netherrack.png,mcl_nether_netherrack.png,,,,,,, +/assets/minecraft/textures/block,warped_wart_block.png,mcl_crimson_warped_wart_block.png,,,,,,, +/assets/minecraft/textures/block,nether_wart_block.png,mcl_nether_nether_wart_block.png,,,,,,, +/assets/minecraft/textures/item,nether_wart.png,mcl_nether_nether_wart.png,,,,,,, +/assets/minecraft/textures/block,nether_wart_stage0.png,mcl_nether_nether_wart_stage_0.png,,,,,,, +/assets/minecraft/textures/block,nether_wart_stage1.png,mcl_nether_nether_wart_stage_1.png,,,,,,, +/assets/minecraft/textures/block,nether_wart_stage2.png,mcl_nether_nether_wart_stage_2.png,,,,,,, +/assets/minecraft/textures/block,quartz_bricks.png,mcl_backstone_quartz_bricks.png,,,,,,, +/assets/minecraft/textures/block,quartz_block_bottom.png,mcl_nether_quartz_block_bottom.png,,,,,,, +/assets/minecraft/textures/block,quartz_block_side.png,mcl_nether_quartz_block_side.png,,,,,,, +/assets/minecraft/textures/block,quartz_block_top.png,mcl_nether_quartz_block_top.png,,,,,,, +/assets/minecraft/textures/block,chiseled_quartz_block.png,mcl_nether_quartz_chiseled_side.png,,,,,,, +/assets/minecraft/textures/block,chiseled_quartz_block_top.png,mcl_nether_quartz_chiseled_top.png,,,,,,, +/assets/minecraft/textures/block,nether_quartz_ore.png,mcl_nether_quartz_ore.png,,,,,,, +/assets/minecraft/textures/block,quartz_pillar.png,mcl_nether_quartz_pillar_side.png,,,,,,, +/assets/minecraft/textures/block,quartz_pillar_top.png,mcl_nether_quartz_pillar_top.png,,,,,,, +/assets/minecraft/textures/item,quartz.png,mcl_nether_quartz.png,,,,,,, +/assets/minecraft/textures/block,red_nether_bricks.png,mcl_nether_red_nether_brick.png,,,,,,, +/assets/minecraft/textures/block,soul_sand.png,mcl_nether_soul_sand.png,,,,,,, +/assets/minecraft/textures/block,prismarine.png,mcl_ocean_prismarine_anim.png,,,,,,, +/assets/minecraft/textures/block,prismarine_bricks.png,mcl_ocean_prismarine_bricks.png,,,,,,, +/assets/minecraft/textures/item,prismarine_crystals.png,mcl_ocean_prismarine_crystals.png,,,,,,, +/assets/minecraft/textures/block,dark_prismarine.png,mcl_ocean_prismarine_dark.png,,,,,,, +/assets/minecraft/textures/item,prismarine_shard.png,mcl_ocean_prismarine_shard.png,,,,,,, +/assets/minecraft/textures/block,sea_lantern.png,mcl_ocean_sea_lantern.png,,,,,,, +/assets/minecraft/textures/block,brain_coral.png,mcl_ocean_brain_coral.png,,,,,,, +/assets/minecraft/textures/block,brain_coral_block.png,mcl_ocean_brain_coral_block.png,,,,,,, +/assets/minecraft/textures/block,brain_coral_fan.png,mcl_ocean_brain_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,bubble_coral.png,mcl_ocean_bubble_coral.png,,,,,,, +/assets/minecraft/textures/block,bubble_coral_block.png,mcl_ocean_bubble_coral_block.png,,,,,,, +/assets/minecraft/textures/block,bubble_coral_fan.png,mcl_ocean_bubble_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,dead_brain_coral.png,mcl_ocean_dead_brain_coral.png,,,,,,, +/assets/minecraft/textures/block,dead_brain_coral_block.png,mcl_ocean_dead_brain_coral_block.png,,,,,,, +/assets/minecraft/textures/block,dead_brain_coral_fan.png,mcl_ocean_dead_brain_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,dead_bubble_coral.png,mcl_ocean_dead_bubble_coral.png,,,,,,, +/assets/minecraft/textures/block,dead_bubble_coral_block.png,mcl_ocean_dead_bubble_coral_block.png,,,,,,, +/assets/minecraft/textures/block,dead_bubble_coral_fan.png,mcl_ocean_dead_bubble_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,dead_fire_coral.png,mcl_ocean_dead_fire_coral.png,,,,,,, +/assets/minecraft/textures/block,dead_fire_coral_block.png,mcl_ocean_dead_fire_coral_block.png,,,,,,, +/assets/minecraft/textures/block,dead_fire_coral_fan.png,mcl_ocean_dead_fire_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,dead_horn_coral.png,mcl_ocean_dead_horn_coral.png,,,,,,, +/assets/minecraft/textures/block,dead_horn_coral_block.png,mcl_ocean_dead_horn_coral_block.png,,,,,,, +/assets/minecraft/textures/block,dead_horn_coral_fan.png,mcl_ocean_dead_horn_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,dead_tube_coral.png,mcl_ocean_dead_tube_coral.png,,,,,,, +/assets/minecraft/textures/block,dead_tube_coral_block.png,mcl_ocean_dead_tube_coral_block.png,,,,,,, +/assets/minecraft/textures/block,dead_tube_coral_fan.png,mcl_ocean_dead_tube_coral_fan.png,,,,,,, +/assets/minecraft/textures/item,dried_kelp.png,mcl_ocean_dried_kelp.png,,,,,,, +/assets/minecraft/textures/block,dried_kelp_bottom.png,mcl_ocean_dried_kelp_bottom.png,,,,,,, +/assets/minecraft/textures/block,dried_kelp_side.png,mcl_ocean_dried_kelp_side.png,,,,,,, +/assets/minecraft/textures/block,dried_kelp_top.png,mcl_ocean_dried_kelp_top.png,,,,,,, +/assets/minecraft/textures/block,fire_coral.png,mcl_ocean_fire_coral.png,,,,,,, +/assets/minecraft/textures/block,fire_coral_block.png,mcl_ocean_fire_coral_block.png,,,,,,, +/assets/minecraft/textures/block,fire_coral_fan.png,mcl_ocean_fire_coral_fan.png,,,,,,, +/assets/minecraft/textures/block,horn_coral.png,mcl_ocean_horn_coral.png,,,,,,, +/assets/minecraft/textures/block,horn_coral_block.png,mcl_ocean_horn_coral_block.png,,,,,,, +/assets/minecraft/textures/block,horn_coral_fan.png,mcl_ocean_horn_coral_fan.png,,,,,,, +/assets/minecraft/textures/item,kelp.png,mcl_ocean_kelp_item.png,,,,,,, +/assets/minecraft/textures/block,kelp_plant.png,mcl_ocean_kelp_plant.png,,,,,,, +/assets/minecraft/textures/block,seagrass.png,mcl_ocean_seagrass.png,,,,,,, +/assets/minecraft/textures/item,seagrass.png,mcl_ocean_seagrass_item.png,,,,,,, +/assets/minecraft/textures/block,tube_coral.png,mcl_ocean_tube_coral.png,,,,,,, +/assets/minecraft/textures/block,tube_coral_block.png,mcl_ocean_tube_coral_block.png,,,,,,, +/assets/minecraft/textures/block,tube_coral_fan.png,mcl_ocean_tube_coral_fan.png,,,,,,, +/assets/minecraft/textures/item,dragon_breath.png,mcl_potions_dragon_breath.png,,,,,,, +/assets/minecraft/textures/item,glistering_melon_slice.png,mcl_potions_melon_speckled.png,,,,,,, +/assets/minecraft/textures/item,potion.png,mcl_potions_potion_bottle.png,,,,,,, +/assets/minecraft/textures/item,splash_potion.png,mcl_potions_splash_bottle.png,,,,,,, +/assets/minecraft/textures/item,lingering_potion.png,mcl_potions_lingering_bottle.png,,,,,,, +/assets/minecraft/textures/item,potion_overlay.png,mcl_potions_potion_overlay.png,,,,,,, +/assets/minecraft/textures/item,potion_overlay.png,mcl_potions_splash_overlay.png,,,,,,, +/assets/minecraft/textures/item,fermented_spider_eye.png,mcl_potions_spider_eye_fermented.png,,,,,,, +/assets/minecraft/textures/block,sponge.png,mcl_sponges_sponge.png,,,,,,, +/assets/minecraft/textures/block,wet_sponge.png,mcl_sponges_sponge_wet.png,,,,,,, +/assets/minecraft/textures/block,wet_sponge.png,mcl_sponges_sponge_wet_river_water.png,,,,,,, +/assets/minecraft/textures/block,smooth_stone_slab_side.png,mcl_stairs_stone_slab_side.png,,,,,,, +/assets/minecraft/textures/block,smooth_stone.png,mcl_stairs_stone_slab_top.png,,,,,,, +/assets/minecraft/textures/item,arrow.png,mcl_bows_arrow_inv.png,,,,,,, +/assets/minecraft/textures/item,bow_pulling_0.png,mcl_bows_bow_0.png,,,,,,, +/assets/minecraft/textures/item,bow_pulling_1.png,mcl_bows_bow_1.png,,,,,,, +/assets/minecraft/textures/item,bow_pulling_2.png,mcl_bows_bow_2.png,,,,,,, +/assets/minecraft/textures/item,bow.png,mcl_bows_bow.png,,,,,,, +/assets/minecraft/textures/item,crossbow_standby.png,mcl_bows_crossbow.png,,,,,,, +/assets/minecraft/textures/item,crossbow_pulling_0.png,mcl_bows_crossbow_0.png,,,,,,, +/assets/minecraft/textures/item,crossbow_pulling_1.png,mcl_bows_crossbow_1.png,,,,,,, +/assets/minecraft/textures/item,crossbow_pulling_2.png,mcl_bows_crossbow_2.png,,,,,,, +/assets/minecraft/textures/item,crossbow_arrow.png,mcl_bows_crossbow_3.png,,,,,,, +/assets/minecraft/textures/item,egg.png,mcl_throwing_egg.png,,,,,,, +/assets/minecraft/textures/item,egg.png,mobs_chicken_egg.png,,,,,,, +/assets/minecraft/textures/item,ender_pearl.png,mcl_throwing_ender_pearl.png,,,,,,, +/assets/minecraft/textures/item,snowball.png,mcl_throwing_snowball.png,,,,,,, +/assets/minecraft/textures/block,tnt_bottom.png,default_tnt_bottom.png,,,,,,, +/assets/minecraft/textures/block,tnt_side.png,default_tnt_side.png,,,,,,, +/assets/minecraft/textures/block,tnt_top.png,default_tnt_top.png,,,,,,, +/assets/minecraft/textures/item,netherite_axe.png,default_tool_netheriteaxe.png,,,,,,, +/assets/minecraft/textures/item,netherite_pickaxe.png,default_tool_netheritepick.png,,,,,,, +/assets/minecraft/textures/item,netherite_shovel.png,default_tool_netheriteshovel.png,,,,,,, +/assets/minecraft/textures/item,netherite_sword.png,default_tool_netheritesword.png,,,,,,, +/assets/minecraft/textures/item,diamond_axe.png,default_tool_diamondaxe.png,,,,,,, +/assets/minecraft/textures/item,diamond_pickaxe.png,default_tool_diamondpick.png,,,,,,, +/assets/minecraft/textures/item,diamond_shovel.png,default_tool_diamondshovel.png,,,,,,, +/assets/minecraft/textures/item,diamond_sword.png,default_tool_diamondsword.png,,,,,,, +/assets/minecraft/textures/item,golden_axe.png,default_tool_goldaxe.png,,,,,,, +/assets/minecraft/textures/item,golden_pickaxe.png,default_tool_goldpick.png,,,,,,, +/assets/minecraft/textures/item,golden_shovel.png,default_tool_goldshovel.png,,,,,,, +/assets/minecraft/textures/item,golden_sword.png,default_tool_goldsword.png,,,,,,, +/assets/minecraft/textures/item,shears.png,default_tool_shears.png,,,,,,, +/assets/minecraft/textures/item,iron_axe.png,default_tool_steelaxe.png,,,,,,, +/assets/minecraft/textures/item,iron_pickaxe.png,default_tool_steelpick.png,,,,,,, +/assets/minecraft/textures/item,iron_shovel.png,default_tool_steelshovel.png,,,,,,, +/assets/minecraft/textures/item,iron_sword.png,default_tool_steelsword.png,,,,,,, +/assets/minecraft/textures/item,stone_axe.png,default_tool_stoneaxe.png,,,,,,, +/assets/minecraft/textures/item,stone_pickaxe.png,default_tool_stonepick.png,,,,,,, +/assets/minecraft/textures/item,stone_shovel.png,default_tool_stoneshovel.png,,,,,,, +/assets/minecraft/textures/item,stone_sword.png,default_tool_stonesword.png,,,,,,, +/assets/minecraft/textures/item,wooden_axe.png,default_tool_woodaxe.png,,,,,,, +/assets/minecraft/textures/item,wooden_pickaxe.png,default_tool_woodpick.png,,,,,,, +/assets/minecraft/textures/item,wooden_shovel.png,default_tool_woodshovel.png,,,,,,, +/assets/minecraft/textures/item,wooden_sword.png,default_tool_woodsword.png,,,,,,, +/assets/minecraft/textures/block,torch.png,default_torch_on_floor_animated.png,,,,,,, +/assets/minecraft/textures/block,torch.png,default_torch_on_floor.png,,,,,,, +/assets/minecraft/textures/block,black_wool.png,wool_black.png,,,,,,, +/assets/minecraft/textures/block,blue_wool.png,wool_blue.png,,,,,,, +/assets/minecraft/textures/block,brown_wool.png,wool_brown.png,,,,,,, +/assets/minecraft/textures/block,cyan_wool.png,wool_cyan.png,,,,,,, +/assets/minecraft/textures/block,gray_wool.png,wool_dark_grey.png,,,,,,, +/assets/minecraft/textures/block,green_wool.png,wool_dark_green.png,,,,,,, +/assets/minecraft/textures/block,light_gray_wool.png,wool_grey.png,,,,,,, +/assets/minecraft/textures/block,light_blue_wool.png,mcl_wool_light_blue.png,,,,,,, +/assets/minecraft/textures/block,lime_wool.png,mcl_wool_lime.png,,,,,,, +/assets/minecraft/textures/block,magenta_wool.png,wool_magenta.png,,,,,,, +/assets/minecraft/textures/block,orange_wool.png,wool_orange.png,,,,,,, +/assets/minecraft/textures/block,pink_wool.png,wool_pink.png,,,,,,, +/assets/minecraft/textures/block,red_wool.png,wool_red.png,,,,,,, +/assets/minecraft/textures/block,purple_wool.png,wool_violet.png,,,,,,, +/assets/minecraft/textures/block,white_wool.png,wool_white.png,,,,,,, +/assets/minecraft/textures/block,yellow_wool.png,wool_yellow.png,,,,,,, +/assets/minecraft/textures/item,chainmail_boots.png,mcl_armor_inv_boots_chain.png,,,,,,, +/assets/minecraft/textures/item,netherite_boots.png,mcl_armor_inv_boots_netherite.png,,,,,,, +/assets/minecraft/textures/item,diamond_boots.png,mcl_armor_inv_boots_diamond.png,,,,,,, +/assets/minecraft/textures/item,golden_boots.png,mcl_armor_inv_boots_gold.png,,,,,,, +/assets/minecraft/textures/item,iron_boots.png,mcl_armor_inv_boots_iron.png,,,,,,, +/assets/minecraft/textures/item,elytra.png,mcl_armor_inv_elytra.png,,,,,,, +/assets/minecraft/textures/item,chainmail_chestplate.png,mcl_armor_inv_chestplate_chain.png,,,,,,, +/assets/minecraft/textures/item,netherite_chestplate.png,mcl_armor_inv_chestplate_netherite.png,,,,,,, +/assets/minecraft/textures/item,diamond_chestplate.png,mcl_armor_inv_chestplate_diamond.png,,,,,,, +/assets/minecraft/textures/item,golden_chestplate.png,mcl_armor_inv_chestplate_gold.png,,,,,,, +/assets/minecraft/textures/item,iron_chestplate.png,mcl_armor_inv_chestplate_iron.png,,,,,,, +/assets/minecraft/textures/item,netherite_helmet.png,mcl_armor_inv_helmet_netherite.png,,,,,,, +/assets/minecraft/textures/item,chainmail_helmet.png,mcl_armor_inv_helmet_chain.png,,,,,,, +/assets/minecraft/textures/item,diamond_helmet.png,mcl_armor_inv_helmet_diamond.png,,,,,,, +/assets/minecraft/textures/item,golden_helmet.png,mcl_armor_inv_helmet_gold.png,,,,,,, +/assets/minecraft/textures/item,iron_helmet.png,mcl_armor_inv_helmet_iron.png,,,,,,, +/assets/minecraft/textures/item,chainmail_leggings.png,mcl_armor_inv_leggings_chain.png,,,,,,, +/assets/minecraft/textures/item,netherite_leggings.png,mcl_armor_inv_leggings_netherite.png,,,,,,, +/assets/minecraft/textures/item,diamond_leggings.png,mcl_armor_inv_leggings_diamond.png,,,,,,, +/assets/minecraft/textures/item,golden_leggings.png,mcl_armor_inv_leggings_gold.png,,,,,,, +/assets/minecraft/textures/item,iron_leggings.png,mcl_armor_inv_leggings_iron.png,,,,,,, +/assets/minecraft/textures/item,armor_stand.png,mcl_armor_stand_item.png,,,,,,, +/assets/minecraft/textures/block,dispenser_front.png,mcl_dispensers_dispenser_front_horizontal.png,,,,,,, +/assets/minecraft/textures/block,dispenser_front_vertical.png,mcl_dispensers_dispenser_front_vertical.png,,,,,,, +/assets/minecraft/textures/block,dropper_front.png,mcl_droppers_dropper_front_horizontal.png,,,,,,, +/assets/minecraft/textures/block,dropper_front_vertical.png,mcl_droppers_dropper_front_vertical.png,,,,,,, +/assets/minecraft/textures/block,observer_back_on.png,mcl_observers_observer_back_lit.png,,,,,,, +/assets/minecraft/textures/block,observer_back.png,mcl_observers_observer_back.png,,,,,,, +/assets/minecraft/textures/block,observer_front.png,mcl_observers_observer_front.png,,,,,,, +/assets/minecraft/textures/block,observer_side.png,mcl_observers_observer_side.png,,,,,,, +/assets/minecraft/textures/block,observer_top.png,mcl_observers_observer_top.png,,,,,,, +/assets/minecraft/textures/item,redstone.png,redstone_redstone_dust.png,,,,,,, +/assets/minecraft/textures/item,repeater.png,mesecons_delayer_item.png,,,,,,, +/assets/minecraft/textures/item,comparator.png,mcl_comparators_item.png,,,,,,, +/assets/minecraft/textures/block,repeater.png,mesecons_delayer_off.png,,,,,,, +/assets/minecraft/textures/block,repeater_on.png,mesecons_delayer_on.png,,,,,,, +/assets/minecraft/textures/block,comparator.png,mcl_comparators_off.png,,,,,,, +/assets/minecraft/textures/block,comparator_on.png,mcl_comparators_on.png,,,,,,, +/assets/minecraft/textures/block,note_block.png,mesecons_noteblock.png,,,,,,, +/assets/minecraft/textures/block,command_block_back.png,jeija_commandblock_off.png,,,,,,, +/assets/minecraft/textures/block,command_block_back.png,jeija_commandblock_on.png,,,,,,, +/assets/minecraft/textures/block,redstone_lamp.png,jeija_lightstone_gray_off.png,,,,,,, +/assets/minecraft/textures/block,redstone_lamp_on.png,jeija_lightstone_gray_on.png,,,,,,, +/assets/minecraft/textures/block,daylight_detector_inverted_top.png,jeija_solar_panel_inverted.png,,,,,,, +/assets/minecraft/textures/block,daylight_detector_top.png,jeija_solar_panel.png,,,,,,, +/assets/minecraft/textures/block,daylight_detector_side.png,jeija_solar_panel_side.png,,,,,,, +/assets/minecraft/textures/block,redstone_torch_off.png,jeija_torches_off.png,,,,,,, +/assets/minecraft/textures/block,redstone_torch.png,jeija_torches_on.png,,,,,,, +/assets/minecraft/textures/block,lever.png,jeija_wall_lever.png,,,,,,, +/assets/minecraft/textures/block,piston_bottom.png,mesecons_piston_back.png,,,,,,, +/assets/minecraft/textures/block,piston_side.png,mesecons_piston_bottom.png,,,,,,, +/assets/minecraft/textures/block,piston_inner.png,mesecons_piston_on_front.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_back.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_bottom.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_front.png,,,,,,, +/assets/minecraft/textures/block,piston_top_sticky.png,mesecons_piston_pusher_front_sticky.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_left.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_right.png,,,,,,, +/assets/minecraft/textures/block,piston_top.png,mesecons_piston_pusher_top.png,,,,,,, +/assets/minecraft/textures/block,redstone_block.png,redstone_redstone_block.png,,,,,,, +/assets/minecraft/textures/block,iron_bars.png,xpanes_pane_iron.png,,,,,,, +/assets/minecraft/textures/item,totem_of_undying.png,mcl_totems_totem.png,,,,,,, +/assets/minecraft/textures/entity,bat.png,mobs_mc_bat.png,,,,,,, +/assets/minecraft/textures/entity,blaze.png,mobs_mc_blaze.png,,,,,,, +/assets/minecraft/textures/entity/cat,all_black.png,mobs_mc_cat_black.png,,,,,,, +/assets/minecraft/textures/entity/cat,ocelot.png,mobs_mc_cat_ocelot.png,,,,,,, +/assets/minecraft/textures/entity/cat,red.png,mobs_mc_cat_red.png,,,,,,, +/assets/minecraft/textures/entity/cat,siamese.png,mobs_mc_cat_siamese.png,,,,,,, +/assets/minecraft/textures/entity/spider,cave_spider.png,mobs_mc_cave_spider.png,,,,,,, +/assets/minecraft/textures/entity,chicken.png,mobs_mc_chicken.png,,,,,,, +/assets/minecraft/textures/entity/cow,cow.png,mobs_mc_cow.png,,,,,,, +/assets/minecraft/textures/entity/creeper,creeper.png,mobs_mc_creeper.png,,,,,,, +/assets/minecraft/textures/entity/enderdragon,dragon.png,mobs_mc_dragon.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker.png,mobs_mc_endergolem.png,,,,,,, +/assets/minecraft/textures/entity/enderman,enderman_eyes.png,mobs_mc_enderman_eyes.png,,,,,,, +/assets/minecraft/textures/entity/enderman,enderman.png,mobs_mc_enderman.png,,,,,,, +/assets/minecraft/textures/entity,endermite.png,mobs_mc_endermite.png,,,,,,, +/assets/minecraft/textures/entity/ghast,ghast.png,mobs_mc_ghast.png,,,,,,, +/assets/minecraft/textures/entity/ghast,ghast_shooting.png,mobs_mc_ghast_firing.png,,,,,,, +/assets/minecraft/textures/item,golden_horse_armor.png,mobs_mc_gold_horse_armor.png,,,,,,, +/assets/minecraft/textures/entity,guardian_elder.png,mobs_mc_guardian_elder.png,,,,,,, +/assets/minecraft/textures/entity,guardian.png,mobs_mc_guardian.png,,,,,,, +/assets/minecraft/textures/entity/zombie,husk.png,mobs_mc_husk.png,,,,,,, +/assets/minecraft/textures/entity/iron_golem,iron_golem.png,mobs_mc_iron_golem.png,,,,,,, +/assets/minecraft/textures/item,iron_horse_armor.png,mobs_mc_iron_horse_armor.png,,,,,,, +/assets/minecraft/textures/entity/slime,magmacube.png,mobs_mc_magmacube.png,,,,,,, +/assets/minecraft/textures/entity/slime,slime.png,mobs_mc_slime.png,,,,,,, +/assets/minecraft/textures/entity/cow,red_mooshroom.png,mobs_mc_mooshroom.png,,,,,,, +/assets/minecraft/textures/entity/cow,brown_mooshroom.png,mobs_mc_mooshroom_brown.png,,,,,,, +/assets/minecraft/textures/entity/pig,pig.png,mobs_mc_pig.png,,,,,,, +/assets/minecraft/textures/entity/pig,pig_saddle.png,mobs_mc_pig_saddle.png,,,,,,, +/assets/minecraft/textures/entity/bear,polarbear.png,mobs_mc_polarbear.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,black.png,mobs_mc_rabbit_black.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,brown.png,mobs_mc_rabbit_brown.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,caerbannog.png,mobs_mc_rabbit_caerbannog.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,gold.png,mobs_mc_rabbit_gold.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,salt.png,mobs_mc_rabbit_salt.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,toast.png,mobs_mc_rabbit_toast.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,white.png,mobs_mc_rabbit_white.png,,,,,,, +/assets/minecraft/textures/entity/rabbit,white_splotched.png,mobs_mc_rabbit_white_splotched.png,,,,,,, +/assets/minecraft/textures/entity/sheep,sheep_fur.png,mobs_mc_sheep_fur.png,,,,,,, +/assets/minecraft/textures/entity/sheep,sheep.png,mobs_mc_sheep.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker.png,mobs_mc_shulker_pink.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_black.png,mobs_mc_shulker_black.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_blue.png,mobs_mc_shulker_blue.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_brown.png,mobs_mc_shulker_brown.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_cyan.png,mobs_mc_shulker_cyan.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_gray.png,mobs_mc_shulker_gray.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_green.png,mobs_mc_shulker_green.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_light_blue.png,mobs_mc_shulker_light_blue.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_lime.png,mobs_mc_shulker_lime.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_magenta.png,mobs_mc_shulker_magenta.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_orange.png,mobs_mc_shulker_orange.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_pink.png,mobs_mc_shulker_pink.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_purple.png,mobs_mc_shulker_purple.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_red.png,mobs_mc_shulker_red.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_light_gray.png,mobs_mc_shulker_silver.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_white.png,mobs_mc_shulker_white.png,,,,,,, +/assets/minecraft/textures/entity/shulker,shulker_yellow.png,mobs_mc_shulker_yellow.png,,,,,,, +/assets/minecraft/textures/entity,silverfish.png,mobs_mc_silverfish.png,,,,,,, +/assets/minecraft/textures/entity/skeleton,skeleton.png,mobs_mc_skeleton.png,,,,,,, +/assets/minecraft/textures/entity,snow_golem.png,mobs_mc_snowman.png,,,,,,, +/assets/minecraft/textures/entity,spider_eyes.png,mobs_mc_spider_eyes.png,,,,,,, +/assets/minecraft/textures/entity/spider,spider.png,mobs_mc_spider.png,,,,,,, +/assets/minecraft/textures/entity/squid,squid.png,mobs_mc_squid.png,,,,,,, +/assets/minecraft/textures/entity/squid,glow_squid.png,mobs_mc_glow_squid.png,,,,,,, +/assets/minecraft/textures/entity/skeleton,stray.png,mobs_mc_stray.png,,,,,,, +/assets/minecraft/textures/entity/skeleton,stray_overlay.png,mobs_mc_stray_overlay.png,,,,,,, +/assets/minecraft/textures/entity/illager,vindicator.png,mobs_mc_vindicator.png,,,,,,, +/assets/minecraft/textures/entity/illager,evoker.png,mobs_mc_evoker.png,,,,,,, +/assets/minecraft/textures/entity/illager,illusioner.png,mobs_mc_illusionist.png,,,,,,, +/assets/minecraft/textures/entity/illager,pillager.png,mobs_mc_pillager.png,,,,,,, +/assets/minecraft/textures/entity,witch.png,mobs_mc_witch.png,,,,,,, +/assets/minecraft/textures/entity/wither,wither.png,mobs_mc_wither.png,,,,,,, +/assets/minecraft/textures/entity/skeleton,wither_skeleton.png,mobs_mc_wither_skeleton.png,,,,,,, +/assets/minecraft/textures/entity/wolf,wolf_angry.png,mobs_mc_wolf_angry.png,,,,,,, +/assets/minecraft/textures/entity/wolf,wolf_collar.png,mobs_mc_wolf_collar.png,,,,,,, +/assets/minecraft/textures/entity/wolf,wolf.png,mobs_mc_wolf.png,,,,,,, +/assets/minecraft/textures/entity/wolf,wolf_tame.png,mobs_mc_wolf_tame.png,,,,,,, +/assets/minecraft/textures/entity/piglin,piglin.png,extra_mobs_piglin.png,,,,,,, +/assets/minecraft/textures/entity/piglin,zombified_piglin.png,mobs_mc_zombie_pigman.png,,,,,,, +/assets/minecraft/textures/entity/zombie,zombie.png,mobs_mc_zombie.png,,,,,,, +/assets/minecraft/textures/gui,icons.png,hbhunger_bgicon.png,16,27,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hbhunger_icon_health_poison.png,88,0,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,hbhunger_icon.png,52,27,9,9,0,0,y +/assets/minecraft/textures/gui,icons.png,mcl_hunger_icon_foodpoison.png,88,27,9,9,0,0,y +/assets/minecraft/textures/particle,particles.png,mcl_particles_smoke.png,56,0,8,8,0,0,y +/assets/minecraft/textures/item,flower_pot.png,mcl_flowerpots_flowerpot_inventory.png,,,,,,, +/assets/minecraft/textures/block,flower_pot.png,mcl_flowerpots_flowerpot.png,,,,,,,y +/assets/minecraft/textures/gui,widgets.png,mcl_inventory_hotbar.png,0,0,182,22,0,0,y +/assets/minecraft/textures/gui,widgets.png,mcl_inventory_hotbar_selected.png,0,22,24,24,0,0,y +/assets/minecraft/textures/item,compass_00.png,mcl_compass_compass_00.png,,,,,,, +/assets/minecraft/textures/item,compass_01.png,mcl_compass_compass_01.png,,,,,,, +/assets/minecraft/textures/item,compass_02.png,mcl_compass_compass_02.png,,,,,,, +/assets/minecraft/textures/item,compass_03.png,mcl_compass_compass_03.png,,,,,,, +/assets/minecraft/textures/item,compass_04.png,mcl_compass_compass_04.png,,,,,,, +/assets/minecraft/textures/item,compass_05.png,mcl_compass_compass_05.png,,,,,,, +/assets/minecraft/textures/item,compass_06.png,mcl_compass_compass_06.png,,,,,,, +/assets/minecraft/textures/item,compass_07.png,mcl_compass_compass_07.png,,,,,,, +/assets/minecraft/textures/item,compass_08.png,mcl_compass_compass_08.png,,,,,,, +/assets/minecraft/textures/item,compass_09.png,mcl_compass_compass_09.png,,,,,,, +/assets/minecraft/textures/item,compass_10.png,mcl_compass_compass_10.png,,,,,,, +/assets/minecraft/textures/item,compass_11.png,mcl_compass_compass_11.png,,,,,,, +/assets/minecraft/textures/item,compass_12.png,mcl_compass_compass_12.png,,,,,,, +/assets/minecraft/textures/item,compass_13.png,mcl_compass_compass_13.png,,,,,,, +/assets/minecraft/textures/item,compass_14.png,mcl_compass_compass_14.png,,,,,,, +/assets/minecraft/textures/item,compass_15.png,mcl_compass_compass_15.png,,,,,,, +/assets/minecraft/textures/item,compass_16.png,mcl_compass_compass_16.png,,,,,,, +/assets/minecraft/textures/item,compass_17.png,mcl_compass_compass_17.png,,,,,,, +/assets/minecraft/textures/item,compass_18.png,mcl_compass_compass_18.png,,,,,,, +/assets/minecraft/textures/item,compass_19.png,mcl_compass_compass_19.png,,,,,,, +/assets/minecraft/textures/item,compass_20.png,mcl_compass_compass_20.png,,,,,,, +/assets/minecraft/textures/item,compass_21.png,mcl_compass_compass_21.png,,,,,,, +/assets/minecraft/textures/item,compass_22.png,mcl_compass_compass_22.png,,,,,,, +/assets/minecraft/textures/item,compass_23.png,mcl_compass_compass_23.png,,,,,,, +/assets/minecraft/textures/item,compass_24.png,mcl_compass_compass_24.png,,,,,,, +/assets/minecraft/textures/item,compass_25.png,mcl_compass_compass_25.png,,,,,,, +/assets/minecraft/textures/item,compass_26.png,mcl_compass_compass_26.png,,,,,,, +/assets/minecraft/textures/item,compass_27.png,mcl_compass_compass_27.png,,,,,,, +/assets/minecraft/textures/item,compass_28.png,mcl_compass_compass_28.png,,,,,,, +/assets/minecraft/textures/item,compass_29.png,mcl_compass_compass_29.png,,,,,,, +/assets/minecraft/textures/item,compass_30.png,mcl_compass_compass_30.png,,,,,,, +/assets/minecraft/textures/item,compass_31.png,mcl_compass_compass_31.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_00.png,mcl_compass_recovery_compass_00.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_01.png,mcl_compass_recovery_compass_01.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_02.png,mcl_compass_recovery_compass_02.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_03.png,mcl_compass_recovery_compass_03.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_04.png,mcl_compass_recovery_compass_04.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_05.png,mcl_compass_recovery_compass_05.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_06.png,mcl_compass_recovery_compass_06.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_07.png,mcl_compass_recovery_compass_07.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_08.png,mcl_compass_recovery_compass_08.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_09.png,mcl_compass_recovery_compass_09.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_10.png,mcl_compass_recovery_compass_10.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_11.png,mcl_compass_recovery_compass_11.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_12.png,mcl_compass_recovery_compass_12.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_13.png,mcl_compass_recovery_compass_13.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_14.png,mcl_compass_recovery_compass_14.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_15.png,mcl_compass_recovery_compass_15.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_16.png,mcl_compass_recovery_compass_16.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_17.png,mcl_compass_recovery_compass_17.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_18.png,mcl_compass_recovery_compass_18.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_19.png,mcl_compass_recovery_compass_19.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_20.png,mcl_compass_recovery_compass_20.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_21.png,mcl_compass_recovery_compass_21.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_22.png,mcl_compass_recovery_compass_22.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_23.png,mcl_compass_recovery_compass_23.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_24.png,mcl_compass_recovery_compass_24.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_25.png,mcl_compass_recovery_compass_25.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_26.png,mcl_compass_recovery_compass_26.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_27.png,mcl_compass_recovery_compass_27.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_28.png,mcl_compass_recovery_compass_28.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_29.png,mcl_compass_recovery_compass_29.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_30.png,mcl_compass_recovery_compass_30.png,,,,,,, +/assets/minecraft/textures/item,recovery_compass_31.png,mcl_compass_recovery_compass_31.png,,,,,,, +/assets/minecraft/textures/item,clock_00.png,mcl_clock_clock_00.png,,,,,,, +/assets/minecraft/textures/item,clock_01.png,mcl_clock_clock_01.png,,,,,,, +/assets/minecraft/textures/item,clock_02.png,mcl_clock_clock_02.png,,,,,,, +/assets/minecraft/textures/item,clock_03.png,mcl_clock_clock_03.png,,,,,,, +/assets/minecraft/textures/item,clock_04.png,mcl_clock_clock_04.png,,,,,,, +/assets/minecraft/textures/item,clock_05.png,mcl_clock_clock_05.png,,,,,,, +/assets/minecraft/textures/item,clock_06.png,mcl_clock_clock_06.png,,,,,,, +/assets/minecraft/textures/item,clock_07.png,mcl_clock_clock_07.png,,,,,,, +/assets/minecraft/textures/item,clock_08.png,mcl_clock_clock_08.png,,,,,,, +/assets/minecraft/textures/item,clock_09.png,mcl_clock_clock_09.png,,,,,,, +/assets/minecraft/textures/item,clock_10.png,mcl_clock_clock_10.png,,,,,,, +/assets/minecraft/textures/item,clock_11.png,mcl_clock_clock_11.png,,,,,,, +/assets/minecraft/textures/item,clock_12.png,mcl_clock_clock_12.png,,,,,,, +/assets/minecraft/textures/item,clock_13.png,mcl_clock_clock_13.png,,,,,,, +/assets/minecraft/textures/item,clock_14.png,mcl_clock_clock_14.png,,,,,,, +/assets/minecraft/textures/item,clock_15.png,mcl_clock_clock_15.png,,,,,,, +/assets/minecraft/textures/item,clock_16.png,mcl_clock_clock_16.png,,,,,,, +/assets/minecraft/textures/item,clock_17.png,mcl_clock_clock_17.png,,,,,,, +/assets/minecraft/textures/item,clock_18.png,mcl_clock_clock_18.png,,,,,,, +/assets/minecraft/textures/item,clock_19.png,mcl_clock_clock_19.png,,,,,,, +/assets/minecraft/textures/item,clock_20.png,mcl_clock_clock_20.png,,,,,,, +/assets/minecraft/textures/item,clock_21.png,mcl_clock_clock_21.png,,,,,,, +/assets/minecraft/textures/item,clock_22.png,mcl_clock_clock_22.png,,,,,,, +/assets/minecraft/textures/item,clock_23.png,mcl_clock_clock_23.png,,,,,,, +/assets/minecraft/textures/item,clock_24.png,mcl_clock_clock_24.png,,,,,,, +/assets/minecraft/textures/item,clock_25.png,mcl_clock_clock_25.png,,,,,,, +/assets/minecraft/textures/item,clock_26.png,mcl_clock_clock_26.png,,,,,,, +/assets/minecraft/textures/item,clock_27.png,mcl_clock_clock_27.png,,,,,,, +/assets/minecraft/textures/item,clock_28.png,mcl_clock_clock_28.png,,,,,,, +/assets/minecraft/textures/item,clock_29.png,mcl_clock_clock_29.png,,,,,,, +/assets/minecraft/textures/item,clock_30.png,mcl_clock_clock_30.png,,,,,,, +/assets/minecraft/textures/item,clock_31.png,mcl_clock_clock_31.png,,,,,,, +/assets/minecraft/textures/item,clock_32.png,mcl_clock_clock_32.png,,,,,,, +/assets/minecraft/textures/item,clock_33.png,mcl_clock_clock_33.png,,,,,,, +/assets/minecraft/textures/item,clock_34.png,mcl_clock_clock_34.png,,,,,,, +/assets/minecraft/textures/item,clock_35.png,mcl_clock_clock_35.png,,,,,,, +/assets/minecraft/textures/item,clock_36.png,mcl_clock_clock_36.png,,,,,,, +/assets/minecraft/textures/item,clock_37.png,mcl_clock_clock_37.png,,,,,,, +/assets/minecraft/textures/item,clock_38.png,mcl_clock_clock_38.png,,,,,,, +/assets/minecraft/textures/item,clock_39.png,mcl_clock_clock_39.png,,,,,,, +/assets/minecraft/textures/item,clock_40.png,mcl_clock_clock_40.png,,,,,,, +/assets/minecraft/textures/item,clock_41.png,mcl_clock_clock_41.png,,,,,,, +/assets/minecraft/textures/item,clock_42.png,mcl_clock_clock_42.png,,,,,,, +/assets/minecraft/textures/item,clock_43.png,mcl_clock_clock_43.png,,,,,,, +/assets/minecraft/textures/item,clock_44.png,mcl_clock_clock_44.png,,,,,,, +/assets/minecraft/textures/item,clock_45.png,mcl_clock_clock_45.png,,,,,,, +/assets/minecraft/textures/item,clock_46.png,mcl_clock_clock_46.png,,,,,,, +/assets/minecraft/textures/item,clock_47.png,mcl_clock_clock_47.png,,,,,,, +/assets/minecraft/textures/item,clock_48.png,mcl_clock_clock_48.png,,,,,,, +/assets/minecraft/textures/item,clock_49.png,mcl_clock_clock_49.png,,,,,,, +/assets/minecraft/textures/item,clock_50.png,mcl_clock_clock_50.png,,,,,,, +/assets/minecraft/textures/item,clock_51.png,mcl_clock_clock_51.png,,,,,,, +/assets/minecraft/textures/item,clock_52.png,mcl_clock_clock_52.png,,,,,,, +/assets/minecraft/textures/item,clock_53.png,mcl_clock_clock_53.png,,,,,,, +/assets/minecraft/textures/item,clock_54.png,mcl_clock_clock_54.png,,,,,,, +/assets/minecraft/textures/item,clock_55.png,mcl_clock_clock_55.png,,,,,,, +/assets/minecraft/textures/item,clock_56.png,mcl_clock_clock_56.png,,,,,,, +/assets/minecraft/textures/item,clock_57.png,mcl_clock_clock_57.png,,,,,,, +/assets/minecraft/textures/item,clock_58.png,mcl_clock_clock_58.png,,,,,,, +/assets/minecraft/textures/item,clock_59.png,mcl_clock_clock_59.png,,,,,,, +/assets/minecraft/textures/item,clock_60.png,mcl_clock_clock_60.png,,,,,,, +/assets/minecraft/textures/item,clock_61.png,mcl_clock_clock_61.png,,,,,,, +/assets/minecraft/textures/item,clock_62.png,mcl_clock_clock_62.png,,,,,,, +/assets/minecraft/textures/item,clock_63.png,mcl_clock_clock_63.png,,,,,,, +/assets/minecraft/textures/item,empty_armor_slot_boots.png,mcl_inventory_empty_armor_slot_boots.png,,,,,,, +/assets/minecraft/textures/item,empty_armor_slot_chestplate.png,mcl_inventory_empty_armor_slot_chestplate.png,,,,,,, +/assets/minecraft/textures/item,empty_armor_slot_helmet.png,mcl_inventory_empty_armor_slot_helmet.png,,,,,,, +/assets/minecraft/textures/item,empty_armor_slot_leggings.png,mcl_inventory_empty_armor_slot_leggings.png,,,,,,, +/assets/minecraft/textures/item,empty_armor_slot_shield.png,mcl_inventory_empty_armor_slot_shield.png,,,,,,, +/assets/minecraft/textures/entity,shield_base.png,mcl_shield_base_nopattern.png,,,,,,, +/assets/minecraft/textures/entity/shield,base.png,mcl_shield_pattern_base.png,,,,,,, +/assets/minecraft/textures/entity/shield,border.png,mcl_shield_pattern_border.png,,,,,,, +/assets/minecraft/textures/entity/shield,bricks.png,mcl_shield_pattern_bricks.png,,,,,,, +/assets/minecraft/textures/entity/shield,circle.png,mcl_shield_pattern_circle.png,,,,,,, +/assets/minecraft/textures/entity/shield,creeper.png,mcl_shield_pattern_creeper.png,,,,,,, +/assets/minecraft/textures/entity/shield,cross.png,mcl_shield_pattern_cross.png,,,,,,, +/assets/minecraft/textures/entity/shield,curly_border.png,mcl_shield_pattern_curly_border.png,,,,,,, +/assets/minecraft/textures/entity/shield,diagonal_left.png,mcl_shield_pattern_diagonal_left.png,,,,,,, +/assets/minecraft/textures/entity/shield,diagonal_right.png,mcl_shield_pattern_diagonal_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,diagonal_up_left.png,mcl_shield_pattern_diagonal_up_left.png,,,,,,, +/assets/minecraft/textures/entity/shield,diagonal_up_right.png,mcl_shield_pattern_diagonal_up_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,flower.png,mcl_shield_pattern_flower.png,,,,,,, +/assets/minecraft/textures/entity/shield,gradient.png,mcl_shield_pattern_gradient.png,,,,,,, +/assets/minecraft/textures/entity/shield,gradient_up.png,mcl_shield_pattern_gradient_up.png,,,,,,, +/assets/minecraft/textures/entity/shield,half_horizontal.png,mcl_shield_pattern_half_horizontal.png,,,,,,, +/assets/minecraft/textures/entity/shield,half_horizontal_bottom.png,mcl_shield_pattern_half_horizontal_bottom.png,,,,,,, +/assets/minecraft/textures/entity/shield,half_vertical.png,mcl_shield_pattern_half_vertical.png,,,,,,, +/assets/minecraft/textures/entity/shield,half_vertical_right.png,mcl_shield_pattern_half_vertical_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,rhombus.png,mcl_shield_pattern_rhombus.png,,,,,,, +/assets/minecraft/textures/entity/shield,skull.png,mcl_shield_pattern_skull.png,,,,,,, +/assets/minecraft/textures/entity/shield,small_stripes.png,mcl_shield_pattern_small_stripes.png,,,,,,, +/assets/minecraft/textures/entity/shield,square_bottom_left.png,mcl_shield_pattern_square_bottom_left.png,,,,,,, +/assets/minecraft/textures/entity/shield,square_bottom_right.png,mcl_shield_pattern_square_bottom_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,square_top_left.png,mcl_shield_pattern_square_top_left.png,,,,,,, +/assets/minecraft/textures/entity/shield,square_top_right.png,mcl_shield_pattern_square_top_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,straight_cross.png,mcl_shield_pattern_straight_cross.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_bottom.png,mcl_shield_pattern_stripe_bottom.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_center.png,mcl_shield_pattern_stripe_center.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_downleft.png,mcl_shield_pattern_stripe_downleft.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_downright.png,mcl_shield_pattern_stripe_downright.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_left.png,mcl_shield_pattern_stripe_left.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_middle.png,mcl_shield_pattern_stripe_middle.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_right.png,mcl_shield_pattern_stripe_right.png,,,,,,, +/assets/minecraft/textures/entity/shield,stripe_top.png,mcl_shield_pattern_stripe_top.png,,,,,,, +/assets/minecraft/textures/entity/shield,triangle_bottom.png,mcl_shield_pattern_triangle_bottom.png,,,,,,, +/assets/minecraft/textures/entity/shield,triangles_bottom.png,mcl_shield_pattern_triangles_bottom.png,,,,,,, +/assets/minecraft/textures/entity/shield,triangles_top.png,mcl_shield_pattern_triangles_top.png,,,,,,, +/assets/minecraft/textures/entity/shield,triangle_top.png,mcl_banners_triangle_top.png,,,,,,, +/assets/minecraft/textures/item,knowledge_book.png,craftguide_book.png,,,,,,, +/assets/minecraft/textures/gui/sprites/icon,search.png,craftguide_search_icon.png,,,,,,, +/assets/minecraft/textures/block,redstone_dust_dot.png,redstone_redstone_dust_dot.png,,,,,,, +/assets/minecraft/textures/block,redstone_dust_line0.png,redstone_redstone_dust_line0.png,,,,,,, +/assets/minecraft/textures/block,redstone_dust_line1.png,redstone_redstone_dust_line1.png,,,,,,, +/assets/minecraft/textures/block,attached_melon_stem.png,mcl_farming_melon_stem_connected.png,,,,,,, +/assets/minecraft/textures/block,melon_stem.png,mcl_farming_melon_stem_disconnected.png,,,,,,, +/assets/minecraft/textures/entity/signs,acacia.png,mcl_signs_acacia_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,bamboo.png,mcl_bamboo_bamboo_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,birch.png,mcl_signs_birch_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,cherry.png,mcl_cherry_blossom_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,crimson.png,mcl_signs_crimson_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,dark_oak.png,mcl_signs_sign_dark.png,,,,,,, +/assets/minecraft/textures/entity/signs,jungle.png,mcl_signs_jungle_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,mangrove.png,mcl_signs_mangrove_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,oak.png,mcl_signs_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,spruce.png,mcl_signs_spruce_sign.png,,,,,,, +/assets/minecraft/textures/entity/signs,warped.png,mcl_signs_warped_sign.png,,,,,,, +/assets/minecraft/textures/item,acacia_sign.png,mcl_signs_acacia_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,bamboo_sign.png,mcl_bamboo_bamboo_sign_wield.png,,,,,,, +/assets/minecraft/textures/item,birch_sign.png,mcl_signs_birch_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,cherry_sign.png,mcl_cherry_blossom_inv.png,,,,,,, +/assets/minecraft/textures/item,crimson_sign.png,mcl_signs_crimson_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,dark_oak_sign.png,mcl_signs_default_dark.png,,,,,,, +/assets/minecraft/textures/item,jungle_sign.png,mcl_signs_jungle_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,mangrove_sign.png,mcl_signs_mangrove_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,oak_sign.png,mcl_signs_default_sign.png,,,,,,, +/assets/minecraft/textures/item,spruce_sign.png,mcl_signs_spruce_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,warped_sign.png,mcl_signs_warped_sign_inv.png,,,,,,, +/assets/minecraft/textures/entity,banner_base.png,mcl_banners_banner_base.png,,,,,,, +/assets/minecraft/textures/entity/banner,base.png,mcl_banners_base.png,,,,,,, +/assets/minecraft/textures/block,nether_portal.png,mcl_portals_portal.png,,,,,,, +/assets/minecraft/textures/entity,end_portal.png,mcl_portals_end_portal.png,,,,,,, +/assets/minecraft/textures/entity/chest,normal.png,mcl_chests_normal.png,,,,,,, +/assets/minecraft/textures/entity/chest,trapped.png,mcl_chests_trapped.png,,,,,,, +/assets/minecraft/textures/entity/chest,ender.png,mcl_chests_ender.png,,,,,,, +/assets/minecraft/textures/block,end_portal_frame_top.png,mcl_portals_endframe_top.png,,,,,,, +/assets/minecraft/textures/block,end_portal_frame_side.png,mcl_portals_endframe_side.png,,,,,,, +/assets/minecraft/textures/block,end_portal_frame_eye.png,mcl_portals_endframe_eye.png,,,,,,, +/assets/minecraft/textures/block,end_stone.png,mcl_portals_endframe_bottom.png,,,,,,, +/assets/minecraft/textures/block,cobblestone.png,mcl_walls_cobble_wall_top.png,,,,,,, +/assets/minecraft/textures/block,cobblestone.png,mcl_walls_cobble_wall_side.png,,,,,,, +/assets/minecraft/textures/block,mossy_cobblestone.png,mcl_walls_cobble_mossy_wall_top.png,,,,,,, +/assets/minecraft/textures/block,mossy_cobblestone.png,mcl_walls_cobble_mossy_wall_side.png,,,,,,, +/assets/minecraft/textures/block,chiseled_deepslate.png,mcl_chiseled_deepslate.png,,,,,,, +/assets/minecraft/textures/block,cobbled_deepslate.png,mcl_cobbled_deepslate.png,,,,,,, +/assets/minecraft/textures/block,cracked_deepslate_bricks.png,mcl_cracked_deepslate_bricks.png,,,,,,, +/assets/minecraft/textures/block,cracked_deepslate_tiles.png,mcl_cracked_deepslate_tiles.png,,,,,,, +/assets/minecraft/textures/block,deepslate.png,mcl_deepslate.png,,,,,,, +/assets/minecraft/textures/block,deepslate_bricks.png,mcl_deepslate_bricks.png,,,,,,, +/assets/minecraft/textures/block,deepslate_coal_ore.png,mcl_deepslate_coal_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_diamond_ore.png,mcl_deepslate_diamond_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_emerald_ore.png,mcl_deepslate_emerald_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_gold_ore.png,mcl_deepslate_gold_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_iron_ore.png,mcl_deepslate_iron_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_lapis_ore.png,mcl_deepslate_lapis_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_redstone_ore.png,mcl_deepslate_redstone_ore.png,,,,,,, +/assets/minecraft/textures/block,deepslate_tiles.png,mcl_deepslate_tiles.png,,,,,,, +/assets/minecraft/textures/block,deepslate_top.png,mcl_deepslate_top.png,,,,,,, +/assets/minecraft/textures/block,polished_deepslate.png,mcl_polished_deepslate.png,,,,,,, +/assets/minecraft/textures/block,tuff.png,mcl_deepslate_tuff.png,,,,,,, +/assets/minecraft/textures/block,grass_block_top.png,mcl_core_grass_block_top.png,,,,,,, +/assets/minecraft/textures/block,grass_block_side_overlay.png,mcl_core_grass_block_side_overlay.png,,,,,,, +/assets/minecraft/textures/item,enchanted_book.png,mcl_enchanting_book_enchanted.png,,,,,,, +/assets/minecraft/textures/item,experience_bottle.png,mcl_experience_bottle.png,,,,,,, +/assets/minecraft/textures/entity/bed,black.png,mcl_beds_bed_black.png,,,,,,, +/assets/minecraft/textures/entity/bed,blue.png,mcl_beds_bed_blue.png,,,,,,, +/assets/minecraft/textures/entity/bed,brown.png,mcl_beds_bed_brown.png,,,,,,, +/assets/minecraft/textures/entity/bed,cyan.png,mcl_beds_bed_cyan.png,,,,,,, +/assets/minecraft/textures/entity/bed,gray.png,mcl_beds_bed_grey.png,,,,,,, +/assets/minecraft/textures/entity/bed,green.png,mcl_beds_bed_green.png,,,,,,, +/assets/minecraft/textures/entity/bed,light_blue.png,mcl_beds_bed_light_blue.png,,,,,,, +/assets/minecraft/textures/entity/bed,light_gray.png,mcl_beds_bed_silver.png,,,,,,, +/assets/minecraft/textures/entity/bed,lime.png,mcl_beds_bed_lime.png,,,,,,, +/assets/minecraft/textures/entity/bed,magenta.png,mcl_beds_bed_magenta.png,,,,,,, +/assets/minecraft/textures/entity/bed,orange.png,mcl_beds_bed_orange.png,,,,,,, +/assets/minecraft/textures/entity/bed,pink.png,mcl_beds_bed_pink.png,,,,,,, +/assets/minecraft/textures/entity/bed,purple.png,mcl_beds_bed_purple.png,,,,,,, +/assets/minecraft/textures/entity/bed,white.png,mcl_beds_bed_white.png,,,,,,, +/assets/minecraft/textures/entity/bed,yellow.png,mcl_beds_bed_yellow.png,,,,,,, +/assets/minecraft/textures/block,cherry_door_top.png,mcl_cherry_blossom_door_top.png,,,,,,, +/assets/minecraft/textures/block,cherry_leaves.png,mcl_cherry_blossom_leaves.png,,,,,,, +/assets/minecraft/textures/block,jungle_leaves.png,mcl_mangrove_leaves.png,,,,,,, +/assets/minecraft/textures/block,cherry_door_bottom.png,mcl_cherry_blossom_door_bottom.png,,,,,,, +/assets/minecraft/textures/item,cherry_sign.png,mcl_cherry_blossom_sign_inv.png,,,,,,, +/assets/minecraft/textures/item,cherry_door.png,mcl_cherry_blossom_door_inv.png,,,,,,, +/assets/minecraft/textures/entity,dolphin.png,extra_mobs_dolphin.png,,,,,,, +/assets/minecraft/textures/entity/hoglin,hoglin.png,extra_mobs_hoglin.png,,,,,,, +/assets/minecraft/textures/entity/hoglin,zoglin.png,extra_mobs_zoglin.png,,,,,,, +/assets/minecraft/textures/entity/strider,strider.png,extra_mobs_strider.png,,,,,,, +/assets/minecraft/textures/entity/strider,strider_cold.png,extra_mobs_strider_cold.png,,,,,,, +/assets/minecraft/textures/item,coast_armor_trim_smithing_template.png,coast_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,dune_armor_trim_smithing_template.png,dune_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,eye_armor_trim_smithing_template.png,eye_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,empty_slot_smithing_template_armor_trim.png,mcl_smithing_table_inventory_trim_bg.png,,,,,,, +/assets/minecraft/textures/item,rib_armor_trim_smithing_template.png,rib_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,sentry_armor_trim_smithing_template.png,sentry_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,silence_armor_trim_smithing_template.png,silence_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,snout_armor_trim_smithing_template.png,snout_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,spire_armor_trim_smithing_template.png,spire_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,tide_armor_trim_smithing_template.png,tide_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,vex_armor_trim_smithing_template.png,vex_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,ward_armor_trim_smithing_template.png,ward_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,wayfinder_armor_trim_smithing_template.png,wayfinder_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/item,wild_armor_trim_smithing_template.png,wild_armor_trim_smithing_template.png,,,,,,, +/assets/minecraft/textures/trims/items,boots_trim.png,boots_trim.png,,,,,,, +/assets/minecraft/textures/trims/items,chestplate_trim.png,chestplate_trim.png,,,,,,, +/assets/minecraft/textures/trims/items,helmet_trim.png,helmet_trim.png,,,,,,, +/assets/minecraft/textures/trims/items,leggings_trim.png,leggings_trim.png,,,,,,, +/assets/minecraft/textures/block,lodestone_side.png,lodestone_bottom.png,,,,,,, +/assets/minecraft/textures/block,lodestone_side.png,lodestone_side1.png,,,,,,, +/assets/minecraft/textures/block,lodestone_side.png,lodestone_side2.png,,,,,,, +/assets/minecraft/textures/block,lodestone_side.png,lodestone_side3.png,,,,,,, +/assets/minecraft/textures/block,lodestone_side.png,lodestone_side4.png,,,,,,, +/assets/minecraft/textures/block,lodestone_top.png,lodestone_top.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_bottom.png,respawn_anchor_bottom.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_side0.png,respawn_anchor_side0.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_side1.png,respawn_anchor_side1.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_side2.png,respawn_anchor_side2.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_side3.png,respawn_anchor_side3.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_side4.png,respawn_anchor_side4.png,,,,,,, +/assets/minecraft/textures/block,respawn_anchor_top_off.png,respawn_anchor_top_off.png,,,,,,, +/assets/minecraft/textures/block,amethyst_block.png,mcl_amethyst_amethyst_block.png,,,,,,, +/assets/minecraft/textures/block,large_amethyst_bud.png,mcl_amethyst_amethyst_bud_large.png,,,,,,, +/assets/minecraft/textures/block,medium_amethyst_bud.png,mcl_amethyst_amethyst_bud_medium.png,,,,,,, +/assets/minecraft/textures/block,small_amethyst_bud.png,mcl_amethyst_amethyst_bud_small.png,,,,,,, +/assets/minecraft/textures/block,amethyst_cluster.png,mcl_amethyst_amethyst_cluster.png,,,,,,, +/assets/minecraft/textures/item,amethyst_shard.png,mcl_amethyst_amethyst_shard.png,,,,,,, +/assets/minecraft/textures/block,budding_amethyst.png,mcl_amethyst_budding_amethyst.png,,,,,,, +/assets/minecraft/textures/block,calcite.png,mcl_amethyst_calcite_block.png,,,,,,, +/assets/minecraft/textures/block,bamboo_planks.png,mcl_bamboo_fence_bamboo.png,,,,,,, +/assets/minecraft/textures/block,bamboo_planks.png,mcl_bamboo_fence_gate_bamboo.png,,,,,,, +/assets/minecraft/textures/block,crimson_planks.png,mcl_crimson_crimson_fence.png,,,,,,, +/assets/minecraft/textures/block,crimson_planks.png,mcl_crimson_crimson_fence_side.png,,,,,,, +/assets/minecraft/textures/block,crimson_planks.png,mcl_crimson_crimson_fence_top.png,,,,,,, +/assets/minecraft/textures/block,warped_planks.png,mcl_crimson_warped_fence.png,,,,,,, +/assets/minecraft/textures/block,warped_planks.png,mcl_crimson_warped_fence_side.png,,,,,,, +/assets/minecraft/textures/block,warped_planks.png,mcl_crimson_warped_fence_top.png,,,,,,, +/assets/minecraft/textures/block,acacia_planks.png,mcl_fences_fence_acacia.png,,,,,,, +/assets/minecraft/textures/block,acacia_planks.png,mcl_fences_fence_gate_acacia.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_planks.png,mcl_fences_fence_big_oak.png,,,,,,, +/assets/minecraft/textures/block,dark_oak_planks.png,mcl_fences_fence_gate_big_oak.png,,,,,,, +/assets/minecraft/textures/block,birch_planks.png,mcl_fences_fence_birch.png,,,,,,, +/assets/minecraft/textures/block,birch_planks.png,mcl_fences_fence_gate_birch.png,,,,,,, +/assets/minecraft/textures/block,jungle_planks.png,mcl_fences_fence_gate_jungle.png,,,,,,, +/assets/minecraft/textures/block,jungle_planks.png,mcl_fences_fence_jungle.png,,,,,,, +/assets/minecraft/textures/block,oak_planks.png,mcl_fences_fence_gate_oak.png,,,,,,, +/assets/minecraft/textures/block,oak_planks.png,mcl_fences_fence_oak.png,,,,,,, +/assets/minecraft/textures/block,spruce_planks.png,mcl_fences_fence_gate_spruce.png,,,,,,, +/assets/minecraft/textures/block,spruce_planks.png,mcl_fences_fence_spruce.png,,,,,,, +/assets/minecraft/textures/block,mangrove_planks.png,mcl_mangrove_fence.png,,,,,,, +/assets/minecraft/textures/block,mangrove_planks.png,mcl_mangrove_fence_gate.png,,,,,,, +/assets/minecraft/textures/block,red_nether_bricks.png,mcl_fences_fence_red_nether_brick.png,,,,,,, +/assets/minecraft/textures/block,red_nether_bricks.png,mcl_fences_fence_gate_red_nether_brick.png,,,,,,, +/assets/minecraft/textures/block,nether_bricks.png,mcl_fences_fence_gate_nether_brick.png,,,,,,, +/assets/minecraft/textures/block,nether_bricks.png,mcl_fences_fence_nether_brick.png,,,,,,, +/assets/minecraft/textures/block,scaffolding_bottom.png,mcl_bamboo_scaffolding_bottom.png,,,,,,, +/assets/minecraft/textures/block,scaffolding_top.png,mcl_bamboo_scaffolding_top.png,,,,,,, +/assets/minecraft/textures/block,oak_planks.png,mcl_banners_fallback_wood.png,,,,,,, +/assets/minecraft/textures/block,barrel_bottom.png,mcl_barrels_barrel_bottom.png,,,,,,, +/assets/minecraft/textures/block,barrel_side.png,mcl_barrels_barrel_side.png,,,,,,, +/assets/minecraft/textures/block,barrel_top.png,mcl_barrels_barrel_top.png,,,,,,, +/assets/minecraft/textures/block,barrel_top_open.png,mcl_barrels_barrel_top_open.png,,,,,,, +/assets/minecraft/textures/block,beehive_end.png,mcl_beehives_beehive_end.png,,,,,,, +/assets/minecraft/textures/block,beehive_front.png,mcl_beehives_beehive_front.png,,,,,,, +/assets/minecraft/textures/block,beehive_front_honey.png,mcl_beehives_beehive_front_honey.png,,,,,,, +/assets/minecraft/textures/block,beehive_side.png,mcl_beehives_beehive_side.png,,,,,,, +/assets/minecraft/textures/block,bee_nest_bottom.png,mcl_beehives_bee_nest_bottom.png,,,,,,, +/assets/minecraft/textures/block,bee_nest_front.png,mcl_beehives_bee_nest_front.png,,,,,,, +/assets/minecraft/textures/block,bee_nest_front_honey.png,mcl_beehives_bee_nest_front_honey.png,,,,,,, +/assets/minecraft/textures/block,bee_nest_side.png,mcl_beehives_bee_nest_side.png,,,,,,, +/assets/minecraft/textures/block,bee_nest_top.png,mcl_beehives_bee_nest_top.png,,,,,,, +/assets/minecraft/textures/item,bell.png,mcl_bells_bell.png,,,,,,, +/assets/minecraft/textures/block,basalt_side.png,mcl_blackstone_basalt_side.png,,,,,,, +/assets/minecraft/textures/block,basalt_top.png,mcl_blackstone_basalt_top.png,,,,,,, +/assets/minecraft/textures/block,polished_basalt_side.png,mcl_blackstone_basalt_side_polished.png,,,,,,, +/assets/minecraft/textures/block,polished_basalt_top.png,mcl_blackstone_basalt_top_polished.png,,,,,,, +/assets/minecraft/textures/block,smooth_basalt.png,mcl_blackstone_basalt_smooth.png,,,,,,, +/assets/minecraft/textures/block,chiseled_polished_blackstone.png,mcl_blackstone_chiseled_polished.png,,,,,,, +/assets/minecraft/textures/block,gilded_blackstone.png,mcl_blackstone_gilded.png,,,,,,, +/assets/minecraft/textures/block,polished_blackstone.png,mcl_blackstone_polished.png,,,,,,, +/assets/minecraft/textures/block,polished_blackstone_bricks.png,mcl_blackstone_polished_bricks.png,,,,,,, +/assets/minecraft/textures/block,blackstone.png,mcl_blackstone_side.png,,,,,,, +/assets/minecraft/textures/block,blackstone_top.png,mcl_blackstone_top.png,,,,,,, +/assets/minecraft/textures/block,soul_soil.png,mcl_blackstone_soul_soil.png,,,,,,, +/assets/minecraft/textures/item,light_00.png,mcl_core_light_0.png,,,,,,, +/assets/minecraft/textures/item,light_01.png,mcl_core_light_1.png,,,,,,, +/assets/minecraft/textures/item,light_02.png,mcl_core_light_2.png,,,,,,, +/assets/minecraft/textures/item,light_03.png,mcl_core_light_3.png,,,,,,, +/assets/minecraft/textures/item,light_04.png,mcl_core_light_4.png,,,,,,, +/assets/minecraft/textures/item,light_05.png,mcl_core_light_5.png,,,,,,, +/assets/minecraft/textures/item,light_06.png,mcl_core_light_6.png,,,,,,, +/assets/minecraft/textures/item,light_07.png,mcl_core_light_7.png,,,,,,, +/assets/minecraft/textures/item,light_08.png,mcl_core_light_8.png,,,,,,, +/assets/minecraft/textures/item,light_09.png,mcl_core_light_9.png,,,,,,, +/assets/minecraft/textures/item,light_10.png,mcl_core_light_10.png,,,,,,, +/assets/minecraft/textures/item,light_11.png,mcl_core_light_11.png,,,,,,, +/assets/minecraft/textures/item,light_12.png,mcl_core_light_12.png,,,,,,, +/assets/minecraft/textures/item,light_13.png,mcl_core_light_13.png,,,,,,, +/assets/minecraft/textures/item,light_14.png,mcl_core_light_14.png,,,,,,, +/assets/minecraft/textures/block,honey_block_bottom.png,mcl_honey_block_bottom.png,,,,,,, +/assets/minecraft/textures/block,honey_block_side.png,mcl_honey_block_side.png,,,,,,, +/assets/minecraft/textures/block,honey_block_top.png,mcl_honey_block_top.png,,,,,,, +/assets/minecraft/textures/item,honey_bottle.png,mcl_honey_honey_bottle.png,,,,,,, +/assets/minecraft/textures/item,honeycomb.png,mcl_honey_honeycomb.png,,,,,,, +/assets/minecraft/textures/block,honeycomb_block.png,mcl_honey_honeycomb_block.png,,,,,,, +/assets/minecraft/textures/mob_effect,bad_omen.png,mcl_potions_effect_bad_omen.png,,,,,,, +/assets/minecraft/textures/mob_effect,fire_resistance.png,mcl_potions_effect_fire_proof.png,,,,,,, +/assets/minecraft/textures/mob_effect,invisibility.png,mcl_potions_effect_invisible.png,,,,,,, +/assets/minecraft/textures/mob_effect,jump_boost.png,mcl_potions_effect_leaping.png,,,,,,, +/assets/minecraft/textures/mob_effect,night_vision.png,mcl_potions_effect_night_vision.png,,,,,,, +/assets/minecraft/textures/mob_effect,poison.png,mcl_potions_effect_poisoned.png,,,,,,, +/assets/minecraft/textures/mob_effect,regeneration.png,mcl_potions_effect_regenerating.png,,,,,,, +/assets/minecraft/textures/mob_effect,slowness.png,mcl_potions_effect_slow.png,,,,,,, +/assets/minecraft/textures/mob_effect,speed.png,mcl_potions_effect_swift.png,,,,,,, +/assets/minecraft/textures/mob_effect,strength.png,mcl_potions_effect_strong.png,,,,,,, +/assets/minecraft/textures/mob_effect,water_breathing.png,mcl_potions_effect_water_breathing.png,,,,,,, +/assets/minecraft/textures/mob_effect,weakness.png,mcl_potions_effect_weak.png,,,,,,, +/assets/minecraft/textures/mob_effect,wither.png,mcl_potions_effect_withering.png,,,,,,, +/assets/minecraft/textures/mob_effect,hero_of_the_village.png,mcl_raids_hero_of_the_village_icon.png,,,,,,, +/assets/minecraft/textures/gui/sprites/hud/heart,withered_full.png,mcl_potions_icon_regen_wither.png,,,,,,, +/assets/minecraft/textures/gui/sprites/hud/heart,withered_full.png,mcl_potions_icon_wither.png,,,,,,, +/assets/minecraft/textures/particle,effect_5.png,mcl_particles_effect.png,,,,,,, +/assets/minecraft/textures/particle,lava.png,mcl_particles_lava.png,,,,,,, +/assets/minecraft/textures/particle,note.png,mcl_particles_note.png,,,,,,, +/assets/minecraft/textures/particle,flame.png,mcl_particles_flame.png,,,,,,, +/assets/minecraft/textures/particle,soul_fire_flame.png,mcl_particles_soul_fire_flame.png,,,,,,, +/assets/minecraft/textures/item,firework_rocket.png,mcl_fireworks_rocket.png,,,,,,, +/assets/minecraft/textures/block,chain.png,mcl_lanterns_chain.png,,,,,,, +/assets/minecraft/textures/item,chain.png,mcl_lanterns_chain_inv.png,,,,,,, +/assets/minecraft/textures/block,lantern.png,mcl_lanterns_lantern.png,,,,,,, +/assets/minecraft/textures/item,lantern.png,mcl_lanterns_lantern_inv.png,,,,,,, +/assets/minecraft/textures/block,soul_lantern.png,mcl_lanterns_soul_lantern.png,,,,,,, +/assets/minecraft/textures/item,soul_lantern.png,mcl_lanterns_soul_lantern_inv.png,,,,,,, +/assets/minecraft/textures/block,soul_torch.png,soul_torch_on_floor.png,,,,,,, +/assets/minecraft/textures/block,soul_torch.png,soul_torch_on_floor_animated.png,,,,,,, +/assets/minecraft/textures/block,lightning_rod.png,mcl_lightning_rods_rod.png,,,,,,, +/assets/minecraft/textures/block,mangrove_roots_side.png,mcl_mangrove_roots_side.png,,,,,,, +/assets/minecraft/textures/block,mangrove_roots_top.png,mcl_mangrove_roots_top.png,,,,,,, +/assets/minecraft/textures/block,mud.png,mcl_mud.png,,,,,,, +/assets/minecraft/textures/block,packed_mud.png,mcl_mud_packed_mud.png,,,,,,, +/assets/minecraft/textures/block,mud_bricks.png,mcl_mud_bricks.png,,,,,,, +/assets/minecraft/textures/item,painting.png,mcl_paintings_painting.png,,,,,,, +/assets/minecraft/textures/block,sculk_catalyst_bottom.png,mcl_sculk_catalyst_bottom.png,,,,,,, +/assets/minecraft/textures/block,sculk_catalyst_side.png,mcl_sculk_catalyst_side.png,,,,,,, +/assets/minecraft/textures/block,sculk_catalyst_top.png,mcl_sculk_catalyst_top.png,,,,,,, +/assets/minecraft/textures/block,sculk.png,mcl_sculk_sculk.png,,,,,,, +/assets/minecraft/textures/block,sculk_sensor_bottom.png,mcl_sculk_sensor_bottom.png,,,,,,, +/assets/minecraft/textures/block,sculk_sensor_side.png,mcl_sculk_sensor_side.png,,,,,,, +/assets/minecraft/textures/block,sculk_sensor_top.png,mcl_sculk_sensor_top.png,,,,,,, +/assets/minecraft/textures/block,sculk_shrieker_bottom.png,mcl_sculk_shrieker_bottom.png,,,,,,, +/assets/minecraft/textures/block,sculk_shrieker_side.png,mcl_sculk_shrieker_side.png,,,,,,, +/assets/minecraft/textures/block,sculk_shrieker_top.png,mcl_sculk_shrieker_top.png,,,,,,, +/assets/minecraft/textures/item,spyglass.png,mcl_spyglass.png,,,,,,, +/assets/minecraft/textures/misc,spyglass_scope.png,mcl_spyglass_scope.png,,,,,,, +/assets/minecraft/textures/block,stonecutter_bottom.png,mcl_stonecutter_bottom.png,,,,,,, +/assets/minecraft/textures/block,stonecutter_side.png,mcl_stonecutter_side.png,,,,,,, +/assets/minecraft/textures/block,stonecutter_top.png,mcl_stonecutter_top.png,,,,,,, +/assets/minecraft/textures/entity/llama,creamy.png,mobs_mc_llama.png,,,,,,, +/assets/minecraft/textures/entity/llama,brown.png,mobs_mc_llama_brown.png,,,,,,, +/assets/minecraft/textures/entity/llama,creamy.png,mobs_mc_llama_creamy.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,black.png,mobs_mc_llama_decor_black.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,blue.png,mobs_mc_llama_decor_blue.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,brown.png,mobs_mc_llama_decor_brown.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,cyan.png,mobs_mc_llama_decor_cyan.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,gray.png,mobs_mc_llama_decor_gray.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,green.png,mobs_mc_llama_decor_green.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,light_blue.png,mobs_mc_llama_decor_light_blue.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,light_gray.png,mobs_mc_llama_decor_light_gray.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,lime.png,mobs_mc_llama_decor_lime.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,magenta.png,mobs_mc_llama_decor_magenta.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,orange.png,mobs_mc_llama_decor_orange.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,pink.png,mobs_mc_llama_decor_pink.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,purple.png,mobs_mc_llama_decor_purple.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,red.png,mobs_mc_llama_decor_red.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,white.png,mobs_mc_llama_decor_white.png,,,,,,, +/assets/minecraft/textures/entity/llama/decor,yellow.png,mobs_mc_llama_decor_yellow.png,,,,,,, +/assets/minecraft/textures/entity/llama,gray.png,mobs_mc_llama_gray.png,,,,,,, +/assets/minecraft/textures/entity/llama,white.png,mobs_mc_llama_white.png,,,,,,, diff --git a/tools/README.md b/tools/README.md index 4dc378bc1..7ff016bf9 100644 --- a/tools/README.md +++ b/tools/README.md @@ -1,10 +1,10 @@ -# MineClone 2 Tools -This directory is for tools and scripts for MineClone 2. +# VoxeLibre Tools +This directory is for tools and scripts for VoxeLibre. Currently, the only tool is Texture Converter. ## Texture Converter (EXPERIMENTAL) This is a Python script which converts a resource pack for Minecraft to -a texture pack for Minetest so it can be used with MineClone 2. +a texture pack for Minetest so it can be used with VoxeLibre. **WARNING**: This script is currently incomplete, not all textures will be converted. Some texture conversions are even buggy! @@ -14,7 +14,7 @@ will be required afterwards. Modes of operation: - Can create a Minetest texture pack (default) -- Can update the MineClone 2 textures +- Can update the VoxeLibre textures Requirements: - Know how to use the console @@ -29,7 +29,7 @@ Usage: any other Minetest texture pack ## Luacheck Globals Generators -This is a Python script which list every single global tables in mineclone2 source code. +This is a Python script which list every single global tables in VoxeLibre source code. It outputs a list to be used in luacheck conf files. Modes of operation: diff --git a/tools/Texture_Converter.py b/tools/Texture_Converter.py index 67800ccfc..df882b681 100755 --- a/tools/Texture_Converter.py +++ b/tools/Texture_Converter.py @@ -1,474 +1,42 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Texture Converter. -# Converts Minecraft resource packs to Minetest texture packs. -# See README.md. +# cli.py -__author__ = "Wuzzy" -__license__ = "MIT License" -__status__ = "Development" +import argparse +import sys +from libtextureconverter.gui import main as launch_gui +from libtextureconverter.config import SUPPORTED_MINECRAFT_VERSION, working_dir, appname, home +from libtextureconverter.utils import handle_default_minecraft_texture, find_all_minecraft_resourcepacks +from libtextureconverter.common import convert_resource_packs -import shutil, csv, os, tempfile, sys, getopt +def main(): + make_texture_pack = True + parser = argparse.ArgumentParser(description=f"This is the official VoxeLibre Texture Converter. This will convert textures from Minecraft resource packs to a Minetest texture pack. Supported Minecraft version: {SUPPORTED_MINECRAFT_VERSION} (Java Edition)") + parser.add_argument("-i", "--input", help="Directory of Minecraft resource pack to convert") + parser.add_argument("-o", "--output", default=working_dir, help="Directory in which to put the resulting Minetest texture pack") + parser.add_argument("-p", "--pixel-size", type=int, help="Size (in pixels) of the original textures") + parser.add_argument("-d", "--dry-run", action="store_true", help="Pretend to convert textures without changing any files") + parser.add_argument("-v", "--verbose", action="store_true", help="Print out all copying actions") + parser.add_argument("-def", "--default", action="store_true", help="Use the default Minecraft texture pack") + parser.add_argument("-a", "--all", action="store_true", help="Convert all known Minecraft texturepacks") + args = parser.parse_args() -# Helper vars -home = os.environ["HOME"] -mineclone2_path = home + "/.minetest/games/mineclone2" -working_dir = os.getcwd() -appname = "Texture_Converter.py" + if len(sys.argv) == 1: + launch_gui() + else: + resource_packs = [] + if args.default: + resource_packs.append(handle_default_minecraft_texture(home, args.output)) + elif args.all: + resource_packs.extend(find_all_minecraft_resourcepacks()) + elif args.input: + resource_packs.append(args.input) -### SETTINGS ### -output_dir = working_dir + if not resource_packs: + print(f"ERROR: No valid resource packs specified. Use '{appname} -h' for help.") + sys.exit(2) -base_dir = None + convert_resource_packs(resource_packs, args.output, args.pixel_size, args.dry_run, args.verbose, make_texture_pack) -# If True, will only make console output but not convert anything. -dry_run = False - -# If True, textures will be put into a texture pack directory structure. -# If False, textures will be put into MineClone 2 directories. -make_texture_pack = True - -# If True, prints all copying actions -verbose = False - -PXSIZE = 16 - -syntax_help = appname+""" -i [-o ] [-d] [-v|-q] [-h] -Mandatory argument: --i - Directory of Minecraft resource pack to convert - -Optional arguments: --p - Specify the size (in pixels) of the original textures (default: 16) --o - Directory in which to put the resulting Minetest texture pack - (default: working directory) --d - Just pretend to convert textures and just print output, but do not actually - change any files. --v - Print out all copying actions --h - Show this help and exit""" -try: - opts, args = getopt.getopt(sys.argv[1:],"hi:o:p:dv") -except getopt.GetoptError: - print( -"""ERROR! The options you gave me make no sense! - -Here's the syntax reference:""") - print(syntax_help) - sys.exit(2) -for opt, arg in opts: - if opt == "-h": - print( -"""This is the official MineClone 2 Texture Converter. -This will convert textures from Minecraft resource packs to -a Minetest texture pack. - -Supported Minecraft version: 1.12 (Java Edition) - -Syntax:""") - print(syntax_help) - sys.exit() - elif opt == "-d": - dry_run = True - elif opt == "-v": - verbose = True - elif opt == "-i": - base_dir = arg - elif opt == "-o": - output_dir = arg - elif opt == "-p": - PXSIZE = int(arg) - -if base_dir == None: - print( -"""ERROR: You didn't tell me the path to the Minecraft resource pack. -Mind-reading has not been implemented yet. - -Try this: - """+appname+""" -i -p - -For the full help, use: - """+appname+""" -h""") - sys.exit(2); - -### END OF SETTINGS ### - -tex_dir = base_dir + "/assets/minecraft/textures" - -# Get texture pack name (from directory name) -bdir_split = base_dir.split("/") -output_dir_name = bdir_split[-1] -if len(output_dir_name) == 0: - if len(bdir_split) >= 2: - output_dir_name = base_dir.split("/")[-2] - else: - # Fallback - output_dir_name = "New_MineClone_2_Texture_Pack" - -# FUNCTION DEFINITIONS -def colorize(colormap, source, colormap_pixel, texture_size, destination): - os.system("convert "+colormap+" -crop 1x1+"+colormap_pixel+" -depth 8 -resize "+texture_size+"x"+texture_size+" "+tempfile1.name) - os.system("composite -compose Multiply "+tempfile1.name+" "+source+" "+destination) - -def colorize_alpha(colormap, source, colormap_pixel, texture_size, destination): - colorize(colormap, source, colormap_pixel, texture_size, tempfile2.name) - os.system("composite -compose Dst_In "+source+" "+tempfile2.name+" -alpha Set "+destination) - -def target_dir(directory): - if make_texture_pack: - return output_dir + "/" + output_dir_name - else: - return mineclone2_path + directory - -# Copy texture files -def convert_textures(): - failed_conversions = 0 - print("Texture conversion BEGINS NOW!") - with open("Conversion_Table.csv", newline="") as csvfile: - reader = csv.reader(csvfile, delimiter=",", quotechar='"') - first_row = True - for row in reader: - # Skip first row - if first_row: - first_row = False - continue - - src_dir = row[0] - src_filename = row[1] - dst_dir = row[2] - dst_filename = row[3] - if row[4] != "": - xs = int(row[4]) - ys = int(row[5]) - xl = int(row[6]) - yl = int(row[7]) - xt = int(row[8]) - yt = int(row[9]) - else: - xs = None - blacklisted = row[10] - - if blacklisted == "y": - # Skip blacklisted files - continue - - if make_texture_pack == False and dst_dir == "": - # If destination dir is empty, this texture is not supposed to be used in MCL2 - # (but maybe an external mod). It should only be used in texture packs. - # Otherwise, it must be ignored. - # Example: textures for mcl_supplemental - continue - - src_file = base_dir + src_dir + "/" + src_filename # source file - src_file_exists = os.path.isfile(src_file) - dst_file = target_dir(dst_dir) + "/" + dst_filename # destination file - - if src_file_exists == False: - print("WARNING: Source file does not exist: "+src_file) - failed_conversions = failed_conversions + 1 - continue - - if xs != None: - # Crop and copy images - if not dry_run: - os.system("convert "+src_file+" -crop "+xl+"x"+yl+"+"+xs+"+"+ys+" "+dst_file) - if verbose: - print(src_file + " → " + dst_file) - else: - # Copy image verbatim - if not dry_run: - shutil.copy2(src_file, dst_file) - if verbose: - print(src_file + " → " + dst_file) - - # Convert map background - map_background_file = tex_dir + "/map/map_background.png" - if os.path.isfile(map_background_file): - os.system("convert " + map_background_file + " -interpolate Integer -filter point -resize \"140x140\" " + target_dir("/mods/ITEMS/mcl_maps/textures") + "/mcl_maps_map_background.png") - - # Convert armor textures (requires ImageMagick) - armor_files = [ - [ tex_dir + "/models/armor/leather_layer_1.png", tex_dir + "/models/armor/leather_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_leather.png", "mcl_armor_chestplate_leather.png", "mcl_armor_leggings_leather.png", "mcl_armor_boots_leather.png" ], - [ tex_dir + "/models/armor/chainmail_layer_1.png", tex_dir + "/models/armor/chainmail_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_chain.png", "mcl_armor_chestplate_chain.png", "mcl_armor_leggings_chain.png", "mcl_armor_boots_chain.png" ], - [ tex_dir + "/models/armor/gold_layer_1.png", tex_dir + "/models/armor/gold_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_gold.png", "mcl_armor_chestplate_gold.png", "mcl_armor_leggings_gold.png", "mcl_armor_boots_gold.png" ], - [ tex_dir + "/models/armor/iron_layer_1.png", tex_dir + "/models/armor/iron_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_iron.png", "mcl_armor_chestplate_iron.png", "mcl_armor_leggings_iron.png", "mcl_armor_boots_iron.png" ], - [ tex_dir + "/models/armor/diamond_layer_1.png", tex_dir + "/models/armor/diamond_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_diamond.png", "mcl_armor_chestplate_diamond.png", "mcl_armor_leggings_diamond.png", "mcl_armor_boots_diamond.png" ], - [ tex_dir + "/models/armor/netherite_layer_1.png", tex_dir + "/models/armor/netherite_layer_2.png", target_dir("/mods/ITEMS/mcl_armor/textures"), "mcl_armor_helmet_netherite.png", "mcl_armor_chestplate_netherite.png", "mcl_armor_leggings_netherite.png", "mcl_armor_boots_netherite.png" ] - ] - for a in armor_files: - APXSIZE = 16 # for some reason MineClone2 requires this - layer_1 = a[0] - layer_2 = a[1] - adir = a[2] - if os.path.isfile(layer_1): - helmet = adir + "/" + a[3] - chestplate = adir + "/" + a[4] - boots = adir + "/" + a[6] - os.system("convert -size "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" xc:none \\( "+layer_1+" -scale "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" -geometry +"+str(APXSIZE * 2)+"+0 -crop "+str(APXSIZE * 2)+"x"+str(APXSIZE)+"+0+0 \) -composite -channel A -fx \"(a > 0.0) ? 1.0 : 0.0\" "+helmet) - os.system("convert -size "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" xc:none \\( "+layer_1+" -scale "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" -geometry +"+str(APXSIZE)+"+"+str(APXSIZE)+" -crop "+str(APXSIZE * 2.5)+"x"+str(APXSIZE)+"+"+str(APXSIZE)+"+"+str(APXSIZE)+" \) -composite -channel A -fx \"(a > 0.0) ? 1.0 : 0.0\" "+chestplate) - os.system("convert -size "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" xc:none \\( "+layer_1+" -scale "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" -geometry +0+"+str(APXSIZE)+" -crop "+str(APXSIZE)+"x"+str(APXSIZE)+"+0+"+str(APXSIZE)+" \) -composite -channel A -fx \"(a > 0.0) ? 1.0 : 0.0\" "+boots) - if os.path.isfile(layer_2): - leggings = adir + "/" + a[5] - os.system("convert -size "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" xc:none \\( "+layer_2+" -scale "+str(APXSIZE * 4)+"x"+str(APXSIZE * 2)+" -geometry +0+"+str(APXSIZE)+" -crop "+str(APXSIZE * 2.5)+"x"+str(APXSIZE)+"+0+"+str(APXSIZE)+" \) -composite -channel A -fx \"(a > 0.0) ? 1.0 : 0.0\" "+leggings) - - # Convert chest textures (requires ImageMagick) - chest_files = [ - [ tex_dir + "/entity/chest/normal.png", target_dir("/mods/ITEMS/mcl_chests/textures"), "default_chest_top.png", "mcl_chests_chest_bottom.png", "default_chest_front.png", "mcl_chests_chest_left.png", "mcl_chests_chest_right.png", "mcl_chests_chest_back.png" ], - [ tex_dir + "/entity/chest/trapped.png", target_dir("/mods/ITEMS/mcl_chests/textures"), "mcl_chests_chest_trapped_top.png", "mcl_chests_chest_trapped_bottom.png", "mcl_chests_chest_trapped_front.png", "mcl_chests_chest_trapped_left.png", "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_back.png" ], - [ tex_dir + "/entity/chest/ender.png", target_dir("/mods/ITEMS/mcl_chests/textures"), "mcl_chests_ender_chest_top.png", "mcl_chests_ender_chest_bottom.png", "mcl_chests_ender_chest_front.png", "mcl_chests_ender_chest_left.png", "mcl_chests_ender_chest_right.png", "mcl_chests_ender_chest_back.png" ] - ] - - for c in chest_files: - chest_file = c[0] - if os.path.isfile(chest_file): - PPX = (PXSIZE/16) - CHPX = (PPX * 14) # Chest width - LIDPX = (PPX * 5) # Lid height - LIDLOW = (PPX * 10) # Lower lid section height - LOCKW = (PPX * 6) # Lock width - LOCKH = (PPX * 5) # Lock height - - cdir = c[1] - top = cdir + "/" + c[2] - bottom = cdir + "/" + c[3] - front = cdir + "/" + c[4] - left = cdir + "/" + c[5] - right = cdir + "/" + c[6] - back = cdir + "/" + c[7] - # Top - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(CHPX)+"+"+str(CHPX)+"+0 \) -geometry +0+0 -composite -extent "+str(CHPX)+"x"+str(CHPX)+" "+top) - # Bottom - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(CHPX)+"+"+str(CHPX*2)+"+"+str(CHPX+LIDPX)+" \) -geometry +0+0 -composite -extent "+str(CHPX)+"x"+str(CHPX)+" "+bottom) - # Front - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDPX)+"+"+str(CHPX)+"+"+str(CHPX)+" \) -geometry +0+0 -composite \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDLOW)+"+"+str(CHPX)+"+"+str(CHPX*2+LIDPX)+" \) -geometry +0+"+str(LIDPX-PPX)+" -composite \ --extent "+str(CHPX)+"x"+str(CHPX)+" "+front) - # TODO: Add lock - - # Left, right back (use same texture, we're lazy - files = [ left, right, back ] - for f in files: - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDPX)+"+"+str(0)+"+"+str(CHPX)+" \) -geometry +0+0 -composite \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDLOW)+"+"+str(0)+"+"+str(CHPX*2+LIDPX)+" \) -geometry +0+"+str(LIDPX-PPX)+" -composite \ --extent "+str(CHPX)+"x"+str(CHPX)+" "+f) - - # Double chests - - chest_files = [ - [ tex_dir + "/entity/chest/normal_double.png", target_dir("/mods/ITEMS/mcl_chests/textures"), "default_chest_front_big.png", "default_chest_top_big.png", "default_chest_side_big.png" ], - [ tex_dir + "/entity/chest/trapped_double.png", target_dir("/mods/ITEMS/mcl_chests/textures"), "mcl_chests_chest_trapped_front_big.png", "mcl_chests_chest_trapped_top_big.png", "mcl_chests_chest_trapped_side_big.png" ] - ] - for c in chest_files: - chest_file = c[0] - if os.path.isfile(chest_file): - PPX = (PXSIZE/16) - CHPX = (PPX * 14) # Chest width (short side) - CHPX2 = (PPX * 15) # Chest width (long side) - LIDPX = (PPX * 5) # Lid height - LIDLOW = (PPX * 10) # Lower lid section height - LOCKW = (PPX * 6) # Lock width - LOCKH = (PPX * 5) # Lock height - - cdir = c[1] - front = cdir + "/" + c[2] - top = cdir + "/" + c[3] - side = cdir + "/" + c[4] - # Top - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX2)+"x"+str(CHPX)+"+"+str(CHPX)+"+0 \) -geometry +0+0 -composite -extent "+str(CHPX2)+"x"+str(CHPX)+" "+top) - # Front - # TODO: Add lock - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX2)+"x"+str(LIDPX)+"+"+str(CHPX)+"+"+str(CHPX)+" \) -geometry +0+0 -composite \ -\( -clone 0 -crop "+str(CHPX2)+"x"+str(LIDLOW)+"+"+str(CHPX)+"+"+str(CHPX*2+LIDPX)+" \) -geometry +0+"+str(LIDPX-PPX)+" -composite \ --extent "+str(CHPX2)+"x"+str(CHPX)+" "+front) - # Side - os.system("convert " + chest_file + " \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDPX)+"+"+str(0)+"+"+str(CHPX)+" \) -geometry +0+0 -composite \ -\( -clone 0 -crop "+str(CHPX)+"x"+str(LIDLOW)+"+"+str(0)+"+"+str(CHPX*2+LIDPX)+" \) -geometry +0+"+str(LIDPX-PPX)+" -composite \ --extent "+str(CHPX)+"x"+str(CHPX)+" "+side) - - - # Generate railway crossings and t-junctions. Note: They may look strange. - # Note: these may be only a temporary solution, as crossings and t-junctions do not occour in MC. - # TODO: Curves - rails = [ - # (Straigt src, curved src, t-junction dest, crossing dest) - ("rail_normal.png", "rail_normal_turned.png", "default_rail_t_junction.png", "default_rail_crossing.png"), - ("rail_golden.png", "rail_normal_turned.png", "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"), - ("rail_golden_powered.png", "rail_normal_turned.png", "mcl_minecarts_rail_golden_t_junction_powered.png", "mcl_minecarts_rail_golden_crossing_powered.png"), - ("rail_detector.png", "rail_normal_turned.png", "mcl_minecarts_rail_detector_t_junction.png", "mcl_minecarts_rail_detector_crossing.png"), - ("rail_detector_powered.png", "rail_normal_turned.png", "mcl_minecarts_rail_detector_t_junction_powered.png", "mcl_minecarts_rail_detector_crossing_powered.png"), - ("rail_activator.png", "rail_normal_turned.png", "mcl_minecarts_rail_activator_t_junction.png", "mcl_minecarts_rail_activator_crossing.png"), - ("rail_activator_powered.png", "rail_normal_turned.png", "mcl_minecarts_rail_activator_d_t_junction.png", "mcl_minecarts_rail_activator_powered_crossing.png"), - ] - for r in rails: - os.system("composite -compose Dst_Over "+tex_dir+"/blocks/"+r[0]+" "+tex_dir+"/blocks/"+r[1]+" "+target_dir("/mods/ENTITIES/mcl_minecarts/textures")+"/"+r[2]) - os.system("convert "+tex_dir+"/blocks/"+r[0]+" -rotate 90 "+tempfile1.name) - os.system("composite -compose Dst_Over "+tempfile1.name+" "+tex_dir+"/blocks/"+r[0]+" "+target_dir("/mods/ENTITIES/mcl_minecarts/textures")+"/"+r[3]) - - # Convert banner overlays - overlays = [ - "base", - "border", - "bricks", - "circle", - "creeper", - "cross", - "curly_border", - "diagonal_left", - "diagonal_right", - "diagonal_up_left", - "diagonal_up_right", - "flower", - "gradient", - "gradient_up", - "half_horizontal_bottom", - "half_horizontal", - "half_vertical", - "half_vertical_right", - "rhombus", - "mojang", - "skull", - "small_stripes", - "straight_cross", - "stripe_bottom", - "stripe_center", - "stripe_downleft", - "stripe_downright", - "stripe_left", - "stripe_middle", - "stripe_right", - "stripe_top", - "square_bottom_left", - "square_bottom_right", - "square_top_left", - "square_top_right", - "triangle_bottom", - "triangles_bottom", - "triangle_top", - "triangles_top", - ] - for o in overlays: - orig = tex_dir + "/entity/banner/" + o + ".png" - if os.path.isfile(orig): - if o == "mojang": - o = "thing" - dest = target_dir("/mods/ITEMS/mcl_banners/textures")+"/"+"mcl_banners_"+o+".png" - os.system("convert "+orig+" -transparent-color white -background black -alpha remove -alpha copy -channel RGB -white-threshold 0 "+dest) - - # Convert grass - grass_file = tex_dir + "/blocks/grass_top.png" - if os.path.isfile(grass_file): - FOLIAG = tex_dir+"/colormap/foliage.png" - GRASS = tex_dir+"/colormap/grass.png" - - - # Leaves - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_oak.png", "116+143", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_leaves.png") - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_big_oak.png", "158+177", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/mcl_core_leaves_big_oak.png") - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_acacia.png", "40+255", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_acacia_leaves.png") - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_spruce.png", "226+230", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/mcl_core_leaves_spruce.png") - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_birch.png", "141+186", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/mcl_core_leaves_birch.png") - colorize_alpha(FOLIAG, tex_dir+"/blocks/leaves_jungle.png", "16+39", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_jungleleaves.png") - - # Waterlily - colorize_alpha(FOLIAG, tex_dir+"/blocks/waterlily.png", "16+39", str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/flowers_waterlily.png") - - # Vines - colorize_alpha(FOLIAG, tex_dir+"/blocks/vine.png", "16+39", str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/mcl_core_vine.png") - - # Tall grass, fern (inventory images) - pcol = "50+173" # Plains grass color - colorize_alpha(GRASS, tex_dir+"/blocks/tallgrass.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_tallgrass_inv.png") - colorize_alpha(GRASS, tex_dir+"/blocks/fern.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_fern_inv.png") - colorize_alpha(GRASS, tex_dir+"/blocks/double_plant_fern_top.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_double_plant_fern_inv.png") - colorize_alpha(GRASS, tex_dir+"/blocks/double_plant_grass_top.png", pcol, str(PXSIZE), target_dir("/mods/ITEMS/mcl_flowers/textures")+"/mcl_flowers_double_plant_grass_inv.png") - - # Convert grass palette: https://minecraft.fandom.com/wiki/Tint - grass_colors = [ - # [Coords or #Color, AdditionalTint], # Index - Minecraft biome name (MineClone2 biome names) - ["50+173"], # 0 - Plains (flat, Plains, Plains_beach, Plains_ocean, End) - ["0+255"], # 1 - Savanna (Savanna, Savanna_beach, Savanna_ocean) - ["255+255"], # 2 - Ice Spikes (IcePlainsSpikes, IcePlainsSpikes_ocean) - ["255+255"], # 3 - Snowy Taiga (ColdTaiga, ColdTaiga_beach, ColdTaiga_beach_water, ColdTaiga_ocean) - ["178+193"], # 4 - Giant Tree Taiga (MegaTaiga, MegaTaiga_ocean) - ["178+193"], # 5 - Giant Tree Taiga (MegaSpruceTaiga, MegaSpruceTaiga_ocean) - ["203+239"], # 6 - Montains (ExtremeHills, ExtremeHills_beach, ExtremeHills_ocean) - ["203+239"], # 7 - Montains (ExtremeHillsM, ExtremeHillsM_ocean) - ["203+239"], # 8 - Montains (ExtremeHills+, ExtremeHills+_snowtop, ExtremeHills+_ocean) - ["50+173"], # 9 - Beach (StoneBeach, StoneBeach_ocean) - ["255+255"], # 10 - Snowy Tundra (IcePlains, IcePlains_ocean) - ["50+173"], # 11 - Sunflower Plains (SunflowerPlains, SunflowerPlains_ocean) - ["191+203"], # 12 - Taiga (Taiga, Taiga_beach, Taiga_ocean) - ["76+112"], # 13 - Forest (Forest, Forest_beach, Forest_ocean) - ["76+112"], # 14 - Flower Forest (FlowerForest, FlowerForest_beach, FlowerForest_ocean) - ["101+163"], # 15 - Birch Forest (BirchForest, BirchForest_ocean) - ["101+163"], # 16 - Birch Forest Hills (BirchForestM, BirchForestM_ocean) - ["0+255"], # 17 - Desert and Nether (Desert, Desert_ocean, Nether) - ["76+112", "#28340A"], # 18 - Dark Forest (RoofedForest, RoofedForest_ocean) - ["#90814d"], # 19 - Mesa (Mesa, Mesa_sandlevel, Mesa_ocean, ) - ["#90814d"], # 20 - Mesa (MesaBryce, MesaBryce_sandlevel, MesaBryce_ocean) - ["#90814d"], # 21 - Mesa (MesaPlateauF, MesaPlateauF_grasstop, MesaPlateauF_sandlevel, MesaPlateauF_ocean) - ["#90814d"], # 22 - Mesa (MesaPlateauFM, MesaPlateauFM_grasstop, MesaPlateauFM_sandlevel, MesaPlateauFM_ocean) - ["0+255"], # 23 - Shattered Savanna (or Savanna Plateau ?) (SavannaM, SavannaM_ocean) - ["12+36"], # 24 - Jungle (Jungle, Jungle_shore, Jungle_ocean) - ["12+36"], # 25 - Modified Jungle (JungleM, JungleM_shore, JungleM_ocean) - ["12+61"], # 26 - Jungle Edge (JungleEdge, JungleEdge_ocean) - ["12+61"], # 27 - Modified Jungle Edge (JungleEdgeM, JungleEdgeM_ocean) - ["#6A7039"], # 28 - Swamp (Swampland, Swampland_shore, Swampland_ocean) - ["25+25"], # 29 - Mushroom Fields and Mushroom Field Shore (MushroomIsland, MushroomIslandShore, MushroomIsland_ocean) - ] - - grass_palette_file = target_dir("/mods/ITEMS/mcl_core/textures") + "/mcl_core_palette_grass.png" - os.system("convert -size 16x16 canvas:transparent " + grass_palette_file) - - for i, color in enumerate(grass_colors): - if color[0][0] == "#": - os.system("convert -size 1x1 xc:\"" + color[0] + "\" " + tempfile1.name + ".png") - else: - os.system("convert " + GRASS + " -crop 1x1+" + color[0] + " " + tempfile1.name + ".png") - - if len(color) > 1: - os.system("convert " + tempfile1.name + ".png \\( -size 1x1 xc:\"" + color[1] + "\" \\) -compose blend -define compose:args=50,50 -composite " + tempfile1.name + ".png") - - os.system("convert " + grass_palette_file + " \\( " + tempfile1.name + ".png -geometry +" + str(i % 16) + "+" + str(int(i / 16)) + " \\) -composite " + grass_palette_file) - - # Metadata - if make_texture_pack: - # Create description file - description = "Texture pack for MineClone 2. Automatically converted from a Minecraft resource pack by the MineClone 2 Texture Converter. Size: "+str(PXSIZE)+"×"+str(PXSIZE) - description_file = open(target_dir("/") + "/description.txt", "w") - description_file.write(description) - description_file.close() - - # Create preview image (screenshot.png) - os.system("convert -size 300x200 canvas:transparent "+target_dir("/") + "/screenshot.png") - os.system("composite "+base_dir+"/pack.png "+target_dir("/") + "/screenshot.png -gravity center "+target_dir("/") + "/screenshot.png") - - print("Textures conversion COMPLETE!") - if failed_conversions > 0: - print("WARNING: Number of missing files in original resource pack: "+str(failed_conversions)) - print("NOTE: Please keep in mind this script does not reliably convert all the textures yet.") - if make_texture_pack: - print("You can now retrieve the texture pack in "+output_dir+"/"+output_dir_name+"/") - -# ENTRY POINT -if make_texture_pack and not os.path.isdir(output_dir+"/"+output_dir_name): - os.mkdir(output_dir+"/"+output_dir_name) - -tempfile1 = tempfile.NamedTemporaryFile() -tempfile2 = tempfile.NamedTemporaryFile() - -convert_textures() - -tempfile1.close() -tempfile2.close() +if __name__ == "__main__": + main() diff --git a/tools/colors.txt b/tools/colors.txt index de20aa49a..86f56c422 100644 --- a/tools/colors.txt +++ b/tools/colors.txt @@ -715,9 +715,9 @@ mcl_furnaces:furnace_active 149 139 133 mcl_grindstone:grindstone 216 216 216 # mcl_heads -mcl_heads:creeper22_5 94 115 69 -mcl_heads:creeper45 94 115 69 -mcl_heads:creeper67_5 94 115 69 +mcl_heads:stalker22_5 94 115 69 +mcl_heads:stalker45 94 115 69 +mcl_heads:stalker67_5 94 115 69 mcl_heads:skeleton22_5 126 126 126 mcl_heads:skeleton45 126 126 126 mcl_heads:skeleton67_5 126 126 126 diff --git a/tools/create_luacheck.py b/tools/create_luacheck.py index d3ee5d038..b10ff1717 100755 --- a/tools/create_luacheck.py +++ b/tools/create_luacheck.py @@ -2,7 +2,7 @@ import os import re from pathlib import Path -# Just run this script from mineclone2 directory to get a list of every global vars to use in luacheck configuration files +# Just run this script from voxelibre directory to get a list of every global vars to use in luacheck configuration files path = "./mods/" diff --git a/tools/dicts/polish.dic b/tools/dicts/polish.dic index 952ae57eb..81603e446 100644 --- a/tools/dicts/polish.dic +++ b/tools/dicts/polish.dic @@ -2,9 +2,9 @@ 1f Badlandach biomeinfo -creeper -Creeper -creepera +stalker +Stalker +stalkera czerwienit czerwienitem czerwienitowych diff --git a/tools/generate_ingame_credits.lua b/tools/generate_ingame_credits.lua index a484322c0..cfcc637f7 100755 --- a/tools/generate_ingame_credits.lua +++ b/tools/generate_ingame_credits.lua @@ -4,7 +4,7 @@ local colors = { ["Creator of MineClone"] = "0x0A9400", - ["Creator of MineClone2"] = "0xFBF837", + ["Creator of VoxeLibre"] = "0xFBF837", ["Maintainers"] = "0xFF51D5", ["Developers"] = "0xF84355", ["Past Developers"] = "0xF84355", diff --git a/tools/libtextureconverter/__init__.py b/tools/libtextureconverter/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tools/libtextureconverter/common.py b/tools/libtextureconverter/common.py new file mode 100644 index 000000000..1c28efdda --- /dev/null +++ b/tools/libtextureconverter/common.py @@ -0,0 +1,68 @@ +import shutil +import csv +import os +import tempfile +import sys +import argparse +import glob +from PIL import Image +from collections import Counter + +from libtextureconverter.utils import detect_pixel_size, target_dir, colorize, colorize_alpha, handle_default_minecraft_texture, find_all_minecraft_resourcepacks +from libtextureconverter.convert import convert_textures +from libtextureconverter.config import SUPPORTED_MINECRAFT_VERSION, working_dir, mineclone2_path, appname, home + + +def convert_resource_packs( + resource_packs, + output_dir, + PXSIZE, + dry_run, + verbose, + make_texture_pack): + for base_dir in resource_packs: + print(f"Converting resource pack: {base_dir}") + + # Autodetect pixel size if not provided + if not PXSIZE: + pixel_size = detect_pixel_size(base_dir) + else: + pixel_size = PXSIZE + # Construct the path to the textures within the resource pack + tex_dir = os.path.join(base_dir, "assets", "minecraft", "textures") + + # Determine the name of the output directory for the converted texture + # pack + output_dir_name = os.path.basename(os.path.normpath(base_dir)) + + # Create the output directory if it doesn't exist + output_path = os.path.join(output_dir, output_dir_name) + if not os.path.isdir(output_path): + os.makedirs(output_path, exist_ok=True) + + # Temporary files for conversion (if needed by your conversion process) + tempfile1 = tempfile.NamedTemporaryFile(delete=False) + tempfile2 = tempfile.NamedTemporaryFile(delete=False) + + try: + # Perform the actual conversion + convert_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + pixel_size) + finally: + # Clean up temporary files + tempfile1.close() + os.unlink(tempfile1.name) + tempfile2.close() + os.unlink(tempfile2.name) + + print(f"Finished converting resource pack: {base_dir}") diff --git a/tools/libtextureconverter/config.py b/tools/libtextureconverter/config.py new file mode 100644 index 000000000..dbba6b3df --- /dev/null +++ b/tools/libtextureconverter/config.py @@ -0,0 +1,30 @@ +import os +import platform + +def get_minetest_directory(): + system = platform.system() + + # Windows + if system == 'Windows': + return os.environ.get('MINETEST_USER_PATH', os.path.expandvars('%APPDATA%\\Minetest')) + + # Linux + elif system == 'Linux': + return os.environ.get('MINETEST_USER_PATH', os.path.expanduser('~/.minetest')) + + # macOS + elif system == 'Darwin': # Darwin is the system name for macOS + return os.environ.get('MINETEST_USER_PATH', os.path.expanduser('~/Library/Application Support/minetest')) + + # Unsupported system + else: + return None + +# Constants +SUPPORTED_MINECRAFT_VERSION = "1.20" + +# Helper vars +home = os.environ["HOME"] +mineclone2_path = os.path.join(get_minetest_directory(),"games","mineclone2") +working_dir = os.getcwd() +appname = "Texture_Converter.py" diff --git a/tools/libtextureconverter/convert.py b/tools/libtextureconverter/convert.py new file mode 100644 index 000000000..a5d4af947 --- /dev/null +++ b/tools/libtextureconverter/convert.py @@ -0,0 +1,137 @@ +from .special_convert_cases import convert_map_textures, convert_armor_textures, convert_chest_textures, convert_rail_textures, convert_banner_overlays, convert_grass_textures +from .utils import target_dir, colorize, colorize_alpha +import shutil +import csv +import os +import tempfile +import sys +import argparse +import glob + + +def convert_standard_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + failed_conversions = 0 + with open("Conversion_Table.csv", newline="") as csvfile: + reader = csv.reader(csvfile, delimiter=",", quotechar='"') + first_row = True + for row in reader: + # Skip first row + if first_row: + first_row = False + continue + src_dir = row[0] + src_filename = row[1] + dst_dir = './textures' + dst_filename = row[2] + if row[4] != "": + xs = int(row[3]) + ys = int(row[4]) + xl = int(row[5]) + yl = int(row[6]) + xt = int(row[7]) + yt = int(row[8]) + else: + xs = None + blacklisted = row[9] + + if blacklisted == "y": + # Skip blacklisted files + continue + + if make_texture_pack == False and dst_dir == "": + # If destination dir is empty, this texture is not supposed to be used in MCL2 + # (but maybe an external mod). It should only be used in texture packs. + # Otherwise, it must be ignored. + # Example: textures for mcl_supplemental + continue + + src_file = base_dir + src_dir + "/" + src_filename # source file + src_file_exists = os.path.isfile(src_file) + dst_file = target_dir(dst_dir, make_texture_pack, output_dir, output_dir_name, + mineclone2_path) + "/" + dst_filename # destination file + + if src_file_exists == False: + print("WARNING: Source file does not exist: " + src_file) + failed_conversions = failed_conversions + 1 + continue + if xs != None: + # Crop and copy images + if not dry_run: + crop_width = int(xl) + crop_height = int(yl) + offset_x = int(xs) + offset_y = int(ys) + with Image(filename=src_file) as img: + # Crop the image + img.crop(left=offset_x, top=offset_y, width=crop_width, height=crop_height) + # Save the result + img.save(filename=dst_file) + if verbose: + print(src_file + " → " + dst_file) + else: + # Copy image verbatim + if not dry_run: + shutil.copy2(src_file, dst_file) + if verbose: + print(src_file + " → " + dst_file) + return failed_conversions + + +def convert_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2, output_dir, output_dir_name, mineclone2_path, PXSIZE): + print("Texture conversion BEGINS NOW!") + + # Convert textures listed in the Conversion_Table.csv + failed_conversions = convert_standard_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, + tempfile1, tempfile2, output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Conversion of map backgrounds + convert_map_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, + tempfile1, tempfile2, output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Convert armor textures + convert_armor_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2,output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Convert chest textures + convert_chest_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2,output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Generate railway crossings and t-junctions + convert_rail_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2,output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Convert banner overlays + convert_banner_overlays(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2,output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Convert grass and related textures + convert_grass_textures(make_texture_pack, dry_run, verbose, base_dir, tex_dir, tempfile1, tempfile2,output_dir, output_dir_name, mineclone2_path, PXSIZE) + + # Metadata + if make_texture_pack: + # Create description file + description = "Texture pack for MineClone 2. Automatically converted from a Minecraft resource pack by the MineClone 2 Texture Converter. Size: "+str(PXSIZE)+"×"+str(PXSIZE) + description_file = open(target_dir("/", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/description.txt", "w") + description_file.write(description) + description_file.close() + + # Create override file + shutil.copyfile("override.txt", target_dir("/", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/override.txt") + + # Create preview image (screenshot.png) + os.system("convert -size 300x200 canvas:transparent "+target_dir("/", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/screenshot.png") + os.system("composite "+base_dir+"/pack.png "+target_dir("/", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/screenshot.png -gravity center "+target_dir("/", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/screenshot.png") + + print("Textures conversion COMPLETE!") + if failed_conversions > 0: + print("WARNING: Number of missing files in original resource pack: " + str(failed_conversions)) + print("NOTE: Please keep in mind this script does not reliably convert all the textures yet.") + if make_texture_pack: + print("You can now retrieve the texture pack in " + output_dir + "/" + output_dir_name + "/") diff --git a/tools/libtextureconverter/gui.py b/tools/libtextureconverter/gui.py new file mode 100644 index 000000000..4ee8b431c --- /dev/null +++ b/tools/libtextureconverter/gui.py @@ -0,0 +1,198 @@ +import tkinter as tk +from tkinter import filedialog, messagebox, ttk, font +from libtextureconverter.utils import handle_default_minecraft_texture, find_all_minecraft_resourcepacks +from libtextureconverter.config import home, get_minetest_directory +from libtextureconverter.common import convert_resource_packs + +import time +import os +import threading + + +class TextureConverterGUI: + def __init__(self, root): + self.root = root + self.root.title("Choose resource packs to convert") + + self.create_widgets() + + def create_widgets(self): + + # Frame for instructions + self.instruction_frame = tk.Frame(self.root) + self.instruction_frame.pack(fill='x', padx=10, pady=10) + tk.Label( + self.instruction_frame, + text="Do you want to convert installed resource packs, or convert a single folder?").pack( + side='left', + fill='x', + expand=True) + + # Table-like structure using Treeview + self.tree = ttk.Treeview(self.root, columns=( + 'Convert', 'Description'), show='headings') + self.tree.heading('Convert', text='Convert') + self.tree.heading('Description', text='Description') + + # Inserting options into the table + entries = [ + ('all', 'Find Minecraft resource packs installed in your minecraft folders and convert those automatically'), + ('default', 'Convert the default resource pack'), + ('other', 'Choose a folder to convert manually') + ] + + for entry in entries: + self.tree.insert('', 'end', values=entry) + + # Button Frame + self.button_frame = tk.Frame(self.root) + # Ensure the buttons are at the bottom + self.button_frame.pack(fill='x', padx=10, pady=10, side='bottom') + # Create and pack the buttons separately + self.ok_button = tk.Button( + self.button_frame, text="OK", command=self.confirm_selection) + self.ok_button.pack(side=tk.RIGHT, padx=5) + self.cancel_button = tk.Button( + self.button_frame, text="Cancel", command=self.cancel_conversion) + self.cancel_button.pack(side=tk.RIGHT) + + self.tree.pack(fill='both', expand=True, padx=10, pady=10) + + self.root.after(1, self.adjust_column_widths) + + def adjust_column_widths(self): + self.root.update_idletasks() # Update the geometry of the widgets + + # Measure and set the column widths + convert_width = tk.font.Font().measure('Convert') + 20 + description_width = max( + tk.font.Font().measure( + self.tree.set( + item, + 'Description')) for item in self.tree.get_children()) + 20 + + # Apply the column widths + self.tree.column('Convert', width=convert_width, anchor='center') + self.tree.column('Description', width=description_width, anchor='w') + + # Calculate the height for each row + row_height = tk.font.Font().metrics('linespace') + 2 + + # Adjust the Treeview height + num_items = len(self.tree.get_children()) + tree_height = (row_height * num_items) * 1.8 + self.tree.config(height=num_items) + + # Calculate the total height needed + total_height = self.instruction_frame.winfo_height( + ) + self.button_frame.winfo_height() + tree_height + 20 + + # Calculate the total width needed + total_width = convert_width + description_width + 20 + + # Set the size of the window based on content + self.root.geometry(f"{int(total_width)}x{int(total_height)}") + + # Prevent the window from resizing smaller than it should + self.root.minsize(int(total_width), int(total_height)) + + # Update the idle tasks to recalculate sizes, may help to remove extra + # space + self.root.update_idletasks() + + def confirm_selection(self): + self.cancel_button.config(state=tk.NORMAL) + selected_item = self.tree.focus() + selection = self.tree.item(selected_item) + option = selection['values'][0] + self.show_loading_screen(option) + + def set_min_window_size(self): + self.root.update_idletasks() # Update the geometry of the widgets + self.root.minsize(self.root.winfo_width(), self.root.winfo_height()) + + def show_loading_screen(self, option): + # Display a non-blocking loading message + self.loading_label = tk.Label( + self.root, text="Converting textures, please wait...", fg="blue") + self.loading_label.pack() + + # Start the conversion process in a separate thread + conversion_thread = threading.Thread( + target=self.perform_conversion, args=(option,), daemon=True) + conversion_thread.start() + + # Disable the OK button while the conversion is in progress + self.ok_button.config(state=tk.DISABLED) + self.cancel_button.config(state=tk.NORMAL) + + def perform_conversion(self, option): + # Set default values for pixelsize, dry_run, and verbose + pixelsize = None + dry_run = False + verbose = False + output_dir = os.path.join(get_minetest_directory(), "textures") + make_texture_pack = True + + # Determine the resource packs to convert based on the option + if option == 'all': + resource_packs = find_all_minecraft_resourcepacks() + elif option == 'default': + resource_packs = [ + handle_default_minecraft_texture(home, output_dir)] + elif option == 'other': + folder_selected = filedialog.askdirectory() + if folder_selected: + resource_packs = [folder_selected] + else: + # User canceled the folder selection + self.loading_label.pack_forget() + self.ok_button.config(state=tk.NORMAL) + return + + # Convert resource packs + convert_resource_packs(resource_packs, output_dir, + pixelsize, dry_run, verbose, make_texture_pack) + + # Update the GUI after conversion + self.loading_label.pack_forget() + self.ok_button.config(state=tk.NORMAL) + messagebox.showinfo( + "Conversion Complete", + f"Resource Packs '{', '.join(resource_packs)}' converted.") + + def convert_all(self): + # Simulate a conversion process + print("Converting all resource packs") + time.sleep(2) # Simulate some time for conversion + + def convert_default(self): + # Simulate a conversion process + print("Converting default resource pack") + time.sleep(2) # Simulate some time for conversion + + def open_folder_dialog(self): + folder_selected = filedialog.askdirectory() + if folder_selected: + # Simulate a conversion process + print(f"Folder selected for conversion: {folder_selected}") + time.sleep(2) # Simulate some time for conversion + + def cancel_conversion(self): + # Placeholder for cancel action, you may need to implement actual + # cancellation logic + print("Conversion cancelled by user.") + self.loading_label.pack_forget() + self.ok_button.config(state=tk.NORMAL) + self.cancel_button.config(state=tk.DISABLED) + + +def main(): + root = tk.Tk() + app = TextureConverterGUI(root) + app.adjust_column_widths() + root.mainloop() + + +if __name__ == "__main__": + main() diff --git a/tools/libtextureconverter/special_convert_cases.py b/tools/libtextureconverter/special_convert_cases.py new file mode 100644 index 000000000..762cb7b6b --- /dev/null +++ b/tools/libtextureconverter/special_convert_cases.py @@ -0,0 +1,809 @@ +import os +from .utils import target_dir, colorize, colorize_alpha +import shutil +import csv +import tempfile +import sys +import argparse +import glob +from wand.image import Image +from wand.color import Color +from wand.display import display +from wand.drawing import Drawing +import warnings + +# Conversion of map backgrounds +def convert_map_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Convert map background + map_background_file = tex_dir + "/map/map_background.png" + if os.path.isfile(map_background_file): + destination_path = target_dir("/mods/ITEMS/mcl_maps/textures", make_texture_pack, output_dir, output_dir_name, mineclone2_path) + "/mcl_maps_map_background.png" + + with Image(filename=map_background_file) as img: + # Resize the image with 'point' filter + img.resize(140, 140, filter='point') + + # Save the result + img.save(filename=destination_path) + + +# Convert armor textures + +def convert_armor_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Convert armor textures (requires ImageMagick) + armor_files = [[tex_dir + "/models/armor/leather_layer_1.png", + tex_dir + "/models/armor/leather_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_leather.png", + "mcl_armor_chestplate_leather.png", + "mcl_armor_leggings_leather.png", + "mcl_armor_boots_leather.png"], + [tex_dir + "/models/armor/chainmail_layer_1.png", + tex_dir + "/models/armor/chainmail_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_chain.png", + "mcl_armor_chestplate_chain.png", + "mcl_armor_leggings_chain.png", + "mcl_armor_boots_chain.png"], + [tex_dir + "/models/armor/gold_layer_1.png", + tex_dir + "/models/armor/gold_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_gold.png", + "mcl_armor_chestplate_gold.png", + "mcl_armor_leggings_gold.png", + "mcl_armor_boots_gold.png"], + [tex_dir + "/models/armor/iron_layer_1.png", + tex_dir + "/models/armor/iron_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_iron.png", + "mcl_armor_chestplate_iron.png", + "mcl_armor_leggings_iron.png", + "mcl_armor_boots_iron.png"], + [tex_dir + "/models/armor/diamond_layer_1.png", + tex_dir + "/models/armor/diamond_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_diamond.png", + "mcl_armor_chestplate_diamond.png", + "mcl_armor_leggings_diamond.png", + "mcl_armor_boots_diamond.png"], + [tex_dir + "/models/armor/netherite_layer_1.png", + tex_dir + "/models/armor/netherite_layer_2.png", + target_dir("/mods/ITEMS/mcl_armor/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_armor_helmet_netherite.png", + "mcl_armor_chestplate_netherite.png", + "mcl_armor_leggings_netherite.png", + "mcl_armor_boots_netherite.png"]] + for a in armor_files: + APXSIZE = 16 # for some reason MineClone2 requires this + layer_1 = a[0] + layer_2 = a[1] + adir = a[2] + if os.path.isfile(layer_1): + helmet = adir + "/" + a[3] + chestplate = adir + "/" + a[4] + boots = adir + "/" + a[6] + # helmet + os.system("convert -size " + + str(APXSIZE * + 4) + + "x" + + str(APXSIZE * + 2) + + " xc:none \\( " + + layer_1 + + " -scale " + + str(APXSIZE * + 4) + + "x" + + str(APXSIZE * + 2) + + " -geometry +" + + str(APXSIZE * + 2) + + "+0 -crop " + + str(APXSIZE * + 2) + + "x" + + str(APXSIZE) + + "+0+0 \\) -composite -channel A -fx \"(a > 0.0) ? 1.0 : 0.0\" " + + helmet) + + + + # chestplate + with Image(width=APXSIZE * 4, height=APXSIZE * 2, background=Color('none')) as img: + # Load layer_1 and scale + with Image(filename=layer_1) as layer1: + layer1.resize(APXSIZE * 4, APXSIZE * 2) + + # Define the crop geometry + crop_width = int(APXSIZE * 2.5) + crop_height = APXSIZE + crop_x = APXSIZE + crop_y = APXSIZE + + # Crop the image + layer1.crop(crop_x, crop_y, width=crop_width, height=crop_height) + + # Composite layer1 over the transparent image + img.composite(layer1, APXSIZE, APXSIZE) + + # Apply channel operation + img.fx("a > 0.0 ? 1.0 : 0.0", channel='alpha') + + # Save the result + img.save(filename=chestplate) + with Image(width=APXSIZE * 4, height=APXSIZE * 2, background=Color('none')) as img: + with Image(filename=layer_1) as layer1: + # Scale the image + layer1.resize(APXSIZE * 4, APXSIZE * 2) + + # Crop the image + crop_x = 0 + crop_y = APXSIZE + crop_width = APXSIZE + crop_height = APXSIZE + layer1.crop(crop_x, crop_y, width=crop_width, height=crop_height) + + # Composite the cropped image over the transparent image + img.composite(layer1, 0, APXSIZE) + + # Apply the channel operation + img.fx("a > 0.0 ? 1.0 : 0.0", channel='alpha') + + # Save the result + img.save(filename=boots) + + if os.path.isfile(layer_2): + leggings = adir + "/" + a[5] + with Image(width=APXSIZE * 4, height=APXSIZE * 2, background=Color('none')) as img: + with Image(filename=layer_2) as layer2: + # Scale the image + layer2.resize(APXSIZE * 4, APXSIZE * 2) + + # Apply geometry and crop + crop_width = int(APXSIZE * 2.5) + crop_height = APXSIZE + crop_x = 0 + crop_y = APXSIZE + layer2.crop(left=crop_x, top=crop_y, width=crop_width, height=crop_height) + + # Composite the cropped image over the transparent image + img.composite(layer2, 0, APXSIZE) + + # Apply channel operation + img.fx("a > 0.0 ? 1.0 : 0.0", channel='alpha') + + # Save the result + img.save(filename=leggings) + +# Convert chest textures + + +def convert_chest_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Convert chest textures (requires ImageMagick) + chest_files = [[tex_dir + "/entity/chest/normal.png", + target_dir("/mods/ITEMS/mcl_chests/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "default_chest_top.png", + "mcl_chests_chest_bottom.png", + "default_chest_front.png", + "mcl_chests_chest_left.png", + "mcl_chests_chest_right.png", + "mcl_chests_chest_back.png"], + [tex_dir + "/entity/chest/trapped.png", + target_dir("/mods/ITEMS/mcl_chests/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_chests_chest_trapped_top.png", + "mcl_chests_chest_trapped_bottom.png", + "mcl_chests_chest_trapped_front.png", + "mcl_chests_chest_trapped_left.png", + "mcl_chests_chest_trapped_right.png", + "mcl_chests_chest_trapped_back.png"], + [tex_dir + "/entity/chest/ender.png", + target_dir("/mods/ITEMS/mcl_chests/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_chests_ender_chest_top.png", + "mcl_chests_ender_chest_bottom.png", + "mcl_chests_ender_chest_front.png", + "mcl_chests_ender_chest_left.png", + "mcl_chests_ender_chest_right.png", + "mcl_chests_ender_chest_back.png"]] + + for c in chest_files: + chest_file = c[0] + if os.path.isfile(chest_file): + PPX = (PXSIZE / 16) + CHPX = (PPX * 14) # Chest width + LIDPX = (PPX * 5) # Lid height + LIDLOW = (PPX * 10) # Lower lid section height + LOCKW = (PPX * 6) # Lock width + LOCKH = (PPX * 5) # Lock height + + cdir = c[1] + top = cdir + "/" + c[2] + bottom = cdir + "/" + c[3] + front = cdir + "/" + c[4] + left = cdir + "/" + c[5] + right = cdir + "/" + c[6] + back = cdir + "/" + c[7] + # Top + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(CHPX) + "+" + str(CHPX) + "+0 \\) -geometry +0+0 -composite -extent " + str(CHPX) + "x" + str(CHPX) + " " + top) + # Bottom + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(CHPX) + "+" + str(CHPX * 2) + "+" + str(CHPX + LIDPX) + " \\) -geometry +0+0 -composite -extent " + str(CHPX) + "x" + str(CHPX) + " " + bottom) + # Front + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDPX) + "+" + str(CHPX) + "+" + str(CHPX) + " \\) -geometry +0+0 -composite \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDLOW) + "+" + str(CHPX) + "+" + str(CHPX * 2 + LIDPX) + " \\) -geometry +0+" + str(LIDPX - PPX) + " -composite \ +-extent " + str(CHPX) + "x" + str(CHPX) + " " + front) + # TODO: Add lock + + # Left, right back (use same texture, we're lazy + files = [left, right, back] + for f in files: + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDPX) + "+" + str(0) + "+" + str(CHPX) + " \\) -geometry +0+0 -composite \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDLOW) + "+" + str(0) + "+" + str(CHPX * 2 + LIDPX) + " \\) -geometry +0+" + str(LIDPX - PPX) + " -composite \ +-extent " + str(CHPX) + "x" + str(CHPX) + " " + f) + + # Double chests + + chest_files = [[tex_dir + "/entity/chest/normal_double.png", + target_dir("/mods/ITEMS/mcl_chests/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "default_chest_front_big.png", + "default_chest_top_big.png", + "default_chest_side_big.png"], + [tex_dir + "/entity/chest/trapped_double.png", + target_dir("/mods/ITEMS/mcl_chests/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path), + "mcl_chests_chest_trapped_front_big.png", + "mcl_chests_chest_trapped_top_big.png", + "mcl_chests_chest_trapped_side_big.png"]] + for c in chest_files: + chest_file = c[0] + if os.path.isfile(chest_file): + PPX = (PXSIZE / 16) + CHPX = (PPX * 14) # Chest width (short side) + CHPX2 = (PPX * 15) # Chest width (long side) + LIDPX = (PPX * 5) # Lid height + LIDLOW = (PPX * 10) # Lower lid section height + LOCKW = (PPX * 6) # Lock width + LOCKH = (PPX * 5) # Lock height + + cdir = c[1] + front = cdir + "/" + c[2] + top = cdir + "/" + c[3] + side = cdir + "/" + c[4] + # Top + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX2) + "x" + str(CHPX) + "+" + str(CHPX) + "+0 \\) -geometry +0+0 -composite -extent " + str(CHPX2) + "x" + str(CHPX) + " " + top) + # Front + # TODO: Add lock + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX2) + "x" + str(LIDPX) + "+" + str(CHPX) + "+" + str(CHPX) + " \\) -geometry +0+0 -composite \ +\\( -clone 0 -crop " + str(CHPX2) + "x" + str(LIDLOW) + "+" + str(CHPX) + "+" + str(CHPX * 2 + LIDPX) + " \\) -geometry +0+" + str(LIDPX - PPX) + " -composite \ +-extent " + str(CHPX2) + "x" + str(CHPX) + " " + front) + # Side + os.system("convert " + chest_file + " \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDPX) + "+" + str(0) + "+" + str(CHPX) + " \\) -geometry +0+0 -composite \ +\\( -clone 0 -crop " + str(CHPX) + "x" + str(LIDLOW) + "+" + str(0) + "+" + str(CHPX * 2 + LIDPX) + " \\) -geometry +0+" + str(LIDPX - PPX) + " -composite \ +-extent " + str(CHPX) + "x" + str(CHPX) + " " + side) + +# Generate railway crossings and t-junctions + + +def convert_rail_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Generate railway crossings and t-junctions. Note: They may look strange. + # Note: these may be only a temporary solution, as crossings and t-junctions do not occour in MC. + # TODO: Curves + rails = [ + # (Straigt src, curved src, t-junction dest, crossing dest) + ("rail.png", "rail_corner.png", + "default_rail_t_junction.png", "default_rail_crossing.png"), + ("powered_rail.png", "rail_corner.png", + "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"), + ("powered_rail_on.png", "rail_corner.png", "mcl_minecarts_rail_golden_t_junction_powered.png", + "mcl_minecarts_rail_golden_crossing_powered.png"), + ("detector_rail.png", "rail_corner.png", "mcl_minecarts_rail_detector_t_junction.png", + "mcl_minecarts_rail_detector_crossing.png"), + ("detector_rail_on.png", "rail_corner.png", "mcl_minecarts_rail_detector_t_junction_powered.png", + "mcl_minecarts_rail_detector_crossing_powered.png"), + ("activator_rail.png", "rail_corner.png", "mcl_minecarts_rail_activator_t_junction.png", + "mcl_minecarts_rail_activator_crossing.png"), + ("activator_rail_on.png", "rail_corner.png", "mcl_minecarts_rail_activator_d_t_junction.png", + "mcl_minecarts_rail_activator_powered_crossing.png"), + ] + for r in rails: + os.system( + "composite -compose Dst_Over " + + tex_dir + + "/block/" + + r[0] + + " " + + tex_dir + + "/block/" + + r[1] + + " " + + target_dir( + "/mods/ENTITIES/mcl_minecarts/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/" + + r[2]) + os.system("convert " + tex_dir + "/block/" + + r[0] + " -rotate 90 " + tempfile1.name) + os.system( + "composite -compose Dst_Over " + + tempfile1.name + + " " + + tex_dir + + "/block/" + + r[0] + + " " + + target_dir( + "/mods/ENTITIES/mcl_minecarts/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/" + + r[3]) + +# Convert banner overlays + + +def convert_banner_overlays( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Convert banner overlays + overlays = [ + "base", + "border", + "bricks", + "circle", + "creeper", + "cross", + "curly_border", + "diagonal_left", + "diagonal_right", + "diagonal_up_left", + "diagonal_up_right", + "flower", + "gradient", + "gradient_up", + "half_horizontal_bottom", + "half_horizontal", + "half_vertical", + "half_vertical_right", + "rhombus", + "mojang", + "skull", + "small_stripes", + "straight_cross", + "stripe_bottom", + "stripe_center", + "stripe_downleft", + "stripe_downright", + "stripe_left", + "stripe_middle", + "stripe_right", + "stripe_top", + "square_bottom_left", + "square_bottom_right", + "square_top_left", + "square_top_right", + "triangle_bottom", + "triangles_bottom", + "triangle_top", + "triangles_top", + ] + for o in overlays: + orig = tex_dir + "/entity/banner/" + o + ".png" + if os.path.isfile(orig): + if o == "mojang": + o = "thing" + dest = target_dir( + "/mods/ITEMS/mcl_banners/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + "/" + "mcl_banners_" + o + ".png" + os.system( + "convert " + + orig + + " -transparent-color white -background black -alpha remove -alpha copy -channel RGB -white-threshold 0 " + + dest) + +# Convert grass and related textures + + +def convert_grass_textures( + make_texture_pack, + dry_run, + verbose, + base_dir, + tex_dir, + tempfile1, + tempfile2, + output_dir, + output_dir_name, + mineclone2_path, + PXSIZE): + # Convert grass + grass_file = tex_dir + "/block/grass_block_top.png" + if os.path.isfile(grass_file): + FOLIAG = tex_dir + "/colormap/foliage.png" + GRASS = tex_dir + "/colormap/grass.png" + + # Leaves + colorize_alpha( + FOLIAG, + tex_dir + + "/block/oak_leaves.png", + "116+143", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/default_leaves.png", + tempfile2.name) + colorize_alpha( + FOLIAG, + tex_dir + + "/block/dark_oak_leaves.png", + "158+177", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_core_leaves_big_oak.png", + tempfile2.name) + colorize_alpha( + FOLIAG, + tex_dir + + "/block/acacia_leaves.png", + "40+255", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/default_acacia_leaves.png", + tempfile2.name) + colorize_alpha( + FOLIAG, + tex_dir + + "/block/spruce_leaves.png", + "226+230", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_core_leaves_spruce.png", + tempfile2.name) + colorize_alpha( + FOLIAG, + tex_dir + + "/block/birch_leaves.png", + "141+186", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_core_leaves_birch.png", + tempfile2.name) + colorize_alpha( + FOLIAG, + tex_dir + + "/block/jungle_leaves.png", + "16+39", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/default_jungleleaves.png", + tempfile2.name) + + # Waterlily + colorize_alpha( + FOLIAG, + tex_dir + + "/block/lily_pad.png", + "16+39", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/flowers_waterlily.png", + tempfile2.name) + + # Vines + colorize_alpha( + FOLIAG, + tex_dir + + "/block/vine.png", + "16+39", + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_core_vine.png", + tempfile2.name) + + # Tall grass, fern (inventory images) + pcol = "50+173" # Plains grass color + # TODO: TALLGRASS.png does no longer exist + colorize_alpha( + GRASS, + tex_dir + + "/block/tallgrass.png", + pcol, + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_flowers_tallgrass_inv.png", + tempfile2.name) + colorize_alpha( + GRASS, + tex_dir + + "/block/fern.png", + pcol, + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_flowers_fern_inv.png", + tempfile2.name) + colorize_alpha( + GRASS, + tex_dir + + "/block/large_fern_top.png", + pcol, + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_flowers_double_plant_fern_inv.png", + tempfile2.name) + colorize_alpha( + GRASS, + tex_dir + + "/block/tall_grass_top.png", + pcol, + str(PXSIZE), + target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + + "/mcl_flowers_double_plant_grass_inv.png", + tempfile2.name) + + # Convert grass palette: https://minecraft.fandom.com/wiki/Tint + grass_colors = [ + # [Coords or #Color, AdditionalTint], # Index - Minecraft biome name (MineClone2 biome names) + # 0 - Plains (flat, Plains, Plains_beach, Plains_ocean, End) + ["50+173"], + # 1 - Savanna (Savanna, Savanna_beach, Savanna_ocean) + ["0+255"], + # 2 - Ice Spikes (IcePlainsSpikes, IcePlainsSpikes_ocean) + ["255+255"], + # 3 - Snowy Taiga (ColdTaiga, ColdTaiga_beach, ColdTaiga_beach_water, ColdTaiga_ocean) + ["255+255"], + # 4 - Giant Tree Taiga (MegaTaiga, MegaTaiga_ocean) + ["178+193"], + # 5 - Giant Tree Taiga (MegaSpruceTaiga, MegaSpruceTaiga_ocean) + ["178+193"], + # 6 - Montains (ExtremeHills, ExtremeHills_beach, ExtremeHills_ocean) + ["203+239"], + # 7 - Montains (ExtremeHillsM, ExtremeHillsM_ocean) + ["203+239"], + # 8 - Montains (ExtremeHills+, ExtremeHills+_snowtop, ExtremeHills+_ocean) + ["203+239"], + ["50+173"], # 9 - Beach (StoneBeach, StoneBeach_ocean) + ["255+255"], # 10 - Snowy Tundra (IcePlains, IcePlains_ocean) + # 11 - Sunflower Plains (SunflowerPlains, SunflowerPlains_ocean) + ["50+173"], + ["191+203"], # 12 - Taiga (Taiga, Taiga_beach, Taiga_ocean) + ["76+112"], # 13 - Forest (Forest, Forest_beach, Forest_ocean) + # 14 - Flower Forest (FlowerForest, FlowerForest_beach, FlowerForest_ocean) + ["76+112"], + # 15 - Birch Forest (BirchForest, BirchForest_ocean) + ["101+163"], + # 16 - Birch Forest Hills (BirchForestM, BirchForestM_ocean) + ["101+163"], + # 17 - Desert and Nether (Desert, Desert_ocean, Nether) + ["0+255"], + # 18 - Dark Forest (RoofedForest, RoofedForest_ocean) + ["76+112", "#28340A"], + ["#90814d"], # 19 - Mesa (Mesa, Mesa_sandlevel, Mesa_ocean, ) + # 20 - Mesa (MesaBryce, MesaBryce_sandlevel, MesaBryce_ocean) + ["#90814d"], + # 21 - Mesa (MesaPlateauF, MesaPlateauF_grasstop, MesaPlateauF_sandlevel, MesaPlateauF_ocean) + ["#90814d"], + # 22 - Mesa (MesaPlateauFM, MesaPlateauFM_grasstop, MesaPlateauFM_sandlevel, MesaPlateauFM_ocean) + ["#90814d"], + # 23 - Shattered Savanna (or Savanna Plateau ?) (SavannaM, SavannaM_ocean) + ["0+255"], + ["12+36"], # 24 - Jungle (Jungle, Jungle_shore, Jungle_ocean) + # 25 - Modified Jungle (JungleM, JungleM_shore, JungleM_ocean) + ["12+36"], + ["12+61"], # 26 - Jungle Edge (JungleEdge, JungleEdge_ocean) + # 27 - Modified Jungle Edge (JungleEdgeM, JungleEdgeM_ocean) + ["12+61"], + # 28 - Swamp (Swampland, Swampland_shore, Swampland_ocean) + ["#6A7039"], + # 29 - Mushroom Fields and Mushroom Field Shore (MushroomIsland, MushroomIslandShore, MushroomIsland_ocean) + ["25+25"], + ] + + grass_palette_file = target_dir( + "/textures", + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path) + "/mcl_core_palette_grass.png" + os.system("convert -size 16x16 canvas:transparent " + + grass_palette_file) + + for i, color in enumerate(grass_colors): + if color[0][0] == "#": + os.system("convert -size 1x1 xc:\"" + + color[0] + "\" " + tempfile1.name + ".png") + else: + os.system("convert " + GRASS + " -crop 1x1+" + + color[0] + " " + tempfile1.name + ".png") + + if len(color) > 1: + os.system( + "convert " + + tempfile1.name + + ".png \\( -size 1x1 xc:\"" + + color[1] + + "\" \\) -compose blend -define compose:args=50,50 -composite " + + tempfile1.name + + ".png") + + os.system("convert " + + grass_palette_file + + " \\( " + + tempfile1.name + + ".png -geometry +" + + str(i % + 16) + + "+" + + str(int(i / + 16)) + + " \\) -composite " + + grass_palette_file) diff --git a/tools/libtextureconverter/utils.py b/tools/libtextureconverter/utils.py new file mode 100644 index 000000000..3756574f6 --- /dev/null +++ b/tools/libtextureconverter/utils.py @@ -0,0 +1,211 @@ +import shutil +import csv +import os +import tempfile +import sys +import argparse +import glob +import re +import zipfile +from .config import SUPPORTED_MINECRAFT_VERSION, home +from collections import Counter +import platform +from wand.image import Image +from wand.color import Color +from wand.display import display +import warnings + +def detect_pixel_size(directory): + from PIL import Image + sizes = [] + for filename in glob.glob(directory + '/**/*.png', recursive=True): + with Image.open(filename) as img: + sizes.append(img.size) + if not sizes: + return 16 # Default to 16x16 if no PNG files are found + most_common_size = Counter(sizes).most_common(1)[0][0] + print( + f"Autodetected pixel size: {most_common_size[0]}x{most_common_size[1]}") + return most_common_size[0] + +def target_dir( + directory, + make_texture_pack, + output_dir, + output_dir_name, + mineclone2_path): + if make_texture_pack: + return output_dir + "/" + output_dir_name + else: + return mineclone2_path + directory + + +def colorize(colormap, source, colormap_pixel, texture_size, destination, tempfile1_name): + try: + # Convert the colormap_pixel to integer coordinates + x, y = map(int, colormap_pixel.split('+')) + + # Define texture size as integer + texture_size = int(texture_size) + + with Image(filename=colormap) as img: + # Crop the image + img.crop(x, y, width=1, height=1) + + # Set depth (This might be ignored by Wand as it manages depth automatically) + img.depth = 8 + + # Resize the image + img.resize(texture_size, texture_size) + + # Save the result + img.save(filename=tempfile1_name) + + except Exception as e: + warnings.warn(f"An error occurred during the first image processing operation: {e}") + + try: + # Load the images + with Image(filename=tempfile1_name) as top_image: + with Image(filename=source) as bottom_image: + # Perform composite operation with Multiply blend mode + bottom_image.composite(top_image, 0, 0, operator='multiply') + + # Save the result + bottom_image.save(filename=destination) + + except Exception as e: + warnings.warn(f"An error occurred during the second image processing operation: {e}") + + +def colorize_alpha( + colormap, + source, + colormap_pixel, + texture_size, + destination, + tempfile2_name): + colorize(colormap, source, colormap_pixel, + texture_size, destination, tempfile2_name) + try: + with Image(filename=source) as source_image: + with Image(filename=tempfile2_name) as tempfile2_image: + # Perform composite operation with Dst_In blend mode + tempfile2_image.composite(source_image, 0, 0, operator='dst_in') + + # Set alpha channel + tempfile2_image.alpha_channel = 'set' + + # Save the result + tempfile2_image.save(filename=destination) + except Exception as e: + warnings.warn(f"An error occurred during the second image processing operation: {e}") + + +def find_highest_minecraft_version(home, supported_version): + version_pattern = re.compile(re.escape(supported_version) + r"\.\d+") + versions_dir = os.path.join(home, ".minecraft", "versions") + highest_version = None + if os.path.isdir(versions_dir): + for folder in os.listdir(versions_dir): + if version_pattern.match(folder): + if not highest_version or folder > highest_version: + highest_version = folder + return highest_version + + +def find_all_minecraft_resourcepacks(): + resourcepacks_dir = os.path.join(home, '.minecraft', 'resourcepacks') + + if not os.path.isdir(resourcepacks_dir): + print(f"Resource packs directory not found: {resourcepacks_dir}") + return + + resourcepacks = [] + for folder in os.listdir(resourcepacks_dir): + folder_path = os.path.join(resourcepacks_dir, folder) + if os.path.isdir(folder_path): + pack_png_path = os.path.join(folder_path, 'pack.png') + if os.path.isfile(pack_png_path): + print(f"Adding resourcepack '{folder}'") + resourcepacks.append(folder_path) + else: + print( + f"pack.png not found in resourcepack '{folder}', not converting") + + return resourcepacks + + +def handle_default_minecraft_texture(home, output_dir): + version = find_highest_minecraft_version(home, SUPPORTED_MINECRAFT_VERSION) + if not version: + print("No suitable Minecraft version found.") + sys.exit(1) + + jar_file = os.path.join( + home, ".minecraft", "versions", version, f"{version}.jar") + if not os.path.isfile(jar_file): + print("Minecraft JAR file not found.") + sys.exit(1) + + temp_zip = f"/tmp/mc-default-{version.replace('.', '')}.zip" + shutil.copy2(jar_file, temp_zip) + + extract_folder = temp_zip.replace(".zip", "") + with zipfile.ZipFile(temp_zip, 'r') as zip_ref: + zip_ref.extractall(extract_folder) + + if not os.path.exists(extract_folder): + print(f"Extraction failed, folder not found: {extract_folder}") + sys.exit(1) + + # Normalize the extract folder path + extract_folder = os.path.normpath(extract_folder) + + # Define the textures directory and normalize it + textures_directory = os.path.normpath( + f"{extract_folder}/assets/minecraft/textures") + + # Using glob to find all files + all_files = glob.glob(f"{extract_folder}/**/*.*", recursive=True) + + # Remove all non-png files except pack.mcmeta and pack.png in the root + for file_path in all_files: + if not file_path.endswith('.png') and not file_path.endswith( + 'pack.mcmeta') and not file_path.endswith('pack.png'): + # print(f"Removing file: {file_path}") + os.remove(file_path) + + # Remove all directories in the root except 'assets' + for item in os.listdir(extract_folder): + item_path = os.path.join(extract_folder, item) + if os.path.isdir(item_path) and item != "assets": + # print(f"Removing directory: {item_path}") + shutil.rmtree(item_path, ignore_errors=True) + + # Remove directories in 'minecraft' except for 'textures' + minecraft_directory = os.path.normpath( + f"{extract_folder}/assets/minecraft") + for item in os.listdir(minecraft_directory): + item_path = os.path.join(minecraft_directory, item) + if os.path.isdir(item_path) and item != "textures": + print(f"Removing directory: {item_path}") + shutil.rmtree(item_path, ignore_errors=True) + + # Copy the textures directory to the output directory + output_textures_directory = os.path.join( + output_dir, 'assets/minecraft/textures') + if os.path.exists(textures_directory) and not os.path.exists( + output_textures_directory): + os.makedirs(os.path.dirname(output_textures_directory), exist_ok=True) + shutil.copytree(textures_directory, + output_textures_directory, dirs_exist_ok=True) + + # Copy pack.mcmeta and pack.png file if exists + for file_name in ['pack.mcmeta', 'pack.png']: + file_path = os.path.join(extract_folder, file_name) + if os.path.exists(file_path): + shutil.copy(file_path, output_dir) + + print(f"Filtered and extracted to: {extract_folder}") + return extract_folder diff --git a/tools/override.txt b/tools/override.txt new file mode 100644 index 000000000..db246e5f5 --- /dev/null +++ b/tools/override.txt @@ -0,0 +1,57 @@ +Signs: + +mcl_signs:wall_sign_warped_hyphae_wood inventory mcl_signs_warped_sign_inv.png +mcl_signs:wall_sign_warped_hyphae_wood wield mcl_signs_warped_sign_inv.png +mcl_signs:wall_sign_warped_hyphae_wood all mcl_signs_warped_sign.png +mcl_signs:standing_sign_warped_hyphae_wood all mcl_signs_warped_sign.png +mcl_signs:standing_sign22_5_warped_hyphae_wood all mcl_signs_warped_sign.png +mcl_signs:standing_sign45_warped_hyphae_wood all mcl_signs_warped_sign.png +mcl_signs:standing_sign67_5_warped_hyphae_wood all mcl_signs_warped_sign.png + +mcl_signs:wall_sign_c rimson_hyphae_wood inventory mcl_signs_crimson_sign_inv.png +mcl_signs:wall_sign_crimson_hyphae_wood wield mcl_signs_crimson_sign_inv.png +mcl_signs:wall_sign_crimson_hyphae_wood all mcl_signs_crimson_sign.png +mcl_signs:standing_sign_crimson_hyphae_wood all mcl_signs_crimson_sign.png +mcl_signs:standing_sign22_5_crimson_hyphae_wood all mcl_signs_crimson_sign.png +mcl_signs:standing_sign45_crimson_hyphae_wood all mcl_signs_crimson_sign.png +mcl_signs:standing_sign67_5_crimson_hyphae_wood all mcl_signs_crimson_sign.png + +mcl_signs:wall_sign_acaciawood inventory mcl_signs_acacia_sign_inv.png +mcl_signs:wall_sign_acaciawood wield mcl_signs_acacia_sign_inv.png +mcl_signs:wall_sign_acaciawood all mcl_signs_acacia_sign.png +mcl_signs:standing_sign_acaciawood all mcl_signs_acacia_sign.png +mcl_signs:standing_sign22_5_acaciawood all mcl_signs_acacia_sign.png +mcl_signs:standing_sign45_acaciawood all mcl_signs_acacia_sign.png +mcl_signs:standing_sign67_5_acaciawood all mcl_signs_acacia_sign.png + +mcl_signs:wall_sign_birchwood inventory mcl_signs_birch_sign_inv.png +mcl_signs:wall_sign_birchwood wield mcl_signs_birch_sign_inv.png +mcl_signs:wall_sign_birchwood all mcl_signs_birch_sign.png +mcl_signs:standing_sign_birchwood all mcl_signs_birch_sign.png +mcl_signs:standing_sign22_5_birchwood all mcl_signs_birch_sign.png +mcl_signs:standing_sign45_birchwood all mcl_signs_birch_sign.png +mcl_signs:standing_sign67_5_birchwood all mcl_signs_birch_sign.png + +mcl_signs:wall_sign_junglewood inventory mcl_signs_jungle_sign_inv.png +mcl_signs:wall_sign_junglewood wield mcl_signs_jungle_sign_inv.png +mcl_signs:wall_sign_junglewood all mcl_signs_jungle_sign.png +mcl_signs:standing_sign_junglewood all mcl_signs_jungle_sign.png +mcl_signs:standing_sign22_5_junglewood all mcl_signs_jungle_sign.png +mcl_signs:standing_sign45_junglewood all mcl_signs_jungle_sign.png +mcl_signs:standing_sign67_5_junglewood all mcl_signs_jungle_sign.png + +mcl_signs:wall_sign_mangrove_wood inventory mcl_signs_mangrove_sign_inv.png +mcl_signs:wall_sign_mangrove_wood wield mcl_signs_mangrove_sign_inv.png +mcl_signs:wall_sign_mangrove_wood all mcl_signs_mangrove_sign.png +mcl_signs:standing_sign_mangrove_wood all mcl_signs_mangrove_sign.png +mcl_signs:standing_sign22_5_mangrove_wood all mcl_signs_mangrove_sign.png +mcl_signs:standing_sign45_mangrove_wood all mcl_signs_mangrove_sign.png +mcl_signs:standing_sign67_5_mangrove_wood all mcl_signs_mangrove_sign.png + +mcl_signs:wall_sign_sprucewood inventory mcl_signs_spruce_sign_inv.png +mcl_signs:wall_sign_sprucewood wield mcl_signs_spruce_sign_inv.png +mcl_signs:wall_sign_sprucewood all mcl_signs_spruce_sign.png +mcl_signs:standing_sign_sprucewood all mcl_signs_spruce_sign.png +mcl_signs:standing_sign22_5_sprucewood all mcl_signs_spruce_sign.png +mcl_signs:standing_sign45_sprucewood all mcl_signs_spruce_sign.png +mcl_signs:standing_sign67_5_sprucewood all mcl_signs_spruce_sign.png diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 000000000..f4c5a4016 --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1,2 @@ +Pillow +Wand diff --git a/tools/texture_conversion_extra_tools/conversion_table_validator.py b/tools/texture_conversion_extra_tools/conversion_table_validator.py new file mode 100644 index 000000000..81039558b --- /dev/null +++ b/tools/texture_conversion_extra_tools/conversion_table_validator.py @@ -0,0 +1,38 @@ +import csv +import os + +def validate_csv(file_path): + with open(file_path, newline='') as csvfile: + reader = csv.reader(csvfile, delimiter=',', quotechar='"') + line_num = 1 + for row in reader: + # Skip the header + if line_num == 1: + line_num += 1 + continue + + # Check if row has correct number of columns + if len(row) != 10: + print(f"Warning: Line {line_num} is not a valid CSV row.") + line_num += 1 + continue + + # Validate source path + if "/assets/minecraft/" not in row[0]: + print(f"Warning: Line {line_num} does not contain '/assets/minecraft/' in the source path.") + + # Validate Source file and Target file + if not row[1].endswith('.png'): + print(f"Warning: Line {line_num} has an invalid or missing Source file. It should end with '.png'.") + if not row[2].endswith('.png'): + print(f"Warning: Line {line_num} has an invalid or missing Target file. It should end with '.png'.") + + line_num += 1 + +if __name__ == "__main__": + csv_file = 'Conversion_Table.csv' + if os.path.exists(csv_file): + validate_csv(csv_file) + print("Validated CSV, if no warnings or errors, your good!") + else: + print(f"Error: The file '{csv_file}' does not exist.") diff --git a/tools/texture_conversion_extra_tools/new_table_conversion.py b/tools/texture_conversion_extra_tools/new_table_conversion.py new file mode 100644 index 000000000..7084fae6f --- /dev/null +++ b/tools/texture_conversion_extra_tools/new_table_conversion.py @@ -0,0 +1,40 @@ +import csv + +def read_csv(file_path): + with open(file_path, mode='r', encoding='utf-8') as file: + return list(csv.reader(file)) + +def write_csv(file_path, data): + with open(file_path, mode='w', encoding='utf-8', newline='') as file: + writer = csv.writer(file) + writer.writerows(data) + +def merge_tables(original_csv, new_csv): + # Convert the lists to dictionaries for easier manipulation + original_dict = {row[3]: row for row in original_csv} + new_dict = {row[3]: row for row in new_csv} + + # Update or add new entries + for key in new_dict: + original_dict[key] = new_dict[key] + + # Convert the dictionary back to a list + merged_data = list(original_dict.values()) + + return merged_data + +def main(): + original_csv_path = './Conversion_Table.csv' + new_csv_path = './Conversion_Table_New.csv' + + original_csv = read_csv(original_csv_path) + new_csv = read_csv(new_csv_path) + + # Skip the header row in new_csv + merged_data = merge_tables(original_csv, new_csv[1:]) + + write_csv(original_csv_path, merged_data) + print("Conversion tables have been merged and updated successfully.") + +if __name__ == "__main__": + main() diff --git a/tools/texture_conversion_extra_tools/outstanding_conv.py b/tools/texture_conversion_extra_tools/outstanding_conv.py new file mode 100644 index 000000000..b3d928a09 --- /dev/null +++ b/tools/texture_conversion_extra_tools/outstanding_conv.py @@ -0,0 +1,36 @@ +import csv + +def read_missing_textures(file_path): + with open(file_path, 'r') as file: + return [line.strip().split('/')[-1] for line in file.readlines()] + +def read_conversion_table(file_path): + with open(file_path, 'r') as file: + return list(csv.reader(file)) + +def find_outstanding_entries(missing_textures, conversion_table): + outstanding_entries = [] + for row in conversion_table: + if row[1] in missing_textures: + outstanding_entries.append(row) + return outstanding_entries + +def write_outstanding_entries(file_path, outstanding_entries): + with open(file_path, 'w', newline='') as file: + writer = csv.writer(file) + writer.writerows(outstanding_entries) + +def main(): + missing_textures_file = './missing_textures_filtered.txt' + conversion_table_file = './Conversion_Table.csv' + output_file = './Conversion_Table_Outstanding.csv' + + missing_textures = read_missing_textures(missing_textures_file) + conversion_table = read_conversion_table(conversion_table_file) + outstanding_entries = find_outstanding_entries(missing_textures, conversion_table) + + write_outstanding_entries(output_file, outstanding_entries) + print("Outstanding conversion table entries written to:", output_file) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/tools/texture_conversion_extra_tools/remove_null_lines.py b/tools/texture_conversion_extra_tools/remove_null_lines.py new file mode 100644 index 000000000..d1657b6f4 --- /dev/null +++ b/tools/texture_conversion_extra_tools/remove_null_lines.py @@ -0,0 +1,15 @@ +def remove_null_lines(input_file, output_file): + with open(input_file, 'r') as infile, open(output_file, 'w') as outfile: + for line in infile: + if "NULL" not in line: + outfile.write(line) + +def main(): + input_file = './Conversion_Table.csv' # Replace with your input file path + output_file = './Conversion_Table_New.csv' # Replace with your output file path + + remove_null_lines(input_file, output_file) + print("File processed successfully, NULL lines removed.") + +if __name__ == "__main__": + main()