diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..8e3084dd3 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +end_of_line = lf + +[*.lua] +charset = utf8 +indent_style = tab +insert_final_newline = true +trim_trailing_whitespace = true +keep_one_space_between_table_and_bracket = false +spaces_around_operators = true diff --git a/.gitea/issue_template/bug.md b/.gitea/issue_template/bug.md new file mode 100644 index 000000000..be76e6395 --- /dev/null +++ b/.gitea/issue_template/bug.md @@ -0,0 +1,36 @@ +--- + +name: "Bug report" +about: "File a bug report" +labels: + +- unconfirmed +- bug + +--- + + + + +MineClone2 version: + +### What happened? +Report about the bug! Please send large log snippets as an attachement file. + +### What should happen: +Tell us what should happen! + +### Steps to reproduce +Tell us how we can reproduce the bug! diff --git a/.gitea/issue_template/feature_request.md b/.gitea/issue_template/feature_request.md new file mode 100644 index 000000000..58a7437ab --- /dev/null +++ b/.gitea/issue_template/feature_request.md @@ -0,0 +1,26 @@ +--- + +name: "Feature request" +about: "File a feature request not in Minecraft" +labels: + +- "non-Minecraft feature" +- "needs discussion" + +--- + + + +### Feature +Tell us about your requested feature not in Minecraft! + +### 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 new file mode 100644 index 000000000..b3e275c9b --- /dev/null +++ b/.gitea/issue_template/missing_feature_request.md @@ -0,0 +1,25 @@ +--- + +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 new file mode 100644 index 000000000..ec7207ee4 --- /dev/null +++ b/.gitea/pull_request_template.md @@ -0,0 +1,20 @@ +--- + +name: "Pull request" +about: "Submit a pull request" +labels: + +--- + + + +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 new file mode 100644 index 000000000..de181d31a --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Text Editor TMP Files +*.swp +*.blend1 +*.blend2 +*.blend3 +/.idea/ +*.xcf +.Rproj.user \ No newline at end of file diff --git a/.luacheckrc b/.luacheckrc new file mode 100644 index 000000000..9d0b8cb2a --- /dev/null +++ b/.luacheckrc @@ -0,0 +1,55 @@ +unused_args = false +allow_defined_top = true +max_line_length = false +redefined = false + +globals = { + "minetest", "core", +} + +read_globals = { + "DIR_DELIM", + "dump", "dump2", + "vector", + "VoxelManip", "VoxelArea", + "PseudoRandom", "PcgRandom", "PerlinNoise", "PerlinNoiseMap", + "ItemStack", + "Settings", + "unpack", + + table = { + fields = { + "copy", + "indexof", + "insert_all", + "key_value_swap", + } + }, + + string = { + fields = { + "split", + "trim", + } + }, + + math = { + fields = { + "hypot", + "sign", + "factorial" + } + }, + ------ + --MODS + ------ + + --GENERAL + "default", + + --ENTITIES + "cmi", + + --HUD + "sfinv", "sfinv_buttons", "unified_inventory", "cmsg", "inventory_plus", +} \ No newline at end of file diff --git a/API.md b/API.md index 344414b72..865630c78 100644 --- a/API.md +++ b/API.md @@ -17,6 +17,10 @@ Items can have these fields: anvil. See `mcl_banners` for an example. +Tools can have these fields: +* `_mcl_diggroups`: Specifies the digging groups that a tool can dig and how + efficiently. See `_mcl_autogroup` for more information. + All nodes can have these fields: * `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0 @@ -37,9 +41,10 @@ A lot of things are possible by using one of the APIs in the mods. Note that not * Beds: `ITEMS/mcl_beds` * Buckets: `ITEMS/mcl_buckets` * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers` +* Campfires: `ITEMS/mcl_campfires` -## Mobs -* Mobs: `ENTITIES/mcl_mods` +### 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. @@ -67,6 +72,9 @@ chances are good that it works out of the box. * Get flowing direction of liquids: `CORE/flowlib` * `on_walk_over` callback for nodes: `CORE/walkover` * Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo` +* Explosion API +* Music discs API +* 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! @@ -79,12 +87,10 @@ The following APIs may be subject to change in future. You could already use the ### Planned APIs -* Flowers * Saplings and trees * Custom banner patterns * Custom dimensions * Custom portals -* Music discs * Dispenser and dropper support * Proper sky and weather APIs -* Explosion API + diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..ffb1194aa --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +ancientmariner_dev@proton.me. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 88370f62e..781b1b85f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,96 +1,420 @@ -# Contributing to MineClone 2 -So you want to MineClone 2? +# Contributing to MineClone2 +So you want to contribute to MineClone2? Wow, thank you! :-) -But first, some things to note: +MineClone2 is maintained by AncientMariner and Nicu. If you have any +problems or questions, contact us on Discord/Matrix (See Links section below). -MineClone 2's development target is to make a free software clone of Minecraft, -***version 1.11***, ***PC edition***. +You can help with MineClone2's development in many different ways, +whether you're a programmer or not. -MineClone 2 is maintained by two persons. Namely, kay27 and EliasFleckenstein. You can find us -in the Minetest forums (forums.minetest.net), in IRC in the #minetest -channel on irc.freenode.net. And finally, you can send e-mails to - or . +## MineClone2's development target is to... +- Create a stable, peformant, moddable, free/libre game based on 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. -There is **no** guarantee we will accept anything from anybody. +## Links +* [Mesehub](https://git.minetest.land/MineClone2/MineClone2) +* [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/) +* [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) -By sending us patches or asking us to include your changes in this game, -you agree that they fall under the terms of the LGPLv2.1, which basically -means they will become part of a free software. +## Using git +MineClone2 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 +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. -## The suggested workflow -We don't **dictate** your workflow, but in order to work with us in an efficient -way, you can follow these suggestions: +Look at our wiki for some concrete guides: +https://git.minetest.land/MineClone2/MineClone2/wiki/ -For small and medium changes: +## 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), +you can report a bug or request a feature. -* Fork the repository +### Rules about both bugs and feature requests +* Stay polite towards the developers and anyone else involved in the +discussion. +* Choose a descriptive title (e.g. not just "crash", "bug" or "question" +). +* Always check the currently opened issues before creating a new one. +Try not to report bugs that have already been reported or request features +that already have been requested. This can often be ambiguous though. +If in doubt open an issue! +* If you know about Minetest's inner workings, please think about +whether the bug / the feature that you are reporting / requesting is +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. + +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) + +### Reporting bugs +* A bug is an unintended behavior or, in the worst case, a crash. +However, it is not a bug if you believe something is missing in the +game. In this case, please read "Requesting features" +* If you report a crash, always include the error message. If you play +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 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. + +### Requesting features +* 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 +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 +latest or development versions. + +### Testing code +If you want to help us with speeding up MineClone2 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 +programmer saying "Look, I modified the game, please apply my changes +to the upstream version of the game". However, every programmer makes +mistakes sometimes, some of which are hard to spot. You can help by +downloading this modified version of the game and trying it out - then +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 +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. + +### Contributing assets +Due to license problems, MineClone2 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). + +#### Textures +For textures we prefer original art, but in the absence of that will accept +Pixel Perfection texture pack contributions. Be warned many of the newer +textures in it are copies or slight modifications of the original MC textures +so great caution needs to be taken when using any textures coming from +Minecraft texture packs. +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. +The sounds in the game come from different sources, like the SnowZone +resource pack or minetest_game. Unfortunately, MineClone2 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 +play these sounds in game. All sounds should be released under an open +source license with clear information on the source, licencing and any +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 +[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 +animations have to be added etc. + +#### Crediting +Asset contributions will be credited in their mods and their own respective +sections in CREDITS.md. If you have commited the results yourself, you will +also be credited in the Contributors section. + +### Contributing Translations + +#### Workflow +To add/update support for your language to MineClone2, 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. + +#### Things to note +You can use the script at `tools/check_translate_files.py` to compare +the translation files for the language you are working on with the +template files, to see what is missing and what is out of date with +the template file. However, template files are often incomplete and/or +out of date, sometimes they don't match the code. You can update the +translation files if that is required, you can also modify the code in +your translation PR if it's related to translation. You can also work on +multiple languages at the same time in one PR. + +#### Crediting +Translation contributions will be credited in their own in CREDITS.md. +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 +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. + +#### Using Minetest's profiler +We frequently will use profiling to optimise our code. We recommend use of +the JIT profiler (RIP Jude) to fully understand performance impact: + +https://content.minetest.net/packages/jwmhjwmh/jitprofiler/ + +Minetest also has a built in profiler. Simply set `profiler.load = true` in +your configuration file and restart the server. After running the server +for some time, just run `/profiler save` in chat - then you will find a +file in the world directory containing the results. Open a new issue and +upload the file. You can name the issue " profiler +results". + +### Let us know your opinion +It is always encouraged to actively contribute to issue discussions on +MeseHub, let us know what you think about a topic and help us make +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). + +### Crediting +If you opened or have contributed to an issue, you receive the +`Community` role on our Discord (after asking for it). +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. + +### Recommended workflow +* Fork the repository (in case you have not already) * Do your change in a new branch -* Upload the repository somewhere where it can be accessed from the Internet and - notify us +* Create a pull request to get your changes merged into master +* It is important that conflicts are resolved prior to merging the pull +request. +* We update our branches via rebasing. Please avoid merging master into +your branch unless it's the only way you can resolve a conflict. We can +rebase branches from the GUI if the user has not merged master into the +branch. +* After the pull request got merged, you can delete the branch if the +merger hasn't done this already. -For small changes, sending us a patch is also good. +### Discuss first +If you feel like a problem needs to fixed or you want to make a new +feature, you could start writing the code right away and notifying us +when you're done, but it never hurts to discuss things first. If there +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. -For big changes: Same as above, but consider notifying us first to avoid -duplicate work and possible tears of rejection. ;-) +### 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 +better, or assist you use development tools. -For trusted people, we might give them direct commit access to this -repository. In this case, you obviously don't need to fork, but you still -need to show your contributions align with the project goals. We still -reserve the right to revert everything that we don't like. -For bigger changes, we strongly recommend to use feature branches and -discuss with me first. +### Maintain your own code, even if already got merged +Sometimes, your code may cause crashes or bugs - we try to avoid such +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. -Contributors will be credited in `README.md`. +### 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: -## Quality remarks -Again: There is ***no*** guarantee we will accept anything from anybody. -But we will gladly take in code from others when we feel it saves us work -in the long run. +* 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) -### Inclusion criteria -Depending on what you add, the chances for inclusion vary: +### Guidelines -### High chance for inclusion -* Gameplay features in Minecraft which are missing in MineClone 2 +#### 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 +* 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 +* 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) +* 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) -### Medium chance for inclusion (discuss first) -* Features which don't a impact on gameplay -* GUI improvement -* Features from pocket or console edition +#### 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 +does not support capital letters in mod names. +* To export functions, store them inside a global table named like the +mod, e.g. -### Low chance for inclusion (discuss/optimize first) -* Overhaul of architecture / mod structure -* Mass-itemstring changes all over the place -* Added files have a unusual high file size -* Indentation looks like crazy -* Single commits which add several unrelated things -* Gameplay features which don't exist in Minecraft +```lua +mcl_example = {} -### Instant rejection -* Proprietary **anything** -* Code contains `minetest.env` anywhere +function mcl_example.do_something() + -- ... +end -## Coding style guide -* Indentations should reflect the code flow -* Use tabs, not spaces for indentation (tab size = 8) -* Never use `minetest.env` +``` -## Reporting bugs -Report all bugs and missing Minecraft features here: +* Public functions should not use self references but rather just access +the table directly, e.g. - +```lua +-- bad +function mcl_example:do_something() +end -## Direct discussion -We have an IRC channel! Join us on #mineclone2 in freenode.net. +-- good +function mcl_example.do_something() +end +``` - +* Use modern Minetest API, e.g. no usage of `minetest.env` +* Tabs should be used for indent, spaces for alignment, e.g. -## Creating releases +```lua + +-- use tabs for indent + +for i = 1, 10 do + if i % 3 == 0 then + print(i) + end +end + +-- use tabs for indent and spaces to align things + +some_table = { + {"a string", 5}, + {"a very much longer string", 10}, +} +``` + +* Use double quotes for strings, e.g. `"asdf"` rather than `'asdf'` +* Use snake_case rather than CamelCase, e.g. `my_function` rather than +`MyFunction` +* Don't declare functions as an assignment, e.g. + +```lua +-- bad +local some_local_func = function() + -- ... +end + +my_mod.some_func = function() + -- ... +end + +-- good +local function some_local_func() + -- ... +end + +function my_mod.some_func() + -- ... +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. + +#### 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. +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 +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 +and could result in merge conflicts for a larger older branch, or needs +art/licencing reviewing. A PR needs at least one approval (by someone else other +than the author). +- The maintainers are usually relatively quick to react to new submissions. + +### Maintainer status +Maintainers carry the main responsibility for the project. + +#### Maintainer responsibilities +- Making sure issues are addressed and pull requests are reviewed and +merged. +- Making releases +- Making project decisions based on community feedback +- Granting/revoking developer access +- Enforcing the code of conduct (See CODE_OF_CONDUCT.md) +- Moderating official community spaces (See Links section) +- Resolving conflicts and problems within the community + +#### Current maintainers +* AncientMariner - 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 * Update the version number in README.md -* Use `git tag ` to tag the latest commit with the version number -* Push to repo (don't forget `--tags`!) -* Update ContentDB (https://content.minetest.net/packages/Wuzzy/mineclone2/) -* Update first post in forum thread (https://forum.minetest.net/viewtopic.php?f=50&t=16407) +* Use `git tag ` to tag the latest commit with the +version number +* Push to repository (don't forget `--tags`!) +* Update ContentDB +(https://content.minetest.net/packages/Wuzzy/mineclone2/) +* Update first post in forum thread +(https://forum.minetest.net/viewtopic.php?f=50&t=16407) * Post release announcement and changelog in forums + +### Licensing +By asking us to include your changes in this game, you agree that they +fall under the terms of the GPLv3, which basically means they will +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, +Developers and Maintainers. diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 000000000..3517615ff --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,210 @@ +# Credits + +## Creator of MineClone +* davedevils + +## Creator of MineClone2 +* Wuzzy + +## Maintainers +* AncientMariner +* Nicu + +## Previous Maintainers +* Fleckenstein +* cora + +## Developers +* AFCMS +* epCode +* chmodsayshello +* PrairieWind +* MrRar +* FossFanatic +* SmokeyDope + +## Past Developers +* jordan4ibanez +* iliekprogrammar +* kabou +* Faerraven / Michieal +* MysticTempest +* NO11 +* SumianVoice + +## Contributors +* RandomLegoBrick +* rudzik8 +* Code-Sploit +* aligator +* Rootyjr +* ryvnf +* bzoss +* talamh +* Laurent Rocher +* HimbeerserverDE +* TechDudie +* Alexander Minges +* ArTee3 +* ZeDique la Ruleta +* pitchum +* wuniversales +* Bu-Gee +* David McMackins II +* Nicholas Niro +* Wouters Dorian +* Blue Blancmange +* Jared Moody +* Li0n +* Midgard +* Saku Laesvuori +* Yukitty +* ZedekThePD +* aldum +* dBeans +* nickolas360 +* yutyo +* Tianyang Zhang +* j45 +* Marcin Serwin +* erlehmann +* E +* n_to +* kay27 +* debiankaios +* Gustavo6046 / wallabra +* CableGuy67 +* Benjamin Schötz +* Doloment +* Sydney Gems +* Emily2255 +* Emojigit +* FinishedFragment +* sfan5 +* Blue Blancmange +* Jared Moody +* SmallJoker +* Sven792 +* aldum +* Dieter44 +* Pepebotella +* Lazerbeak12345 +* mrminer +* Thunder1035 +* opfromthestart +* snowyu +* FaceDeer +* Herbert West +* GuyLiner +* 3raven +* anarquimico +* TheOnlyJoeEnderman +* Ranko Saotome +* Gregor Parzefall +* Wbjitscool +* b3nderman +* CyberMango +* gldrk +* atomdmac +* emptyshore +* FlamingRCCars +* uqers +* Niterux +* appgurueu + +## 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) +* 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 +* Wuzzy +* Fleckenstein +* BlockMen +* TenPlus1 +* PilzAdam +* ryvnf +* stujones11 +* Arcelmi +* celeron55 +* maikerumine +* GunshipPenguin +* Qwertymine3 +* Rochambeau +* rubenwardy +* stu +* 4aiman +* Kahrl +* Krock +* UgnilJoZ +* lordfingle +* 22i +* bzoss +* kilbith +* xeranas +* kddekadenz +* sofar +* 4Evergreen4 +* jordan4ibanez +* paramat +* debian044 / debian44 +* chmodsayshello +* cora +* Faerraven / Michieal +* PrairieWind + +## 3D Models +* 22i +* tobyplowy +* epCode +* Faerraven / Michieal +* SumianVoice + +## Textures +* XSSheep +* Wuzzy +* kingoscargames +* leorockway +* xMrVizzy +* yutyo +* NO11 +* kay27 +* MysticTempest +* RandomLegoBrick +* cora +* Faerraven / Michieal +* Nicu +* Exhale +* Wbjitscool +* SmokeyDope + +## Translations +* Wuzzy +* Rocher Laurent +* wuniversales +* kay27 +* pitchum +* todoporlalibertad +* Marcin Serwin +* Pepebotella +* Emojigit +* snowyu +* 3raven +* SakuraRiu +* anarquimico +* syl +* Temak +* megustanlosfrijoles +* kbundg + +## Funders +* 40W +* bauknecht +* Cora + +## 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 diff --git a/GROUPS.md b/GROUPS.md index f94b04979..e6d878990 100644 --- a/GROUPS.md +++ b/GROUPS.md @@ -21,7 +21,7 @@ The basic digging time groups determine by which tools a node can be dug. * `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb * `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb * `shearsy=1`: Diggable by shears, and this node is *not* wool -* `shearsy=wool=1`: Diggable by shears, and this node is wool +* `shearsy_wool=1`: Diggable by shears, and this node is wool * `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 @@ -41,6 +41,7 @@ Please read to learn how digging times * `flammable=-1` Does not get destroyed by fire * `fire_encouragement`: How quickly this block catches fire * `fire_flammability`: How fast the block will burn away +* `path_creation_possible=1`: Node can be turned into grass path by using a shovel on it * `spreading_dirt_type=1`: A dirt-type block with a cover (e.g. grass) which may spread to neighbor dirt blocks * `dirtifies_below_solid=1`: This node turns into dirt immediately when a solid or dirtifier node is placed on top * `dirtifier=1`: This node turns nodes the above group into dirt when placed above @@ -56,6 +57,7 @@ Please read to learn how digging times * `no_eat_delay=1`: Only for foodstuffs. When eating this, all eating delays are ignored. * `can_eat_when_full=1`: Only for foodstuffs. This item can be eaten when the user has a full hunger bar * `attached_node_facedir=1`: Like `attached_node`, but for facedir nodes +* `supported_node=1`: Like `attached_node`, but can be placed on any nodes that do not have the `drawtype="airlike"` attribute. * `cauldron`: Cauldron. 1: Empty. 2-4: Water height * `anvil`: Anvil. 1: No damage. 2-3: Higher damage levels * `no_rename=1`: Item cannot be renamed by anvil @@ -71,6 +73,9 @@ Please read to learn how digging times * `coral_block=X`: Coral block (1 = alive, 2 = dead) * `coral_species=X`: Specifies the species of a coral; equal X means equal species * `set_on_fire=X`: Sets any (not fire-resistant) mob or player on fire for X seconds when touching +* `compostability=X`: Item can be used on a composter block; X (1-100) is the % chance of adding a level of compost +* `leaves=X`: Node will spotaneously decay if no tree trunk nodes remain within 6 blocks distance. +* `leaves_orphan`: See above, these nodes are in the process of decayed. #### Footnotes @@ -99,6 +104,8 @@ Please read to learn how digging times * `water_bucket=1`: Bucket containing a liquid of group “water” * `enchantability=X`: How good the enchantments are the item gets (1 equals book) * `enchanted=1`: The item is already enchanted, meaning that it can't be enchanted using an enchanting table +* `cobble=1`: Cobblestone of any kind +* `soul_block`: Fire burning on these blocks turns to soul fire, can be used to craft soul torch ### Material groups @@ -149,7 +156,7 @@ These groups are used mostly for informational purposes * `trapdoor=2`: Open trapdoor * `glass=1`: Glass (full cubes only) * `rail=1`: Rail -* `music_record`: Music Disc (rating is track ID) +* `music_record`: Item is Music Disc * `tnt=1`: Block is TNT * `boat=1`: Boat * `minecart=1`: Minecart @@ -200,6 +207,9 @@ These groups are used mostly for informational purposes * `building_block=1`: Block is a building block * `deco_block=1`: Block is a decorational block +* `blast_furnace_smeltable=1` : Item or node is smeltable by a blast furnace +* `smoker_cookable=1` : Food is cookable by a smoker. + ## Fake item groups These groups put similar items together which should all be treated by the gameplay or the GUI as a single item. diff --git a/HOW_TO_PLAY.md b/HOW_TO_PLAY.md new file mode 100644 index 000000000..bc6cad1a5 --- /dev/null +++ b/HOW_TO_PLAY.md @@ -0,0 +1,21 @@ +Survive, farm, build, explore, play with friends, and do much more. Inspired by a well known block game, pushing beyond. + +How to play: + +#### Download Minetest +- Navigate to https://www.minetest.net/ to download the client. +- Once installed, open and select the "Content" tab + +#### Install MineClone2 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 +- 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) +- Click "New", give your world a name +- You can leave seed blank or put in a word of your choice +- Select your new world +- Click "Play Game" and enjoy! \ No newline at end of file diff --git a/LEGAL.md b/LEGAL.md new file mode 100644 index 000000000..aace346bf --- /dev/null +++ b/LEGAL.md @@ -0,0 +1,52 @@ +# Legal information +This is a fan game, not developed or endorsed by Mojang AB. + +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. + +MineClone 2 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 (in the LICENSE.txt file) for more +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. + +MineClone 2 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. + +## License of media (textures and sounds) +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]. +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/) + +All other files, unless mentioned otherwise, fall under: +Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +See README.txt in each mod directory for detailed information about other authors. + diff --git a/MISSING_ENGINE_FEATURES.md b/MISSING_ENGINE_FEATURES.md deleted file mode 100644 index fddb89f6c..000000000 --- a/MISSING_ENGINE_FEATURES.md +++ /dev/null @@ -1,40 +0,0 @@ -# Missing features in Minetest to recreate Minecraft features - -A side goal of the MineClone 2 project is to find any shortcomings of Minetest which make it impossible to recreate a Minecraft feature exactly. -This file lists some of the missing features in Minetest which MineClone 2 would require. - -## No workaround possible -For these features, no easy Lua workaround could be found. - -### Lua API -#### Tools/wielded item -- “Lock” hotbar for a brief time after using an item, making it impossible to switch item or to attach/mine/build until the delay is over (For eating with delay) -- Tool charging: Holding down the mouse and releasing it, applying a “power level” (For bow and arrows, more charge = higher arrow range) ([issue 5212](https://github.com/minetest/minetest/issues/5212)) -- [Dual Wielding](http://minecraft.gamepedia.com/Dual_wield) -- Eating/drinking animation ([issue 2811](https://github.com/minetest/minetest/issues/2811)) - -#### Nodes -- Light level 15 for nodes (not sunlight) -- Nodes makes light level drop by 2 or or more per node ([issue 5209](https://github.com/minetest/minetest/issues/5209)) - -## Interface -- Inventory: Hold down right mouse button while holding an item stack to drop items into the slots as you move the mouse. Makes crafting MUCH faster -- Sneak+Leftclick on crafting output crafts as many items as possible and immediately puts it into the player inventory ([issue 5211](https://github.com/minetest/minetest/issues/5211)) -- Sneak+click puts items in different inventories depending on the item type (maybe group-based)? Required for sneak-clicking to armor slots - -## Workaround theoretically possible -For these features, a workaround (or hack ;-)) by using Lua is theoretically possible. But engine support would be clearly better, more performant, more reliable, etc. - -### Lua API -#### Nodes -- Change walking speed on block (soul sand) -- Change jumping height on block (soul sand), -- Change object movement speed *through* a block, but for non-liquids (for cobweb) -- Add `on_walk_over` event -- Set frequency in which players lose breath. 2 seconds are hardcoded in Minetest, in Minecraft it's 1 second -- Set damage frequency of `damage_per_second`. In Minecraft many things damage players every half-second rather than every second -- Possible to damage players directly when they are with the head inside. This allows to add Minecraft-like suffocation -- Sneak+click on inventory slot should be able to put items into additional “fallback inventories” if the first inventory is full. Useful for large chests - -#### Nice-to-haye -- Utility function to rotate pillar-like nodes, requiring only 3 possible orientations (X, Y, Z). Basically this is `minetest.rotate_node` but with less orientations; the purpur pillar would mess up if a mirrored rotation would be possible. This is already implemented in MCL2, See `mcl_util` for more infos diff --git a/MODELS.md b/MODELS.md new file mode 100644 index 000000000..4b9094c33 --- /dev/null +++ b/MODELS.md @@ -0,0 +1,70 @@ +#Models in Minetest/Mineclone2 + +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. + +## 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 + +###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. + +Download blender [Here](https://www.blender.org/download/) + +### .b3d addon for blender + +Blitz 3D (.b3d) Is one of the main animated model formats used for entities in the minetest engine. It cannot be imported to blender without a plugin called "Import-Export:Bitz 3D format (.b3d)". + +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 + +###Animated, skinned models +* Blitz 3D files (.b3d) + +* Microsoft DirectX (.x) (binary & text, compression is not supported) + +###Static meshes +* Wavefront OBJ (.obj) + +Note: The sometimes accompanying .mtl files are not supported and can safely be deleted. + +Note: Do not use .b3d and .x files for static meshes at the moment, Minetest currently spawns animated mesh scene nodes for these, which may result in reduced performance. + +### Supported texture formats + +* .png + +* .jpg + +* .bmp (depreciated, please use .png or .jpg) + +* .tga (depreciated, please use .png or .jpg) + +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 + +###B3D +* [+] Binary format means a small size + +* [-] Difficult to postprocess after exporting + +* [-] Difficult to debug problems + +###X (text version) +* [+] Can be parsed easily with lua scripts + +* [+] Can be easily generated by scripts + +* [+] Easy to debug issues (you can just read it) + +* [+] Can be optimized by quantizing some data + +* [-] Blender exporter is kinda buggy and inefficient + +* [-] Probably still bigger than an equivalent .b3d + +Note: Avoid using the binary X format! It's actually just a tokenized version of the ASCII representation, and may actually be less efficient than a sufficiently optimized text .x file! diff --git a/README.md b/README.md index 12f5658e2..7221e6163 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -# MineClone 2 +# MineClone2 An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. Developed by many people. Not developed or endorsed by Mojang AB. -Version: 0.70.0 - ### Gameplay You start in a randomly-generated world made entirely of cubes. You can explore the world and dig and build almost every block in the world to create new @@ -65,40 +63,46 @@ map builders. They can not be obtained in-game or in the creative inventory. Use the `/giveme` chat command to obtain them. See the in-game help for an explanation. -#### Incomplete items -These items do not work yet, but you can get them with `/giveme` for testing: - -* Minecart with Chest: `mcl_minecarts:chest_minecart` -* Minecart with Furnace: `mcl_minecarts:furnace_minecart` -* Minecart with Hopper: `mcl_minecarts:hopper_minecart` -* Minecart with Command Block: `mcl_minecarts:command_block_minecart` - ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or +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 MineClone 2 in development versions of Minetest. +There is no support for running MineClone2 in development versions of Minetest. -To install MineClone 2 (if you haven't already), move this directory into the +To install MineClone2 (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. -## Project description -The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. +## Useful links +The MineClone2 repository is hosted at Mesehub. To contribute or report issues, head there. -* **Target of development: Minecraft, PC Edition, version 1.11** (later known as “Java Edition”) -* Features of later Minecraft versions might sneak in, but they have a low priority -* In general, Minecraft is aimed to be cloned as good as Minetest currently permits (no hacks) -* Cloning the gameplay has highest priority -* MineClone 2 will use different graphics and sounds, but with a similar style -* Cloning the interface has no priority. It will only be roughly imitated -* Limitations found in Minetest will be written down and reported in the course of development +* Mesehub: +* Discord: +* YouTube: +* IRC: +* Matrix: +* Reddit: +* Minetest forums: +* ContentDB: +* OpenCollective: + +## 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. ## Completion status -This game is currently in **alpha** stage. -It is playable, but unfinished, many bugs are to be expected. -Backwards-compability is *not* guaranteed, updating your world might cause small and -big bugs (such as “missing node” errors or even crashes). +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. The following main features are available: @@ -113,7 +117,7 @@ The following main features are available: * Most blocks in the overworld * Water and lava * Weather -* 28 biomes +* 28 biomes + 5 Nether Biomes * The Nether, a fiery underworld in another dimension * Redstone circuits (partially) * Minecarts (partial) @@ -127,7 +131,7 @@ The following main features are available: * Clock * Compass * Sponge -* Slime block (does not interact with redstone) +* Slime block * Small plants and saplings * Dyes * Banners @@ -139,19 +143,19 @@ The following main features are available: * Creative inventory * Farming * Writable books -* A few server commands +* Commands +* Villages +* The End * And more! The following features are incomplete: -* Generated structures (especially villages) * Some monsters and animals * Redstone-related things -* The End -* Special minecarts +* Some special minecarts (hopper and chest minecarts work) * A couple of non-trivial blocks and items -Bonus features (not found in Minecraft 1.11): +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 @@ -164,6 +168,9 @@ Bonus features (not found in Minecraft 1.11): * Nether Brick Fence Gate * Red Nether Brick Fence * Red Nether Brick Fence Gate +* Structure replacements - these small variants of Minecraft structures serve as replacements until we can get large structures working: + * Woodland Cabin (Mansions) + * Nether Outpost (Fortress) Technical differences from Minecraft: @@ -176,142 +183,14 @@ Technical differences from Minecraft: * Different textures (Pixel Perfection) * Different sounds (various sources) * Different engine (Minetest) +* Different easter eggs -… and finally, MineClone 2 is free software (“free” as in “freedom”)! - -## Reporting bugs -Please report all bugs and missing Minecraft features here: - - +… and finally, MineClone2 is free software (“free” as in “freedom”)! ## Other readme files * `LICENSE.txt`: The GPLv3 license text * `CONTRIBUTING.md`: Information for those who want to contribute -* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which MineClone 2 would need for improvement * `API.md`: For Minetest modders who want to mod this game - -## Credits -There are so many people to list (sorry). Check out the respective mod directories for details. This section is only a rough overview of the core authors of this game. - -### Coding -* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main programmer of most mods (retired) -* davedevils: Creator of MineClone on which MineClone 2 is based on -* [ex-bart](https://github.com/ex-bart): Redstone comparators -* [Rootyjr](https://github.com/Rootyjr): Fishing rod and bugfixes -* [aligator](https://github.com/aligator): Improvement of doors -* [ryvnf](https://github.com/ryvnf): Explosion mechanics -* MysticTempest: Bugfixes -* [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand -* kay27 : Experience system, bugfixes, optimizations (Current maintainer) -* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer) -* 2mac: Fix bug with powered rail -* Lots of other people: TO BE WRITTEN (see mod directories for details) - -#### Mod credits (summary) - -* `controls`: Arcelmi -* `flowlib`: Qwertymine13 -* `walkover`: lordfingle -* `drippingwater`: kddekadenz -* `mobs_mc`: maikerumine, 22i and others -* `awards`: rubenwardy -* `screwdriver`: RealBadAngel, Maciej Kastakin, Minetest contributors -* `xpanes`: Minetest contributors -* `mesecons` mods: Jeija and contributors -* `wieldview`: Stuart Jones -* `mcl_meshhand`: Based on `newhand` by jordan4ibanez -* `mcl_mobs`: Based on Mobs Redo [`mobs`] by TenPlus1 and contributors -* Most other mods: Wuzzy - -Detailed credits for each mod can be found in the individual mod directories. - -### Graphics -* [XSSheep](http://www.minecraftforum.net/members/XSSheep): Main author; creator of the Pixel Perfection resource pack of Minecraft 1.11 -* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main menu imagery and various edits and additions of texture pack -* [kingoscargames](https://github.com/kingoscargames): Various edits and additions of existing textures -* [leorockway](https://github.com/leorockway): Some edits of mob textures -* [xMrVizzy](https://minecraft.curseforge.com/members/xMrVizzy): Glazed terracotta (textures are subject to be replaced later) -* yutyo : MineClone 2 logo -* Other authors: GUI images - -### Translations -* Wuzzy: German -* Rocher Laurent : French -* wuniversales: Spanish -* kay27 : Russian - -### Models -* [22i](https://github.com/22i): Creator of all models -* [tobyplowy](https://github.com/tobyplowy): UV-mapping fixes to said models - -### Sounds and music -Various sources. See the respective mod directories for details. - -### Special thanks - -* davedevils for starting MineClone, the original version of this game -* Wuzzy for starting and maintaining MineClone2 for several years -* celeron55 for creating Minetest -* Minetest's modding community for providing a huge selection of mods, some of which ended up in MineClone 2 -* Jordach for the jukebox music compilation from Big Freaking Dig -* 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 -* XSSheep for creating the Pixel Perfection resource pack -* [22i](https://github.com/22i) for providing great models and support -* [maikerumine](http://github.com/maikerumine) for kicking off mobs and biomes - -## Info for programmers -You find interesting and useful infos in `API.md`. - -## Legal information -This is a fan game, not developed or endorsed by Mojang AB. - -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 kay27, EliasFleckenstein, Wuzzy, davedevils and countless others) -is an imitation of Minecraft. - -MineClone 2 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 (in the LICENSE.txt file) for more -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. - -MineClone 2 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. - -### License of media (textures and sounds) -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]. -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/) - -All other files, unless mentioned otherwise, fall under: -Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) -http://creativecommons.org/licenses/by-sa/3.0/ - -See README.txt in each mod directory for detailed information about other authors. +* `LEGAL.md`: Legal information +* `CREDITS.md`: List of everyone who contributed diff --git a/README_locale/README.fr.md b/README_locale/README.fr.md new file mode 100644 index 000000000..9317f09f3 --- /dev/null +++ b/README_locale/README.fr.md @@ -0,0 +1,173 @@ +# 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. + +### 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 + +* Jeu de type bac-à-sable, sans objetifs +* Survie : combattez des monstres hostiles et la faim +* Creusez pour du minerai et d'autres trésors +* Magie : gagnez de l'expérience et enchantez les outils +* Utilisez les blocs ramassés pour construire de magnifiques bâtiments, votre imagination est la seule limite +* Ramassez des fleurs (et d'autres sources de teinture) et colorez votre monde +* Trouvez des graines et commencez à cultiver +* Trouvez ou fabriquez des centaines d'objets +* Construisez un réseau ferroviaire complexe et amusez-vous avec les wagonnets +* En mode créatif vous pouvez construire presque n'importe quoi gratuitement et sans limite + +## Comment jouer (démarrer rapidement) +### 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** +* **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 ! +* Continuez à jouer comme vous voulez. Amusez-vous ! + +### 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 +* Récoltez les plantes une fois matûres +* Les terres agricoles proche de l'eau deviennent humides et accélèrent la croissance + +### Four +* Fabriquez un four +* Le four permet d'obtenir plus d'objets +* L'emplacement du haut doit contenir un objet fondable (par ex : minerai de fer) +* L'emplacement du bas doit contenir un objet combustible (par ex : charbon) +* Voir le guide d'artisanat pour en apprendre plus sur les objets fondables et combustibles + +### Aide supplémentaire +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. + +* Barrière : `mcl_core:barrier` + +Utilisez la commande de chat `/giveme` pour les obtenir. Voir l'aide interne au jeu pour une explication. + +## 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. + +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. + +## Liens utiles +Le dépôt de MineClone2 est hébergé sur Mesehub. Pour contribuer ou signaler des problèmes, allez là-bas. + +* Mesehub : +* Discord : +* YouTube : +* IRC : +* Matrix : +* Reddit : +* Forums Minetest : +* ContentDB : +* OpenCollective : + +## 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. + +## 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. + +Les principales fonctionnalités suivantes sont disponibles : + +* Outils, armes +* Armure +* Système de fabrication : grille 2x2, établi (grille 3x3), four, incluant un guide de fabrication +* Coffres, grands coffres, coffre ender, boites de Shulker +* Fours, entonnoirs +* Faim +* La plupart des monstres et animaux +* Tous les minerais de Minecraft +* La plupart des blocs de l'overworld +* Eau et lave +* Météo +* 28 biomes + 5 biomes du Nether +* Le Nether, monde souterrain brûlant dans une autre dimension +* Circuits Redstone (partiel) +* Effets de Statut (partiel) +* Expérience +* Enchantement +* Brassage, potions, flèches trempées (partiel) +* Bâteaux +* Feu +* Blocs de construction : escaliers, dalles, portes, trappes, barrières, portillons, murets +* Horloge +* Boussole +* Éponge +* 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 +* Juke-boxes +* Lits +* Menu d'inventaire +* Inventaire créatif +* Agriculture +* Livres pour écrire +* Commandes +* Villages +* L'End +* et plus ! + +Les fonctionnalités suivantes sont incomplètes : + +* Certains monstres et animaux +* Certains composants de Redstone +* Wagonnets spéciaux +* Quelques blocs et objets non-triviaux + +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 +* 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 + * Plus de dalles et d'escaliers + * Portillon en briques du Nether + * Barrière en briques du Nether rouges + * Portillon en briques du Nether rouges +* Structures de remplacement - ces petites variantes de structures de Minecraft servent de remplacement en attendant qu'on arrive à en faire fonctionner de plus grandes : + * Cabine dans les bois (Manoir des bois) + * Avant-poste du Nether (Forteresse) + +Différences techniques avec Minecraft : + +* Limite en hauteur de 31000 blocs (bien plus grand que Minecraft) +* Taille horizontale du monde 62000×62000 blocs (bien plus petit que Minecraft mais toujours très grand) +* Toujours assez incomplet et buggé +* Des blocs, objets, ennemis et fonctionnalités manquent +* Quelques objets ont des noms légèrement différents pour être plus faciles à distinguer +* Des musiques différentes pour le juke-boxe +* Des textures différentes (Pixel Perfection) +* Des sons différents (sources diverses) +* Un moteur de jeu différent (Minetest) +* Des bonus cachés différents + +...et enfin MineClone2 est un logiciel libre ! + +## Autres fichiers readme + +* `LICENSE.txt` : Le texte de la licence GPLv3 +* `CONTRIBUTING.md` : Information pour ceux qui veulent contribuer +* `API.md` : Pour les modders Minetest qui veulent modder ce jeu +* `LEGAL.md` : Information légale +* `CREDITS.md` : Liste de toutes les personnes qui ont contribué diff --git a/README_locale/README.zh_TW.md b/README_locale/README.zh_TW.md new file mode 100644 index 000000000..eb7540247 --- /dev/null +++ b/README_locale/README.zh_TW.md @@ -0,0 +1,324 @@ +# MineClone 2 +一個非官方的Minetest遊戲,遊玩方式和Minecraft類似。由davedevils從MineClone分拆。 +由許多人開發。並非由Mojang Studios開發。 + +版本:0.71.0 + +### 遊玩 +你開始在一個完全由方塊隨機生成的世界裡。你可以探索這個世界,挖掘和建造世界上幾乎所有的方塊,以創造新的結構。你可以選擇在「生存模式」中進行遊戲,在這個模式中,你必須與怪物戰鬥,飢餓求生,並在遊戲的其他各個環節中慢慢進步,如採礦、養殖、建造機器等等。 + +或者你也可以在「創造模式」中玩,在這個模式中,你可以瞬間建造大部分東西。 +#### Gameplay summary + +* 沙盒式遊戲,沒有明確目標 +* 生存:與怪物和飢餓搏鬥 +* 挖礦來獲得礦物和寶物 +* 附魔:獲得經驗值並以附魔強化你的工具 +* 使用收集的方塊來創造偉大的建築 +* 收集鮮花(和其他染料來源),令世界多姿多彩 +* 找些種子並開始耕種 +* 尋找或合成數百個物品之一 +* 建立一個鐵路系統,並從礦車中得到樂趣 +* 用紅石電路建造複雜的機器 +* 在創造模式下,你幾乎可以免費建造任何東西,而且沒有限制。 + +## 如何開始 +### 開始生存 +* **挖樹幹**直到其破裂並收集木材 +* 將木頭**放入2×2的格子中**(你的物品欄中的「合成格子」),然後製作4塊木材。 +* 將4塊木材按2×2的形狀擺放在合成格子裡,製作成合成臺。 +* **右鍵單擊製作臺**以獲得3×3製作網格,製作更複雜的東西 +* 使用**合成指南**(書形圖標)了解所有可能的合成方式 +* **製作一個木鎬**,這樣你就可以挖石頭了。 +* 不同的工具可以打破不同種類的方塊。試試吧! +* 繼續玩你想玩的。盡情享受吧! + +### 耕種 +* 找到種子 +* 合成鋤頭 +* 用鋤頭右鍵點擊泥土或類似的方塊,創建農田 +* 將種子放在農田上,看著它們長出來 +* Collect plant when fully grown +* If near water, farmland becomes wet and speeds up growth + +### Furnace +* Craft furnace +* 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 + +### Additional help +More help about the gameplay, blocks items and much more can be found from inside +the game. You can access the help from your inventory menu. + +### Special items +The following items are interesting for Creative Mode and for adventure +map builders. They can not be obtained in-game or in the creative inventory. + +* Barrier: `mcl_core:barrier` + +Use the `/giveme` chat command to obtain them. See the in-game help for +an explanation. + +#### Incomplete items +These items do not work yet, but you can get them with `/giveme` for testing: + +* Minecart with Chest: `mcl_minecarts:chest_minecart` +* Minecart with Furnace: `mcl_minecarts:furnace_minecart` +* Minecart with Hopper: `mcl_minecarts:hopper_minecart` +* Minecart with Command Block: `mcl_minecarts:command_block_minecart` + +## Installation +This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or +later). So you need to install Minetest first. Only stable versions of Minetest +are officially supported. +There is no support for running MineClone 2 in development versions of Minetest. + +To install MineClone 2 (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. + +## Project description +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功能。 +* 後期Minecraft版本的功能可能會偷偷加入,但它們的優先級較低。 +* 總的來說,Minecraft的目標是在Minetest目前允許的情況下進行克隆。 +* 克隆Minecraft是最優先的。 +* MineClone2將使用不同的圖形和聲音,但風格相似。 +* 克隆界面沒有優先權。只會被粗略地模仿。 +* 在Minetest中發現的局限性將在開發過程中被記錄和報告。 + +## 完成程度 +該遊戲目前處於**alpha**階段。 +它是可玩的,但尚未完成,預計會出現許多錯誤。 +向後兼容性是**不能保證的**,更新你的世界可能會造成大大小小的bug(比如「缺少節點」的錯誤甚至崩潰)。 + +已經實現以下功能: + +* 工具,武器 +* 盔甲 +* 合成和熔煉系統:2×2 合成格, 合成臺 (3×3 合成格), 熔爐, 合成教學 +* 儲物箱,大型儲物箱,終界箱和界伏盒 +* 熔爐, 漏斗 +* 飢餓和飽食 +* 大多數怪物和動物 +* Minecraft 1.12中的所有礦物 +* 主世界的大部分方塊 +* 水和岩漿 +* 天氣 +* 28個生態域 +* 地獄,熾熱的維度 +* 紅石電路(部分) +* 礦車(部分) +* 狀態效果(部分) +* 經驗系統 +* 附魔 +* 釀造,藥水,藥水箭(部分) +* 船 +* 火 +* 建築方塊:樓梯、半磚、門、地板門、柵欄、柵欄門、牆。 +* 時鐘 +* 指南針 +* 海綿 +* 史萊姆方塊(不與紅石互動) +* 小植物和樹苗 +* 染料 +* 旗幟 +* 裝飾方塊:玻璃、染色玻璃、玻璃片、鐵柵欄、陶土(和染色版本)、頭顱等 +* 物品展示框 +* 唱片機 +* 床 +* 物品欄 +* 創造模式物品欄 +* 生產 +* 書和羽毛筆 +* 一些服務器命令 +* 還有更多! + +以下是不完整的特性: + +* 生成結構(特別是村莊) +* 一些怪物和動物 +* 紅石系統 +* 終界 +* 特殊的礦車 +* 一些不簡單的方塊和物品。 + +額外功能(在Minecraft 1.11中沒有)。 + +* 內置合成指南,向你展示製作和熔煉的配方 +* 遊戲中的幫助系統包含了大量關於遊戲基礎知識、方塊、物品等方面的幫助。 +* 臨時製作配方。它們的存在只是為了在你不在創造模式下時,提供一些其他無法獲得的物品。這些配方將隨著開發的進行和更多功能的出現而被移除。 +* v6地圖生成器中箱子裡的樹苗。 +* 完全可修改(得益於Minetest強大的Lua API)。 +* 新的方塊和物品: + * 查找工具,顯示觸及事物的幫助 + * 更多的半磚和樓梯 + * 地獄磚柵欄門 + * 紅地獄磚柵欄 + * 紅地獄磚柵欄門 + +與Minecraft的技性術差異: + +* 高度限制為31000格(遠高於Minecraft) +* 水平世界大小約為62000×62000格(比Minecraft中的小得多,但仍然非常大)。 +* 仍然非常不完整和有問題 +* 塊、物品、敵人和其他功能缺失。 +* 一些項目的名稱略有不同,以便於區分。 +* 唱片機的音樂不同 +* 不同的材質(像素完美) +* 不同的聲音(各種來源) +* 不同的引擎(Minetest) + +...最後,MineClone2是自由軟件! + +## 錯誤報告 +請在此處報告所有錯誤和缺少的功能: + + + +## Chating with the community +我們有Discord交流羣: + + + + +## Other readme files + +* `LICENSE.txt`:GPLv3許可文本 +* `CONTRIBUTING.md`: 為那些想參與貢獻的人提供資訊 +* `MISSING_ENGINE_FEATURES.md`: MineClone2需要改进,Minetest中缺失的功能列表。 +* `API.md`: 關於MineClone2的API + +## 參與者 +有這麼多人要列出(抱歉)。詳情請查看各mod目錄。本節只是粗略地介紹了本遊戲的核心作者。 + +### 程式碼 +* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082):大多數mod的主要程序員(已退休) +* davedevils:MineClone 2的原型——「MineClone」的創造者 +* [ex-bart](https://github.com/ex-bart):紅石比較器 +* [Rootyjr](https://github.com/Rootyjr):釣竿和錯誤修復 +* [aligator](https://github.com/aligator):改進門 +* [ryvnf](https://github.com/ryvnf):爆炸物理 +* MysticTempest:錯誤修復 +* [bzoss](https://github.com/bzoss):狀態效果,釀造,藥水 +* kay27 :經驗系統,錯誤修復和優化(當前維護者) +* [EliasFleckenstein03](https://github.com/EliasFleckenstein03):終界水晶,附魔,燃燒的怪物/玩家,箱子的動畫和錯誤修復(當前維護者) +* epCode:更好的玩家動畫,新徽標 +* 2mac:修復動力鐵軌的錯誤 +* 更多:待篇寫 (請查看各mod目錄) + +#### Mod(概括) + +* `controls`: Arcelmi +* `flowlib`: Qwertymine13 +* `walkover`: lordfingle +* `drippingwater`: kddekadenz +* `mobs_mc`: maikerumine, 22i and others +* `awards`: rubenwardy +* `screwdriver`: RealBadAngel, Maciej Kastakin, Minetest contributors +* `xpanes`: Minetest contributors +* `mesecons` mods: Jeija and contributors +* `wieldview`: Stuart Jones +* `mcl_meshhand`: Based on `newhand` by jordan4ibanez +* `mcl_mobs`: Based on Mobs Redo [`mobs`] by TenPlus1 and contributors +* 大多其他的Mod: Wuzzy + +每个mod的详细參與者可以在各个mod目录中找到。 + +### 圖形 +* [XSSheep](http://www.minecraftforum.net/members/XSSheep):主要作者;Minecraft 1.11的Pixel Perfection资源包的制作者 +* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082):主菜單圖像和各種編輯和添加的材質包 +* [kingoscargames](https://github.com/kingoscargames):現有材質的各種編輯和添加 +* [leorockway](https://github.com/leorockway):怪物紋理的一些編輯 +* [xMrVizzy](https://minecraft.curseforge.com/members/xMrVizzy):釉陶(材質以後會被替換) +* yutyo :MineClone2標志 +* 其他:GUI圖片 + +### 翻譯 +* Wuzzy:德語 +* Rocher Laurent :法語 +* wuniversales:西班牙語 +* kay27 :俄語 +* [Emoji](https://toyshost2.ddns.net):繁體中文 + +### 模型 +* [22i](https://github.com/22i):所有模型的作者 +* [tobyplowy](https://github.com/tobyplowy):對上述模型進行UV映射修復 + +### 聲音和音樂 +多種來源。 有關詳細信息,請參見相應的mod目錄。 + +### 特殊感謝 + +* Wuzzy,感謝他啟動和維護MineClone2多年。 +* celeron55,創建Minetest。 +* Minetest的社區提供了大量的mods選擇,其中一些最終被納入MineClone 2。 +* Jordach,為《Big Freaking Dig》的唱片機音樂合輯而來 +* 花了太多時間為Minecraft Wiki寫作的工作狂。它是創建這個遊戲的寶貴資源。 +* Notch和Jeb是Minecraft背后的主要力量 +* XSSheep用於創建Pixel Perfection資源包。 +* [22i](https://github.com/22i) 提供出色的模型和支持 +* [maikerumine](http://github.com/maikerumine) 揭開生物和生物群落的序幕 + +## 給程序員的信息 +你可以在「API.md」中找到有趣和有用的信息。 + +## 法律信息 +這是一款粉絲開發的遊戲,並非由Mojang AB開發或認可。 + +複製是一種愛的行為。請複制和分享! <3 +下面是詳細的法律條文,有需要的朋友可以參考。 + +### License of source code +``` +MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others) +is an imitation of Minecraft. + +MineClone 2 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 (in the LICENSE.txt file) for more +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. + +MineClone 2 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. +``` + +### License of media (textures and sounds) +``` +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]. +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/) + +All other files, unless mentioned otherwise, fall under: +Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) +http://creativecommons.org/licenses/by-sa/3.0/ + +See README.txt in each mod directory for detailed information about other authors. +``` diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 000000000..4d82ab9e3 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,75 @@ +### Standard Release + +#File to document release steps with a view to evolving into a script + +#Update CREDITS.md +#Update version in game.conf + +lua tools/generate_ingame_credits.lua + +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. + +### 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. + +##### Inform people + +* Add a comment to the forum post with the release number and what is involved, and maintainer will update main post. +* Add a comment in Discord announcement \ No newline at end of file diff --git a/TEXTURES.md b/TEXTURES.md new file mode 100644 index 000000000..157965ae6 --- /dev/null +++ b/TEXTURES.md @@ -0,0 +1,57 @@ +# Making Textures In Mineclone2 + +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. + +## 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. + +## 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 + +## Recommended Software + +### GIMP + +GIMP (GNU Image Manipulation Program) is a very popular and free image editing software supported on Windows, MacOS, and most Linux distributions. It is recommended to use GIMP to create and modify textures within the minetest engine. + +Download GIMP [here](http://gimp.org/) + +# Getting Started +## Creating a new file +the first thing to do is open GIMP and create a new file to work in by opening the File menu and choosing "New". + +Choose width of 16 and height of 16 for the image size. While higher resolution textures are possible, The default size is 16x16. It is recommended you use this size as well, as it is universally supported on all systems. + +## Zoom In +Next, you'll want to zoom in as the canvas is very small at the default zoom level. To do this either use CTRL + mousewheel, +/-, or navigate to the View menu > zoom > zoom in + +## Configure Grid +Now, we'll want to turn on the grid. Open the edit menu and enable the 'show grid' option. + +The default grid size is 10 pixels, we want to change it to a 1 pixel grid. Go to the Image menu and choose 'configure grid. + +In the Spacing section, change both the Horizontal and Vertical pixel settings to 1.00 then click ok and the grid will update. + +## Pencil Tool & Color Picking +The most useful brush type for pixel art is the Pencil tool. Its nested under the paintbrush tool in the toolbox, or you can use the keyboard shortcut 'N'. + +Once the pencil tool is selected, navigate to the sliders on the left side of the canvas and change brush size to 1 pixel. + +Now choose a color! You can do this by clicking on the two colored squares under the toolbox. The Color Picker tool is also a good option if you already have a reference image for color palette. + +## How to export optimally + +Once you have finished up a texture and are ready to export it, navigate to the file menu > export as... and make sure the file name extention is .png + +After clicking 'Export', a menu will appear with a bunch of options checked. Make sure to uncheck all of these options!!! This will drastically reduce the file size from multiple kilobytes to a couple of hundred bytes. Finally click 'Export' one more time. + +### Further optimization with OptiPNG +For those running a GNU/linux distribution, you most likely have the 'optipng' command available to you. If it does not come with your system by default, the software homepage can be found [here](https://optipng.sourceforge.net/) where you can download and install from source. + +First, Open up the terminal in the directory where your exported texture is located (or navigate to the directory with the 'cd your/directory/path/to/textures'), then run this command +``` +optipng -o7 -zm1-9 -nc -clobber -strip all *.png +``` +This will further optimize all the textures in the directory. + +NOTE: If you would like to further edit a texture that has been optipng'd in GIMP, you must manually set the color palette back to RBG after opening. Navigate to Image menu > Mode > select RGB diff --git a/description.txt b/description.txt index 805bdb217..922f5dceb 100644 --- a/description.txt +++ b/description.txt @@ -1 +1 @@ -A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.11. This is a work in progress! Expect bugs! +A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. diff --git a/game.conf b/game.conf index db7357702..a7716f284 100644 --- a/game.conf +++ b/game.conf @@ -1,2 +1,4 @@ -name = MineClone 2 +title = MineClone 2 description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more. +disallowed_mapgens = v6 +version=0.84.0-SNAPSHOT \ No newline at end of file diff --git a/menu/Header.blend b/menu/Header.blend new file mode 100644 index 000000000..78a9f6158 Binary files /dev/null and b/menu/Header.blend differ diff --git a/menu/HeaderTemplate.png b/menu/HeaderTemplate.png new file mode 100644 index 000000000..ceddaa1f6 Binary files /dev/null and b/menu/HeaderTemplate.png differ diff --git a/menu/Logo.blend b/menu/Logo.blend new file mode 100644 index 000000000..08284ef67 Binary files /dev/null and b/menu/Logo.blend differ diff --git a/menu/background.1.png b/menu/background.1.png new file mode 100644 index 000000000..07e1f6672 Binary files /dev/null and b/menu/background.1.png differ diff --git a/menu/background.10.png b/menu/background.10.png new file mode 100644 index 000000000..5f63b0ea1 Binary files /dev/null and b/menu/background.10.png differ diff --git a/menu/background.2.png b/menu/background.2.png new file mode 100644 index 000000000..3050cf411 Binary files /dev/null and b/menu/background.2.png differ diff --git a/menu/background.3.png b/menu/background.3.png new file mode 100644 index 000000000..a4d1c4358 Binary files /dev/null and b/menu/background.3.png differ diff --git a/menu/background.4.png b/menu/background.4.png new file mode 100644 index 000000000..c50332f6f Binary files /dev/null and b/menu/background.4.png differ diff --git a/menu/background.5.png b/menu/background.5.png new file mode 100644 index 000000000..1c776a88e Binary files /dev/null and b/menu/background.5.png differ diff --git a/menu/background.6.png b/menu/background.6.png new file mode 100644 index 000000000..478c65912 Binary files /dev/null and b/menu/background.6.png differ diff --git a/menu/background.7.png b/menu/background.7.png new file mode 100644 index 000000000..56c30a08b Binary files /dev/null and b/menu/background.7.png differ diff --git a/menu/background.8.png b/menu/background.8.png new file mode 100644 index 000000000..ed285700c Binary files /dev/null and b/menu/background.8.png differ diff --git a/menu/background.9.png b/menu/background.9.png new file mode 100644 index 000000000..760aaa4e5 Binary files /dev/null and b/menu/background.9.png differ diff --git a/menu/background.png b/menu/background.png new file mode 100644 index 000000000..51bfb374e Binary files /dev/null and b/menu/background.png differ diff --git a/menu/footer.png b/menu/footer.png index 9207b26d3..fff8c3f64 100644 Binary files a/menu/footer.png and b/menu/footer.png differ diff --git a/menu/header.1.png b/menu/header.1.png new file mode 100644 index 000000000..5204a0d02 Binary files /dev/null and b/menu/header.1.png differ diff --git a/menu/header.2.png b/menu/header.2.png new file mode 100644 index 000000000..8b131302e Binary files /dev/null and b/menu/header.2.png differ diff --git a/menu/header.3.png b/menu/header.3.png new file mode 100644 index 000000000..dc618d7c6 Binary files /dev/null and b/menu/header.3.png differ diff --git a/menu/header.png b/menu/header.png index 5d34dd6a2..3c146f3cd 100644 Binary files a/menu/header.png and b/menu/header.png differ diff --git a/menu/icon.png b/menu/icon.png index e479dfff5..46b7475e3 100644 Binary files a/menu/icon.png and b/menu/icon.png differ diff --git a/menu/icon_big.png b/menu/icon_big.png new file mode 100644 index 000000000..ecdd62b78 Binary files /dev/null and b/menu/icon_big.png differ diff --git a/menu/icon_small.png b/menu/icon_small.png new file mode 100644 index 000000000..6e4497d32 Binary files /dev/null and b/menu/icon_small.png differ diff --git a/menu/overlay.1.png b/menu/overlay.1.png deleted file mode 100644 index 62790a202..000000000 Binary files a/menu/overlay.1.png and /dev/null differ diff --git a/menu/overlay.2.png b/menu/overlay.2.png deleted file mode 100644 index ad1de325a..000000000 Binary files a/menu/overlay.2.png and /dev/null differ diff --git a/menu/overlay.3.png b/menu/overlay.3.png deleted file mode 100644 index 390848476..000000000 Binary files a/menu/overlay.3.png and /dev/null differ diff --git a/menu/overlay.4.png b/menu/overlay.4.png deleted file mode 100644 index 2480f2c50..000000000 Binary files a/menu/overlay.4.png and /dev/null differ diff --git a/menu/overlay.5.png b/menu/overlay.5.png deleted file mode 100644 index 482ec23f0..000000000 Binary files a/menu/overlay.5.png and /dev/null differ diff --git a/menu/overlay.png b/menu/overlay.png deleted file mode 100644 index 5d4f51b6f..000000000 Binary files a/menu/overlay.png and /dev/null differ diff --git a/menu/theme.ogg b/menu/theme.ogg new file mode 100644 index 000000000..00644da4a Binary files /dev/null and b/menu/theme.ogg differ diff --git a/minetest.conf b/minetest.conf index 6b6a4d678..223587f4d 100644 --- a/minetest.conf +++ b/minetest.conf @@ -1,5 +1,8 @@ # This is a game specific minetest.conf file, do not edit +# If any of these settings are set in your minetest.conf file in ~/.minetest (Linux) or in the root directory of the game (Run in place/Windows) +# They will override these settings + # Basic game rules time_speed = 72 @@ -31,3 +34,14 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de # MCL2-specific stuff keepInventory = false + +# Performance settings +dedicated_server_step = 0.05 #tick rate +# abm_interval = 0.25 +# max_objects_per_block = 4096 +# max_packets_per_iteration = 10096 + +# Clientmodding to support official client +enable_client_modding = true +csm_restriction_flags = 0 +enable_mod_channels = true diff --git a/mods/CORE/_mcl_autogroup/README.txt b/mods/CORE/_mcl_autogroup/README.txt index b7068a0b3..11383f311 100644 --- a/mods/CORE/_mcl_autogroup/README.txt +++ b/mods/CORE/_mcl_autogroup/README.txt @@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes: 1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft. 2) Generating digging time group for all nodes based on node metadata (it's complicated) +This mod also requires another mod called “mcl_autogroup” to function properly. +“mcl_autogroup” exposes the API used to register digging groups, while this mod +uses those digging groups to set the digging time groups for all the nodes and +tools. + See init.lua for more infos. The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible. diff --git a/mods/CORE/_mcl_autogroup/depends.txt b/mods/CORE/_mcl_autogroup/depends.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/mods/CORE/_mcl_autogroup/description.txt b/mods/CORE/_mcl_autogroup/description.txt deleted file mode 100644 index dbc4f3186..000000000 --- a/mods/CORE/_mcl_autogroup/description.txt +++ /dev/null @@ -1 +0,0 @@ -MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/_mcl_autogroup/init.lua b/mods/CORE/_mcl_autogroup/init.lua index aabfa5906..1a259189b 100644 --- a/mods/CORE/_mcl_autogroup/init.lua +++ b/mods/CORE/_mcl_autogroup/init.lua @@ -1,169 +1,375 @@ ---[[ Mining times. Yeah, mining times … Alright, this is going to be FUN! +--[[ +This mod implements a HACK to make 100% sure the digging times of all tools +match Minecraft's perfectly. The digging times system of Minetest is very +different, so this weird group trickery has to be used. In Minecraft, each +block has a hardness and the actual Minecraft digging time is determined by +this: -This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly. -The digging times system of Minetest is very different, so this weird group trickery has to be used. -In Minecraft, each block has a hardness and the actual Minecraft digging time is determined by this: 1) The block's hardness -2) The tool being used -3) Whether the tool is considered as “eligible” for the block +2) The tool being used (the tool speed and its efficiency level) +3) Whether the tool is considered as "eligible" for the block (e.g. only diamond pick eligible for obsidian) -See Minecraft Wiki for more information. -In MineClone 2, all diggable node have the hardness set in the custom field “_mcl_hardness” (0 by default). -The nodes are also required to specify the “eligible” tools in groups like “pickaxey”, “shovely”, etc. -This mod then calculates the real digging time based on the node meta data. The real digging times -are then added into mcl_autogroup.digtimes where the table indices are group rating and the values are the -digging times in seconds. These digging times can be then added verbatim into the tool definitions. +See Minecraft Wiki for more +information. -Example: -mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2 +How the mod is used +=================== -→ This means that when a node has been assigned the group “pickaxey_dig_diamond=1”, it can be dug by the -diamond pickaxe in 0.2 seconds. +In MineClone 2, 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: + mcl_autogroup.register_diggroup("shovely") + mcl_autogroup.register_diggroup("pickaxey", { + levels = { "wood", "gold", "stone", "iron", "diamond" } + }) +The first line registers a simple digging group. The second line registers a +digging group with 5 different levels (in this case one for each material of a +pickaxes). -This strange setup with mcl_autogroup has been done to minimize the amount of required digging times -a single tool needs to use. If this is not being done, the loading time will increase considerably -(>10s). +Nodes indicate that they belong to a particular digging group by being member of +the digging group in their node definition. "mcl_core:dirt" for example has +shovely=1 in its groups. If the digging group has multiple levels the value of +the group indicates which digging level the node requires. +"mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a +pickaxe of level 4 be mined. -]] +For tools to be able to dig nodes of digging groups they need to use the have +the custom field "_mcl_diggroups" function to get the groupcaps. The value of +this field is a table which defines which groups the tool can dig and how +efficiently. -local materials = { "wood", "gold", "stone", "iron", "diamond" } -local basegroups = { "pickaxey", "axey", "shovely" } -local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } -local divisors = { - ["wood"] = 2, - ["gold"] = 12, - ["stone"] = 4, - ["iron"] = 6, - ["diamond"] = 8, - ["handy"] = 1, - ["shearsy"] = 15, - ["swordy"] = 1.5, - ["shearsy_wool"] = 5, - ["swordy_cobweb"] = 15, -} -local max_efficiency_level = 5 + _mcl_diggroups = { + handy = { speed = 1, level = 1, uses = 0 }, + pickaxey = { speed = 1, level = 0, uses = 0 }, + } -mcl_autogroup = {} -mcl_autogroup.digtimes = {} -mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode +The "uses" field indicate how many uses (0 for infinite) a tool has when used on +the specified digging group. The "speed" field is a multiplier to the dig speed +on that digging group. -for m=1, #materials do - for g=1, #basegroups do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {} - mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {} +The "level" field indicates which levels of the group the tool can harvest. A +level of 0 means that the tool cannot harvest blocks of that node. A level of 1 +or above means that the tool can harvest nodes with that level or below. See +"mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice. + +Information about the mod +========================= + +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. + +This also means that it is very important that no mod adds _mcl_autogroup as a +dependency. +--]] + +assert(minetest.get_modpath("mcl_autogroup"), "This mod requires the mod mcl_autogroup to function") + +-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to +-- each diggroup. +local function get_hardness_values_for_groups() + local maps = {} + local values = {} + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + maps[g] = {} + values[g] = {} + end + + for _, ndef in pairs(minetest.registered_nodes) do + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + if ndef.groups[g] then + maps[g][ndef._mcl_hardness or 0] = true + end + end + end + + for g, map in pairs(maps) do + for k, _ in pairs(map) do + table.insert(values[g], k) + end + end + + for g, _ in pairs(mcl_autogroup.registered_diggroups) do + table.sort(values[g]) + end + return values +end + +-- Returns a table containing a table indexed by "_mcl_hardness_value" to get +-- its index in the list of unique hardnesses for each diggroup. +local function get_hardness_lookup_for_groups(hardness_values) + local map = {} + for g, values in pairs(hardness_values) do + map[g] = {} + for k, v in pairs(values) do + map[g][v] = k + end + end + return map +end + +-- Array of unique hardness values for each group which affects dig time. +local hardness_values = get_hardness_values_for_groups() + +-- Map indexed by hardness values which return the index of that value in +-- hardness_value. Used for quick lookup. +local hardness_lookup = get_hardness_lookup_for_groups(hardness_values) + +--[[local function compute_creativetimes(group) + local creativetimes = {} + + for index, hardness in pairs(hardness_values[group]) do + table.insert(creativetimes, 0) + end + + return creativetimes +end]] + +-- Get the list of digging times for using a specific tool on a specific +-- diggroup. +-- +-- Parameters: +-- group - the group which it is digging +-- can_harvest - if the tool can harvest the block +-- speed - dig speed multiplier for tool (default 1) +-- efficiency - efficiency level for the tool if applicable +local function get_digtimes(group, can_harvest, speed, efficiency) + local speed = speed or 1 + if efficiency then + speed = speed + efficiency * efficiency + 1 + end + + local digtimes = {} + + for index, hardness in pairs(hardness_values[group]) do + local digtime = (hardness or 0) / speed + if can_harvest then + digtime = digtime * 1.5 + else + digtime = digtime * 5 + end + + if digtime <= 0.05 then + digtime = 0 + else + digtime = math.ceil(digtime * 20) / 20 + end + table.insert(digtimes, digtime) + end + + return digtimes +end + +-- Get one groupcap field for using a specific tool on a specific group. +local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +end + +-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a +-- tool. +local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency) + if not groupcaps_def then + return + end + + for g, capsdef in pairs(groupcaps_def) do + local mult = capsdef.speed or 1 + local uses = capsdef.uses + local def = mcl_autogroup.registered_diggroups[g] + local max_level = def.levels and #def.levels or 1 + + assert(capsdef.level, toolname .. ' is missing level for ' .. g) + local level = math.min(capsdef.level, max_level) + + if def.levels then + groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses) + if level > 0 then + groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses) + end + else + groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses) end end end -for g=1, #minigroups do - mcl_autogroup.digtimes[minigroups[g].."_dig"] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {} - for e=1, max_efficiency_level do - mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {} - mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {} + +-- Checks if the given node would drop its useful drop if dug by a given tool. +-- Returns true if it will yield its useful drop, false otherwise. +function mcl_autogroup.can_harvest(nodename, toolname, player) + local ndef = minetest.registered_nodes[nodename] + + if not ndef then + return false end + + if minetest.get_item_group(nodename, "dig_immediate") >= 2 then + return true + end + + if minetest.get_item_group(nodename, "dig_immediate_piston") >= 1 then + return true + end + + -- Check if it can be dug by tool + local tdef = minetest.registered_tools[toolname] + if tdef and tdef._mcl_diggroups then + for g, gdef in pairs(tdef._mcl_diggroups) do + if ndef.groups[g] then + if ndef.groups[g] <= gdef.level then + return true + end + end + end + end + + -- Check if it can be dug by hand + if not player or not player:is_player() then return false end + local name = player:get_inventory():get_stack("hand", 1):get_name() + local tdef = minetest.registered_items[name] + if tdef then + for g, gdef in pairs(tdef._mcl_diggroups) do + if ndef.groups[g] then + if ndef.groups[g] <= gdef.level then + return true + end + end + end + end + + return false end -local overwrite = function() +-- Get one groupcap field for using a specific tool on a specific group. +--[[local function get_groupcap(group, can_harvest, multiplier, efficiency, uses) + return { + times = get_digtimes(group, can_harvest, multiplier, efficiency), + uses = uses, + maxlevel = 0, + } +end]] + +-- Returns the tool_capabilities from a tool definition or a default set of +-- tool_capabilities +local function get_tool_capabilities(tdef) + if tdef.tool_capabilities then + return tdef.tool_capabilities + end + + -- If the damage group and punch interval from hand is not included, + -- then the user will not be able to attack with the tool. + local hand_toolcaps = mcl_meshhand.survival_hand_tool_caps + return { + full_punch_interval = hand_toolcaps.full_punch_interval, + damage_groups = hand_toolcaps.damage_groups + } +end + +-- Get the groupcaps for a tool. This function returns "groupcaps" table of +-- digging which should be put in the "tool_capabilities" of the tool definition +-- or in the metadata of an enchanted tool. +-- +-- Parameters: +-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +-- efficiency - The efficiency level the tool is enchanted with (default 0) +-- +-- NOTE: +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_groupcaps(toolname, efficiency) + local tdef = minetest.registered_items[toolname] + local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {}) + add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency) + return groupcaps +end + +-- Get the wear from using a tool on a digging group. +-- +-- Parameters +-- toolname - Name of the tool used +-- diggroup - The name of the diggroup the tool is used on +-- +-- NOTE: +-- This function can only be called after mod initialization. Otherwise a mod +-- would have to add _mcl_autogroup as a dependency which would break the mod +-- loading order. +function mcl_autogroup.get_wear(toolname, diggroup) + local tdef = minetest.registered_tools[toolname] + if not tdef then + minetest.log("warning", "Adding wear for tool: " .. tostring(toolname) .. " failed with diggroup: " .. tostring(diggroup)) + return nil + end + local uses = tdef._mcl_diggroups[diggroup].uses + return math.ceil(65535 / uses) +end + +local function overwrite() for nname, ndef in pairs(minetest.registered_nodes) do - local groups_changed = false local newgroups = table.copy(ndef.groups) if (nname ~= "ignore" and ndef.diggable) then - -- Automatically assign the “solid” group for solid nodes + -- Automatically assign the "solid" group for solid nodes if (ndef.walkable == nil or ndef.walkable == true) and (ndef.collision_box == nil or ndef.collision_box.type == "regular") and (ndef.node_box == nil or ndef.node_box.type == "regular") and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then newgroups.solid = 1 - groups_changed = true end - -- Automatically assign the “opaque” group for opaque nodes + -- Automatically assign the "opaque" group for opaque nodes if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and (ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then newgroups.opaque = 1 - groups_changed = true end - local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency) - local time, validity_factor - if actual_rating >= expected_rating then - -- Valid tool - validity_factor = 1.5 - else - -- Wrong tool (higher digging time) - validity_factor = 5 - end - local speed_multiplier = divisors[material] - if efficiency then - speed_multiplier = speed_multiplier + efficiency * efficiency + 1 - end - time = (hardness * validity_factor) / speed_multiplier - if time <= 0.05 then - time = 0 - else - time = math.ceil(time * 20) / 20 - end - table.insert(mcl_autogroup.digtimes[diggroup], time) - if not efficiency then - table.insert(mcl_autogroup.creativetimes[diggroup], 0) - end - newgroups[diggroup] = #mcl_autogroup.digtimes[diggroup] - return newgroups - end + --local creative_breakable = false - -- Hack in digging times - local hardness = ndef._mcl_hardness - if not hardness then - hardness = 0 - end + -- Assign groups used for digging this node depending on + -- the registered digging groups + for g, gdef in pairs(mcl_autogroup.registered_diggroups) do + --creative_breakable = true + local index = hardness_lookup[g][ndef._mcl_hardness or 0] + if ndef.groups[g] then + if gdef.levels then + newgroups[g .. "_dig_default"] = index - -- Handle pickaxey, axey and shovely - for _, basegroup in pairs(basegroups) do - if (hardness ~= -1 and ndef.groups[basegroup]) then - for g=1,#materials do - local diggroup = basegroup.."_dig_"..materials[g] - newgroups = calculate_group(hardness, materials[g], diggroup, newgroups, g, ndef.groups[basegroup]) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, materials[g], diggroup .. "_efficiency_" .. e, newgroups, g, ndef.groups[basegroup], e) + for i = ndef.groups[g], #gdef.levels do + newgroups[g .. "_dig_" .. gdef.levels[i]] = index end - groups_changed = true - end - end - end - for m=1, #minigroups do - local minigroup = minigroups[m] - if hardness ~= -1 then - local diggroup = minigroup.."_dig" - -- actual rating - local ar = ndef.groups[minigroup] - if ar == nil then - ar = 0 - end - if (minigroup == "handy") - or - (ndef.groups.shearsy_wool and minigroup == "shearsy_wool" and ndef.groups.wool) - or - (ndef.groups.swordy_cobweb and minigroup == "swordy_cobweb" and nname == "mcl_core:cobweb") - or - (ndef.groups[minigroup] and minigroup ~= "swordy_cobweb" and minigroup ~= "shearsy_wool") then - newgroups = calculate_group(hardness, minigroup, diggroup, newgroups, ar, 1) - for e=1,max_efficiency_level do - newgroups = calculate_group(hardness, minigroup, diggroup .. "_efficiency_" .. e, newgroups, ar, 1, e) - end - groups_changed = true + else + newgroups[g .. "_dig"] = index end end end - if groups_changed then - minetest.override_item(nname, { - groups = newgroups - }) - end + -- Automatically assign the node to the + -- creative_breakable group if it belongs to any digging + -- group. + newgroups["creative_breakable"] = 1 + + minetest.override_item(nname, { + groups = newgroups + }) + end + end + + for tname, tdef in pairs(minetest.registered_items) do + -- Assign groupcaps for digging the registered digging groups + -- depending on the _mcl_diggroups in the tool definition + if tdef._mcl_diggroups then + local toolcaps = table.copy(get_tool_capabilities(tdef)) + toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname) + + minetest.override_item(tname, { + tool_capabilities = toolcaps + }) end end end diff --git a/mods/CORE/_mcl_autogroup/mod.conf b/mods/CORE/_mcl_autogroup/mod.conf index fb171b765..eea72c40f 100644 --- a/mods/CORE/_mcl_autogroup/mod.conf +++ b/mods/CORE/_mcl_autogroup/mod.conf @@ -1 +1,3 @@ name = _mcl_autogroup +author = ryvnf +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/biomeinfo/init.lua b/mods/CORE/biomeinfo/init.lua index 5013647ed..950925f9d 100644 --- a/mods/CORE/biomeinfo/init.lua +++ b/mods/CORE/biomeinfo/init.lua @@ -81,11 +81,11 @@ if v6_use_snow_biomes then end local v6_freq_desert = tonumber(minetest.get_mapgen_setting("mgv6_freq_desert") or 0.45) -local NOISE_MAGIC_X = 1619 -local NOISE_MAGIC_Y = 31337 -local NOISE_MAGIC_Z = 52591 -local NOISE_MAGIC_SEED = 1013 -local noise2d = function(x, y, seed) +--local NOISE_MAGIC_X = 1619 +--local NOISE_MAGIC_Y = 31337 +--local NOISE_MAGIC_Z = 52591 +--local NOISE_MAGIC_SEED = 1013 +local function noise2d(x, y, seed) -- TODO: implement noise2d function for biome blend return 0 --[[ diff --git a/mods/CORE/biomeinfo/mod.conf b/mods/CORE/biomeinfo/mod.conf index 95be561a3..8e9f3b1d0 100644 --- a/mods/CORE/biomeinfo/mod.conf +++ b/mods/CORE/biomeinfo/mod.conf @@ -1,2 +1,3 @@ name = biomeinfo +author = Wuzzy description = Simple API to get data about biomes. diff --git a/mods/CORE/controls/API.md b/mods/CORE/controls/API.md new file mode 100644 index 000000000..8d9df6ca5 --- /dev/null +++ b/mods/CORE/controls/API.md @@ -0,0 +1,23 @@ +# controls + +## controls.players +Table containing player controls at runtime. +WARNING: Never use this table in writing + +## controls.register_on_press(func) +Register a function that will be executed with (player, keyname) every time a player press a key. + +## controls.registered_on_press +Table containing functions registered with controls.register_on_press(). + +## controls.register_on_release(func) +Register a function that will be executed with (player, keyname, clock_from_last_press) every time a player release a key. + +## controls.registered_on_release +Table containing functions registered with controls.register_on_release(). + +## controls.register_on_hold(func) +Register a function that will be executed with (player, keyname, clock_from_start_hold) every time a player hold a key. + +## controls.registered_on_hold +Table containing functions registered with controls.register_on_hold(). \ No newline at end of file diff --git a/mods/CORE/controls/init.lua b/mods/CORE/controls/init.lua index a219b794c..ef57281a4 100644 --- a/mods/CORE/controls/init.lua +++ b/mods/CORE/controls/init.lua @@ -1,3 +1,8 @@ +local get_connected_players = minetest.get_connected_players +local clock = os.clock + +local pairs = pairs + controls = {} controls.players = {} @@ -17,15 +22,15 @@ function controls.register_on_hold(func) end local known_controls = { - jump=true, - right=true, - left=true, - LMB=true, - RMB=true, - sneak=true, - aux1=true, - down=true, - up=true, + jump = true, + right = true, + left = true, + LMB = true, + RMB = true, + sneak = true, + aux1 = true, + down = true, + up = true, } minetest.register_on_joinplayer(function(player) @@ -42,31 +47,31 @@ minetest.register_on_leaveplayer(function(player) end) minetest.register_globalstep(function(dtime) - for _, player in pairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do local player_name = player:get_player_name() local player_controls = player:get_player_control() if controls.players[player_name] then - for cname, cbool in pairs(player_controls) do - if known_controls[cname] == true then - --Press a key - if cbool==true and controls.players[player_name][cname][1]==false then - for _, func in pairs(controls.registered_on_press) do - func(player, cname) + for cname, cbool in pairs(player_controls) do + if known_controls[cname] == true then + --Press a key + if cbool == true and controls.players[player_name][cname][1] == false then + for _, func in pairs(controls.registered_on_press) do + func(player, cname) + end + controls.players[player_name][cname] = {true, clock()} + elseif cbool == true and controls.players[player_name][cname][1] == true then + for _, func in pairs(controls.registered_on_hold) do + func(player, cname, clock()-controls.players[player_name][cname][2]) + end + --Release a key + elseif cbool == false and controls.players[player_name][cname][1] == true then + for _, func in pairs(controls.registered_on_release) do + func(player, cname, clock()-controls.players[player_name][cname][2]) + end + controls.players[player_name][cname] = {false} + end end - controls.players[player_name][cname] = {true, os.clock()} - elseif cbool==true and controls.players[player_name][cname][1]==true then - for _, func in pairs(controls.registered_on_hold) do - func(player, cname, os.clock()-controls.players[player_name][cname][2]) - end - --Release a key - elseif cbool==false and controls.players[player_name][cname][1]==true then - for _, func in pairs(controls.registered_on_release) do - func(player, cname, os.clock()-controls.players[player_name][cname][2]) - end - controls.players[player_name][cname] = {false} end end - end - end end end) diff --git a/mods/CORE/controls/mod.conf b/mods/CORE/controls/mod.conf index 8fab3aa2b..83ebb2e25 100644 --- a/mods/CORE/controls/mod.conf +++ b/mods/CORE/controls/mod.conf @@ -1 +1,4 @@ -name=controls +name = controls +author = Arcelmi +description = Controls framework by Arcelmi + diff --git a/mods/CORE/flowlib/API.md b/mods/CORE/flowlib/API.md new file mode 100644 index 000000000..20e85036b --- /dev/null +++ b/mods/CORE/flowlib/API.md @@ -0,0 +1,45 @@ +# flowlib +Simple flow functions. + +## flowlib.is_touching(realpos, nodepos, radius) +Return true if a sphere of at collide with node at . +* realpos: position +* nodepos: position +* radius: number + +## flowlib.is_water(pos) +Return true if node at is water, false overwise. +* pos: position + +## flowlib.node_is_water(node) +Return true if is water, false overwise. +* node: node + +## flowlib.is_lava(pos) +Return true if node at is lava, false overwise. +* pos: position + +## flowlib.node_is_lava(node) +Return true if is lava, false overwise. +* node: node + +## flowlib.is_liquid(pos) +Return true if node at is liquid, false overwise. +* pos: position + +## flowlib.node_is_liquid(node) +Return true if is liquid, false overwise. +* node: node + +## flowlib.quick_flow(pos, node) +Return direction where the water is flowing (to be use to push mobs, items...). +* pos: position +* node: node + +## flowlib.move_centre(pos, realpos, node, radius) +Return the pos of the nearest not water block near from in a sphere of at . +WARNING: This function is never used in mcl2, use at your own risk. The informations described here may be wrong. +* pos: position +* realpos: position, position of the entity +* node: node +* radius: number \ No newline at end of file diff --git a/mods/CORE/flowlib/init.lua b/mods/CORE/flowlib/init.lua index e4e22a20e..ab710e476 100644 --- a/mods/CORE/flowlib/init.lua +++ b/mods/CORE/flowlib/init.lua @@ -1,95 +1,100 @@ +local math = math + +local get_node = minetest.get_node +local get_item_group = minetest.get_item_group + +local registered_nodes = minetest.registered_nodes + flowlib = {} --sum of direction vectors must match an array index + +--(sum,root) +--(0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8) + +local inv_roots = { + [0] = 1, + [1] = 1, + [2] = 0.70710678118655, + [4] = 0.5, + [5] = 0.44721359549996, + [8] = 0.35355339059327, +} + local function to_unit_vector(dir_vector) - --(sum,root) - -- (0,1), (1,1+0=1), (2,1+1=2), (3,1+2^2=5), (4,2^2+2^2=8) - local inv_roots = {[0] = 1, [1] = 1, [2] = 0.70710678118655, [4] = 0.5 - , [5] = 0.44721359549996, [8] = 0.35355339059327} - local sum = dir_vector.x*dir_vector.x + dir_vector.z*dir_vector.z - return {x=dir_vector.x*inv_roots[sum],y=dir_vector.y - ,z=dir_vector.z*inv_roots[sum]} + local sum = dir_vector.x * dir_vector.x + dir_vector.z * dir_vector.z + return {x = dir_vector.x * inv_roots[sum], y = dir_vector.y, z = dir_vector.z * inv_roots[sum]} end -local is_touching = function(realpos,nodepos,radius) +local function is_touching(realpos,nodepos,radius) local boarder = 0.5 - radius - return (math.abs(realpos - nodepos) > (boarder)) + return math.abs(realpos - nodepos) > (boarder) end flowlib.is_touching = is_touching -local is_water = function(pos) - return (minetest.get_item_group(minetest.get_node( - {x=pos.x,y=pos.y,z=pos.z}).name - , "water") ~= 0) +local function is_water(pos) + return get_item_group(get_node(pos).name, "water") ~= 0 end flowlib.is_water = is_water -local node_is_water = function(node) - return (minetest.get_item_group(node.name, "water") ~= 0) +local function node_is_water(node) + return get_item_group(node.name, "water") ~= 0 end flowlib.node_is_water = node_is_water -local is_lava = function(pos) - return (minetest.get_item_group(minetest.get_node( - {x=pos.x,y=pos.y,z=pos.z}).name - , "lava") ~= 0) +local function is_lava(pos) + return get_item_group(get_node(pos).name, "lava") ~= 0 end flowlib.is_lava = is_lava -local node_is_lava = function(node) - return (minetest.get_item_group(node.name, "lava") ~= 0) +local function node_is_lava(node) + return get_item_group(node.name, "lava") ~= 0 end flowlib.node_is_lava = node_is_lava -local is_liquid = function(pos) - return (minetest.get_item_group(minetest.get_node( - {x=pos.x,y=pos.y,z=pos.z}).name - , "liquid") ~= 0) +local function is_liquid(pos) + return get_item_group(get_node(pos).name, "liquid") ~= 0 end flowlib.is_liquid = is_liquid -local node_is_liquid = function(node) - return (minetest.get_item_group(node.name, "liquid") ~= 0) +local function node_is_liquid(node) + return minetest.get_item_group(node.name, "liquid") ~= 0 end flowlib.node_is_liquid = node_is_liquid --This code is more efficient -local function quick_flow_logic(node,pos_testing,direction) +local function quick_flow_logic(node, pos_testing, direction) local name = node.name - if not minetest.registered_nodes[name] then + if not registered_nodes[name] then return 0 end - if minetest.registered_nodes[name].liquidtype == "source" then - local node_testing = minetest.get_node(pos_testing) - local param2_testing = node_testing.param2 - if not minetest.registered_nodes[node_testing.name] then + if registered_nodes[name].liquidtype == "source" then + local node_testing = get_node(pos_testing) + if not registered_nodes[node_testing.name] then return 0 end - if minetest.registered_nodes[node_testing.name].liquidtype - ~= "flowing" then + if registered_nodes[node_testing.name].liquidtype ~= "flowing" then return 0 else return direction end - elseif minetest.registered_nodes[name].liquidtype == "flowing" then - local node_testing = minetest.get_node(pos_testing) + elseif registered_nodes[name].liquidtype == "flowing" then + local node_testing = get_node(pos_testing) local param2_testing = node_testing.param2 - if not minetest.registered_nodes[node_testing.name] then + if not registered_nodes[node_testing.name] then return 0 end - if minetest.registered_nodes[node_testing.name].liquidtype - == "source" then + if registered_nodes[node_testing.name].liquidtype == "source" then return -direction - elseif minetest.registered_nodes[node_testing.name].liquidtype - == "flowing" then + elseif registered_nodes[node_testing.name].liquidtype == "flowing" then if param2_testing < node.param2 then if (node.param2 - param2_testing) > 6 then return -direction @@ -108,48 +113,41 @@ local function quick_flow_logic(node,pos_testing,direction) return 0 end -local quick_flow = function(pos,node) - local x = 0 - local z = 0 - +local function quick_flow(pos, node) if not node_is_liquid(node) then - return {x=0,y=0,z=0} + return {x = 0, y = 0, z = 0} end - - x = x + quick_flow_logic(node,{x=pos.x-1,y=pos.y,z=pos.z},-1) - x = x + quick_flow_logic(node,{x=pos.x+1,y=pos.y,z=pos.z}, 1) - z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z-1},-1) - z = z + quick_flow_logic(node,{x=pos.x,y=pos.y,z=pos.z+1}, 1) - - return to_unit_vector({x=x,y=0,z=z}) + local x = quick_flow_logic(node,{x = pos.x-1, y = pos.y, z = pos.z},-1) + quick_flow_logic(node,{x = pos.x+1, y = pos.y, z = pos.z}, 1) + local z = quick_flow_logic(node,{x = pos.x, y = pos.y, z = pos.z-1},-1) + quick_flow_logic(node,{x = pos.x, y = pos.y, z = pos.z+1}, 1) + return to_unit_vector({x = x, y = 0, z = z}) end flowlib.quick_flow = quick_flow +--if not in water but touching, move centre to touching block +--x has higher precedence than z +--if pos changes with x, it affects z - --if not in water but touching, move centre to touching block - --x has higher precedence than z - --if pos changes with x, it affects z -local move_centre = function(pos,realpos,node,radius) - if is_touching(realpos.x,pos.x,radius) then - if is_liquid({x=pos.x-1,y=pos.y,z=pos.z}) then - node = minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) - pos = {x=pos.x-1,y=pos.y,z=pos.z} - elseif is_liquid({x=pos.x+1,y=pos.y,z=pos.z}) then - node = minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) - pos = {x=pos.x+1,y=pos.y,z=pos.z} +local function move_centre(pos, realpos, node, radius) + if is_touching(realpos.x, pos.x, radius) then + if is_liquid({x = pos.x-1, y = pos.y, z = pos.z}) then + node = get_node({x=pos.x-1, y = pos.y, z = pos.z}) + pos = {x = pos.x-1, y = pos.y, z = pos.z} + elseif is_liquid({x = pos.x+1, y = pos.y, z = pos.z}) then + node = get_node({x = pos.x+1, y = pos.y, z = pos.z}) + pos = {x = pos.x+1, y = pos.y, z = pos.z} end end - if is_touching(realpos.z,pos.z,radius) then - if is_liquid({x=pos.x,y=pos.y,z=pos.z-1}) then - node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) - pos = {x=pos.x,y=pos.y,z=pos.z-1} - elseif is_liquid({x=pos.x,y=pos.y,z=pos.z+1}) then - node = minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) - pos = {x=pos.x,y=pos.y,z=pos.z+1} + if is_touching(realpos.z, pos.z, radius) then + if is_liquid({x = pos.x, y = pos.y, z = pos.z - 1}) then + node = get_node({x = pos.x, y = pos.y, z = pos.z - 1}) + pos = {x = pos.x, y = pos.y, z = pos.z - 1} + elseif is_liquid({x = pos.x, y = pos.y, z = pos.z + 1}) then + node = get_node({x = pos.x, y = pos.y, z = pos.z + 1}) + pos = {x = pos.x, y = pos.y, z = pos.z + 1} end end - return pos,node + return pos, node end flowlib.move_centre = move_centre diff --git a/mods/CORE/flowlib/mod.conf b/mods/CORE/flowlib/mod.conf index 0d982481c..7b3a325f3 100644 --- a/mods/CORE/flowlib/mod.conf +++ b/mods/CORE/flowlib/mod.conf @@ -1 +1,4 @@ name = flowlib +author = Qwertymine3 +description = Simple flow functions for use in Minetest mods by Qwertymine3 + diff --git a/mods/CORE/mcl_attached/description.txt b/mods/CORE/mcl_attached/description.txt deleted file mode 100644 index 3532db31d..000000000 --- a/mods/CORE/mcl_attached/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds additional ways for nodes to be attached. diff --git a/mods/CORE/mcl_attached/init.lua b/mods/CORE/mcl_attached/init.lua index 146cb2251..2013dbde2 100644 --- a/mods/CORE/mcl_attached/init.lua +++ b/mods/CORE/mcl_attached/init.lua @@ -1,26 +1,98 @@ +-- Overrides the builtin minetest.check_single_for_falling. +-- We need to do this in order to handle nodes in mineclone specific groups +-- "supported_node" and "attached_node_facedir". +-- +-- Nodes in group "supported_node" can be placed on any node that does not +-- have the "airlike" drawtype. Carpets are an example of this type. + +local pairs = pairs +local math = math +local vector = vector + +local facedir_to_dir = minetest.facedir_to_dir +local get_item_group = minetest.get_item_group +local remove_node = minetest.remove_node +local get_node = minetest.get_node +local get_meta = minetest.get_meta +local registered_nodes = minetest.registered_nodes +local get_node_drops = minetest.get_node_drops +local add_item = minetest.add_item + +-- drop_attached_node(p) +-- +-- This function is copied verbatim from minetest/builtin/game/falling.lua +-- We need this to do the exact same dropping node handling in our override +-- minetest.check_single_for_falling() function as in the builtin function. +-- +---@param p Vector +local function drop_attached_node(p) + local n = get_node(p) + local drops = get_node_drops(n, "") + local def = registered_nodes[n.name] + + if def and def.preserve_metadata then + local oldmeta = get_meta(p):to_table().fields + -- Copy pos and node because the callback can modify them. + local pos_copy = vector.copy(p) + local node_copy = { name = n.name, param1 = n.param1, param2 = n.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 + + if def and def.sounds and def.sounds.fall then + minetest.sound_play(def.sounds.fall, { pos = p }, true) + end + + remove_node(p) + for _, item in pairs(drops) do + local pos = vector.offset(p, + math.random() / 2 - 0.25, + math.random() / 2 - 0.25, + math.random() / 2 - 0.25 + ) + add_item(pos, item) + end +end + +-- minetest.check_single_for_falling(pos) +-- +-- * causes an unsupported `group:falling_node` node to fall and causes an +-- unattached `group:attached_node` or `group:attached_node_facedir` node +-- or unsupported `group:supported_node` node to drop. +-- * does not spread these updates to neighbours. +-- +-- Returns true if the node at has spawned a falling node or has been +-- dropped as item(s). +-- local original_function = minetest.check_single_for_falling -minetest.check_single_for_falling = function(pos) - local ret_o = original_function(pos) +function minetest.check_single_for_falling(pos) + if original_function(pos) then + return true + end - local ret = false - local node = minetest.get_node(pos) - if minetest.get_item_group(node.name, "attached_node_facedir") ~= 0 then - local dir = minetest.facedir_to_dir(node.param2) + local node = get_node(pos) + if get_item_group(node.name, "attached_node_facedir") ~= 0 then + local dir = facedir_to_dir(node.param2) if dir then - local cpos = vector.add(pos, dir) - local cnode = minetest.get_node(cpos) - if minetest.get_item_group(cnode.name, "solid") == 0 then - minetest.remove_node(pos) - local drops = minetest.get_node_drops(node.name, "") - for dr=1, #drops do - minetest.add_item(pos, drops[dr]) - end - ret = true + if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then + drop_attached_node(pos) + return true end end end - return ret_o or ret -end + if get_item_group(node.name, "supported_node") ~= 0 then + local def = registered_nodes[get_node(vector.offset(pos, 0, -1, 0)).name] + if def and def.drawtype == "airlike" then + drop_attached_node(pos) + return true + end + end + return false +end diff --git a/mods/CORE/mcl_attached/mod.conf b/mods/CORE/mcl_attached/mod.conf new file mode 100644 index 000000000..7ad1b4a4c --- /dev/null +++ b/mods/CORE/mcl_attached/mod.conf @@ -0,0 +1,3 @@ +name = mcl_attached +author = Wuzzy +description = Adds additional ways for nodes to be attached. diff --git a/mods/CORE/mcl_autogroup/API.md b/mods/CORE/mcl_autogroup/API.md new file mode 100644 index 000000000..b3a913ab6 --- /dev/null +++ b/mods/CORE/mcl_autogroup/API.md @@ -0,0 +1,28 @@ +# mcl_autogroup +This mod emulate digging times from mc. + +## mcl_autogroup.can_harvest(nodename, toolname, player) +Return true if can be dig with by . +* nodename: string, valid nodename +* toolname: (optional) string, valid toolname +* player: (optinal) ObjectRef, valid player + +## mcl_autogroup.get_groupcaps(toolname, efficiency) +This function is used to calculate diggroups for tools. +WARNING: This function can only be called after mod initialization. +* toolname: string, name of the tool being enchanted (like "mcl_tools:diamond_pickaxe") +* efficiency: (optional) integer, the efficiency level the tool is enchanted with (default 0) + +## mcl_autogroup.get_wear(toolname, diggroup) +Return the max wear of with +WARNING: This function can only be called after mod initialization. +* toolname: string, name of the tool used +* diggroup: string, the name of the diggroup the tool is used on + +## mcl_autogroup.register_diggroup(group, def) +* group: string, name of the group to register as a digging group +* def: (optional) table, table with information about the diggroup (defaults to {} if unspecified) + * level: (optional) string, if specified it is an array containing the names of the different digging levels the digging group supports + +## mcl_autogroup.registered_diggroups +List of registered diggroups, indexed by name. \ No newline at end of file diff --git a/mods/CORE/mcl_autogroup/init.lua b/mods/CORE/mcl_autogroup/init.lua new file mode 100644 index 000000000..16dd831c0 --- /dev/null +++ b/mods/CORE/mcl_autogroup/init.lua @@ -0,0 +1,28 @@ +--[[ +This is one part of a mod to replicate the digging times from Minecraft. This +part only exposes a function to register digging groups. The rest of the mod is +implemented and documented in the _mcl_autogroup. + +The mod is split up into two parts, mcl_autogroup and _mcl_autogroup. +mcl_autogroup contains the API functions used to register custom digging groups. +_mcl_autogroup contains most of the code. The leading underscore in the name +"_mcl_autogroup" is used to force Minetest to load that part of the mod as late +as possible. Minetest loads mods in reverse alphabetical order. +--]] +mcl_autogroup = {} +mcl_autogroup.registered_diggroups = {} + +assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_autogroup to function") + +-- Register a group as a digging group. +-- +-- Parameters: +-- group - Name of the group to register as a digging group +-- def - Table with information about the diggroup (defaults to {} if unspecified) +-- +-- Values in def: +-- level - If specified it is an array containing the names of the different +-- digging levels the digging group supports. +function mcl_autogroup.register_diggroup(group, def) + mcl_autogroup.registered_diggroups[group] = def or {} +end diff --git a/mods/CORE/mcl_autogroup/mod.conf b/mods/CORE/mcl_autogroup/mod.conf new file mode 100644 index 000000000..45818cd58 --- /dev/null +++ b/mods/CORE/mcl_autogroup/mod.conf @@ -0,0 +1,3 @@ +name = mcl_autogroup +author = ryvnf +description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times. diff --git a/mods/CORE/mcl_colors/API.md b/mods/CORE/mcl_colors/API.md new file mode 100644 index 000000000..71cad335b --- /dev/null +++ b/mods/CORE/mcl_colors/API.md @@ -0,0 +1,8 @@ +# mcl_colors +Mod providing global table containing legacity minecraft colors to be used in mods. + +## mcl_colors.* +Colors by upper name, in hex value. + +## mcl_colors.background.* +Background colors by upper name, in hex value. diff --git a/mods/CORE/mcl_colors/init.lua b/mods/CORE/mcl_colors/init.lua new file mode 100644 index 000000000..e88f91d9d --- /dev/null +++ b/mods/CORE/mcl_colors/init.lua @@ -0,0 +1,36 @@ +mcl_colors = { + BLACK = "#000000", + DARK_BLUE = "#0000AA", + DARK_GREEN = "#00AA00", + DARK_AQUA = "#00AAAA", + DARK_RED = "#AA0000", + DARK_PURPLE = "#AA00AA", + GOLD = "#FFAA00", + GRAY = "#AAAAAA", + DARK_GRAY = "#555555", + BLUE = "#5555FF", + GREEN = "#55FF55", + AQUA = "#55FFFF", + RED = "#FF5555", + LIGHT_PURPLE = "#FF55FF", + YELLOW = "#FFFF55", + WHITE = "#FFFFFF", + background = { + BLACK = "#000000", + DARK_BLUE = "#00002A", + DARK_GREEN = "#002A00", + DARK_AQUA = "#002A2A", + DARK_RED = "#2A0000", + DARK_PURPLE = "#2A002A", + GOLD = "#2A2A00", + GRAY = "#2A2A2A", + DARK_GRAY = "#151515", + BLUE = "#15153F", + GREEN = "#153F15", + AQUA = "#153F3F", + RED = "#3F1515", + LIGHT_PURPLE = "#3F153F", + YELLOW = "#3F3F15", + WHITE = "#373501", + } +} diff --git a/mods/CORE/mcl_colors/mod.conf b/mods/CORE/mcl_colors/mod.conf new file mode 100644 index 000000000..549d94351 --- /dev/null +++ b/mods/CORE/mcl_colors/mod.conf @@ -0,0 +1,3 @@ +name = mcl_colors +author = Fleckenstein +description = The HTML sequences for the minecraft colors diff --git a/mods/CORE/mcl_damage/API.md b/mods/CORE/mcl_damage/API.md new file mode 100644 index 000000000..9ffdcb9f4 --- /dev/null +++ b/mods/CORE/mcl_damage/API.md @@ -0,0 +1,15 @@ +# mcl_damage + +This mod is intended to overall minetest's native damage system, to provide a better integration between features that deals with entities' health. + +WARNING: Not using it inside your mods may cause strange bugs (using the native damage system may cause conflicts with this system). + +## Callbacks + +To modify the amount of damage made by something: + +```lua +--obj: an ObjectRef +mcl_damage.register_modifier(function(obj, damage, reason) +end, 0) +``` \ No newline at end of file diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua new file mode 100644 index 000000000..8804b8561 --- /dev/null +++ b/mods/CORE/mcl_damage/init.lua @@ -0,0 +1,171 @@ +mcl_damage = { + modifiers = {}, + damage_callbacks = {}, + death_callbacks = {}, + types = { + in_fire = {is_fire = true}, + lightning_bolt = {is_lightning = true}, + on_fire = {is_fire = true, bypasses_armor = true}, + lava = {is_fire = true}, + hot_floor = {is_fire = true}, + in_wall = {bypasses_armor = true}, + drown = {bypasses_armor = true}, + starve = {bypasses_armor = true, bypasses_magic = true}, + cactus = {}, + sweet_berry = {}, + fall = {bypasses_armor = true}, + fly_into_wall = {bypasses_armor = true}, -- unused + out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true, bypasses_totem = true}, + generic = {bypasses_armor = true}, + magic = {is_magic = true, bypasses_armor = true}, + dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable + wither = {bypasses_armor = true}, -- unused + wither_skull = {is_magic = true, is_explosion = true}, -- this is non-MC but a workaround to get the proper death message + anvil = {}, + falling_node = {}, -- this is falling_block in MC + mob = {}, + player = {}, + arrow = {is_projectile = true}, + fireball = {is_projectile = true, is_fire = true}, + thorns = {is_magic = true}, + explosion = {is_explosion = true}, + cramming = {bypasses_armor = true}, -- unused + fireworks = {is_explosion = true}, -- unused + } +} + +local damage_enabled = minetest.settings:get_bool("enabled_damage",true) + +function mcl_damage.register_modifier(func, priority) + table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0}) +end + +function mcl_damage.register_on_damage(func) + table.insert(mcl_damage.damage_callbacks, func) +end + +function mcl_damage.register_on_death(func) + table.insert(mcl_damage.death_callbacks, func) +end + +function mcl_damage.run_modifiers(obj, damage, reason) + for _, modf in ipairs(mcl_damage.modifiers) do + damage = modf.func(obj, damage, reason) or damage + if damage == 0 then + return 0 + end + end + + return damage +end + +local function run_callbacks(funcs, ...) + for _, func in pairs(funcs) do + func(...) + end +end + +function mcl_damage.run_damage_callbacks(obj, damage, reason) + run_callbacks(mcl_damage.damage_callbacks, obj, damage, reason) +end + +function mcl_damage.run_death_callbacks(obj, reason) + run_callbacks(mcl_damage.death_callbacks, obj, reason) +end + +function mcl_damage.from_punch(mcl_reason, object) + mcl_reason.direct = object + local luaentity = mcl_reason.direct:get_luaentity() + if luaentity then + if luaentity._is_arrow then + mcl_reason.type = "arrow" + elseif luaentity._is_fireball then + mcl_reason.type = "fireball" + elseif luaentity.is_mob then + mcl_reason.type = "mob" + end + mcl_reason.source = mcl_reason.source or luaentity._source_object + else + mcl_reason.type = "player" + end +end + +function mcl_damage.finish_reason(mcl_reason) + mcl_reason.source = mcl_reason.source or mcl_reason.direct + mcl_reason.flags = mcl_damage.types[mcl_reason.type] +end + +function mcl_damage.from_mt(mt_reason) + if mt_reason._mcl_chached_reason then + return mt_reason._mcl_chached_reason + end + + local mcl_reason + + if mt_reason._mcl_reason then + mcl_reason = mt_reason._mcl_reason + else + mcl_reason = {type = "generic"} + + if mt_reason._mcl_type then + mcl_reason.type = mt_reason._mcl_type + elseif mt_reason.type == "fall" then + mcl_reason.type = "fall" + elseif mt_reason.type == "drown" then + mcl_reason.type = "drown" + elseif mt_reason.type == "punch" then + mcl_damage.from_punch(mcl_reason, mt_reason.object) + elseif mt_reason.type == "node_damage" and mt_reason.node then + if minetest.get_item_group(mt_reason.node, "fire") > 0 then + mcl_reason.type = "in_fire" + end + if minetest.get_item_group(mt_reason.node, "lava") > 0 then + mcl_reason.type = "lava" + end + end + + for key, value in pairs(mt_reason) do + if key:find("_mcl_") == 1 then + mcl_reason[key:sub(6, #key)] = value + end + end + end + + mcl_damage.finish_reason(mcl_reason) + mt_reason._mcl_cached_reason = mcl_reason + + return mcl_reason +end + +function mcl_damage.register_type(name, def) + mcl_damage.types[name] = def +end + +minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if not damage_enabled then return 0 end + if hp_change < 0 then + if player:get_hp() <= 0 then + return 0 + end + hp_change = -mcl_damage.run_modifiers(player, -hp_change, mcl_damage.from_mt(mt_reason)) + end + return hp_change +end, true) + +minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if not damage_enabled then return 0 end + if player:get_hp() > 0 then + if hp_change < 0 then + mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason)) + end + end +end, false) + +minetest.register_on_dieplayer(function(player, mt_reason) + mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason)) + minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos()))) +end) + +minetest.register_on_mods_loaded(function() + table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) +end) diff --git a/mods/CORE/mcl_damage/mod.conf b/mods/CORE/mcl_damage/mod.conf new file mode 100644 index 000000000..c7d96395e --- /dev/null +++ b/mods/CORE/mcl_damage/mod.conf @@ -0,0 +1,3 @@ +name = mcl_damage +author = Fleckenstein +description = Minecraft-like damage reason system diff --git a/mods/CORE/mcl_events/API.md b/mods/CORE/mcl_events/API.md new file mode 100644 index 000000000..c94328e50 --- /dev/null +++ b/mods/CORE/mcl_events/API.md @@ -0,0 +1,27 @@ +## mcl_events +### Registering Events + `mlc_events.register_event("name",def)` + +#### Event Definition + { + stage = 0, + max_stage = 1, + percent = 100, + bars = {}, + completed = false, + cond_start = function() end, + --return table of paramtables e.g. { { player = playername, pos = position, ... } }, custom parameters will be passed to the event object/table + on_step = function(event) end, + --this function is run every game step when the event is active + on_start = function(event) end, + -- this function is run when the event starts + on_stage_begin = function(event) end, + -- this function runs when a new stage of the event starts + cond_progress = function(event) end, --return false or next stage id + --this function checks if the event should progress to the next (or any other) stage + cond_complete = function(event) end, + --return true if event finished successfully +} + +### Debugging + * /event_start -- starts the given event at the current player coordinates diff --git a/mods/CORE/mcl_events/init.lua b/mods/CORE/mcl_events/init.lua new file mode 100644 index 000000000..625076bae --- /dev/null +++ b/mods/CORE/mcl_events/init.lua @@ -0,0 +1,155 @@ +mcl_events = {} +mcl_events.registered_events = {} +local disabled_events = minetest.settings:get("mcl_disabled_events") +if disabled_events then disabled_events = disabled_events:split(",") +else disabled_events = {} end +local DBG = minetest.settings:get_bool("mcl_logging_event_api",false) +local active_events = {} + +local event_tpl = { + stage = 0, + max_stage = 1, + percent = 100, + bars = {}, + completed = false, + cond_start = function(event) end, --return table of positions + on_step = function(event) end, + on_start = function(event) end, + on_stage_begin = function(event) end, + cond_progress = function(event) end, --return next stage + cond_complete = function(event) end, --return success +} + +local function mcl_log(m,l) + if DBG then + if not l then l = "action" end + minetest.log(l,"[mcl_events] "..m) + end +end + +function mcl_events.register_event(name,def) + if table.indexof(disabled_events,name) ~= -1 then return end + mcl_events.registered_events[name] = def + mcl_events.registered_events[name].name = name +end + +local function addbars(self) + if not self.enable_bossbar then return end + for _,player in pairs(minetest.get_connected_players()) do + if vector.distance(self.pos,player:get_pos()) < 64 then + local bar = mcl_bossbars.add_bar(player, {color = "red", text = self.readable_name .. ": Wave "..self.stage.." / "..self.max_stage, percentage = self.percent }, true,1) + table.insert(self.bars,bar) + end + end +end + +local function start_event(p,e) + mcl_log("[mcl_events] Event started: "..e.readable_name.." at "..minetest.pos_to_string(vector.round(p.pos))) + local idx = #active_events + 1 + active_events[idx] = table.copy(e) + setmetatable(active_events[idx],{__index = event_tpl}) + for k,v in pairs(p) do active_events[idx][k] = v end + active_events[idx].stage = 0 + active_events[idx].percent = 100 + active_events[idx].bars = {} + active_events[idx].time_start = os.time() + if active_events[idx].on_start then + active_events[idx]:on_start(p.pos) + end + addbars(active_events[idx]) +end + +local function finish_event(self,idx) + mcl_log("[mcl_events] Finished: "..self.readable_name.." at "..minetest.pos_to_string(vector.round(self.pos))) + if self.on_complete then self:on_complete() end + for _,b in pairs(self.bars) do + mcl_bossbars.remove_bar(b) + end + table.remove(active_events,idx) +end + +local etime = 0 +function check_events(dtime) + --process active events + for idx,ae in pairs(active_events) do + if ae.cond_complete and ae:cond_complete() then + ae.finished = true + finish_event(ae,idx) + elseif not ae.cond_complete and ae.max_stage and ae.max_stage <= ae.stage then + ae.finished = true + finish_event(ae,idx) + elseif not ae.finished and ae.cond_progress then + local p = ae:cond_progress() + if p == true then + ae.stage = ae.stage + 1 + if ae:on_stage_begin() == true then + mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." failed at stage_begin of stage "..ae.stage ) + active_events[idx] = nil + end + elseif tonumber(p) then + ae.stage = tonumber(p) or ae.stage + 1 + ae:on_stage_begin() + end + elseif not ae.finished and ae.on_step then + ae:on_step(dtime) + end + addbars(ae) + end + -- check if a new event should be started + etime = etime - dtime + if etime > 0 then return end + etime = 10 + for _,e in pairs(mcl_events.registered_events) do + local pp = e.cond_start() + if pp then + --minetest.log("It's gonna start the raid maybe") + for _,p in pairs(pp) do + local start = true + if e.exclusive_to_area then + for _,ae in pairs(active_events) do + if e.name == ae.name and vector.distance(p.pos,ae.pos) < e.exclusive_to_area then start = false end + end + end + if start then + --minetest.log("It's gonna start the raid definitely") + start_event(p,e) + elseif DBG then + mcl_log("[mcl_events] Event "..e.readable_name.." already active at "..minetest.pos_to_string(vector.round(p.pos))) + end + end + else + --minetest.log("Do not start this raid") + end + end + for idx,ae in pairs(active_events) do + local player_near = false + for _,pl in pairs(minetest.get_connected_players()) do + if ae.pos and vector.distance(pl:get_pos(),ae.pos) < 64 then player_near = true end + end + if ae.pos and not player_near then + mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." aborted - no players near." ) + active_events[idx] = nil + end + end +end + +minetest.register_globalstep(check_events) + +mcl_info.register_debug_field("Active Events",{ + level = 4, + func = function(pl,pos) + return tostring(#active_events) + end +}) + +minetest.register_chatcommand("event_start",{ + privs = {debug = true}, + description = "Debug command to start events", + func = function(pname,param) + local p = minetest.get_player_by_name(pname) + local evdef = mcl_events.registered_events[param] + if not evdef then return false,"Event "..param.." doesn't exist.'" end + start_event({pos=p:get_pos(),player=pname,factor=1},evdef) + return true,"Started event "..param + end, +}) diff --git a/mods/CORE/mcl_events/mod.conf b/mods/CORE/mcl_events/mod.conf new file mode 100644 index 000000000..29a45628a --- /dev/null +++ b/mods/CORE/mcl_events/mod.conf @@ -0,0 +1,3 @@ +name = mcl_events +author = cora +depends = mcl_mobs,mcl_bossbars, mcl_info diff --git a/mods/CORE/mcl_explosions/API.md b/mods/CORE/mcl_explosions/API.md new file mode 100644 index 000000000..cb0e9252d --- /dev/null +++ b/mods/CORE/mcl_explosions/API.md @@ -0,0 +1,15 @@ +# mcl_explosions +This mod provide helper functions to create explosions. + +## mcl_explosions.explode(pos, strength, info, puncher) +* pos: position, initial position of the explosion +* strenght: number, radius of the explosion +* info: table, explosion informations: + * drop_chance: number, if specified becomes the drop chance of all nodes in the explosion (default: 1.0 / strength) + * max_blast_resistance: int, if specified the explosion will treat all non-indestructible nodes as having a blast resistance of no more than this value + * sound: bool, if true, the explosion will play a sound (default: true) + * particles: bool, if true, the explosion will create particles (default: true) + * fire: bool, if true, 1/3 nodes become fire (default: false) + * griefing: bool, if true, the explosion will destroy nodes (default: true) + * grief_protected: bool, if true, the explosion will also destroy nodes which have been protected (default: false) +* puncher: (optional) entity, will be used as source for damage done by the explosion \ No newline at end of file diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index b23489861..c6a6d192f 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -12,11 +12,24 @@ under the LGPLv2.1 license. mcl_explosions = {} -local mod_death_messages = minetest.get_modpath("mcl_death_messages") ~= nil -local mod_fire = minetest.get_modpath("mcl_fire") ~= nil -local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") +local mod_fire = minetest.get_modpath("mcl_fire") +local explosions_griefing = minetest.settings:get_bool("mcl_explosions_griefing", true) +--local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") -local S = minetest.get_translator("mcl_explosions") +local math = math +local vector = vector +local table = table + +local hash_node_position = minetest.hash_node_position +local get_objects_inside_radius = minetest.get_objects_inside_radius +local get_position_from_hash = minetest.get_position_from_hash +local get_node_drops = minetest.get_node_drops +local get_name_from_content_id = minetest.get_name_from_content_id +local get_voxel_manip = minetest.get_voxel_manip +local bulk_set_node = minetest.bulk_set_node +local check_for_falling = minetest.check_for_falling +local add_item = minetest.add_item +local pos_to_string = minetest.pos_to_string -- Saved sphere explosion shapes for various radiuses local sphere_shapes = {} @@ -57,46 +70,44 @@ local function compute_sphere_rays(radius) local rays = {} local sphere = {} - for i=1, 2 do + local function add_ray(pos) + sphere[hash_node_position(pos)] = pos + end + + for y = -radius, radius do + for z = -radius, radius do + for x = -radius, 0 do + local d = x * x + y * y + z * z + if d <= radius * radius then + add_ray(vector.new(x, y, z)) + add_ray(vector.new(-x, y, z)) + break + end + end + end + end + + for x = -radius, radius do + for z = -radius, radius do + for y = -radius, 0 do + local d = x * x + y * y + z * z + if d <= radius * radius then + add_ray(vector.new(x, y, z)) + add_ray(vector.new(x, -y, z)) + break + end + end + end + end + + for x = -radius, radius do for y = -radius, radius do - for z = -radius, radius do - for x = -radius, 0, 1 do - local d = x * x + y * y + z * z - if d <= radius * radius then - local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos - break - end - end - end - end - end - - for i=1,2 do - for x = -radius, radius do - for z = -radius, radius do - for y = -radius, 0, 1 do - local d = x * x + y * y + z * z - if d <= radius * radius then - local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos - break - end - end - end - end - end - - for i=1,2 do - for x = -radius, radius do - for y = -radius, radius do - for z = -radius, 0, 1 do - local d = x * x + y * y + z * z - if d <= radius * radius then - local pos = { x = x, y = y, z = z } - sphere[minetest.hash_node_position(pos)] = pos - break - end + for z = -radius, 0 do + local d = x * x + y * y + z * z + if d <= radius * radius then + add_ray(vector.new(x, y, z)) + add_ray(vector.new(x, y, -z)) + break end end end @@ -120,10 +131,10 @@ local function add_particles(pos, radius) time = 0.125, minpos = pos, maxpos = pos, - minvel = {x = -radius, y = -radius, z = -radius}, - maxvel = {x = radius, y = radius, z = radius}, - minacc = vector.new(), - maxacc = vector.new(), + minvel = vector.new(-radius, -radius, -radius), + maxvel = vector.new(radius, radius, radius), + minacc = vector.zero(), + maxacc = vector.zero(), minexptime = 0.5, maxexptime = 1.0, minsize = radius * 0.5, @@ -140,7 +151,8 @@ end -- raydirs - The directions for each ray -- radius - The maximum distance each ray will go -- info - Table containing information about explosion --- puncher - object that punches other objects (optional) +-- direct - direct source object of the damage (optional) +-- source - indirect source object of the damage (optional) -- -- Values in info: -- drop_chance - The chance that destroyed nodes will drop their items @@ -149,12 +161,14 @@ end -- max_blast_resistance - The explosion will treat all non-indestructible nodes -- as having a blast resistance of no more than this -- value +-- grief_protected - If true, the explosion will also destroy nodes which have +-- been protected -- -- Note that this function has been optimized, it contains code which has been -- inlined to avoid function calls and unnecessary table creation. This was -- measured to give a significant performance increase. -local function trace_explode(pos, strength, raydirs, radius, info, puncher) - local vm = minetest.get_voxel_manip() +local function trace_explode(pos, strength, raydirs, radius, info, direct, source) + local vm = get_voxel_manip() local emin, emax = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius)) @@ -164,23 +178,21 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local ystride = (emax.x - emin_x + 1) local zstride = ystride * (emax.y - emin_y + 1) - local pos_x = pos.x - local pos_y = pos.y - local pos_z = pos.z - local area = VoxelArea:new { + --[[local area = VoxelArea:new { MinEdge = emin, MaxEdge = emax - } + }]] local data = vm:get_data() local destroy = {} local drop_chance = info.drop_chance local fire = info.fire local max_blast_resistance = info.max_blast_resistance + local grief_protected = info.grief_protected -- Trace rays for environment destruction - if info.griefing then + if info.griefing and explosions_griefing then for i = 1, #raydirs do local rpos_x = pos.x local rpos_y = pos.y @@ -194,16 +206,17 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local npos_x = math.floor(rpos_x + 0.5) local npos_y = math.floor(rpos_y + 0.5) local npos_z = math.floor(rpos_z + 0.5) + local npos = { x = npos_x, y = npos_y, z = npos_z } local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + - npos_x - emin_x + 1 + npos_x - emin_x + 1 local cid = data[idx] - local br = node_blastres[cid] + local br = node_blastres[cid] or INDESTRUCT_BLASTRES if br < INDESTRUCT_BLASTRES and br > max_blast_resistance then br = max_blast_resistance end - local hash = minetest.hash_node_position({x=npos_x, y=npos_y, z=npos_z}) + local hash = hash_node_position(npos) rpos_x = rpos_x + STEP_LENGTH * rdir_x rpos_y = rpos_y + STEP_LENGTH * rdir_y @@ -215,8 +228,10 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) break end - if cid ~= minetest.CONTENT_AIR and not minetest.is_protected({x = npos_x, y = npos_y, z = npos_z}, "") then - destroy[hash] = idx + if cid ~= minetest.CONTENT_AIR then + if not minetest.is_protected(npos, "") or grief_protected then + destroy[hash] = idx + end end end end @@ -224,14 +239,14 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) -- Entities in radius of explosion local punch_radius = 2 * strength - local objs = minetest.get_objects_inside_radius(pos, punch_radius) + local objs = get_objects_inside_radius(pos, punch_radius) -- Trace rays for entity damage for _, obj in pairs(objs) do local ent = obj:get_luaentity() -- Ignore items to lower lag - if obj:is_player() or (ent and ent.name ~= '__builtin.item') then + if (obj:is_player() or (ent and ent.name ~= "__builtin.item")) and obj:get_hp() > 0 then local opos = obj:get_pos() local collisionbox = nil @@ -244,20 +259,20 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) if collisionbox then -- Create rays from random points in the collision box - local x1 = collisionbox[1] * 2 - local y1 = collisionbox[2] * 2 - local z1 = collisionbox[3] * 2 - local x2 = collisionbox[4] * 2 - local y2 = collisionbox[5] * 2 - local z2 = collisionbox[6] * 2 + local x1 = collisionbox[1] + local y1 = collisionbox[2] + local z1 = collisionbox[3] + local x2 = collisionbox[4] + local y2 = collisionbox[5] + local z2 = collisionbox[6] local x_len = math.abs(x2 - x1) local y_len = math.abs(y2 - y1) local z_len = math.abs(z2 - z1) -- Move object position to the center of its bounding box - opos.x = opos.x + x1 + x2 - opos.y = opos.y + y1 + y2 - opos.z = opos.z + z1 + z2 + opos.x = opos.x + 0.5 * (x1 + x2) + opos.y = opos.y + 0.5 * (y1 + y2) + opos.z = opos.z + 0.5 * (z1 + z2) -- Count number of rays from collision box which are unobstructed local count = N_EXPOSURE_RAYS @@ -274,7 +289,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) rdir_y = rdir_y / rdir_len rdir_z = rdir_z / rdir_len - for i=0, rdir_len / STEP_LENGTH do + for i = 0, rdir_len / STEP_LENGTH do rpos_x = rpos_x + rdir_x * STEP_LENGTH rpos_y = rpos_y + rdir_y * STEP_LENGTH rpos_z = rpos_z + rdir_z * STEP_LENGTH @@ -282,7 +297,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local npos_y = math.floor(rpos_y + 0.5) local npos_z = math.floor(rpos_z + 0.5) local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + - npos_x - emin_x + 1 + npos_x - emin_x + 1 local cid = data[idx] @@ -305,7 +320,6 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) impact = 0 end local damage = math.floor((impact * impact + impact) * 7 * strength + 1) - local source = puncher or obj local sleep_formspec_doesnt_close_mt53 = false if obj:is_player() then @@ -317,31 +331,44 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) sleep_formspec_doesnt_close_mt53 = true end end - if mod_death_messages then - mcl_death_messages.player_damage(obj, S("@1 was caught in an explosion.", name)) - end - if rawget(_G, "armor") and armor.last_damage_types then - armor.last_damage_types[name] = "explosion" - end end if sleep_formspec_doesnt_close_mt53 then - minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE - if not obj then return end - obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) - obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) - end, obj, damage, impact, vector.new(punch_dir)) - else - obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) + minetest.after(0.3, + function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE + if not obj:is_player() then + return + end + mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source }) - if obj:is_player() then - obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) - elseif ent.tnt_knockback then + obj:add_velocity(vector.multiply(punch_dir, impact * 20)) + end) + else + mcl_util.deal_damage(obj, damage, { type = "explosion", direct = direct, source = source }) + + if obj:is_player() or ent.tnt_knockback then obj:add_velocity(vector.multiply(punch_dir, impact * 20)) end end end end + + -- Punch End Crystals to make them explode + if ent and ent.name == "mcl_end:crystal" then + if direct then + local puncher = direct:get_luaentity() + if puncher and puncher.name == "mcl_end:crystal" then + ent.object:punch(direct, 1.0, { -- End Crystal nearby, trigger it. + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil, nil) + else + ent.object:remove() -- Direct Exists, but it is not an end crystal, remove crystal. + end + else + ent.object:remove() -- Node exploded the end crystal, remove it. + end + end end local airs, fires = {}, {} @@ -352,52 +379,52 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local on_blast = node_on_blast[data[idx]] local remove = true - if do_drop or on_blast ~= nil then - local npos = minetest.get_position_from_hash(hash) - if on_blast ~= nil then + if do_drop or on_blast then + local npos = get_position_from_hash(hash) + if on_blast then on_blast(npos, 1.0, do_drop) remove = false else - local name = minetest.get_name_from_content_id(data[idx]) - local drop = minetest.get_node_drops(name, "") + local name = get_name_from_content_id(data[idx]) + local drop = get_node_drops(name, "") for _, item in ipairs(drop) do if type(item) ~= "string" then item = item:get_name() .. item:get_count() end - minetest.add_item(npos, item) + add_item(npos, item) end end end if remove then if mod_fire and fire and math.random(1, 3) == 1 then - table.insert(fires, minetest.get_position_from_hash(hash)) + table.insert(fires, get_position_from_hash(hash)) else - table.insert(airs, minetest.get_position_from_hash(hash)) + table.insert(airs, get_position_from_hash(hash)) end end end -- We use bulk_set_node instead of LVM because we want to have on_destruct and -- on_construct being called if #airs > 0 then - minetest.bulk_set_node(airs, {name="air"}) + bulk_set_node(airs, { name = "air" }) end if #fires > 0 then - minetest.bulk_set_node(fires, {name="mcl_fire:fire"}) + bulk_set_node(fires, { name = "mcl_fire:fire" }) end -- Update falling nodes - for a=1, #airs do + for a = 1, #airs do local p = airs[a] - minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling(vector.offset(p, 0, 1, 0)) end - for f=1, #fires do + for f = 1, #fires do local p = fires[f] - minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) + check_for_falling(vector.offset(p, 0, 1, 0)) end -- Log explosion - minetest.log('action', 'Explosion at ' .. minetest.pos_to_string(pos) .. - ' with strength ' .. strength .. ' and radius ' .. radius) + minetest.log("action", "Explosion at " .. pos_to_string(pos) .. " with strength " .. strength .. " and radius " .. + radius) end -- Create an explosion with strength at pos. @@ -406,7 +433,8 @@ end -- pos - The position where the explosion originates from -- strength - The blast strength of the explosion (a TNT explosion uses 4) -- info - Table containing information about explosion --- puncher - object that is reported as source of punches/damage (optional) +-- direct - direct source object of the damage (optional) +-- source - indirect source object of the damage (optional) -- -- Values in info: -- drop_chance - If specified becomes the drop chance of all nodes in the @@ -418,7 +446,14 @@ end -- particles - If true, the explosion will create particles (default: true) -- fire - If true, 1/3 nodes become fire (default: false) -- griefing - If true, the explosion will destroy nodes (default: true) -function mcl_explosions.explode(pos, strength, info, puncher) +-- grief_protected - If true, the explosion will also destroy nodes which have +-- been protected (default: false) +---@param pos Vector +---@param strength number +---@param info {drop_chance: number, max_blast_resistance: number, sound: boolean, particles: boolean, fire: boolean, griefing: boolean, grief_protected: boolean} +---@param direct? ObjectRef +---@param source? ObjectRef +function mcl_explosions.explode(pos, strength, info, direct, source) if info == nil then info = {} end @@ -437,20 +472,17 @@ function mcl_explosions.explode(pos, strength, info, puncher) if info.sound == nil then info.sound = true end if info.fire == nil then info.fire = false end if info.griefing == nil then info.griefing = true end + if info.grief_protected == nil then info.grief_protected = false end if info.max_blast_resistance == nil then info.max_blast_resistance = INDESTRUCT_BLASTRES end - -- For backwards compatibility - if info.no_particle then info.particles = false end - if info.no_sound then info.sound = false end - -- Dont do drops in creative mode if minetest.is_creative_enabled("") then info.drop_chance = 0 end - trace_explode(pos, strength, shape, radius, info, puncher) + trace_explode(pos, strength, shape, radius, info, direct, source) if info.particles then add_particles(pos, radius) diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.de.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.de.tr deleted file mode 100644 index 4abbc64bf..000000000 --- a/mods/CORE/mcl_explosions/locale/mcl_explosions.de.tr +++ /dev/null @@ -1,2 +0,0 @@ -# textdomain:mcl_explosions -@1 was caught in an explosion.=@1 wurde Opfer einer Explosion. diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr index cb9a0f38e..7804d608c 100644 --- a/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.fr.tr @@ -1,2 +1,2 @@ # textdomain:mcl_explosions -@1 was caught in an explosion.=@1 a été pris dans une explosion. \ No newline at end of file +@1 was caught in an explosion.=@1 est mort dans une explosion \ No newline at end of file diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr new file mode 100644 index 000000000..ce59ab4b3 --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.ja.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1は爆発に巻き込まれた。 diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.pl.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.pl.tr new file mode 100644 index 000000000..f7811d733 --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.pl.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1 została wysadzona. diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr deleted file mode 100644 index 2c885845f..000000000 --- a/mods/CORE/mcl_explosions/locale/mcl_explosions.ru.tr +++ /dev/null @@ -1,2 +0,0 @@ -# textdomain:mcl_explosions -@1 was caught in an explosion.=@1 не удалось пережить взрыва. diff --git a/mods/CORE/mcl_explosions/locale/mcl_explosions.zh_TW.tr b/mods/CORE/mcl_explosions/locale/mcl_explosions.zh_TW.tr new file mode 100644 index 000000000..9cac9b412 --- /dev/null +++ b/mods/CORE/mcl_explosions/locale/mcl_explosions.zh_TW.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_explosions +@1 was caught in an explosion.=@1 被炸飛了 diff --git a/mods/CORE/mcl_explosions/locale/template.txt b/mods/CORE/mcl_explosions/locale/template.txt index 6a9348ddf..656b444f9 100644 --- a/mods/CORE/mcl_explosions/locale/template.txt +++ b/mods/CORE/mcl_explosions/locale/template.txt @@ -1,2 +1,2 @@ # textdomain:mcl_explosions -@1 was caught in an explosion.= +@1 was caught in an explosion.= \ No newline at end of file diff --git a/mods/CORE/mcl_explosions/mod.conf b/mods/CORE/mcl_explosions/mod.conf index 4ec206e17..5c203e621 100644 --- a/mods/CORE/mcl_explosions/mod.conf +++ b/mods/CORE/mcl_explosions/mod.conf @@ -1,4 +1,5 @@ name = mcl_explosions +author = ryvnf description = A common API to create explosions. depends = mcl_particles optional_depends = mcl_fire diff --git a/mods/CORE/mcl_init/description.txt b/mods/CORE/mcl_init/description.txt deleted file mode 100644 index 4ab7458f1..000000000 --- a/mods/CORE/mcl_init/description.txt +++ /dev/null @@ -1 +0,0 @@ -Initialization mod of MineClone 2. 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_init/init.lua b/mods/CORE/mcl_init/init.lua index ebbfd5591..f77b03828 100644 --- a/mods/CORE/mcl_init/init.lua +++ b/mods/CORE/mcl_init/init.lua @@ -3,23 +3,26 @@ mcl_vars = {} mcl_vars.redstone_tick = 0.1 ---- GUI / inventory menu settings +-- GUI / inventory menu settings mcl_vars.gui_slots = "listcolors[#9990;#FFF7;#FFF0;#000;#FFF]" + -- nonbg is added as formspec prepend in mcl_formspec_prepend -mcl_vars.gui_nonbg = mcl_vars.gui_slots .. - "style_type[image_button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]".. - "style_type[button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]".. - "style_type[field;textcolor=#323232]".. - "style_type[label;textcolor=#323232]".. - "style_type[textarea;textcolor=#323232]".. - "style_type[checkbox;textcolor=#323232]" +mcl_vars.gui_nonbg = table.concat({ + mcl_vars.gui_slots, + "style_type[image_button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]", + "style_type[button;border=false;bgimg=mcl_inventory_button9.png;bgimg_pressed=mcl_inventory_button9_pressed.png;bgimg_middle=2,2]", + "style_type[field;textcolor=#323232]", + "style_type[label;textcolor=#323232]", + "style_type[textarea;textcolor=#323232]", + "style_type[checkbox;textcolor=#323232]", +}) -- Background stuff must be manually added by mods (no formspec prepend) mcl_vars.gui_bg_color = "bgcolor[#00000000]" mcl_vars.gui_bg_img = "background9[1,1;1,1;mcl_base_textures_background9.png;true;7]" --- Legacy -mcl_vars.inventory_header = "" +-- Tool wield size +mcl_vars.tool_wield_scale = vector.new(1.8, 1.8, 1) -- Mapgen variables local mg_name = minetest.get_mapgen_setting("mg_name") @@ -29,22 +32,73 @@ local singlenode = mg_name == "singlenode" -- Calculate mapgen_edge_min/mapgen_edge_max mcl_vars.chunksize = math.max(1, tonumber(minetest.get_mapgen_setting("chunksize")) or 5) -mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16) +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, core.MAX_MAP_GENERATION_LIMIT or 31000) +mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, minetest.MAX_MAP_GENERATION_LIMIT or 31000) + local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2) -local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE + +mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE +mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE + local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE -local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1 +local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1 local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE -local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE) +local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / + mcl_vars.MAP_BLOCKSIZE) local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1 -local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk -local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. -mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes -mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes +local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk +local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits. + +mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes +mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes + +---@param x integer +---@return integer +local function coordinate_to_block(x) + return math.floor(x / mcl_vars.MAP_BLOCKSIZE) +end + +---@param x integer +---@return integer +local function coordinate_to_chunk(x) + return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize) +end + +---@param pos Vector +---@return Vector +function mcl_vars.pos_to_block(pos) + return vector.new( + coordinate_to_block(pos.x), + coordinate_to_block(pos.y), + coordinate_to_block(pos.z) + ) +end + +---@param pos Vector +---@return Vector +function mcl_vars.pos_to_chunk(pos) + return vector.new( + coordinate_to_chunk(pos.x), + coordinate_to_chunk(pos.y), + coordinate_to_chunk(pos.z) + ) +end + +local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes) +local k_positive_z = k_positive * 2 +local k_positive_y = k_positive_z * k_positive_z + +---@param pos Vector +---@return integer +function mcl_vars.get_chunk_number(pos) -- unsigned int + local c = mcl_vars.pos_to_chunk(pos) + return (c.y + k_positive) * k_positive_y + + (c.z + k_positive) * k_positive_z + + c.x + k_positive +end if not superflat and not singlenode then -- Normal mode @@ -77,11 +131,8 @@ elseif singlenode then mcl_vars.mg_bedrock_is_rough = false else -- Classic superflat - local ground = minetest.get_mapgen_setting("mgflat_ground_level") - ground = tonumber(ground) - if not ground then - ground = 8 - end + local ground = tonumber(minetest.get_mapgen_setting("mgflat_ground_level")) or 8 + mcl_vars.mg_overworld_min = ground - 3 mcl_vars.mg_overworld_max_official = mcl_vars.mg_overworld_min + minecraft_height_limit mcl_vars.mg_bedrock_overworld_min = mcl_vars.mg_overworld_min @@ -91,13 +142,14 @@ else mcl_vars.mg_bedrock_is_rough = false end -mcl_vars.mg_overworld_max = 31000 +mcl_vars.mg_overworld_max = mcl_vars.mapgen_edge_max -- The Nether (around Y = -29000) mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border mcl_vars.mg_nether_max = mcl_vars.mg_nether_min + 128 mcl_vars.mg_bedrock_nether_bottom_min = mcl_vars.mg_nether_min mcl_vars.mg_bedrock_nether_top_max = mcl_vars.mg_nether_max +mcl_vars.mg_nether_deco_max = mcl_vars.mg_nether_max -11 -- this is so ceiling decorations don't spill into other biomes as bedrock generation calls minetest.generate_decorations to put netherrack under the bedrock if not superflat then mcl_vars.mg_bedrock_nether_bottom_max = mcl_vars.mg_bedrock_nether_bottom_min + 4 mcl_vars.mg_bedrock_nether_top_min = mcl_vars.mg_bedrock_nether_top_max - 4 @@ -122,7 +174,8 @@ end mcl_vars.mg_end_min = -27073 -- Carefully chosen to be at a mapchunk border mcl_vars.mg_end_max_official = mcl_vars.mg_end_min + minecraft_height_limit mcl_vars.mg_end_max = mcl_vars.mg_overworld_min - 2000 -mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 74, z = 0 } +mcl_vars.mg_end_platform_pos = { x = 100, y = mcl_vars.mg_end_min + 64, z = 0 } +mcl_vars.mg_end_exit_portal_pos = vector.new(0, mcl_vars.mg_end_min + 71, 0) -- Realm barrier used to safely separate the End from the void below the Overworld mcl_vars.mg_realm_barrier_overworld_end_max = mcl_vars.mg_end_max @@ -138,3 +191,90 @@ minetest.craftitemdef_default.stack_max = 64 -- Set random seed for all other mods (Remember to make sure no other mod calls this function) math.randomseed(os.time()) +local chunks = {} -- intervals of chunks generated + +---@param pos Vector +function mcl_vars.add_chunk(pos) + local n = mcl_vars.get_chunk_number(pos) -- unsigned int + local prev + for i, d in pairs(chunks) do + if n <= d[2] then -- we've found it + if (n == d[2]) or (n >= d[1]) then return end -- already here + if n == d[1] - 1 then -- right before: + if prev and (prev[2] == n - 1) then + prev[2] = d[2] + table.remove(chunks, i) + return + end + d[1] = n + return + end + if prev and (prev[2] == n - 1) then --join to previous + prev[2] = n + return + end + table.insert(chunks, i, { n, n }) -- insert new interval before i + return + end + prev = d + end + chunks[#chunks + 1] = { n, n } +end + +---@param pos Vector +---@return boolean +function mcl_vars.is_generated(pos) + local n = mcl_vars.get_chunk_number(pos) -- unsigned int + for i, d in pairs(chunks) do + if n <= d[2] then + return (n >= d[1]) + end + end + return false +end + +---"Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like mt 5.4 does. +---@param pos Vector Position, if it's wrong, `{name="error"}` node will return. +---@param force? boolean Optional (default: `false`), Do the maximum to still read the node within us_timeout. +---@param us_timeout? number Optional (default: `244 = 0.000244 s = 1/80/80/80`), set it at least to `3000000` to let mapgen to finish its job +---@return node # Node definition, eg. `{name="air"}`. Unfortunately still can return `{name="ignore"}`. +---@nodiscard +function mcl_vars.get_node(pos, force, us_timeout) + -- check initial circumstances + if not pos or not pos.x or not pos.y or not pos.z then return { name = "error" } end + + -- try common way + local node = minetest.get_node(pos) + if node.name ~= "ignore" then + return node + end + + -- copy vector to get sure it won't changed by other threads + local pos_copy = vector.copy(pos) + + -- try LVM + minetest.get_voxel_manip():read_from_map(pos_copy, pos_copy) + node = minetest.get_node(pos_copy) + if node.name ~= "ignore" or not force then + return node + end + + -- all ways failed - need to emerge (or forceload if generated) + if mcl_vars.is_generated(pos_copy) then + minetest.chat_send_all("IMPOSSIBLE! Please report this to MCL2 issue tracker!") + minetest.forceload_block(pos_copy) + else + minetest.emerge_area(pos_copy, pos_copy) + end + + local t = minetest.get_us_time() + + node = minetest.get_node(pos_copy) + + while (not node or node.name == "ignore") and (minetest.get_us_time() - t < (us_timeout or 244)) do + node = minetest.get_node(pos_copy) + end + + return node + -- it still can return "ignore", LOL, even if force = true, but only after time out +end diff --git a/mods/CORE/mcl_init/mod.conf b/mods/CORE/mcl_init/mod.conf index 5a3e4b6b2..a0e810a2f 100644 --- a/mods/CORE/mcl_init/mod.conf +++ b/mods/CORE/mcl_init/mod.conf @@ -1 +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. diff --git a/mods/CORE/mcl_loot/description.txt b/mods/CORE/mcl_loot/description.txt deleted file mode 100644 index 30ba9a6f3..000000000 --- a/mods/CORE/mcl_loot/description.txt +++ /dev/null @@ -1 +0,0 @@ -API for filling a chest with random treasures. diff --git a/mods/CORE/mcl_loot/init.lua b/mods/CORE/mcl_loot/init.lua index e3db73be1..b90cd4428 100644 --- a/mods/CORE/mcl_loot/init.lua +++ b/mods/CORE/mcl_loot/init.lua @@ -40,10 +40,9 @@ function mcl_loot.get_loot(loot_definitions, pr) total_weight = total_weight + (loot_definitions.items[i].weight or 1) end - local stacks_min = loot_definitions.stacks_min - local stacks_max = loot_definitions.stacks_max - if not stacks_min then stacks_min = 1 end - if not stacks_max then stacks_max = 1 end + --local stacks_min = loot_definitions.stacks_min or 1 + --local stacks_max = loot_definitions.stacks_max or 1 + local stacks = pr:next(loot_definitions.stacks_min, loot_definitions.stacks_max) for s=1, stacks do local r = pr:next(1, total_weight) @@ -59,26 +58,27 @@ function mcl_loot.get_loot(loot_definitions, pr) end if item then local itemstring = item.itemstring - local itemstack = item.itemstack + if itemstring then + local stack = ItemStack(itemstring) + if item.amount_min and item.amount_max then - itemstring = itemstring .. " " .. pr:next(item.amount_min, item.amount_max) + stack:set_count(pr:next(item.amount_min, item.amount_max)) end + if item.wear_min and item.wear_max then -- Sadly, PseudoRandom only allows very narrow ranges, so we set wear in steps of 10 local wear_min = math.floor(item.wear_min / 10) local wear_max = math.floor(item.wear_max / 10) - local wear = pr:next(wear_min, wear_max) * 10 - if not item.amount_min and not item.amount_max then - itemstring = itemstring .. " 1" - end - - itemstring = itemstring .. " " .. tostring(wear) + stack:set_wear(pr:next(wear_min, wear_max) * 10) end - table.insert(items, itemstring) - elseif itemstack then - table.insert(items, itemstack) + + if item.func then + item.func(stack, pr) + end + + table.insert(items, stack) else minetest.log("error", "[mcl_loot] INTERNAL ERROR! Failed to select random loot item!") end @@ -111,14 +111,14 @@ end Returns a table of length `max_slot` and all natural numbers between 1 and `max_slot` in a random order. ]] -local function get_random_slots(max_slot) +local function get_random_slots(max_slot, pr) local slots = {} for s=1, max_slot do slots[s] = s end local slots_out = {} while #slots > 0 do - local r = math.random(1, #slots) + local r = pr and pr:next(1, #slots) or math.random(1, #slots) table.insert(slots_out, slots[r]) table.remove(slots, r) end @@ -135,9 +135,9 @@ Items will be added from start of the table to end. If the inventory already has occupied slots, or is too small, placement of some items might fail. ]] -function mcl_loot.fill_inventory(inv, listname, items) +function mcl_loot.fill_inventory(inv, listname, items, pr) local size = inv:get_size(listname) - local slots = get_random_slots(size) + local slots = get_random_slots(size, pr) local leftovers = {} -- 1st pass: Add items into random slots for i=1, math.min(#items, size) do diff --git a/mods/CORE/mcl_loot/mod.conf b/mods/CORE/mcl_loot/mod.conf index 8406dcc2f..82a41d0e5 100644 --- a/mods/CORE/mcl_loot/mod.conf +++ b/mods/CORE/mcl_loot/mod.conf @@ -1 +1,3 @@ name = mcl_loot +author = Wuzzy +description = API for filling a chest with random treasures. diff --git a/mods/CORE/mcl_oxidation/README.md b/mods/CORE/mcl_oxidation/README.md new file mode 100644 index 000000000..3f3291b19 --- /dev/null +++ b/mods/CORE/mcl_oxidation/README.md @@ -0,0 +1,14 @@ +# Oxidization API for MineClone 2 +This mods adds the oxidization api, so that modders can easily use the same features that copper uses. + +## API +To take advantage of the actual oxidization, put `oxidizable = 1` into the list of groups for the oxidizable node. +You would also need to put `_mcl_oxidized_variant = itemstring of node this node will oxidize into` into the node definition. +For example, a copper block oxidizes into exposed copper, so the defintion would be `_mcl_oxidized_variant = "mcl_copper:block_exposed"`. + +To utilize the ability to wax the block for protection from oxidization, put `mcl_waxed_variant = item string of waxed variant of node` into the node definition table. +For example, Copper Blocks have the definition arguement of `_mcl_waxed_variant = "mcl_copper:waxed_block"`. + +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"`. diff --git a/mods/CORE/mcl_oxidation/init.lua b/mods/CORE/mcl_oxidation/init.lua new file mode 100644 index 000000000..201d0260a --- /dev/null +++ b/mods/CORE/mcl_oxidation/init.lua @@ -0,0 +1,12 @@ +minetest.register_abm({ + label = "Oxidatize Nodes", + nodenames = { "group:oxidizable" }, + interval = 500, + chance = 3, + action = function(pos, node) + local def = minetest.registered_nodes[node.name] + if def and def._mcl_oxidized_variant then + minetest.set_node(pos, { name = def._mcl_oxidized_variant, param2 = node.param2 }) + end + end, +}) diff --git a/mods/CORE/mcl_oxidation/mod.conf b/mods/CORE/mcl_oxidation/mod.conf new file mode 100644 index 000000000..7ab7eeffe --- /dev/null +++ b/mods/CORE/mcl_oxidation/mod.conf @@ -0,0 +1,4 @@ +name = mcl_oxidation +title = Oxidation API for MineClone 2 +author = PrairieWind, N011, Michael +description = API to allow oxidizing different nodes. diff --git a/mods/CORE/mcl_particles/description.txt b/mods/CORE/mcl_particles/description.txt deleted file mode 100644 index 62d5cd61a..000000000 --- a/mods/CORE/mcl_particles/description.txt +++ /dev/null @@ -1 +0,0 @@ -Contains particle images of MineClone 2. No code. diff --git a/mods/CORE/mcl_particles/init.lua b/mods/CORE/mcl_particles/init.lua index 757c0452f..4854afd54 100644 --- a/mods/CORE/mcl_particles/init.lua +++ b/mods/CORE/mcl_particles/init.lua @@ -1,3 +1,12 @@ +local vector = vector +local table = table + +local hash_node_position = minetest.hash_node_position +local add_particlespawner = minetest.add_particlespawner +local delete_particlespawner = minetest.delete_particlespawner + +local ipairs = ipairs + mcl_particles = {} -- Table of particlespawner IDs on a per-node hash basis @@ -32,11 +41,11 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition, if allowed_level == 0 or levels[level] > allowed_level then return end - local poshash = minetest.hash_node_position(pos) + local poshash = hash_node_position(pos) if not poshash then return end - local id = minetest.add_particlespawner(particlespawner_definition) + local id = add_particlespawner(particlespawner_definition) if id == -1 then return end @@ -47,6 +56,8 @@ function mcl_particles.add_node_particlespawner(pos, particlespawner_definition, return id end +local add_node_particlespawner = mcl_particles.add_node_particlespawner + -- Deletes all particlespawners that are assigned to a node position. -- If no particlespawners exist for this position, nothing happens. -- pos: Node positon. MUST use integer values! @@ -55,14 +66,66 @@ function mcl_particles.delete_node_particlespawners(pos) if allowed_level == 0 then return false end - local poshash = minetest.hash_node_position(pos) + local poshash = hash_node_position(pos) local ids = particle_nodes[poshash] if ids then for i=1, #ids do - minetest.delete_particlespawner(ids[i]) + delete_particlespawner(ids[i]) end particle_nodes[poshash] = nil return true end return false end + +-- 3 exptime variants because the animation is not tied to particle expiration time. +-- 3 colorized variants to imitate minecraft's +local smoke_pdef_cached = {} + +function mcl_particles.spawn_smoke(pos, name, smoke_pdef_base) + local new_minpos = vector.add(pos, smoke_pdef_base.minrelpos) + local new_maxpos = vector.add(pos, smoke_pdef_base.maxrelpos) + + -- populate the cache + if smoke_pdef_cached[name] then + for i, smoke_pdef in ipairs(smoke_pdef_cached[name]) do + smoke_pdef.minpos = new_minpos + smoke_pdef.maxpos = new_maxpos + add_node_particlespawner(pos, smoke_pdef, "high") + end + -- cache already populated + else + smoke_pdef_cached[name] = {} + + local smoke_pdef = table.copy(smoke_pdef_base) + smoke_pdef.amount = smoke_pdef_base.amount / 9 + smoke_pdef.time = 0 + smoke_pdef.animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + -- length = 3 exptime variants + } + smoke_pdef.collisiondetection = true + smoke_pdef.minpos = new_minpos + smoke_pdef.maxpos = new_maxpos + + -- the last frame plays for 1/8 * N seconds, so we can take advantage of it + -- to have varying exptime for each variant. + local exptimes = { 0.175, 0.375, 1.0 } + local colorizes = { "199", "209", "243" } -- round(78%, 82%, 90% of 256) - 1 + + for _,exptime in ipairs(exptimes) do + for _,colorize in ipairs(colorizes) do + smoke_pdef.maxexptime = exptime * smoke_pdef_base.maxexptime + smoke_pdef.animation.length = exptime + 0.1 + -- minexptime must be set such that the last frame is actully rendered, + -- even if its very short. Larger exptime -> larger range + smoke_pdef.minexptime = math.min(exptime, (7.0/8.0 * (exptime + 0.1) + 0.1)) + smoke_pdef.texture = "mcl_particles_smoke_anim.png^[colorize:#000000:" ..colorize + add_node_particlespawner(pos, smoke_pdef, "high") + table.insert(smoke_pdef_cached[name], table.copy(smoke_pdef)) + end + end + end +end \ No newline at end of file diff --git a/mods/CORE/mcl_particles/mod.conf b/mods/CORE/mcl_particles/mod.conf index f7be80395..b8252cbc5 100644 --- a/mods/CORE/mcl_particles/mod.conf +++ b/mods/CORE/mcl_particles/mod.conf @@ -1 +1,3 @@ name = mcl_particles +author = Wuzzy +description = Contains particle images of MineClone 2. No code. diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_lava.png b/mods/CORE/mcl_particles/textures/mcl_particles_lava.png deleted file mode 100644 index b4a8fd58f..000000000 Binary files a/mods/CORE/mcl_particles/textures/mcl_particles_lava.png and /dev/null differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png b/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png deleted file mode 100644 index 6dc9cdc69..000000000 Binary files a/mods/CORE/mcl_particles/textures/mcl_particles_mob_death.png and /dev/null differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_note.png b/mods/CORE/mcl_particles/textures/mcl_particles_note.png deleted file mode 100644 index 9fb2c923a..000000000 Binary files a/mods/CORE/mcl_particles/textures/mcl_particles_note.png and /dev/null differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_smoke_anim.png b/mods/CORE/mcl_particles/textures/mcl_particles_smoke_anim.png deleted file mode 100644 index 6c85a6feb..000000000 Binary files a/mods/CORE/mcl_particles/textures/mcl_particles_smoke_anim.png and /dev/null differ diff --git a/mods/CORE/mcl_sounds/README.txt b/mods/CORE/mcl_sounds/README.txt index 9fc2ba28f..2ede2c1f9 100644 --- a/mods/CORE/mcl_sounds/README.txt +++ b/mods/CORE/mcl_sounds/README.txt @@ -11,42 +11,22 @@ Creative Commons Attribution 3.0 Unported (CC BY-SA 3.0) http://creativecommons.org/licenses/by/3.0/ Glass breaking sounds (CC BY 3.0): - 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ - 2: http://www.freesound.org/people/Tomlija/sounds/97669/ - 3: http://www.freesound.org/people/lsprice/sounds/88808/ + 1: http://www.freesound.org/people/cmusounddesign/sounds/71947/ + 2: http://www.freesound.org/people/Tomlija/sounds/97669/ + 3: http://www.freesound.org/people/lsprice/sounds/88808/ default_tool_breaks.ogg by EdgardEdition (CC BY 3.0), http://www.freesound.org/people/EdgardEdition Mito551 (sounds) (CC BY-SA 3.0): - default_dig_choppy.ogg - default_dig_cracky.ogg - default_dig_crumbly.1.ogg - default_dig_crumbly.2.ogg + default_dig_crumbly.ogg default_dig_oddly_breakable_by_hand.ogg - default_dug_node.1.ogg - default_dug_node.2.ogg - default_grass_footstep.1.ogg - default_grass_footstep.2.ogg - default_grass_footstep.3.ogg - default_gravel_footstep.1.ogg - default_gravel_footstep.2.ogg - default_gravel_footstep.3.ogg - default_gravel_footstep.4.ogg - default_grass_footstep.1.ogg - default_place_node.1.ogg - default_place_node.2.ogg - default_place_node.3.ogg - default_place_node_hard.1.ogg - default_place_node_hard.2.ogg - default_hard_footstep.1.ogg - default_hard_footstep.2.ogg - default_hard_footstep.3.ogg - default_sand_footstep.1.ogg - default_sand_footstep.2.ogg - default_wood_footstep.1.ogg - default_wood_footstep.2.ogg - default_dirt_footstep.1.ogg - default_dirt_footstep.2.ogg + default_dug_node.*.ogg + default_grass_footstep.*.ogg + default_gravel_footstep.*.ogg + default_place_node.*.ogg + default_place_node_hard.*.ogg + default_wood_footstep.*.ogg + default_dirt_footstep.*.ogg default_glass_footstep.ogg Metal sounds: @@ -54,35 +34,64 @@ Metal sounds: - https://www.freesound.org/people/yadronoff/sounds/320397/ default_dug_metal.*.ogg - Iwan Gabovitch - qubodup - CC0 - http://opengameart.org/users/qubodup - default_metal_footstep.*.ogg - Ottomaani138 - CC0 - - https://www.freesound.org/people/Ottomaani138/sounds/232692/ + default_metal_footstep.*.ogg - (CC0 1.0) - CC0 1.0 + - https://freesound.org/people/mypantsfelldown/sounds/398937/ default_place_node_metal.*.ogg - Ogrebane - CC0 - http://opengameart.org/content/wood-and-metal-sound-effects-volume-2 -AGFX (CC BY 3.0) +AGFX (CC BY 3.0): https://www.freesound.org/people/AGFX/packs/1253/ - default_water_footstep.1.ogg - default_water_footstep.2.ogg - default_water_footstep.3.ogg -(default_water_footstep.4.ogg is silent) + default_water_footstep.*.ogg -blukotek (CC0 1.0) +blukotek (CC0 1.0): https://www.freesound.org/people/blukotek/sounds/251660/ default_dig_snappy.ogg -sonictechtonic (CC BY 3.0) +sonictechtonic (CC BY 3.0): https://www.freesound.org/people/sonictechtonic/sounds/241872/ player_damage.ogg -Voxelands project (CC BY-SA 3.0) +Sheyvan (CC0 1.0): +https://freesound.org/people/Sheyvan/sounds/476113/ + default_dig_choppy.*.ogg + +lolamadeus (CC0 1.0): +https://freesound.org/people/lolamadeus/sounds/179341/ + default_gravel_dig.*.ogg + default_gravel_dug.*.ogg + +Benboncan (CC BY 3.0): +https://freesound.org/people/Benboncan/sounds/71823/ + default_dig_cracky.*.ogg + +Erdie (CC BY 3.0): +https://freesound.org/people/Erdie/sounds/41579/ + default_hard_footstep.*.ogg + +worthahep88 (CC0 1.0): +https://freesound.org/people/worthahep88/sounds/319224/ + default_sand_footstep.*.ogg + +dheming (CC BY 3.0): +https://freesound.org/people/dheming/sounds/268023/ + default_ice_dig.*.ogg + +InspectorJ (CC BY 3.0): +https://freesound.org/people/InspectorJ/sounds/416967/ + default_ice_footstep.*.ogg + +Angel_Perez_Grandi (CC BY 3.0): +https://freesound.org/people/Angel_Perez_Grandi/sounds/49190/ + default_ice_dug.ogg + +Voxelands project (CC BY-SA 3.0): mcl_sounds_place_node_water.ogg mcl_sounds_dug_water.ogg (Note: Artists from the Voxelands project include: sdzen, darkrose, sapier, Tom Peter, Telaron, juskiddink) -Michel Baradari (CC BY 3.0) - +Michel Baradari (CC BY 3.0): default_place_node_lava.ogg Adam_N (CC0 1.0): @@ -90,7 +99,7 @@ Adam_N (CC0 1.0): Source: Alecia Shepherd (CC BY-SA 4.0): - mcl_sounds_cloth.ogg + mcl_sounds_cloth.*.ogg Source: SnowSong sound and music pack Unknown authors (WTFPL): diff --git a/mods/CORE/mcl_sounds/description.txt b/mods/CORE/mcl_sounds/description.txt deleted file mode 100644 index 26c21e3b1..000000000 --- a/mods/CORE/mcl_sounds/description.txt +++ /dev/null @@ -1 +0,0 @@ -This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them. diff --git a/mods/CORE/mcl_sounds/init.lua b/mods/CORE/mcl_sounds/init.lua index 13ca7bf72..30157060c 100644 --- a/mods/CORE/mcl_sounds/init.lua +++ b/mods/CORE/mcl_sounds/init.lua @@ -11,7 +11,7 @@ function mcl_sounds.node_sound_defaults(table) table.dug = table.dug or {name="default_dug_node", gain=0.25} table.dig = table.dig or - {name="default_dig_oddly_breakable_by_hand", gain=1.0} + {name="default_dig_oddly_breakable_by_hand", gain=0.5} table.place = table.place or {name="default_place_node_hard", gain=1.0} return table @@ -20,11 +20,11 @@ end function mcl_sounds.node_sound_stone_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_hard_footstep", gain=0.5} + {name="default_hard_footstep", gain=0.2} table.dug = table.dug or {name="default_hard_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_cracky", gain=1.0} + {name="default_dig_cracky", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end @@ -32,13 +32,13 @@ end function mcl_sounds.node_sound_metal_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_metal_footstep", gain=0.5} + {name="default_metal_footstep", gain=0.2} table.dug = table.dug or - {name="default_dug_metal", gain=1.0} + {name="default_dug_metal", gain=0.5} table.dig = table.dig or - {name="default_dig_metal", gain=1.0} + {name="default_dig_metal", gain=0.5} table.place = table.place or - {name="default_place_node_metal", gain=1.0} + {name="default_place_node_metal", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end @@ -46,11 +46,11 @@ end function mcl_sounds.node_sound_dirt_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_dirt_footstep", gain=1.0} + {name="default_dirt_footstep", gain=0.25} table.dug = table.dug or - {name="default_dirt_footstep", gain=1.5} + {name="default_dirt_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="default_dig_crumbly", gain=0.4} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) @@ -60,11 +60,25 @@ end function mcl_sounds.node_sound_sand_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_sand_footstep", gain=0.5} + {name="default_sand_footstep", gain=0.05} table.dug = table.dug or - {name="default_sand_footstep", gain=1.0} + {name="default_sand_footstep", gain=0.15} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="default_dig_crumbly", gain=0.4} + table.place = table.place or + {name="default_place_node", gain=1.0} + mcl_sounds.node_sound_defaults(table) + return table +end + +function mcl_sounds.node_sound_gravel_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name="default_gravel_footstep", gain=0.25} + table.dug = table.dug or + {name="default_gravel_dug", gain=1.0} + table.dig = table.dig or + {name="default_gravel_dig", gain=0.35} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) @@ -78,21 +92,33 @@ function mcl_sounds.node_sound_snow_defaults(table) table.dug = table.dug or {name="pedology_snow_soft_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_crumbly", gain=1.0} + {name="pedology_snow_soft_footstep", gain=1.0} table.place = table.place or {name="default_place_node", gain=1.0} mcl_sounds.node_sound_defaults(table) return table end +function mcl_sounds.node_sound_ice_defaults(table) + table = table or {} + table.footstep = table.footstep or + {name="default_ice_footstep", gain=0.15} + table.dug = table.dug or + {name="default_ice_dug", gain=0.5} + table.dig = table.dig or + {name="default_ice_dig", gain=0.5} + mcl_sounds.node_sound_defaults(table) + return table +end + function mcl_sounds.node_sound_wood_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_wood_footstep", gain=0.5} + {name="default_wood_footstep", gain=0.15} table.dug = table.dug or {name="default_wood_footstep", gain=1.0} table.dig = table.dig or - {name="default_dig_choppy", gain=1.0} + {name="default_dig_choppy", gain=0.4} mcl_sounds.node_sound_defaults(table) return table end @@ -128,11 +154,11 @@ end function mcl_sounds.node_sound_glass_defaults(table) table = table or {} table.footstep = table.footstep or - {name="default_glass_footstep", gain=0.5} + {name="default_glass_footstep", gain=0.3} table.dug = table.dug or {name="default_break_glass", gain=1.0} table.dig = table.dig or - {name="default_dig_cracky", gain=1.0} + {name="default_dig_cracky", gain=0.5} mcl_sounds.node_sound_defaults(table) return table end diff --git a/mods/CORE/mcl_sounds/mod.conf b/mods/CORE/mcl_sounds/mod.conf index 3227e6126..33bcafd9f 100644 --- a/mods/CORE/mcl_sounds/mod.conf +++ b/mods/CORE/mcl_sounds/mod.conf @@ -1 +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. diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg new file mode 100644 index 000000000..95fa6d4e7 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg new file mode 100644 index 000000000..5d3a04443 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg new file mode 100644 index 000000000..2bb0aceb5 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg deleted file mode 100644 index e2ecd8416..000000000 Binary files a/mods/CORE/mcl_sounds/sounds/default_dig_choppy.ogg and /dev/null differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg new file mode 100644 index 000000000..ffced27a6 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg new file mode 100644 index 000000000..d9e801039 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg new file mode 100644 index 000000000..7d19d4082 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg b/mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg deleted file mode 100644 index da1167916..000000000 Binary files a/mods/CORE/mcl_sounds/sounds/default_dig_cracky.ogg and /dev/null differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg index 84a197d2b..201aa3b2d 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg index 2e23b8a2b..2667dbc21 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_dirt_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg new file mode 100644 index 000000000..baf8fca71 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg new file mode 100644 index 000000000..e0c0c50f9 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dig.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg new file mode 100644 index 000000000..130343355 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg new file mode 100644 index 000000000..ee5ed3309 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg new file mode 100644 index 000000000..add4c54bf Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_gravel_dug.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg index 1748bc56a..0a08efa8d 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg index fe39fd784..be52a8701 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg index 5030e0607..a342787dd 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg and b/mods/CORE/mcl_sounds/sounds/default_hard_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg new file mode 100644 index 000000000..97399c831 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg new file mode 100644 index 000000000..8a5da119b Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg new file mode 100644 index 000000000..765fb9be1 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dig.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg new file mode 100644 index 000000000..ae37673e0 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_dug.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg new file mode 100644 index 000000000..c235f1eff Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg new file mode 100644 index 000000000..61d2c990f Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg new file mode 100644 index 000000000..2ecbb431c Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_ice_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg index 841286bdc..49fe89ba8 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg index aa61ed338..878711d5b 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg index 4cc1ca47a..2a566a83a 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg and b/mods/CORE/mcl_sounds/sounds/default_metal_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg index 65b68c7e6..b92feabbb 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.1.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg index 57f35f30a..6bc5da3e8 100644 Binary files a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.2.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg new file mode 100644 index 000000000..880306fd3 Binary files /dev/null and b/mods/CORE/mcl_sounds/sounds/default_sand_footstep.3.ogg differ diff --git a/mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg b/mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg deleted file mode 100644 index 6f1eab824..000000000 Binary files a/mods/CORE/mcl_sounds/sounds/default_water_footstep.4.ogg and /dev/null differ diff --git a/mods/CORE/mcl_util/depends.txt b/mods/CORE/mcl_util/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/CORE/mcl_util/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/CORE/mcl_util/description.txt b/mods/CORE/mcl_util/description.txt deleted file mode 100644 index c778045c1..000000000 --- a/mods/CORE/mcl_util/description.txt +++ /dev/null @@ -1 +0,0 @@ -Helper functions for MineClone 2. diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 6c63c21ab..5872ce742 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -1,5 +1,107 @@ mcl_util = {} +-- Updates all values in t using values from to*. +function table.update(t, ...) + for _, to in ipairs {...} do + for k, v in pairs(to) do + t[k] = v + end + end + return t +end + +-- Updates nil values in t using values from to*. +function table.update_nil(t, ...) + for _, to in ipairs {...} do + for k, v in pairs(to) do + if t[k] == nil then + t[k] = v + end + end + end + return t +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) + local selected_module = LOG_MODULE + if module then + selected_module = module + end + if (bypass_default_logger or LOGGING_ON) and message then + minetest.log(selected_module .. " " .. message) + end +end + +local player_timers = {} + +-- This is a dtime timer than can be used in on_step functions so it works every x seconds +-- self - Object you want to store timer data on. E.g. mob or a minecart, or player_name +-- dtime - The time since last run of on_step, should be passed in to function +-- timer_name - This is the name of the timer and also the key to store the data. No spaces + lowercase. +-- threshold - The time before it returns successful. 0.2 if you want to run it 5 times a second. +function mcl_util.check_dtime_timer(self, dtime, timer_name, threshold) + if not self or not threshold or not dtime then return end + if not timer_name or timer_name == "" then return end + + if type(self) == "string" then + local player_name = self + if not player_timers[player_name] then + player_timers[player_name] = {} + end + self = player_timers[player_name] + end + + if not self._timers then + self._timers = {} + end + + if not self._timers[timer_name] then + self._timers[timer_name] = 0 + else + self._timers[timer_name] = self._timers[timer_name] + dtime + --minetest.log("dtime: " .. tostring(self._timers[timer_name])) + end + + if self._timers[timer_name] > threshold then + --minetest.log("Over threshold") + self._timers[timer_name] = 0 + return true + --else + --minetest.log("Not over threshold") + 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 +function mcl_util.get_natural_light (pos, time) + local status, retVal = pcall(minetest.get_natural_light, pos, time) + if status then + return retVal + else + minetest.log("warning", "Failed to get natural light at pos: " .. dump(pos) .. ", time: " .. dump(time)) + if (pos) then + local node = minetest.get_node(pos) + minetest.log("warning", "Node at pos: " .. dump(node.name)) + end + end + return 0 +end + +function mcl_util.file_exists(name) + if type(name) ~= "string" then return end + local f = io.open(name) + if not f then + return false + end + f:close() + return true +end + -- Based on minetest.rotate_and_place --[[ @@ -24,7 +126,7 @@ function mcl_util.rotate_axis_and_place(itemstack, placer, pointed_thing, infini local undef = minetest.registered_nodes[unode.name] if undef and undef.on_rightclick then undef.on_rightclick(pointed_thing.under, unode, placer, - itemstack, pointed_thing) + itemstack, pointed_thing) return end local fdir = minetest.dir_to_facedir(placer:get_look_dir()) @@ -106,23 +208,23 @@ end function mcl_util.get_double_container_neighbor_pos(pos, param2, side) if side == "right" then if param2 == 0 then - return {x=pos.x-1, y=pos.y, z=pos.z} + return {x = pos.x - 1, y = pos.y, z = pos.z} elseif param2 == 1 then - return {x=pos.x, y=pos.y, z=pos.z+1} + return {x = pos.x, y = pos.y, z = pos.z + 1} elseif param2 == 2 then - return {x=pos.x+1, y=pos.y, z=pos.z} + return {x = pos.x + 1, y = pos.y, z = pos.z} elseif param2 == 3 then - return {x=pos.x, y=pos.y, z=pos.z-1} + return {x = pos.x, y = pos.y, z = pos.z - 1} end else if param2 == 0 then - return {x=pos.x+1, y=pos.y, z=pos.z} + return {x = pos.x + 1, y = pos.y, z = pos.z} elseif param2 == 1 then - return {x=pos.x, y=pos.y, z=pos.z-1} + return {x = pos.x, y = pos.y, z = pos.z - 1} elseif param2 == 2 then - return {x=pos.x-1, y=pos.y, z=pos.z} + return {x = pos.x - 1, y = pos.y, z = pos.z} elseif param2 == 3 then - return {x=pos.x, y=pos.y, z=pos.z+1} + return {x = pos.x, y = pos.y, z = pos.z + 1} end end end @@ -140,7 +242,7 @@ end function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_inventory, dst_list, condition) local size = src_inventory:get_size(src_list) local stack - for i=1, size do + for i = 1, 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 return i @@ -150,7 +252,7 @@ function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_i end -- Returns true if itemstack is a shulker box -local is_not_shulker_box = function(itemstack) +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 @@ -212,7 +314,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, end -- Normalize double container by forcing to always use the left segment first - local normalize_double_container = function(pos, node, ctype) + 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 @@ -243,10 +345,10 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- 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 + -- Furnace: output elseif sctype == 4 then source_list = "dst" - -- Unknown source container type. Bail out + -- Unknown source container type. Bail out else return false end @@ -299,7 +401,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list, -- 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 + -- Furnace source slot elseif dctype == 4 then destination_list = "src" end @@ -335,10 +437,36 @@ function mcl_util.get_first_occupied_inventory_slot(inventory, listname) return mcl_util.get_eligible_transfer_item_slot(inventory, listname) end +local function drop_item_stack(pos, stack) + if not stack or stack:is_empty() then return end + local drop_offset = vector.new(math.random() - 0.5, 0, math.random() - 0.5) + minetest.add_item(vector.add(pos, drop_offset), stack) +end + +function mcl_util.drop_items_from_meta_container(listname) + return function(pos, oldnode, oldmetadata) + if oldmetadata and oldmetadata.inventory then + -- process in after_dig_node callback + local main = oldmetadata.inventory.main + if not main then return end + for _, stack in pairs(main) do + drop_item_stack(pos, stack) + end + else + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + for i = 1, inv:get_size("main") do + drop_item_stack(pos, inv:get_stack("main", i)) + end + meta:from_table() + end + end +end + -- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel. -- Returns false otherwise function mcl_util.is_fuel(item) - return minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0 + return minetest.get_craft_result({method = "fuel", width = 1, items = {item}}).time ~= 0 end -- Returns a on_place function for plants @@ -385,7 +513,7 @@ function mcl_util.generate_on_place_plant_function(condition) if success then if idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=pointed_thing.above, gain=1}, true) + minetest.sound_play(idef.sounds.place, {pos = pointed_thing.above, gain = 1}, true) end end itemstack = new_itemstack @@ -405,3 +533,571 @@ function mcl_util.get_object_center(obj) pos.y = pos.y + (ymax - ymin) / 2.0 return pos end + +function mcl_util.get_color(colorstr) + local mc_color = mcl_colors[colorstr:upper()] + if mc_color then + colorstr = mc_color + elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#" then + return + end + local hex = tonumber(colorstr:sub(2, 7), 16) + if hex then + return colorstr, hex + end +end + +function mcl_util.call_on_rightclick(itemstack, player, pointed_thing) + -- Call on_rightclick if the pointed node defines it + if pointed_thing and pointed_thing.type == "node" then + local pos = pointed_thing.under + local node = minetest.get_node(pos) + if player and not player:get_player_control().sneak then + local nodedef = minetest.registered_nodes[node.name] + local on_rightclick = nodedef and nodedef.on_rightclick + if on_rightclick then + return on_rightclick(pos, node, player, itemstack, pointed_thing) or itemstack + end + end + end +end + +function mcl_util.calculate_durability(itemstack) + local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking") + local armor_uses = minetest.get_item_group(itemstack:get_name(), "mcl_armor_uses") + + local uses + + if armor_uses > 0 then + uses = armor_uses + if unbreaking_level > 0 then + uses = uses / (0.6 + 0.4 / (unbreaking_level + 1)) + end + else + local def = itemstack:get_definition() + if def then + local fixed_uses = def._mcl_uses + if fixed_uses then + uses = fixed_uses + if unbreaking_level > 0 then + uses = uses * (unbreaking_level + 1) + end + end + end + + local _, groupcap = next(itemstack:get_tool_capabilities().groupcaps) + uses = uses or (groupcap or {}).uses + end + + return uses or 0 +end + +function mcl_util.use_item_durability(itemstack, n) + local uses = mcl_util.calculate_durability(itemstack) + itemstack:add_wear(65535 / uses * n) +end + +function mcl_util.deal_damage(target, damage, mcl_reason) + local luaentity = target:get_luaentity() + + if luaentity then + if luaentity.deal_damage then + luaentity:deal_damage(damage, mcl_reason or {type = "generic"}) + return + elseif luaentity.is_mob then + -- local puncher = mcl_reason and mcl_reason.direct or target + -- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage) + if luaentity.health > 0 then + luaentity.health = luaentity.health - damage + end + return + end + end + + local is_immortal = target:get_armor_groups().immortal or 0 + if is_immortal>0 then + return + end + + local hp = target:get_hp() + + if hp > 0 then + target:set_hp(hp - damage, {_mcl_reason = mcl_reason}) + end +end + +function mcl_util.get_hp(obj) + local luaentity = obj:get_luaentity() + + if luaentity and luaentity.is_mob then + return luaentity.health + else + return obj:get_hp() + end +end + +function mcl_util.get_inventory(object, create) + if object:is_player() then + return object:get_inventory() + else + local luaentity = object:get_luaentity() + local inventory = luaentity.inventory + + if create and not inventory and luaentity.create_inventory then + inventory = luaentity:create_inventory() + end + + return inventory + end +end + +function mcl_util.get_wielded_item(object) + if object:is_player() then + return object:get_wielded_item() + else + -- ToDo: implement getting wielditems from mobs as soon as mobs have wielditems + return ItemStack() + end +end + +function mcl_util.get_object_name(object) + if object:is_player() then + return object:get_player_name() + else + local luaentity = object:get_luaentity() + + if not luaentity then + return tostring(object) + end + + return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name + end +end + +function mcl_util.replace_mob(obj, mob) + if not obj then return end + local rot = obj:get_yaw() + local pos = obj:get_pos() + obj:remove() + obj = minetest.add_entity(pos, mob) + if not obj then return end + obj:set_yaw(rot) + return obj +end + +function mcl_util.get_pointed_thing(player, liquid) + local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0) + local look_dir = vector.multiply(player:get_look_dir(), 5) + local pos2 = vector.add(pos, look_dir) + local ray = minetest.raycast(pos, pos2, false, liquid) + + if ray then + for pointed_thing in ray do + return pointed_thing + end + end +end + +-- This following part is 2 wrapper functions + helpers for +-- object:set_bones +-- and player:set_properties preventing them from being resent on +-- every globalstep when they have not changed. + +local function roundN(n, d) + if type(n) ~= "number" then return n end + local m = 10 ^ d + return math.floor(n * m + 0.5) / m +end + +local function close_enough(a, b) + local rt = true + if type(a) == "table" and type(b) == "table" then + for k, v in pairs(a) do + if roundN(v, 2) ~= roundN(b[k], 2) then + rt = false + break + end + end + else + rt = roundN(a, 2) == roundN(b, 2) + end + return rt +end + +local function props_changed(props, oldprops) + local changed = false + local p = {} + for k, v in pairs(props) do + if not close_enough(v, oldprops[k]) then + p[k] = v + changed = true + end + end + return changed, p +end + +--tests for roundN +local test_round1 = 15 +local test_round2 = 15.00199999999 +local test_round3 = 15.00111111 +local test_round4 = 15.00999999 + +assert(roundN(test_round1, 2) == roundN(test_round1, 2)) +assert(roundN(test_round1, 2) == roundN(test_round2, 2)) +assert(roundN(test_round1, 2) == roundN(test_round3, 2)) +assert(roundN(test_round1, 2) ~= roundN(test_round4, 2)) + +-- tests for close_enough +local test_cb = {-0.35, 0, -0.35, 0.35, 0.8, 0.35} --collisionboxes +local test_cb_close = {-0.351213, 0, -0.35, 0.35, 0.8, 0.351212} +local test_cb_diff = {-0.35, 0, -1.35, 0.35, 0.8, 0.35} + +local test_eh = 1.65 --eye height +local test_eh_close = 1.65123123 +local test_eh_diff = 1.35 + +local test_nt = {r = 225, b = 225, a = 225, g = 225} --nametag +local test_nt_diff = {r = 225, b = 225, a = 0, g = 225} + +assert(close_enough(test_cb, test_cb_close)) +assert(not close_enough(test_cb, test_cb_diff)) +assert(close_enough(test_eh, test_eh_close)) +assert(not close_enough(test_eh, test_eh_diff)) +assert(not close_enough(test_nt, test_nt_diff)) --no floats involved here + +--tests for properties_changed +local test_properties_set1 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 0.65, + nametag_color = {r = 225, b = 225, a = 225, g = 225}} +local test_properties_set2 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 1.35, + nametag_color = {r = 225, b = 225, a = 225, g = 225}} + +local test_p1, _ = props_changed(test_properties_set1, test_properties_set1) +local test_p2, _ = props_changed(test_properties_set1, test_properties_set2) + +assert(not test_p1) +assert(test_p2) + +function mcl_util.set_properties(obj, props) + local changed, p = props_changed(props, obj:get_properties()) + if changed then + obj:set_properties(p) + end +end + +function mcl_util.set_bone_position(obj, bone, pos, rot) + local current_pos, current_rot = obj:get_bone_position(bone) + local pos_equal = not pos or vector.equals(vector.round(current_pos), vector.round(pos)) + local rot_equal = not rot or vector.equals(vector.round(current_rot), vector.round(rot)) + if not pos_equal or not rot_equal then + obj:set_bone_position(bone, pos or current_pos, rot or current_rot) + end +end + +---Return a function to use in `on_place`. +--- +---Allow to bypass the `buildable_to` node field in a `on_place` callback. +--- +---You have to make sure that the nodes you return true for have `buildable_to = true`. +---@param func fun(node_name: string): boolean Return `true` if node must not replace the buildable_to node which have `node_name` +---@return fun(itemstack: ItemStack, placer: ObjectRef, pointed_thing: pointed_thing, param2: integer): ItemStack? +function mcl_util.bypass_buildable_to(func) + -------------------------- + -- MINETEST CODE: UTILS -- + -------------------------- + + local function copy_pointed_thing(pointed_thing) + return { + type = pointed_thing.type, + above = pointed_thing.above and vector.copy(pointed_thing.above), + under = pointed_thing.under and vector.copy(pointed_thing.under), + ref = pointed_thing.ref, + } + end + + 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 + + local function check_attached_node(p, n, group_rating) + local def = core.registered_nodes[n.name] + local d = vector.zero() + if group_rating == 3 then + -- always attach to floor + d.y = -1 + elseif group_rating == 4 then + -- always attach to ceiling + d.y = 1 + elseif group_rating == 2 then + -- attach to facedir or 4dir direction + if (def.paramtype2 == "facedir" or + def.paramtype2 == "colorfacedir") then + -- Attach to whatever facedir is "mounted to". + -- For facedir, this is where tile no. 5 point at. + + -- The fallback vector here is in case 'facedir to dir' is nil due + -- to voxelmanip placing a wallmounted node without resetting a + -- pre-existing param2 value that is out-of-range for facedir. + -- The fallback vector corresponds to param2 = 0. + d = core.facedir_to_dir(n.param2) or vector.new(0, 0, 1) + elseif (def.paramtype2 == "4dir" or + def.paramtype2 == "color4dir") then + -- Similar to facedir handling + d = core.fourdir_to_dir(n.param2) or vector.new(0, 0, 1) + end + elseif def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted" then + -- Attach to whatever this node is "mounted to". + -- This where tile no. 2 points at. + + -- The fallback vector here is used for the same reason as + -- for facedir nodes. + d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0) + else + d.y = -1 + end + local p2 = vector.add(p, d) + local nn = core.get_node(p2).name + local def2 = core.registered_nodes[nn] + if def2 and not def2.walkable then + return false + end + return true + end + + return function(itemstack, placer, pointed_thing, param2) + ------------------- + -- MINETEST CODE -- + ------------------- + local def = itemstack:get_definition() + if def.type ~= "node" or pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local oldnode_under = minetest.get_node_or_nil(under) + local above = pointed_thing.above + local oldnode_above = minetest.get_node_or_nil(above) + local playername = user_name(placer) + local log = make_log(playername) + + if not oldnode_under or not oldnode_above then + log("info", playername .. " tried to place" + .. " node in unloaded position " .. minetest.pos_to_string(above)) + return itemstack + end + + local olddef_under = minetest.registered_nodes[oldnode_under.name] + olddef_under = olddef_under or minetest.nodedef_default + local olddef_above = minetest.registered_nodes[oldnode_above.name] + olddef_above = olddef_above or minetest.nodedef_default + + if not olddef_above.buildable_to and not olddef_under.buildable_to then + log("info", playername .. " tried to place" + .. " node in invalid position " .. minetest.pos_to_string(above) + .. ", replacing " .. oldnode_above.name) + return itemstack + end + + --------------------- + -- CUSTOMIZED CODE -- + --------------------- + + -- Place above pointed node + local place_to = vector.copy(above) + + -- If node under is buildable_to, check for callback result and place into it instead + if olddef_under.buildable_to and not func(oldnode_under.name) then + log("info", "node under is buildable to") + place_to = vector.copy(under) + end + + ------------------- + -- MINETEST CODE -- + ------------------- + + if minetest.is_protected(place_to, playername) then + log("action", playername + .. " tried to place " .. def.name + .. " at protected position " + .. minetest.pos_to_string(place_to)) + minetest.record_protection_violation(place_to, playername) + return itemstack + end + + local oldnode = minetest.get_node(place_to) + local newnode = {name = def.name, param1 = 0, param2 = param2 or 0} + + -- Calculate direction for wall mounted stuff like torches and signs + if def.place_param2 ~= nil then + newnode.param2 = def.place_param2 + elseif (def.paramtype2 == "wallmounted" or + def.paramtype2 == "colorwallmounted") and not param2 then + local dir = vector.subtract(under, above) + newnode.param2 = minetest.dir_to_wallmounted(dir) + -- Calculate the direction for furnaces and chests and stuff + elseif (def.paramtype2 == "facedir" or + def.paramtype2 == "colorfacedir" or + def.paramtype2 == "4dir" or + def.paramtype2 == "color4dir") and not param2 then + local placer_pos = placer and placer:get_pos() + if placer_pos then + local dir = vector.subtract(above, placer_pos) + newnode.param2 = minetest.dir_to_facedir(dir) + log("info", "facedir: " .. newnode.param2) + end + end + + local metatable = itemstack:get_meta():to_table().fields + + -- Transfer color information + if metatable.palette_index and not def.place_param2 then + local color_divisor = nil + if def.paramtype2 == "color" then + color_divisor = 1 + elseif def.paramtype2 == "colorwallmounted" then + color_divisor = 8 + elseif def.paramtype2 == "colorfacedir" then + color_divisor = 32 + elseif def.paramtype2 == "color4dir" then + color_divisor = 4 + elseif def.paramtype2 == "colordegrotate" then + color_divisor = 32 + end + if color_divisor then + local color = math.floor(metatable.palette_index / color_divisor) + local other = newnode.param2 % color_divisor + newnode.param2 = color * color_divisor + other + end + end + + -- Check if the node is attached and if it can be placed there + local an = minetest.get_item_group(def.name, "attached_node") + if an ~= 0 and + not check_attached_node(place_to, newnode, an) then + log("action", "attached node " .. def.name .. + " cannot be placed at " .. minetest.pos_to_string(place_to)) + return itemstack + end + + log("action", playername .. " places node " + .. def.name .. " at " .. minetest.pos_to_string(place_to)) + + -- Add node and update + minetest.add_node(place_to, newnode) + + -- Play sound if it was done by a player + if playername ~= "" and def.sounds and def.sounds.place then + minetest.sound_play(def.sounds.place, { + pos = place_to, + exclude_player = playername, + }, true) + end + + local take_item = true + + -- Run callback + if def.after_place_node then + -- Deepcopy place_to and pointed_thing because callback can modify it + local place_to_copy = vector.copy(place_to) + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if def.after_place_node(place_to_copy, placer, itemstack, + pointed_thing_copy) then + take_item = false + end + end + + -- Run script hook + for _, callback in ipairs(minetest.registered_on_placenodes) do + -- Deepcopy pos, node and pointed_thing because callback can modify them + local place_to_copy = vector.copy(place_to) + local newnode_copy = {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local pointed_thing_copy = copy_pointed_thing(pointed_thing) + if callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack, pointed_thing_copy) then + take_item = false + end + end + + if take_item then + itemstack:take_item() + end + return itemstack + end +end + +--[[Check for a protection violation in a given area. +-- +-- Applies is_protected() to a 3D lattice of points in the defined volume. The points are spaced +-- evenly throughout the volume and have a spacing similar to, but no larger than, "interval". +-- +-- @param pos1 A position table of the area volume's first edge. +-- @param pos2 A position table of the area volume's second edge. +-- @param player The player performing the action. +-- @param interval Optional. Max spacing between checked points at the volume. +-- Default: Same as minetest.is_area_protected. +-- +-- @return true on protection violation detection. false otherwise. +-- +-- @notes *All corners and edges of the defined volume are checked. +]] +function mcl_util.check_area_protection(pos1, pos2, player, interval) + local name = player and player:get_player_name() or "" + + local protected_pos = minetest.is_area_protected(pos1, pos2, name, interval) + if protected_pos then + minetest.record_protection_violation(protected_pos, name) + return true + end + + return false +end + +--[[Check for a protection violation on a single position. +-- +-- @param position A position table to check for protection violation. +-- @param player The player performing the action. +-- +-- @return true on protection violation detection. false otherwise. +]] +function mcl_util.check_position_protection(position, player) + local name = player and player:get_player_name() or "" + + if minetest.is_protected(position, name) then + minetest.record_protection_violation(position, name) + return true + end + + return false +end + +local palette_indexes = {grass_palette_index = 0, foliage_palette_index = 0, water_palette_index = 0} +function mcl_util.get_palette_indexes_from_pos(pos) + local biome_data = minetest.get_biome_data(pos) + local biome = biome_data.biome + local biome_name = minetest.get_biome_name(biome) + local reg_biome = minetest.registered_biomes[biome_name] + if reg_biome and reg_biome._mcl_grass_palette_index and reg_biome._mcl_foliage_palette_index and reg_biome._mcl_water_palette_index then + local gpi = reg_biome._mcl_grass_palette_index + local fpi = reg_biome._mcl_foliage_palette_index + local wpi = reg_biome._mcl_water_palette_index + local palette_indexes = {grass_palette_index = gpi, foliage_palette_index = fpi, water_palette_index = wpi} + return palette_indexes + else + return palette_indexes + end +end + +function mcl_util.get_colorwallmounted_rotation(pos) + local colorwallmounted_node = minetest.get_node(pos) + for i = 0, 32, 1 do + local colorwallmounted_rotation = colorwallmounted_node.param2 - (i * 8) + if colorwallmounted_rotation < 6 then + return colorwallmounted_rotation + end + end +end diff --git a/mods/CORE/mcl_util/mod.conf b/mods/CORE/mcl_util/mod.conf index e45f9124e..82f9137e4 100644 --- a/mods/CORE/mcl_util/mod.conf +++ b/mods/CORE/mcl_util/mod.conf @@ -1 +1,4 @@ name = mcl_util +author = Wuzzy +description = Helper functions for MineClone 2. +depends = mcl_init diff --git a/mods/CORE/mcl_worlds/API.md b/mods/CORE/mcl_worlds/API.md new file mode 100644 index 000000000..69508e924 --- /dev/null +++ b/mods/CORE/mcl_worlds/API.md @@ -0,0 +1,81 @@ +# mcl_worlds +This mod provides utility functions about positions and dimensions. + +## mcl_worlds.is_in_void(pos) +This function returns: + +* true, true: if pos is in deep void (deadly) +* true, false: if the pos is in void (non deadly) +* false, false: owerwise + +Params: + +* pos: position + +## mcl_worlds.y_to_layer(y) +This function is used to calculate the minetest y layer and dimension of the given minecraft layer. +Mainly used for ore generation. +Takes an Y coordinate as input and returns: + +* The corresponding Minecraft layer (can be nil if void) +* The corresponding Minecraft dimension ("overworld", "nether" or "end") or "void" if is in the void +If the Y coordinate is not located in any dimension, it will return: nil, "void" + +Params: + +* y: int + +## mcl_worlds.pos_to_dimension(pos) +This function return the Minecraft dimension of ("overworld", "nether" or "end") or "void" if is in the void. + +* 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. +mc_dimension can be "overworld", "nether", "end" (default: "overworld"). + +* layer: int +* mc_dimension: string + +## mcl_worlds.has_weather(pos) +Returns true if can have weather, false owerwise. +Weather can be only in the overworld. + +* pos: position + +## mcl_worlds.has_dust(pos) +Returns true if can have nether dust, false owerwise. +Nether dust can be only in the nether. + +* pos: position + +## mcl_worlds.compass_works(pos) +Returns true if compasses are working at , false owerwise. +In mc, you cant use compass in the nether and the end. + +* pos: position + +## mcl_worlds.compass_works(pos) +Returns true if clock are working at , false owerwise. +In mc, you cant use clock in the nether and the end. + +* pos: position + +## mcl_worlds.register_on_dimension_change(function(player, dimension, last_dimension)) +Register a callback function func(player, dimension). +It will be called whenever a player changes between dimensions. +The void counts as dimension. + +* player: player, the player who changed of dimension +* dimension: string, The new dimension of the player ("overworld", "nether", "end", "void"). +* last_dimension: string, The dimension where the player was ("overworld", "nether", "end", "void"). + + +## mcl_worlds.registered_on_dimension_change +Table containing all function registered with mcl_worlds.register_on_dimension_change() + +## mcl_worlds.dimension_change(player, dimension) +Notify this mod of a dimension change of to + +* player: player, player who changed the dimension +* dimension: string, new dimension ("overworld", "nether", "end", "void") diff --git a/mods/CORE/mcl_worlds/depends.txt b/mods/CORE/mcl_worlds/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/CORE/mcl_worlds/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/CORE/mcl_worlds/description.txt b/mods/CORE/mcl_worlds/description.txt deleted file mode 100644 index 470cf7a84..000000000 --- a/mods/CORE/mcl_worlds/description.txt +++ /dev/null @@ -1 +0,0 @@ -Utility functions for worlds and the “dimensions”. diff --git a/mods/CORE/mcl_worlds/init.lua b/mods/CORE/mcl_worlds/init.lua index 35549ffad..4f8914506 100644 --- a/mods/CORE/mcl_worlds/init.lua +++ b/mods/CORE/mcl_worlds/init.lua @@ -1,12 +1,14 @@ mcl_worlds = {} +local get_connected_players = minetest.get_connected_players + -- For a given position, returns a 2-tuple: -- 1st return value: true if pos is in void -- 2nd return value: true if it is in the deadly part of the void function mcl_worlds.is_in_void(pos) local void = not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or - (pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or + (pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or (pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min)) local void_deadly = false @@ -15,11 +17,11 @@ function mcl_worlds.is_in_void(pos) -- Overworld → Void → End → Void → Nether → Void if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance - elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then + elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then -- The void between End and Nether. Like usual, but here, the void -- *above* the Nether also has a small tolerance area, so player -- can fly above the Nether without getting hurt instantly. - void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance) + void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance) elseif pos.y < mcl_vars.mg_nether_min then void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance end @@ -33,60 +35,64 @@ end -- If the Y coordinate is not located in any dimension, it will return: -- nil, "void" function mcl_worlds.y_to_layer(y) - if y >= mcl_vars.mg_overworld_min then - return y - mcl_vars.mg_overworld_min, "overworld" - elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then - return y - mcl_vars.mg_nether_min, "nether" - elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then - return y - mcl_vars.mg_end_min, "end" - else - return nil, "void" - end + if y >= mcl_vars.mg_overworld_min then + return y - mcl_vars.mg_overworld_min, "overworld" + elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then + return y - mcl_vars.mg_nether_min, "nether" + elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then + return y - mcl_vars.mg_end_min, "end" + else + return nil, "void" + end end +local y_to_layer = mcl_worlds.y_to_layer + -- Takes a pos and returns the dimension it belongs to (same as above) function mcl_worlds.pos_to_dimension(pos) - local _, dim = mcl_worlds.y_to_layer(pos.y) + local _, dim = y_to_layer(pos.y) return dim end +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. -- 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 - return layer + mcl_vars.mg_overworld_min - elseif mc_dimension == "nether" then - return layer + mcl_vars.mg_nether_min - elseif mc_dimension == "end" then - return layer + mcl_vars.mg_end_min - end + if mc_dimension == "overworld" or mc_dimension == nil then + return layer + mcl_vars.mg_overworld_min + elseif mc_dimension == "nether" then + return layer + mcl_vars.mg_nether_min + elseif mc_dimension == "end" then + return layer + mcl_vars.mg_end_min + end end -- Takes a position and returns true if this position can have weather function mcl_worlds.has_weather(pos) - -- Weather in the Overworld and the high part of the void below - return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 + -- Weather in the Overworld and the high part of the void below + return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 end -- Takes a position and returns true if this position can have Nether dust function mcl_worlds.has_dust(pos) - -- Weather in the Overworld and the high part of the void below - return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64 + -- Weather in the Overworld and the high part of the void below + return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10 end -- Takes a position (pos) and returns true if compasses are working here function mcl_worlds.compass_works(pos) - -- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below - local _, dim = mcl_worlds.y_to_layer(pos.y) - if dim == "nether" or dim == "end" then - return false - elseif dim == "void" then - return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 - else - return true - end + -- It doesn't work in Nether and the End, but it works in the Overworld and in the high part of the void below + local _, dim = mcl_worlds.y_to_layer(pos.y) + if dim == "nether" or dim == "end" then + return false + elseif dim == "void" then + return pos.y <= mcl_vars.mg_overworld_max and pos.y >= mcl_vars.mg_overworld_min - 64 + else + return true + end end -- Takes a position (pos) and returns true if clocks are working here @@ -112,12 +118,15 @@ local last_dimension = {} -- * player: Player who changed the dimension -- * dimension: New dimension ("overworld", "nether", "end", "void") function mcl_worlds.dimension_change(player, dimension) + local playername = player:get_player_name() for i=1, #mcl_worlds.registered_on_dimension_change do - mcl_worlds.registered_on_dimension_change[i](player, dimension) - last_dimension[player:get_player_name()] = dimension + mcl_worlds.registered_on_dimension_change[i](player, dimension, last_dimension[playername]) end + last_dimension[playername] = dimension end +local dimension_change = mcl_worlds.dimension_change + ----------------------- INTERNAL STUFF ---------------------- -- Update the dimension callbacks every DIM_UPDATE seconds @@ -125,22 +134,41 @@ local DIM_UPDATE = 1 local dimtimer = 0 minetest.register_on_joinplayer(function(player) - last_dimension[player:get_player_name()] = mcl_worlds.pos_to_dimension(player:get_pos()) + last_dimension[player:get_player_name()] = pos_to_dimension(player:get_pos()) end) minetest.register_globalstep(function(dtime) -- regular updates based on iterval dimtimer = dimtimer + dtime; if dimtimer >= DIM_UPDATE then - local players = minetest.get_connected_players() - for p=1, #players do - local dim = mcl_worlds.pos_to_dimension(players[p]:get_pos()) + local players = get_connected_players() + for p = 1, #players do + local dim = pos_to_dimension(players[p]:get_pos()) local name = players[p]:get_player_name() if dim ~= last_dimension[name] then - mcl_worlds.dimension_change(players[p], dim) + dimension_change(players[p], dim) end end dimtimer = 0 end end) +function mcl_worlds.get_cloud_parameters() + if minetest.get_mapgen_setting("mg_name") == "valleys" then + return { + height = 384, --valleys has a much higher average elevation thus often "normal" landscape ends up in the clouds + speed = {x=-2, z=0}, + thickness=5, + color="#FFF0FEF", + ambient = "#201060", + } + else + -- MC-style clouds: Layer 127, thickness 4, fly to the “West” + return { + height = mcl_worlds.layer_to_y(127), + speed = {x=-2, z=0}, + thickness = 4, + color = "#FFF0FEF", + } + end +end diff --git a/mods/CORE/mcl_worlds/mod.conf b/mods/CORE/mcl_worlds/mod.conf new file mode 100644 index 000000000..4b979b4fe --- /dev/null +++ b/mods/CORE/mcl_worlds/mod.conf @@ -0,0 +1,5 @@ +name = mcl_worlds +author = Wuzzy +description = Utility functions for worlds and the “dimensions”. +depends = mcl_init + diff --git a/mods/CORE/tga_encoder/README.md b/mods/CORE/tga_encoder/README.md new file mode 100644 index 000000000..9b3293dda --- /dev/null +++ b/mods/CORE/tga_encoder/README.md @@ -0,0 +1,4 @@ +# tga_encoder +A TGA Encoder written in Lua without the use of external Libraries. + +May be used as a Minetest mod. diff --git a/mods/CORE/tga_encoder/init.lua b/mods/CORE/tga_encoder/init.lua new file mode 100644 index 000000000..24ec502e1 --- /dev/null +++ b/mods/CORE/tga_encoder/init.lua @@ -0,0 +1,92 @@ +tga_encoder = {} + +local image = setmetatable({}, { + __call = function(self, ...) + local t = setmetatable({}, {__index = self}) + t:constructor(...) + return t + end, +}) + +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 +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 +end + +function image:encode_header() + 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 +end + +function image:encode_data() + local current_pixel = '' + local previous_pixel = '' + local count = 1 + local packets = {} + local rle_packet = '' + 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 + count = 1 + previous_pixel = current_pixel + else + count = count + 1 + end + rle_packet = string.char(128 + count - 1) .. current_pixel + end + end + packets[#packets +1] = rle_packet + self.data = self.data .. table.concat(packets) +end + +function image:encode_footer() + self.data = self.data + .. string.char(0, 0, 0, 0) -- extension area offset + .. string.char(0, 0, 0, 0) -- developer area offset + .. "TRUEVISION-XFILE" + .. "." + .. string.char(0) +end + +function image:encode() + self:encode_header() -- header + -- no color map and image id data + self:encode_data() -- encode data + -- no extension or developer area + self:encode_footer() -- footer +end + +function image:save(filename) + local f = assert(io.open(filename, "wb")) + f:write(self.data) + f:close() +end + +tga_encoder.image = image diff --git a/mods/CORE/tga_encoder/mod.conf b/mods/CORE/tga_encoder/mod.conf new file mode 100644 index 000000000..e4bfac898 --- /dev/null +++ b/mods/CORE/tga_encoder/mod.conf @@ -0,0 +1,3 @@ +name = tga_encoder +author = Fleckenstein +description = A TGA Encoder written in Lua without the use of external Libraries. diff --git a/mods/CORE/walkover/init.lua b/mods/CORE/walkover/init.lua index 6bbd505d2..552ac4ff4 100644 --- a/mods/CORE/walkover/init.lua +++ b/mods/CORE/walkover/init.lua @@ -1,35 +1,49 @@ -- register extra flavours of a base nodedef + +local get_connected_players = minetest.get_connected_players +local get_node = minetest.get_node +local vector = vector +local ceil = math.ceil +local pairs = pairs + walkover = {} -walkover.registered_globals = {} + +local on_walk = {} +local registered_globals = {} + +walkover.registered_globals = registered_globals function walkover.register_global(func) - table.insert(walkover.registered_globals, func) + table.insert(registered_globals, func) end +minetest.register_on_mods_loaded(function() + for name,def in pairs(minetest.registered_nodes) do + if def.on_walk_over then + on_walk[name] = def.on_walk_over + end + end +end) + local timer = 0 minetest.register_globalstep(function(dtime) - timer = timer + dtime; - if timer >= 0.3 then - for _,player in pairs(minetest.get_connected_players()) do - local pp = player:get_pos() - pp.y = math.ceil(pp.y) - local loc = vector.add(pp, {x=0,y=-1,z=0}) - if loc ~= nil then - - local nodeiamon = minetest.get_node(loc) - - if nodeiamon ~= nil then - local def = minetest.registered_nodes[nodeiamon.name] - if def ~= nil and def.on_walk_over ~= nil then - def.on_walk_over(loc, nodeiamon, player) - end - for _, func in ipairs(walkover.registered_globals) do - func(loc, nodeiamon, player) - end - end - end - end - + timer = timer + dtime + if timer >= 0.6 then + for _, player in pairs(get_connected_players()) do + local ppos = player:get_pos() + local npos = vector.add(ppos, vector.new(0, -0.1, 0)) + if npos then + local node = get_node(npos) + if node then + if on_walk[node.name] then + on_walk[node.name](npos, node, player) + end + for i = 1, #registered_globals do + registered_globals[i](npos, node, player) + end + end + end + end timer = 0 end end) diff --git a/mods/CORE/walkover/mod.conf b/mods/CORE/walkover/mod.conf new file mode 100644 index 000000000..837d81365 --- /dev/null +++ b/mods/CORE/walkover/mod.conf @@ -0,0 +1,4 @@ +name = walkover +author = lordfingle +description = Some mode developers have shown an interest in having an `on_walk_over` event. This is useful for pressure-plates and the like. + diff --git a/mods/ENTITIES/drippingwater/depends.txt b/mods/ENTITIES/drippingwater/depends.txt deleted file mode 100644 index 315237e07..000000000 --- a/mods/ENTITIES/drippingwater/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_core diff --git a/mods/ENTITIES/drippingwater/init.lua b/mods/ENTITIES/drippingwater/init.lua deleted file mode 100644 index 730cb7b77..000000000 --- a/mods/ENTITIES/drippingwater/init.lua +++ /dev/null @@ -1,125 +0,0 @@ ---Dripping Water Mod ---by kddekadenz - --- License of code, textures & sounds: CC0 - ---Drop entities - ---water - -local water_tex = "default_water_source_animated.png^[verticalframe:16:0" -minetest.register_entity("drippingwater:drop_water", { - hp_max = 1, - physical = true, - collide_with_objects = false, - collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025}, - pointable = false, - visual = "cube", - visual_size = {x=0.05, y=0.1}, - textures = {water_tex, water_tex, water_tex, water_tex, water_tex, water_tex}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, - static_save = false, - - on_activate = function(self, staticdata) - self.object:set_sprite({x=0,y=0}, 1, 1, true) - end, - - on_step = function(self, dtime) - local k = math.random(1,222) - local ownpos = self.object:get_pos() - - if k==1 then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - - if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - - if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then - self.object:remove() - minetest.sound_play({name="drippingwater_drip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) - end - end, -}) - - ---lava - -local lava_tex = "default_lava_source_animated.png^[verticalframe:16:0" -minetest.register_entity("drippingwater:drop_lava", { - hp_max = 1, - physical = true, - collide_with_objects = false, - collisionbox = {-0.025,-0.05,-0.025,0.025,-0.01,0.025}, - glow = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), - pointable = false, - visual = "cube", - visual_size = {x=0.05, y=0.1}, - textures = {lava_tex, lava_tex, lava_tex, lava_tex, lava_tex, lava_tex}, - spritediv = {x=1, y=1}, - initial_sprite_basepos = {x=0, y=0}, - static_save = false, - - on_activate = function(self, staticdata) - self.object:set_sprite({x=0,y=0}, 1, 0, true) - end, - - on_step = function(self, dtime) - local k = math.random(1,222) - local ownpos = self.object:get_pos() - - if k==1 then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - - if minetest.get_node({x=ownpos.x, y=ownpos.y +0.5, z=ownpos.z}).name == "air" then - self.object:set_acceleration({x=0, y=-5, z=0}) - end - - - if minetest.get_node({x=ownpos.x, y=ownpos.y -0.5, z=ownpos.z}).name ~= "air" then - self.object:remove() - minetest.sound_play({name="drippingwater_lavadrip"}, {pos = ownpos, gain = 0.5, max_hear_distance = 8}, true) - end - end, -}) - - - ---Create drop - -minetest.register_abm( - { - label = "Create water drops", - nodenames = {"group:opaque", "group:leaves"}, - neighbors = {"group:water"}, - interval = 2, - chance = 22, - action = function(pos) - if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "water") ~= 0 and - minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then - local i = math.random(-45,45) / 100 - minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_water") - end - end, -}) - ---Create lava drop - -minetest.register_abm( - { - label = "Create lava drops", - nodenames = {"group:opaque"}, - neighbors = {"group:lava"}, - interval = 2, - chance = 22, - action = function(pos) - if minetest.get_item_group(minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name, "lava") ~= 0 and - minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name == "air" then - local i = math.random(-45,45) / 100 - minetest.add_entity({x=pos.x + i, y=pos.y - 0.501, z=pos.z + i}, "drippingwater:drop_lava") - end - end, -}) diff --git a/mods/ENTITIES/drippingwater/readme.txt b/mods/ENTITIES/drippingwater/readme.txt deleted file mode 100644 index f609163ed..000000000 --- a/mods/ENTITIES/drippingwater/readme.txt +++ /dev/null @@ -1,29 +0,0 @@ -Dripping Water Mod -by kddekadenz - -modified for MineClone 2 by Wuzzy - - -Installing instructions: - - 1. Copy the drippingwater mod folder into games/gamemode/mods - - 2. Start game and enjoy :) - - -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 - - -License: - -code & sounds: CC0 - - -Changelog: - -16.04.2012 - first release -28.04.2012 - drops are now 3D; added lava drops; fixed generating of drops (not at edges now) diff --git a/mods/ENTITIES/mcl_boats/README.txt b/mods/ENTITIES/mcl_boats/README.txt index 195a2241a..0d56aa0e1 100644 --- a/mods/ENTITIES/mcl_boats/README.txt +++ b/mods/ENTITIES/mcl_boats/README.txt @@ -20,4 +20,4 @@ Authors include: * Various Minetest / Minetest Game developers and contributors (2012-2016) * maikerumine (2017) * Wuzzy (2017) - +* Fleckenstein (2020-2021) diff --git a/mods/ENTITIES/mcl_boats/depends.txt b/mods/ENTITIES/mcl_boats/depends.txt deleted file mode 100644 index 7a3ef812e..000000000 --- a/mods/ENTITIES/mcl_boats/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_player -mcl_core? -doc_identifier? diff --git a/mods/ENTITIES/mcl_boats/description.txt b/mods/ENTITIES/mcl_boats/description.txt deleted file mode 100644 index 65a979e8a..000000000 --- a/mods/ENTITIES/mcl_boats/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds drivable boats. diff --git a/mods/ENTITIES/mcl_boats/init.lua b/mods/ENTITIES/mcl_boats/init.lua index 5f666709c..fabfae91c 100644 --- a/mods/ENTITIES/mcl_boats/init.lua +++ b/mods/ENTITIES/mcl_boats/init.lua @@ -1,13 +1,32 @@ -local S = minetest.get_translator("mcl_boats") --- --- Helper functions --- +local S = minetest.get_translator(minetest.get_current_modname()) -local function is_water(pos) +local boat_visual_size = {x = 1, y = 1, z = 1} +local paddling_speed = 22 +local boat_y_offset = 0.35 +local boat_y_offset_ground = boat_y_offset + 0.6 +local boat_side_offset = 1.001 +local boat_max_hp = 4 + +local function is_group(pos, group) local nn = minetest.get_node(pos).name - return minetest.get_item_group(nn, "water") ~= 0 + return minetest.get_item_group(nn, group) ~= 0 end +local is_water = flowlib.is_water +local function is_river_water(p) + local n = minetest.get_node(p).name + if n == "mclx_core:river_water_source" or n == "mclx_core:river_water_flowing" then + return true + end +end + +local function is_ice(pos) + return is_group(pos, "ice") +end + +local function is_fire(pos) + return is_group(pos, "set_on_fire") +end local function get_sign(i) if i == 0 then @@ -17,67 +36,27 @@ local function get_sign(i) end end - local function get_velocity(v, yaw, y) local x = -math.sin(yaw) * v local z = math.cos(yaw) * v return {x = x, y = y, z = z} end - local function get_v(v) return math.sqrt(v.x ^ 2 + v.z ^ 2) end -local boat_visual_size = {x = 3, y = 3} --- Note: This mod assumes the default player visual_size is {x=1, y=1} -local driver_visual_size = { x = 1/boat_visual_size.x, y = 1/boat_visual_size.y } -local paddling_speed = 22 -local boat_y_offset = 0.35 -local boat_y_offset_ground = boat_y_offset + 0.6 -local boat_side_offset = 1.001 - --- --- Boat entity --- - -local boat = { - physical = true, - -- Warning: Do not change the position of the collisionbox top surface, - -- lowering it causes the boat to fall through the world if underwater - collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5}, - visual = "mesh", - mesh = "mcl_boats_boat.b3d", - textures = {"mcl_boats_texture_oak_boat.png"}, - visual_size = boat_visual_size, - hp_max = 4, - - _driver = nil, -- Attached driver (player) or nil if none - _passenger = nil, - _v = 0, -- Speed - _last_v = 0, -- Temporary speed variable - _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored - _itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type) - _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards -} - -local function detach_player(player, change_pos) - player:set_detach() - player:set_properties({visual_size = {x=1, y=1}}) - mcl_player.player_attached[player:get_player_name()] = false - mcl_player.player_set_animation(player, "stand" , 30) - if change_pos then - player:set_pos(vector.add(player:get_pos(), vector.new(0, 0.2, 0))) - end -end - local function check_object(obj) return obj and (obj:is_player() or obj:get_luaentity()) and obj end +local function get_visual_size(obj) + return obj:is_player() and {x = 1, y = 1, z = 1} or obj:get_luaentity()._old_visual_size or obj:get_properties().visual_size +end + local function set_attach(boat) boat._driver:set_attach(boat.object, "", - {x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0}) + {x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0}) end local function set_double_attach(boat) @@ -86,60 +65,125 @@ local function set_double_attach(boat) boat._passenger:set_attach(boat.object, "", {x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0}) end +local function set_choat_attach(boat) + boat._driver:set_attach(boat.object, "", + {x = 0, y = 1.5, z = 1}, {x = 0, y = 0, z = 0}) +end -minetest.register_on_respawnplayer(detach_player) +local function attach_object(self, obj) + if self._driver and not self._inv_id then + if self._driver:is_player() then + self._passenger = obj + else + self._passenger = self._driver + self._driver = obj + end + set_double_attach(self) + else + self._driver = obj + if self._inv_id then + set_choat_attach(self) + else + set_attach(self) + end + end + + local visual_size = get_visual_size(obj) + local yaw = self.object:get_yaw() + obj:set_properties({visual_size = vector.divide(visual_size, boat_visual_size)}) + + if obj:is_player() then + local name = obj:get_player_name() + mcl_player.player_attached[name] = true + minetest.after(0.2, function(name) + local player = minetest.get_player_by_name(name) + if player then + mcl_player.player_set_animation(player, "sit" , 30) + end + end, name) + obj:set_look_horizontal(yaw) + mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) + else + obj:get_luaentity()._old_visual_size = visual_size + end +end + +local function detach_object(obj, change_pos) + if not obj or not obj:get_pos() then return end + obj:set_detach() + obj:set_properties({visual_size = get_visual_size(obj)}) + if obj:is_player() then + mcl_player.player_attached[obj:get_player_name()] = false + mcl_player.player_set_animation(obj, "stand" , 30) + else + obj:get_luaentity()._old_visual_size = nil + end + if change_pos then + obj:set_pos(vector.add(obj:get_pos(), vector.new(0, 0.2, 0))) + end +end + +-- +-- Boat entity +-- + +local boat = { + physical = true, + pointable = true, + -- Warning: Do not change the position of the collisionbox top surface, + -- lowering it causes the boat to fall through the world if underwater + collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.55, 0.5}, + selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.55, 0.7}, + visual = "mesh", + mesh = "mcl_boats_boat.b3d", + textures = { "mcl_boats_texture_oak_boat.png", "blank.png" }, + visual_size = boat_visual_size, + hp_max = boat_max_hp, + damage_texture_modifier = "^[colorize:white:0", + + _driver = nil, -- Attached driver (player) or nil if none + _passenger = nil, + _v = 0, -- Speed + _last_v = 0, -- Temporary speed variable + _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored + _itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type) + _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling backwards + _regen_timer = 0, + _damage_anim = 0, +} + +minetest.register_on_respawnplayer(detach_object) function boat.on_rightclick(self, clicker) if self._passenger or not clicker or clicker:get_attach() then return end - local name = clicker:get_player_name() - --[[if attach and attach:get_luaentity() then - local luaentity = attach:get_luaentity() - if luaentity._driver then - luaentity._driver = nil - end - clicker:set_detach() - clicker:set_properties({visual_size = {x=1, y=1}}) - end--]] - if self._driver then - if self._driver:is_player() then - self._passenger = clicker - else - -- for later use: transport mobs in boats - self._passenger = self._driver - self._driver = clicker - end - set_double_attach(self) - else - self._driver = clicker - set_attach(self) - end - clicker:set_properties({ visual_size = driver_visual_size }) - mcl_player.player_attached[name] = true - minetest.after(0.2, function(name) - local player = minetest.get_player_by_name(name) - if player then - mcl_player.player_set_animation(player, "sit" , 30) - end - end, name) - clicker:set_look_horizontal(self.object:get_yaw()) - mcl_tmp_message.message(clicker, S("Sneak to dismount")) + attach_object(self, clicker) end function boat.on_activate(self, staticdata, dtime_s) - --self.object:set_armor_groups({immortal = 1}) + self.object:set_armor_groups({fleshy = 100}) local data = minetest.deserialize(staticdata) if type(data) == "table" then self._v = data.v self._last_v = self._v self._itemstring = data.itemstring - self.object:set_properties({textures = data.textures, damage_texture_modifier = ""}) + + -- Update the texutes for existing old boat entity instances. + -- Maybe remove this in the future. + if #data.textures ~= 2 then + local has_chest = self._itemstring:find("chest") + data.textures = { + data.textures[1]:gsub("_chest", ""), + has_chest and "mcl_chests_normal.png" or "blank.png" + } + end + + self.object:set_properties({textures = data.textures}) end end - function boat.get_staticdata(self) return minetest.serialize({ v = self._v, @@ -148,8 +192,9 @@ function boat.get_staticdata(self) }) end - function boat.on_death(self, killer) + mcl_burning.extinguish(self.object) + if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then local inv = killer:get_inventory() if not inv:contains_item("main", self._itemstring) then @@ -159,37 +204,69 @@ function boat.on_death(self, killer) minetest.add_item(self.object:get_pos(), self._itemstring) end if self._driver then - detach_player(self._driver) + detach_object(self._driver) end if self._passenger then - detach_player(self._passenger) + detach_object(self._passenger) end self._driver = nil self._passenger = nil end +function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + if damage > 0 then + self._regen_timer = 0 + end +end + function boat.on_step(self, dtime, moveresult) + mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end + self._v = get_v(self.object:get_velocity()) * get_sign(self._v) - local on_water = true - local in_water = false local v_factor = 1 local v_slowdown = 0.02 local p = self.object:get_pos() - if (not is_water({x=p.x, y=p.y-boat_y_offset, z=p.z})) then + local on_water = true + local on_ice = false + local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) + local in_river_water = is_river_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z}) + local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z} + if not is_water(waterp) then on_water = false - v_factor = 0.5 - v_slowdown = 0.04 - elseif (is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})) then + if not in_water and is_ice(waterp) then + on_ice = true + elseif is_fire({x=p.x, y=p.y-boat_y_offset, z=p.z}) then + boat.on_death(self, nil) + self.object:remove() + return + else + v_slowdown = 0.04 + v_factor = 0.5 + end + elseif in_water and not in_river_water then on_water = false in_water = true v_factor = 0.75 v_slowdown = 0.05 end + local hp = self.object:get_hp() + local regen_timer = self._regen_timer + dtime + if hp >= boat_max_hp then + regen_timer = 0 + elseif regen_timer >= 0.5 then + hp = hp + 1 + self.object:set_hp(hp) + regen_timer = 0 + end + self._regen_timer = regen_timer + if moveresult and moveresult.collides then - for _, collision in ipairs(moveresult.collisions) do + for _, collision in pairs(moveresult.collisions) do local pos = collision.node_pos - if collision.type == "node" and minetest.get_node_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then + if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then minetest.dig_node(pos) end end @@ -207,7 +284,7 @@ function boat.on_step(self, dtime, moveresult) else local ctrl = self._passenger:get_player_control() if ctrl and ctrl.sneak then - detach_player(self._passenger, true) + detach_object(self._passenger, true) self._passenger = nil end end @@ -219,12 +296,12 @@ function boat.on_step(self, dtime, moveresult) end local ctrl = self._driver:get_player_control() if ctrl and ctrl.sneak then - detach_player(self._driver, true) + detach_object(self._driver, true) self._driver = nil return end local yaw = self.object:get_yaw() - if ctrl.up then + if ctrl and ctrl.up then -- Forwards self._v = self._v + 0.1 * v_factor @@ -233,7 +310,7 @@ function boat.on_step(self, dtime, moveresult) self.object:set_animation({x=0, y=40}, paddling_speed, 0, true) self._animation = 1 end - elseif ctrl.down then + elseif ctrl and ctrl.down then -- Backwards self._v = self._v - 0.1 * v_factor @@ -268,11 +345,19 @@ function boat.on_step(self, dtime, moveresult) self.object:set_animation({x=0, y=40}, 0, 0, true) self._animation = 0 end + + for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do + local entity = obj:get_luaentity() + if entity and entity.is_mob then + attach_object(self, obj) + break + end + end end local s = get_sign(self._v) - if not on_water and not in_water and math.abs(self._v) > 1.0 then - v_slowdown = math.min(math.abs(self._v) - 1.0, v_slowdown * 5) - elseif in_water and math.abs(self._v) > 1.5 then + if not on_ice and not on_water and not in_water and math.abs(self._v) > 2.0 then + v_slowdown = math.min(math.abs(self._v) - 2.0, v_slowdown * 5) + elseif not on_ice and in_water and math.abs(self._v) > 1.5 then v_slowdown = math.min(math.abs(self._v) - 1.5, v_slowdown * 5) end self._v = self._v - v_slowdown * s @@ -282,16 +367,28 @@ function boat.on_step(self, dtime, moveresult) p.y = p.y - boat_y_offset local new_velo - local new_acce = {x = 0, y = 0, z = 0} - if not is_water(p) then + local new_acce + if not is_water(p) and not on_ice then -- Not on water or inside water: Free fall - local nodedef = minetest.registered_nodes[minetest.get_node(p).name] + --local nodedef = minetest.registered_nodes[minetest.get_node(p).name] new_acce = {x = 0, y = -9.8, z = 0} new_velo = get_velocity(self._v, self.object:get_yaw(), self.object:get_velocity().y) else p.y = p.y + 1 - if is_water(p) then + local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian" + if is_river_water(p) then + local y = self.object:get_velocity().y + if y >= 5 then + y = 5 + elseif y < 0 then + new_acce = {x = 0, y = 10, z = 0} + else + new_acce = {x = 0, y = 2, z = 0} + end + new_velo = get_velocity(self._v, self.object:get_yaw(), y) + self.object:set_pos(self.object:get_pos()) + elseif is_water(p) and not is_river_water(p) or is_obsidian_boat then -- Inside water: Slowly sink local y = self.object:get_velocity().y y = y - 0.01 @@ -313,12 +410,17 @@ function boat.on_step(self, dtime, moveresult) end -- Terminal velocity: 8 m/s per axis of travel + local terminal_velocity = on_ice and 57.1 or 8.0 for _,axis in pairs({"z","y","x"}) do - if math.abs(new_velo[axis]) > 8 then - new_velo[axis] = 8 * get_sign(new_velo[axis]) + if math.abs(new_velo[axis]) > terminal_velocity then + new_velo[axis] = terminal_velocity * get_sign(new_velo[axis]) end end + local yaw = self.object:get_yaw() + local anim = (boat_max_hp - hp - regen_timer * 2) / boat_max_hp * math.pi / 4 + + self.object:set_rotation(vector.new(anim, yaw, anim)) self.object:set_velocity(new_velo) self.object:set_acceleration(new_acce) end @@ -326,13 +428,18 @@ end -- Register one entity for all boat types minetest.register_entity("mcl_boats:boat", boat) -local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak" } -local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat") } -local craftstuffs = {} -if minetest.get_modpath("mcl_core") then - craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood" } -end -local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak" } +local cboat = table.copy(boat) +cboat.textures = { "mcl_boats_texture_oak_chest_boat.png", "mcl_chests_normal.png" } +cboat._itemstring = "mcl_boats:chest_boat" +cboat.collisionbox = {-0.5, -0.15, -0.5, 0.5, 0.75, 0.5} +cboat.selectionbox = {-0.7, -0.15, -0.7, 0.7, 0.75, 0.7} + +minetest.register_entity("mcl_boats:chest_boat", cboat) +mcl_entity_invs.register_inv("mcl_boats:chest_boat","Boat",27) + +local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian", "boat_mangrove", "boat_cherry", "chest_boat", "chest_boat_spruce", "chest_boat_birch", "chest_boat_jungle", "chest_boat_acacia", "chest_boat_dark_oak", "chest_boat_mangrove", "chest_boat_cherry" } +local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat"), S("Mangrove Boat"), S("Cherry Boat"), S("Oak Chest Boat"), S("Spruce Chest Boat"), S("Birch Chest Boat"), S("Jungle Chest Boat"), S("Acacia Chest Boat"), S("Dark Oak Chest Boat"), S("Mangrove Chest Boat"), S("Cherry Chest Boat") } +local craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian", "mcl_mangrove:mangrove_wood", "mcl_cherry_blossom:cherrywood" } for b=1, #boat_ids do local itemstring = "mcl_boats:"..boat_ids[b] @@ -343,11 +450,26 @@ for b=1, #boat_ids do if b == 1 then help = true longdesc = S("Boats are used to travel on the surface of water.") - usagehelp = S("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.") + usagehelp = S("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.") helpname = S("Boat") end tt_help = S("Water vehicle") + local inventory_image + local texture + local id = boat_ids[b] + if id:find("chest") then + if id == "chest_boat" then id = "oak" end + local id = id:gsub("chest_boat_", "") + inventory_image = "mcl_boats_" .. id .. "_chest_boat.png" + texture = "mcl_boats_texture_" .. id .. "_boat.png" + else + if id == "boat" then id = "oak" end + local id = id:gsub("boat_", "") + inventory_image = "mcl_boats_" .. id .. "_boat.png" + texture = "mcl_boats_texture_" .. id .. "_boat.png" + end + minetest.register_craftitem(itemstring, { description = names[b], _tt_help = tt_help, @@ -355,7 +477,7 @@ for b=1, #boat_ids do _doc_items_entry_name = helpname, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - inventory_image = "mcl_boats_"..images[b].."_boat.png", + inventory_image = inventory_image, liquids_pointable = true, groups = { boat = 1, transport = 1}, stack_max = 1, @@ -382,9 +504,15 @@ for b=1, #boat_ids do else pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground)) end - local boat = minetest.add_entity(pos, "mcl_boats:boat") + local boat_ent = "mcl_boats:boat" + local chest_tex = "blank.png" + if itemstring:find("chest") then + boat_ent = "mcl_boats:chest_boat" + chest_tex = "mcl_chests_normal.png" + end + local boat = minetest.add_entity(pos, boat_ent) boat:get_luaentity()._itemstring = itemstring - boat:set_properties({textures = { "mcl_boats_texture_"..images[b].."_boat.png" }}) + boat:set_properties({ textures = { texture, chest_tex } }) boat:set_yaw(placer:get_look_horizontal()) if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() @@ -404,13 +532,22 @@ for b=1, #boat_ids do }) local c = craftstuffs[b] - minetest.register_craft({ - output = itemstring, - recipe = { - {c, "", c}, - {c, c, c}, - }, - }) + if not itemstring:find("chest") then + minetest.register_craft({ + output = itemstring:gsub(":boat",":chest_boat"), + recipe = { + {"mcl_chests:chest"}, + {itemstring}, + }, + }) + minetest.register_craft({ + output = itemstring, + recipe = { + {c, "", c}, + {c, c, c}, + }, + }) + end end minetest.register_craft({ @@ -419,6 +556,6 @@ minetest.register_craft({ burntime = 20, }) -if minetest.get_modpath("doc_identifier") ~= nil then +if minetest.get_modpath("doc_identifier") then doc.sub.identifier.register_object("mcl_boats:boat", "craftitems", "mcl_boats:boat") end diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.de.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.de.tr index 95066b530..c1864a871 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.de.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.de.tr @@ -6,6 +6,7 @@ Boats are used to travel on the surface of water.=Boote werden benutzt, um sich Dark Oak Boat=Schwarzeichenboot Jungle Boat=Dschungelboot Oak Boat=Eichenboot -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.=Rechtsklicken Sie auf eine Wasserquelle, um das Boot zu platzieren. Rechtsklicken Sie auf das Boot, um es zu betreten. Mit [Links] und [Rechts] lenken, mit [Vorwärts] und [Rückwärts] Geschwindigkeit regeln oder rückwärts fahren. Rechtsklicken Sie erneut auf das Boot, um es zu verlassen, schlagen Sie das Boot, um es als Gegenstand fallen zu lassen. +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.=Rechtsklicken Sie auf eine Wasserquelle, um das Boot zu platzieren. Rechtsklicken Sie auf das Boot, um es zu betreten. Mit [Links] und [Rechts] lenken, mit [Vorwärts] und [Rückwärts] Geschwindigkeit regeln oder rückwärts fahren. Nutzen sie [Schleichen], um das Boot zu verlassen, schlagen Sie das Boot, um es als Gegenstand fallen zu lassen. Spruce Boat=Fichtenboot Water vehicle=Wasserfahrzeug +Sneak to dismount=Zum Aussteigen schleichen diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.dk.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.dk.tr new file mode 100644 index 000000000..53a6f50e7 --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.dk.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_boats +Acacia Boat=Akaciebåd +Birch Boat=Birkebåd +Boat=Båd +Boats are used to travel on the surface of water.=Både blier brugt til at rejse på vandoverflader. +Dark Oak Boat=Mørk egetræsbåd +Jungle Boat=Junglebåd +Oak Boat=Egetræsbåd +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.=Højre-klik på en vand for at placere båden. Højre-klik på båden for at gå ombord. Brug [Left] og [Right] til at styre. [Forwards] for at øge hastigheden, og [Backwards] for at sænke farten eller sejle bagud. Brug [Sneak] for at forlade båden, slå båden for at lave den om til en genstand. +Spruce Boat=Granbåd +Water vehicle=Vandfartøj +Sneak to dismount=Snig for at stige ud +Obsidian Boat=Obsidianbåd \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.es.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.es.tr index 644efdb6b..d3596e056 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.es.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.es.tr @@ -8,3 +8,6 @@ Jungle Boat=Barca de la selva Oak Boat=Barca de roble 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.=Haga clic derecho en una fuente de agua para colocar el barco. Haga clic derecho en el barco para entrar. Utilice [Izquierda] y [Derecha] para dirigir, [Adelante] para acelerar y [Atrás] para reducir la velocidad o retroceder. Haga clic derecho en el barco nuevamente para dejarlo, golpee el barco para que se caiga como un artículo. Spruce Boat=Barca de abeto +Water vehicle=Vehículo acuático +Sneak to dismount=Agáchate para bajar +Obsidian Boat=Barca de obsidiana diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr index 04d6d9da9..e1ecd9b01 100644 --- a/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.fr.tr @@ -1,11 +1,21 @@ # textdomain: mcl_boats -Acacia Boat=Bateau en Acacia -Birch Boat=Bateau en Bouleau +Acacia Boat=Bateau en acacia +Birch Boat=Bateau en bouleau Boat=Bateau Boats are used to travel on the surface of water.=Les bateaux sont utilisés pour voyager à la surface de l'eau. -Dark Oak Boat=Bateau en Chêne Noir -Jungle Boat=Bateau en Acajou -Oak Boat=Bateau en Chêne -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.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Cliquez de nouveau avec le bouton droit sur le bateau pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. -Spruce Boat=Bateau en Sapin -Water vehicle=Véhicule aquatique \ No newline at end of file +Dark Oak Boat=Bateau en chêne noir +Jungle Boat=Bateau en acajou +Oak Boat=Bateau en chêne +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.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet. +Spruce Boat=Bateau en sapin +Water vehicle=Véhicule aquatique +Sneak to dismount=Se baisser pour descendre +Obsidian Boat=Bateau en obsidienne +Mangrove Boat=Bateau en palétuvier +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 +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 diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr new file mode 100644 index 000000000..05ff22b1b --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.ja.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_boats +Acacia Boat=アカシアのボート +Birch Boat=シラカバのボート +Boat=ボート +Boats are used to travel on the surface of water.=ボートは、水面を移動するために使われます。 +Dark Oak 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. 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=黒曜石のボート \ No newline at end of file diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.pl.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.pl.tr new file mode 100644 index 000000000..17b5183bc --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.pl.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_boats +Acacia Boat=Akacjowa łódź +Birch Boat=Brzozowa łódź +Boat=Łódź +Boats are used to travel on the surface of water.=Łodzie są wykorzystywane do podróżowania po powierzchni wody. +Dark Oak Boat=Ciemno-dębowa łódź +Jungle Boat=Tropikalna łódź +Oak Boat=Dębowa łódź +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.=Kliknij prawym przyciskiem myszy na źródło wody by postawić łódź. Kliknij prawym przyciskiem myszy by w nią wsiąść. Użyj przycisków [Lewy] oraz [Prawy] by sterować, [Naprzód] by przyspieszyć i [W tył] by zwolnić lub się cofać. Kliknij [Skradanie] by z niej wyjść, uderz ją by wziąć ją jako przedmiot. +Spruce Boat=Świerkowa łódź +Water vehicle=Pojazd wodny +Sneak to dismount=Skradaj się by opuścić łódź diff --git a/mods/ENTITIES/mcl_boats/locale/mcl_boats.zh_TW.tr b/mods/ENTITIES/mcl_boats/locale/mcl_boats.zh_TW.tr new file mode 100644 index 000000000..c1c404f2a --- /dev/null +++ b/mods/ENTITIES/mcl_boats/locale/mcl_boats.zh_TW.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_boats +Acacia Boat=相思木船 +Birch Boat=白樺木船 +Boat=船 +Boats are used to travel on the surface of water.=船是用來在水上行走的交通工具。 +Dark Oak 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.=右鍵單擊水源以放置船。右鍵單擊船以搭乘它。使用[左]和[右]進行轉向,[向前]加快速度,[向後]減速或向後移動。再次右鍵單擊船以離開它,打擊船以使其掉落為物品。 +Spruce Boat=杉木船 +Water vehicle=水上交通工具 diff --git a/mods/ENTITIES/mcl_boats/locale/template.txt b/mods/ENTITIES/mcl_boats/locale/template.txt index 54f1fd646..c3919e8b9 100644 --- a/mods/ENTITIES/mcl_boats/locale/template.txt +++ b/mods/ENTITIES/mcl_boats/locale/template.txt @@ -6,6 +6,18 @@ Boats are used to travel on the surface of water.= Dark Oak 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_boats/mod.conf b/mods/ENTITIES/mcl_boats/mod.conf index f14456c5f..fcbe3f2f6 100644 --- a/mods/ENTITIES/mcl_boats/mod.conf +++ b/mods/ENTITIES/mcl_boats/mod.conf @@ -1 +1,5 @@ name = mcl_boats +author = PilzAdam +description = Adds drivable boats. +depends = mcl_player, flowlib, mcl_title, mcl_entity_invs +optional_depends = mcl_core, doc_identifier diff --git a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d index e53bc4129..344bb3e70 100644 Binary files a/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d and b/mods/ENTITIES/mcl_boats/models/mcl_boats_boat.b3d differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_boat.png deleted file mode 100644 index 3ba009117..000000000 Binary files a/mods/ENTITIES/mcl_boats/textures/mcl_boats_acacia_boat.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_boat.png deleted file mode 100644 index ac0f3dc1b..000000000 Binary files a/mods/ENTITIES/mcl_boats/textures/mcl_boats_birch_boat.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_boat.png b/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_boat.png deleted file mode 100644 index 371596f63..000000000 Binary files a/mods/ENTITIES/mcl_boats/textures/mcl_boats_oak_boat.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua new file mode 100644 index 000000000..74c66d5f1 --- /dev/null +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -0,0 +1,186 @@ +local enable_damage = minetest.settings:get_bool("enable_damage") + +function mcl_burning.get_storage(obj) + return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity() +end + +function mcl_burning.is_burning(obj) + local storage = mcl_burning.get_storage(obj) + if storage then + return mcl_burning.get_storage(obj).burn_time + else + return false + end +end + +function mcl_burning.is_affected_by_rain(obj) + return mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos()) +end + +function mcl_burning.get_collisionbox(obj, smaller, storage) + local cache = storage.collisionbox_cache + if cache then + local box = cache[smaller and 2 or 1] + return box[1], box[2] + else + local box = obj:get_properties().collisionbox + local minp, maxp = vector.new(box[1], box[2], box[3]), vector.new(box[4], box[5], box[6]) + local s_vec = vector.new(0.1, 0.1, 0.1) + local s_minp = vector.add(minp, s_vec) + local s_maxp = vector.subtract(maxp, s_vec) + storage.collisionbox_cache = {{minp, maxp}, {s_minp, s_maxp}} + return minp, maxp + end +end + +local find_nodes_in_area = minetest.find_nodes_in_area + +function mcl_burning.get_touching_nodes(obj, nodenames, storage) + local pos = obj:get_pos() + local minp, maxp = mcl_burning.get_collisionbox(obj, true, storage) + local nodes = find_nodes_in_area(vector.add(pos, minp), vector.add(pos, maxp), nodenames) + return nodes +end + +-- Manages the fire animation on a burning player's HUD +-- +-- Parameters: +-- player - a valid player object; +-- +-- If the player already has a fire HUD, updates the burning animation. +-- If the fire does not have a fire HUD, initializes the HUD. +-- +function mcl_burning.update_hud(player) + local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 + local hud_flame_animated = "mcl_burning_hud_flame_animated.png^[opacity:180^[verticalframe:" .. animation_frames .. ":" + + local storage = mcl_burning.get_storage(player) + if not storage.fire_hud_id then + storage.animation_frame = 1 + storage.fire_hud_id = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -100, y = -100}, + text = hud_flame_animated .. storage.animation_frame, + z_index = 1000, + }) + else + storage.animation_frame = storage.animation_frame + 1 + if storage.animation_frame > animation_frames - 1 then + storage.animation_frame = 0 + end + player:hud_change(storage.fire_hud_id, "text", hud_flame_animated .. storage.animation_frame) + end +end + +-- Sets and object state as burning and adds a fire animation to the object. +-- +-- Parameters: +-- obj - may be a player or a lua_entity; +-- burn_time - sets the object's burn duration; +-- +-- If obj is a player, adds a fire animation to the HUD, if obj is a +-- lua_entity, adds an animated fire entity to obj. +-- The effective burn duration is modified by obj's armor protection. +-- If obj was already burning, its burn duration is updated if the current +-- duration is less than burn_time. +-- If obj is dead, fireproof or enable_damage is disabled, this function does nothing. +-- +function mcl_burning.set_on_fire(obj, burn_time) + if obj:get_hp() < 0 then + return + end + + local luaentity = obj:get_luaentity() + if luaentity and luaentity.fire_resistant then + return + end + + if obj:is_player() and not enable_damage then + burn_time = 0 + return + else + local max_fire_prot_lvl = 0 + local inv = mcl_util.get_inventory(obj) + local armor_list = inv and inv:get_list("armor") + + if armor_list then + for _, stack in pairs(armor_list) do + local fire_prot_lvl = mcl_enchanting.get_enchantment(stack, "fire_protection") + if fire_prot_lvl > max_fire_prot_lvl then + max_fire_prot_lvl = fire_prot_lvl + end + end + end + if max_fire_prot_lvl > 0 then + burn_time = burn_time - math.floor(burn_time * max_fire_prot_lvl * 0.15) + end + end + + local storage = mcl_burning.get_storage(obj) + if storage.burn_time then + if burn_time > storage.burn_time then + storage.burn_time = burn_time + end + return + end + storage.burn_time = burn_time + storage.fire_damage_timer = 0 + + local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage) + local size = vector.subtract(maxp, minp) + size = vector.multiply(size, vector.new(1.1, 1.2, 1.1)) + size = vector.divide(size, obj:get_properties().visual_size) + + local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") + fire_entity:set_properties({visual_size = size}) + fire_entity:set_attach(obj, "", vector.new(0, size.y * 5, 0), vector.new(0, 0, 0)) + + if obj:is_player() then + mcl_burning.update_hud(obj) + end +end + +function mcl_burning.extinguish(obj) + if not obj:get_pos() then return end + if mcl_burning.is_burning(obj) then + local storage = mcl_burning.get_storage(obj) + if obj:is_player() then + if storage.fire_hud_id then + obj:hud_remove(storage.fire_hud_id) + end + mcl_burning.storage[obj] = {} + else + storage.burn_time = nil + storage.fire_damage_timer = nil + end + end +end + +function mcl_burning.tick(obj, dtime, storage) + if not storage then + minetest.log("warning", "No storage for burning tick. Should not happen: " .. dump(obj)) + return + end + + if storage.burn_time then + storage.burn_time = storage.burn_time - dtime + + if storage.burn_time <= 0 or mcl_burning.is_affected_by_rain(obj) or #mcl_burning.get_touching_nodes(obj, "group:puts_out_fire", storage) > 0 then + mcl_burning.extinguish(obj) + return true + else + storage.fire_damage_timer = storage.fire_damage_timer + dtime + + if storage.fire_damage_timer >= 1 then + storage.fire_damage_timer = 0 + + local luaentity = obj:get_luaentity() + + if not luaentity or not luaentity.fire_damage_resistant then + mcl_util.deal_damage(obj, 1, {type = "on_fire"}) + end + end + end + end +end diff --git a/mods/ENTITIES/mcl_burning/engine.lua b/mods/ENTITIES/mcl_burning/engine.lua deleted file mode 100644 index 57890dd2f..000000000 --- a/mods/ENTITIES/mcl_burning/engine.lua +++ /dev/null @@ -1,304 +0,0 @@ -local S = minetest.get_translator("mcl_burning") - -function mcl_burning.get_default(datatype) - local default_table = {string = "", float = 0.0, int = 0, bool = false} - return default_table[datatype] -end - -function mcl_burning.get(obj, datatype, name) - local key - if obj:is_player() then - local meta = obj:get_meta() - return meta["get_" .. datatype](meta, "mcl_burning:" .. name) - else - local luaentity = obj:get_luaentity() - return luaentity and luaentity["mcl_burning_" .. name] or mcl_burning.get_default(datatype) - end -end - -function mcl_burning.set(obj, datatype, name, value) - if obj:is_player() then - local meta = obj:get_meta() - meta["set_" .. datatype](meta, "mcl_burning:" .. name, value or mcl_burning.get_default(datatype)) - else - local luaentity = obj:get_luaentity() - if mcl_burning.get_default(datatype) == value then - value = nil - end - luaentity["mcl_burning_" .. name] = value - end -end - -function mcl_burning.is_burning(obj) - return mcl_burning.get(obj, "float", "burn_time") > 0 -end - -function mcl_burning.is_affected_by_rain(obj) - return mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos()) -end - -function mcl_burning.get_collisionbox(obj, smaller) - local box = obj:get_properties().collisionbox - local minp, maxp = vector.new(box[1], box[2], box[3]), vector.new(box[4], box[5], box[6]) - if smaller then - local s_vec = vector.new(0.1, 0.1, 0.1) - minp = vector.add(minp, s_vec) - maxp = vector.subtract(maxp, s_vec) - end - return minp, maxp -end - -function mcl_burning.get_touching_nodes(obj, nodenames) - local pos = obj:get_pos() - local box = obj:get_properties().collisionbox - local minp, maxp = mcl_burning.get_collisionbox(obj, true) - local nodes = minetest.find_nodes_in_area(vector.add(pos, minp), vector.add(pos, maxp), nodenames) - return nodes -end - -function mcl_burning.get_highest_group_value(obj, groupname) - local nodes = mcl_burning.get_touching_nodes(obj, "group:" .. groupname, true) - local highest_group_value = 0 - - for _, pos in pairs(nodes) do - local node = minetest.get_node(pos) - local group_value = minetest.get_item_group(node.name, groupname) - if group_value > highest_group_value then - highest_group_value = group_value - end - end - - return highest_group_value -end - -function mcl_burning.damage(obj) - local luaentity = obj:get_luaentity() - local health - - if luaentity then - health = luaentity.health - end - - local hp = health or obj:get_hp() - - if hp <= 0 then - return - end - - local do_damage = true - - if obj:is_player() then - if mcl_potions.player_has_effect(obj, "fire_proof") then - do_damage = false - else - local name = obj:get_player_name() - armor.last_damage_types[name] = "fire" - local deathmsg = S("@1 burned to death.", name) - local reason = mcl_burning.get(obj, "string", "reason") - if reason ~= "" then - deathmsg = S("@1 was burned by @2.", name, reason) - end - mcl_death_messages.player_damage(obj, deathmsg) - end - else - if luaentity.fire_damage_resistant then - do_damage = false - end - end - - if do_damage then - local damage = mcl_burning.get(obj, "float", "damage") - if damage == 0 then - damage = 1 - end - local new_hp = hp - damage - if health then - luaentity.health = new_hp - else - obj:set_hp(new_hp) - end - end -end - -function mcl_burning.set_on_fire(obj, burn_time, damage, reason) - local luaentity = obj:get_luaentity() - if luaentity and luaentity.fire_resistant then - return - end - - local old_burn_time = mcl_burning.get(obj, "float", "burn_time") - local max_fire_prot_lvl = 0 - - if obj:is_player() then - if minetest.is_creative_enabled(obj:get_player_name()) then - burn_time = burn_time / 100 - end - - local inv = obj:get_inventory() - - for i = 2, 5 do - local stack = inv:get_stack("armor", i) - - local fire_prot_lvl = mcl_enchanting.get_enchantment(stack, "fire_protection") - max_fire_prot_lvl = math.max(max_fire_prot_lvl, fire_prot_lvl) - end - end - - if max_fire_prot_lvl > 0 then - burn_time = burn_time - math.floor(burn_time * max_fire_prot_lvl * 0.15) - end - - if old_burn_time <= burn_time then - local sound_id = mcl_burning.get(obj, "int", "sound_id") - if sound_id == 0 then - sound_id = minetest.sound_play("fire_fire", { - object = obj, - gain = 0.18, - max_hear_distance = 16, - loop = true, - }) + 1 - end - - local hud_id - if obj:is_player() then - hud_id = mcl_burning.get(obj, "int", "hud_id") - if hud_id == 0 then - hud_id = obj:hud_add({ - hud_elem_type = "image", - position = {x = 0.5, y = 0.5}, - scale = {x = -100, y = -100}, - text = "fire_basic_flame.png", - z_index = 1000, - }) + 1 - end - end - mcl_burning.set(obj, "float", "burn_time", burn_time) - mcl_burning.set(obj, "float", "damage", damage) - mcl_burning.set(obj, "string", "reason", reason) - mcl_burning.set(obj, "int", "hud_id", hud_id) - mcl_burning.set(obj, "int", "sound_id", sound_id) - - local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") - local minp, maxp = mcl_burning.get_collisionbox(obj) - local obj_size = obj:get_properties().visual_size - - local vertical_grow_factor = 1.2 - local horizontal_grow_factor = 1.1 - local grow_vector = vector.new(horizontal_grow_factor, vertical_grow_factor, horizontal_grow_factor) - - local size = vector.subtract(maxp, minp) - size = vector.multiply(size, grow_vector) - size = vector.divide(size, obj_size) - local offset = vector.new(0, size.y * 10 / 2, 0) - - fire_entity:set_properties({visual_size = size}) - fire_entity:set_attach(obj, "", offset, {x = 0, y = 0, z = 0}) - mcl_burning.update_animation_frame(obj, fire_entity, 0) - end -end - -function mcl_burning.extinguish(obj) - if mcl_burning.is_burning(obj) then - local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1 - minetest.sound_stop(sound_id) - - if obj:is_player() then - local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1 - obj:hud_remove(hud_id) - end - - mcl_burning.set(obj, "float", "damage") - mcl_burning.set(obj, "string", "reason") - mcl_burning.set(obj, "float", "burn_time") - mcl_burning.set(obj, "float", "damage_timer") - mcl_burning.set(obj, "int", "hud_id") - mcl_burning.set(obj, "int", "sound_id") - end -end - -function mcl_burning.catch_fire_tick(obj, dtime) - if mcl_burning.is_affected_by_rain(obj) or #mcl_burning.get_touching_nodes(obj, "group:puts_out_fire") > 0 then - mcl_burning.extinguish(obj) - else - local set_on_fire_value = mcl_burning.get_highest_group_value(obj, "set_on_fire") - - if set_on_fire_value > 0 then - mcl_burning.set_on_fire(obj, set_on_fire_value) - end - end -end - -function mcl_burning.tick(obj, dtime) - local burn_time = mcl_burning.get(obj, "float", "burn_time") - dtime - - if burn_time <= 0 then - mcl_burning.extinguish(obj) - else - mcl_burning.set(obj, "float", "burn_time", burn_time) - - local damage_timer = mcl_burning.get(obj, "float", "damage_timer") + dtime - - if damage_timer >= 1 then - damage_timer = 0 - mcl_burning.damage(obj) - end - - mcl_burning.set(obj, "float", "damage_timer", damage_timer) - end - - mcl_burning.catch_fire_tick(obj, dtime) -end - -function mcl_burning.update_animation_frame(obj, fire_entity, animation_frame) - local fire_texture = "mcl_burning_entity_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. animation_frame - local fire_HUD_texture = "mcl_burning_hud_flame_animated.png^[opacity:180^[verticalframe:" .. mcl_burning.animation_frames .. ":" .. animation_frame - fire_entity:set_properties({textures = {"blank.png", "blank.png", fire_texture, fire_texture, fire_texture, fire_texture}}) - if obj:is_player() then - local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1 - obj:hud_change(hud_id, "text", fire_HUD_texture) - end -end - -function mcl_burning.fire_entity_step(self, dtime) - if self.removed then - return - end - - local obj = self.object - local parent = obj:get_attach() - local do_remove - - self.doing_step = true - - if not parent or not mcl_burning.is_burning(parent) then - do_remove = true - else - for _, other in ipairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do - local luaentity = obj:get_luaentity() - if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then - do_remove = true - break - end - end - end - - self.doing_step = false - - if do_remove then - self.removed = true - obj:remove() - return - end - - local animation_timer = self.animation_timer + dtime - if animation_timer >= 0.015 then - animation_timer = 0 - local animation_frame = self.animation_frame + 1 - if animation_frame > mcl_burning.animation_frames - 1 then - animation_frame = 0 - end - mcl_burning.update_animation_frame(parent, obj, animation_frame) - self.animation_frame = animation_frame - end - self.animation_timer = animation_timer -end diff --git a/mods/ENTITIES/mcl_burning/init.lua b/mods/ENTITIES/mcl_burning/init.lua index 1b341273e..039d295b7 100644 --- a/mods/ENTITIES/mcl_burning/init.lua +++ b/mods/ENTITIES/mcl_burning/init.lua @@ -1,29 +1,51 @@ -local S = minetest.get_translator("mcl_burning") -local modpath = minetest.get_modpath("mcl_burning") +local modpath = minetest.get_modpath(minetest.get_current_modname()) mcl_burning = { - animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 + -- the storage table holds a list of objects (players,luaentities) and tables + -- associated with these objects. These tables have the following attributes: + -- burn_time: + -- Remaining time that object will burn. + -- fire_damage_timer: + -- Timer for dealing damage every second while burning. + -- fire_hud_id: + -- HUD id of the flames animation on a burning player's HUD. + -- animation_frame: + -- The HUD's current animation frame, used by update_hud(). + -- collisionbox_cache: + -- Used by mcl_burning.get_collisionbox() to avoid recalculations. + storage = {} } -dofile(modpath .. "/engine.lua") +dofile(modpath .. "/api.lua") -minetest.register_entity("mcl_burning:fire", { - initial_properties = { - physical = false, - collisionbox = {0, 0, 0, 0, 0, 0}, - visual = "cube", - pointable = false, - glow = -1, - }, - - animation_frame = 0, - animation_timer = 0, - on_step = mcl_burning.fire_entity_step, -}) +local pairs = pairs +local get_connected_players = minetest.get_connected_players +local get_item_group = minetest.get_item_group minetest.register_globalstep(function(dtime) - for _, player in ipairs(minetest.get_connected_players()) do - mcl_burning.tick(player, dtime) + for _, player in pairs(get_connected_players()) do + local storage = mcl_burning.storage[player] + if not mcl_burning.tick(player, dtime, storage) and not mcl_burning.is_affected_by_rain(player) then + local nodes = mcl_burning.get_touching_nodes(player, {"group:puts_out_fire", "group:set_on_fire"}, storage) + local burn_time = 0 + + for _, pos in pairs(nodes) do + local node = minetest.get_node(pos) + if get_item_group(node.name, "puts_out_fire") > 0 then + burn_time = 0 + break + end + + local value = get_item_group(node.name, "set_on_fire") + if value > burn_time then + burn_time = value + end + end + + if burn_time > 0 then + mcl_burning.set_on_fire(player, burn_time) + end + end end end) @@ -31,6 +53,79 @@ minetest.register_on_respawnplayer(function(player) mcl_burning.extinguish(player) end) +minetest.register_on_joinplayer(function(player) + local storage = {} + local burn_data = player:get_meta():get_string("mcl_burning:data") + if burn_data ~= "" then + storage = minetest.deserialize(burn_data) or storage + end + mcl_burning.storage[player] = storage + if storage.burn_time and storage.burn_time > 0 then + mcl_burning.update_hud(player) + end +end) + +local function on_leaveplayer(player) + local storage = mcl_burning.storage[player] + if not storage then + -- For some unexplained reasons, mcl_burning.storage can be `nil` here. + -- Logging this exception to assist in finding the cause of this. + minetest.log("warning", "on_leaveplayer: missing mcl_burning.storage " + .. "for player " .. player:get_player_name()) + storage = {} + end + storage.fire_hud_id = nil + player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage)) + mcl_burning.storage[player] = nil +end + minetest.register_on_leaveplayer(function(player) - mcl_burning.set(player, "int", "hud_id") -end) \ No newline at end of file + on_leaveplayer(player) +end) + +minetest.register_on_shutdown(function() + for _,player in ipairs(minetest.get_connected_players()) do + on_leaveplayer(player) + end +end) + +local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 + +minetest.register_entity("mcl_burning:fire", { + initial_properties = { + physical = false, + collisionbox = {0, 0, 0, 0, 0, 0}, + visual = "upright_sprite", + textures = { + "mcl_burning_entity_flame_animated.png", + "mcl_burning_entity_flame_animated.png" + }, + spritediv = {x = 1, y = animation_frames}, + pointable = false, + glow = -1, + backface_culling = false, + }, + _mcl_animation_timer = 0, + on_activate = function(self) + self.object:set_sprite({x = 0, y = 0}, animation_frames, 1.0 / animation_frames) + end, + on_step = function(self, dtime) + local parent = self.object:get_attach() + if not parent then + self.object:remove() + return + end + local storage = mcl_burning.get_storage(parent) + if not storage or not storage.burn_time then + self.object:remove() + return + end + if parent:is_player() then + self._mcl_animation_timer = self._mcl_animation_timer + dtime + if self._mcl_animation_timer >= 0.1 then + self._mcl_animation_timer = 0 + mcl_burning.update_hud(parent) + end + end + end, +}) diff --git a/mods/ENTITIES/mcl_burning/mod.conf b/mods/ENTITIES/mcl_burning/mod.conf index c64959cbb..651698fc7 100644 --- a/mods/ENTITIES/mcl_burning/mod.conf +++ b/mods/ENTITIES/mcl_burning/mod.conf @@ -1,3 +1,4 @@ name = mcl_burning description = Burning Objects for MineClone2 author = Fleckenstein +depends = mcl_weather \ No newline at end of file diff --git a/mods/ENTITIES/mcl_dripping/README.md b/mods/ENTITIES/mcl_dripping/README.md new file mode 100644 index 000000000..d6ff75ff1 --- /dev/null +++ b/mods/ENTITIES/mcl_dripping/README.md @@ -0,0 +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, +}) +``` diff --git a/mods/ENTITIES/mcl_dripping/init.lua b/mods/ENTITIES/mcl_dripping/init.lua new file mode 100644 index 000000000..b5a5043b7 --- /dev/null +++ b/mods/ENTITIES/mcl_dripping/init.lua @@ -0,0 +1,101 @@ +-- Dripping Water Mod +-- by kddekadenz +-- License of code, textures & sounds: CC0 + +local math = math + +mcl_dripping = {} + + +---@param pos Vector +---@param liquid string +---@param sound SimpleSoundSpec +---@param interval integer +---@param texture string +local function make_drop(pos, liquid, sound, interval, texture) + local pt = { + velocity = vector.zero(), + collision_removal = false, + } + + local t = math.random() + math.random(1, interval) + + minetest.after(t, function() + local x, z = math.random(-45, 45) / 100, math.random(-45, 45) / 100 + + pt.pos = vector.offset(pos, x, -0.52, z) + pt.acceleration = vector.zero() + pt.collisiondetection = false + pt.expirationtime = t + + pt.texture = "[combine:2x2:" .. + -math.random(1, 16) .. "," .. -math.random(1, 16) .. "=" .. texture + + minetest.add_particle(pt) + + minetest.after(t, function() + pt.acceleration = vector.new(0, -5, 0) + pt.collisiondetection = true + pt.expirationtime = math.random() + math.random(1, interval / 2) + + minetest.add_particle(pt) + + minetest.sound_play(sound, { pos = pos, gain = 0.5, max_hear_distance = 8 }, + true) + end) + end) +end + +---@class mcl_dripping_drop_definition +---@field liquid string The group the liquid's nodes belong to +---@field texture string The texture used (particles will take a random 2x2 area of it) +---@field light integer Define particle glow, ranges from `0` to `minetest.LIGHT_MAX` +---@field nodes string[] The nodes (or node group) the particles will spawn under +---@field interval integer The interval for the ABM to run +---@field chance integer The chance of the ABM +---@field sound SimpleSoundSpec The sound that will be played then the particle detaches from the roof + +---@param def mcl_dripping_drop_definition +function mcl_dripping.register_drop(def) + minetest.register_abm({ + label = "Create drops", + nodenames = def.nodes, + neighbors = { "group:" .. def.liquid }, + interval = def.interval, + chance = def.chance, + action = function(pos) + local below = minetest.get_node(vector.offset(pos,0,-1,0)).name + if below ~= "air" then return end + local r = math.ceil(def.interval / 20) + local nn = minetest.find_nodes_in_area(vector.offset(pos, -r, 0, -r), vector.offset(pos, r, 0, r), def.nodes) + --start a bunch of particle cycles to be able to get away + --with longer abm cycles + table.shuffle(nn) + for i = 1, math.random(#nn) do + if minetest.get_item_group(minetest.get_node(vector.offset(nn[i], 0, 1, 0)).name, def.liquid) ~= 0 then + make_drop(nn[i], def.liquid, def.sound, def.interval, def.texture) + end + end + end, + }) +end + +mcl_dripping.register_drop({ + liquid = "water", + texture = "default_water_source_animated.png", + light = 1, + nodes = { "group:opaque", "group:leaves" }, + sound = "drippingwater_drip", + interval = 60.3, + chance = 10, +}) + +mcl_dripping.register_drop({ + liquid = "lava", + texture = "default_lava_source_animated.png", + light = math.max(7, minetest.registered_nodes["mcl_core:lava_source"].light_source - 3), + nodes = { "group:opaque" }, + sound = "drippingwater_lavadrip", + interval = 110.1, + chance = 10, +}) diff --git a/mods/ENTITIES/mcl_dripping/mod.conf b/mods/ENTITIES/mcl_dripping/mod.conf new file mode 100644 index 000000000..921d5e59f --- /dev/null +++ b/mods/ENTITIES/mcl_dripping/mod.conf @@ -0,0 +1,4 @@ +name = mcl_dripping +author = kddekadenz +description = Drops are generated rarely under solid nodes +depends = mcl_core diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.1.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.1.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.1.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.1.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.2.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.2.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.2.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.2.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_drip.3.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.3.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_drip.3.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_drip.3.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.1.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.1.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.1.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.1.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.2.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.2.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.2.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.2.ogg diff --git a/mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.3.ogg b/mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.3.ogg similarity index 100% rename from mods/ENTITIES/drippingwater/sounds/drippingwater_lavadrip.3.ogg rename to mods/ENTITIES/mcl_dripping/sounds/drippingwater_lavadrip.3.ogg diff --git a/mods/ENTITIES/mcl_entity_invs/api.txt b/mods/ENTITIES/mcl_entity_invs/api.txt new file mode 100644 index 000000000..98cee1a23 --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/api.txt @@ -0,0 +1,13 @@ +mcl_entity_invs +=============== + +Inventories for your entities. It's simple. Depend on mcl_entity_invs and register your entity like so: + +* mcl_entity_invs.register_inv("entity:name","Title shown in formspec",inventory_size,disable_on_righclick) + *If disable_on_righclick is true other mods can handle when to show the inventory themselves + * The inventory size can be set dynamically by initializing it with an explicit nil + +* mcl_entity_invs.show_inv_form(entity,clicker,[formspec text]) + * formspec_text is an additional text that is put after the title + +It works by setting up a detached inventory per entity which is accessed by an id/hash generated from the entities position at creation, the progressed gametime at creation and a random salt. diff --git a/mods/ENTITIES/mcl_entity_invs/init.lua b/mods/ENTITIES/mcl_entity_invs/init.lua new file mode 100644 index 000000000..35af491e1 --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/init.lua @@ -0,0 +1,210 @@ +mcl_entity_invs = {} + +local open_invs = {} + +local function mcl_log (message) + mcl_util.mcl_log (message, "[Entity Invs]") +end + +local function check_distance(inv,player,count) + for _,o in pairs(minetest.get_objects_inside_radius(player:get_pos(),5)) do + local l = o:get_luaentity() + if l and l._inv_id and inv:get_location().name == l._inv_id then return count end + end + return 0 +end + +local inv_callbacks = { + allow_take = function(inv, listname, index, stack, player) + return check_distance(inv,player,stack:get_count()) + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return check_distance(inv,player,count) + end, + allow_put = function(inv, listname, index, stack, player) + return check_distance(inv,player,stack:get_count()) + end, +} + +function mcl_entity_invs.load_inv(ent,size) + mcl_log("load_inv") + if not ent._inv_id then return end + mcl_log("load_inv 2") + local inv = minetest.get_inventory({type="detached", name=ent._inv_id}) + if not inv then + mcl_log("load_inv 3") + inv = minetest.create_detached_inventory(ent._inv_id, inv_callbacks) + inv:set_size("main", size) + if ent._items then + inv:set_list("main",ent._items) + end + else + mcl_log("load_inv 4") + end + return inv +end + +function mcl_entity_invs.save_inv(ent) + if ent._inv then + ent._items = {} + for i,it in ipairs(ent._inv:get_list("main")) do + ent._items[i] = it:to_string() + end + minetest.remove_detached_inventory(ent._inv_id) + ent._inv = nil + end +end + +local function load_default_formspec (ent, text) + text = text or "" + + local invent_size = ent._inv_size + local div_by_two = invent_size % 2 == 0 + local div_by_three = invent_size % 3 == 0 + + --mcl_log("Div by 3: ".. tostring(div_by_three)) + --mcl_log("Div by 2: ".. tostring(div_by_two)) + --mcl_log("invent_size: ".. tostring(invent_size)) + local rows = 3 + if invent_size > 18 or (div_by_three == true and invent_size > 8) then + --mcl_log("Div by 3") + rows = 3 + elseif (div_by_two == true and invent_size > 3) or invent_size > 9 then + --mcl_log("Div by 2") + rows = 2 + else + --mcl_log("Not div by 2 or 3") + rows = 1 + end + + --local rows = 3 + local cols = (math.ceil(ent._inv_size/rows)) + local spacing = (9 - cols) / 2 + + local formspec = "size[9,8.75]" + .. "label[0,0;" .. minetest.formspec_escape( + minetest.colorize("#313131", ent._inv_title .. " ".. text)) .. "]" + .. "list[detached:"..ent._inv_id..";main;"..spacing..",0.5;"..cols..","..rows..";]" + .. mcl_formspec.get_itemslot_bg(spacing,0.5,cols,rows) + .. "label[0,4.0;" .. minetest.formspec_escape( + minetest.colorize("#313131", "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[detached:"..ent._inv_id..";main]" + .. "listring[current_player;main]" + return formspec +end + + +function mcl_entity_invs.show_inv_form(ent,player,text) + if not ent._inv_id then return end + if not open_invs[ent] then + open_invs[ent] = 0 + end + ent._inv = mcl_entity_invs.load_inv(ent,ent._inv_size) + open_invs[ent] = open_invs[ent] + 1 + + local playername = player:get_player_name() + + minetest.show_formspec(playername, ent._inv_id, load_default_formspec (ent, text)) +end + +local function drop_inv(ent) + if not ent._items then return end + local pos = ent.object:get_pos() + for i,it in pairs(ent._items) do + local p = vector.add(pos,vector.new(math.random() - 0.5, math.random()-0.5, math.random()-0.5)) + minetest.add_item(p,it) + end + ent._items = nil +end + +local function on_remove(self,killer,oldf) + mcl_entity_invs.save_inv(self) + drop_inv(self) + if oldf then return oldf(self,killer) end +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + for k,v in pairs(open_invs) do + if formname == k._inv_id then + open_invs[k] = open_invs[k] - 1 + if open_invs[k] < 1 then + mcl_entity_invs.save_inv(k) + open_invs[k] = nil + end + end + end +end) + +function mcl_entity_invs.register_inv(entity_name,show_name,size,no_on_righclick,no_sneak) + assert(minetest.registered_entities[entity_name],"mcl_entity_invs.register_inv called with invalid entity: "..tostring(entity_name)) + minetest.registered_entities[entity_name]._inv_size = size + minetest.registered_entities[entity_name]._inv_title = show_name + + local old_oa = minetest.registered_entities[entity_name].on_activate + minetest.registered_entities[entity_name].on_activate = function(self,staticdata,dtime_s) + local r + if old_oa then r=old_oa(self,staticdata,dtime_s) end + local d = minetest.deserialize(staticdata) + if type(d) == "table" and d._inv_id then + self._inv_id = d._inv_id + self._items = d._items + self._inv_size = d._inv_size + else + self._inv_id="entity_inv_"..minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) + --gametime and position for collision safety and math.random salt to protect against position brute-force + end + return r + end + if not no_on_righclick then + local old_rc = minetest.registered_entities[entity_name].on_rightclick + minetest.registered_entities[entity_name].on_rightclick = function(self,clicker) + if no_sneak or clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker,"") + if not no_sneak then return end + end + if old_rc then return old_rc(self,clicker) end + end + end + + local old_gsd = minetest.registered_entities[entity_name].get_staticdata + minetest.registered_entities[entity_name].get_staticdata = function(self) + local old_sd = old_gsd(self) + local d = minetest.deserialize(old_sd) + assert(type(d) == "table","mcl_entity_invs currently only works with entities that return a (serialized) table in get_staticdata. "..tostring(self.name).." returned: "..tostring(old_sd)) + d._inv_id = self._inv_id + d._inv_size = self._inv_size + d._items = {} + if self._items then + for i,it in ipairs(self._items) do + d._items[i] = it + end + end + return minetest.serialize(d) + end + + local old_ode = minetest.registered_entities[entity_name].on_deactivate + minetest.registered_entities[entity_name].on_deactivate = function(self,removal) + mcl_entity_invs.save_inv(self) + if removal then + on_remove(self) + end + if old_ode then return old_ode(self,removal) end + end + + local old_od = minetest.registered_entities[entity_name].on_death + minetest.registered_entities[entity_name].on_death = function(self,killer) + if not self.is_mob then + on_remove(self,killer,old_od) + end + end + local old_odi = minetest.registered_entities[entity_name].on_die + minetest.registered_entities[entity_name].on_die = function(self,killer) + if self.is_mob then + on_remove(self,killer,old_od) + end + end +end diff --git a/mods/ENTITIES/mcl_entity_invs/mod.conf b/mods/ENTITIES/mcl_entity_invs/mod.conf new file mode 100644 index 000000000..8e94d6b1e --- /dev/null +++ b/mods/ENTITIES/mcl_entity_invs/mod.conf @@ -0,0 +1,3 @@ +name = mcl_entity_invs +author = cora +depends = mcl_formspec diff --git a/mods/ENTITIES/mcl_falling_nodes/description.txt b/mods/ENTITIES/mcl_falling_nodes/description.txt deleted file mode 100644 index 8b436bf28..000000000 --- a/mods/ENTITIES/mcl_falling_nodes/description.txt +++ /dev/null @@ -1 +0,0 @@ -Falling node entities, Minecraft-style diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 1ffc87b34..d527603de 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -1,7 +1,4 @@ -local S = minetest.get_translator("mcl_falling_nodes") -local dmes = minetest.get_modpath("mcl_death_messages") ~= nil - -local get_falling_depth = function(self) +local function get_falling_depth(self) if not self._startpos then -- Fallback self._startpos = self.object:get_pos() @@ -9,56 +6,45 @@ local get_falling_depth = function(self) return self._startpos.y - vector.round(self.object:get_pos()).y end -local deal_falling_damage = function(self, dtime) +local function deal_falling_damage(self, dtime) if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then return end - -- Cause damage to any player it hits. + -- Cause damage to any entity it hits. -- Algorithm based on MC anvils. - -- TODO: Support smashing other objects, too. local pos = self.object:get_pos() if not self._startpos then -- Fallback self._startpos = pos end - local objs = minetest.get_objects_inside_radius(pos, 1) - for _,v in ipairs(objs) do - local hp = v:get_hp() - if v:is_player() and hp ~= 0 then - if not self._hit_players then - self._hit_players = {} - end - local name = v:get_player_name() - local hit = false - for _,v in ipairs(self._hit_players) do - if name == v then - hit = true - end - end - if not hit then - table.insert(self._hit_players, name) - local way = self._startpos.y - pos.y - local damage = (way - 1) * 2 - damage = math.min(40, math.max(0, damage)) - if damage >= 1 then - hp = hp - damage - if hp < 0 then - hp = 0 + self._hit = self._hit or {} + for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + local entity = obj:get_luaentity() + if entity and entity.name == "__builtin:item" then + obj:remove() + elseif mcl_util.get_hp(obj) > 0 and not self._hit[obj] then + self._hit[obj] = true + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + -- Reduce damage if wearing a helmet + local inv = mcl_util.get_inventory(obj) + if inv then + local helmet = inv:get_stack("armor", 2) + if minetest.get_item_group(helmet:get_name(), "combat_armor") > 0 then + damage = damage / 4 * 3 + mcl_util.use_item_durability(helmet, 1) + inv:set_stack("armor", 2, helmet) end - if v:is_player() then - -- TODO: Reduce damage if wearing a helmet - local msg - if minetest.get_item_group(self.node.name, "anvil") ~= 0 then - msg = S("@1 was smashed by a falling anvil.", v:get_player_name()) - else - msg = S("@1 was smashed by a falling block.", v:get_player_name()) - end - if dmes then - mcl_death_messages.player_damage(v, msg) - end - end - v:set_hp(hp, { type = "punch", from = "mod" }) end + local dmg_type + if minetest.get_item_group(self.node.name, "anvil") ~= 0 then + dmg_type = "anvil" + else + dmg_type = "falling_node" + end + mcl_util.deal_damage(obj, damage, {type = dmg_type}) end end end @@ -74,10 +60,8 @@ minetest.register_entity(":__builtin:falling_node", { collide_with_objects = false, collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, }, - node = {}, meta = {}, - set_node = function(self, node, meta) local def = minetest.registered_nodes[node.name] -- Change falling node if definition tells us to @@ -104,7 +88,6 @@ minetest.register_entity(":__builtin:falling_node", { glow = glow, }) end, - get_staticdata = function(self) local meta = self.meta -- Workaround: Save inventory seperately from metadata. @@ -125,10 +108,9 @@ minetest.register_entity(":__builtin:falling_node", { } return minetest.serialize(ds) end, - on_activate = function(self, staticdata) self.object:set_armor_groups({immortal = 1}) - + local ds = minetest.deserialize(staticdata) if ds then self._startpos = ds._startpos @@ -148,7 +130,6 @@ minetest.register_entity(":__builtin:falling_node", { end self._startpos = vector.round(self._startpos) end, - on_step = function(self, dtime) -- Set gravity local acceleration = self.object:get_acceleration() @@ -162,7 +143,7 @@ minetest.register_entity(":__builtin:falling_node", { local np = {x = pos.x, y = pos.y + 0.3, z = pos.z} local n2 = minetest.get_node(np) if n2.name == "mcl_portals:portal_end" then - -- TODO: Teleport falling node. + -- TODO: Teleport falling node. self.object:remove() return end @@ -200,10 +181,9 @@ minetest.register_entity(":__builtin:falling_node", { return end local nd = minetest.registered_nodes[n2.name] - if n2.name == "mcl_portals:portal_end" then - -- TODO: Teleport falling node. - - elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then + --if n2.name == "mcl_portals:portal_end" then + -- TODO: Teleport falling node. + if (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then -- Replace destination node if it's buildable to minetest.remove_node(np) -- Run script hook @@ -270,7 +250,6 @@ minetest.register_entity(":__builtin:falling_node", { self.object:set_pos(npos) end end - deal_falling_damage(self, dtime) end }) diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.de.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.de.tr deleted file mode 100644 index 71dfa4be9..000000000 --- a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.de.tr +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_falling_nodes -@1 was smashed by a falling anvil.=@1 wurde von einem fallenden Amboss zerschmettert. -@1 was smashed by a falling block.=@1 wurde von einem fallenden Block zerschmettert. diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.dk.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.dk.tr new file mode 100644 index 000000000..31918cbe8 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.dk.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_falling_nodes +@1 was smashed by a falling anvil.=@1 blev smadret af en nedfaldende ambolt. +@1 was smashed by a falling block.=@1 blev smadret af en nedfaldende blok. diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.es.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.es.tr index 41cbf61b4..9bf17e1bb 100644 --- a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.es.tr +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.es.tr @@ -1,3 +1,3 @@ # textdomain: mcl_falling_nodes -@1 was smashed by a falling anvil.=@1 fue aplastado por la caída de un yunque. -@1 was smashed by a falling block.=@1 fue aplastado por la caída de un bloque. +@1 was smashed by a falling anvil.=@1 fue aplastado por un yunque. +@1 was smashed by a falling block.=@1 fue aplastado por un bloque. diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.fr.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.fr.tr index 781cd7048..5d311d3e2 100644 --- a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.fr.tr +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.fr.tr @@ -1,3 +1,3 @@ # textdomain: mcl_falling_nodes -@1 was smashed by a falling anvil.=@1 a été écrasé par une enclume qui tombait. -@1 was smashed by a falling block.=@1 a été écrasé par un bloc qui tombait. +@1 was smashed by a falling anvil.=@1 a été écrasé par une enclume +@1 was smashed by a falling block.=@1 a été écrasé par un bloc diff --git a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pl.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pl.tr new file mode 100644 index 000000000..9be9cf7c6 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.pl.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_falling_nodes +@1 was smashed by a falling anvil.=@1 została zmiażdżona przez spadające kowadło. +@1 was smashed by a falling block.=@1 została zmiażdżona przez spadający blok. 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 deleted file mode 100644 index 6c8b9375a..000000000 --- a/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.ru.tr +++ /dev/null @@ -1,3 +0,0 @@ -# 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_falling_nodes/locale/mcl_falling_nodes.zh_TW.tr b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.zh_TW.tr new file mode 100644 index 000000000..2772fb357 --- /dev/null +++ b/mods/ENTITIES/mcl_falling_nodes/locale/mcl_falling_nodes.zh_TW.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_falling_nodes/mod.conf b/mods/ENTITIES/mcl_falling_nodes/mod.conf index 032b75023..068987194 100644 --- a/mods/ENTITIES/mcl_falling_nodes/mod.conf +++ b/mods/ENTITIES/mcl_falling_nodes/mod.conf @@ -1 +1,3 @@ name = mcl_falling_nodes +author = Wuzzy +description = Falling node entities, Minecraft-style diff --git a/mods/ENTITIES/mcl_item_entity/README.txt b/mods/ENTITIES/mcl_item_entity/README.txt index 41e9e6e57..d39ec0ba9 100644 --- a/mods/ENTITIES/mcl_item_entity/README.txt +++ b/mods/ENTITIES/mcl_item_entity/README.txt @@ -25,4 +25,10 @@ http://minetest.net/ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. You just DO WHAT THE FUCK YOU WANT TO. + 0. You just DO WHAT THE FUCK YOU WANT TO. + +--------- + +Alterations and contributions are released under GNU GPLv3 after 11/11/2022 and for contributors: + +AncientMariner/ancientmarinerdev \ No newline at end of file diff --git a/mods/ENTITIES/mcl_item_entity/depends.txt b/mods/ENTITIES/mcl_item_entity/depends.txt deleted file mode 100644 index f80274858..000000000 --- a/mods/ENTITIES/mcl_item_entity/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -flowlib -mcl_enchanting diff --git a/mods/ENTITIES/mcl_item_entity/description.txt b/mods/ENTITIES/mcl_item_entity/description.txt deleted file mode 100644 index dba26fb6c..000000000 --- a/mods/ENTITIES/mcl_item_entity/description.txt +++ /dev/null @@ -1 +0,0 @@ -Dropped items will be attracted to the player like a magnet. diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index e5863abbc..149b5ed93 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -1,155 +1,183 @@ +--these are lua locals, used for higher performance +local minetest, math, vector, ipairs, pairs = minetest, math, vector, ipairs, pairs + +--this is used for the player pool in the sound buffer +local pool = {} + +local tick = false + + + + +minetest.register_on_joinplayer(function(player) + pool[player:get_player_name()] = 0 +end) + +minetest.register_on_leaveplayer(function(player) + pool[player:get_player_name()] = nil +end) + +local has_awards = minetest.get_modpath("awards") + +mcl_item_entity = {} + --basic settings local item_drop_settings = {} --settings table +item_drop_settings.dug_buffer = 0.65 -- the warm up period before a dug item can be collected item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting item_drop_settings.radius_magnet = 2.0 --radius of item magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.xp_radius_magnet = 7.25 --radius of xp magnet. MUST BE LARGER THAN radius_collect! item_drop_settings.radius_collect = 0.2 --radius of collection -item_drop_settings.player_collect_height = 1.0 --added to their pos y value +item_drop_settings.player_collect_height = 0.8 --added to their pos y value item_drop_settings.collection_safety = false --do this to prevent items from flying away on laggy servers item_drop_settings.random_item_velocity = true --this sets random item velocity if velocity is 0 item_drop_settings.drop_single_item = false --if true, the drop control drops 1 item instead of the entire stack, and sneak+drop drops the stack -- drop_single_item is disabled by default because it is annoying to throw away items from the intentory screen -item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up +item_drop_settings.magnet_time = 0.75 -- how many seconds an item follows the player before giving up -local get_gravity = function() +local function get_gravity() return tonumber(minetest.settings:get("movement_gravity")) or 9.81 end -local check_pickup_achievements = function(object, player) - local itemname = ItemStack(object:get_luaentity().itemstring):get_name() - if minetest.get_item_group(itemname, "tree") ~= 0 then - awards.unlock(player:get_player_name(), "mcl:mineWood") - elseif itemname == "mcl_mobitems:blaze_rod" then - awards.unlock(player:get_player_name(), "mcl:blazeRod") - elseif itemname == "mcl_mobitems:leather" then - awards.unlock(player:get_player_name(), "mcl:killCow") - elseif itemname == "mcl_core:diamond" then - awards.unlock(player:get_player_name(), "mcl:diamonds") +mcl_item_entity.registered_pickup_achievement = {} + +---Register an achievement that will be unlocked on pickup. +--- +---TODO: remove limitation of 1 award per itemname +---@param itemname string +---@param award string +function mcl_item_entity.register_pickup_achievement(itemname, award) + if not has_awards then + minetest.log("warning", + "[mcl_item_entity] Trying to register pickup achievement [" .. award .. "] for [" .. + itemname .. "] while awards missing") + elseif mcl_item_entity.registered_pickup_achievement[itemname] then + minetest.log("error", + "[mcl_item_entity] Trying to register already existing pickup achievement [" .. award .. "] for [" .. itemname .. "]") + else + mcl_item_entity.registered_pickup_achievement[itemname] = award end end -local enable_physics = function(object, luaentity, ignore_check) +mcl_item_entity.register_pickup_achievement("tree", "mcl:mineWood") +mcl_item_entity.register_pickup_achievement("mcl_mobitems:blaze_rod", "mcl:blazeRod") +mcl_item_entity.register_pickup_achievement("mcl_mobitems:leather", "mcl:killCow") +mcl_item_entity.register_pickup_achievement("mcl_core:diamond", "mcl:diamonds") +mcl_item_entity.register_pickup_achievement("mcl_core:crying_obsidian", "mcl:whosCuttingOnions") +mcl_item_entity.register_pickup_achievement("mcl_nether:ancient_debris", "mcl:hiddenInTheDepths") +mcl_item_entity.register_pickup_achievement("mcl_end:dragon_egg", "mcl:PickUpDragonEgg") +mcl_item_entity.register_pickup_achievement("mcl_armor:elytra", "mcl:skysTheLimit") + +---@param object ObjectRef +---@param player ObjectRef +local function check_pickup_achievements(object, player) + if has_awards then + local itemname = ItemStack(object:get_luaentity().itemstring):get_name() + local playername = player:get_player_name() + for name, award in pairs(mcl_item_entity.registered_pickup_achievement) do + if itemname == name or minetest.get_item_group(itemname, name) ~= 0 then + awards.unlock(playername, award) + end + end + end +end + +---@param object ObjectRef +---@param luaentity Luaentity +---@param ignore_check? boolean +local function enable_physics(object, luaentity, ignore_check) if luaentity.physical_state == false or ignore_check == true then luaentity.physical_state = true object:set_properties({ physical = true }) - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=-get_gravity(),z=0}) + object:set_acceleration(vector.new(0, -get_gravity(), 0)) end end -local disable_physics = function(object, luaentity, ignore_check, reset_movement) +---@param object ObjectRef +---@param luaentity Luaentity +---@param ignore_check? boolean +---@param reset_movement? boolean +local function disable_physics(object, luaentity, ignore_check, reset_movement) if luaentity.physical_state == true or ignore_check == true then luaentity.physical_state = false object:set_properties({ physical = false }) if reset_movement ~= false then - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=0,z=0}) + object:set_velocity(vector.zero()) + object:set_acceleration(vector.zero()) end end end -minetest.register_globalstep(function(dtime) - for _,player in ipairs(minetest.get_connected_players()) do +minetest.register_globalstep(function(_) + tick = not tick + + for _, player in pairs(minetest.get_connected_players()) do if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then + + local name = player:get_player_name() + local pos = player:get_pos() + + if tick == true and pool[name] > 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 + pool[name] = 6 + else + pool[name] = pool[name] - 1 + end + end + + local inv = player:get_inventory() - local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} + local checkpos = vector.offset(pos, 0, item_drop_settings.player_collect_height, 0) --magnet and collection - for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do - if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and 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 - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime - local collected = false - 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 + for _, object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do + if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and + 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 vector.distance(checkpos, object:get_pos()) <= item_drop_settings.radius_collect and not object:get_luaentity()._removed then + 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)) - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) - check_pickup_achievements(object, player) + 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:remove() - collected = 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 - - -- Magnet - else - - object:get_luaentity()._magnet_active = true - object:get_luaentity()._collector_timer = 0 - - -- Move object to player - disable_physics(object, object:get_luaentity()) - - local opos = object:get_pos() - local vec = vector.subtract(checkpos, opos) - vec = vector.add(opos, vector.divide(vec, 2)) - object:move_to(vec) - - - --fix eternally falling items - minetest.after(0, function(object) - local lua = object:get_luaentity() - if lua then - object:set_acceleration({x=0, y=0, z=0}) - end - end, object) - - - --this is a safety to prevent items flying away on laggy servers - if item_drop_settings.collection_safety == true then - if object:get_luaentity().init ~= true then - object:get_luaentity().init = true - minetest.after(1, function(args) - local playername = args[1] - local player = minetest.get_player_by_name(playername) - local object = args[2] - local lua = object:get_luaentity() - if player == nil or not player:is_player() or object == nil or lua == nil or lua.itemstring == nil then - return - end - if inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then - inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) - if not object:get_luaentity()._removed then - minetest.sound_play("item_drop_pickup", { - pos = pos, - max_hear_distance = 16, - gain = 1.0, - }, true) - end - check_pickup_achievements(object, player) - object:get_luaentity()._removed = true - object:remove() - else - enable_physics(object, object:get_luaentity()) - end - end, {player:get_player_name(), object}) - end - end - end - end - - if not collected then - if object:get_luaentity()._magnet_timer > 1 then - object:get_luaentity()._magnet_timer = -item_drop_settings.magnet_time - object:get_luaentity()._magnet_active = false - elseif object:get_luaentity()._magnet_timer < 0 then - object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime end end @@ -157,7 +185,6 @@ minetest.register_globalstep(function(dtime) local entity = object:get_luaentity() entity.collector = player:get_player_name() entity.collected = true - end end @@ -165,66 +192,6 @@ minetest.register_globalstep(function(dtime) end end) -local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" } -local basegroups = { "pickaxey", "axey", "shovely" } -local materials = { "wood", "gold", "stone", "iron", "diamond" } - --- Checks if the given node would drop its useful drop if dug by a tool --- with the given tool capabilities. Returns true if it will yield its useful --- drop, false otherwise. -local check_can_drop = function(node_name, tool_capabilities) - local handy = minetest.get_item_group(node_name, "handy") - local dig_immediate = minetest.get_item_group(node_name, "dig_immediate") - if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then - return true - else - local toolgroupcaps - if tool_capabilities then - toolgroupcaps = tool_capabilities.groupcaps - else - return false - end - - -- Compare node groups with tool capabilities - for m=1, #minigroups do - local minigroup = minigroups[m] - local g = minetest.get_item_group(node_name, minigroup) - if g ~= 0 then - local plus = minigroup .. "_dig" - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - for b=1, #basegroups do - local basegroup = basegroups[b] - local g = minetest.get_item_group(node_name, basegroup) - if g ~= 0 then - for m=g, #materials do - local plus = basegroup .. "_dig_"..materials[m] - if toolgroupcaps[plus] then - return true - end - for e=1,5 do - local effplus = plus .. "_efficiency_" .. e - if toolgroupcaps[effplus] then - return true - end - end - end - end - end - - return false - end -end - -- Stupid workaround to get drops from a drop table: -- Create a temporary table in minetest.registered_nodes that contains the proper drops, -- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition @@ -232,6 +199,11 @@ end local tmp_id = 0 +---@param drop string|drop_definition +---@param toolname string +---@param param2 integer +---@param paramtype2 paramtype2 +---@return string[] local function get_drops(drop, toolname, param2, paramtype2) tmp_id = tmp_id + 1 local tmp_node_name = "mcl_item_entity:" .. tmp_id @@ -240,7 +212,7 @@ local function get_drops(drop, toolname, param2, paramtype2) drop = drop, paramtype2 = paramtype2 } - local drops = minetest.get_node_drops({name = tmp_node_name, param2 = param2}, toolname) + local drops = minetest.get_node_drops({ name = tmp_node_name, param2 = param2 }, toolname) minetest.registered_nodes[tmp_node_name] = nil return drops end @@ -269,29 +241,40 @@ local function get_fortune_drops(fortune_drops, fortune_level) return drop or {} end +local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true) + function minetest.handle_node_drops(pos, drops, digger) -- NOTE: This function override allows digger to be nil. -- This means there is no digger. This is a special case which allows this function to be called -- by hand. Creative Mode is intentionally ignored in this case. - - local doTileDrops = minetest.settings:get_bool("mcl_doTileDrops", true) - if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then + if digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name()) then + 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 return - end + elseif not doTileDrops then return end -- Check if node will yield its useful drop by the digger's tool local dug_node = minetest.get_node(pos) - local toolcaps + local tooldef local tool - if digger ~= nil then + if digger then tool = digger:get_wielded_item() - toolcaps = tool:get_tool_capabilities() + tooldef = minetest.registered_items[tool:get_name()] - if not check_can_drop(dug_node.name, toolcaps) then + if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name(), digger) then return end end + local diggroups = tooldef and tooldef._mcl_diggroups + local shearsy_level = diggroups and diggroups.shearsy and diggroups.shearsy.level + --[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop from the node definition. Definition of _mcl_shears_drop / _mcl_silk_touch_drop: @@ -299,11 +282,13 @@ function minetest.handle_node_drops(pos, drops, digger) * table: Drop every itemstring in this table when dug by shears _mcl_silk_touch_drop ]] - local enchantments = tool and mcl_enchanting.get_enchantments(tool, "silk_touch") + local enchantments = tool and mcl_enchanting.get_enchantments(tool) local silk_touch_drop = false local nodedef = minetest.registered_nodes[dug_node.name] - if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then + if not nodedef then return end + + if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then if nodedef._mcl_shears_drop == true then drops = { dug_node.name } else @@ -326,7 +311,8 @@ function minetest.handle_node_drops(pos, drops, digger) local max_count = fortune_drop.max_count + fortune_level * (fortune_drop.factor or 1) local chance = fortune_drop.chance or fortune_drop.get_chance and fortune_drop.get_chance(fortune_level) if not chance or math.random() < chance then - drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, fortune_drop.cap) + drops = discrete_uniform_distribution(fortune_drop.multiply and drops or fortune_drop.items, min_count, max_count, + fortune_drop.cap) elseif fortune_drop.override then drops = {} end @@ -337,14 +323,14 @@ function minetest.handle_node_drops(pos, drops, digger) end end - if digger and mcl_experience.throw_experience and not silk_touch_drop then - local experience_amount = minetest.get_item_group(dug_node.name,"xp") + if digger and mcl_experience.throw_xp and not silk_touch_drop then + local experience_amount = minetest.get_item_group(dug_node.name, "xp") if experience_amount > 0 then - mcl_experience.throw_experience(pos, experience_amount) + mcl_experience.throw_xp(pos, experience_amount) end end - for _,item in ipairs(drops) do + for _, item in ipairs(drops) do local count if type(item) == "string" then count = ItemStack(item):get_count() @@ -353,7 +339,7 @@ function minetest.handle_node_drops(pos, drops, digger) end local drop_item = ItemStack(item) drop_item:set_count(1) - for i=1,count do + for i = 1, count do local dpos = table.copy(pos) -- Apply offset for plantlike_rooted nodes because of their special shape if nodedef and nodedef.drawtype == "plantlike_rooted" and nodedef.walkable then @@ -361,16 +347,16 @@ function minetest.handle_node_drops(pos, drops, digger) end -- Spawn item and apply random speed local obj = minetest.add_item(dpos, drop_item) - if obj ~= nil then - local x = math.random(1, 5) - if math.random(1,2) == 1 then - x = -x + if obj then + -- set the velocity multiplier to the stored amount or if the game dug this node, apply a bigger velocity + local v = 1 + if digger and digger:is_player() then + obj:get_luaentity().random_velocity = 1 + else + obj:get_luaentity().random_velocity = 1.6 end - local z = math.random(1, 5) - if math.random(1,2) == 1 then - z = -z - end - obj:set_velocity({x=1/x, y=obj:get_velocity().y, z=1/z}) + obj:get_luaentity().age = item_drop_settings.dug_buffer + obj:get_luaentity()._insta_collect = false end end end @@ -380,7 +366,7 @@ end function minetest.item_drop(itemstack, dropper, pos) if dropper and dropper:is_player() then local v = dropper:get_look_dir() - local p = {x=pos.x, y=pos.y+1.2, z=pos.z} + local p = vector.offset(pos, 0, 1.2, 0) local cs = itemstack:get_count() if dropper:get_player_control().sneak then cs = 1 @@ -388,9 +374,9 @@ function minetest.item_drop(itemstack, dropper, pos) local item = itemstack:take_item(cs) local obj = minetest.add_item(p, item) if obj then - v.x = v.x*4 - v.y = v.y*4 + 2 - v.z = v.z*4 + v.x = v.x * 4 + v.y = v.y * 4 + 2 + v.z = v.z * 4 obj:set_velocity(v) -- Force collection delay obj:get_luaentity()._insta_collect = false @@ -406,18 +392,201 @@ if not time_to_live then time_to_live = 300 end +local function cxcz(o, cw, one, zero) + if cw < 0 then + table.insert(o, { [one] = 1, y = 0, [zero] = 0 }) + table.insert(o, { [one] = -1, y = 0, [zero] = 0 }) + else + table.insert(o, { [one] = -1, y = 0, [zero] = 0 }) + table.insert(o, { [one] = 1, y = 0, [zero] = 0 }) + end + return o +end + +local function nodes_destroy_items (self, moveresult, def, nn) + local lg = minetest.get_item_group(nn, "lava") + local fg = minetest.get_item_group(nn, "fire") + local dg = minetest.get_item_group(nn, "destroys_items") + + if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then + local item_string = self.itemstring + local item_name = ItemStack(item_string):get_name() + + --Wait 2 seconds to allow mob drops to be cooked, & picked up instead of instantly destroyed. + if self.age > 2 and minetest.get_item_group(item_name, "fire_immune") == 0 then + if dg ~= 2 then + minetest.sound_play("builtin_item_lava", { pos = self.object:get_pos(), gain = 0.5 }) + end + self._removed = true + self.object:remove() + return true + end + end + + -- Destroy item when it collides with a cactus + if moveresult and moveresult.collides then + for _, collision in pairs(moveresult.collisions) do + local pos = collision.node_pos + if collision.type == "node" and minetest.get_node(pos).name == "mcl_core:cactus" then + -- TODO We need to play a sound when it gets destroyed + self._removed = true + self.object:remove() + return true + end + end + end +end + +local function push_out_item_stuck_in_solid(self, dtime, p, def, is_in_water) + if not is_in_water and def and def.walkable and def.groups and def.groups.opaque == 1 then + local shootdir + local cx = (p.x % 1) - 0.5 + local cz = (p.z % 1) - 0.5 + local order = {} + + -- First prepare the order in which the 4 sides are to be checked. + -- 1st: closest + -- 2nd: other direction + -- 3rd and 4th: other axis + if math.abs(cx) < math.abs(cz) then + order = cxcz(order, cx, "x", "z") + order = cxcz(order, cz, "z", "x") + else + order = cxcz(order, cz, "z", "x") + order = cxcz(order, cx, "x", "z") + end + + -- Check which one of the 4 sides is free + for o = 1, #order do + local nn = minetest.get_node(vector.add(p, order[o])).name + local def = minetest.registered_nodes[nn] + if def and def.walkable == false and nn ~= "ignore" then + shootdir = order[o] + break + end + end + -- If none of the 4 sides is free, shoot upwards + if shootdir == nil then + shootdir = vector.new(0, 1, 0) + local nn = minetest.get_node(vector.add(p, shootdir)).name + if nn == "ignore" then + -- Do not push into ignore + return true + end + end + + -- Set new item moving speed accordingly + local newv = vector.multiply(shootdir, 3) + self.object:set_acceleration(vector.zero()) + self.object:set_velocity(newv) + disable_physics(self.object, self, false, false) + + + if shootdir.y == 0 then + self._force = newv + p.x = math.floor(p.x) + p.y = math.floor(p.y) + p.z = math.floor(p.z) + self._forcestart = p + self._forcetimer = 1 + end + return true + end + + -- This code is run after the entity got a push from above “push away” code. + -- It is responsible for making sure the entity is entirely outside the solid node + -- (with its full collision box), not just its center. + if self._forcetimer > 0 then + local cbox = self.object:get_properties().collisionbox + local ok = false + if self._force.x > 0 and (p.x > (self._forcestart.x + 0.5 + (cbox[4] - cbox[1]) / 2)) then ok = true + elseif self._force.x < 0 and (p.x < (self._forcestart.x + 0.5 - (cbox[4] - cbox[1]) / 2)) then ok = true + elseif self._force.z > 0 and (p.z > (self._forcestart.z + 0.5 + (cbox[6] - cbox[3]) / 2)) then ok = true + elseif self._force.z < 0 and (p.z < (self._forcestart.z + 0.5 - (cbox[6] - cbox[3]) / 2)) then ok = true end + -- Item was successfully forced out. No more pushing + if ok then + self._forcetimer = -1 + self._force = nil + enable_physics(self.object, self) + else + self._forcetimer = self._forcetimer - dtime + end + return true + elseif self._force then + self._force = nil + enable_physics(self.object, self) + return true + end +end + +local function move_items_in_water (self, p, def, node, is_floating, is_in_water) + -- Move item around on flowing liquids; add 'source' check to allow items to continue flowing a bit in the source block of flowing water. + if def and not is_floating and (def.liquidtype == "flowing" or def.liquidtype == "source") then + self._flowing = true + + --[[ Get flowing direction (function call from flowlib), if there's a liquid. + NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. + Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] + local vec = flowlib.quick_flow(p, node) + -- Just to make sure we don't manipulate the speed for no reason + if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then + -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" + local f = 1.2 + -- Set new item moving speed into the direciton of the liquid + local newv = vector.multiply(vec, f) + -- Swap to acceleration instead of a static speed to better mimic MC mechanics. + self.object:set_acceleration(vector.new(newv.x, -0.22, newv.z)) + + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + return true + end + if is_in_water and def.liquidtype == "source" then + local cur_vec = self.object:get_velocity() + -- apply some acceleration in the opposite direction so it doesn't slide forever + local vec = { + x = 0 - cur_vec.x * 0.9, + y = 3 - cur_vec.y * 0.9, + z = 0 - cur_vec.z * 0.9 + } + self.object:set_acceleration(vec) + -- slow down the item in water + local vel = self.object:get_velocity() + if vel.y < 0 then + vel.y = vel.y * 0.9 + end + self.object:set_velocity(vel) + if self.physical_state ~= false or self._flowing ~= true then + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + end + end + elseif self._flowing == true and not is_in_water and not is_floating then + -- Disable flowing physics if not on/in flowing liquid + self._flowing = false + enable_physics(self.object, self, true) + return true + end +end + minetest.register_entity(":__builtin:item", { initial_properties = { hp_max = 1, physical = true, collide_with_objects = false, - collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3}, + collisionbox = { -0.3, -0.3, -0.3, 0.3, 0.3, 0.3 }, pointable = false, visual = "wielditem", - visual_size = {x = 0.4, y = 0.4}, - textures = {""}, - spritediv = {x = 1, y = 1}, - initial_sprite_basepos = {x = 0, y = 0}, + visual_size = { x = 0.4, y = 0.4 }, + textures = { "" }, + spritediv = { x = 1, y = 1 }, + initial_sprite_basepos = { x = 0, y = 0 }, is_visible = false, infotext = "", }, @@ -426,7 +595,7 @@ minetest.register_entity(":__builtin:item", { -- The itemstring MUST be set immediately to a non-empty string after creating the entity. -- The hand is NOT permitted as dropped item. ;-) -- Item entities will be deleted if they still have an empty itemstring on their first on_step tick. - itemstring = '', + itemstring = "", -- If true, item will fall physical_state = true, @@ -437,6 +606,37 @@ minetest.register_entity(":__builtin:item", { -- Number of seconds this item entity has existed so far age = 0, + -- Multiplier for initial random velocity when the item is spawned + random_velocity = 1, + + -- How old it has become in the collection animation + collection_age = 0, + + -- Function to apply a random velocity + apply_random_vel = function(self, speed) + if not self or not self.object or not self.object:get_luaentity() then + return + end + -- if you passed a value then use that for the velocity multiplier + if speed ~= nil then self.random_velocity = speed end + + local vel = self.object:get_velocity() + + -- There is perhaps a cleverer way of making this physical so it bounces off the wall like swords. + local max_vel = 6.5 -- Faster than this and it throws it into the wall / floor and turns black because of clipping. + + if vel and vel.x == 0 and vel.z == 0 and self.random_velocity > 0 then + local v = self.random_velocity + local x = math.random(5, max_vel) / 10 * v + if math.random(0, 10) < 5 then x = -x end + local z = math.random(5, max_vel) / 10 * v + if math.random(0, 10) < 5 then z = -z end + local y = math.random(1, 2) + self.object:set_velocity(vector.new(x, y, z)) + end + self.random_velocity = 0 + end, + set_item = function(self, itemstring) self.itemstring = itemstring if self.itemstring == "" then @@ -444,11 +644,23 @@ minetest.register_entity(":__builtin:item", { return end local stack = ItemStack(itemstring) + if minetest.get_item_group(stack:get_name(), "compass") > 0 then + if string.find(stack:get_name(), "_lodestone") then + stack:set_name("mcl_compass:18_lodestone") + else + stack:set_name("mcl_compass:18") + end + itemstring = stack:to_string() + self.itemstring = itemstring + end + if minetest.get_item_group(stack:get_name(), "clock") > 0 then + self.is_clock = true + end local count = stack:get_count() local max_count = stack:get_stack_max() if count > max_count then count = max_count - self.itemstring = stack:get_name().." "..max_count + self.itemstring = stack:get_name() .. " " .. max_count end local itemtable = stack:to_table() local itemname = nil @@ -456,13 +668,9 @@ minetest.register_entity(":__builtin:item", { if itemtable then itemname = stack:to_table().name end - local item_texture = nil - local item_type = "" local glow local def = minetest.registered_items[itemname] if def then - item_texture = def.inventory_image - item_type = def.type description = def.description glow = def.light_source end @@ -473,39 +681,21 @@ minetest.register_entity(":__builtin:item", { local prop = { is_visible = true, visual = "wielditem", - textures = {itemname}, - visual_size = {x = s, y = s}, - collisionbox = {-c, -c, -c, c, c, c}, + textures = { itemname }, + visual_size = { x = s, y = s }, + collisionbox = { -c, -c, -c, c, c, c }, automatic_rotate = math.pi * 0.5, infotext = description, glow = glow, } self.object:set_properties(prop) - if item_drop_settings.random_item_velocity == true then - minetest.after(0, function(self) - if not self or not self.object or not self.object:get_luaentity() then - return - end - local vel = self.object:get_velocity() - if vel and vel.x == 0 and vel.z == 0 then - local x = math.random(1, 5) - if math.random(1,2) == 1 then - x = -x - end - local z = math.random(1, 5) - if math.random(1,2) == 1 then - z = -z - end - local y = math.random(2,4) - self.object:set_velocity({x=1/x, y=y, z=1/z}) - end - end, self) + if item_drop_settings.random_item_velocity == true and self.age < 1 then + minetest.after(0, self.apply_random_vel, self) end - end, get_staticdata = function(self) - return minetest.serialize({ + local data = minetest.serialize({ itemstring = self.itemstring, always_collect = self.always_collect, age = self.age, @@ -513,6 +703,39 @@ minetest.register_entity(":__builtin:item", { _flowing = self._flowing, _removed = self._removed, }) + -- sfan5 guessed that the biggest serializable item + -- entity would have a size of 65530 bytes. This has + -- been experimentally verified to be still too large. + -- + -- anon5 has calculated that the biggest serializable + -- item entity has a size of exactly 65487 bytes: + -- + -- 1. serializeString16 can handle max. 65535 bytes. + -- 2. The following engine metadata is always saved: + -- • 1 byte (version) + -- • 2 byte (length prefix) + -- • 14 byte “__builtin:item” + -- • 4 byte (length prefix) + -- • 2 byte (health) + -- • 3 × 4 byte = 12 byte (position) + -- • 4 byte (yaw) + -- • 1 byte (version 2) + -- • 2 × 4 byte = 8 byte (pitch and roll) + -- 3. This leaves 65487 bytes for the serialization. + if #data > 65487 then -- would crash the engine + local stack = ItemStack(self.itemstring) + stack:get_meta():from_table(nil) + self.itemstring = stack:to_string() + minetest.log( + "warning", + "Overlong item entity metadata removed: “" .. + self.itemstring .. + "” had serialized length of " .. + #data + ) + return self:get_staticdata() + end + return data end, on_activate = function(self, staticdata, dtime_s) @@ -522,9 +745,9 @@ minetest.register_entity(":__builtin:item", { self.itemstring = data.itemstring self.always_collect = data.always_collect if data.age then - self.age = data.age + dtime_s + self.age = data.age else - self.age = dtime_s + self.age = self.age end --remember collection data -- If true, can collect item without delay @@ -556,9 +779,9 @@ minetest.register_entity(":__builtin:item", { self._forcestart = nil self._forcetimer = 0 - self.object:set_armor_groups({immortal = 1}) - self.object:set_velocity({x = 0, y = 2, z = 0}) - self.object:set_acceleration({x = 0, y = -get_gravity(), z = 0}) + self.object:set_armor_groups({ immortal = 1 }) + -- self.object:set_velocity(vector.new(0, 2, 0)) + self.object:set_acceleration(vector.new(0, -get_gravity(), 0)) self:set_item(self.itemstring) end, @@ -571,9 +794,9 @@ minetest.register_entity(":__builtin:item", { local stack = ItemStack(entity.itemstring) local name = stack:get_name() if own_stack:get_name() ~= name or - own_stack:get_meta() ~= stack:get_meta() or - own_stack:get_wear() ~= stack:get_wear() or - own_stack:get_free_space() == 0 then + own_stack:get_meta() ~= stack:get_meta() or + own_stack:get_wear() ~= stack:get_wear() or + own_stack:get_free_space() == 0 then -- Can not merge different or full stack return false end @@ -585,14 +808,23 @@ minetest.register_entity(":__builtin:item", { if total_count > max_count then return false end - -- Merge the remote stack into this one + -- Merge the remote stack into this one + local self_pos = self.object:get_pos() local pos = object:get_pos() - pos.y = pos.y + ((total_count - count) / max_count) * 0.15 - self.object:move_to(pos) + + --local y = pos.y + ((total_count - count) / max_count) * 0.15 + local x_diff = (self_pos.x - pos.x) / 2 + local z_diff = (self_pos.z - pos.z) / 2 + + local new_pos = vector.offset(pos, x_diff, 0, z_diff) + new_pos.y = math.max(self_pos.y, pos.y) + 0.1 + + self.object:move_to(new_pos) self.age = 0 -- Handle as new entity own_stack:set_count(total_count) + self.random_velocity = 0 self:set_item(own_stack:to_string()) entity._removed = true @@ -600,12 +832,18 @@ minetest.register_entity(":__builtin:item", { return true end, - on_step = function(self, dtime) + on_step = function(self, dtime, moveresult) if self._removed then + self.object:set_properties({ + physical = false + }) + self.object:set_velocity(vector.zero()) + self.object:set_acceleration(vector.zero()) return end + self.age = self.age + dtime - if self._collector_timer ~= nil then + if self._collector_timer then self._collector_timer = self._collector_timer + dtime end if time_to_live > 0 and self.age > time_to_live then @@ -616,191 +854,97 @@ minetest.register_entity(":__builtin:item", { -- Delete corrupted item entities. The itemstring MUST be non-empty on its first step, -- otherwise there might have some data corruption. if self.itemstring == "" then - minetest.log("warning", "Item entity with empty itemstring found at "..minetest.pos_to_string(self.object:get_pos()).. "! Deleting it now.") + minetest.log("warning", + "Item entity with empty itemstring found and being deleted at: " .. minetest.pos_to_string(self.object:get_pos())) self._removed = true self.object:remove() return end local p = self.object:get_pos() - local node = minetest.get_node_or_nil(p) - local in_unloaded = (node == nil) + local node = minetest.get_node(p) + local in_unloaded = node.name == "ignore" - -- If no collector was found for a long enough time, declare the magnet as disabled - if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then - self._magnet_active = false - enable_physics(self.object, self) - return - end if in_unloaded then -- Don't infinetly fall into unloaded map disable_physics(self.object, self) return end - -- Destroy item in lava, fire or special nodes + + + + if self.is_clock then + self.object:set_properties({ + textures = { "mcl_clock:clock_" .. (mcl_worlds.clock_works(p) and mcl_clock.old_time or mcl_clock.random_frame) } + }) + end + local nn = node.name - local def = minetest.registered_nodes[nn] - local lg = minetest.get_item_group(nn, "lava") - local fg = minetest.get_item_group(nn, "fire") - local dg = minetest.get_item_group(nn, "destroys_items") - if (def and (lg ~= 0 or fg ~= 0 or dg == 1)) then - --Wait 2 seconds to allow mob drops to be cooked, & picked up instead of instantly destroyed. - if self.age > 2 then - if dg ~= 2 then - minetest.sound_play("builtin_item_lava", {pos = self.object:get_pos(), gain = 0.5}) - end - self._removed = true - self.object:remove() - return - end + local is_in_water = (minetest.get_item_group(nn, "liquid") ~= 0) + local nn_above = minetest.get_node(vector.offset(p, 0, 0.1, 0)).name + -- make sure it's more or less stationary and is at water level + local sleep_threshold = 0.3 + local is_floating = false + local is_stationary = math.abs(self.object:get_velocity().x) < sleep_threshold + and math.abs(self.object:get_velocity().y) < sleep_threshold + and math.abs(self.object:get_velocity().z) < sleep_threshold + if is_in_water and is_stationary then + is_floating = (is_in_water + and (minetest.get_item_group(nn_above, "liquid") == 0)) end - -- Push item out when stuck inside solid opaque node - if def and def.walkable and def.groups and def.groups.opaque == 1 then - local shootdir - local cx = (p.x % 1) - 0.5 - local cz = (p.z % 1) - 0.5 - local order = {} - - -- First prepare the order in which the 4 sides are to be checked. - -- 1st: closest - -- 2nd: other direction - -- 3rd and 4th: other axis - local cxcz = function(o, cw, one, zero) - if cw < 0 then - table.insert(o, { [one]=1, y=0, [zero]=0 }) - table.insert(o, { [one]=-1, y=0, [zero]=0 }) - else - table.insert(o, { [one]=-1, y=0, [zero]=0 }) - table.insert(o, { [one]=1, y=0, [zero]=0 }) - end - return o - end - if math.abs(cx) < math.abs(cz) then - order = cxcz(order, cx, "x", "z") - order = cxcz(order, cz, "z", "x") - else - order = cxcz(order, cz, "z", "x") - order = cxcz(order, cx, "x", "z") - end - - -- Check which one of the 4 sides is free - for o=1, #order do - local nn = minetest.get_node(vector.add(p, order[o])).name - local def = minetest.registered_nodes[nn] - if def and def.walkable == false and nn ~= "ignore" then - shootdir = order[o] - break - end - end - -- If none of the 4 sides is free, shoot upwards - if shootdir == nil then - shootdir = { x=0, y=1, z=0 } - local nn = minetest.get_node(vector.add(p, shootdir)).name - if nn == "ignore" then - -- Do not push into ignore - return - end - end - - -- Set new item moving speed accordingly - local newv = vector.multiply(shootdir, 3) - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity(newv) - - disable_physics(self.object, self, false, false) - - if shootdir.y == 0 then - self._force = newv - p.x = math.floor(p.x) - p.y = math.floor(p.y) - p.z = math.floor(p.z) - self._forcestart = p - self._forcetimer = 1 - end - return + if is_floating and self.physical_state == true then + self.object:set_velocity(vector.zero()) + self.object:set_acceleration(vector.zero()) + disable_physics(self.object, self) end - - -- This code is run after the entity got a push from above “push away” code. - -- It is responsible for making sure the entity is entirely outside the solid node - -- (with its full collision box), not just its center. - if self._forcetimer > 0 then - local cbox = self.object:get_properties().collisionbox - local ok = false - if self._force.x > 0 and (p.x > (self._forcestart.x + 0.5 + (cbox[4] - cbox[1])/2)) then ok = true - elseif self._force.x < 0 and (p.x < (self._forcestart.x + 0.5 - (cbox[4] - cbox[1])/2)) then ok = true - elseif self._force.z > 0 and (p.z > (self._forcestart.z + 0.5 + (cbox[6] - cbox[3])/2)) then ok = true - elseif self._force.z < 0 and (p.z < (self._forcestart.z + 0.5 - (cbox[6] - cbox[3])/2)) then ok = true end - -- Item was successfully forced out. No more pushing - if ok then - self._forcetimer = -1 - self._force = nil - enable_physics(self.object, self) - else - self._forcetimer = self._forcetimer - dtime - end - return - elseif self._force then - self._force = nil + -- If no collector was found for a long enough time, declare the magnet as disabled + if self._magnet_active and (self._collector_timer == nil or (self._collector_timer > item_drop_settings.magnet_time)) then + self._magnet_active = false enable_physics(self.object, self) return end - -- Move item around on flowing liquids - if def and def.liquidtype == "flowing" then + -- Destroy item in lava, fire or special nodes - --[[ Get flowing direction (function call from flowlib), if there's a liquid. - NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. - Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] - local vec = flowlib.quick_flow(p, node) - -- Just to make sure we don't manipulate the speed for no reason - if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then - -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" - local f = 1.39 - -- Set new item moving speed into the direciton of the liquid - local newv = vector.multiply(vec, f) - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z}) + local def = minetest.registered_nodes[nn] - self.physical_state = true - self._flowing = true - self.object:set_properties({ - physical = true - }) - return - end - elseif self._flowing == true then - -- Disable flowing physics if not on/in flowing liquid - self._flowing = false - enable_physics(self.object, self, true) - return - end + if nodes_destroy_items(self, moveresult, def, nn) then return end + + if push_out_item_stuck_in_solid(self, dtime, p, def, is_in_water) then return end + + if move_items_in_water (self, p, def, node, is_floating, is_in_water) then return end -- If node is not registered or node is walkably solid and resting on nodebox - local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name + local nn = minetest.get_node(vector.offset(p, 0, -0.5, 0)).name + local def = minetest.registered_nodes[nn] local v = self.object:get_velocity() + local is_on_floor = def and (def.walkable + and not def.groups.slippery and v.y == 0) - if not minetest.registered_nodes[nn] or minetest.registered_nodes[nn].walkable and v.y == 0 then - if self.physical_state then - local own_stack = ItemStack(self.object:get_luaentity().itemstring) - -- Merge with close entities of the same item - for _, object in ipairs(minetest.get_objects_inside_radius(p, 0.8)) do - local obj = object:get_luaentity() - if obj and obj.name == "__builtin:item" - and obj.physical_state == false then - if self:try_merge_with(own_stack, object, obj) then - return - end + if not minetest.registered_nodes[nn] or is_floating or is_on_floor then + + local own_stack = ItemStack(self.object:get_luaentity().itemstring) + -- Merge with close entities of the same item + for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do + local obj = object:get_luaentity() + if obj and obj.name == "__builtin:item" and obj.physical_state == false then + if self:try_merge_with(own_stack, object, obj) then + return end end - disable_physics(self.object, self) + -- don't disable if underwater + if not is_in_water then + disable_physics(self.object, self) + end end else - if self._magnet_active == false then + if self._magnet_active == false and not is_floating then enable_physics(self.object, self) end end + end, -- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching diff --git a/mods/ENTITIES/mcl_item_entity/mod.conf b/mods/ENTITIES/mcl_item_entity/mod.conf index 9f35f5ed9..acd9f00f3 100644 --- a/mods/ENTITIES/mcl_item_entity/mod.conf +++ b/mods/ENTITIES/mcl_item_entity/mod.conf @@ -1 +1,4 @@ name = mcl_item_entity +author = PilzAdam +description = Dropped items will be attracted to the player like a magnet. +depends = flowlib, mcl_enchanting diff --git a/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt b/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt new file mode 100644 index 000000000..781759352 --- /dev/null +++ b/mods/ENTITIES/mcl_item_entity/sounds/Attributes.txt @@ -0,0 +1 @@ + Item_Drop_Pickup - https://freesound.org/people/benniknop/sounds/317848/ (License: CC0) diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg deleted file mode 100644 index 8010ff0a2..000000000 Binary files a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.1.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.2.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.2.ogg deleted file mode 100644 index a5087ab7d..000000000 Binary files a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.2.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg deleted file mode 100644 index f234a482c..000000000 Binary files a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.3.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.4.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.4.ogg deleted file mode 100644 index 6436f2678..000000000 Binary files a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.4.ogg and /dev/null differ diff --git a/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg new file mode 100644 index 000000000..e7f5df094 Binary files /dev/null and b/mods/ENTITIES/mcl_item_entity/sounds/item_drop_pickup.ogg differ diff --git a/mods/ENTITIES/mcl_minecarts/depends.txt b/mods/ENTITIES/mcl_minecarts/depends.txt deleted file mode 100644 index cdf7feb54..000000000 --- a/mods/ENTITIES/mcl_minecarts/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_explosions -mcl_core -mcl_sounds -mcl_player -mcl_achievements -mcl_chests -mcl_furnaces -mesecons_commandblock -mcl_hoppers -mcl_tnt -mesecons -doc_identifier? diff --git a/mods/ENTITIES/mcl_minecarts/description.txt b/mods/ENTITIES/mcl_minecarts/description.txt deleted file mode 100644 index 27f6c313d..000000000 --- a/mods/ENTITIES/mcl_minecarts/description.txt +++ /dev/null @@ -1 +0,0 @@ -Minecarts are vehicles to move players quickly on rails. diff --git a/mods/ENTITIES/mcl_minecarts/functions.lua b/mods/ENTITIES/mcl_minecarts/functions.lua index 42cdecd12..2f0dfe0ae 100644 --- a/mods/ENTITIES/mcl_minecarts/functions.lua +++ b/mods/ENTITIES/mcl_minecarts/functions.lua @@ -1,3 +1,5 @@ +local vector = vector + function mcl_minecarts:get_sign(z) if z == 0 then return 0 @@ -38,11 +40,9 @@ end function mcl_minecarts:check_front_up_down(pos, dir_, check_down, railtype) local dir = vector.new(dir_) - local cur = nil - -- Front dir.y = 0 - cur = vector.add(pos, dir) + local cur = vector.add(pos, dir) if mcl_minecarts:is_rail(cur, railtype) then return dir end @@ -65,9 +65,9 @@ end function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) local pos = vector.round(pos_) - local cur = nil + local cur local left_check, right_check = true, true - + -- Check left and right local left = {x=0, y=0, z=0} local right = {x=0, y=0, z=0} @@ -78,7 +78,7 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) left.z = dir.x right.z = -dir.x end - + if ctrl then if old_switch == 1 then left_check = false @@ -100,13 +100,13 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) right_check = true end end - + -- Normal cur = mcl_minecarts:check_front_up_down(pos, dir, true, railtype) if cur then return cur end - + -- Left, if not already checked if left_check then cur = mcl_minecarts:check_front_up_down(pos, left, false, railtype) @@ -114,7 +114,7 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) return cur end end - + -- Right, if not already checked if right_check then cur = mcl_minecarts:check_front_up_down(pos, right, false, railtype) @@ -122,7 +122,6 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) return cur end end - -- Backwards if not old_switch then cur = mcl_minecarts:check_front_up_down(pos, { @@ -134,7 +133,5 @@ function mcl_minecarts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype) return cur end end - return {x=0, y=0, z=0} -end - +end \ No newline at end of file diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 7bea3bd46..b87175494 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -1,13 +1,24 @@ -local S = minetest.get_translator("mcl_minecarts") +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +local has_mcl_wip = minetest.get_modpath("mcl_wip") mcl_minecarts = {} -mcl_minecarts.modpath = minetest.get_modpath("mcl_minecarts") +mcl_minecarts.modpath = minetest.get_modpath(modname) mcl_minecarts.speed_max = 10 mcl_minecarts.check_float_time = 15 dofile(mcl_minecarts.modpath.."/functions.lua") dofile(mcl_minecarts.modpath.."/rails.lua") +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_minecarts", false) +local function mcl_log(message) + if LOGGING_ON then + mcl_util.mcl_log(message, "[Minecarts]", true) + end +end + + local function detach_driver(self) if not self._driver then return @@ -48,6 +59,126 @@ end local activate_normal_minecart = detach_driver +local function hopper_take_item(self, dtime) + local pos = self.object:get_pos() + if not pos then return end + + if not self or self.name ~= "mcl_minecarts:hopper_minecart" then return end + + if mcl_util.check_dtime_timer(self, dtime, "hoppermc_take", 0.15) then + --minetest.log("The check timer was triggered: " .. dump(pos) .. ", name:" .. self.name) + else + --minetest.log("The check timer was not triggered") + return + end + + --mcl_log("self.itemstring: ".. self.itemstring) + + local above_pos = vector.offset(pos, 0, 0.9, 0) + --mcl_log("self.itemstring: ".. minetest.pos_to_string(above_pos)) + local objs = minetest.get_objects_inside_radius(above_pos, 1.25) + + if objs then + + mcl_log("there is an itemstring. Number of objs: ".. #objs) + + for k, v in pairs(objs) do + local ent = v:get_luaentity() + + if ent and not ent._removed and ent.itemstring and ent.itemstring ~= "" then + local taken_items = false + + mcl_log("ent.name: " .. tostring(ent.name)) + mcl_log("ent pos: " .. tostring(ent.object:get_pos())) + + local inv = mcl_entity_invs.load_inv(self, 5) + if not inv then return false end + + local current_itemstack = ItemStack(ent.itemstring) + + mcl_log("inv. size: " .. self._inv_size) + if inv:room_for_item("main", current_itemstack) then + mcl_log("Room") + inv:add_item("main", current_itemstack) + ent.object:get_luaentity().itemstring = "" + ent.object:remove() + taken_items = true + else + mcl_log("no Room") + end + + if not taken_items then + local items_remaining = current_itemstack:get_count() + + -- This will take part of a floating item stack if no slot can hold the full amount + for i = 1, self._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Items remaining: " .. items_remaining) + mcl_log("Name: " .. tostring(stack:get_name())) + + if current_itemstack:get_name() == stack:get_name() then + mcl_log("We have a match. Name: " .. tostring(stack:get_name())) + + local room_for = stack:get_stack_max() - stack:get_count() + mcl_log("Room for: " .. tostring(room_for)) + + if room_for == 0 then + -- Do nothing + mcl_log("No room") + elseif room_for < items_remaining then + mcl_log("We have more items remaining than space") + + items_remaining = items_remaining - room_for + stack:set_count(stack:get_stack_max()) + inv:set_stack("main", i, stack) + taken_items = true + else + local new_stack_size = stack:get_count() + items_remaining + stack:set_count(new_stack_size) + mcl_log("We have more than enough space. Now holds: " .. new_stack_size) + + inv:set_stack("main", i, stack) + items_remaining = 0 + + ent.object:get_luaentity().itemstring = "" + ent.object:remove() + + taken_items = true + break + end + + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + --mcl_log("Is it empty: " .. stack:to_string()) + end + + if i == self._inv_size and taken_items then + mcl_log("We are on last item and still have items left. Set final stack size: " .. items_remaining) + current_itemstack:set_count(items_remaining) + --mcl_log("Itemstack2: " .. current_itemstack:to_string()) + ent.itemstring = current_itemstack:to_string() + end + end + end + + --Add in, and delete + if taken_items then + mcl_log("Saving") + mcl_entity_invs.save_inv(ent) + return taken_items + else + mcl_log("No need to save") + end + + end + end + end + + return false +end + -- Table for item-to-entity mapping. Keys: itemstring, Values: Corresponding entity ID local entity_mapping = {} @@ -63,6 +194,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o on_rightclick = on_rightclick, _driver = nil, -- player who sits in and controls the minecart (only for minecart!) + _passenger = nil, -- for mobs _punched = false, -- used to re-send _velocity and position _velocity = {x=0, y=0, z=0}, -- only used on punch _start_pos = nil, -- Used to calculate distance for “On A Rail” achievement @@ -83,6 +215,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o local data = minetest.deserialize(staticdata) if type(data) == "table" then self._railtype = data._railtype + self._passenger = data._passenger end self.object:set_armor_groups({immortal=1}) @@ -174,7 +307,24 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o cart.on_activate_by_rail = on_activate_by_rail + local passenger_attach_position = vector.new(0, -1.75, 0) + function cart:on_step(dtime) + hopper_take_item(self, dtime) + + local ctrl, player = nil, nil + if self._driver then + player = minetest.get_player_by_name(self._driver) + if player then + ctrl = player:get_player_control() + -- player detach + if ctrl.sneak then + detach_driver(self) + return + end + end + end + local vel = self.object:get_velocity() local update = {} if self._last_float_check == nil then @@ -182,26 +332,58 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o else self._last_float_check = self._last_float_check + dtime end - local pos, rou_pos, node + + local pos, rou_pos, node = self.object:get_pos() + local r = 0.6 + for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do + if minetest.get_node(vector.offset(pos, node_pos[1], 0, node_pos[2])).name == "mcl_core:cactus" then + detach_driver(self) + for d = 1, #drop do + minetest.add_item(pos, drop[d]) + end + self.object:remove() + return + end + end + + -- Grab mob + if math.random(1,20) > 15 and not self._passenger then + if self.name == "mcl_minecarts:minecart" then + local mobsnear = minetest.get_objects_inside_radius(self.object:get_pos(), 1.3) + for n=1, #mobsnear do + local mob = mobsnear[n] + if mob then + local entity = mob:get_luaentity() + if entity and entity.is_mob then + self._passenger = entity + mob:set_attach(self.object, "", passenger_attach_position, vector.zero()) + break + end + end + end + end + elseif self._passenger then + local passenger_pos = self._passenger.object:get_pos() + if not passenger_pos then + self._passenger = nil + end + end + -- Drop minecart if it isn't on a rail anymore if self._last_float_check >= mcl_minecarts.check_float_time then pos = self.object:get_pos() rou_pos = vector.round(pos) node = minetest.get_node(rou_pos) local g = minetest.get_item_group(node.name, "connect_to_raillike") - if g ~= self._railtype and self._railtype ~= nil then - local player + if g ~= self._railtype and self._railtype then -- Detach driver - if self._driver then + if player then if self._old_pos then self.object:set_pos(self._old_pos) end mcl_player.player_attached[self._driver] = nil - player = minetest.get_player_by_name(self._driver) - if player then - player:set_detach() - player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) - end + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) end -- Explode if already ignited @@ -211,19 +393,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o return end - -- Drop items and remove cart entity - local pname = "" - if player then - pname = player:get_player_name() - end - if not minetest.is_creative_enabled(pname) then - for d=1, #drop do - minetest.add_item(self.object:get_pos(), drop[d]) - end - end - - self.object:remove() - return + -- Do not drop minecart. It goes off the rails too frequently, and anyone using them for farms won't + -- notice and lose their iron and not bother. Not cool until fixed. end self._last_float_check = 0 end @@ -337,14 +508,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end end - local ctrl, player = nil, nil - if self._driver then - player = minetest.get_player_by_name(self._driver) - if player then - ctrl = player:get_player_control() - end - end - -- Stop cart if velocity vector flips if self._old_vel and self._old_vel.y == 0 and (self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then @@ -415,7 +578,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o -- Slow down or speed up local acc = dir.y * -1.8 local friction = 0.4 - local speed_mod = minetest.registered_nodes[minetest.get_node(pos).name]._rail_acceleration + local ndef = minetest.registered_nodes[minetest.get_node(pos).name] + local speed_mod = ndef and ndef._rail_acceleration acc = acc - friction @@ -483,7 +647,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o if update.pos then self.object:set_pos(pos) end - update = nil end function cart:get_staticdata() @@ -494,7 +657,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end -- Place a minecart at pointed_thing -mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer) +function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer) if not pointed_thing.type == "node" then return end @@ -521,7 +684,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer) local cart = minetest.add_entity(railpos, entity_id) local railtype = minetest.get_item_group(node.name, "connect_to_raillike") local le = cart:get_luaentity() - if le ~= nil then + 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) @@ -538,7 +701,7 @@ mcl_minecarts.place_minecart = function(itemstack, pointed_thing, placer) end -local register_craftitem = function(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) +local function register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) entity_mapping[itemstring] = entity_id local groups = { minecart = 1, transport = 1 } @@ -604,7 +767,7 @@ Register a minecart local function register_minecart(itemstring, entity_id, description, tt_help, longdesc, usagehelp, mesh, textures, icon, drop, on_rightclick, on_activate_by_rail, creative) register_entity(entity_id, mesh, textures, drop, on_rightclick, on_activate_by_rail) register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) - if minetest.get_modpath("doc_identifier") ~= nil then + if minetest.get_modpath("doc_identifier") then doc.sub.identifier.register_object(entity_id, "craftitems", itemstring) end end @@ -643,6 +806,7 @@ register_minecart( if player then mcl_player.player_set_animation(player, "sit" , 30) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) + mcl_title.set(clicker, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60}) end end, name) end @@ -659,7 +823,8 @@ register_minecart( { "mcl_chests_normal.png", "mcl_minecarts_minecart.png" }, "mcl_minecarts_minecart_chest.png", {"mcl_minecarts:minecart", "mcl_chests:chest"}, - nil, nil, false) + nil, nil, true) +mcl_entity_invs.register_inv("mcl_minecarts:chest_minecart","Minecart",27,false,true) -- Minecart with Furnace register_minecart( @@ -712,7 +877,7 @@ register_minecart( "mcl_minecarts_minecart.png", }}) end - end, nil, false + end, nil, true ) -- Minecart with Command Block @@ -751,8 +916,9 @@ register_minecart( }, "mcl_minecarts_minecart_hopper.png", {"mcl_minecarts:minecart", "mcl_hoppers:hopper"}, - nil, nil, false + nil, nil, true ) +mcl_entity_invs.register_inv("mcl_minecarts:hopper_minecart", "Hopper Minecart", 5, false, true) -- Minecart with TNT register_minecart( @@ -812,9 +978,6 @@ minetest.register_craft({ }, }) --- TODO: Re-enable crafting of special minecarts when they have been implemented -if false then - minetest.register_craft({ output = "mcl_minecarts:furnace_minecart", recipe = { @@ -831,6 +994,7 @@ minetest.register_craft({ }, }) + minetest.register_craft({ output = "mcl_minecarts:chest_minecart", recipe = { @@ -839,4 +1003,9 @@ minetest.register_craft({ }, }) + +if has_mcl_wip then + mcl_wip.register_wip_item("mcl_minecarts:chest_minecart") + mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart") + mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart") end diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.de.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.de.tr index 4d9b6c2ff..1d270ee6c 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.de.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.de.tr @@ -33,3 +33,4 @@ Activates minecarts when powered=Aktiviert Loren, wenn bestromt Emits redstone power when a minecart is detected=Gibt ein Redstonesignal aus, wenn eine Lore erfasst wird Vehicle for fast travel on rails=Fahrzeug zum schnellen Transport auf Schienen Can be ignited by tools or powered activator rail=Kann mit Werkzeugen oder bestromten Aktivierungsschienen angezündet werden +Sneak to dismount=Zum Aussteigen schleichen diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.dk.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.dk.tr new file mode 100644 index 000000000..f946b83e4 --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.dk.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_minecarts +Minecart=Minevogn +Minecarts can be used for a quick transportion on rails.=Minevogne kan bruges til hurtig transport på spor. +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.=Minevogne kan kun køre på spor, og følger dem altid. Ved et T-kryds uden en vej ligeud drejer de altid til venstre. Farten påvirkes af sportypen. +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Du kan placere minevogne på spor. Højre-klik for at stige ombord. +To obtain the minecart, punch it while holding down the sneak key.=For at at få minevognen i din oppakning. +A minecart with TNT is an explosive vehicle that travels on rail.=En minevogn med TNT as et eksplosivt fartøj som kører på spor. +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.=Placér den på spor. Slå den for at flytte den. TNTet bliver antændt med flint og stål eller når minevognen er på et aktiveringsspor. +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=For at få minevognen med TNT i din oppakning skal du slå den mens du holder snigeknappen nede. Du kan ikke gøre dette hvis TNTen er antændt. +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=En minevogn med ovn er et fartøj som kører på spor. Den kan køre af sig selv med brændstof. +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.=Placér den på spor. Hvis du putter kul i den vil ovnen brænde i lang tid, og minevognen vil køre af sig selv. Slå den for at sætte den i bevægelse. +To obtain the minecart and furnace, punch them while holding down the sneak key.=For at få minevognen med ovn i din oppakning skal du slå den mens du holder snigeknappen nede. +Minecart with Chest=Minevogn med kiste +Minecart with Furnace=Minevogn med ovn +Minecart with Command Block=Minevogn med kommandoblok +Minecart with Hopper=Minevogn med tragt +Minecart with TNT=Minevogn med 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.=Placér dem på jorden for at bygge din jerbane. Sporene kobler sig automatisk sammen med hinanden og laver sving, T-kryds, kryds og skråninger efter behov. +Rail=Spor +Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Spor kan bruges til at bygge jernbaner til minevogne. Normale spor sænker minevognene en smule på grund af friktionsmodstand. +Powered Rail=Strømspor +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Spor kan bruges til at bygge jernbaner til minevogne. Strømspor kan accelerere eller bremse minevogne. +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Uden redstonekraft vil sporet bremse minevognen. For at accelerere minevognen skal den bruge redstoneskraft. +Activator Rail=Aktiveringsspor +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Spor kan bruges til at bygge jernbaner til minevogne. Aktiveringsspor bruges til at aktivere specielle minevogne. +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=For at få dette spor til at aktiere minevogne skal du give det redstonekraft og sende en minevogn over dette sporstykke. +Detector Rail=Detektorspor +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.=Spor kan bruges til at bygge jernbaner til minevogne. Et detektorspor kan opdage en minevogn som kører over det og give kraft til redstonemekanismer. +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=For at opdage en minevogn og give redstonekraft skal den forbindes til redstonestøv eller redstonemekanismer og send en hvilkensomhelst minevogn hen over sporet. +Track for minecarts=Spor til minevogne. +Speed up when powered, slow down when not powered=Accelerérer når der er strøm, sænk hastigheden når der ikke er strøm. +Activates minecarts when powered=Aktieverer minevogne når der er strøm. +Emits redstone power when a minecart is detected=Udsender redstonekraft når en minevogn bliver opdaget. +Vehicle for fast travel on rails=Fartøj til hurtig kørsel på spor. +Can be ignited by tools or powered activator rail=Kan antændes med værktøj eller et aktivatorspor med strøm. +Sneak to dismount=Snig for at stige af. diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr index 39cdfd013..2b9833a78 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.fr.tr @@ -10,15 +10,15 @@ To obtain the minecart and TNT, punch them while holding down the sneak key. You A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Une wagonnet avec un four est un véhicule qui se déplace sur rails. Il peut se propulser avec du 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.=Placez-le sur des rails. Si vous lui donnez du charbon, le four commencera à brûler pendant longtemps et le wagonnet pourra se déplacer. Frappez-le pour le faire bouger. To obtain the minecart and furnace, punch them while holding down the sneak key.=Pour obtenir le wagonnet et le four, frappez-les tout en maintenant la touche furtive enfoncée. -Minecart with Chest=Wagonnet avec Coffre -Minecart with Furnace=Wagonnet avec Four -Minecart with Command Block=Wagonnet avec Bloc de Commande -Minecart with Hopper=Wagonnet avec Entonoir +Minecart with Chest=Wagonnet avec coffre +Minecart with Furnace=Wagonnet avec four +Minecart with Command Block=Wagonnet avec bloc de commande +Minecart with Hopper=Wagonnet avec entonnoir Minecart with TNT=Wagonnet avec 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.=Placez-les sur le sol pour construire votre chemin de fer, les rails se connecteront automatiquement les uns aux autres et se transformeront en courbes, en jonctions en T, en traversées et en pentes au besoin. Rail=Rail Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Les rails peuvent être utilisés pour construire des voies de transport pour les wagonnets. Les rails ralentissent légèrement les wagonnets en raison de la friction. -Powered Rail=Rail allimenté +Powered Rail=Rail alimenté Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Les rails peuvent être utilisés pour construire des voies de transport pour les wagonnets. Les rails motorisés sont capables d'accélérer et de freiner les wagonnets. Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Sans énergie de redstone, le rail freinera les wagonnets. Pour que ce rail accélère les minecarts, alimentez-le avec une source d'énergie redstone. Activator Rail=Rail d'activation @@ -33,3 +33,4 @@ Activates minecarts when powered=Active les wagonnets lorsqu'il est alimenté Emits redstone power when a minecart is detected=Émet de l'énergie redstone lorsqu'un wagonnet est détecté Vehicle for fast travel on rails=Véhicule pour voyager rapidement sur rails Can be ignited by tools or powered activator rail=Peut être allumé par des outils ou un rail d'activation motorisé +Sneak to dismount=Se baisser pour descendre \ No newline at end of file diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr new file mode 100644 index 000000000..30af73c48 --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ja.tr @@ -0,0 +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.=TNT付きトロッコは、レール上を行きかう爆薬車両です。 +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.=レール上に配置。パンチで移動。TNTが着火するのは、火打石と打金を使った時か、稼動中のアクティベーターレール上にトロッコが乗った時です。 +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=トロッコとTNTを入手するには、スニークキーを押しながらパンチしてください。TNTに火が着いていた場合は、無理です。 +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=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.=地面に置いて線路を作ると、レール同士が自動的につながり、必要に応じてカーブや丁字路、踏切、坂道などに変化します。 +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.=トロッコを検知してレッドストーン動力を供給するには、レッドストーン導線またはレッドストーン機構に接続し、任意のトロッコをレール上に送り込みます。 +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=道具や稼動中のアクティベーターレールにより着火が可能 +Sneak to dismount=スニークで降りる diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pl.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pl.tr new file mode 100644 index 000000000..b36ec5eb1 --- /dev/null +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.pl.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_minecarts +Minecart=Wagonik +Minecarts can be used for a quick transportion on rails.=Wagoniki mogą być użyte do szybkiego transportu po torach. +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.=Wagoniki mogą jeździć tylko po torach i zawsze podążają za wytyczoną ścieżką. W przypadku skrzyżowań typu T, gdzie nie ma prostej ścieżki, skręcają w lew. Ich szybkość zależy od typu torów. +You can place the minecart on rails. Right-click it to enter it. Punch it to get it moving.=Możesz postawić wagonik na torach. Kliknij prawym przyciskiem myszy aby do niego wejść. Uderz go by zaczął się poruszać. +To obtain the minecart, punch it while holding down the sneak key.=Aby odzyskać wagonik uderz go podczas skradania. +A minecart with TNT is an explosive vehicle that travels on rail.=Wagonik z TNT jest wybuchowym pojazdem podróżującym po torach. +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.=Postaw go na torach. Uderz by zaczął się poruszać. TNT zapala się krzesiwem lub gdy wagonik jest na zasilonych torach aktywacyjnych. +To obtain the minecart and TNT, punch them while holding down the sneak key. You can't do this if the TNT was ignited.=Aby odzyskać wagonik z TNT uderz go podczas skradania. Nie możesz tego zrobić gdy TNT jest zapalone. +A minecart with furnace is a vehicle that travels on rails. It can propel itself with fuel.=Wagonik z piecem jest pojazdem podróżującym na torach. Napędza on samego siebie za pomocą paliwa. +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.=Postaw go na torach. Jeśli dasz mu nieco węgla piec zacznie palić przez długi czas, a wagonik będzie się sam poruszał. Uderz go by zaczął się poruszać. +To obtain the minecart and furnace, punch them while holding down the sneak key.=Aby odzyskać wagonik z piecem uderz go podczas skradania. +Minecart with Chest=Wagonik ze skrzynią +Minecart with Furnace=Wagonik z piecem +Minecart with Command Block=Wagonik z blokiem poleceń +Minecart with Hopper=Wagonik z lejem +Minecart with TNT=Wagonik z 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.=Postaw je na ziemi by zbudować ścieżkę z torów. Tory automatycznie połączą się ze sobą i zamienią się w zakręty, skrzyżowania typu T, skrzyżowania i równie w zależności od potrzeb. +Rail=Tor +Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zwyczajne tory nieco spowalniają wagoniki ze względu na tarcie. +Powered Rail=Zasilane tory +Rails can be used to build transport tracks for minecarts. Powered rails are able to accelerate and brake minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Zasilane tory mogą przyspieszać lub spowalniać wagoniki. +Without redstone power, the rail will brake minecarts. To make this rail accelerate minecarts, power it with redstone power.=Bez zasilania czerwienitem tory będą spowalniać wagoniki. Aby sprawić by je przyspieszały zasil je czerwienitem. +Activator Rail=Tory aktywacyjne +Rails can be used to build transport tracks for minecarts. Activator rails are used to activate special minecarts.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory aktywacyjne są wykorzystywane do aktywacji specjalnych wagoników. +To make this rail activate minecarts, power it with redstone power and send a minecart over this piece of rail.=Aby ten tor aktywował wagonik, zasil go czerwienitem i spraw by wagonik po nim przejechał. +Detector Rail=Tory z czujnikiem +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.=Tory mogą być wykorzystane do zbudowania torów dla wagoników. Tory z czujnikiem są w stanie wykryć kiedy wagonik po nich przejeżdża i wysłać sygnał do czerwienitowych mechanizmów. +To detect a minecart and provide redstone power, connect it to redstone trails or redstone mechanisms and send any minecart over the rail.=Aby wykryć wagonik i dostarczyć zasilanie czerwienitem podłącz go czerwienitem to mechanizmu i spraw by wagonik po nim przejechał. +Track for minecarts=Tor dla wagoników +Speed up when powered, slow down when not powered=Przyspiesza gdy zasilane, spowalnia gdy nie +Activates minecarts when powered=Aktywuje wagoniki gdy zasilane +Emits redstone power when a minecart is detected=Emituje zasilanie czerwienitem gdy wagonik jest wykryty +Vehicle for fast travel on rails=Pojazd do szybkiej podróży na torach +Can be ignited by tools or powered activator rail=Może być zapalony przez narzędzia, lub zasilane tor aktywacyjne +Sneak to dismount=Zacznij się skradać by zejść diff --git a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr index e8f914128..6189bac84 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr +++ b/mods/ENTITIES/mcl_minecarts/locale/mcl_minecarts.ru.tr @@ -33,3 +33,4 @@ 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/locale/template.txt b/mods/ENTITIES/mcl_minecarts/locale/template.txt index 254189542..dff98587c 100644 --- a/mods/ENTITIES/mcl_minecarts/locale/template.txt +++ b/mods/ENTITIES/mcl_minecarts/locale/template.txt @@ -33,3 +33,4 @@ 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/mod.conf b/mods/ENTITIES/mcl_minecarts/mod.conf index 5661f8b9c..b810c2b6a 100644 --- a/mods/ENTITIES/mcl_minecarts/mod.conf +++ b/mods/ENTITIES/mcl_minecarts/mod.conf @@ -1 +1,5 @@ name = mcl_minecarts +author = Krock +description = Minecarts are vehicles to move players quickly on rails. +depends = mcl_title, mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_entity_invs +optional_depends = doc_identifier, mcl_wip diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index 4c26aea8c..9c9050341 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -1,8 +1,8 @@ -local S = minetest.get_translator("mcl_minecarts") +local S = minetest.get_translator(minetest.get_current_modname()) -- Template rail function -local register_rail = function(itemstring, tiles, def_extras, creative) - local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1} +local function register_rail(itemstring, tiles, def_extras, creative) + local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=0,destroy_by_lava_flow=0, transport=1} if creative == false then groups.not_in_creative_inventory = 1 end @@ -21,7 +21,7 @@ local register_rail = function(itemstring, tiles, def_extras, creative) stack_max = 64, groups = groups, sounds = mcl_sounds.node_sound_metal_defaults(), - _mcl_blast_resistance = 3.5, + _mcl_blast_resistance = 0.7, _mcl_hardness = 0.7, after_destruct = function(pos) -- Scan for minecarts in this pos and force them to execute their "floating" check. @@ -206,11 +206,11 @@ register_rail("mcl_minecarts:detector_rail_on", -- Crafting minetest.register_craft({ - output = 'mcl_minecarts:rail 16', + output = "mcl_minecarts:rail 16", recipe = { - {'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', 'mcl_core:stick', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'}, + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_core:stick", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, } }) diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_furnace.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_furnace.png deleted file mode 100644 index 7beaaa1c7..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_furnace.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator.png deleted file mode 100644 index 15f2cdba6..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing.png deleted file mode 100644 index 52674486d..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing_powered.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing_powered.png deleted file mode 100644 index 08b20a814..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_crossing_powered.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved.png deleted file mode 100644 index b5dabcc01..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved_powered.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved_powered.png deleted file mode 100644 index 2a9cc6029..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_curved_powered.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_powered.png b/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_powered.png deleted file mode 100644 index c118032ef..000000000 Binary files a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_powered.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 00635861f..a9a1a0dad 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -1,80 +1,29 @@ - +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) -mobs = {} -mobs.mod = "mrm" -mobs.version = "20210106" -- don't rely too much on this, rarely updated, if ever - -local MAX_MOB_NAME_LENGTH = 30 -local HORNY_TIME = 30 -local HORNY_AGAIN_TIME = 300 -local CHILD_GROW_TIME = 60*20 -local DEATH_DELAY = 0.5 -local DEFAULT_FALL_SPEED = -10 -local FLOP_HEIGHT = 5.0 -local FLOP_HOR_SPEED = 1.5 - -local MOB_CAP = {} -MOB_CAP.hostile = 70 -MOB_CAP.passive = 10 -MOB_CAP.ambient = 15 -MOB_CAP.water = 15 +local PATHFINDING = "gowp" +local CRASH_WARN_FREQUENCY = 60 +local LIFETIMER_DISTANCE = 47 -- Localize local S = minetest.get_translator("mcl_mobs") --- CMI support check -local use_cmi = minetest.global_exists("cmi") - +local DEVELOPMENT = minetest.settings:get_bool("mcl_development",false) -- Invisibility mod check -mobs.invis = {} -if minetest.global_exists("invisibility") then - mobs.invis = invisibility -end +mcl_mobs.invis = {} - --- creative check -function mobs.is_creative(name) - return minetest.is_creative_enabled(name) -end - - --- localize math functions -local pi = math.pi -local sin = math.sin -local cos = math.cos -local abs = math.abs -local min = math.min -local max = math.max -local atann = math.atan -local random = math.random -local floor = math.floor -local atan = function(x) - if not x or x ~= x then - return 0 - else - return atann(x) - end -end - - --- Load settings -local damage_enabled = minetest.settings:get_bool("enable_damage") -local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false - -local disable_blood = minetest.settings:get_bool("mobs_disable_blood") -local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false -local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false -local spawn_protected = minetest.settings:get_bool("mobs_spawn_protected") ~= false local remove_far = true -local difficulty = tonumber(minetest.settings:get("mob_difficulty")) or 1.0 -local show_health = false -local max_per_block = tonumber(minetest.settings:get("max_objects_per_block") or 64) -local mobs_spawn_chance = tonumber(minetest.settings:get("mobs_spawn_chance") or 2.5) --- Shows helpful debug info above each mob -local mobs_debug = minetest.settings:get_bool("mobs_debug", false) +local mobs_debug = minetest.settings:get_bool("mobs_debug", false) -- Shows helpful debug info above each mob +local spawn_logging = minetest.settings:get_bool("mcl_logging_mobs_spawn",true) + +local MAPGEN_LIMIT = mcl_vars.mapgen_limit +local MAPGEN_MOB_LIMIT = MAPGEN_LIMIT - 90 +-- 30927 seems to be the edge of the world, so could be closer, but this is safer + -- Peaceful mode message so players will know there are no monsters if minetest.settings:get_bool("only_peaceful_mobs", false) then @@ -84,549 +33,14 @@ if minetest.settings:get_bool("only_peaceful_mobs", false) then end) end --- calculate aoc range for mob count -local aosrb = tonumber(minetest.settings:get("active_object_send_range_blocks")) -local abr = tonumber(minetest.settings:get("active_block_range")) -local aoc_range = max(aosrb, abr) * 16 - --- pathfinding settings -local enable_pathfinding = true -local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching -local stuck_path_timeout = 10 -- how long will mob follow path before giving up - --- default nodes -local node_ice = "mcl_core:ice" -local node_snowblock = "mcl_core:snowblock" -local node_snow = "mcl_core:snow" -mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" - -local mod_weather = minetest.get_modpath("mcl_weather") ~= nil -local mod_explosions = minetest.get_modpath("mcl_explosions") ~= nil -local mod_mobspawners = minetest.get_modpath("mcl_mobspawners") ~= nil -local mod_hunger = minetest.get_modpath("mcl_hunger") ~= nil -local mod_worlds = minetest.get_modpath("mcl_worlds") ~= nil -local mod_armor = minetest.get_modpath("mcl_armor") ~= nil -local mod_experience = minetest.get_modpath("mcl_experience") ~= nil - -----For Water Flowing: -local enable_physics = function(object, luaentity, ignore_check) - if luaentity.physical_state == false or ignore_check == true then - luaentity.physical_state = true - object:set_properties({ - physical = true - }) - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=-9.81,z=0}) - end -end - -local disable_physics = function(object, luaentity, ignore_check, reset_movement) - if luaentity.physical_state == true or ignore_check == true then - luaentity.physical_state = false - object:set_properties({ - physical = false - }) - if reset_movement ~= false then - object:set_velocity({x=0,y=0,z=0}) - object:set_acceleration({x=0,y=0,z=0}) - end - end -end - - --- play sound -local mob_sound = function(self, soundname, is_opinion, fixed_pitch) - - local soundinfo - if self.sounds_child and self.child then - soundinfo = self.sounds_child - elseif self.sounds then - soundinfo = self.sounds - end - if not soundinfo then - return - end - local sound = soundinfo[soundname] - if sound then - if is_opinion and self.opinion_sound_cooloff > 0 then - return - end - local pitch - if not fixed_pitch then - local base_pitch = soundinfo.base_pitch - if not base_pitch then - base_pitch = 1 - end - if self.child and (not self.sounds_child) then - -- Children have higher pitch - pitch = base_pitch * 1.5 - else - pitch = base_pitch - end - -- randomize the pitch a bit - pitch = pitch + math.random(-10, 10) * 0.005 - end - minetest.sound_play(sound, { - object = self.object, - gain = 1.0, - max_hear_distance = self.sounds.distance, - pitch = pitch, - }, true) - self.opinion_sound_cooloff = 1 - end -end - --- Return true if object is in view_range -local function object_in_range(self, object) - if not object then - return false - end - local factor - -- Apply view range reduction for special player armor - if object:is_player() and mod_armor then - factor = armor:get_mob_view_range_factor(object, self.name) - end - -- Distance check - local dist - if factor and factor == 0 then - return false - elseif factor then - dist = self.view_range * factor - else - dist = self.view_range - end - - local p1, p2 = self.object:get_pos(), object:get_pos() - return p1 and p2 and (vector.distance(p1, p2) <= dist) -end - --- attack player/mob -local do_attack = function(self, player) - - if self.state == "attack" or self.state == "die" then - return - end - - self.attack = player - self.state = "attack" - - -- TODO: Implement war_cry sound without being annoying - --if random(0, 100) < 90 then - --mob_sound(self, "war_cry", true) - --end -end - - --- collision function borrowed amended from jordan4ibanez open_ai mod -local collision = function(self) - - local pos = self.object:get_pos() - local vel = self.object:get_velocity() - local x = 0 - local z = 0 - local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 - - for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do - - if object:is_player() - or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then - - local pos2 = object:get_pos() - local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} - local force = (width + 0.5) - vector.distance( - {x = pos.x, y = 0, z = pos.z}, - {x = pos2.x, y = 0, z = pos2.z}) - - x = x + (vec.x * force) - z = z + (vec.z * force) - end - end - - return({x,z}) -end - --- move mob in facing direction -local set_velocity = function(self, v) - - local c_x, c_y = 0, 0 - - -- can mob be pushed, if so calculate direction - if self.pushable then - c_x, c_y = unpack(collision(self)) - end - - -- halt mob if it has been ordered to stay - if self.order == "stand" then - self.object:set_velocity({x = 0, y = 0, z = 0}) - return - end - - local yaw = (self.object:get_yaw() or 0) + self.rotate - - self.object:set_velocity({ - x = (sin(yaw) * -v) + c_x, - y = self.object:get_velocity().y, - z = (cos(yaw) * v) + c_y, - }) -end - - - --- calculate mob velocity -local get_velocity = function(self) - - local v = self.object:get_velocity() - if v then - return (v.x * v.x + v.z * v.z) ^ 0.5 - end - - return 0 -end - - --- set and return valid yaw -local set_yaw = function(self, yaw, delay, dtime) - - if not yaw or yaw ~= yaw then - yaw = 0 - end - - delay = delay or 0 - - if delay == 0 then - if self.shaking and dtime then - yaw = yaw + (math.random() * 2 - 1) * 5 * dtime - end - self.object:set_yaw(yaw) - return yaw - end - - self.target_yaw = yaw - self.delay = delay - - return self.target_yaw -end - --- global function to set mob yaw -function mobs:yaw(self, yaw, delay, dtime) - set_yaw(self, yaw, delay, dtime) -end - -local add_texture_mod = function(self, mod) - local full_mod = "" - local already_added = false - for i=1, #self.texture_mods do - if mod == self.texture_mods[i] then - already_added = true - end - full_mod = full_mod .. self.texture_mods[i] - end - if not already_added then - full_mod = full_mod .. mod - table.insert(self.texture_mods, mod) - end - self.object:set_texture_mod(full_mod) -end -local remove_texture_mod = function(self, mod) - local full_mod = "" - local remove = {} - for i=1, #self.texture_mods do - if self.texture_mods[i] ~= mod then - full_mod = full_mod .. self.texture_mods[i] - else - table.insert(remove, i) - end - end - for i=#remove, 1 do - table.remove(self.texture_mods, remove[i]) - end - self.object:set_texture_mod(full_mod) -end - --- set defined animation -local set_animation = function(self, anim, fixed_frame) - if not self.animation or not anim then - return - end - if self.state == "die" and anim ~= "die" and anim ~= "stand" then - return - end - - self.animation.current = self.animation.current or "" - - if (anim == self.animation.current - or not self.animation[anim .. "_start"] - or not self.animation[anim .. "_end"]) and self.state ~= "die" then - return - end - - self.animation.current = anim - - local a_start = self.animation[anim .. "_start"] - local a_end - if fixed_frame then - a_end = a_start - else - a_end = self.animation[anim .. "_end"] - end - - self.object:set_animation({ - x = a_start, - y = a_end}, - self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, - 0, self.animation[anim .. "_loop"] ~= false) -end - - --- above function exported for mount.lua -function mobs:set_animation(self, anim) - set_animation(self, anim) -end - --- Returns true is node can deal damage to self -local is_node_dangerous = function(self, nodename) - local nn = nodename - if self.lava_damage > 0 then - if minetest.get_item_group(nn, "lava") ~= 0 then - return true - end - end - if self.fire_damage > 0 then - if minetest.get_item_group(nn, "fire") ~= 0 then - return true - end - end - if minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then - return true - end - return false -end - - --- Returns true if node is a water hazard -local is_node_waterhazard = function(self, nodename) - local nn = nodename - if self.water_damage > 0 then - if minetest.get_item_group(nn, "water") ~= 0 then - return true - end - end - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].drowning and minetest.registered_nodes[nn].drowning > 0 then - if self.breath_max ~= -1 then - -- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case - -- this will prevent water-breathing mobs to classify water or e.g. sand below them as dangerous - if not self.breathes_in_water and minetest.get_item_group(nn, "water") ~= 0 then - return true - end - end - end - return false -end - - --- check line of sight (BrunoMine) -local line_of_sight = function(self, pos1, pos2, stepsize) - - stepsize = stepsize or 1 - - local s, pos = minetest.line_of_sight(pos1, pos2, stepsize) - - -- normal walking and flying mobs can see you through air - if s == true then - return true - end - - -- New pos1 to be analyzed - local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z} - - local r, pos = minetest.line_of_sight(npos1, pos2, stepsize) - - -- Checks the return - if r == true then return true end - - -- Nodename found - local nn = minetest.get_node(pos).name - - -- Target Distance (td) to travel - local td = vector.distance(pos1, pos2) - - -- Actual Distance (ad) traveled - local ad = 0 - - -- It continues to advance in the line of sight in search of a real - -- obstruction which counts as 'normal' nodebox. - while minetest.registered_nodes[nn] - and minetest.registered_nodes[nn].walkable == false do - - -- Check if you can still move forward - if td < ad + stepsize then - return true -- Reached the target - end - - -- Moves the analyzed pos - local d = vector.distance(pos1, pos2) - - npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x - npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y - npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z - - -- NaN checks - if d == 0 - or npos1.x ~= npos1.x - or npos1.y ~= npos1.y - or npos1.z ~= npos1.z then - return false - end - - ad = ad + stepsize - - -- scan again - r, pos = minetest.line_of_sight(npos1, pos2, stepsize) - - if r == true then return true end - - -- New Nodename found - nn = minetest.get_node(pos).name - - end - - return false -end - - --- are we flying in what we are suppose to? (taikedz) -local flight_check = function(self) - - local nod = self.standing_in - local def = minetest.registered_nodes[nod] - - if not def then return false end -- nil check - - local fly_in - if type(self.fly_in) == "string" then - fly_in = { self.fly_in } - elseif type(self.fly_in) == "table" then - fly_in = self.fly_in - else - return false - end - - for _,checknode in pairs(fly_in) do - if nod == checknode then - return true - elseif checknode == "__airlike" and def.walkable == false and - (def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then - return true - end - end - - return false -end - - --- custom particle effects -local effect = function(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down) - - radius = radius or 2 - min_size = min_size or 0.5 - max_size = max_size or 1 - gravity = gravity or -10 - glow = glow or 0 - go_down = go_down or false - - local ym - if go_down then - ym = 0 - else - ym = -radius - end - - minetest.add_particlespawner({ - amount = amount, - time = 0.25, - minpos = pos, - maxpos = pos, - minvel = {x = -radius, y = ym, z = -radius}, - maxvel = {x = radius, y = radius, z = radius}, - minacc = {x = 0, y = gravity, z = 0}, - maxacc = {x = 0, y = gravity, z = 0}, - minexptime = 0.1, - maxexptime = 1, - minsize = min_size, - maxsize = max_size, - texture = texture, - glow = glow, - }) -end - -local damage_effect = function(self, damage) - -- damage particles - if (not disable_blood) and damage > 0 then - - local amount_large = math.floor(damage / 2) - local amount_small = damage % 2 - - local pos = self.object:get_pos() - - pos.y = pos.y + (self.collisionbox[5] - self.collisionbox[2]) * .5 - - local texture = "mobs_blood.png" - -- full heart damage (one particle for each 2 HP damage) - if amount_large > 0 then - effect(pos, amount_large, texture, 2, 2, 1.75, 0, nil, true) - end - -- half heart damage (one additional particle if damage is an odd number) - if amount_small > 0 then - -- TODO: Use "half heart" - effect(pos, amount_small, texture, 1, 1, 1.75, 0, nil, true) - end - end -end - -mobs.death_effect = function(pos, yaw, collisionbox, rotate) - local min, max - if collisionbox then - min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} - max = {x=collisionbox[4], y=collisionbox[5], z=collisionbox[6]} - else - min = { x = -0.5, y = 0, z = -0.5 } - max = { x = 0.5, y = 0.5, z = 0.5 } - end - if rotate then - min = vector.rotate(min, {x=0, y=yaw, z=pi/2}) - max = vector.rotate(max, {x=0, y=yaw, z=pi/2}) - min, max = vector.sort(min, max) - min = vector.multiply(min, 0.5) - max = vector.multiply(max, 0.5) - end - - minetest.add_particlespawner({ - amount = 50, - time = 0.001, - minpos = vector.add(pos, min), - maxpos = vector.add(pos, max), - minvel = vector.new(-5,-5,-5), - maxvel = vector.new(5,5,5), - minexptime = 1.1, - maxexptime = 1.5, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "mcl_particles_mob_death.png^[colorize:#000000:255", - }) - - minetest.sound_play("mcl_mobs_mob_poof", { - pos = pos, - gain = 1.0, - max_hear_distance = 8, - }, true) -end - -local update_tag = function(self) +function mob_class:update_tag() --update nametag and/or the debug box local tag if mobs_debug then - tag = "nametag = '"..tostring(self.nametag).."'\n".. + local name = self.name + if self.nametag and self.nametag ~= "" then + name = self.nametag + end + tag = "name = '"..tostring(name).."'\n".. "state = '"..tostring(self.state).."'\n".. "order = '"..tostring(self.order).."'\n".. "attack = "..tostring(self.attack).."\n".. @@ -637,2582 +51,49 @@ local update_tag = function(self) "horny = "..tostring(self.horny).."\n".. "hornytimer = "..tostring(self.hornytimer).."\n".. "runaway_timer = "..tostring(self.runaway_timer).."\n".. - "following = "..tostring(self.following) + "following = "..tostring(self.following).."\n".. + "lifetimer = "..tostring(self.lifetimer) else tag = self.nametag end self.object:set_properties({ nametag = tag, }) - end - --- drop items -local item_drop = function(self, cooked, looting_level) - - -- no drops if disabled by setting - if not mobs_drop_items then return end - - looting_level = looting_level or 0 - - -- no drops for child mobs (except monster) - if (self.child and self.type ~= "monster") then - return - end - - local obj, item, num +function mob_class:jock_to(mob, reletive_pos, rot) local pos = self.object:get_pos() + if not pos then return end - self.drops = self.drops or {} -- nil check - - for n = 1, #self.drops do - local dropdef = self.drops[n] - local chance = 1 / dropdef.chance - local looting_type = dropdef.looting - - if looting_level > 0 then - local chance_function = dropdef.looting_chance_function - if chance_function then - chance = chance_function(looting_level) - elseif looting_type == "rare" then - chance = chance + (dropdef.looting_factor or 0.01) * looting_level - end - end - - local num = 0 - local do_common_looting = (looting_level > 0 and looting_type == "common") - if random() < chance then - num = random(dropdef.min or 1, dropdef.max or 1) - elseif not dropdef.looting_ignore_chance then - do_common_looting = false - end - - if do_common_looting then - num = num + math.floor(math.random(0, looting_level) + 0.5) - end - - if num > 0 then - item = dropdef.name - - -- cook items when true - if cooked then - - local output = minetest.get_craft_result({ - method = "cooking", width = 1, items = {item}}) - - if output and output.item and not output.item:is_empty() then - item = output.item:get_name() - end - end - - -- add item if it exists - obj = minetest.add_item(pos, ItemStack(item .. " " .. num)) - - if obj and obj:get_luaentity() then - - obj:set_velocity({ - x = random(-10, 10) / 9, - y = 6, - z = random(-10, 10) / 9, - }) - elseif obj then - obj:remove() -- item does not exist - end - end - end - - self.drops = {} + self.jockey = mob + local jock = minetest.add_entity(pos, mob) + if not jock then return end + jock:get_luaentity().docile_by_day = false + jock:get_luaentity().riden_by_jock = true + self.object:set_attach(jock, "", reletive_pos, rot) end +function mob_class:get_staticdata() --- check if mob is dead or only hurt -local check_for_death = function(self, cause, cmi_cause) - - if self.state == "die" then - return true - end - - -- has health actually changed? - if self.health == self.old_health and self.health > 0 then - return false - end - - local damaged = self.health < self.old_health - self.old_health = self.health - - -- still got some health? - if self.health > 0 then - - -- make sure health isn't higher than max - if self.health > self.hp_max then - self.health = self.hp_max - end - - -- play damage sound if health was reduced and make mob flash red. - if damaged then - add_texture_mod(self, "^[colorize:#FF000040") - minetest.after(.2, function(self) - if self and self.object then - remove_texture_mod(self, "^[colorize:#FF000040") - end - end, self) - mob_sound(self, "damage") - end - - -- backup nametag so we can show health stats - if not self.nametag2 then - self.nametag2 = self.nametag or "" - end - - if show_health - and (cmi_cause and cmi_cause.type == "punch") then - - self.htimer = 2 - self.nametag = "♥ " .. self.health .. " / " .. self.hp_max - - update_tag(self) - end - - return false - end - - mob_sound(self, "death") - - local function death_handle(self) - -- dropped cooked item if mob died in fire or lava - if cause == "lava" or cause == "fire" then - item_drop(self, true, 0) - else - local wielditem = ItemStack() - if cause == "hit" then - local puncher = cmi_cause.puncher - if puncher then - wielditem = puncher:get_wielded_item() - end - end - local cooked = mcl_burning.is_burning(self.object) or mcl_enchanting.has_enchantment(wielditem, "fire_aspect") - local looting = mcl_enchanting.get_enchantment(wielditem, "looting") - item_drop(self, cooked, looting) - - if mod_experience and ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= 5000000) then - mcl_experience.throw_experience(self.object:get_pos(), math.random(self.xp_min, self.xp_max)) - end - end - end - - -- execute custom death function - if self.on_die then - - local pos = self.object:get_pos() - local on_die_exit = self.on_die(self, pos, cmi_cause) - if on_die_exit ~= true then - death_handle(self) - end - - if use_cmi then - cmi.notify_die(self.object, cmi_cause) - end - - if on_die_exit == true then - self.state = "die" - mcl_burning.extinguish(self.object) - self.object:remove() - return true - end - end - - local collisionbox - if self.collisionbox then - collisionbox = table.copy(self.collisionbox) - end - - self.state = "die" - self.attack = nil - self.v_start = false - self.fall_speed = DEFAULT_FALL_SPEED - self.timer = 0 - self.blinktimer = 0 - remove_texture_mod(self, "^[colorize:#FF000040") - remove_texture_mod(self, "^[brighten") - self.passive = true - self.object:set_properties({ - pointable = false, - collide_with_objects = false, - }) - set_velocity(self, 0) - local acc = self.object:get_acceleration() - acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 - self.object:set_acceleration(acc) - - local length - -- default death function and die animation (if defined) - if self.instant_death then - length = 0 - elseif self.animation - and self.animation.die_start - and self.animation.die_end then - - local frames = self.animation.die_end - self.animation.die_start - local speed = self.animation.die_speed or 15 - length = max(frames / speed, 0) + DEATH_DELAY - set_animation(self, "die") - else - local rot = self.object:get_rotation() - rot.z = pi/2 - self.object:set_rotation(rot) - length = 1 + DEATH_DELAY - set_animation(self, "stand", true) - end - - - -- Remove body after a few seconds and drop stuff - local kill = function(self) - if not self.object:get_luaentity() then - return - end - if use_cmi then - cmi.notify_die(self.object, cmi_cause) - end - - death_handle(self) - local dpos = self.object:get_pos() - local cbox = self.collisionbox - local yaw = self.object:get_rotation().y - mcl_burning.extinguish(self.object) - self.object:remove() - mobs.death_effect(dpos, yaw, cbox, not self.instant_death) - end - if length <= 0 then - kill(self) - else - minetest.after(length, kill, self) - end - - return true -end - - --- check if within physical map limits (-30911 to 30927) -local within_limits, wmin, wmax = nil, -30913, 30928 -within_limits = function(pos, radius) - if mcl_vars then - if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then - wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max - within_limits = function(pos, radius) - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax - end - end - end - return pos - and (pos.x - radius) > wmin and (pos.x + radius) < wmax - and (pos.y - radius) > wmin and (pos.y + radius) < wmax - and (pos.z - radius) > wmin and (pos.z + radius) < wmax -end - - --- is mob facing a cliff or danger -local is_at_cliff_or_danger = function(self) - - if self.fear_height == 0 then -- 0 for no falling protection! - return false - end - - if not self.object:get_luaentity() then - return false - end - local yaw = self.object:get_yaw() - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - local pos = self.object:get_pos() - local ypos = pos.y + self.collisionbox[2] -- just above floor - - local free_fall, blocker = minetest.line_of_sight( - {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, - {x = pos.x + dir_x, y = ypos - self.fear_height, z = pos.z + dir_z}) - if free_fall then - return true - else - local bnode = minetest.get_node(blocker) - local danger = is_node_dangerous(self, bnode.name) - if danger then - return true - else - local def = minetest.registered_nodes[bnode.name] - if def and def.walkable then - return false - end - end - end - - return false -end - - --- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water -local is_at_water_danger = function(self) - - - if not self.object:get_luaentity() then - return false - end - local yaw = self.object:get_yaw() - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - local pos = self.object:get_pos() - local ypos = pos.y + self.collisionbox[2] -- just above floor - - local free_fall, blocker = minetest.line_of_sight( - {x = pos.x + dir_x, y = ypos, z = pos.z + dir_z}, - {x = pos.x + dir_x, y = ypos - 3, z = pos.z + dir_z}) - if free_fall then - return true - else - local bnode = minetest.get_node(blocker) - local waterdanger = is_node_waterhazard(self, bnode.name) - if - waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) then - return false - elseif waterdanger and (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) == false then - return true - else - local def = minetest.registered_nodes[bnode.name] - if def and def.walkable then - return false - end - end - end - - return false -end - - --- get node but use fallback for nil or unknown -local node_ok = function(pos, fallback) - - fallback = fallback or mobs.fallback_node - - local node = minetest.get_node_or_nil(pos) - - if node and minetest.registered_nodes[node.name] then - return node - end - - return minetest.registered_nodes[fallback] -end - - --- environmental damage (water, lava, fire, light etc.) -local do_env_damage = function(self) - - -- feed/tame text timer (so mob 'full' messages dont spam chat) - if self.htimer > 0 then - self.htimer = self.htimer - 1 - end - - -- reset nametag after showing health stats - if self.htimer < 1 and self.nametag2 then - - self.nametag = self.nametag2 - self.nametag2 = nil - - update_tag(self) - end - - local pos = self.object:get_pos() - - self.time_of_day = minetest.get_timeofday() - - -- remove mob if beyond map limits - if not within_limits(pos, 0) then - mcl_burning.extinguish(self.object) - self.object:remove() - return true - end - - - -- Deal light damage to mob, returns true if mob died - local deal_light_damage = function(self, pos, damage) - if not (mod_weather and (mcl_weather.rain.raining or mcl_weather.state == "snow") and mcl_weather.is_outdoor(pos)) then - self.health = self.health - damage - - effect(pos, 5, "mcl_particles_smoke.png") - - if check_for_death(self, "light", {type = "light"}) then - return true - end - end - end - - -- bright light harms mob - if self.light_damage ~= 0 and (minetest.get_node_light(pos) or 0) > 12 then - if deal_light_damage(self, pos, self.light_damage) then - return true - end - end - local _, dim = nil, "overworld" - if mod_worlds then - _, dim = mcl_worlds.y_to_layer(pos.y) - end - if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (minetest.get_node_light(pos) or 0) >= minetest.LIGHT_MAX and dim == "overworld" then - if self.ignited_by_sunlight then - mcl_burning.set_on_fire(self.object, 10, self.sunlight_damage or 1) - else - deal_light_damage(self, pos, self.sunlight_damage) - return true - end - end - - local y_level = self.collisionbox[2] - - if self.child then - y_level = self.collisionbox[2] * 0.5 - end - - -- what is mob standing in? - pos.y = pos.y + y_level + 0.25 -- foot level - local pos2 = {x=pos.x, y=pos.y-1, z=pos.z} - self.standing_in = node_ok(pos, "air").name - self.standing_on = node_ok(pos2, "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}) - end - - local nodef = minetest.registered_nodes[self.standing_in] - - -- rain - if self.rain_damage > 0 and mod_weather then - if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then - - self.health = self.health - self.rain_damage - - if check_for_death(self, "rain", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - end - - pos.y = pos.y + 1 -- for particle effect position - - -- water damage - if self.water_damage > 0 - and nodef.groups.water then - - if self.water_damage ~= 0 then - - self.health = self.health - self.water_damage - - effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil) - - if check_for_death(self, "water", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- lava damage - elseif self.lava_damage > 0 - and (nodef.groups.lava) then - - if self.lava_damage ~= 0 then - - self.health = self.health - self.lava_damage - - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - - if check_for_death(self, "lava", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- fire damage - elseif self.fire_damage > 0 - and (nodef.groups.fire) then - - if self.fire_damage ~= 0 then - - self.health = self.health - self.fire_damage - - effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) - - if check_for_death(self, "fire", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- damage_per_second node check - elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then - - self.health = self.health - nodef.damage_per_second - - effect(pos, 5, "mcl_particles_smoke.png") - - if check_for_death(self, "dps", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - - -- Drowning damage - if self.breath_max ~= -1 then - local drowning = false - if self.breathes_in_water then - if minetest.get_item_group(self.standing_in, "water") == 0 then - drowning = true - end - elseif nodef.drowning > 0 then - drowning = true - end - if drowning then - - self.breath = math.max(0, self.breath - 1) - - effect(pos, 2, "bubble.png", nil, nil, 1, nil) - if self.breath <= 0 then - local dmg - if nodef.drowning > 0 then - dmg = nodef.drowning - else - dmg = 4 - end - damage_effect(self, dmg) - self.health = self.health - dmg - end - if check_for_death(self, "drowning", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - else - self.breath = math.min(self.breath_max, self.breath + 1) - end - end - - --- suffocation inside solid node - -- FIXME: Redundant with mcl_playerplus - if (self.suffocation == true) - and (nodef.walkable == nil or nodef.walkable == true) - and (nodef.collision_box == nil or nodef.collision_box.type == "regular") - and (nodef.node_box == nil or nodef.node_box.type == "regular") - and (nodef.groups.disable_suffocation ~= 1) - and (nodef.groups.opaque == 1) then - - -- Short grace period before starting to take suffocation damage. - -- This is different from players, who take damage instantly. - -- This has been done because mobs might briefly be inside solid nodes - -- when e.g. climbing up stairs. - -- This is a bit hacky because it assumes that do_env_damage - -- is called roughly every second only. - self.suffocation_timer = self.suffocation_timer + 1 - if self.suffocation_timer >= 3 then - -- 2 damage per second - -- TODO: Deal this damage once every 1/2 second - self.health = self.health - 2 - - if check_for_death(self, "suffocation", {type = "environment", - pos = pos, node = self.standing_in}) then - return true - end - end - else - self.suffocation_timer = 0 - end - - return check_for_death(self, "", {type = "unknown"}) -end - - --- jump if facing a solid node (not fences or gates) -local do_jump = function(self) - - if not self.jump - or self.jump_height == 0 - or self.fly - or (self.child and self.type ~= "monster") - or self.order == "stand" then - return false - end - - self.facing_fence = false - - -- something stopping us while moving? - if self.state ~= "stand" - and get_velocity(self) > 0.5 - and self.object:get_velocity().y ~= 0 then - return false - end - - local pos = self.object:get_pos() - local yaw = self.object:get_yaw() - - -- what is mob standing on? - pos.y = pos.y + self.collisionbox[2] - 0.2 - - local nod = node_ok(pos) - - if minetest.registered_nodes[nod.name].walkable == false then - return false - end - - -- where is front - local dir_x = -sin(yaw) * (self.collisionbox[4] + 0.5) - local dir_z = cos(yaw) * (self.collisionbox[4] + 0.5) - - -- what is in front of mob? - nod = node_ok({ - x = pos.x + dir_x, - y = pos.y + 0.5, - z = pos.z + dir_z - }) - - -- this is used to detect if there's a block on top of the block in front of the mob. - -- If there is, there is no point in jumping as we won't manage. - local nodTop = node_ok({ - x = pos.x + dir_x, - y = pos.y + 1.5, - z = pos.z + dir_z - }, "air") - - -- we don't attempt to jump if there's a stack of blocks blocking - if minetest.registered_nodes[nodTop.name].walkable == true then - return false - end - - -- thin blocks that do not need to be jumped - if nod.name == node_snow then - return false - end - - if self.walk_chance == 0 - or minetest.registered_items[nod.name].walkable then - - if minetest.get_item_group(nod.name, "fence") == 0 - and minetest.get_item_group(nod.name, "fence_gate") == 0 - and minetest.get_item_group(nod.name, "wall") == 0 then - - local v = self.object:get_velocity() - - v.y = self.jump_height - - set_animation(self, "jump") -- only when defined - - self.object:set_velocity(v) - - -- when in air move forward - minetest.after(0.3, function(self, v) - if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then - return - end - self.object:set_acceleration({ - x = v.x * 2, - y = -10, - z = v.z * 2, - }) - end, self, v) - - if self.jump_sound_cooloff <= 0 then - mob_sound(self, "jump") - self.jump_sound_cooloff = 0.5 - end - else - self.facing_fence = true - end - - -- if we jumped against a block/wall 4 times then turn - if self.object:get_velocity().x ~= 0 - and self.object:get_velocity().z ~= 0 then - - self.jump_count = (self.jump_count or 0) + 1 - - if self.jump_count == 4 then - - local yaw = self.object:get_yaw() or 0 - - yaw = set_yaw(self, yaw + 1.35, 8) - - self.jump_count = 0 - end - end - - return true - end - - return false -end - - --- blast damage to entities nearby -local entity_physics = function(pos, radius) - - radius = radius * 2 - - local objs = minetest.get_objects_inside_radius(pos, radius) - local obj_pos, dist - - for n = 1, #objs do - - obj_pos = objs[n]:get_pos() - - dist = vector.distance(pos, obj_pos) - if dist < 1 then dist = 1 end - - local damage = floor((4 / dist) * radius) - local ent = objs[n]:get_luaentity() - - -- punches work on entities AND players - objs[n]:punch(objs[n], 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, pos) - end -end - - --- should mob follow what I'm holding ? -local follow_holding = function(self, clicker) - - if mobs.invis[clicker:get_player_name()] then - return false - end - - local item = clicker:get_wielded_item() - local t = type(self.follow) - - -- single item - if t == "string" - and item:get_name() == self.follow then - return true - - -- multiple items - elseif t == "table" then - - for no = 1, #self.follow do - - if self.follow[no] == item:get_name() then - return true - end - end - end - - return false -end - - --- find two animals of same type and breed if nearby and horny -local breed = function(self) - - -- child takes a long time before growing into adult - if self.child == true then - - -- When a child, hornytimer is used to count age until adulthood - self.hornytimer = self.hornytimer + 1 - - if self.hornytimer >= CHILD_GROW_TIME then - - self.child = false - self.hornytimer = 0 - - self.object:set_properties({ - textures = self.base_texture, - mesh = self.base_mesh, - visual_size = self.base_size, - collisionbox = self.base_colbox, - selectionbox = self.base_selbox, - }) - - -- custom function when child grows up - if self.on_grown then - self.on_grown(self) - else - -- jump when fully grown so as not to fall into ground - self.object:set_velocity({ - x = 0, - y = self.jump_height, - z = 0 - }) - end - end - - return - end - - -- horny animal can mate for HORNY_TIME seconds, - -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds - if self.horny == true - and self.hornytimer < HORNY_TIME + HORNY_AGAIN_TIME then - - self.hornytimer = self.hornytimer + 1 - - if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then - self.hornytimer = 0 - self.horny = false - end - end - - -- find another same animal who is also horny and mate if nearby - if self.horny == true - and self.hornytimer <= HORNY_TIME then - - local pos = self.object:get_pos() - - effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) - - local objs = minetest.get_objects_inside_radius(pos, 3) - local num = 0 - local ent = nil - - for n = 1, #objs do - - ent = objs[n]:get_luaentity() - - -- check for same animal with different colour - local canmate = false - - if ent then - - if ent.name == self.name then - canmate = true - else - local entname = string.split(ent.name,":") - local selfname = string.split(self.name,":") - - if entname[1] == selfname[1] then - entname = string.split(entname[2],"_") - selfname = string.split(selfname[2],"_") - - if entname[1] == selfname[1] then - canmate = true - end - end - end - end - - if ent - and canmate == true - and ent.horny == true - and ent.hornytimer <= HORNY_TIME then - num = num + 1 - end - - -- found your mate? then have a baby - if num > 1 then - - self.hornytimer = HORNY_TIME + 1 - ent.hornytimer = HORNY_TIME + 1 - - -- spawn baby - minetest.after(5, function(parent1, parent2, pos) - if not parent1.object:get_luaentity() then - return - end - if not parent2.object:get_luaentity() then - return - end - - -- Give XP - if mod_experience then - mcl_experience.throw_experience(pos, math.random(1, 7)) - end - - -- custom breed function - if parent1.on_breed then - -- when false, skip going any further - if parent1.on_breed(parent1, parent2) == false then - return - end - end - - local child = mobs:spawn_child(pos, parent1.name) - - local ent_c = child:get_luaentity() - - - -- Use texture of one of the parents - local p = math.random(1, 2) - if p == 1 then - ent_c.base_texture = parent1.base_texture - else - ent_c.base_texture = parent2.base_texture - end - child:set_properties({ - textures = ent_c.base_texture - }) - - -- tamed and owned by parents' owner - ent_c.tamed = true - ent_c.owner = parent1.owner - end, self, ent, pos) - - num = 0 - - break - end - end - end -end - - --- find and replace what mob is looking for (grass, wheat etc.) -local replace = function(self, pos) - - if not self.replace_rate - or not self.replace_what - or self.child == true - or self.object:get_velocity().y ~= 0 - or random(1, self.replace_rate) > 1 then - return - end - - local what, with, y_offset - - if type(self.replace_what[1]) == "table" then - - local num = random(#self.replace_what) - - what = self.replace_what[num][1] or "" - with = self.replace_what[num][2] or "" - y_offset = self.replace_what[num][3] or 0 - else - what = self.replace_what - with = self.replace_with or "" - y_offset = self.replace_offset or 0 - end - - pos.y = pos.y + y_offset - - local node = minetest.get_node(pos) - if node.name == what then - - local oldnode = {name = what, param2 = node.param2} - local newnode = {name = with, param2 = node.param2} - local on_replace_return - - if self.on_replace then - on_replace_return = self.on_replace(self, pos, oldnode, newnode) - end - - if on_replace_return ~= false then - - if mobs_griefing then - minetest.set_node(pos, newnode) - end - - end - end -end - - --- check if daytime and also if mob is docile during daylight hours -local day_docile = function(self) - - if self.docile_by_day == false then - - return false - - elseif self.docile_by_day == true - and self.time_of_day > 0.2 - and self.time_of_day < 0.8 then - - return true - end -end - - -local los_switcher = false -local height_switcher = false - --- path finding and smart mob routine by rnd, line_of_sight and other edits by Elkien3 -local smart_mobs = function(self, s, p, dist, dtime) - - local s1 = self.path.lastpos - - local target_pos = self.attack:get_pos() - - -- is it becoming stuck? - if abs(s1.x - s.x) + abs(s1.z - s.z) < .5 then - self.path.stuck_timer = self.path.stuck_timer + dtime - else - self.path.stuck_timer = 0 - end - - self.path.lastpos = {x = s.x, y = s.y, z = s.z} - - local use_pathfind = false - local has_lineofsight = minetest.line_of_sight( - {x = s.x, y = (s.y) + .5, z = s.z}, - {x = target_pos.x, y = (target_pos.y) + 1.5, z = target_pos.z}, .2) - - -- im stuck, search for path - if not has_lineofsight then - - if los_switcher == true then - use_pathfind = true - los_switcher = false - end -- cannot see target! - else - if los_switcher == false then - - los_switcher = true - use_pathfind = false - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end -- can see target! - end - - if (self.path.stuck_timer > stuck_timeout and not self.path.following) then - - use_pathfind = true - self.path.stuck_timer = 0 - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end - - if (self.path.stuck_timer > stuck_path_timeout and self.path.following) then - - use_pathfind = true - self.path.stuck_timer = 0 - - minetest.after(1, function(self) - if not self.object:get_luaentity() then - return - end - if has_lineofsight then self.path.following = false end - end, self) - end - - if math.abs(vector.subtract(s,target_pos).y) > self.stepheight then - - if height_switcher then - use_pathfind = true - height_switcher = false - end - else - if not height_switcher then - use_pathfind = false - height_switcher = true - end - end - - if use_pathfind then - -- lets try find a path, first take care of positions - -- since pathfinder is very sensitive - local sheight = self.collisionbox[5] - self.collisionbox[2] - - -- round position to center of node to avoid stuck in walls - -- also adjust height for player models! - s.x = floor(s.x + 0.5) - s.z = floor(s.z + 0.5) - - local ssight, sground = minetest.line_of_sight(s, { - x = s.x, y = s.y - 4, z = s.z}, 1) - - -- determine node above ground - if not ssight then - s.y = sground.y + 1 - end - - local p1 = self.attack:get_pos() - - p1.x = floor(p1.x + 0.5) - p1.y = floor(p1.y + 0.5) - p1.z = floor(p1.z + 0.5) - - local dropheight = 12 - if self.fear_height ~= 0 then dropheight = self.fear_height end - local jumpheight = 0 - if self.jump and self.jump_height >= 4 then - jumpheight = math.min(math.ceil(self.jump_height / 4), 4) - elseif self.stepheight > 0.5 then - jumpheight = 1 - end - self.path.way = minetest.find_path(s, p1, 16, jumpheight, dropheight, "A*_noprefetch") - - self.state = "" - do_attack(self, self.attack) - - -- no path found, try something else - if not self.path.way then - - self.path.following = false - - -- lets make way by digging/building if not accessible - if self.pathfinding == 2 and mobs_griefing then - - -- is player higher than mob? - if s.y < p1.y then - - -- build upwards - if not minetest.is_protected(s, "") then - - local ndef1 = minetest.registered_nodes[self.standing_in] - - if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then - - minetest.set_node(s, {name = mobs.fallback_node}) - end - end - - local sheight = math.ceil(self.collisionbox[5]) + 1 - - -- assume mob is 2 blocks high so it digs above its head - s.y = s.y + sheight - - -- remove one block above to make room to jump - if not minetest.is_protected(s, "") then - - local node1 = node_ok(s, "air").name - local ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.set_node(s, {name = "air"}) - minetest.add_item(s, ItemStack(node1)) - - end - end - - s.y = s.y - sheight - self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) - - else -- dig 2 blocks to make door toward player direction - - local yaw1 = self.object:get_yaw() + pi / 2 - local p1 = { - x = s.x + cos(yaw1), - y = s.y, - z = s.z + sin(yaw1) - } - - if not minetest.is_protected(p1, "") then - - local node1 = node_ok(p1, "air").name - local ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.add_item(p1, ItemStack(node1)) - minetest.set_node(p1, {name = "air"}) - end - - p1.y = p1.y + 1 - node1 = node_ok(p1, "air").name - ndef1 = minetest.registered_nodes[node1] - - if node1 ~= "air" - and node1 ~= "ignore" - and ndef1 - and not ndef1.groups.level - and not ndef1.groups.unbreakable - and not ndef1.groups.liquid then - - minetest.add_item(p1, ItemStack(node1)) - minetest.set_node(p1, {name = "air"}) - end - - end - end - end - - -- will try again in 2 seconds - self.path.stuck_timer = stuck_timeout - 2 - elseif s.y < p1.y and (not self.fly) then - do_jump(self) --add jump to pathfinding - self.path.following = true - -- Yay, I found path! - -- TODO: Implement war_cry sound without being annoying - --mob_sound(self, "war_cry", true) - else - set_velocity(self, self.walk_velocity) - - -- follow path now that it has it - self.path.following = true - end - end -end - - --- specific attacks -local specific_attack = function(list, what) - - -- no list so attack default (player, animals etc.) - if list == nil then - return true - end - - -- found entity on list to attack? - for no = 1, #list do - - if list[no] == what then - return true - end - end - - return false -end - --- monster find someone to attack -local monster_attack = function(self) - - if self.type ~= "monster" - or not damage_enabled - or minetest.is_creative_enabled("") - or self.passive - or self.state == "attack" - or day_docile(self) then - return - end - - local s = self.object:get_pos() - local p, sp, dist - local player, obj, min_player - local type, name = "", "" - local min_dist = self.view_range + 1 - local objs = minetest.get_objects_inside_radius(s, self.view_range) - - for n = 1, #objs do - - if objs[n]:is_player() then - - if mobs.invis[ objs[n]:get_player_name() ] or (not object_in_range(self, objs[n])) then - type = "" - else - player = objs[n] - type = "player" - name = "player" - end - else - obj = objs[n]:get_luaentity() - - if obj then - player = obj.object - type = obj.type - name = obj.name or "" - end - end - - -- find specific mob to attack, failing that attack player/npc/animal - if specific_attack(self.specific_attack, name) - and (type == "player" or type == "npc" - or (type == "animal" and self.attack_animals == true)) then - - p = player:get_pos() - sp = s - - dist = vector.distance(p, s) - - -- aim higher to make looking up hills more realistic - p.y = p.y + 1 - sp.y = sp.y + 1 - - - -- choose closest player to attack - if dist < min_dist - and line_of_sight(self, sp, p, 2) == true then - min_dist = dist - min_player = player - end - end - end - - -- attack player - if min_player then - do_attack(self, min_player) - end -end - - --- npc, find closest monster to attack -local npc_attack = function(self) - - if self.type ~= "npc" - or not self.attacks_monsters - or self.state == "attack" then - return - end - - local p, sp, obj, min_player - local s = self.object:get_pos() - local min_dist = self.view_range + 1 - local objs = minetest.get_objects_inside_radius(s, self.view_range) - - for n = 1, #objs do - - obj = objs[n]:get_luaentity() - - if obj and obj.type == "monster" then - - p = obj.object:get_pos() - sp = s - - local dist = vector.distance(p, s) - - -- aim higher to make looking up hills more realistic - p.y = p.y + 1 - sp.y = sp.y + 1 - - if dist < min_dist - and line_of_sight(self, sp, p, 2) == true then - min_dist = dist - min_player = obj.object - end - end - end - - if min_player then - do_attack(self, min_player) - end -end - - --- specific runaway -local specific_runaway = function(list, what) - - -- no list so do not run - if list == nil then - return false - end - - -- found entity on list to attack? - for no = 1, #list do - - if list[no] == what then - return true - end - end - - return false -end - - --- find someone to runaway from -local runaway_from = function(self) - - if not self.runaway_from and self.state ~= "flop" then - return - end - - local s = self.object:get_pos() - local p, sp, dist - local player, obj, min_player - local type, name = "", "" - local min_dist = self.view_range + 1 - local objs = minetest.get_objects_inside_radius(s, self.view_range) - - for n = 1, #objs do - - if objs[n]:is_player() then - - if mobs.invis[ objs[n]:get_player_name() ] - or self.owner == objs[n]:get_player_name() - or (not object_in_range(self, objs[n])) then - type = "" - else - player = objs[n] - type = "player" - name = "player" - end - else - obj = objs[n]:get_luaentity() - - if obj then - player = obj.object - type = obj.type - name = obj.name or "" - end - end - - -- find specific mob to runaway from - if name ~= "" and name ~= self.name - and specific_runaway(self.runaway_from, name) then - - p = player:get_pos() - sp = s - - -- aim higher to make looking up hills more realistic - p.y = p.y + 1 - sp.y = sp.y + 1 - - dist = vector.distance(p, s) - - - -- choose closest player/mpb to runaway from - if dist < min_dist - and line_of_sight(self, sp, p, 2) == true then - min_dist = dist - min_player = player - end - end - end - - if min_player then - - local lp = player:get_pos() - local vec = { - x = lp.x - s.x, - y = lp.y - s.y, - z = lp.z - s.z - } - - local yaw = (atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate - - if lp.x > s.x then - yaw = yaw + pi - end - - yaw = set_yaw(self, yaw, 4) - self.state = "runaway" - self.runaway_timer = 3 - self.following = nil - end -end - - --- follow player if owner or holding item, if fish outta water then flop -local follow_flop = function(self) - - -- find player to follow - if (self.follow ~= "" - or self.order == "follow") - and not self.following - and self.state ~= "attack" - and self.order ~= "sit" - and self.state ~= "runaway" then - - local s = self.object:get_pos() - local players = minetest.get_connected_players() - - for n = 1, #players do - - if (object_in_range(self, players[n])) - and not mobs.invis[ players[n]:get_player_name() ] then - - self.following = players[n] - - break - end - end - end - - if self.type == "npc" - and self.order == "follow" - and self.state ~= "attack" - and self.order ~= "sit" - and self.owner ~= "" then - - -- npc stop following player if not owner - if self.following - and self.owner - and self.owner ~= self.following:get_player_name() then - self.following = nil - end - else - -- stop following player if not holding specific item, - -- mob is horny, fleeing or attacking - if self.following - and self.following:is_player() - and (follow_holding(self, self.following) == false or - self.horny or self.state == "runaway") then - self.following = nil - end - - end - - -- follow that thing - if self.following then - - local s = self.object:get_pos() - local p - - if self.following:is_player() then - - p = self.following:get_pos() - - elseif self.following.object then - - p = self.following.object:get_pos() - end - - if p then - - local dist = vector.distance(p, s) - - -- dont follow if out of range - if (not object_in_range(self, self.following)) then - self.following = nil - else - local vec = { - x = p.x - s.x, - z = p.z - s.z - } - - local yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - set_yaw(self, yaw, 2.35) - - -- anyone but standing npc's can move along - if dist > 3 - and self.order ~= "stand" then - - set_velocity(self, self.follow_velocity) - - if self.walk_chance ~= 0 then - set_animation(self, "run") - end - else - set_velocity(self, 0) - set_animation(self, "stand") - end - - return - end - end - end - - -- swimmers flop when out of their element, and swim again when back in - if self.fly then - local s = self.object:get_pos() - if not flight_check(self, s) then - - self.state = "flop" - self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0}) - - local sdef = minetest.registered_nodes[self.standing_on] - -- Flop on ground - if sdef and sdef.walkable then - mob_sound(self, "flop") - self.object:set_velocity({ - x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), - y = FLOP_HEIGHT, - z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), - }) - end - - set_animation(self, "stand", true) - - return - elseif self.state == "flop" then - self.state = "stand" - self.object:set_acceleration({x = 0, y = 0, z = 0}) - set_velocity(self, 0) - end - end -end - - --- dogshoot attack switch and counter function -local dogswitch = function(self, dtime) - - -- switch mode not activated - if not self.dogshoot_switch - or not dtime then - return 0 - end - - self.dogshoot_count = self.dogshoot_count + dtime - - if (self.dogshoot_switch == 1 - and self.dogshoot_count > self.dogshoot_count_max) - or (self.dogshoot_switch == 2 - and self.dogshoot_count > self.dogshoot_count2_max) then - - self.dogshoot_count = 0 - - if self.dogshoot_switch == 1 then - self.dogshoot_switch = 2 - else - self.dogshoot_switch = 1 - end - end - - return self.dogshoot_switch -end - --- execute current state (stand, walk, run, attacks) --- returns true if mob has died -local do_states = function(self, dtime) - - local yaw = self.object:get_yaw() or 0 - - if self.state == "stand" then - - if random(1, 4) == 1 then - - local lp = nil - local s = self.object:get_pos() - local objs = minetest.get_objects_inside_radius(s, 3) - - for n = 1, #objs do - - if objs[n]:is_player() then - lp = objs[n]:get_pos() - break - end - end - - -- look at any players nearby, otherwise turn randomly - if lp then - - local vec = { - x = lp.x - s.x, - z = lp.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if lp.x > s.x then yaw = yaw + pi end - else - yaw = yaw + random(-0.5, 0.5) - end - - yaw = set_yaw(self, yaw, 8) - end - - set_velocity(self, 0) - set_animation(self, "stand") - - -- npc's ordered to stand stay standing - if self.type ~= "npc" - or self.order ~= "stand" then - - if self.walk_chance ~= 0 - and self.facing_fence ~= true - and random(1, 100) <= self.walk_chance - and is_at_cliff_or_danger(self) == false then - - set_velocity(self, self.walk_velocity) - self.state = "walk" - set_animation(self, "walk") - end - end - - elseif self.state == "walk" then - - local s = self.object:get_pos() - local lp = nil - - -- is there something I need to avoid? - if (self.water_damage > 0 - and self.lava_damage > 0) - or self.breath_max ~= -1 then - - lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) - - elseif self.water_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:water"}) - - elseif self.lava_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:lava"}) - - elseif self.fire_damage > 0 then - - lp = minetest.find_node_near(s, 1, {"group:fire"}) - - end - - local is_in_danger = false - if lp then - -- If mob in or on dangerous block, look for land - if (is_node_dangerous(self, self.standing_in) or - is_node_dangerous(self, self.standing_on)) or (is_node_waterhazard(self, self.standing_in) or is_node_waterhazard(self, self.standing_on)) and (not self.fly) then - is_in_danger = true - - -- If mob in or on dangerous block, look for land - if is_in_danger then - -- Better way to find shore - copied from upstream - lp = minetest.find_nodes_in_area_under_air( - {x = s.x - 5, y = s.y - 0.5, z = s.z - 5}, - {x = s.x + 5, y = s.y + 1, z = s.z + 5}, - {"group:solid"}) - - lp = #lp > 0 and lp[random(#lp)] - - -- did we find land? - if lp then - - local vec = { - x = lp.x - s.x, - z = lp.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - - if lp.x > s.x then yaw = yaw + pi end - - -- look towards land and move in that direction - yaw = set_yaw(self, yaw, 6) - set_velocity(self, self.walk_velocity) - - end - end - - -- A danger is near but mob is not inside - else - - -- Randomly turn - if random(1, 100) <= 30 then - yaw = yaw + random(-0.5, 0.5) - yaw = set_yaw(self, yaw, 8) - end - end - - yaw = set_yaw(self, yaw, 8) - - -- otherwise randomly turn - elseif random(1, 100) <= 30 then - - yaw = yaw + random(-0.5, 0.5) - yaw = set_yaw(self, yaw, 8) - end - - -- stand for great fall or danger or fence in front - local cliff_or_danger = false - if is_in_danger then - cliff_or_danger = is_at_cliff_or_danger(self) - end - if self.facing_fence == true - or cliff_or_danger - or random(1, 100) <= 30 then - - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - - set_velocity(self, self.walk_velocity) - - if flight_check(self) - and self.animation - and self.animation.fly_start - and self.animation.fly_end then - set_animation(self, "fly") - else - set_animation(self, "walk") - end - end - - -- runaway when punched - elseif self.state == "runaway" then - - self.runaway_timer = self.runaway_timer + 1 - - -- stop after 5 seconds or when at cliff - if self.runaway_timer > 5 - or is_at_cliff_or_danger(self) then - self.runaway_timer = 0 - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - set_velocity(self, self.run_velocity) - set_animation(self, "run") - end - - -- attack routines (explode, dogfight, shoot, dogshoot) - elseif self.state == "attack" then - - local s = self.object:get_pos() - local p = self.attack:get_pos() or s - - -- stop attacking if player invisible or out of range - if not self.attack - or not self.attack:get_pos() - or not object_in_range(self, self.attack) - or self.attack:get_hp() <= 0 - or (self.attack:is_player() and mobs.invis[ self.attack:get_player_name() ]) then - - self.state = "stand" - set_velocity(self, 0) - set_animation(self, "stand") - self.attack = nil - self.v_start = false - self.timer = 0 - self.blinktimer = 0 - self.path.way = nil - - return - end - - -- calculate distance from mob and enemy - local dist = vector.distance(p, s) - - if self.attack_type == "explode" then - - local vec = { - x = p.x - s.x, - z = p.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - local node_break_radius = self.explosion_radius or 1 - local entity_damage_radius = self.explosion_damage_radius - or (node_break_radius * 2) - - -- start timer when in reach and line of sight - if not self.v_start - and dist <= self.reach - and line_of_sight(self, s, p, 2) then - - self.v_start = true - self.timer = 0 - self.blinktimer = 0 - mob_sound(self, "fuse", nil, false) - - -- stop timer if out of reach or direct line of sight - elseif self.allow_fuse_reset - and self.v_start - and (dist > self.reach - or not line_of_sight(self, s, p, 2)) then - self.v_start = false - self.timer = 0 - self.blinktimer = 0 - self.blinkstatus = false - remove_texture_mod(self, "^[brighten") - end - - -- walk right up to player unless the timer is active - if self.v_start and (self.stop_to_explode or dist < 1.5) then - set_velocity(self, 0) - else - set_velocity(self, self.run_velocity) - end - - if self.animation and self.animation.run_start then - set_animation(self, "run") - else - set_animation(self, "walk") - end - - if self.v_start then - - self.timer = self.timer + dtime - self.blinktimer = (self.blinktimer or 0) + dtime - - if self.blinktimer > 0.2 then - - self.blinktimer = 0 - - if self.blinkstatus then - remove_texture_mod(self, "^[brighten") - else - add_texture_mod(self, "^[brighten") - end - - self.blinkstatus = not self.blinkstatus - end - - if self.timer > self.explosion_timer then - - local pos = self.object:get_pos() - - if mod_explosions then - if mobs_griefing and not minetest.is_protected(pos, "") then - mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { drop_chance = 1.0 }, self.object) - else - minetest.sound_play(self.sounds.explode, { - pos = pos, - gain = 1.0, - max_hear_distance = self.sounds.distance or 32 - }, true) - - entity_physics(pos, entity_damage_radius) - effect(pos, 32, "mcl_particles_smoke.png", nil, nil, node_break_radius, 1, 0) - end - end - mcl_burning.extinguish(self.object) - self.object:remove() - - return true - end - end - - elseif self.attack_type == "dogfight" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 2) - or (self.attack_type == "dogshoot" and dist <= self.reach and dogswitch(self) == 0) then - - if self.fly - and dist > self.reach then - - local p1 = s - local me_y = floor(p1.y) - local p2 = p - local p_y = floor(p2.y + 1) - local v = self.object:get_velocity() - - if flight_check(self, s) then - - if me_y < p_y then - - self.object:set_velocity({ - x = v.x, - y = 1 * self.walk_velocity, - z = v.z - }) - - elseif me_y > p_y then - - self.object:set_velocity({ - x = v.x, - y = -1 * self.walk_velocity, - z = v.z - }) - end - else - if me_y < p_y then - - self.object:set_velocity({ - x = v.x, - y = 0.01, - z = v.z - }) - - elseif me_y > p_y then - - self.object:set_velocity({ - x = v.x, - y = -0.01, - z = v.z - }) - end - end - - end - - -- rnd: new movement direction - if self.path.following - and self.path.way - and self.attack_type ~= "dogshoot" then - - -- no paths longer than 50 - if #self.path.way > 50 - or dist < self.reach then - self.path.following = false - return - end - - local p1 = self.path.way[1] - - if not p1 then - self.path.following = false - return - end - - if abs(p1.x-s.x) + abs(p1.z - s.z) < 0.6 then - -- reached waypoint, remove it from queue - table.remove(self.path.way, 1) - end - - -- set new temporary target - p = {x = p1.x, y = p1.y, z = p1.z} - end - - local vec = { - x = p.x - s.x, - z = p.z - s.z - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - -- move towards enemy if beyond mob reach - if dist > self.reach then - - -- path finding by rnd - if self.pathfinding -- only if mob has pathfinding enabled - and enable_pathfinding then - - smart_mobs(self, s, p, dist, dtime) - end - - if is_at_cliff_or_danger(self) then - - set_velocity(self, 0) - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - else - - if self.path.stuck then - set_velocity(self, self.walk_velocity) - else - set_velocity(self, self.run_velocity) - end - - if self.animation and self.animation.run_start then - set_animation(self, "run") - else - set_animation(self, "walk") - end - end - - else -- rnd: if inside reach range - - self.path.stuck = false - self.path.stuck_timer = 0 - self.path.following = false -- not stuck anymore - - set_velocity(self, 0) - - if not self.custom_attack then - - if self.timer > 1 then - - self.timer = 0 - - if self.double_melee_attack - and random(1, 2) == 1 then - set_animation(self, "punch2") - else - set_animation(self, "punch") - end - - local p2 = p - local s2 = s - - p2.y = p2.y + .5 - s2.y = s2.y + .5 - - if line_of_sight(self, p2, s2) == true then - - -- play attack sound - mob_sound(self, "attack") - - -- punch player (or what player is attached to) - local attached = self.attack:get_attach() - if attached then - self.attack = attached - end - self.attack:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = self.damage} - }, nil) - end - end - else -- call custom attack every second - if self.custom_attack - and self.timer > 1 then - - self.timer = 0 - - self.custom_attack(self, p) - end - end - end - - elseif self.attack_type == "shoot" - or (self.attack_type == "dogshoot" and dogswitch(self, dtime) == 1) - or (self.attack_type == "dogshoot" and dist > self.reach and dogswitch(self) == 0) then - - 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 - } - - yaw = (atan(vec.z / vec.x) + pi / 2) - self.rotate - - if p.x > s.x then yaw = yaw + pi end - - yaw = set_yaw(self, yaw, 0, dtime) - - set_velocity(self, 0) - - local p = self.object:get_pos() - p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 - - if self.shoot_interval - and self.timer > self.shoot_interval - and not minetest.raycast(p, self.attack:get_pos(), false, false):next() - and random(1, 100) <= 60 then - - self.timer = 0 - set_animation(self, "shoot") - - -- play shoot attack sound - mob_sound(self, "shoot_attack") - - -- Shoot arrow - if minetest.registered_entities[self.arrow] then - - local arrow, ent - local v = 1 - if not self.shoot_arrow then - arrow = minetest.add_entity(p, 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 - 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(p, vec) - else - arrow:set_velocity(vec) - end - end - end - end - end -end - - --- falling and fall damage --- returns true if mob died -local falling = function(self, pos) - - if self.fly and self.state ~= "die" then - return - end - - if mcl_portals ~= nil then - if mcl_portals.nether_portal_cooloff[self.object] then - return false -- mob has teleported through Nether portal - it's 99% not falling - end - end - - -- floating in water (or falling) - local v = self.object:get_velocity() - - if v.y > 0 then - - -- apply gravity when moving up - self.object:set_acceleration({ - x = 0, - y = -10, - z = 0 - }) - - elseif v.y <= 0 and v.y > self.fall_speed then - - -- fall downwards at set speed - self.object:set_acceleration({ - x = 0, - y = self.fall_speed, - z = 0 - }) - else - -- stop accelerating once max fall speed hit - self.object:set_acceleration({x = 0, y = 0, z = 0}) - end - - -- in water then float up - if minetest.registered_nodes[node_ok(pos).name].groups.water then - - if self.floats == 1 then - - self.object:set_acceleration({ - x = 0, - y = -self.fall_speed / (max(1, v.y) ^ 2), - z = 0 - }) - end - else - - -- fall damage onto solid ground - if self.fall_damage == 1 - and self.object:get_velocity().y == 0 then - - local d = (self.old_y or 0) - self.object:get_pos().y - - if d > 5 then - - local add = minetest.get_item_group(self.standing_on, "fall_damage_add_percent") - local damage = d - 5 - if add ~= 0 then - damage = damage + damage * (add/100) - end - damage = floor(damage) - if damage > 0 then - self.health = self.health - damage - - effect(pos, 5, "mcl_particles_smoke.png", 1, 2, 2, nil) - - if check_for_death(self, "fall", {type = "fall"}) then - return true - end - end - end - - self.old_y = self.object:get_pos().y - end - end -end - -local teleport = function(self, target) - if self.do_teleport then - if self.do_teleport(self, target) == false then - return - end - end -end - - --- deal damage and effects when mob punched -local mob_punch = function(self, hitter, tflp, tool_capabilities, dir) - - -- custom punch function - if self.do_punch then - - -- when false skip going any further - if self.do_punch(self, hitter, tflp, tool_capabilities, dir) == false then - return - end - end - - -- error checking when mod profiling is enabled - if not tool_capabilities then - minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") - return - end - - local is_player = hitter:is_player() - - 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 - - -- set/update 'drop xp' timestamp if hitted by player - self.xp_timestamp = minetest.get_us_time() - end - - - -- punch interval - local weapon = hitter:get_wielded_item() - local punch_interval = 1.4 - - -- exhaust attacker - if mod_hunger and is_player then - mcl_hunger.exhaust(hitter:get_player_name(), mcl_hunger.EXHAUST_ATTACK) - end - - -- calculate mob damage - local damage = 0 - local armor = self.object:get_armor_groups() or {} - local tmp - - -- quick error check incase it ends up 0 (serialize.h check test) - if tflp == 0 then - tflp = 0.2 - end - - if use_cmi then - damage = cmi.calculate_damage(self.object, hitter, tflp, tool_capabilities, dir) - else - - for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do - - tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) - - if tmp < 0 then - tmp = 0.0 - elseif tmp > 1 then - tmp = 1.0 - end - - damage = damage + (tool_capabilities.damage_groups[group] or 0) - * tmp * ((armor[group] or 0) / 100.0) - end - end - - if weapon then - local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") - if fire_aspect_level > 0 then - mcl_burning.set_on_fire(self.object, 4, fire_aspect_level * 2) - end - end - - -- check for tool immunity or special damage - for n = 1, #self.immune_to do - - if self.immune_to[n][1] == weapon:get_name() then - - damage = self.immune_to[n][2] or 0 - break - end - end - - -- healing - if damage <= -1 then - self.health = self.health - floor(damage) - return - end - - if use_cmi then - - local cancel = cmi.notify_punch(self.object, hitter, tflp, tool_capabilities, dir, damage) - - if cancel then return end - end - - if tool_capabilities then - punch_interval = tool_capabilities.full_punch_interval or 1.4 - end - - -- add weapon wear manually - -- Required because we have custom health handling ("health" property) - if minetest.is_creative_enabled("") ~= true - and tool_capabilities then - if tool_capabilities.punch_attack_uses then - -- Without this delay, the wear does not work. Quite hacky ... - minetest.after(0, function(name) - local player = minetest.get_player_by_name(name) - if not player then return end - local weapon = hitter:get_wielded_item(player) - local def = weapon:get_definition() - if def.tool_capabilities and def.tool_capabilities.punch_attack_uses then - local wear = floor(65535/tool_capabilities.punch_attack_uses) - weapon:add_wear(wear) - hitter:set_wielded_item(weapon) - end - end, hitter:get_player_name()) - end - end - - local die = false - - -- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately. - if damage >= 0.1 then - - -- weapon sounds - if weapon:get_definition().sounds ~= nil then - - local s = random(0, #weapon:get_definition().sounds) - - minetest.sound_play(weapon:get_definition().sounds[s], { - object = self.object, --hitter, - max_hear_distance = 8 - }, true) - else - minetest.sound_play("default_punch", { - object = self.object, - max_hear_distance = 5 - }, true) - end - - damage_effect(self, damage) - - -- do damage - self.health = self.health - damage - - -- skip future functions if dead, except alerting others - if check_for_death(self, "hit", {type = "punch", puncher = hitter}) then - die = true - end - - -- knock back effect (only on full punch) - if not die - and self.knock_back - and tflp >= punch_interval then - - local v = self.object:get_velocity() - local r = 1.4 - min(punch_interval, 1.4) - local kb = r * 2.0 - local up = 2 - - -- if already in air then dont go up anymore when hit - if v.y > 0 - or self.fly then - up = 0 - end - - -- direction error check - dir = dir or {x = 0, y = 0, z = 0} - - -- check if tool already has specific knockback value - if tool_capabilities.damage_groups["knockback"] then - kb = tool_capabilities.damage_groups["knockback"] - else - kb = kb * 1.5 - end - - - local luaentity - if hitter then - luaentity = hitter:get_luaentity() - 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 + luaentity._knockback - end - - self.object:set_velocity({ - x = dir.x * kb, - y = dir.y * kb + up * 2, - z = dir.z * kb - }) - - self.pause_timer = 0.25 - end - end -- END if damage - - -- if skittish then run away - if not die and self.runaway == true and self.state ~= "flop" then - - local lp = hitter:get_pos() - local s = self.object:get_pos() - local vec = { - x = lp.x - s.x, - y = lp.y - s.y, - z = lp.z - s.z - } - - local yaw = (atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate - - if lp.x > s.x then - yaw = yaw + pi - end - - yaw = set_yaw(self, yaw, 6) - self.state = "runaway" - self.runaway_timer = 0 - self.following = nil - end - - local name = hitter:get_player_name() or "" - - -- attack puncher and call other mobs for help - if self.passive == false - and self.state ~= "flop" - and (self.child == false or self.type == "monster") - and hitter:get_player_name() ~= self.owner - and not mobs.invis[ name ] then - - if not die then - -- attack whoever punched mob - self.state = "" - do_attack(self, hitter) - end - - -- alert others to the attack - local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range) - local obj = nil - - for n = 1, #objs do - - 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 - do_attack(obj, hitter) - elseif type(obj.group_attack) == "table" then - for i=1, #obj.group_attack do - if obj.name == obj.group_attack[i] then - do_attack(obj, hitter) - break - end - end - end - end - - -- have owned mobs attack player threat - if obj.owner == name and obj.owner_loyal then - do_attack(obj, self.object) - end - end - end - end -end - -local mob_detach_child = function(self, child) - - if self.driver == child then - self.driver = nil + for _,p in pairs(minetest.get_connected_players()) do + self:remove_particlespawners(p:get_player_name()) end -end - --- get entity staticdata -local mob_staticdata = function(self) - ---[[ -- remove mob when out of range unless tamed if remove_far - and self.can_despawn - and self.remove_ok - and ((not self.nametag) or (self.nametag == "")) + and self:despawn_allowed() and self.lifetimer <= 20 then + if spawn_logging then + minetest.log("action", "[mcl_mobs] Mob "..tostring(self.name).." despawns at "..minetest.pos_to_string(vector.round(self.object:get_pos())) .. " - out of range") + end - minetest.log("action", "Mob "..name.." despawns in mob_staticdata at "..minetest.pos_to_string(self.object.get_pos(), 1)) - mcl_burning.extinguish(self.object) - self.object:remove() - - return ""-- nil + return "remove"-- nil end ---]] - self.remove_ok = true + self.attack = nil self.following = nil self.state = "stand" - if use_cmi then - self.serialized_cmi_components = cmi.serialize_components(self._cmi_components) - end - local tmp = {} for _,stat in pairs(self) do @@ -3230,20 +111,34 @@ local mob_staticdata = function(self) return minetest.serialize(tmp) end +local function valid_texture(self, def_textures) + if not self.base_texture then + return false + end --- activate mob and reload settings -local mob_activate = function(self, staticdata, def, dtime) + if self.texture_selected then + if #def_textures < self.texture_selected then + self.texture_selected = nil + else + return true + end + end + return false +end - -- remove monsters in peaceful mode +function mob_class:mob_activate(staticdata, def, dtime) + if not self.object:get_pos() or staticdata == "remove" then + mcl_burning.extinguish(self.object) + self.object:remove() + return + end if self.type == "monster" and minetest.settings:get_bool("only_peaceful_mobs", false) then mcl_burning.extinguish(self.object) self.object:remove() - return end - -- load entity variables local tmp = minetest.deserialize(staticdata) if tmp then @@ -3252,46 +147,47 @@ local mob_activate = function(self, staticdata, def, dtime) end end - -- select random texture, set model and size - if not self.base_texture then + --If textures in definition change, reload textures + if not valid_texture(self, def.textures) then -- compatiblity with old simple mobs textures if type(def.textures[1]) == "string" then def.textures = {def.textures} end - self.base_texture = def.textures[random(1, #def.textures)] + if not self.texture_selected then + local c = 1 + if #def.textures > c then c = #def.textures end + self.texture_selected = math.random(c) + end + + self.base_texture = def.textures[self.texture_selected] self.base_mesh = def.mesh self.base_size = self.visual_size self.base_colbox = self.collisionbox self.base_selbox = self.selectionbox end - -- for current mobs that dont have this set if not self.base_selbox then self.base_selbox = self.selectionbox or self.base_colbox end - -- set texture, model and size local textures = self.base_texture local mesh = self.base_mesh local vis_size = self.base_size local colbox = self.base_colbox local selbox = self.base_selbox - -- specific texture if gotten if self.gotten == true and def.gotten_texture then textures = def.gotten_texture end - -- specific mesh if gotten if self.gotten == true and def.gotten_mesh then mesh = def.gotten_mesh end - -- set child objects to half size if self.child == true then vis_size = { @@ -3322,13 +218,12 @@ local mob_activate = function(self, staticdata, def, dtime) end if self.health == 0 then - self.health = random (self.hp_min, self.hp_max) + self.health = math.random (self.hp_min, self.hp_max) end if self.breath == nil then self.breath = self.breath_max end - -- pathfinding init self.path = {} self.path.way = {} -- path to follow, table of positions self.path.lastpos = {x = 0, y = 0, z = 0} @@ -3368,1217 +263,388 @@ local mob_activate = function(self, staticdata, def, dtime) self.blinktimer = 0 self.blinkstatus = false - -- check existing nametag if not self.nametag then self.nametag = def.nametag end - - -- set anything changed above - self.object:set_properties(self) - set_yaw(self, (random(0, 360) - 180) / 180 * pi, 6) - update_tag(self) - set_animation(self, "stand") - - -- run on_spawn function if found - if self.on_spawn and not self.on_spawn_run then - if self.on_spawn(self) then - self.on_spawn_run = true -- if true, set flag to run once only + if not self.custom_visual_size then + self.visual_size = nil + self.base_size = self.visual_size + if self.child then + self.visual_size = { + x = self.visual_size.x * 0.5, + y = self.visual_size.y * 0.5, + } end end - -- run after_activate + self.object:set_properties(self) + self:set_yaw( (math.random(0, 360) - 180) / 180 * math.pi, 6) + self:update_tag() + self._current_animation = nil + self:set_animation( "stand") + + + if self.riden_by_jock then --- Keep this function before self.on_spawn() is run. + self.object:remove() + return + end + + + if self.on_spawn and not self.on_spawn_run then + if self.on_spawn(self) then + self.on_spawn_run = true + end + end + + if not self.wears_armor and self.armor_list then + self.armor_list = nil + end + + if not self._run_armor_init and self.wears_armor then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + self:set_armor_texture() + self._run_armor_init = true + end + + + + if def.after_activate then def.after_activate(self, staticdata, def, dtime) end +end - if use_cmi then - self._cmi_components = cmi.activate_components(self.serialized_cmi_components) - cmi.notify_activate(self.object, dtime) +-- execute current state (stand, walk, run, attacks) +-- returns true if mob has died +function mob_class:do_states(dtime, player_in_active_range) + --if self.can_open_doors then check_doors(self) end + + -- knockback timer. set in on_punch + if self.pause_timer > 0 then + self.pause_timer = self.pause_timer - dtime + return + end + + self:env_danger_movement_checks(player_in_active_range) + + if self.state == PATHFINDING then + self:check_gowp(dtime) + elseif self.state == "attack" then + if self:do_states_attack(dtime) then + return true + end + else + if mcl_util.check_dtime_timer(self, dtime, "onstep_dostates", 1) then + if self.state == "stand" then + self:do_states_stand(player_in_active_range) + elseif self.state == "walk" then + self:do_states_walk() + elseif self.state == "runaway" then + self:do_states_runaway() + end + end end end +function mob_class:outside_limits() + local pos = self.object:get_pos() + if pos then + local posx = math.abs(pos.x) + local posy = math.abs(pos.y) + local posz = math.abs(pos.z) + if posx > MAPGEN_MOB_LIMIT or posy > MAPGEN_MOB_LIMIT or posz > MAPGEN_MOB_LIMIT then + --minetest.log("action", "Getting close to limits of worldgen: " .. minetest.pos_to_string(pos)) + if posx > MAPGEN_LIMIT or posy > MAPGEN_LIMIT or posz > MAPGEN_LIMIT then + minetest.log("action", "Warning mob past limits of worldgen: " .. minetest.pos_to_string(pos)) + else + if self.state ~= "stand" then + minetest.log("action", "Warning mob close to limits of worldgen: " .. minetest.pos_to_string(pos)) + self.state = "stand" + self:set_animation("stand") + self.object:set_acceleration(vector.zero()) + self.object:set_velocity(vector.zero()) + end + end + return true + end + end +end + + + +local function on_step_work (self, dtime) + local pos = self.object:get_pos() + if not pos then return end + + if self:check_despawn(pos, dtime) then return true end + if self:outside_limits() then return end + + -- Start: Death/damage processing + -- All damage needs to be undertaken at the start. We need to exit processing if the mob dies. + if self:check_death_and_slow_mob() then + --minetest.log("action", "Mob is dying: ".. tostring(self.name)) + -- Do we abandon out of here now? + end + + if self:falling(pos) then return end + if self:step_damage (dtime, pos) then return end + + if self.state == "die" then return end + -- End: Death/damage processing + + local player_in_active_range = self:player_in_active_range() + self:check_suspend(player_in_active_range) + + self:check_water_flow() + + if not self._jumping_cliff then + self._can_jump_cliff = self:can_jump_cliff() + else + self._can_jump_cliff = false + end + + self:flop() + + self:check_smooth_rotation(dtime) + + if player_in_active_range then + self:set_animation_speed() -- set animation speed relative to velocity + + self:check_head_swivel(dtime) + + if mcl_util.check_dtime_timer(self, dtime, "onstep_engage", 0.2) then + self:check_follow() + self:check_runaway_from() + self:monster_attack() + self:npc_attack() + end + + self:check_herd(dtime) + + if self.jump_sound_cooloff > 0 then self.jump_sound_cooloff = self.jump_sound_cooloff - dtime end + self:do_jump() + end + + if mcl_util.check_dtime_timer(self, dtime, "onstep_occassional", 1) then + + if player_in_active_range then + self:check_item_pickup() + self:set_armor_texture() + self:step_opinion_sound(dtime) + end + + self:check_breeding() + end + + self:check_aggro(dtime) + + self:check_particlespawners(dtime) + + if self.do_custom and self.do_custom(self, dtime) == false then return end + + if self:do_states(dtime, player_in_active_range) then return end + + if mobs_debug then self:update_tag() end + + if not self.object:get_luaentity() then + return false + end +end + +local last_crash_warn_time = 0 + +local function log_error (stack_trace, info, info2) + minetest.log("action", "--- Bug report start (please provide a few lines before this also for context) ---") + minetest.log("action", "Error: " .. stack_trace) + minetest.log("action", "Bug info: " .. info) + if info2 then + minetest.log("action", "Bug info additional: " .. info2) + end + minetest.log("action", "--- Bug report end ---") +end + +local function warn_user_error () + local current_time = os.time() + local time_since_warning = current_time - last_crash_warn_time + + --minetest.log("previous_crash_time: " .. current_time) + --minetest.log("last_crash_time: " .. last_crash_warn_time) + --minetest.log("time_since_warning: " .. time_since_warning) + + 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)") + end +end + +local on_step_error_handler = function () + warn_user_error () + local info = debug.getinfo(1, "SnlufL") + log_error(tostring(debug.traceback()), dump(info)) +end + + -- main mob function -local mob_step = function(self, dtime) - - if not self.fire_resistant then - mcl_burning.tick(self.object, dtime) - end - - if use_cmi then - cmi.notify_step(self.object, dtime) - end - - local pos = self.object:get_pos() - local yaw = 0 - - if mobs_debug then - update_tag(self) - end - - if self.state == "die" then - return - end - - if self.jump_sound_cooloff > 0 then - self.jump_sound_cooloff = self.jump_sound_cooloff - dtime - end - if self.opinion_sound_cooloff > 0 then - self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime - end - if falling(self, pos) then - -- Return if mob died after falling - return - end - - -- smooth rotation by ThomasMonroe314 - - if self.delay and self.delay > 0 then - - local yaw = self.object:get_yaw() or 0 - - if self.delay == 1 then - yaw = self.target_yaw +function mob_class:on_step(dtime) + if not DEVELOPMENT then + -- Removed as bundled Lua (5.1 doesn't support xpcall) + --local status, retVal = xpcall(on_step_work, on_step_error_handler, self, dtime) + local status, retVal = pcall(on_step_work, self, dtime) + if status then + return retVal else - local dif = abs(yaw - self.target_yaw) - - if yaw > self.target_yaw then - - if dif > pi then - dif = 2 * pi - dif -- need to add - yaw = yaw + dif / self.delay - else - yaw = yaw - dif / self.delay -- need to subtract - end - - elseif yaw < self.target_yaw then - - if dif > pi then - dif = 2 * pi - dif - yaw = yaw - dif / self.delay -- need to subtract - else - yaw = yaw + dif / self.delay -- need to add - end - end - - if yaw > (pi * 2) then yaw = yaw - (pi * 2) end - if yaw < 0 then yaw = yaw + (pi * 2) end - end - - self.delay = self.delay - 1 - if self.shaking then - yaw = yaw + (math.random() * 2 - 1) * 5 * dtime - end - self.object:set_yaw(yaw) - end - - -- end rotation - - -- knockback timer - if self.pause_timer > 0 then - - self.pause_timer = self.pause_timer - dtime - - return - end - - -- run custom function (defined in mob lua file) - if self.do_custom then - - -- when false skip going any further - if self.do_custom(self, dtime) == false then - return - end - end - - -- attack timer - self.timer = self.timer + dtime - - if self.state ~= "attack" then - - if self.timer < 1 then - return - end - - self.timer = 0 - end - - -- never go over 100 - if self.timer > 100 then - self.timer = 1 - end - - -- mob plays random sound at times - if random(1, 100) == 1 then - mob_sound(self, "random", true) - end - - -- environmental damage timer (every 1 second) - self.env_damage_timer = self.env_damage_timer + dtime - - if (self.state == "attack" and self.env_damage_timer > 1) - or self.state ~= "attack" then - - self.env_damage_timer = 0 - - -- check for environmental damage (water, fire, lava etc.) - if do_env_damage(self) then - return - end - - -- node replace check (cow eats grass etc.) - replace(self, pos) - end - - monster_attack(self) - - npc_attack(self) - - breed(self) - - if do_states(self, dtime) then - return - end - - do_jump(self) - - runaway_from(self) - - if is_at_water_danger(self) and self.state ~= "attack" then - if random(1, 10) <= 6 then - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - yaw = yaw + random(-0.5, 0.5) - yaw = set_yaw(self, yaw, 8) - end - end - - -- Add water flowing for mobs from mcl_item_entity - local p, node, nn, def - p = self.object:get_pos() - node = minetest.get_node_or_nil(p) - if node then - nn = node.name - def = minetest.registered_nodes[nn] - end - - -- Move item around on flowing liquids - if def and def.liquidtype == "flowing" then - - --[[ Get flowing direction (function call from flowlib), if there's a liquid. - NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. - Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] - local vec = flowlib.quick_flow(p, node) - -- Just to make sure we don't manipulate the speed for no reason - if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then - -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" - local f = 1.39 - -- Set new item moving speed into the direciton of the liquid - local newv = vector.multiply(vec, f) - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z}) - - self.physical_state = true - self._flowing = true - self.object:set_properties({ - physical = true - }) - return - end - elseif self._flowing == true then - -- Disable flowing physics if not on/in flowing liquid - self._flowing = false - enable_physics(self.object, self, true) - return - end - - --Mob following code. - follow_flop(self) - - if is_at_cliff_or_danger(self) then - set_velocity(self, 0) - self.state = "stand" - set_animation(self, "stand") - local yaw = self.object:get_yaw() or 0 - yaw = set_yaw(self, yaw + 0.78, 8) - end - - -- Despawning: when lifetimer expires, remove mob - if remove_far - and self.can_despawn == true - and ((not self.nametag) or (self.nametag == "")) - and self.state ~= "attack" - and self.following == nil then - - self.lifetimer = self.lifetimer - dtime - if self.despawn_immediately or self.lifetimer <= 0 then - minetest.log("action", "Mob "..self.name.." despawns in mob_step at "..minetest.pos_to_string(pos, 1)) - mcl_burning.extinguish(self.object) - self.object:remove() - elseif self.lifetimer <= 10 then - if math.random(10) < 4 then - self.despawn_immediately = true - else - self.lifetimer = 20 - end - end - end -end - - --- default function when mobs are blown up with TNT -local do_tnt = function(obj, damage) - - obj.object:punch(obj.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, nil) - - return false, true, {} -end - - -mobs.spawning_mobs = {} - --- Code to execute before custom on_rightclick handling -local on_rightclick_prefix = function(self, clicker) - local item = clicker:get_wielded_item() - - -- Name mob with nametag - if not self.ignores_nametag and item:get_name() == "mcl_mobs:nametag" then - - local tag = item:get_meta():get_string("name") - if tag ~= "" then - if string.len(tag) > MAX_MOB_NAME_LENGTH then - tag = string.sub(tag, 1, MAX_MOB_NAME_LENGTH) - end - self.nametag = tag - - update_tag(self) - - if not mobs.is_creative(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - return true - end - - end - return false -end - -local create_mob_on_rightclick = function(on_rightclick) - return function(self, clicker) - local stop = on_rightclick_prefix(self, clicker) - if (not stop) and (on_rightclick) then - on_rightclick(self, clicker) - end - end -end - --- register mob entity -function mobs:register_mob(name, def) - - mobs.spawning_mobs[name] = true - -local can_despawn -if def.can_despawn ~= nil then - can_despawn = def.can_despawn -else - can_despawn = true -end - -local function scale_difficulty(value, default, min, special) - if (not value) or (value == default) or (value == special) then - return default - else - return max(min, value * difficulty) - end -end - -local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25} --- Workaround for : --- Increase upper Y limit to avoid mobs glitching through solid nodes. --- FIXME: Remove workaround if it's no longer needed. -if collisionbox[5] < 0.79 then - collisionbox[5] = 0.79 -end - -minetest.register_entity(name, { - - stepheight = def.stepheight or 0.6, - name = name, - type = def.type, - attack_type = def.attack_type, - fly = def.fly, - fly_in = def.fly_in or {"air", "__airlike"}, - owner = def.owner or "", - order = def.order or "", - on_die = def.on_die, - spawn_small_alternative = def.spawn_small_alternative, - do_custom = def.do_custom, - jump_height = def.jump_height or 4, -- was 6 - rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2 - lifetimer = def.lifetimer or 57.73, - hp_min = scale_difficulty(def.hp_min, 5, 1), - hp_max = scale_difficulty(def.hp_max, 10, 1), - xp_min = def.xp_min or 0, - xp_max = def.xp_max or 0, - xp_timestamp = 0, - breath_max = def.breath_max or 15, - breathes_in_water = def.breathes_in_water or false, - physical = true, - collisionbox = collisionbox, - selectionbox = def.selectionbox or def.collisionbox, - visual = def.visual, - visual_size = def.visual_size or {x = 1, y = 1}, - mesh = def.mesh, - makes_footstep_sound = def.makes_footstep_sound or false, - view_range = def.view_range or 16, - walk_velocity = def.walk_velocity or 1, - run_velocity = def.run_velocity or 2, - damage = scale_difficulty(def.damage, 0, 0), - light_damage = def.light_damage or 0, - sunlight_damage = def.sunlight_damage or 0, - water_damage = def.water_damage or 0, - lava_damage = def.lava_damage or 8, - fire_damage = def.fire_damage or 1, - suffocation = def.suffocation or true, - fall_damage = def.fall_damage or 1, - fall_speed = def.fall_speed or DEFAULT_FALL_SPEED, -- must be lower than -2 - drops = def.drops or {}, - armor = def.armor or 100, - on_rightclick = create_mob_on_rightclick(def.on_rightclick), - arrow = def.arrow, - shoot_interval = def.shoot_interval, - sounds = def.sounds or {}, - animation = def.animation, - follow = def.follow, - jump = def.jump ~= false, - walk_chance = def.walk_chance or 50, - attacks_monsters = def.attacks_monsters or false, - group_attack = def.group_attack or false, - passive = def.passive or false, - knock_back = def.knock_back ~= false, - shoot_offset = def.shoot_offset or 0, - floats = def.floats or 1, -- floats in water by default - replace_rate = def.replace_rate, - replace_what = def.replace_what, - replace_with = def.replace_with, - replace_offset = def.replace_offset or 0, - on_replace = def.on_replace, - timer = 0, - env_damage_timer = 0, - tamed = false, - pause_timer = 0, - horny = false, - hornytimer = 0, - gotten = false, - health = 0, - reach = def.reach or 3, - htimer = 0, - texture_list = def.textures, - child_texture = def.child_texture, - docile_by_day = def.docile_by_day or false, - time_of_day = 0.5, - fear_height = def.fear_height or 0, - runaway = def.runaway, - runaway_timer = 0, - pathfinding = def.pathfinding, - immune_to = def.immune_to or {}, - explosion_radius = def.explosion_radius, -- LEGACY - explosion_damage_radius = def.explosion_damage_radius, -- LEGACY - explosion_timer = def.explosion_timer or 3, - allow_fuse_reset = def.allow_fuse_reset ~= false, - stop_to_explode = def.stop_to_explode ~= false, - custom_attack = def.custom_attack, - double_melee_attack = def.double_melee_attack, - dogshoot_switch = def.dogshoot_switch, - dogshoot_count = 0, - dogshoot_count_max = def.dogshoot_count_max or 5, - dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5), - attack_animals = def.attack_animals or false, - specific_attack = def.specific_attack, - runaway_from = def.runaway_from, - owner_loyal = def.owner_loyal, - facing_fence = false, - _cmi_is_mob = true, - pushable = def.pushable or true, - - - -- MCL2 extensions - teleport = teleport, - do_teleport = def.do_teleport, - spawn_class = def.spawn_class, - ignores_nametag = def.ignores_nametag or false, - rain_damage = def.rain_damage or 0, - glow = def.glow, - can_despawn = can_despawn, - child = def.child or false, - texture_mods = {}, - shoot_arrow = def.shoot_arrow, - sounds_child = def.sounds_child, - explosion_strength = def.explosion_strength, - suffocation_timer = 0, - follow_velocity = def.follow_velocity or 2.4, - instant_death = def.instant_death or false, - fire_resistant = def.fire_resistant or false, - fire_damage_resistant = def.fire_damage_resistant or false, - ignited_by_sunlight = def.ignited_by_sunlight or false, - -- End of MCL2 extensions - - on_spawn = def.on_spawn, - - on_blast = def.on_blast or do_tnt, - - on_step = mob_step, - - do_punch = def.do_punch, - - on_punch = mob_punch, - - on_breed = def.on_breed, - - on_grown = def.on_grown, - - on_detach_child = mob_detach_child, - - on_activate = function(self, staticdata, dtime) - return mob_activate(self, staticdata, def, dtime) - end, - - get_staticdata = function(self) - return mob_staticdata(self) - end, - - harmed_by_heal = def.harmed_by_heal, - -}) - -if minetest.get_modpath("doc_identifier") ~= nil then - doc.sub.identifier.register_object(name, "basics", "mobs") -end - -end -- END mobs:register_mob function - - --- count how many mobs of one type are inside an area -local count_mobs = function(pos, mobtype) - - local num = 0 - local objs = minetest.get_objects_inside_radius(pos, aoc_range) - - for n = 1, #objs do - - local obj = objs[n]:get_luaentity() - - if obj and obj.name and obj._cmi_is_mob then - - -- count passive mobs only - if mobtype == "!passive" then - if obj.spawn_class == "passive" then - num = num + 1 - end - -- count hostile mobs only - elseif mobtype == "!hostile" then - if obj.spawn_class == "hostile" then - num = num + 1 - end - -- count ambient mobs only - elseif mobtype == "!ambient" then - if obj.spawn_class == "ambient" then - num = num + 1 - end - -- count water mobs only - elseif mobtype == "!water" then - if obj.spawn_class == "water" then - num = num + 1 - end - -- count mob type - elseif mobtype and obj.name == mobtype then - num = num + 1 - -- count total mobs - elseif not mobtype then - num = num + 1 - end - end - end - - return num -end - - --- global functions - -function mobs:spawn_abm_check(pos, node, name) - -- global function to add additional spawn checks - -- return true to stop spawning mob -end - - -function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, - interval, chance, aoc, min_height, max_height, day_toggle, on_spawn) - - -- Do mobs spawn at all? - if not mobs_spawn then - return - end - - -- chance/spawn number override in minetest.conf for registered mob - local numbers = minetest.settings:get(name) - - if numbers then - numbers = numbers:split(",") - chance = tonumber(numbers[1]) or chance - aoc = tonumber(numbers[2]) or aoc - - if chance == 0 then - minetest.log("warning", string.format("[mobs] %s has spawning disabled", name)) - return - end - - minetest.log("action", - string.format("[mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) - - end - - local spawn_action - spawn_action = function(pos, node, active_object_count, active_object_count_wider, name) - - local orig_pos = table.copy(pos) - -- is mob actually registered? - if not mobs.spawning_mobs[name] - or not minetest.registered_entities[name] then - minetest.log("warning", "Mob spawn of "..name.." failed, unknown entity or mob is not registered for spawning!") - return - end - - -- additional custom checks for spawning mob - if mobs:spawn_abm_check(pos, node, name) == true then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, ABM check rejected!") - return - end - - -- count nearby mobs in same spawn class - local entdef = minetest.registered_entities[name] - local spawn_class = entdef and entdef.spawn_class - if not spawn_class then - if entdef.type == "monster" then - spawn_class = "hostile" - else - spawn_class = "passive" - end - end - local in_class_cap = count_mobs(pos, "!"..spawn_class) < MOB_CAP[spawn_class] - -- do not spawn if too many of same mob in area - if active_object_count_wider >= max_per_block -- large-range mob cap - or (not in_class_cap) -- spawn class mob cap - or count_mobs(pos, name) >= aoc then -- per-mob mob cap - -- too many entities - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too crowded!") - return - end - - -- if toggle set to nil then ignore day/night check - if day_toggle ~= nil then - - local tod = (minetest.get_timeofday() or 0) * 24000 - - if tod > 4500 and tod < 19500 then - -- daylight, but mob wants night - if day_toggle == false then - -- mob needs night - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs light!") - return - end - else - -- night time but mob wants day - if day_toggle == true then - -- mob needs day - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, mob needs daylight!") - return - end - end - end - - -- spawn above node - pos.y = pos.y + 1 - - -- only spawn away from player - local objs = minetest.get_objects_inside_radius(pos, 24) - - for n = 1, #objs do - - if objs[n]:is_player() then - -- player too close - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, player too close!") - return - end - end - - -- mobs cannot spawn in protected areas when enabled - if not spawn_protected - and minetest.is_protected(pos, "") then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, position is protected!") - return - end - - -- are we spawning within height limits? - if pos.y > max_height - or pos.y < min_height then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, out of height limit!") - return - end - - -- are light levels ok? - local light = minetest.get_node_light(pos) - if not light - or light > max_light - or light < min_light then - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, bad light!") - return - end - - -- do we have enough space to spawn mob? - local ent = minetest.registered_entities[name] - local width_x = max(1, math.ceil(ent.collisionbox[4] - ent.collisionbox[1])) - local min_x, max_x - if width_x % 2 == 0 then - max_x = math.floor(width_x/2) - min_x = -(max_x-1) - else - max_x = math.floor(width_x/2) - min_x = -max_x - end - - local width_z = max(1, math.ceil(ent.collisionbox[6] - ent.collisionbox[3])) - local min_z, max_z - if width_z % 2 == 0 then - max_z = math.floor(width_z/2) - min_z = -(max_z-1) - else - max_z = math.floor(width_z/2) - min_z = -max_z - end - - local max_y = max(0, math.ceil(ent.collisionbox[5] - ent.collisionbox[2]) - 1) - - for y = 0, max_y do - for x = min_x, max_x do - for z = min_z, max_z do - local pos2 = {x = pos.x+x, y = pos.y+y, z = pos.z+z} - if minetest.registered_nodes[node_ok(pos2).name].walkable == true then - -- inside block - minetest.log("info", "Mob spawn of "..name.." at "..minetest.pos_to_string(pos).." failed, too little space!") - if ent.spawn_small_alternative ~= nil and (not minetest.registered_nodes[node_ok(pos).name].walkable) then - minetest.log("info", "Trying to spawn smaller alternative mob: "..ent.spawn_small_alternative) - spawn_action(orig_pos, node, active_object_count, active_object_count_wider, ent.spawn_small_alternative) - end - return - end - end - end - end - - -- tweak X/Y/Z spawn pos - if width_x % 2 == 0 then - pos.x = pos.x + 0.5 - end - if width_z % 2 == 0 then - pos.z = pos.z + 0.5 - end - pos.y = pos.y - 0.5 - - local mob = minetest.add_entity(pos, name) - minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) - - if on_spawn then - - local ent = mob:get_luaentity() - - on_spawn(ent, pos) - end - end - - local function spawn_abm_action(pos, node, active_object_count, active_object_count_wider) - spawn_action(pos, node, active_object_count, active_object_count_wider, name) - end - - minetest.register_abm({ - label = name .. " spawning", - nodenames = nodes, - neighbors = neighbors, - interval = interval, - chance = floor(max(1, chance * mobs_spawn_chance)), - catch_up = false, - action = spawn_abm_action, - }) -end - - --- compatibility with older mob registration -function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, day_toggle) - - mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, - chance, active_object_count, -31000, max_height, day_toggle) -end - - --- MarkBu's spawn function -function mobs:spawn(def) - - local name = def.name - local nodes = def.nodes or {"group:soil", "group:stone"} - local neighbors = def.neighbors or {"air"} - local min_light = def.min_light or 0 - local max_light = def.max_light or 15 - local interval = def.interval or 30 - local chance = def.chance or 5000 - local active_object_count = def.active_object_count or 1 - local min_height = def.min_height or -31000 - local max_height = def.max_height or 31000 - local day_toggle = def.day_toggle - local on_spawn = def.on_spawn - - mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) -end - - --- register arrow for shoot attack -function mobs:register_arrow(name, def) - - if not name or not def then return end -- errorcheck - - minetest.register_entity(name, { - - physical = false, - visual = def.visual, - visual_size = def.visual_size, - textures = def.textures, - velocity = def.velocity, - hit_player = def.hit_player, - hit_node = def.hit_node, - hit_mob = def.hit_mob, - hit_object = def.hit_object, - 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, - owner_id = def.owner_id, - rotate = def.rotate, - automatic_face_movement_dir = def.rotate - and (def.rotate - (pi / 180)) or false, - - on_activate = def.on_activate, - - on_step = def.on_step or function(self, dtime) - - self.timer = self.timer + 1 - + warn_user_error () local pos = self.object:get_pos() - - if self.switch == 0 - or self.timer > 150 - or not within_limits(pos, 0) then - mcl_burning.extinguish(self.object) - self.object:remove(); - - return - end - - -- does arrow have a tail (fireball) - if def.tail - and def.tail == 1 - and def.tail_texture then - - minetest.add_particle({ - pos = pos, - velocity = {x = 0, y = 0, z = 0}, - acceleration = {x = 0, y = 0, z = 0}, - expirationtime = def.expire or 0.25, - collisiondetection = false, - texture = def.tail_texture, - size = def.tail_size or 5, - glow = def.glow or 0, - }) - end - - if self.hit_node then - - local node = node_ok(pos).name - - if minetest.registered_nodes[node].walkable then - - self.hit_node(self, pos, node) - - if self.drop == true then - - pos.y = pos.y + 1 - - self.lastpos = (self.lastpos or pos) - - minetest.add_item(self.lastpos, self.object:get_luaentity().name) - end - - self.object:remove(); - - return + if pos then + local node = minetest.get_node(pos) + if node and node.name == "ignore" then + minetest.log("warning", "Pos is ignored: " .. dump(pos)) 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.0)) do - - if self.hit_player - and player:is_player() then - - self.hit_player(self, player) - self.object:remove(); - return - end - - local entity = player:get_luaentity() - - if entity - and self.hit_mob - and entity._cmi_is_mob == true - and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_mob(self, player) - self.object:remove(); - return - end - - if entity - and self.hit_object - and (not entity._cmi_is_mob) - and tostring(player) ~= self.owner_id - and entity.name ~= self.object:get_luaentity().name then - self.hit_object(self, player) - self.object:remove(); - return - end - end - end - - self.lastpos = pos - end - }) -end - - --- no damage to nodes explosion -function mobs:safe_boom(self, pos, strength) - minetest.sound_play(self.sounds and self.sounds.explode or "tnt_explode", { - pos = pos, - gain = 1.0, - max_hear_distance = self.sounds and self.sounds.distance or 32 - }, true) - local radius = strength - entity_physics(pos, radius) - effect(pos, 32, "mcl_particles_smoke.png", radius * 3, radius * 5, radius, 1, 0) -end - - --- make explosion with protection and tnt mod check -function mobs:boom(self, pos, strength, fire) - - if mod_explosions then - if mobs_griefing and not minetest.is_protected(pos, "") then - mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) - else - mobs:safe_boom(self, pos, strength) + log_error (dump(retVal), dump(pos), dump(self)) end else - mobs:safe_boom(self, pos, strength) + return on_step_work (self, dtime) end end - --- Register spawn eggs - --- Note: This also introduces the “spawn_egg” group: --- * spawn_egg=1: Spawn egg (generic mob, no metadata) --- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata) -function mobs:register_egg(mob, desc, background, addegg, no_creative) - - local grp = {spawn_egg = 1} - - -- do NOT add this egg to creative inventory (e.g. dungeon master) - if no_creative == true then - grp.not_in_creative_inventory = 1 - end - - local invimg = background - - if addegg == 1 then - invimg = "mobs_chicken_egg.png^(" .. invimg .. - "^[mask:mobs_chicken_egg_overlay.png)" - end - - -- register old stackable mob egg - minetest.register_craftitem(mob, { - - description = desc, - inventory_image = invimg, - groups = grp, - - _doc_items_longdesc = S("This allows you to place a single mob."), - _doc_items_usagehelp = S("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."), - - on_place = function(itemstack, placer, pointed_thing) - - local pos = pointed_thing.above - - -- am I clicking on something with existing on_rightclick function? - local under = minetest.get_node(pointed_thing.under) - local def = minetest.registered_nodes[under.name] - if def and def.on_rightclick then - return def.on_rightclick(pointed_thing.under, under, placer, itemstack) - end - - if pos - and within_limits(pos, 0) - and not minetest.is_protected(pos, placer:get_player_name()) then - - local name = placer:get_player_name() - local privs = minetest.get_player_privs(name) - if mod_mobspawners and under.name == "mcl_mobspawners:spawner" then - if minetest.is_protected(pointed_thing.under, name) then - minetest.record_protection_violation(pointed_thing.under, name) - return itemstack - end - if not privs.maphack then - minetest.chat_send_player(name, S("You need the “maphack” privilege to change the mob spawner.")) - return itemstack - end - mcl_mobspawners.setup_spawner(pointed_thing.under, itemstack:get_name()) - if not mobs.is_creative(name) then - itemstack:take_item() - end - return itemstack - end - - if not minetest.registered_entities[mob] then - return itemstack - end - - if minetest.settings:get_bool("only_peaceful_mobs", false) - and minetest.registered_entities[mob].type == "monster" then - minetest.chat_send_player(name, S("Only peaceful mobs allowed!")) - return itemstack - end - - pos.y = pos.y - 0.5 - - local mob = minetest.add_entity(pos, mob) - minetest.log("action", "Mob spawned: "..name.." at "..minetest.pos_to_string(pos)) - local ent = mob:get_luaentity() - - -- don't set owner if monster or sneak pressed - if ent.type ~= "monster" - and not placer:get_player_control().sneak then - ent.owner = placer:get_player_name() - ent.tamed = true - end - - -- set nametag - local nametag = itemstack:get_meta():get_string("name") - if nametag ~= "" then - if string.len(nametag) > MAX_MOB_NAME_LENGTH then - nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH) - end - ent.nametag = nametag - update_tag(ent) - end - - -- if not in creative then take item - if not mobs.is_creative(placer:get_player_name()) then - itemstack:take_item() - end - end - - return itemstack - end, - }) - -end - - --- No-op in MCL2 (capturing mobs is not possible). --- Provided for compability with Mobs Redo -function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) - return false -end - - --- No-op in MCL2 (protecting mobs is not possible). -function mobs:protect(self, clicker) - return false -end - - --- feeding, taming and breeding (thanks blert2112) -function mobs:feed_tame(self, clicker, feed_count, breed, tame) - if not self.follow then - return false - end - - -- can eat/tame with item in hand - if follow_holding(self, clicker) then - - -- if not in creative then take item - if not mobs.is_creative(clicker:get_player_name()) then - - local item = clicker:get_wielded_item() - - item:take_item() - - clicker:set_wielded_item(item) - end - - mob_sound(self, "eat", nil, true) - - -- increase health - self.health = self.health + 4 - - if self.health >= self.hp_max then - - self.health = self.hp_max - - if self.htimer < 1 then - self.htimer = 5 - end - end - - self.object:set_hp(self.health) - - update_tag(self) - - -- make children grow quicker - if self.child == true then - - -- deduct 10% of the time to adulthood - self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1) - - return true - end - - -- feed and tame - self.food = (self.food or 0) + 1 - if self.food >= feed_count then - - self.food = 0 - - if breed and self.hornytimer == 0 then - self.horny = true - end - - if tame then - - self.tamed = true - - if not self.owner or self.owner == "" then - self.owner = clicker:get_player_name() - end - end - - -- make sound when fed so many times - mob_sound(self, "random", true) - end - - return true - end - - return false -end - --- Spawn a child -function mobs:spawn_child(pos, mob_type) - local child = minetest.add_entity(pos, mob_type) - if not child then - return - end - - local ent = child:get_luaentity() - effect(pos, 15, "mcl_particles_smoke.png", 1, 2, 2, 15, 5) - - ent.child = true - - local textures - -- using specific child texture (if found) - if ent.child_texture then - textures = ent.child_texture[1] - end - - -- and resize to half height - child:set_properties({ - textures = textures, - visual_size = { - x = ent.base_size.x * .5, - y = ent.base_size.y * .5, - }, - collisionbox = { - ent.base_colbox[1] * .5, - ent.base_colbox[2] * .5, - ent.base_colbox[3] * .5, - ent.base_colbox[4] * .5, - ent.base_colbox[5] * .5, - ent.base_colbox[6] * .5, - }, - selectionbox = { - ent.base_selbox[1] * .5, - ent.base_selbox[2] * .5, - ent.base_selbox[3] * .5, - ent.base_selbox[4] * .5, - ent.base_selbox[5] * .5, - ent.base_selbox[6] * .5, - }, - }) - - return child -end - - --- compatibility function for old entities to new modpack entities -function mobs:alias_mob(old_name, new_name) - - -- spawn egg - minetest.register_alias(old_name, new_name) - - -- entity - minetest.register_entity(":" .. old_name, { - - physical = false, - - on_step = function(self) - - if minetest.registered_entities[new_name] then - minetest.add_entity(self.object:get_pos(), new_name) - end - - self.object:remove() - end - }) - -end - local timer = 0 -minetest.register_globalstep(function(dtime) + +local function update_lifetimer(dtime) timer = timer + dtime if timer < 1 then return end - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(minetest.get_connected_players()) do local pos = player:get_pos() - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 47)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, LIFETIMER_DISTANCE)) do local lua = obj:get_luaentity() - if lua and lua._cmi_is_mob then + if lua and lua.is_mob then lua.lifetimer = math.max(20, lua.lifetimer) lua.despawn_immediately = false end end end timer = 0 +end + +minetest.register_globalstep(function(dtime) + update_lifetimer(dtime) end) + + +minetest.register_chatcommand("clearmobs", { + privs = { maphack = true }, + params = "[all|monster|passive| [|nametagged|tamed]]", + description = S("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."), + func = function(player, param) + local default = false + if not param or param == "" then + default = true + minetest.chat_send_player(player, + S("Default usage. Clearing hostile mobs. For more options please type: /help clearmobs")) + end + local mob, unsafe = param:match("^([%w]+)[ ]?([%w%d]*)$") + + local all = false + local nametagged = false + local tamed = false + + local mob_name, mob_type, range + + -- Param 1 resolve + if mob and mob ~= "" then + if mob == "all" then + all = true + elseif mob == "passive" or mob == "monster" then + mob_type = mob + elseif mob then + mob_name = mob + end + --minetest.log ("mob: [" .. mob .. "]") + else + --minetest.log("No valid first param") + if default then + --minetest.log("Use default") + mob_type = "monster" + end + --return + end + + -- Param 2 resolve + if unsafe and unsafe ~= "" then + --minetest.log ("unsafe: [" .. unsafe .. "]") + if unsafe == "nametagged" then + nametagged = true + elseif unsafe == "tamed" then + tamed = true + end + + local num = tonumber(unsafe) + if num then range = num end + end + + local p = minetest.get_player_by_name(player) + + for _,o in pairs(minetest.luaentities) do + if o and o.is_mob then + local mob_match = false + + if all then + --minetest.log("Match - All mobs specified") + mob_match = true + elseif mob_type then + + --minetest.log("Match - o.type: ".. tostring(o.type)) + --minetest.log("mob_type: ".. tostring(mob_type)) + if mob_type == "monster" and o.type == mob_type then + --minetest.log("Match - monster") + mob_match = true + elseif mob_type == "passive" and o.type ~= "monster" and o.type ~= "npc" then + --minetest.log("Match - passive") + mob_match = true + else + --minetest.log("No match for type.") + end + + elseif mob_name and (o.name == mob_name or string.find(o.name, mob_name)) then + --minetest.log("Match - mob_name = ".. tostring(o.name)) + mob_match = true + else + --minetest.log("No match - o.type = ".. tostring(o.type)) + --minetest.log("No match - mob_name = ".. tostring(o.name)) + --minetest.log("No match - mob_type = ".. tostring(mob_name)) + end + + if mob_match then + local in_range = true + if (not range or range <= 0 ) then + in_range = true + else + if ( vector.distance(p:get_pos(),o.object:get_pos()) <= range ) then + in_range = true + else + --minetest.log("Out of range") + in_range = false + end + end + + --minetest.log("o.nametag: ".. tostring(o.nametag)) + + if nametagged then + if o.nametag then + --minetest.log("Namedtagged and it has a name tag. Kill it") + o.object:remove() + end + elseif tamed then + if o.tamed then + --minetest.log("Tamed. Kill it") + o.object:remove() + end + elseif in_range and (not o.nametag or o.nametag == "") and not o.tamed then + --minetest.log("No nametag or tamed. Kill it") + o.object:remove() + end + end + end + end +end}) diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index ee97489b5..fe0da4be2 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -12,246 +12,259 @@ Registering Mobs To register a mob and have it ready for use requires the following function: - mobs:register_mob(name, definition) + mobs:register_mob(name, definition) The 'name' of a mob usually starts with the mod name it's running from followed by it's own name e.g. - "mobs_monster:sand_monster" or "mymod:totally_awesome_beast" + "mobs_monster:sand_monster" or "mymod:totally_awesome_beast" ... and the 'definition' is a table which holds all of the settings and functions needed for the mob to work properly which contains the following: - 'nametag' contains the name which is shown above mob. - 'type' holds the type of mob that inhabits your world e.g. - "animal" usually docile and walking around. - "monster" attacks player or npc on sight. - "npc" walk around and will defend themselves if hit first, they - kill monsters. - 'hp_min' the minimum health value the mob can spawn with. - 'hp_max' the maximum health value the mob can spawn with. - 'breath_max' The maximum breath value the mob can spawn with and can have. - If -1 (default), mob does not take drowning damage. - 'breathes_in_water' If true, mob loses breath when not in water. Otherwise, - mob loses breath when inside a node with `drowning` attribute - set (default: false). - 'armor' entity armor groups (see lua_api.txt). If table, a list of - armor groups like for entities. If number, set value of - 'fleshy' armor group only. - Note: The 'immortal=1' armor group will automatically be added - since this mod handles health and damage manually. - Default: 100 (mob will take full dmg from 'fleshy' hits) - 'passive' when true allows animals to defend themselves when hit, - otherwise they amble onwards. - 'walk_velocity' is the speed that your mob can walk around. - 'run_velocity' is the speed your mob can run with, usually when attacking. - 'walk_chance' has a 0-100 chance value your mob will walk from standing, - set to 0 for jumping mobs only. - 'jump' when true allows your mob to jump updwards. - 'jump_height' holds the height your mob can jump, 0 to disable jumping. - 'stepheight' height of a block that your mob can easily walk up onto, - defaults to 0.6. - 'fly' when true allows your mob to fly around instead of walking. - 'fly_in' holds the node name or a table of node names in which the - mob flies (or swims) around in. The special name - '__airlike' stands for all nodes with 'walkable=false' - that are not liquids - 'runaway' if true causes animals to turn and run away when hit. - 'view_range' how many nodes in distance the mob can see a player. - 'damage' how many health points the mob does to a player or another - mob when melee attacking. - 'knock_back' when true has mobs falling backwards when hit, the greater - the damage the more they move back. - 'fear_height' is how high a cliff or edge has to be before the mob stops - walking, 0 to turn off height fear. - 'fall_speed' has the maximum speed the mob can fall at, default is -10. - 'fall_damage' when true causes falling to inflict damage. - 'water_damage' holds the damage per second infliced to mobs when standing in - water (default: 0). - 'lava_damage' holds the damage per second inflicted to mobs when standing - in lava (default: 8). - 'fire_damage' holds the damage per second inflicted to mobs when standing - in fire (default: 1). - 'light_damage' holds the damage per second inflicted to mobs when it's too - bright (above 13 light). - 'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second). - 'floats' when set to 1 mob will float in water, 0 has them sink. - 'follow' mobs follow player when holding any of the items which appear - on this table, the same items can be fed to a mob to tame or - breed e.g. {"farming:wheat", "default:apple"} + 'nametag' contains the name which is shown above mob. + 'type' holds the type of mob that inhabits your world e.g. + "animal" usually docile and walking around. + "monster" attacks player or npc on sight. + "npc" walk around and will defend themselves if hit first, they + kill monsters. + 'hp_min' the minimum health value the mob can spawn with. + 'hp_max' the maximum health value the mob can spawn with. + 'breath_max' The maximum breath value the mob can spawn with and can have. + If -1 (default), mob does not take drowning damage. + 'breathes_in_water' If true, mob loses breath when not in water. Otherwise, + mob loses breath when inside a node with `drowning` attribute + set (default: false). + 'armor' entity armor groups (see lua_api.txt). If table, a list of + armor groups like for entities. If number, set value of + 'fleshy' armor group only. + Note: The 'immortal=1' armor group will automatically be added + since this mod handles health and damage manually. + Default: 100 (mob will take full dmg from 'fleshy' hits) + 'passive' when true allows animals to defend themselves when hit, + otherwise they amble onwards. + 'walk_velocity' is the speed that your mob can walk around. + 'run_velocity'is the speed your mob can run with, usually when attacking. + 'walk_chance' has a 0-100 chance value your mob will walk from standing, + set to 0 for jumping mobs only. + 'jump' when true allows your mob to jump updwards. + 'jump_height' holds the height your mob can jump, 0 to disable jumping. + 'stepheight' height of a block that your mob can easily walk up onto, + defaults to 0.6. + 'fly' when true allows your mob to fly around instead of walking. + 'fly_in' holds the node name or a table of node names in which the + mob flies (or swims) around in. The special name + '__airlike' stands for all nodes with 'walkable=false' + that are not liquids + 'runaway' if true causes animals to turn and run away when hit. + 'view_range' how many nodes in distance the mob can see a player. + 'damage' how many health points the mob does to a player or another + mob when melee attacking. + 'knock_back' when true has mobs falling backwards when hit, the greater + the damage the more they move back. + 'fear_height' is how high a cliff or edge has to be before the mob stops + walking, 0 to turn off height fear. + 'fall_speed' has the maximum speed the mob can fall at, default is -10. + 'fall_damage' when true causes falling to inflict damage. + 'water_damage'holds the damage per second infliced to mobs when standing in + water (default: 0). + 'lava_damage' holds the damage per second inflicted to mobs when standing + in lava (default: 8). + 'fire_damage' holds the damage per second inflicted to mobs when standing + in fire (default: 1). + 'light_damage'holds the damage per second inflicted to mobs when it's too + bright (above 13 light). + 'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second). + 'floats' when set to 1 mob will float in water, 0 has them sink. + 'follow' mobs follow player when holding any of the items which appear + on this table, the same items can be fed to a mob to tame or + breed e.g. {"farming:wheat", "default:apple"} - 'reach' is how far the mob can attack player when standing - nearby, default is 3 nodes. - 'docile_by_day' when true has mobs wandering around during daylight - hours and only attacking player at night or when - provoked. - 'attacks_monsters' when true has npc's attacking monsters or not. - 'attack_animals' when true will have monsters attacking animals. - 'owner_loyal' when true will have tamed mobs attack anything player - punches when nearby. - 'group_attack' when true has same mob type grouping together to attack - offender. - [MCL2 extension:] When a table, this is a list of - mob types that will get alerted as well (besides same mob type) - 'attack_type' tells the api what a mob does when attacking the player - or another mob: - 'dogfight' is a melee attack when player is within mob reach. - 'shoot' has mob shoot pre-defined arrows at player when inside - view_range. - 'dogshoot' has melee attack when inside reach and shoot attack - when inside view_range. - 'explode' causes mob to stop and explode when inside reach. - 'explosion_radius' the radius of explosion node destruction, - defaults to 1 - 'explosion_damage_radius' the radius of explosion entity & player damage, - defaults to explosion_radius * 2 - 'explosion_timer' number of seconds before mob explodes while its target - is still inside reach or explosion_damage_radius, - defaults to 3. - 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume - chasing if target leaves the blast radius or line of - sight. Defaults to true. - 'stop_to_explode' When set to true (default), mob must stop and wait for - explosion_timer in order to explode. If false, mob will - continue chasing. - 'arrow' holds the pre-defined arrow object to shoot when - attacking. - 'dogshoot_switch' allows switching between attack types by using timers - (1 for shoot, 2 for dogfight) - 'dogshoot_count_max' contains how many seconds before switching from - dogfight to shoot. - 'dogshoot_count2_max' contains how many seconds before switching from shoot - to dogfight. - 'shoot_interval' has the number of seconds between shots. - 'shoot_offset' holds the y position added as to where the - arrow/fireball appears on mob. - 'specific_attack' has a table of entity names that mob can also attack - e.g. {"player", "mobs_animal:chicken"}. - 'runaway_from' contains a table with mob names to run away from, add - "player" to list to runaway from player also. - 'pathfinding' set to 1 for mobs to use pathfinder feature to locate - player, set to 2 so they can build/break also (only - works with dogfight attack and when 'mobs_griefing' - in minetest.conf is not false). - 'immune_to' is a table that holds specific damage when being hit by - certain items e.g. - {"default:sword_wood", 0} -- causes no damage. - {"default:gold_lump", -10} -- heals by 10 health points. - {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. + 'reach' is how far the mob can attack player when standing + nearby, default is 3 nodes. + 'docile_by_day' when true has mobs wandering around during daylight + hours and only attacking player at night or when + provoked. + 'attacks_monsters' when true has npc's attacking monsters or not. + 'attack_animals' when true will have monsters attacking animals. + 'owner_loyal' when true will have tamed mobs attack anything player + punches when nearby. + 'group_attack' when true has same mob type grouping together to attack + offender. + [MCL2 extension:] When a table, this is a list of + mob types that will get alerted as well (besides same mob type) + 'attack_type' tells the api what a mob does when attacking the player + or another mob: + 'dogfight' is a melee attack when player is within mob reach. + 'shoot' has mob shoot pre-defined arrows at player when inside + view_range. + 'dogshoot' has melee attack when inside reach and shoot attack + when inside view_range. + 'explode' causes mob to stop and explode when inside reach. + 'explosion_radius' the radius of explosion node destruction, + defaults to 1 + 'explosion_damage_radius' the radius of explosion entity & player damage, + defaults to explosion_radius * 2 + 'explosion_timer' number of seconds before mob explodes while its target + is still inside reach or explosion_damage_radius, + defaults to 3. + 'explosiontimer_reset_radius' The distance you must travel before the timer will be reset. + 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume + chasing if target leaves the blast radius or line of + sight. Defaults to true. + 'stop_to_explode' When set to true (default), mob must stop and wait for + explosion_timer in order to explode. If false, mob will + continue chasing. + 'arrow' holds the pre-defined arrow object to shoot when + attacking. + 'dogshoot_switch' allows switching between attack types by using timers + (1 for shoot, 2 for dogfight) + 'dogshoot_count_max'contains how many seconds before switching from + dogfight to shoot. + 'dogshoot_count2_max' contains how many seconds before switching from shoot + to dogfight. + 'shoot_interval' has the number of seconds between shots. + 'shoot_offset' holds the y position added as to where the + arrow/fireball appears on mob. + 'specific_attack' has a table of entity names that mob can also attack + e.g. {"player", "mobs_animal:chicken"}. + 'runaway_from' contains a table with mob names to run away from, add + "player" to list to runaway from player also. + 'pathfinding' set to 1 for mobs to use pathfinder feature to locate + player, set to 2 so they can build/break also (only + works with dogfight attack and when 'mobs_griefing' + in minetest.conf is not false). + 'immune_to' is a table that holds specific damage when being hit by + certain items e.g. + {"default:sword_wood",0} -- causes no damage. + {"default:gold_lump", -10} -- heals by 10 health points. + {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. - 'makes_footstep_sound' when true you can hear mobs walking. - 'sounds' this is a table with sounds of the mob - 'distance' maximum distance sounds can be heard, default is 10. - 'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension) - 'random' played randomly from time to time. - also played for overfeeding animal. - 'eat' played when mob eats something - 'war_cry' what you hear when mob starts to attack player. (currently disabled) - 'attack' what you hear when being attacked. - 'shoot_attack' sound played when mob shoots. - 'damage' sound heard when mob is hurt. - 'death' played when mob is killed. - 'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam - 'flop' played when mob flops (like a stranded fish) - 'fuse' sound played when mob explode timer starts. - 'explode' sound played when mob explodes. + 'makes_footstep_sound' when true you can hear mobs walking. + 'sounds' this is a table with sounds of the mob + 'distance' maximum distance sounds can be heard, default is 10. + 'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension) + 'random' played randomly from time to time. + also played for overfeeding animal. + 'eat' played when mob eats something + 'war_cry' what you hear when mob starts to attack player. (currently disabled) + 'attack' what you hear when being attacked. + 'shoot_attack' sound played when mob shoots. + 'damage' sound heard when mob is hurt. + 'death' played when mob is killed. + 'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam + 'flop' played when mob flops (like a stranded fish) + 'fuse' sound played when mob explode timer starts. + 'explode' sound played when mob explodes. - Note: For all sounds except fuse and explode, the pitch is slightly randomized from the base pitch - The pitch of children is 50% higher. + Note: For all sounds except fuse and explode, the pitch is slightly randomized from the base pitch + The pitch of children is 50% higher. - 'drops' table of items that are dropped when mob is killed, fields are: - 'name' name of item to drop. - 'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc. - 'min' minimum number of items dropped. - 'max' maximum number of items dropped. + 'drops' table of items that are dropped when mob is killed, fields are: + 'name' name of item to drop. + 'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc. + 'min' minimum number of items dropped. + 'max' maximum number of items dropped. - 'visual' holds the look of the mob you wish to create: - 'cube' looks like a normal node - 'sprite' sprite which looks same from all angles. - 'upright_sprite' flat model standing upright. - 'wielditem' how it looks when player holds it in hand. - 'mesh' uses separate object file to define mob. - 'visual_size' has the size of the mob, defaults to {x = 1, y = 1} - 'collisionbox' has the box in which mob can be interacted with the - world e.g. {-0.5, -0.5, -0.5, 0.5, 0.8, 0.5}. - NOTE: Due to a workaround, the upper Y coordinate will be forced - to a minimum value of 0.79. - 'selectionbox' has the box in which player can interact with mob - 'textures' holds a table list of textures to be used for mob, or you - could use multiple lists inside another table for random - selection e.g. { {"texture1.png"}, {"texture2.png"} } - 'child_texture' holds the texture table for when baby mobs are used. - 'gotten_texture' holds the texture table for when self.gotten value is - true, used for milking cows or shearing sheep. - 'mesh' holds the name of the external object used for mob model - e.g. "mobs_cow.b3d" - 'gotten_mesh" holds the name of the external object used for when - self.gotten is true for mobs. - 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, - 270 = other side. - 'double_melee_attack' when true has the api choose between 'punch' and - 'punch2' animations. + 'visual' holds the look of the mob you wish to create: + 'cube' looks like a normal node + 'sprite' sprite which looks same from all angles. + 'upright_sprite' flat model standing upright. + 'wielditem' how it looks when player holds it in hand. + 'mesh' uses separate object file to define mob. + 'visual_size' has the size of the mob, defaults to {x = 1, y = 1} + 'collisionbox' has the box in which mob can be interacted with the + world e.g. {-0.5, -0.5, -0.5, 0.5, 0.8, 0.5}. + NOTE: Due to a workaround, the upper Y coordinate will be forced + to a minimum value of 0.79. + 'selectionbox' has the box in which player can interact with mob + 'textures' holds a table list of textures to be used for mob, or you + could use multiple lists inside another table for random + selection e.g. { {"texture1.png"}, {"texture2.png"} } + 'child_texture' holds the texture table for when baby mobs are used. + 'gotten_texture' holds the texture table for when self.gotten value is + true, used for milking cows or shearing sheep. + 'mesh' holds the name of the external object used for mob model + e.g. "mobs_cow.b3d" + 'gotten_mesh" holds the name of the external object used for when + self.gotten is true for mobs. + 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, + 270 = other side. + 'double_melee_attack' when true has the api choose between 'punch' and + 'punch2' animations. - 'animation' holds a table containing animation names and settings for use with mesh models: - 'stand_start' start frame for when mob stands still. - 'stand_end' end frame of stand animation. - 'stand_speed' speed of animation in frames per second. - 'walk_start' when mob is walking around. - 'walk_end' - 'walk_speed' - 'run_start' when a mob runs or attacks. - 'run_end' - 'run_speed' - 'fly_start' when a mob is flying. - 'fly_end' - 'fly_speed' - 'punch_start' when a mob melee attacks. - 'punch_end' - 'punch_speed' - 'punch2_start' alternative melee attack animation. - 'punch2_end' - 'punch2_speed' - 'shoot_start' shooting animation. - 'shoot_end' - 'shoot_speed' - 'die_start' death animation - 'die_end' - 'die_speed' - 'die_loop' when set to false stops the animation looping. + 'animation' holds a table containing animation names and settings for use with mesh models: + { + 'stand_start'start frame for when mob stands still. + 'stand_end' end frame of stand animation. + 'stand_speed'speed of animation in frames per second. + 'walk_start' when mob is walking around. + 'walk_end' + 'walk_speed' + 'run_start' when a mob runs or attacks. + 'run_end' + 'run_speed' + 'fly_start' when a mob is flying. + 'fly_end' + 'fly_speed' + 'punch_start'when a mob melee attacks. + 'punch_end' + 'punch_speed' + 'punch2_start' alternative melee attack animation. + 'punch2_end' + 'punch2_speed' + 'shoot_start'shooting animation. + 'shoot_end' + 'shoot_speed' + 'die_start' death animation + 'die_end' + 'die_speed' + 'die_loop' when set to false stops the animation looping. + } - Using '_loop = false' setting will stop any of the above animations from - looping. + Using '_loop = false' setting will stop any of the above animations from + looping. - 'speed_normal' is used for animation speed for compatibility with some - older mobs. - 'pushable' Allows players, & other mobs to push the mob. + 'speed_normal' is used for animation speed for compatibility with some + older mobs. + 'pushable' Allows players, & other mobs to push the mob. - MineClone 2 extensions: + MineClone 2 extensions: - 'spawn_class' Classification of mod for the spawning algorithm: - "hostile", "passive", "ambient" or "water" - 'ignores_nametag' if true, mob cannot be named by nametag - 'rain_damage' damage per second if mob is standing in rain (default: 0) - 'sunlight_damage' holds the damage per second inflicted to mobs when they - are in direct sunlight - 'spawn_small_alternative': name of a smaller mob to use as replacement if - spawning fails due to space requirements - 'glow' same as in entity definition - 'child' if true, spawn mob as child - 'shoot_arrow(self, pos, dir)' function that is called when mob wants to shoot an arrow. - You can spawn your own arrow here. pos is mob position, - dir is mob's aiming direction - 'sounds_child' same as sounds, but for childs. If not defined, childs will use same - sound as adults but with higher pitch - 'follow_velocity' The speed at which a mob moves toward the player when they're holding the appropriate follow item. - 'instant_death' If true, mob dies instantly (no death animation or delay) (default: false) - 'xp_min' the minimum XP it drops on death (default: 0) - 'xp_max' the maximum XP it drops on death (default: 0) - 'fire_resistant' If true, the mob can't burn - 'fire_damage_resistant' If true the mob will not take damage when burning - 'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second) + 'spawn_class' Classification of mod for the spawning algorithm: + "hostile", "passive", "ambient" or "water" + 'ignores_nametag' if true, mob cannot be named by nametag + 'rain_damage' damage per second if mob is standing in rain (default: 0) + 'sunlight_damage' holds the damage per second inflicted to mobs when they + are in direct sunlight + 'spawn_small_alternative' name of a smaller mob to use as replacement if + spawning fails due to space requirements + 'glow' same as in entity definition + 'child' if true, spawn mob as child + 'shoot_arrow(self, pos, dir)' function that is called when mob wants to shoot an arrow. + You can spawn your own arrow here. pos is mob position, + dir is mob's aiming direction + 'sounds_child' same as sounds, but for childs. If not defined, childs will use same + sound as adults but with higher pitch + 'follow_velocity' The speed at which a mob moves toward the player when they're holding the appropriate follow item. + 'instant_death' If true, mob dies instantly (no death animation or delay) (default: false) + 'xp_min' the minimum XP it drops on death (default: 0) + 'xp_max' the maximum XP it drops on death (default: 0) + 'fire_resistant' If true, the mob can't burn + 'fire_damage_resistant' If true the mob will not take damage when burning + 'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second) + 'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers) + that are bred in a different way. + 'pick_up' table of itemstrings the mob will pick up (e.g. for breeding) + 'on_pick_up' function that will be called on item pickup - arguments are self and the itementity return a (modified) itemstack + 'custom_visual_size' will not reset visual_size from the base class on reload + 'noyaw' If true this mob will not automatically change yaw + 'particlespawners' Table of particlespawners attached to the mob. This is implemented in a coord safe manner i.e. spawners are only sent to players within the player_transfer_distance (and automatically removed). This enables infinitely lived particlespawners. + 'attack_frequency' Attack frequency in seconds. If unset, this defaults to 1. Implemented for melee only atm. + + mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival @@ -261,30 +274,30 @@ Node Replacement Mobs can look around for specific nodes as they walk and replace them to mimic eating. - 'replace_what' group of items to replace e.g. - {"farming:wheat_8", "farming:carrot_8"} - or you can use the specific options of what, with and - y offset by using this instead: - { - {"group:grass", "air", 0}, - {"default:dirt_with_grass", "default:dirt", -1} - } - 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" - 'replace_rate' how random should the replace rate be (typically 10) - 'replace_offset' +/- value to check specific node to replace + 'replace_what' group of items to replace e.g. + {"farming:wheat_8", "farming:carrot_8"} + or you can use the specific options of what, with and + y offset by using this instead: + { + {"group:grass", "air", 0}, + {"default:dirt_with_grass", "default:dirt", -1} + } + 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" + 'replace_rate' how random should the replace rate be (typically 10) + 'replace_offset' +/- value to check specific node to replace - 'on_replace(self, pos, oldnode, newnode)' - is called when mob is about to replace a node. Also called - when not actually replacing due to mobs_griefing setting being false. - 'self' ObjectRef of mob - 'pos' Position of node to replace - 'oldnode' Current node - 'newnode' What the node will become after replacing + 'on_replace(self, pos, oldnode, newnode)' + is called when mob is about to replace a node. Also called + when not actually replacing due to mobs_griefing setting being false. + 'self' ObjectRef of mob + 'pos' Position of node to replace + 'oldnode' Current node + 'newnode' What the node will become after replacing - If false is returned, the mob will not replace the node. + If false is returned, the mob will not replace the node. - By default, replacing sets self.gotten to true and resets the object - properties. + By default, replacing sets self.gotten to true and resets the object + properties. Custom Definition Functions @@ -293,33 +306,33 @@ Custom Definition Functions Along with the above mob registry settings we can also use custom functions to enhance mob functionality and have them do many interesting things: - 'on_die' a function that is called when the mob is killed; the - parameters are (self, pos). Return true to skip the builtin - death animation and death effects - 'on_rightclick' its same as in minetest.register_entity() - 'on_blast' is called when an explosion happens near mob when using TNT - functions, parameters are (object, damage) and returns - (do_damage, do_knockback, drops) - 'on_spawn' is a custom function that runs on mob spawn with 'self' as - variable, return true at end of function to run only once. - 'after_activate' is a custom function that runs once mob has been activated - with these paramaters (self, staticdata, def, dtime) - 'on_breed' called when two similar mobs breed, paramaters are - (parent1, parent2) objects, return false to stop child from - being resized and owner/tamed flags and child textures being - applied. Function itself must spawn new child mob. - 'on_grown' is called when a child mob has grown up, only paramater is - (self). - 'do_punch' called when mob is punched with paramaters (self, hitter, - time_from_last_punch, tool_capabilities, direction), return - false to stop punch damage and knockback from taking place. - 'custom_attack' when set this function is called instead of the normal mob - melee attack, parameters are (self, to_attack). - 'on_die' a function that is called when mob is killed (self, pos) - 'do_custom' a custom function that is called every tick while mob is - active and which has access to all of the self.* variables - e.g. (self.health for health or self.standing_in for node - status), return with 'false' to skip remainder of mob API. + 'on_die' a function that is called when the mob is killed; the + parameters are (self, pos). Return true to skip the builtin + death animation and death effects + 'on_rightclick'its same as in minetest.register_entity() + 'on_blast' is called when an explosion happens near mob when using TNT + functions, parameters are (object, damage) and returns + (do_damage, do_knockback, drops) + 'on_spawn' is a custom function that runs on mob spawn with 'self' as + variable, return true at end of function to run only once. + 'after_activate' is a custom function that runs once mob has been activated + with these paramaters (self, staticdata, def, dtime) + 'on_breed' called when two similar mobs breed, paramaters are + (parent1, parent2) objects, return false to stop child from + being resized and owner/tamed flags and child textures being + applied.Function itself must spawn new child mob. + 'on_grown' is called when a child mob has grown up, only paramater is + (self). + 'do_punch' called when mob is punched with paramaters (self, hitter, + time_from_last_punch, tool_capabilities, direction), return + false to stop punch damage and knockback from taking place. + 'custom_attack'when set this function is called instead of the normal mob + melee attack, parameters are (self, to_attack). + 'on_die' a function that is called when mob is killed (self, pos) + 'do_custom' a custom function that is called every tick while mob is + active and which has access to all of the self.* variables + e.g. (self.health for health or self.standing_in for node + status), return with 'false' to skip remainder of mob API. Internal Variables @@ -328,84 +341,84 @@ Internal Variables The mob api also has some preset variables and functions that it will remember for each mob. - 'self.health' contains current health of mob (cannot exceed - self.hp_max) - 'self.breath' contains current breath of mob, if mob takes drowning - damage at all (cannot exceed self.breath_max). Breath - decreases by 1 each second while in a node with drowning - damage and increases by 1 each second otherwise. - 'self.texture_list' contains list of all mob textures - 'self.child_texture' contains mob child texture when growing up - 'self.base_texture' contains current skin texture which was randomly - selected from textures list - 'self.gotten' this is used to track whether some special item has been - gotten from the mob, for example, wool from sheep. - Initialized as false, and the mob must set this value - manually. - 'self.horny' when animal fed enough it is set to true and animal can - breed with same animal - 'self.hornytimer' background timer that controls breeding functions and - mob childhood timings - 'self.child' used for when breeding animals have child, will use - child_texture and be half size - 'self.owner' string used to set owner of npc mobs, typically used for - dogs - 'self.order' set to "follow" or "stand" so that npc will follow owner - or stand it's ground - 'self.state' Current mob state. - "stand": no movement (except turning around) - "walk": walk or move around aimlessly - "attack": chase and attack enemy - "runaway": flee from target - "flop": bounce around aimlessly - (for swimming mobs that have stranded) - "die": during death - 'self.nametag' contains the name of the mob which it can show above + 'self.health' contains current health of mob (cannot exceed + self.hp_max) + 'self.breath' contains current breath of mob, if mob takes drowning + damage at all (cannot exceed self.breath_max). Breath + decreases by 1 each second while in a node with drowning + damage and increases by 1 each second otherwise. + 'self.texture_list'contains list of all mob textures + 'self.child_texture' contains mob child texture when growing up + 'self.base_texture'contains current skin texture which was randomly + selected from textures list + 'self.gotten' this is used to track whether some special item has been + gotten from the mob, for example, wool from sheep. + Initialized as false, and the mob must set this value + manually. + 'self.horny' when animal fed enough it is set to true and animal can + breed with same animal + 'self.hornytimer' background timer that controls breeding functions and + mob childhood timings + 'self.child' used for when breeding animals have child, will use + child_texture and be half size + 'self.owner' string used to set owner of npc mobs, typically used for + dogs + 'self.order' set to "follow" or "stand" so that npc will follow owner + or stand it's ground + 'self.state' Current mob state. + "stand": no movement (except turning around) + "walk": walk or move around aimlessly + "attack": chase and attack enemy + "runaway": flee from target + "flop": bounce around aimlessly + (for swimming mobs that have stranded) + "die": during death + 'self.nametag' contains the name of the mob which it can show above Spawning Mobs in World ---------------------- mobs:register_spawn(name, nodes, max_light, min_light, chance, - active_object_count, max_height, day_toggle) + active_object_count, max_height, day_toggle) mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) These functions register a spawn algorithm for the mob. Without this function the call the mobs won't spawn. - 'name' is the name of the animal/monster - 'nodes' is a list of nodenames on that the animal/monster can - spawn on top of - 'neighbors' is a list of nodenames on that the animal/monster will - spawn beside (default is {"air"} for - mobs:register_spawn) - 'max_light' is the maximum of light - 'min_light' is the minimum of light - 'interval' is same as in register_abm() (default is 30 for - mobs:register_spawn) - 'chance' is same as in register_abm() - 'active_object_count' number of this type of mob to spawn at one time inside - map area - 'min_height' is the minimum height the mob can spawn - 'max_height' is the maximum height the mob can spawn - 'day_toggle' true for day spawning, false for night or nil for - anytime - 'on_spawn' is a custom function which runs after mob has spawned - and gives self and pos values. + 'name' is the name of the animal/monster + 'nodes' is a list of nodenames on that the animal/monster can + spawn on top of + 'neighbors' is a list of nodenames on that the animal/monster will + spawn beside (default is {"air"} for + mobs:register_spawn) + 'max_light' is the maximum of light + 'min_light' is the minimum of light + 'interval' is same as in register_abm() (default is 30 for + mobs:register_spawn) + 'chance' is same as in register_abm() + 'active_object_count' number of this type of mob to spawn at one time inside + map area + 'min_height' is the minimum height the mob can spawn + 'max_height' is the maximum height the mob can spawn + 'day_toggle' true for day spawning, false for night or nil for + anytime + 'on_spawn' is a custom function which runs after mob has spawned + and gives self and pos values. A simpler way to handle mob spawns has been added with the mobs:spawn(def) command which uses above names to make settings clearer: - mobs:spawn({name = "mobs_monster:tree_monster", - nodes = {"group:leaves"}, - max_light = 7, - }) + mobs:spawn({name = "mobs_monster:tree_monster", + nodes = {"group:leaves"}, + max_light = 7, + }) For each mob that spawns with this function is a field in mobs.spawning_mobs. -It tells if the mob should spawn or not. Default is true. So other mods can +It tells if the mob should spawn or not.Default is true.So other mods can only use the API of this mod by disabling the spawning of the default mobs in this mod. @@ -413,18 +426,18 @@ this mod. mobs:spawn_abm_check(pos, node, name) This global function can be changed to contain additional checks for mobs to -spawn e.g. mobs that spawn only in specific areas and the like. By returning +spawn e.g. mobs that spawn only in specific areas and the like.By returning true the mob will not spawn. - 'pos' holds the position of the spawning mob - 'node' contains the node the mob is spawning on top of - 'name' is the name of the animal/monster + 'pos' holds the position of the spawning mob + 'node' contains the node the mob is spawning on top of + 'name' is the name of the animal/monster MineClone 2 extensions ---------------------- -mobs:spawn_child(pos, mob_type) +mcl_mobs:spawn_child(pos, mob_type) This function spawns a mob as a child. The parameter mob_type is the entitystring of the new mob. @@ -434,6 +447,7 @@ mobs:death_effect(pos, collisionbox) Create death particles at pos with the given collisionbox. +mcl_mobs.spawn(pos,name/entity name) Making Arrows ------------- @@ -442,62 +456,62 @@ mobs:register_arrow(name, definition) This function registers a arrow for mobs with the attack type shoot. - 'name' is the name of the arrow - 'definition' is a table with the following values: - 'visual' same is in minetest.register_entity() - 'visual_size' same is in minetest.register_entity() - 'textures' same is in minetest.register_entity() - 'velocity' the velocity of the arrow - 'drop' if set to true any arrows hitting a node will drop as item - 'hit_player' a function that is called when the arrow hits a player; - this function should hurt the player, the parameters are - (self, player) - 'hit_mob' a function that is called when the arrow hits a mob; - this function should hurt the mob, the parameters are - (self, mob) - 'hit_object' a function that is called when the arrow hits an object - that is neither a player nor a mob. this function should - hurt the object, the parameters are (self, object) - 'hit_node' a function that is called when the arrow hits a node, the - parameters are (self, pos, node) - 'tail' when set to 1 adds a trail or tail to mob arrows - 'tail_texture' texture string used for above effect - 'tail_size' has size for above texture (defaults to between 5 and 10) - 'expire' contains float value for how long tail appears for - (defaults to 0.25) - 'glow' has value for how brightly tail glows 1 to 10 (default is - 0 for no glow) - 'rotate' integer value in degrees to rotate arrow - 'on_step' is a custom function when arrow is active, nil for - default. + 'name' is the name of the arrow + 'definition' is a table with the following values: + 'visual' same is in minetest.register_entity() + 'visual_size'same is in minetest.register_entity() + 'textures' same is in minetest.register_entity() + 'velocity' the velocity of the arrow + 'drop' if set to true any arrows hitting a node will drop as item + 'hit_player' a function that is called when the arrow hits a player; + this function should hurt the player, the parameters are + (self, player) + 'hit_mob' a function that is called when the arrow hits a mob; + this function should hurt the mob, the parameters are + (self, mob) + 'hit_object' a function that is called when the arrow hits an object + that is neither a player nor a mob. this function should + hurt the object, the parameters are (self, object) + 'hit_node' a function that is called when the arrow hits a node, the + parameters are (self, pos, node) + 'tail' when set to 1 adds a trail or tail to mob arrows + 'tail_texture' texture string used for above effect + 'tail_size' has size for above texture (defaults to between 5 and 10) + 'expire' contains float value for how long tail appears for + (defaults to 0.25) + 'glow' has value for how brightly tail glows 1 to 10 (default is + 0 for no glow) + 'rotate' integer value in degrees to rotate arrow + 'on_step' is a custom function when arrow is active, nil for + default. Spawn Eggs ---------- -mobs:register_egg(name, description, background, addegg, no_creative) +mobs:register_egg(name, description, background_color, overlay_color, addegg, no_creative) This function registers a spawn egg which can be used by admin to properly spawn in a mob. - 'name' this is the name of your new mob to spawn e.g. "mob:sheep" - 'description' the name of the new egg you are creating e.g. "Spawn Sheep" - 'background' the texture displayed for the egg in inventory - 'addegg' would you like an egg image in front of your texture (1 = yes, - 0 = no) - 'no_creative' when set to true this stops spawn egg appearing in creative - mode for destructive mobs like Dungeon Masters. + 'name' this is the name of your new mob to spawn e.g. "mob:sheep" + 'description' the name of the new egg you are creating e.g. "Spawn Sheep" + 'background_color' and 'overlay_color' define the colors for the texture displayed for the egg in inventory + 'addegg' would you like an egg image in front of your texture (1 = yes, + 0 = no) + 'no_creative' when set to true this stops spawn egg appearing in creative + mode for destructive mobs like Dungeon Masters. Explosion Function ------------------ mobs:boom(self, pos, radius) - 'self' mob entity - 'pos' centre position of explosion - 'radius' radius of explosion (typically set to 3) + 'self' mob entity + 'pos' centre position of explosion + 'radius' radius of explosion (typically set to 3) This function generates an explosion which removes nodes in a specific radius -and damages any entity caught inside the blast radius. Protection will limit +and damages any entity caught inside the blast radius.Protection will limit node destruction but not entity damage. @@ -525,13 +539,13 @@ This function allows the mob to be fed the item inside self.follow be it apple, wheat or whatever a set number of times and be tamed or bred as a result. Will return true when mob is fed with item it likes. - 'self' mob information - 'clicker' player information - 'feed_count' number of times mob must be fed to tame or breed - 'breed' true or false stating if mob can be bred and a child created - afterwards - 'tame' true or false stating if mob can be tamed so player can pick - them up + 'self' mob information + 'clicker' player information + 'feed_count' number of times mob must be fed to tame or breed + 'breed' true or false stating if mob can be bred and a child created + afterwards + 'tame' true or false stating if mob can be tamed so player can pick + them up Protecting Mobs @@ -541,10 +555,10 @@ mobs:protect(self, clicker) This function can be used to right-click any tamed mob with mobs:protector item, this will protect the mob from harm inside of a protected area from other -players. Will return true when mob right-clicked with mobs:protector item. +players.Will return true when mob right-clicked with mobs:protector item. - 'self' mob information - 'clicker' player information + 'self' mob information + 'clicker' player information Riding Mobs @@ -558,8 +572,8 @@ mobs:attach(self, player) This function attaches a player to the mob so it can be ridden. - 'self' mob information - 'player' player information + 'self' mob information + 'player' player information mobs:detach(player, offset) @@ -567,8 +581,8 @@ mobs:detach(player, offset) This function will detach the player currently riding a mob to an offset position. - 'player' player information - 'offset' position table containing offset values + 'player' player information + 'offset' position table containing offset values mobs:drive(self, move_animation, stand_animation, can_fly, dtime) @@ -576,12 +590,12 @@ mobs:drive(self, move_animation, stand_animation, can_fly, dtime) This function allows an attached player to move the mob around and animate it at same time. - 'self' mob information - 'move_animation' string containing movement animation e.g. "walk" - 'stand_animation' string containing standing animation e.g. "stand" - 'can_fly' if true then jump and sneak controls will allow mob to fly - up and down - 'dtime' tick time used inside drive function + 'self' mob information + 'move_animation'string containing movement animation e.g. "walk" + 'stand_animation' string containing standing animation e.g. "stand" + 'can_fly' if true then jump and sneak controls will allow mob to fly + up and down + 'dtime' tick time used inside drive function mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation) @@ -589,16 +603,16 @@ mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_anim This function allows an attached player to fly the mob around using directional controls. - 'self' mob information - 'dtime' tick time used inside fly function - 'speed' speed of flight - 'can_shoot' true if mob can fire arrow (sneak and left mouse button - fires) - 'arrow_entity' name of arrow entity used for firing - 'move_animation' string containing name of pre-defined animation e.g. "walk" - or "fly" etc. - 'stand_animation' string containing name of pre-defined animation e.g. - "stand" or "blink" etc. + 'self' mob information + 'dtime' tick time used inside fly function + 'speed' speed of flight + 'can_shoot' true if mob can fire arrow (sneak and left mouse button + fires) + 'arrow_entity' name of arrow entity used for firing + 'move_animation'string containing name of pre-defined animation e.g. "walk" + or "fly" etc. + 'stand_animation' string containing name of pre-defined animation e.g. + "stand" or "blink" etc. Note: animation names above are from the pre-defined animation lists inside mob registry without extensions. @@ -609,46 +623,46 @@ mobs:set_animation(self, name) This function sets the current animation for mob, defaulting to "stand" if not found. - 'self' mob information - 'name' name of animation + 'self' mob information + 'name' name of animation Certain variables need to be set before using the above functions: - 'self.v2' toggle switch used to define below values for the - first time - 'self.max_speed_forward' max speed mob can move forward - 'self.max_speed_reverse' max speed mob can move backwards - 'self.accel' acceleration speed - 'self.terrain_type' integer containing terrain mob can walk on - (1 = water, 2 or 3 = land) - 'self.driver_attach_at' position offset for attaching player to mob - 'self.driver_eye_offset' position offset for attached player view - 'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1} + 'self.v2' toggle switch used to define below values for the + first time + 'self.max_speed_forward' max speed mob can move forward + 'self.max_speed_reverse' max speed mob can move backwards + 'self.accel' acceleration speed + 'self.terrain_type' integer containing terrain mob can walk on + (1 = water, 2 or 3 = land) + 'self.driver_attach_at'position offset for attaching player to mob + 'self.driver_eye_offset' position offset for attached player view + 'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1} External Settings for "minetest.conf" ------------------------------------ - 'enable_damage' if true monsters will attack players (default is true) - 'only_peaceful_mobs' if true only animals will spawn in game (default is - false) - 'mobs_disable_blood' if false, damage effects appear when mob is hit (default - is false) - 'mobs_spawn_protected' if set to false then mobs will not spawn in protected - areas (default is true) - 'mob_difficulty' sets difficulty level (health and hit damage - multiplied by this number), defaults to 1.0. - 'mob_spawn_chance' multiplies chance of all mobs spawning and can be set - to 0.5 to have mobs spawn more or 2.0 to spawn less. - e.g. 1 in 7000 * 0.5 = 1 in 3500 so better odds of - spawning. - 'mobs_spawn' if false then mobs no longer spawn without spawner or - spawn egg. - 'mobs_drop_items' when false mobs no longer drop items when they die. - 'mobs_griefing' when false mobs cannot break blocks when using either - pathfinding level 2, replace functions or mobs:boom - function. + 'enable_damage' if true monsters will attack players (default is true) + 'only_peaceful_mobs' if true only animals will spawn in game (default is + false) + 'mobs_disable_blood' if false, damage effects appear when mob is hit (default + is false) + 'mobs_spawn_protected' if set to false then mobs will not spawn in protected + areas (default is true) + 'mob_difficulty' sets difficulty level (health and hit damage + multiplied by this number), defaults to 1.0. + 'mob_spawn_chance' multiplies chance of all mobs spawning and can be set + to 0.5 to have mobs spawn more or 2.0 to spawn less. + e.g.1 in 7000 * 0.5 = 1 in 3500 so better odds of + spawning. + 'mobs_spawn' if false then mobs no longer spawn without spawner or + spawn egg. + 'mobs_drop_items' when false mobs no longer drop items when they die. + 'mobs_griefing' when false mobs cannot break blocks when using either + pathfinding level 2, replace functions or mobs:boom + function. Players can override the spawn chance for each mob registered by adding a line to their minetest.conf file with a new value, the lower the value the more each diff --git a/mods/ENTITIES/mcl_mobs/breeding.lua b/mods/ENTITIES/mcl_mobs/breeding.lua new file mode 100644 index 000000000..c6d8f92cd --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/breeding.lua @@ -0,0 +1,350 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local HORNY_TIME = 30 +local HORNY_AGAIN_TIME = 30 -- was 300 or 15*20 +local CHILD_GROW_TIME = 60 + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false) + +local LOG_MODULE = "[mcl_mobs]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + +-- No-op in MCL2 (capturing mobs is not possible). +-- Provided for compability with Mobs Redo +function mcl_mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) + return false +end + + +-- No-op in MCL2 (protecting mobs is not possible). +function mcl_mobs:protect(self, clicker) + return false +end + + +-- feeding, taming and breeding (thanks blert2112) +function mob_class:feed_tame(clicker, feed_count, breed, tame, notake) + if not self.follow then + return false + end + -- can eat/tame with item in hand + if self.nofollow or self:follow_holding(clicker) then + local consume_food = false + + -- tame if not still a baby + + if tame and not self.child then + if not self.owner or self.owner == "" then + self.tamed = true + self.owner = clicker:get_player_name() + consume_food = true + end + end + + -- increase health + + if self.health < self.hp_max and not consume_food then + consume_food = true + self.health = math.min(self.health + 4, self.hp_max) + + if self.htimer < 1 then + self.htimer = 5 + end + self.object:set_hp(self.health) + end + + -- make children grow quicker + + if not consume_food and self.child == true then + consume_food = true + -- deduct 10% of the time to adulthood + self.hornytimer = self.hornytimer + ((CHILD_GROW_TIME - self.hornytimer) * 0.1) + end + + -- breed animals + + if breed and not consume_food and self.hornytimer == 0 and not self.horny then + self.food = (self.food or 0) + 1 + consume_food = true + if self.food >= feed_count then + self.food = 0 + self.horny = true + self.persistent = true + end + end + + self:update_tag() + -- play a sound if the animal used the item and take the item if not in creative + if consume_food then + -- don't consume food if clicker is in creative + if not minetest.is_creative_enabled(clicker:get_player_name()) and not notake then + local item = clicker:get_wielded_item() + item:take_item() + clicker:set_wielded_item(item) + end + -- always play the eat sound if food is used, even in creative + self:mob_sound("eat", nil, true) + + else + -- make sound when the mob doesn't want food + self:mob_sound("random", true) + end + return true + end + return false +end + +-- Spawn a child +function mcl_mobs.spawn_child(pos, mob_type) + local child = minetest.add_entity(pos, mob_type) + if not child then + return + end + + local ent = child:get_luaentity() + mcl_mobs.effect(pos, 15, "mcl_particles_smoke.png", 1, 2, 2, 15, 5) + + ent.child = true + + local textures + -- using specific child texture (if found) + if ent.child_texture then + textures = ent.child_texture[1] + end + + -- and resize to half height + child:set_properties({ + textures = textures, + visual_size = { + x = ent.base_size.x * .5, + y = ent.base_size.y * .5, + }, + collisionbox = { + ent.base_colbox[1] * .5, + ent.base_colbox[2] * .5, + ent.base_colbox[3] * .5, + ent.base_colbox[4] * .5, + ent.base_colbox[5] * .5, + ent.base_colbox[6] * .5, + }, + selectionbox = { + ent.base_selbox[1] * .5, + ent.base_selbox[2] * .5, + ent.base_selbox[3] * .5, + ent.base_selbox[4] * .5, + ent.base_selbox[5] * .5, + ent.base_selbox[6] * .5, + }, + }) + + ent.animation = ent._child_animations + ent._current_animation = nil + ent:set_animation("stand") + + return child +end + +-- find two animals of same type and breed if nearby and horny +function mob_class:check_breeding() + + --mcl_log("In breed function") + -- child takes a long time before growing into adult + if self.child == true then + + -- When a child, hornytimer is used to count age until adulthood + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer >= CHILD_GROW_TIME then + + self.child = false + self.hornytimer = 0 + + self.object:set_properties({ + textures = self.base_texture, + mesh = self.base_mesh, + visual_size = self.base_size, + collisionbox = self.base_colbox, + selectionbox = self.base_selbox, + }) + + -- custom function when child grows up + if self.on_grown then + self.on_grown(self) + else + -- jump when fully grown so as not to fall into ground + self.object:set_velocity({ + x = 0, + y = self.jump_height, + z = 0 + }) + end + + self.animation = nil + local anim = self._current_animation + self._current_animation = nil -- Mobs Redo does nothing otherwise + self:set_animation(anim) + end + + return + else + -- horny animal can mate for HORNY_TIME seconds, + -- afterwards horny animal cannot mate again for HORNY_AGAIN_TIME seconds + if self.horny == true then + self.hornytimer = self.hornytimer + 1 + + if self.hornytimer >= HORNY_TIME + HORNY_AGAIN_TIME then + self.hornytimer = 0 + self.horny = false + end + end + end + + -- find another same animal who is also horny and mate if nearby + if self.horny == true + and self.hornytimer <= HORNY_TIME then + + mcl_log("In breed function. All good. Do the magic.") + + local pos = self.object:get_pos() + + mcl_mobs.effect({x = pos.x, y = pos.y + 1, z = pos.z}, 8, "heart.png", 3, 4, 1, 0.1) + + local objs = minetest.get_objects_inside_radius(pos, 3) + local num = 0 + local ent = nil + + for n = 1, #objs do + + ent = objs[n]:get_luaentity() + + -- check for same animal with different colour + local canmate = false + + if ent then + + if ent.name == self.name then + canmate = true + else + local entname = string.split(ent.name,":") + local selfname = string.split(self.name,":") + + if entname[1] == selfname[1] then + entname = string.split(entname[2],"_") + selfname = string.split(selfname[2],"_") + + if entname[1] == selfname[1] then + canmate = true + end + end + end + end + + if canmate then mcl_log("In breed function. Can mate.") end + + if ent + and canmate == true + and ent.horny == true + and ent.hornytimer <= HORNY_TIME then + num = num + 1 + end + + -- found your mate? then have a baby + if num > 1 then + + self.hornytimer = HORNY_TIME + 1 + ent.hornytimer = HORNY_TIME + 1 + + -- spawn baby + + + minetest.after(5, function(parent1, parent2, pos) + if not parent1.object:get_luaentity() then + return + end + if not parent2.object:get_luaentity() then + return + end + + mcl_experience.throw_xp(pos, math.random(1, 7)) + + -- custom breed function + if parent1.on_breed then + -- when false, skip going any further + if parent1.on_breed(parent1, parent2) == false then + return + end + end + + local child = mcl_mobs.spawn_child(pos, parent1.name) + + local ent_c = child:get_luaentity() + + + -- Use texture of one of the parents + local p = math.random(1, 2) + if p == 1 then + ent_c.base_texture = parent1.base_texture + else + ent_c.base_texture = parent2.base_texture + end + child:set_properties({ + textures = ent_c.base_texture + }) + + -- tamed and owned by parents' owner + ent_c.tamed = true + ent_c.owner = parent1.owner + end, self, ent, pos) + + num = 0 + + break + end + end + end +end + +function mob_class:toggle_sit(clicker,p) + if not self.tamed or self.child or self.owner ~= clicker:get_player_name() then + return + end + local pos = self.object:get_pos() + local particle + if not self.order or self.order == "" or self.order == "sit" then + particle = "mobs_mc_wolf_icon_roam.png" + self.order = "roam" + self.state = "stand" + self.walk_chance = default_walk_chance + self.jump = true + self:set_animation("stand") + -- TODO: Add sitting model + else + particle = "mobs_mc_wolf_icon_sit.png" + self.order = "sit" + self.state = "stand" + self.walk_chance = 0 + self.jump = false + if self.animation.sit_start then + self:set_animation("sit") + else + self:set_animation("stand") + end + end + local pp = vector.new(0,1.4,0) + if p then pp = vector.offset(pp,0,p,0) end + -- Display icon to show current order (sit or roam) + minetest.add_particle({ + pos = vector.add(pos, pp), + velocity = {x=0,y=0.2,z=0}, + expirationtime = 1, + size = 4, + texture = particle, + playername = self.owner, + glow = minetest.LIGHT_MAX, + }) +end diff --git a/mods/ENTITIES/mcl_mobs/combat.lua b/mods/ENTITIES/mcl_mobs/combat.lua new file mode 100644 index 000000000..836f53753 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/combat.lua @@ -0,0 +1,1214 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local damage_enabled = minetest.settings:get_bool("enable_damage") +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + +-- pathfinding settings +local stuck_timeout = 3 -- how long before mob gets stuck in place and starts searching +local stuck_path_timeout = 10 -- how long will mob follow path before giving up + +local enable_pathfinding = true + +local TIME_TO_FORGET_TARGET = 15 + +local atann = math.atan +local function atan(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + + +-- check if daytime and also if mob is docile during daylight hours +function mob_class:day_docile() + if self.docile_by_day == false then + return false + elseif self.docile_by_day == true + and self.time_of_day > 0.2 + and self.time_of_day < 0.8 then + return true + end +end + +-- attack player/mob +function mob_class:do_attack(player) + + if self.state == "attack" or self.state == "die" then + return + end + + self.attack = player + self.state = "attack" + + -- TODO: Implement war_cry sound without being annoying + --if random(0, 100) < 90 then + --self:mob_sound("war_cry", true) + --end +end + +-- blast damage to entities nearby +local function entity_physics(pos,radius) + + radius = radius * 2 + + local objs = minetest.get_objects_inside_radius(pos, radius) + local obj_pos, dist + + for n = 1, #objs do + + obj_pos = objs[n]:get_pos() + + dist = vector.distance(pos, obj_pos) + if dist < 1 then dist = 1 end + + local damage = math.floor((4 / dist) * radius) + local ent = objs[n]:get_luaentity() + + -- punches work on entities AND players + objs[n]:punch(objs[n], 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, pos) + end +end + +function mob_class:entity_physics(pos,radius) return entity_physics(pos,radius) end + +local los_switcher = false +local height_switcher = false + +-- path finding and smart mob routine by rnd, line_of_sight and other edits by Elkien3 +function mob_class:smart_mobs(s, p, dist, dtime) + + local s1 = self.path.lastpos + + local target_pos = self.attack:get_pos() + + -- is it becoming stuck? + if math.abs(s1.x - s.x) + math.abs(s1.z - s.z) < .5 then + self.path.stuck_timer = self.path.stuck_timer + dtime + else + self.path.stuck_timer = 0 + end + + self.path.lastpos = {x = s.x, y = s.y, z = s.z} + + local use_pathfind = false + local has_lineofsight = minetest.line_of_sight( + {x = s.x, y = (s.y) + .5, z = s.z}, + {x = target_pos.x, y = (target_pos.y) + 1.5, z = target_pos.z}, .2) + + -- im stuck, search for path + if not has_lineofsight then + + if los_switcher == true then + use_pathfind = true + los_switcher = false + end -- cannot see target! + else + if los_switcher == false then + + los_switcher = true + use_pathfind = false + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end -- can see target! + end + + if (self.path.stuck_timer > stuck_timeout and not self.path.following) then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end + + if (self.path.stuck_timer > stuck_path_timeout and self.path.following) then + + use_pathfind = true + self.path.stuck_timer = 0 + + minetest.after(1, function(self) + if not self.object:get_luaentity() then + return + end + if has_lineofsight then self.path.following = false end + end, self) + end + + if math.abs(vector.subtract(s,target_pos).y) > self.stepheight then + + if height_switcher then + use_pathfind = true + height_switcher = false + end + else + if not height_switcher then + use_pathfind = false + height_switcher = true + end + end + + if use_pathfind then + -- lets try find a path, first take care of positions + -- since pathfinder is very sensitive + local sheight = self.collisionbox[5] - self.collisionbox[2] + + -- round position to center of node to avoid stuck in walls + -- also adjust height for player models! + s.x = math.floor(s.x + 0.5) + s.z = math.floor(s.z + 0.5) + + local ssight, sground = minetest.line_of_sight(s, { + x = s.x, y = s.y - 4, z = s.z}, 1) + + -- determine node above ground + if not ssight then + s.y = sground.y + 1 + end + + local p1 = self.attack:get_pos() + + p1.x = math.floor(p1.x + 0.5) + p1.y = math.floor(p1.y + 0.5) + p1.z = math.floor(p1.z + 0.5) + + local dropheight = 12 + if self.fear_height ~= 0 then dropheight = self.fear_height end + local jumpheight = 0 + if self.jump and self.jump_height >= 4 then + jumpheight = math.min(math.ceil(self.jump_height / 4), 4) + elseif self.stepheight > 0.5 then + jumpheight = 1 + end + self.path.way = minetest.find_path(s, p1, 16, jumpheight, dropheight, "A*_noprefetch") + + self.state = "" + self:do_attack(self.attack) + + -- no path found, try something else + if not self.path.way then + + self.path.following = false + + -- lets make way by digging/building if not accessible + if self.pathfinding == 2 and mobs_griefing then + + -- is player higher than mob? + if s.y < p1.y then + + -- build upwards + if not minetest.is_protected(s, "") then + + local ndef1 = minetest.registered_nodes[self.standing_in] + + if ndef1 and (ndef1.buildable_to or ndef1.groups.liquid) then + + minetest.set_node(s, {name = mcl_mobs.fallback_node}) + end + end + + local sheight = math.ceil(self.collisionbox[5]) + 1 + + -- assume mob is 2 blocks high so it digs above its head + s.y = s.y + sheight + + -- remove one block above to make room to jump + if not minetest.is_protected(s, "") then + + local node1 = node_ok(s, "air").name + local ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.set_node(s, {name = "air"}) + minetest.add_item(s, ItemStack(node1)) + + end + end + + s.y = s.y - sheight + self.object:set_pos({x = s.x, y = s.y + 2, z = s.z}) + + else -- dig 2 blocks to make door toward player direction + + local yaw1 = self.object:get_yaw() + math.pi / 2 + local p1 = { + x = s.x + math.cos(yaw1), + y = s.y, + z = s.z + math.sin(yaw1) + } + + if not minetest.is_protected(p1, "") then + + local node1 = node_ok(p1, "air").name + local ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.add_item(p1, ItemStack(node1)) + minetest.set_node(p1, {name = "air"}) + end + + p1.y = p1.y + 1 + node1 = node_ok(p1, "air").name + ndef1 = minetest.registered_nodes[node1] + + if node1 ~= "air" + and node1 ~= "ignore" + and ndef1 + and not ndef1.groups.level + and not ndef1.groups.unbreakable + and not ndef1.groups.liquid then + + minetest.add_item(p1, ItemStack(node1)) + minetest.set_node(p1, {name = "air"}) + end + + end + end + end + + -- will try again in 2 seconds + self.path.stuck_timer = stuck_timeout - 2 + elseif s.y < p1.y and (not self.fly) then + self:do_jump() --add jump to pathfinding + self.path.following = true + -- Yay, I found path! + -- TODO: Implement war_cry sound without being annoying + --self:mob_sound("war_cry", true) + else + self:set_velocity(self.walk_velocity) + + -- follow path now that it has it + self.path.following = true + end + end +end + + +-- specific attacks +local specific_attack = function(list, what) + + -- no list so attack default (player, animals etc.) + if list == nil then + return true + end + + -- found entity on list to attack? + for no = 1, #list do + + if list[no] == what then + return true + end + end + + return false +end + +-- find someone to attack +function mob_class:monster_attack() + if not damage_enabled or self.passive ~= false or self.state == "attack" or self:day_docile() then + return + end + + local s = self.object:get_pos() + local p, sp, dist + local player, obj, min_player + local type, name = "", "" + local min_dist = self.view_range + 1 + + local blacklist_attack = {} + + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + if not objs[n]:is_player() then + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + name = obj.name or "" + end + if obj and obj.type == self.type and obj.passive == false and obj.state == "attack" and obj.attack then + table.insert(blacklist_attack, obj.attack) + end + end + end + + for n = 1, #objs do + if objs[n]:is_player() then + if mcl_mobs.invis[ objs[n]:get_player_name() ] or (not self:object_in_range(objs[n])) then + type = "" + elseif (self.type == "monster" or self._aggro) then + -- self.aggro made player be attacked by npc again if out of range then back in again + -- Does it serve a purpose other than that? + player = objs[n] + type = "player" + name = "player" + end + else + obj = objs[n]:get_luaentity() + if obj then + player = obj.object + type = obj.type + name = obj.name or "" + end + end + + -- 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 + p = player:get_pos() + sp = s + + dist = vector.distance(p, s) + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + local attacked_p = false + for c=1, #blacklist_attack do + if blacklist_attack[c] == player then + attacked_p = true + end + end + + -- choose closest player to attack + local line_of_sight = self:line_of_sight( sp, p, 2) == true + if dist < min_dist and not attacked_p and line_of_sight then + min_dist = dist + min_player = player + end + end + end + if not min_player and #blacklist_attack > 0 then + min_player=blacklist_attack[math.random(#blacklist_attack)] + end + -- attack player + if min_player then + self:do_attack(min_player) + end +end + + +-- npc, find closest monster to attack +function mob_class:npc_attack() + + if self.type ~= "npc" + or not self.attacks_monsters + or self.state == "attack" then + return + end + + local p, sp, obj, min_player + local s = self.object:get_pos() + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + obj = objs[n]:get_luaentity() + + if obj and obj.type == "monster" then + p = obj.object:get_pos() + sp = s + + local dist = vector.distance(p, s) + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + if dist < min_dist and self:line_of_sight( sp, p, 2) == true then + min_dist = dist + min_player = obj.object + end + end + end + + if min_player then + self:do_attack(min_player) + end +end + + + +-- dogshoot attack switch and counter function +function mob_class:dogswitch(dtime) + + -- switch mode not activated + if not self.dogshoot_switch + or not dtime then + return 0 + end + + self.dogshoot_count = self.dogshoot_count + dtime + + if (self.dogshoot_switch == 1 + and self.dogshoot_count > self.dogshoot_count_max) + or (self.dogshoot_switch == 2 + and self.dogshoot_count > self.dogshoot_count2_max) then + + self.dogshoot_count = 0 + + if self.dogshoot_switch == 1 then + self.dogshoot_switch = 2 + else + self.dogshoot_switch = 1 + end + end + + return self.dogshoot_switch +end + +-- no damage to nodes explosion +function mob_class:safe_boom(pos, strength) + minetest.sound_play(self.sounds and self.sounds.explode or "tnt_explode", { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds and self.sounds.distance or 32 + }, true) + local radius = strength + entity_physics(pos, radius) + mcl_mobs.effect(pos, 32, "mcl_particles_smoke.png", radius * 3, radius * 5, radius, 1, 0) +end + + +-- make explosion with protection and tnt mod check +function mob_class:boom(pos, strength, fire) + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(pos, strength, { drop_chance = 1.0, fire = fire }, self.object) + else + mcl_mobs.mob_class.safe_boom(self, pos, strength) --need to call it this way bc self is the "arrow" object here + end + + -- delete the object after it punched the player to avoid nil entities in e.g. mcl_shields!! + self.object:remove() +end + +-- deal damage and effects when mob punched +function mob_class:on_punch(hitter, tflp, tool_capabilities, dir) + + -- custom punch function + if self.do_punch then + + -- when false skip going any further + if self.do_punch(self, hitter, tflp, tool_capabilities, dir) == false then + return + end + end + + -- error checking when mod profiling is enabled + if not tool_capabilities then + minetest.log("warning", "[mobs] Mod profiling enabled, damage not enabled") + return + end + + local is_player = hitter:is_player() + + 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() + end + + + -- punch interval + local weapon = hitter:get_wielded_item() + local punch_interval = 1.4 + + -- exhaust attacker + if is_player then + mcl_hunger.exhaust(hitter:get_player_name(), mcl_hunger.EXHAUST_ATTACK) + end + + -- calculate mob damage + local damage = 0 + local armor = self.object:get_armor_groups() or {} + local tmp + + -- quick error check incase it ends up 0 (serialize.h check test) + if tflp == 0 then + tflp = 0.2 + end + + + for group,_ in pairs( (tool_capabilities.damage_groups or {}) ) do + + tmp = tflp / (tool_capabilities.full_punch_interval or 1.4) + + if tmp < 0 then + tmp = 0.0 + elseif tmp > 1 then + tmp = 1.0 + end + + damage = damage + (tool_capabilities.damage_groups[group] or 0) + * tmp * ((armor[group] or 0) / 100.0) + end + + if weapon then + local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") + if fire_aspect_level > 0 then + mcl_burning.set_on_fire(self.object, fire_aspect_level * 4) + end + end + + -- check for tool immunity or special damage + for n = 1, #self.immune_to do + + if self.immune_to[n][1] == weapon:get_name() then + + damage = self.immune_to[n][2] or 0 + break + end + end + + -- healing + if damage <= -1 then + self.health = self.health - math.floor(damage) + return + end + + if tool_capabilities then + punch_interval = tool_capabilities.full_punch_interval or 1.4 + end + + -- add weapon wear manually + -- Required because we have custom health handling ("health" property) + if minetest.is_creative_enabled("") ~= true + and tool_capabilities then + if tool_capabilities.punch_attack_uses then + -- Without this delay, the wear does not work. Quite hacky ... + minetest.after(0, function(name) + local player = minetest.get_player_by_name(name) + if not player then return end + local weapon = hitter:get_wielded_item(player) + local def = weapon:get_definition() + 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) + hitter:set_wielded_item(weapon) + end + end, hitter:get_player_name()) + end + end + + local die = false + + + if damage >= 0 then + -- only play hit sound and show blood effects if damage is 1 or over; lower to 0.1 to ensure armor works appropriately. + if damage >= 0.1 then + -- weapon sounds + if weapon:get_definition().sounds ~= nil then + + local s = math.random(0, #weapon:get_definition().sounds) + + minetest.sound_play(weapon:get_definition().sounds[s], { + object = self.object, --hitter, + max_hear_distance = 8 + }, true) + else + minetest.sound_play("default_punch", { + object = self.object, + max_hear_distance = 5 + }, true) + end + + self:damage_effect(damage) + + -- do damage + self.health = self.health - damage + + -- skip future functions if dead, except alerting others + if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then + die = true + end + end + -- knock back effect (only on full punch) + if self.knock_back + and tflp >= punch_interval then + -- direction error check + dir = dir or {x = 0, y = 0, z = 0} + + local v = self.object:get_velocity() + 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 + + if die==true then + kb=kb*2 + end + + -- if already in air then dont go up anymore when hit + if math.abs(v.y) > 0.1 + or self.fly then + up = 0 + end + + + -- check if tool already has specific knockback value + if tool_capabilities.damage_groups["knockback"] then + kb = tool_capabilities.damage_groups["knockback"] + else + kb = kb * 1.5 + end + + + local luaentity + if hitter then + luaentity = hitter:get_luaentity() + 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 + luaentity._knockback + end + self._kb_turn = true + self._turn_to=self.object:get_yaw()-1.57 + self.frame_speed_multiplier=2.3 + if self.animation.run_end then + self:set_animation( "run") + elseif self.animation.walk_end then + self:set_animation( "walk") + end + minetest.after(0.2, function() + if self and self.object then + self.frame_speed_multiplier=1 + self._kb_turn = false + end + end) + self.object:add_velocity({ + x = dir.x * kb, + y = up*2, + z = dir.z * kb + }) + + self.pause_timer = 0.25 + end + end -- END if damage + + -- if skittish then run away + if hitter and is_player and hitter:get_pos() and not die and self.runaway == true and self.state ~= "flop" then + + local yaw = self:set_yaw( minetest.dir_to_yaw(vector.direction(hitter:get_pos(), self.object:get_pos()))) + minetest.after(0.2,function() + if self and self.object and self.object:get_pos() and hitter and is_player and hitter:get_pos() then + yaw = self:set_yaw( minetest.dir_to_yaw(vector.direction(hitter:get_pos(), self.object:get_pos()))) + self:set_velocity( self.run_velocity) + end + end) + self.state = "runaway" + self.runaway_timer = 0 + self.following = nil + end + + local name = hitter:get_player_name() or "" + + -- attack puncher + if self.passive == false + and self.state ~= "flop" + and (self.child == false or self.type == "monster") + and hitter:get_player_name() ~= self.owner + and not mcl_mobs.invis[ name ] then + if not die then + -- attack whoever punched mob + self.state = "" + self:do_attack(hitter) + self._aggro= true + end + end + + -- alert others to the attack + local objs = minetest.get_objects_inside_radius(hitter:get_pos(), self.view_range) + local obj = nil + + for n = 1, #objs do + + 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 + end + end + end + end + + -- have owned mobs attack player threat + if obj.owner == name and obj.owner_loyal then + obj:do_attack(self.object) + end + end + end +end + +function mob_class:check_aggro(dtime) + if not self._aggro or not self.attack then return end + + if not self._check_aggro_timer then + self._check_aggro_timer = 0 + end + + if self._check_aggro_timer > 5 then + self._check_aggro_timer = 0 + + if self.attack then + -- TODO consider removing this in favour of what is done in do_states_attack + -- Attack is dropped in do_states_attack if out of range, so won't even trigger here + -- I do not think this code does anything. Are mobs still loaded in at 128? + if not self.attack:get_pos() or vector.distance(self.attack:get_pos(),self.object:get_pos()) > 128 then + self._aggro = nil + self.attack = nil + self.state = "stand" + end + end + end + self._check_aggro_timer = self._check_aggro_timer + dtime +end + + + +local function clear_aggro(self) + self.state = "stand" + self:set_velocity( 0) + self:set_animation( "stand") + + self.attack = nil + self._aggro = nil + + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.path.way = nil +end + +function mob_class:do_states_attack (dtime) + self.timer = self.timer + dtime + if self.timer > 100 then + self.timer = 1 + end + + local s = self.object:get_pos() + if not s then return end + + local p = self.attack:get_pos() or s + + local yaw = self.object:get_yaw() or 0 + + -- stop attacking if player invisible or out of range + if not self.attack + or not self.attack:get_pos() + or not self:object_in_range(self.attack) + or self.attack:get_hp() <= 0 + or (self.attack:is_player() and mcl_mobs.invis[ self.attack:get_player_name() ]) then + + clear_aggro(self) + return + end + + local target_line_of_sight = self:line_of_sight(s, p, 2) + if not target_line_of_sight then + if self.target_time_lost then + local time_since_seen = os.time() - self.target_time_lost + if time_since_seen > TIME_TO_FORGET_TARGET then + self.target_time_lost = nil + clear_aggro(self) + return + end + else + self.target_time_lost = os.time() + end + else + self.target_time_lost = nil + end + + -- calculate distance from mob and enemy + local dist = vector.distance(p, s) + + if self.attack_type == "explode" then + + if target_line_of_sight then + local vec = { x = p.x - s.x, z = p.z - s.z } + 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) + end + + local node_break_radius = self.explosion_radius or 1 + local entity_damage_radius = self.explosion_damage_radius + or (node_break_radius * 2) + + -- start timer when in reach and line of sight + if not self.v_start and dist <= self.reach and target_line_of_sight then + self.v_start = true + self.timer = 0 + self.blinktimer = 0 + self:mob_sound("fuse", nil, false) + + -- stop timer if out of reach or direct line of sight + elseif self.allow_fuse_reset and self.v_start + and (dist >= self.explosiontimer_reset_radius or not target_line_of_sight) then + self.v_start = false + self.timer = 0 + self.blinktimer = 0 + self.blinkstatus = false + self:remove_texture_mod("^[brighten") + end + + -- walk right up to player unless the timer is active + if self.v_start and (self.stop_to_explode or dist < self.reach) or not target_line_of_sight then + self:set_velocity(0) + else + self:set_velocity(self.run_velocity) + end + + if self.animation and self.animation.run_start then + self:set_animation( "run") + else + self:set_animation( "walk") + end + + if self.v_start then + self.timer = self.timer + dtime + self.blinktimer = (self.blinktimer or 0) + dtime + + if self.blinktimer > 0.2 then + self.blinktimer = 0 + if self.blinkstatus then + self:remove_texture_mod("^[brighten") + else + self:add_texture_mod("^[brighten") + end + self.blinkstatus = not self.blinkstatus + end + + if self.timer > self.explosion_timer then + local pos = self.object:get_pos() + + if mobs_griefing and not minetest.is_protected(pos, "") then + mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { drop_chance = 1.0 }, self.object) + else + minetest.sound_play(self.sounds.explode, { + pos = pos, + gain = 1.0, + max_hear_distance = self.sounds.distance or 32 + }, true) + self:entity_physics(pos,entity_damage_radius) + mcl_mobs.effect(pos, 32, "mcl_particles_smoke.png", nil, nil, node_break_radius, 1, 0) + end + mcl_burning.extinguish(self.object) + self.object:remove() + + return true + end + end + + elseif self.attack_type == "dogfight" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 2) and (dist >= self.avoid_distance or not self.shooter_avoid_enemy) + or (self.attack_type == "dogshoot" and dist <= self.reach and self:dogswitch() == 0) then + + if self.fly + and dist > self.reach then + + local p1 = s + local me_y = math.floor(p1.y) + local p2 = p + local p_y = math.floor(p2.y + 1) + local v = self.object:get_velocity() + + if self:flight_check( s) then + + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 1 * self.walk_velocity, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -1 * self.walk_velocity, + z = v.z + }) + end + else + if me_y < p_y then + + self.object:set_velocity({ + x = v.x, + y = 0.01, + z = v.z + }) + + elseif me_y > p_y then + + self.object:set_velocity({ + x = v.x, + y = -0.01, + z = v.z + }) + end + end + + end + + -- rnd: new movement direction + if self.path.following + and self.path.way + and self.attack_type ~= "dogshoot" then + + -- no paths longer than 50 + if #self.path.way > 50 + or dist < self.reach then + self.path.following = false + return + end + + local p1 = self.path.way[1] + + if not p1 then + self.path.following = false + return + end + + if math.abs(p1.x-s.x) + math.abs(p1.z - s.z) < 0.6 then + -- reached waypoint, remove it from queue + table.remove(self.path.way, 1) + end + + -- set new temporary target + p = {x = p1.x, y = p1.y, z = p1.z} + end + + local vec = { + x = p.x - s.x, + z = p.z - s.z + } + + 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) + + -- move towards enemy if beyond mob reach + if dist > self.reach then + -- path finding by rnd + if enable_pathfinding and self.pathfinding then + self:smart_mobs(s, p, dist, dtime) + end + + if self:is_at_cliff_or_danger() then + self:set_velocity( 0) + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + if self.path.stuck then + self:set_velocity(self.walk_velocity) + else + self:set_velocity(self.run_velocity) + end + if self.animation and self.animation.run_start then + self:set_animation("run") + else + self:set_animation("walk") + end + end + else -- rnd: if inside reach range + self.path.stuck = false + self.path.stuck_timer = 0 + self.path.following = false -- not stuck anymore + + self:set_velocity( 0) + + local attack_frequency = self.attack_frequency or 1 + + if self.timer > attack_frequency then + self.timer = 0 + + if not self.custom_attack then + if self.double_melee_attack and math.random(1, 2) == 1 then + self:set_animation("punch2") + else + self:set_animation("punch") + end + + local p2 = p + local s2 = s + + p2.y = p2.y + .5 + s2.y = s2.y + .5 + + if self:line_of_sight( p2, s2) == true then + self:mob_sound("attack") + + -- punch player (or what player is attached to) + local attached = self.attack:get_attach() + if attached then + self.attack = attached + end + self.attack:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.damage} + }, nil) + end + else + self.custom_attack(self, p) + end + end + end + + elseif self.attack_type == "shoot" + or (self.attack_type == "dogshoot" and self:dogswitch(dtime) == 1) + or (self.attack_type == "dogshoot" and (dist > self.reach or dist < self.avoid_distance and self.shooter_avoid_enemy) and self:dogswitch() == 0) then + + 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 + } + + 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.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 + + local p = self.object:get_pos() + p.y = p.y + (self.collisionbox[2] + self.collisionbox[5]) / 2 + + if self.shoot_interval + and self.timer > self.shoot_interval + and not minetest.raycast(vector.add(p, 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(p, 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(p, vec) + else + arrow:set_velocity(vec) + end + end + end + else + + end +end diff --git a/mods/ENTITIES/mcl_mobs/compat.lua b/mods/ENTITIES/mcl_mobs/compat.lua new file mode 100644 index 000000000..020a089b2 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/compat.lua @@ -0,0 +1,32 @@ + +-- this is to make the register_mob and register egg functions commonly used by mods not break +-- when they use the weird old : notation AND self as first argument +local oldregmob = mcl_mobs.register_mob +function mcl_mobs.register_mob(self,name,def) + if type(self) == "string" then + def = name + name = self + end + return oldregmob(name,def) +end +local oldregegg = mcl_mobs.register_egg +function mcl_mobs.register_egg(self, mob, desc, background_color, overlay_color, addegg, no_creative) + if type(self) == "string" then + no_creative = addegg + addegg = overlay_color + overlay_color = background_color + background_color = desc + desc = mob + mob = self + end + return oldregegg(mob, desc, background_color, overlay_color, addegg, no_creative) +end + +local oldregarrow = mcl_mobs.register_mob +function mcl_mobs.register_mob(self,name,def) + if type(self) == "string" then + def = name + name = self + end + return oldregarrow(name,def) +end diff --git a/mods/ENTITIES/mcl_mobs/description.txt b/mods/ENTITIES/mcl_mobs/description.txt deleted file mode 100644 index a426a1006..000000000 --- a/mods/ENTITIES/mcl_mobs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a mob API for mods to add animals or monsters, etc. diff --git a/mods/ENTITIES/mcl_mobs/effects.lua b/mods/ENTITIES/mcl_mobs/effects.lua new file mode 100644 index 000000000..aa44a67f7 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/effects.lua @@ -0,0 +1,456 @@ +local math, tonumber, vector, minetest, mcl_mobs = math, tonumber, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +local active_particlespawners = {} +local disable_blood = minetest.settings:get_bool("mobs_disable_blood") +local DEFAULT_FALL_SPEED = -9.81*1.5 + +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) + + radius = radius or 2 + min_size = min_size or 0.5 + max_size = max_size or 1 + gravity = gravity or DEFAULT_FALL_SPEED + glow = glow or 0 + go_down = go_down or false + + local ym + if go_down then + ym = 0 + else + ym = -radius + end + + minetest.add_particlespawner({ + amount = amount, + time = 0.25, + minpos = pos, + maxpos = pos, + minvel = {x = -radius, y = ym, z = -radius}, + maxvel = {x = radius, y = radius, z = radius}, + minacc = {x = 0, y = gravity, z = 0}, + maxacc = {x = 0, y = gravity, z = 0}, + minexptime = 0.1, + maxexptime = 1, + minsize = min_size, + maxsize = max_size, + texture = texture, + glow = glow, + }) +end + +function mcl_mobs.death_effect(pos, yaw, collisionbox, rotate) + local min, max + if collisionbox then + min = {x=collisionbox[1], y=collisionbox[2], z=collisionbox[3]} + max = {x=collisionbox[4], y=collisionbox[5], z=collisionbox[6]} + else + min = { x = -0.5, y = 0, z = -0.5 } + max = { x = 0.5, y = 0.5, z = 0.5 } + end + if rotate then + min = vector.rotate(min, {x=0, y=yaw, z=math.pi/2}) + max = vector.rotate(max, {x=0, y=yaw, z=math.pi/2}) + min, max = vector.sort(min, max) + min = vector.multiply(min, 0.5) + max = vector.multiply(max, 0.5) + end + + minetest.add_particlespawner({ + amount = 50, + time = 0.001, + minpos = vector.add(pos, min), + maxpos = vector.add(pos, max), + minvel = vector.new(-5,-5,-5), + maxvel = vector.new(5,5,5), + minexptime = 1.1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_mob_death.png^[colorize:#000000:255", + }) + + minetest.sound_play("mcl_mobs_mob_poof", { + pos = pos, + gain = 1.0, + max_hear_distance = 8, + }, true) +end + + +-- play sound +function mob_class:mob_sound(soundname, is_opinion, fixed_pitch) + + local soundinfo + if self.sounds_child and self.child then + soundinfo = self.sounds_child + elseif self.sounds then + soundinfo = self.sounds + end + if not soundinfo then + return + end + local sound = soundinfo[soundname] + if sound then + if is_opinion and self.opinion_sound_cooloff > 0 then + return + end + local pitch + if not fixed_pitch then + local base_pitch = soundinfo.base_pitch + if not base_pitch then + base_pitch = 1 + end + if self.child and (not self.sounds_child) then + -- Children have higher pitch + pitch = base_pitch * 1.5 + else + pitch = base_pitch + end + -- randomize the pitch a bit + pitch = pitch + math.random(-10, 10) * 0.005 + end + -- Should be 0.1 to 0.2 for mobs. Cow and zombie farms loud. At least have cool down. + minetest.sound_play(sound, { + object = self.object, + gain = 1.0, + max_hear_distance = self.sounds.distance, + pitch = pitch, + }, true) + self.opinion_sound_cooloff = 1 + end +end + +function mob_class:step_opinion_sound(dtime) + if self.state ~= "attack" and self.state ~= PATHFINDING then + + if self.opinion_sound_cooloff > 0 then + self.opinion_sound_cooloff = self.opinion_sound_cooloff - dtime + end + -- mob plays random sound at times. Should be 120. Zombie and mob farms are ridiculous + if math.random(1, 70) == 1 then + self:mob_sound("random", true) + end + end +end + +function mob_class:add_texture_mod(mod) + local full_mod = "" + local already_added = false + for i=1, #self.texture_mods do + if mod == self.texture_mods[i] then + already_added = true + end + full_mod = full_mod .. self.texture_mods[i] + end + if not already_added then + full_mod = full_mod .. mod + table.insert(self.texture_mods, mod) + end + self.object:set_texture_mod(full_mod) +end + +function mob_class:remove_texture_mod(mod) + local full_mod = "" + local remove = {} + for i=1, #self.texture_mods do + if self.texture_mods[i] ~= mod then + full_mod = full_mod .. self.texture_mods[i] + else + table.insert(remove, i) + end + end + for i=#remove, 1 do + table.remove(self.texture_mods, remove[i]) + end + self.object:set_texture_mod(full_mod) +end + +function mob_class:damage_effect(damage) + -- damage particles + if (not disable_blood) and damage > 0 then + + local amount_large = math.floor(damage / 2) + local amount_small = damage % 2 + + local pos = self.object:get_pos() + + pos.y = pos.y + (self.collisionbox[5] - self.collisionbox[2]) * .5 + + local texture = "mobs_blood.png" + -- full heart damage (one particle for each 2 HP damage) + if amount_large > 0 then + mcl_mobs.effect(pos, amount_large, texture, 2, 2, 1.75, 0, nil, true) + end + -- half heart damage (one additional particle if damage is an odd number) + if amount_small > 0 then + -- TODO: Use "half heart" + mcl_mobs.effect(pos, amount_small, texture, 1, 1, 1.75, 0, nil, true) + end + end +end + +function mob_class:remove_particlespawners(pn) + if not active_particlespawners[pn] then return end + if not active_particlespawners[pn][self.object] then return end + for k,v in pairs(active_particlespawners[pn][self.object]) do + minetest.delete_particlespawner(v) + end +end + +function mob_class:add_particlespawners(pn) + if not active_particlespawners[pn] then active_particlespawners[pn] = {} end + if not active_particlespawners[pn][self.object] then active_particlespawners[pn][self.object] = {} end + for _,ps in pairs(self.particlespawners) do + ps.attached = self.object + ps.playername = pn + table.insert(active_particlespawners[pn][self.object],minetest.add_particlespawner(ps)) + end +end + +function mob_class:check_particlespawners(dtime) + if not self.particlespawners then return end + --minetest.log(dump(active_particlespawners)) + if self._particle_timer and self._particle_timer >= 1 then + self._particle_timer = 0 + local players = {} + for _,player in pairs(minetest.get_connected_players()) do + local pn = player:get_player_name() + table.insert(players,pn) + if not active_particlespawners[pn] then + active_particlespawners[pn] = {} end + + local dst = vector.distance(player:get_pos(),self.object:get_pos()) + if dst < player_transfer_distance and not active_particlespawners[pn][self.object] then + self:add_particlespawners(pn) + elseif dst >= player_transfer_distance and active_particlespawners[pn][self.object] then + self:remove_particlespawners(pn) + end + end + elseif not self._particle_timer then + self._particle_timer = 0 + end + self._particle_timer = self._particle_timer + dtime +end + + +-- set defined animation +function mob_class:set_animation(anim, fixed_frame) + if not self.animation or not anim then + return + end + + if self.jockey and self.object:get_attach() then + anim = "jockey" + elseif not self.object:get_attach() then + self.jockey = nil + end + + if self.state == "die" and anim ~= "die" and anim ~= "stand" then + return + end + + + + if self.fly and self:flight_check() and anim == "walk" then anim = "fly" end + + self._current_animation = self._current_animation or "" + + if (anim == self._current_animation + or not self.animation[anim .. "_start"] + or not self.animation[anim .. "_end"]) and self.state ~= "die" then + return + end + + self._current_animation = anim + + local a_start = self.animation[anim .. "_start"] + local a_end + if fixed_frame then + a_end = a_start + else + a_end = self.animation[anim .. "_end"] + end + if a_start and a_end then + self.object:set_animation({ + x = a_start, + y = a_end}, + self.animation[anim .. "_speed"] or self.animation.speed_normal or 15, + 0, self.animation[anim .. "_loop"] ~= false) + end +end + +-- above function exported for mount.lua +function mcl_mobs:set_animation(self, anim) + self:set_animation(anim) +end + +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function who_are_you_looking_at (self, dtime) + local pos = self.object:get_pos() + + local stop_look_at_player_chance = math.random(833/self.curiosity) + -- was 10000 - div by 12 for avg entities as outside loop + + local stop_look_at_player = stop_look_at_player_chance == 1 + + if self.attack then + if not self.target_time_lost then + self._locked_object = self.attack + else + self._locked_object = nil + end + elseif self.following then + self._locked_object = self.following + elseif self._locked_object then + if stop_look_at_player then + --minetest.log("Stop look: ".. self.name) + self._locked_object = nil + end + elseif not self._locked_object then + if mcl_util.check_dtime_timer(self, dtime, "step_look_for_someone", 0.2) then + --minetest.log("Change look check: ".. self.name) + + -- For the wither this was 20/60=0.33, so probably need to rebalance and divide rates. + -- but frequency of check isn't good as it is costly. Making others too infrequent requires testing + local chance = 150/self.curiosity + + if chance < 1 then chance = 1 end + local look_at_player_chance = math.random(chance) + + -- was 5000 but called in loop based on entities. so div by 12 as estimate avg of entities found, + -- then div by 20 as less freq lookup + + local look_at_player = look_at_player_chance == 1 + + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 8)) do + if obj:is_player() and vector.distance(pos,obj:get_pos()) < 4 then + --minetest.log("Change look to player: ".. self.name) + self._locked_object = obj + break + elseif obj:is_player() or (obj:get_luaentity() and obj:get_luaentity().name == self.name and self ~= obj:get_luaentity()) then + if look_at_player then + --minetest.log("Change look to mob: ".. self.name) + self._locked_object = obj + break + end + end + end + end + + end +end + +function mob_class:check_head_swivel(dtime) + if not self.head_swivel or type(self.head_swivel) ~= "string" then return end + + + who_are_you_looking_at (self, dtime) + + local final_rotation = vector.zero() + local oldp,oldr = self.object:get_bone_position(self.head_swivel) + + if self._locked_object and (self._locked_object:is_player() or self._locked_object:get_luaentity()) and self._locked_object:get_hp() > 0 then + local _locked_object_eye_height = 1.5 + if self._locked_object:get_luaentity() then + _locked_object_eye_height = self._locked_object:get_luaentity().head_eye_height + end + if self._locked_object:is_player() then + _locked_object_eye_height = self._locked_object:get_properties().eye_height + end + if _locked_object_eye_height then + + local self_rot = self.object:get_rotation() + -- If a mob is attached, should we really be messing with what they are looking at? + -- Should this be excluded? + if self.object:get_attach() and self.object:get_attach():get_rotation() then + self_rot = self.object:get_attach():get_rotation() + end + + local player_pos = self._locked_object:get_pos() + local direction_player = vector.direction(vector.add(self.object:get_pos(), vector.new(0, self.head_eye_height*.7, 0)), vector.add(player_pos, vector.new(0, _locked_object_eye_height, 0))) + local mob_yaw = math.deg(-(-(self_rot.y)-(-minetest.dir_to_yaw(direction_player))))+self.head_yaw_offset + local mob_pitch = math.deg(-dir_to_pitch(direction_player))*self.head_pitch_multiplier + + if (mob_yaw < -60 or mob_yaw > 60) and not (self.attack and self.state == "attack" and not self.runaway) then + final_rotation = vector.multiply(oldr, 0.9) + elseif self.attack and self.state == "attack" and not self.runaway then + if self.head_yaw == "y" then + final_rotation = vector.new(mob_pitch, mob_yaw, 0) + elseif self.head_yaw == "z" then + final_rotation = vector.new(mob_pitch, 0, -mob_yaw) + end + + else + + if self.head_yaw == "y" then + final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, ((mob_yaw-oldr.y)*.3)+oldr.y, 0) + elseif self.head_yaw == "z" then + final_rotation = vector.new(((mob_pitch-oldr.x)*.3)+oldr.x, 0, -(((mob_yaw-oldr.y)*.3)+oldr.y)*3) + end + end + end + elseif not self._locked_object and math.abs(oldr.y) > 3 and math.abs(oldr.x) < 3 then + final_rotation = vector.multiply(oldr, 0.9) + else + --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) +end + + + +function mob_class:set_animation_speed() + local v = self.object:get_velocity() + if v then + if self.frame_speed_multiplier then + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + if not self.animation.walk_speed then + self.animation.walk_speed = 25 + end + if math.abs(v.x)+math.abs(v.z) > 0.5 then + self.object:set_animation_frame_speed((v2/math.max(1,self.run_velocity))*self.animation.walk_speed*self.frame_speed_multiplier) + else + self.object:set_animation_frame_speed(25) + end + end + --set_speed + if validate_vector(self.acc) then + self.object:add_velocity(self.acc) + end + end +end + +minetest.register_on_leaveplayer(function(player) + local pn = player:get_player_name() + if not active_particlespawners[pn] then return end + for _,m in pairs(active_particlespawners[pn]) do + for k,v in pairs(m) do + minetest.delete_particlespawner(v) + end + end + active_particlespawners[pn] = nil +end) diff --git a/mods/ENTITIES/mcl_mobs/init.lua b/mods/ENTITIES/mcl_mobs/init.lua index c2d6cb21b..62100c627 100644 --- a/mods/ENTITIES/mcl_mobs/init.lua +++ b/mods/ENTITIES/mcl_mobs/init.lua @@ -1,11 +1,574 @@ - -local path = minetest.get_modpath(minetest.get_current_modname()) - --- Mob API +mcl_mobs = {} +mcl_mobs.mob_class = {} +mcl_mobs.mob_class_meta = {__index = mcl_mobs.mob_class} +mcl_mobs.registered_mobs = {} +local modname = minetest.get_current_modname() +local path = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) +mcl_mobs.fallback_node = minetest.registered_aliases["mapgen_dirt"] or "mcl_core:dirt" +--api and helpers +-- effects: sounds and particles mostly +dofile(path .. "/effects.lua") +-- physics: involuntary mob movement - particularly falling and death +dofile(path .. "/physics.lua") +-- movement: general voluntary mob movement, walking avoiding cliffs etc. +dofile(path .. "/movement.lua") +-- items: item management for mobs +dofile(path .. "/items.lua") +-- pathfinding: pathfinding to target positions +dofile(path .. "/pathfinding.lua") +-- combat: attack logic +dofile(path .. "/combat.lua") +-- the enity functions themselves dofile(path .. "/api.lua") --- Rideable Mobs -dofile(path .. "/mount.lua") --- Mob Items +--utility functions +dofile(path .. "/breeding.lua") +dofile(path .. "/spawning.lua") +dofile(path .. "/mount.lua") dofile(path .. "/crafts.lua") +dofile(path .. "/compat.lua") + +local DEFAULT_FALL_SPEED = -9.81*1.5 +local MAX_MOB_NAME_LENGTH = 30 + +local old_spawn_icons = minetest.settings:get_bool("mcl_old_spawn_icons",false) +local extended_pet_control = minetest.settings:get_bool("mcl_extended_pet_control",true) +local difficulty = tonumber(minetest.settings:get("mob_difficulty")) or 1.0 + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + fallback = fallback or mcl_mobs.fallback_node + local node = minetest.get_node_or_nil(pos) + if node and minetest.registered_nodes[node.name] then + return node + end + return minetest.registered_nodes[fallback] +end + +--#### REGISTER FUNCS + +-- Code to execute before custom on_rightclick handling +local on_rightclick_prefix = function(self, clicker) + if not clicker:is_player() then return end + local item = clicker:get_wielded_item() + if extended_pet_control and self.tamed and self.owner == clicker:get_player_name() then + self:toggle_sit(clicker) + end + -- Name mob with nametag + if not self.ignores_nametag and item:get_name() == "mcl_mobs:nametag" then + + local tag = item:get_meta():get_string("name") + if tag ~= "" then + if string.len(tag) > MAX_MOB_NAME_LENGTH then + tag = string.sub(tag, 1, MAX_MOB_NAME_LENGTH) + end + self.nametag = tag + + self:update_tag() + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + item:take_item() + clicker:set_wielded_item(item) + end + return true + end + + end + + return false +end + +local create_mob_on_rightclick = function(on_rightclick) + return function(self, clicker) + local stop = on_rightclick_prefix(self, clicker) + if (not stop) and (on_rightclick) then + on_rightclick(self, clicker) + end + end +end + +-- check if within physical map limits (-30911 to 30927) +local function within_limits(pos, radius) + local wmin, wmax = -30912, 30928 + if mcl_vars then + if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then + wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max + end + end + if radius then + wmin = wmin - radius + wmax = wmax + radius + end + for _,v in pairs(pos) do + if v < wmin or v > wmax then return false end + end + return true +end + +mcl_mobs.spawning_mobs = {} +-- register mob entity +function mcl_mobs.register_mob(name, def) + + mcl_mobs.spawning_mobs[name] = true + mcl_mobs.registered_mobs[name] = def + + local can_despawn + if def.can_despawn ~= nil then + can_despawn = def.can_despawn + elseif def.spawn_class == "passive" then + can_despawn = false + else + can_despawn = true + end + + local function scale_difficulty(value, default, min, special) + if (not value) or (value == default) or (value == special) then + return default + else + return math.max(min, value * difficulty) + end + end + + local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25} + -- Workaround for : + -- Increase upper Y limit to avoid mobs glitching through solid nodes. + -- FIXME: Remove workaround if it's no longer needed. + if collisionbox[5] < 0.79 then + collisionbox[5] = 0.79 + end + local final_def = { + use_texture_alpha = def.use_texture_alpha, + head_swivel = def.head_swivel or nil, -- bool to activate this function + head_yaw_offset = def.head_yaw_offset or 0, -- for wonkey model bones + head_pitch_multiplier = def.head_pitch_multiplier or 1, --for inverted pitch + bone_eye_height = def.bone_eye_height or 1.4, -- head bone offset + 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, + wears_armor = def.wears_armor, -- a number value used to index texture slot for armor + stepheight = def.stepheight or 0.6, + name = name, + description = def.description, + type = def.type, + attack_type = def.attack_type, + attack_frequency = def.attack_frequency, + fly = def.fly or false, + fly_in = def.fly_in or {"air", "__airlike"}, + owner = def.owner or "", + order = def.order or "", + on_die = def.on_die, + spawn_small_alternative = def.spawn_small_alternative, + do_custom = def.do_custom, + detach_child = def.detach_child, + jump_height = def.jump_height or 4, -- was 6 + rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2 + lifetimer = def.lifetimer or 57.73, + hp_min = scale_difficulty(def.hp_min, 5, 1), + hp_max = scale_difficulty(def.hp_max, 10, 1), + xp_min = def.xp_min or 0, + xp_max = def.xp_max or 0, + xp_timestamp = 0, + breath_max = def.breath_max or 15, + breathes_in_water = def.breathes_in_water or false, + physical = true, + collisionbox = collisionbox, + selectionbox = def.selectionbox or def.collisionbox, + visual = def.visual, + visual_size = def.visual_size or {x = 1, y = 1}, + mesh = def.mesh, + makes_footstep_sound = def.makes_footstep_sound or false, + view_range = def.view_range or 16, + walk_velocity = def.walk_velocity or 1, + run_velocity = def.run_velocity or 2, + damage = scale_difficulty(def.damage, 0, 0), + light_damage = def.light_damage or 0, + sunlight_damage = def.sunlight_damage or 0, + water_damage = def.water_damage or 0, + lava_damage = def.lava_damage or 8, + fire_damage = def.fire_damage or 1, + suffocation = def.suffocation or true, + fall_damage = def.fall_damage or 1, + fall_speed = def.fall_speed or DEFAULT_FALL_SPEED, -- must be lower than -2 + drops = def.drops or {}, + armor = def.armor or 100, + on_rightclick = create_mob_on_rightclick(def.on_rightclick), + arrow = def.arrow, + shoot_interval = def.shoot_interval, + sounds = def.sounds or {}, + animation = def.animation or {}, + follow = def.follow, + nofollow = def.nofollow, + can_open_doors = def.can_open_doors, + jump = def.jump ~= false, + automatic_face_movement_max_rotation_per_sec = 300, + walk_chance = def.walk_chance or 50, + attacks_monsters = def.attacks_monsters or false, + group_attack = def.group_attack or false, + passive = def.passive or false, + knock_back = def.knock_back ~= false, + shoot_offset = def.shoot_offset or 0, + floats = def.floats or 1, -- floats in water by default + floats_on_lava = def.floats_on_lava or 0, + replace_rate = def.replace_rate, + replace_what = def.replace_what, + replace_with = def.replace_with, + replace_offset = def.replace_offset or 0, + on_replace = def.on_replace, + replace_delay = def.replace_delay or 0, + timer = 0, + env_damage_timer = 0, + tamed = false, + pause_timer = 0, + horny = false, + hornytimer = 0, + gotten = false, + health = 0, + frame_speed_multiplier = 1, + reach = def.reach or 3, + htimer = 0, + texture_list = def.textures, + child_texture = def.child_texture, + docile_by_day = def.docile_by_day or false, + time_of_day = 0.5, + fear_height = def.fear_height or 0, + runaway = def.runaway, + runaway_timer = 0, + pathfinding = def.pathfinding, + immune_to = def.immune_to or {}, + explosion_radius = def.explosion_radius, -- LEGACY + explosion_damage_radius = def.explosion_damage_radius, -- LEGACY + explosiontimer_reset_radius = def.explosiontimer_reset_radius, + explosion_timer = def.explosion_timer or 3, + allow_fuse_reset = def.allow_fuse_reset ~= false, + stop_to_explode = def.stop_to_explode ~= false, + custom_attack = def.custom_attack, + double_melee_attack = def.double_melee_attack, + dogshoot_switch = def.dogshoot_switch, + dogshoot_count = 0, + dogshoot_count_max = def.dogshoot_count_max or 5, + dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5), + attack_animals = def.attack_animals or false, + attack_npcs = def.attack_npcs or false, + specific_attack = def.specific_attack, + runaway_from = def.runaway_from, + owner_loyal = def.owner_loyal, + facing_fence = false, + is_mob = true, + pushable = def.pushable or true, + + -- MCL2 extensions + shooter_avoid_enemy = def.shooter_avoid_enemy, + strafes = def.strafes, + avoid_distance = def.avoid_distance or 9, + do_teleport = def.do_teleport, + spawn_class = def.spawn_class, + can_spawn = def.can_spawn, + ignores_nametag = def.ignores_nametag or false, + rain_damage = def.rain_damage or 0, + glow = def.glow, + can_despawn = can_despawn, + child = def.child or false, + texture_mods = {}, + shoot_arrow = def.shoot_arrow, + sounds_child = def.sounds_child, + _child_animations = def.child_animations, + pick_up = def.pick_up, + explosion_strength = def.explosion_strength, + suffocation_timer = 0, + follow_velocity = def.follow_velocity or 2.4, + instant_death = def.instant_death or false, + fire_resistant = def.fire_resistant or false, + fire_damage_resistant = def.fire_damage_resistant or false, + ignited_by_sunlight = def.ignited_by_sunlight or false, + spawn_in_group = def.spawn_in_group, + spawn_in_group_min = def.spawn_in_group_min, + noyaw = def.noyaw or false, + particlespawners = def.particlespawners, + -- End of MCL2 extensions + on_spawn = def.on_spawn, + on_blast = def.on_blast or function(self,damage) + self.object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = damage}, + }, nil) + return false, true, {} + end, + do_punch = def.do_punch, + on_breed = def.on_breed, + on_grown = def.on_grown, + on_pick_up = def.on_pick_up, + on_activate = function(self, staticdata, dtime) + --this is a temporary hack so mobs stop + --glitching and acting really weird with the + --default built in engine collision detection + self.is_mob = true + self.object:set_properties({ + collide_with_objects = false, + }) + + return self:mob_activate(staticdata, def, dtime) + end, + harmed_by_heal = def.harmed_by_heal, + on_lightning_strike = def.on_lightning_strike + } + 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") + end + +end -- END mcl_mobs.register_mob function + + +-- register arrow for shoot attack +function mcl_mobs.register_arrow(name, def) + + if not name or not def then return end -- errorcheck + + minetest.register_entity(name, { + + physical = false, + visual = def.visual, + visual_size = def.visual_size, + textures = def.textures, + velocity = def.velocity, + hit_player = def.hit_player, + hit_node = def.hit_node, + hit_mob = def.hit_mob, + hit_object = def.hit_object, + 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, + 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}) + end, + collisionbox = def.collisionbox or {0, 0, 0, 0, 0, 0}, + automatic_face_movement_dir = def.rotate + and (def.rotate - (math.pi / 180)) or false, + + on_activate = def.on_activate, + + on_step = def.on_step or function(self, dtime) + + self.timer = self.timer + 1 + + local pos = self.object:get_pos() + + if self.switch == 0 + or self.timer > 150 + or not within_limits(pos, 0) then + mcl_burning.extinguish(self.object) + self.object:remove(); + + return + end + + -- does arrow have a tail (fireball) + if def.tail + and def.tail == 1 + and def.tail_texture then + + minetest.add_particle({ + pos = pos, + velocity = {x = 0, y = 0, z = 0}, + acceleration = {x = 0, y = 0, z = 0}, + expirationtime = def.expire or 0.25, + collisiondetection = false, + texture = def.tail_texture, + size = def.tail_size or 5, + glow = def.glow or 0, + }) + end + + if self.hit_node then + + local node = node_ok(pos).name + + if minetest.registered_nodes[node].walkable then + + self.hit_node(self, pos, node) + + if self.drop == true then + + pos.y = pos.y + 1 + + self.lastpos = (self.lastpos or pos) + + minetest.add_item(self.lastpos, self.object:get_luaentity().name) + end + + self.object:remove(); + + return + 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 + + if self.hit_player + and player:is_player() then + + self.hit_player(self, player) + self.object:remove(); + return + end + + local entity = player:get_luaentity() + + if entity + and self.hit_mob + and entity.is_mob == true + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + self.hit_mob(self, player) + self.object:remove(); + return + end + + if entity + and self.hit_object + and (not entity.is_mob) + and tostring(player) ~= self.owner_id + and entity.name ~= self.object:get_luaentity().name then + self.hit_object(self, player) + self.object:remove(); + return + end + end + end + + self.lastpos = pos + end + }) +end + +-- Register spawn eggs + +-- Note: This also introduces the “spawn_egg” group: +-- * spawn_egg=1: Spawn egg (generic mob, no metadata) +-- * spawn_egg=2: Spawn egg (captured/tamed mob, metadata) +function mcl_mobs.register_egg(mob, desc, background_color, overlay_color, addegg, no_creative) + + local grp = {spawn_egg = 1} + + -- do NOT add this egg to creative inventory (e.g. dungeon master) + if no_creative == true then + grp.not_in_creative_inventory = 1 + end + + local invimg = "(spawn_egg.png^[multiply:" .. background_color ..")^(spawn_egg_overlay.png^[multiply:" .. overlay_color .. ")" + if old_spawn_icons then + local mobname = mob:gsub("mobs_mc:","") + local fn = "mobs_mc_spawn_icon_"..mobname..".png" + if mcl_util.file_exists(minetest.get_modpath("mobs_mc").."/textures/"..fn) then + invimg = fn + end + end + if addegg == 1 then + invimg = "mobs_chicken_egg.png^(" .. invimg .. + "^[mask:mobs_chicken_egg_overlay.png)" + end + + -- register old stackable mob egg + minetest.register_craftitem(mob, { + + description = desc, + inventory_image = invimg, + groups = grp, + + _doc_items_longdesc = S("This allows you to place a single mob."), + _doc_items_usagehelp = S("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."), + + on_place = function(itemstack, placer, pointed_thing) + + local pos = pointed_thing.above + + -- am I clicking on something with existing on_rightclick function? + local under = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[under.name] + if def and def.on_rightclick then + return def.on_rightclick(pointed_thing.under, under, placer, itemstack) + end + + if pos and within_limits(pos, 0) and not minetest.is_protected(pos, placer:get_player_name()) then + local name = placer:get_player_name() + local privs = minetest.get_player_privs(name) + + + if under.name == "mcl_mobspawners:spawner" then + if minetest.is_protected(pointed_thing.under, name) then + minetest.record_protection_violation(pointed_thing.under, name) + return itemstack + end + if not privs.maphack then + minetest.chat_send_player(name, S("You need the “maphack” privilege to change the mob spawner.")) + return itemstack + end + + local dim = mcl_worlds.pos_to_dimension(placer:get_pos()) + local mob_light_lvl = {mcl_mobs:mob_light_lvl(itemstack:get_name(),dim)} + + --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]) + if not minetest.is_creative_enabled(name) then + itemstack:take_item() + end + return itemstack + end + + if not minetest.registered_entities[mob] then + return itemstack + end + + if minetest.settings:get_bool("only_peaceful_mobs", false) + and minetest.registered_entities[mob].type == "monster" then + minetest.chat_send_player(name, S("Only peaceful mobs allowed!")) + return itemstack + end + + pos.y = pos.y - 0.5 + + local mob = minetest.add_entity(pos, mob) + local entityname = itemstack:get_name() + minetest.log("action", "Player " ..name.." spawned "..entityname.." at "..minetest.pos_to_string(pos)) + local ent = mob:get_luaentity() + + -- don't set owner if monster or sneak pressed + if ent.type ~= "monster" + and not placer:get_player_control().sneak then + ent.owner = placer:get_player_name() + ent.tamed = true + end + + -- set nametag + local nametag = itemstack:get_meta():get_string("name") + if nametag ~= "" then + if string.len(nametag) > MAX_MOB_NAME_LENGTH then + nametag = string.sub(nametag, 1, MAX_MOB_NAME_LENGTH) + end + ent.nametag = nametag + ent:update_tag() + end + + -- if not in creative then take item + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + end + + return itemstack + end, + }) + +end diff --git a/mods/ENTITIES/mcl_mobs/items.lua b/mods/ENTITIES/mcl_mobs/items.lua new file mode 100644 index 000000000..267dd8595 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/items.lua @@ -0,0 +1,103 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +--- Item and armor management + +local function player_near(pos) + for _,o in pairs(minetest.get_objects_inside_radius(pos,2)) do + if o:is_player() then return true end + end +end + +local function get_armor_texture(armor_name) + if armor_name == "" then + return "" + end + if armor_name=="blank.png" then + return "blank.png" + end + local seperator = string.find(armor_name, ":") + return "mcl_armor_"..string.sub(armor_name, seperator+1, -1)..".png^" +end + +function mob_class:set_armor_texture() + if self.armor_list then + local chestplate=minetest.registered_items[self.armor_list.chestplate] or {name=""} + local boots=minetest.registered_items[self.armor_list.boots] or {name=""} + local leggings=minetest.registered_items[self.armor_list.leggings] or {name=""} + local helmet=minetest.registered_items[self.armor_list.helmet] or {name=""} + + if helmet.name=="" and chestplate.name=="" and leggings.name=="" and boots.name=="" then + helmet={name="blank.png"} + end + local texture = get_armor_texture(chestplate.name)..get_armor_texture(helmet.name)..get_armor_texture(boots.name)..get_armor_texture(leggings.name) + if string.sub(texture, -1,-1) == "^" then + texture=string.sub(texture,1,-2) + end + if self.textures[self.wears_armor] then + self.textures[self.wears_armor]=texture + end + self.object:set_properties({textures=self.textures}) + + local armor_ + if type(self.armor) == "table" then + armor_ = table.copy(self.armor) + armor_.immortal = 1 + else + armor_ = {immortal=1, fleshy = self.armor} + end + + for _,item in pairs(self.armor_list) do + if not item then return end + if type(minetest.get_item_group(item, "mcl_armor_points")) == "number" then + armor_.fleshy=armor_.fleshy-(minetest.get_item_group(item, "mcl_armor_points")*3.5) + end + end + self.object:set_armor_groups(armor_) + end +end + +function mob_class:check_item_pickup() + if self.pick_up and #self.pick_up > 0 or self.wears_armor then + local p = self.object:get_pos() + if not p then return end + for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do + local l=o:get_luaentity() + if l and l.name == "__builtin:item" then + if not player_near(p) and l.itemstring:find("mcl_armor") and self.wears_armor then + local armor_type + if l.itemstring:find("chestplate") then + armor_type = "chestplate" + elseif l.itemstring:find("boots") then + armor_type = "boots" + elseif l.itemstring:find("leggings") then + armor_type = "leggings" + elseif l.itemstring:find("helmet") then + armor_type = "helmet" + end + if not armor_type then + return + end + if not self.armor_list then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + elseif self.armor_list[armor_type] and self.armor_list[armor_type] ~= "" then + return + end + self.armor_list[armor_type]=ItemStack(l.itemstring):get_name() + o:remove() + 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 r = self.on_pick_up(self,l) + if r and r.is_empty and not r:is_empty() then + l.itemstring = r:to_string() + elseif r and r.is_empty and r:is_empty() then + o:remove() + end + end + end + end + end + end + end +end diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.dk.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.dk.tr new file mode 100644 index 000000000..63f8e25cc --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.dk.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_mobs +Peaceful mode active! No monsters will spawn.=Fredelig tilstand aktiveret! Ingen monstre vil spawne. +This allows you to place a single mob.=Dette gør dig i stand til at placere et enkelt monster. +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.=Placér det blot der hvor du ønsker, at monsteret skal komme. Dyr vil spawne tamme, medmindre du holder snige-knappen nede mens du placerer dem. Hvis du placerer denne på et monsterspawn, ændrer du hvilket monster det spawner. +You need the “maphack” privilege to change the mob spawner.=Du skal have "maphack" privilegier for at ændre monsterspawneren. +Name Tag=Navneskilt +A name tag is an item to name a mob.=Et navneskilt bruges til at navngive et monster. +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.=Før du bruger navneskiltet, skal du vælge navnet ved en ambolt. Derefter kan du bruge navneskiltet til at navngive et monster. Dette opbruger navneskiltet. +Only peaceful mobs allowed!=Kun fredelige monstre er tilladt! +Give names to mobs=Giv navne til monstre +Set name at anvil=Vælg navn ved en ambolt. diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.fr.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.fr.tr index 96ac6a817..58fcaa51d 100644 --- a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.fr.tr +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.fr.tr @@ -9,3 +9,5 @@ Before you use the name tag, you need to set a name at an anvil. Then you can us Only peaceful mobs allowed!=Seuls les mobs pacifiques sont autorisées! Give names to mobs=Donne des noms aux mobs Set name at anvil=Définir le nom sur l'enclume +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.=Enlève les mobs spécifiés sauf ceux qui sont nommés et apprivoisés. Pour le deuxième paramètre, utiliser nametagged/tamed pour ne sélectionner que les mobs nommés/apprivoisés, ou une distance pour spécifier la distance maximale par rapport au joueur. +Default usage. Clearing hostile mobs. For more options please type: /help clearmobs=Usage par défaut. Enlève les mobs hostiles. Pour plus d'options saisir : /help clearmobs diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr new file mode 100644 index 000000000..a97d3e545 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ja.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_mobs +Peaceful mode active! No monsters will spawn.=ピースフルモード有効! モンスターは出現しません。 +This allows you to place a single mob.=これにより、1体の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.=MOBを出現させたい場所に、置くだけです。スニークキーを押しながら配置しない限り、動物は飼いならされた状態でスポーンします。MOBスポナーに設置すると、スポーンするMOBが変わります。 +You need the “maphack” privilege to change the mob spawner.=MOBスポナーを変更するには、"maphack"権限が必要です。 +Name Tag=名札 +A name tag is an item to name a mob.=名札は、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.=名札を使用する前に、金床で名前の設定をする必要があります。その後、MOBに名前をつけるために名札が使えます。これで名札は使い切ります。 +Only peaceful mobs allowed!=平和的なMOBのみ許可! +Give names to mobs=MOBに名前を付与 +Set name at anvil=金床で名前の設定 diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr index 3fb2eb2f1..477d3d642 100644 --- a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.ru.tr @@ -1,11 +1,11 @@ # 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”, чтобы изменить спаунер моба. +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.=Именная бирка это предмет, чтобы дать мобу имя. +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=Даёт имена мобам +Only peaceful mobs allowed!=Разрешены только мирные существа! +Give names to mobs=Даёт имена существам Set name at anvil=Задайте имя при помощи наковальни diff --git a/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.zh_TW.tr b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.zh_TW.tr new file mode 100644 index 000000000..90d24fd21 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/locale/mcl_mobs.zh_TW.tr @@ -0,0 +1,11 @@ +# 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=在鐵砧上設置名字 diff --git a/mods/ENTITIES/mcl_mobs/locale/template.txt b/mods/ENTITIES/mcl_mobs/locale/template.txt index e24974a41..9674a8ca6 100644 --- a/mods/ENTITIES/mcl_mobs/locale/template.txt +++ b/mods/ENTITIES/mcl_mobs/locale/template.txt @@ -9,3 +9,5 @@ Before you use the name tag, you need to set a name at an anvil. Then you can us 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.= +Default usage. Clearing hostile mobs. For more options please type: /help clearmobs= diff --git a/mods/ENTITIES/mcl_mobs/mod.conf b/mods/ENTITIES/mcl_mobs/mod.conf index c3d971374..9c10e9a2b 100644 --- a/mods/ENTITIES/mcl_mobs/mod.conf +++ b/mods/ENTITIES/mcl_mobs/mod.conf @@ -1,3 +1,5 @@ name = mcl_mobs +author = PilzAdam +description = Adds a mob API for mods to add animals or monsters, etc. depends = mcl_particles -optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience +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/mount.lua b/mods/ENTITIES/mcl_mobs/mount.lua index 8c4a6aa55..21c52157a 100644 --- a/mods/ENTITIES/mcl_mobs/mount.lua +++ b/mods/ENTITIES/mcl_mobs/mount.lua @@ -1,4 +1,5 @@ - +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class -- lib_mount by Blert2112 (edited by TenPlus1) local enable_crash = false @@ -12,7 +13,7 @@ local crash_threshold = 6.5 -- ignored if enable_crash=false local node_ok = function(pos, fallback) - fallback = fallback or mobs.fallback_node + fallback = fallback or mcl_mobs.fallback_node local node = minetest.get_node_or_nil(pos) @@ -119,7 +120,7 @@ end) ------------------------------------------------------------------------------- -function mobs.attach(entity, player) +function mcl_mobs.attach(entity, player) local attach_at, eye_offset @@ -154,7 +155,7 @@ function mobs.attach(entity, player) minetest.after(0.2, function(name) local player = minetest.get_player_by_name(name) if player then - mcl_player.player_set_animation(player, "sit" , 30) + mcl_player.player_set_animation(player, "sit_mount" , 30) end end, player:get_player_name()) @@ -162,26 +163,30 @@ function mobs.attach(entity, player) end -function mobs.detach(player, offset) +function mcl_mobs.detach(player, offset) force_detach(player) mcl_player.player_set_animation(player, "stand" , 30) - local pos = player:get_pos() + --local pos = player:get_pos() - pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + --pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z} + player:add_velocity(vector.new(math.random(-6,6),math.random(5,8),math.random(-6,6))) --throw the rider off + + --[[ minetest.after(0.1, function(name, pos) local player = minetest.get_player_by_name(name) if player then player:set_pos(pos) end end, player:get_player_name(), pos) + ]]-- end -function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) +function mcl_mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) local rot_view = 0 @@ -202,7 +207,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- move forwards if ctrl.up then - entity.v = entity.v + entity.accel / 10 + entity.v = entity.v + entity.accel / 10 * entity.run_velocity / 2.6 -- move backwards elseif ctrl.down then @@ -257,7 +262,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then if stand_anim then - mobs:set_animation(entity, stand_anim) + mcl_mobs:set_animation(entity, stand_anim) end return @@ -265,7 +270,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) -- set moving animation if moving_anim then - mobs:set_animation(entity, moving_anim) + mcl_mobs:set_animation(entity, moving_anim) end -- Stop! @@ -381,10 +386,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) entity.v2 = v end - -- directional flying routine by D00Med (edited by TenPlus1) -function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) +function mcl_mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) local ctrl = entity.driver:get_player_control() local velo = entity.object:get_velocity() @@ -436,9 +440,24 @@ function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim) -- change animation if stopped if velo.x == 0 and velo.y == 0 and velo.z == 0 then - mobs:set_animation(entity, stand_anim) + mcl_mobs:set_animation(entity, stand_anim) else -- moving animation - mobs:set_animation(entity, moving_anim) + mcl_mobs:set_animation(entity, moving_anim) + end +end + +mcl_mobs.mob_class.drive = mcl_mobs.drive +mcl_mobs.mob_class.fly = mcl_mobs.fly +mcl_mobs.mob_class.attach = mcl_mobs.attach + +function mob_class:on_detach_child(child) + if self.detach_child then + if self.detach_child(self, child) then + return + end + end + if self.driver == child then + self.driver = nil end end diff --git a/mods/ENTITIES/mcl_mobs/movement.lua b/mods/ENTITIES/mcl_mobs/movement.lua new file mode 100644 index 000000000..317ac9f28 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/movement.lua @@ -0,0 +1,1033 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class +local DEFAULT_FALL_SPEED = -9.81*1.5 +local FLOP_HEIGHT = 6 +local FLOP_HOR_SPEED = 1.5 + +local CHECK_HERD_FREQUENCY = 4 + +local PATHFINDING = "gowp" + +local node_snow = "mcl_core:snow" + +local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false + +local atann = math.atan +local function atan(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +local registered_fallback_node = minetest.registered_nodes[mcl_mobs.fallback_node] + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + local node = minetest.get_node_or_nil(pos) + if node and minetest.registered_nodes[node.name] then + return node + end + if fallback then + return minetest.registered_nodes[fallback] + else + return registered_fallback_node + end +end + +-- Returns true is node can deal damage to self +function mob_class:is_node_dangerous(nodename) + local nn = nodename + if self.lava_damage > 0 then + if minetest.get_item_group(nn, "lava") ~= 0 then + return true + end + end + if self.fire_damage > 0 then + if minetest.get_item_group(nn, "fire") ~= 0 then + return true + end + end + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then + return true + end + return false +end + + +-- Returns true if node is a water hazard +function mob_class:is_node_waterhazard(nodename) + local nn = nodename + if self.water_damage > 0 then + if minetest.get_item_group(nn, "water") ~= 0 then + return true + end + end + if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].drowning and minetest.registered_nodes[nn].drowning > 0 then + if self.breath_max ~= -1 then + -- check if the mob is water-breathing _and_ the block is water; only return true if neither is the case + -- this will prevent water-breathing mobs to classify water or e.g. sand below them as dangerous + if not self.breathes_in_water and minetest.get_item_group(nn, "water") ~= 0 then + return true + end + end + end + return false +end + +-- check line of sight (BrunoMine) +function mob_class:line_of_sight(pos1, pos2, stepsize) + + stepsize = stepsize or 1 + + local s, pos = minetest.line_of_sight(pos1, pos2, stepsize) + + -- normal walking and flying mobs can see you through air + if s == true then + return true + end + + -- New pos1 to be analyzed + local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z} + + local r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + -- Checks the return + if r == true then return true end + + -- Nodename found + local nn = minetest.get_node(pos).name + + -- Target Distance (td) to travel + local td = vector.distance(pos1, pos2) + + -- Actual Distance (ad) traveled + local ad = 0 + + -- It continues to advance in the line of sight in search of a real + -- obstruction which counts as 'normal' nodebox. + while minetest.registered_nodes[nn] + and minetest.registered_nodes[nn].walkable == false do + + -- Check if you can still move forward + if td < ad + stepsize then + return true -- Reached the target + end + + -- Moves the analyzed pos + local d = vector.distance(pos1, pos2) + + npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x + npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y + npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z + + -- NaN checks + if d == 0 + or npos1.x ~= npos1.x + or npos1.y ~= npos1.y + or npos1.z ~= npos1.z then + return false + end + + ad = ad + stepsize + + -- scan again + r, pos = minetest.line_of_sight(npos1, pos2, stepsize) + + if r == true then return true end + + -- New Nodename found + nn = minetest.get_node(pos).name + + end + + return false +end + +function mob_class:can_jump_cliff() + local yaw = self.object:get_yaw() + local pos = self.object:get_pos() + local v = self.object:get_velocity() + + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + local jump_c_multiplier = 1 + if v2/self.walk_velocity/2>1 then + jump_c_multiplier = v2/self.walk_velocity/2 + end + + -- where is front + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+0.6 + + --is there nothing under the block in front? if so jump the gap. + local nodLow = node_ok({ + x = pos.x + dir_x-0.6, + y = pos.y - 0.5, + z = pos.z + dir_z-0.6 + }, "air") + + local nodFar = node_ok({ + x = pos.x + dir_x*2, + y = pos.y - 0.5, + z = pos.z + dir_z*2 + }, "air") + + local nodFar2 = node_ok({ + x = pos.x + dir_x*2.5, + y = pos.y - 0.5, + z = pos.z + dir_z*2.5 + }, "air") + + + if minetest.registered_nodes[nodLow.name] + and minetest.registered_nodes[nodLow.name].walkable ~= true + + + and (minetest.registered_nodes[nodFar.name] + and minetest.registered_nodes[nodFar.name].walkable == true + + or minetest.registered_nodes[nodFar2.name] + and minetest.registered_nodes[nodFar2.name].walkable == true) + + then + --disable fear heigh while we make our jump + self._jumping_cliff = true + minetest.after(1, function() + if self and self.object then + self._jumping_cliff = false + end + end) + return true + else + return false + end +end + +-- is mob facing a cliff or danger +function mob_class:is_at_cliff_or_danger() + if self.fear_height == 0 or self._jumping_cliff or self._can_jump_cliff or not self.object:get_luaentity() then -- 0 for no falling protection! + return false + end + + local yaw = self.object:get_yaw() + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5) + + local pos = self.object:get_pos() + local ypos = pos.y + self.collisionbox[2] -- just above floor + + local free_fall, blocker = minetest.line_of_sight( + vector.new(pos.x + dir_x, ypos, pos.z + dir_z), + vector.new(pos.x + dir_x, ypos - self.fear_height, pos.z + dir_z)) + + if free_fall then + return true + else + local bnode = minetest.get_node(blocker) + local danger = self:is_node_dangerous(bnode.name) + if danger then + return true + else + local def = minetest.registered_nodes[bnode.name] + if def and def.walkable then + return false + end + end + end + + return false +end + + +-- copy the 'mob facing cliff_or_danger check' from above, and rework to avoid water +function mob_class:is_at_water_danger() + if self.water_damage == 0 and self.breath_max == -1 then + --minetest.log("Do not need a water check for: " .. self.name) + return + end + + local in_water_danger = self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on) + if in_water_danger then return false end -- If you're in trouble, do not stop + + if not self.object:get_luaentity() or self._jumping_cliff or self._can_jump_cliff then + return false + end + local yaw = self.object:get_yaw() + local pos = self.object:get_pos() + + if not yaw or not pos then + return + end + + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5) + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5) + + local ypos = pos.y + self.collisionbox[2] -- just above floor + + local los, blocker = minetest.line_of_sight( + vector.new(pos.x + dir_x, ypos, pos.z + dir_z), + vector.new(pos.x + dir_x, ypos - 3, pos.z + dir_z)) + + if not los then + local bnode = minetest.get_node(blocker) + local waterdanger = self:is_node_waterhazard(bnode.name) + + if waterdanger and not in_water_danger then + return true + end + end + + return false +end + +function mob_class:env_danger_movement_checks(player_in_active_range) + local yaw = 0 + + if not player_in_active_range then return end + + if self.state == PATHFINDING + or self.state == "attack" + or self.state == "stand" + or self.state == "runaway" then + return + end + + if self:is_at_water_danger() then + --minetest.log("At water danger for mob, stop?: " .. self.name) + if math.random(1, 10) <= 7 then + if self.state ~= "stand" then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + end + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + return + end + end + + --[[if self:is_at_cliff_or_danger(can_jump_cliff) then + if self.state ~= "stand" then + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + end + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + end--]] +end + +-- jump if facing a solid node (not fences or gates) +function mob_class:do_jump() + if not self.jump + or self.jump_height == 0 + or self.fly + or self.order == "stand" then + return false + end + + self.facing_fence = false + + -- something stopping us while moving? + if self.state ~= "stand" + and self:get_velocity() > 0.5 + and self.object:get_velocity().y ~= 0 then + return false + end + + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + + -- what is mob standing on? + pos.y = pos.y + self.collisionbox[2] - 0.2 + + local nod = node_ok(pos) + + if minetest.registered_nodes[nod.name].walkable == false then + return false + end + + local v = self.object:get_velocity() + local v2 = math.abs(v.x)+math.abs(v.z)*.833 + local jump_c_multiplier = 1 + if v2/self.walk_velocity/2>1 then + jump_c_multiplier = v2/self.walk_velocity/2 + end + + local yaw_dir = minetest.yaw_to_dir(self.object:get_yaw()) + + -- where is front + local dir_x = -math.sin(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+yaw_dir.x + local dir_z = math.cos(yaw) * (self.collisionbox[4] + 0.5)*jump_c_multiplier+yaw_dir.z + + -- what is in front of mob? + nod = node_ok({ + x = pos.x + dir_x, + y = pos.y + 0.5, + z = pos.z + dir_z + }) + + -- this is used to detect if there's a block on top of the block in front of the mob. + -- If there is, there is no point in jumping as we won't manage. + local nodTop = node_ok({ + x = pos.x + dir_x, + y = pos.y + 1.5, + z = pos.z + dir_z + }, "air") + + + -- we don't attempt to jump if there's a stack of blocks blocking + if minetest.registered_nodes[nodTop.name].walkable == true and not (self.attack and self.state == "attack") then + return false + end + + -- thin blocks that do not need to be jumped + if nod.name == node_snow then + return false + end + + local ndef = minetest.registered_nodes[nod.name] + if self.walk_chance == 0 or ndef and ndef.walkable or self._can_jump_cliff then + + if minetest.get_item_group(nod.name, "fence") == 0 + and minetest.get_item_group(nod.name, "fence_gate") == 0 + and minetest.get_item_group(nod.name, "wall") == 0 then + + local v = self.object:get_velocity() + + v.y = self.jump_height + 0.1 * 3 + + if self._can_jump_cliff then + v=vector.multiply(v, vector.new(2.8,1,2.8)) + end + + self:set_animation( "jump") -- only when defined + + self.object:set_velocity(v) + + -- when in air move forward + minetest.after(0.3, function(self, v) + if (not self.object) or (not self.object:get_luaentity()) or (self.state == "die") then + return + end + self.object:set_acceleration({ + x = v.x * 2, + y = DEFAULT_FALL_SPEED, + z = v.z * 2, + }) + end, self, v) + + if self.jump_sound_cooloff <= 0 then + self:mob_sound("jump") + self.jump_sound_cooloff = 0.5 + end + else + self.facing_fence = true + end + + -- if we jumped against a block/wall 4 times then turn + if self.object:get_velocity().x ~= 0 + and self.object:get_velocity().z ~= 0 then + + self.jump_count = (self.jump_count or 0) + 1 + + if self.jump_count == 4 then + + local yaw = self.object:get_yaw() or 0 + + yaw = self:set_yaw( yaw + 1.35, 8) + + self.jump_count = 0 + end + end + + return true + end + + return false +end + +-- should mob follow what I'm holding ? +function mob_class:follow_holding(clicker) + if self.nofollow then return false end + + if mcl_mobs.invis[clicker:get_player_name()] then + return false + end + + local item = clicker:get_wielded_item() + local t = type(self.follow) + + -- single item + if t == "string" + and item:get_name() == self.follow then + return true + + -- multiple items + elseif t == "table" then + + for no = 1, #self.follow do + + if self.follow[no] == item:get_name() then + return true + end + end + end + + return false +end + + +-- find and replace what mob is looking for (grass, wheat etc.) +function mob_class:replace_node(pos) + + + if not self.replace_rate + or not self.replace_what + or self.child == true + or self.object:get_velocity().y ~= 0 + or math.random(1, self.replace_rate) > 1 then + return + end + + local what, with, y_offset + + if type(self.replace_what[1]) == "table" then + + local num = math.random(#self.replace_what) + + what = self.replace_what[num][1] or "" + with = self.replace_what[num][2] or "" + y_offset = self.replace_what[num][3] or 0 + else + what = self.replace_what + with = self.replace_with or "" + y_offset = self.replace_offset or 0 + end + + pos.y = pos.y + y_offset + + local node = minetest.get_node(pos) + if node.name == what then + + local oldnode = {name = what, param2 = node.param2} + local newnode = {name = with, param2 = node.param2} + local on_replace_return = false + if self.on_replace then + on_replace_return = self.on_replace(self, pos, oldnode, newnode) + end + + + if on_replace_return ~= false then + + if mobs_griefing then + minetest.after(self.replace_delay, function() + if self and self.object and self.object:get_velocity() and self.health > 0 then + minetest.set_node(pos, newnode) + end + end) + end + end + end +end + +-- specific runaway +local specific_runaway = function(list, what) + if type(list) ~= "table" then + list = {} + end + + -- no list so do not run + if list == nil then + return false + end + + -- found entity on list to attack? + for no = 1, #list do + + if list[no] == what then + return true + end + end + + return false +end + + +-- find someone to runaway from +function mob_class:check_runaway_from() + if not self.runaway_from and self.state ~= "flop" then + return + end + + local s = self.object:get_pos() + local p, sp, dist + local player, obj, min_player + local type, name = "", "" + local min_dist = self.view_range + 1 + local objs = minetest.get_objects_inside_radius(s, self.view_range) + + for n = 1, #objs do + + if objs[n]:is_player() then + + if mcl_mobs.invis[ objs[n]:get_player_name() ] + or self.owner == objs[n]:get_player_name() + or (not self:object_in_range(objs[n])) then + type = "" + else + player = objs[n] + type = "player" + name = "player" + end + else + obj = objs[n]:get_luaentity() + + if obj then + player = obj.object + type = obj.type + name = obj.name or "" + end + end + + -- find specific mob to runaway from + if name ~= "" and name ~= self.name + and specific_runaway(self.runaway_from, name) then + + p = player:get_pos() + sp = s + + -- aim higher to make looking up hills more realistic + p.y = p.y + 1 + sp.y = sp.y + 1 + + dist = vector.distance(p, s) + + + -- choose closest player/mpb to runaway from + if dist < min_dist + and self:line_of_sight(sp, p, 2) == true then + min_dist = dist + min_player = player + end + end + end + + if min_player then + + local lp = player:get_pos() + local vec = { + x = lp.x - s.x, + y = lp.y - s.y, + z = lp.z - s.z + } + + local yaw = (atan(vec.z / vec.x) + 3 *math.pi/ 2) - self.rotate + + if lp.x > s.x then + yaw = yaw + math.pi + end + + yaw = self:set_yaw( yaw, 4) + self.state = "runaway" + self.runaway_timer = 3 + self.following = nil + end +end + + +-- follow player if owner or holding item +function mob_class:check_follow() + -- find player to follow + if (self.follow ~= "" or self.order == "follow") and not self.following + and self.state ~= "attack" + and self.order ~= "sit" + and self.state ~= "runaway" then + local s = self.object:get_pos() + local players = minetest.get_connected_players() + for n = 1, #players do + if (self:object_in_range(players[n])) and not mcl_mobs.invis[ players[n]:get_player_name() ] then + self.following = players[n] + break + end + end + end + + if self.type == "npc" and self.order == "follow" + and self.state ~= "attack" and self.order ~= "sit" and self.owner ~= "" then + + if self.following and self.owner and self.owner ~= self.following:get_player_name() then + self.following = nil + end + else + -- stop following player if not holding specific item, + -- mob is horny, fleeing or attacking + if self.following and self.following:is_player() + and (self:follow_holding(self.following) == false or self.horny or self.state == "runaway") then + self.following = nil + end + end + + -- follow that thing + if self.following then + local s = self.object:get_pos() + + local p + if self.following:is_player() then + p = self.following:get_pos() + elseif self.following.object then + p = self.following.object:get_pos() + end + + if p then + local dist = vector.distance(p, s) + + if (not self:object_in_range(self.following)) then + self.following = nil + else + local vec = { + x = p.x - s.x, + 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 + self:set_yaw( yaw, 2.35) + + -- anyone but standing npc's can move along + if dist > 3 and self.order ~= "stand" then + self:set_velocity(self.follow_velocity) + if self.walk_chance ~= 0 then + self:set_animation( "run") + end + else + self:set_velocity(0) + self:set_animation( "stand") + end + return + end + end + end +end + +function mob_class:flop() + -- swimmers flop when out of their element, and swim again when back in + if self.fly then + local s = self.object:get_pos() + + if self:flight_check(s) == false then + self.state = "flop" + self.object:set_acceleration({x = 0, y = DEFAULT_FALL_SPEED, z = 0}) + + local p = self.object:get_pos() + local sdef = minetest.registered_nodes[node_ok(vector.add(p, vector.new(0,self.collisionbox[2]-0.2,0))).name] + -- Flop on ground + if sdef and sdef.walkable then + if self.object:get_velocity().y < 0.1 then + self:mob_sound("flop") + self.object:set_velocity({ + x = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), + y = FLOP_HEIGHT, + z = math.random(-FLOP_HOR_SPEED, FLOP_HOR_SPEED), + }) + end + end + + self:set_animation( "stand", true) + return + elseif self.state == "flop" then + self.state = "stand" + self.object:set_acceleration(vector.zero()) + self:set_velocity(0) + end + end +end + +function mob_class:go_to_pos(b) + if not self then return end + local s=self.object:get_pos() + if not b then + --self.state = "stand" + return end + if vector.distance(b,s) < 1 then + --self:set_velocity(0) + return true + end + local v = { x = b.x - s.x, z = b.z - s.z } + local yaw = (atann(v.z / v.x) +math.pi/ 2) - self.rotate + if b.x > s.x then yaw = yaw +math.pi end + self.object:set_yaw(yaw) + self:set_velocity(self.follow_velocity) + self:set_animation("walk") +end + +local check_herd_timer = 0 +function mob_class:check_herd(dtime) + local pos = self.object:get_pos() + if not pos or self.state == "attack" then return end + -- Does any mob not move in group. Weird check for something not set? + if self.move_in_group == false then return end + + check_herd_timer = check_herd_timer + dtime + if check_herd_timer < CHECK_HERD_FREQUENCY then return end + check_herd_timer = 0 + for _,o in pairs(minetest.get_objects_inside_radius(pos,self.view_range)) do + local l = o:get_luaentity() + local p,y + if l and l.is_mob and l.name == self.name then + if self.horny and l.horny then + p = l.object:get_pos() + else + y = o:get_yaw() + end + if p then + self:go_to_pos(p) + elseif y then + self:set_yaw(y) + end + end + end +end + +function mob_class:teleport(target) + if self.do_teleport then + if self.do_teleport(self, target) == false then + return + end + end +end + +function mob_class:do_states_walk() + local yaw = self.object:get_yaw() or 0 + + local s = self.object:get_pos() + local lp = nil + + -- is there something I need to avoid? + if (self.water_damage > 0 + and self.lava_damage > 0) + or self.breath_max ~= -1 then + lp = minetest.find_node_near(s, 1, {"group:water", "group:lava"}) + elseif self.water_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:water"}) + elseif self.lava_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:lava"}) + elseif self.fire_damage > 0 then + lp = minetest.find_node_near(s, 1, {"group:fire"}) + end + + local is_in_danger = false + if lp then + -- If mob in or on dangerous block, look for land + if (self:is_node_dangerous(self.standing_in) or + self:is_node_dangerous(self.standing_on)) or (self:is_node_waterhazard(self.standing_in) or self:is_node_waterhazard(self.standing_on)) and (not self.fly) then + is_in_danger = true + + -- If mob in or on dangerous block, look for land + if is_in_danger then + -- Better way to find shore - copied from upstream + lp = minetest.find_nodes_in_area_under_air( + {x = s.x - 5, y = s.y - 0.5, z = s.z - 5}, + {x = s.x + 5, y = s.y + 1, z = s.z + 5}, + {"group:solid"}) + + lp = #lp > 0 and lp[math.random(#lp)] + + -- did we find land? + if lp then + + local vec = { + x = lp.x - s.x, + z = lp.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + + if lp.x > s.x then yaw = yaw +math.pi end + + -- look towards land and move in that direction + yaw = self:set_yaw( yaw, 6) + self:set_velocity(self.walk_velocity) + + end + end + + -- A danger is near but mob is not inside + else + + -- Randomly turn + if math.random(1, 100) <= 30 then + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + end + end + + yaw = self:set_yaw( yaw, 8) + + -- otherwise randomly turn + elseif math.random(1, 100) <= 30 then + yaw = yaw + math.random(-0.5, 0.5) + yaw = self:set_yaw( yaw, 8) + end + + -- stand for great fall or danger or fence in front + local cliff_or_danger = false + if is_in_danger then + cliff_or_danger = self:is_at_cliff_or_danger() + end + if self.facing_fence == true + or cliff_or_danger + or math.random(1, 100) <= 30 then + + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + + self:set_velocity(self.walk_velocity) + + if self:flight_check() + and self.animation + and self.animation.fly_start + and self.animation.fly_end then + self:set_animation( "fly") + else + self:set_animation( "walk") + end + end +end + +function mob_class:do_states_stand(player_in_active_range) + local yaw = self.object:get_yaw() or 0 + + if math.random(1, 4) == 1 then + + local s = self.object:get_pos() + local objs = minetest.get_objects_inside_radius(s, 3) + local lp + for n = 1, #objs do + if objs[n]:is_player() then + lp = objs[n]:get_pos() + break + end + end + + -- look at any players nearby, otherwise turn randomly + if lp and self.look_at_players then + + local vec = { + x = lp.x - s.x, + z = lp.z - s.z + } + + yaw = (atan(vec.z / vec.x) +math.pi/ 2) - self.rotate + + if lp.x > s.x then yaw = yaw +math.pi end + else + yaw = yaw + math.random(-0.5, 0.5) + end + + yaw = self:set_yaw( yaw, 8) + end + if self.order == "sit" then + self:set_animation( "sit") + self:set_velocity(0) + else + self:set_animation( "stand") + self:set_velocity(0) + end + + -- npc's ordered to stand stay standing + if self.order == "stand" or self.order == "sleep" or self.order == "work" then + + else + if player_in_active_range then + if self.walk_chance ~= 0 + and self.facing_fence ~= true + and math.random(1, 100) <= self.walk_chance + and self:is_at_cliff_or_danger() == false then + + self:set_velocity(self.walk_velocity) + self.state = "walk" + self:set_animation( "walk") + end + end + end +end + +function mob_class:do_states_runaway() + local yaw = self.object:get_yaw() or 0 + + self.runaway_timer = self.runaway_timer + 1 + + -- stop after 5 seconds or when at cliff + if self.runaway_timer > 5 + or self:is_at_cliff_or_danger() then + self.runaway_timer = 0 + self:set_velocity(0) + self.state = "stand" + self:set_animation( "stand") + local yaw = self.object:get_yaw() or 0 + yaw = self:set_yaw( yaw + 0.78, 8) + else + self:set_velocity( self.run_velocity) + self:set_animation( "run") + end +end + + + + + + +function mob_class:check_smooth_rotation(dtime) + -- smooth rotation by ThomasMonroe314 + if self._turn_to then + self:set_yaw( self._turn_to, .1) + end + + if self.delay and self.delay > 0 then + + local yaw = self.object:get_yaw() or 0 + + if self.delay == 1 then + yaw = self.target_yaw + else + local dif = math.abs(yaw - self.target_yaw) + + if yaw > self.target_yaw then + + if dif > math.pi then + dif = 2 * math.pi - dif -- need to add + yaw = yaw + dif / self.delay + else + yaw = yaw - dif / self.delay -- need to subtract + end + + elseif yaw < self.target_yaw then + + if dif >math.pi then + dif = 2 * math.pi - dif + yaw = yaw - dif / self.delay -- need to subtract + else + yaw = yaw + dif / self.delay -- need to add + end + end + + if yaw > (math.pi * 2) then yaw = yaw - (math.pi * 2) end + if yaw < 0 then yaw = yaw + (math.pi * 2) end + end + + self.delay = self.delay - 1 + if self.shaking then + yaw = yaw + (math.random() * 2 - 1) * 5 * dtime + end + self.object:set_yaw(yaw) + --self:update_roll() + end + -- end rotation +end diff --git a/mods/ENTITIES/mcl_mobs/pathfinding.lua b/mods/ENTITIES/mcl_mobs/pathfinding.lua new file mode 100644 index 000000000..ce706b190 --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/pathfinding.lua @@ -0,0 +1,457 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local PATHFINDING_FAIL_THRESHOLD = 100 -- no. of ticks to fail before giving up. 20p/s. 5s helps them get through door +local PATHFINDING_FAIL_WAIT = 30 -- how long to wait before trying to path again +local PATHING_START_DELAY = 4 -- When doing non-prioritised pathing, how long to wait until last mob pathed + +local PATHFINDING_SEARCH_DISTANCE = 50 -- How big the square is that pathfinding will look + +local PATHFINDING = "gowp" + +local one_down = vector.new(0,-1,0) +local one_up = vector.new(0,1,0) + +local plane_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_pathfinding",false) + +local LOG_MODULE = "[Mobs Pathfinding]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + +function output_table (wp) + if not wp then return end + mcl_log("wp items: ".. tostring(#wp)) + for a,b in pairs(wp) do + mcl_log(a.. ": ".. tostring(b)) + end +end + +function append_paths (wp1, wp2) + --mcl_log("Start append") + if not wp1 or not wp2 then + mcl_log("Cannot append wp's") + return + end + output_table(wp1) + output_table(wp2) + for _,a in pairs (wp2) do + table.insert(wp1, a) + end + --mcl_log("End append") +end + +local function output_enriched (wp_out) + mcl_log("Output enriched path") + local i = 0 + for _,outy in pairs (wp_out) do + i = i + 1 + mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])) + + local action = outy["action"] + if action then + --mcl_log("Pos ".. i ..":" .. minetest.pos_to_string(outy["pos"])) + mcl_log("type: " .. action["type"]) + mcl_log("action: " .. action["action"]) + mcl_log("target: " .. minetest.pos_to_string(action["target"])) + end + --mcl_log("failed attempts: " .. outy["failed_attempts"]) + end +end + +-- This function will take a list of paths, and enrich it with: +-- a var for failed attempts +-- an action, such as to open or close a door where we know that pos requires that action +local function generate_enriched_path(wp_in, door_open_pos, door_close_pos, cur_door_pos) + local wp_out = {} + + -- TODO Just pass in door position and the index before is open, the index after is close + local current_door_index = -1 + + for i, cur_pos in pairs(wp_in) do + local action = nil + + local cur_pos_to_add = vector.add(cur_pos, one_down) + if door_open_pos and vector.equals (cur_pos, door_open_pos) then + mcl_log ("Door open match") + action = {type = "door", action = "open", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + elseif door_close_pos and vector.equals(cur_pos, door_close_pos) then + mcl_log ("Door close match") + action = {type = "door", action = "close", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + elseif cur_door_pos and vector.equals(cur_pos, cur_door_pos) then + mcl_log("Current door pos") + action = {type = "door", action = "open", target = cur_door_pos} + cur_pos_to_add = vector.add(cur_pos, one_down) + else + cur_pos_to_add = cur_pos + --mcl_log ("Pos doesn't match") + end + + wp_out[i] = {} + wp_out[i]["pos"] = cur_pos_to_add + wp_out[i]["failed_attempts"] = 0 + wp_out[i]["action"] = action + + --wp_out[i] = {"pos" = cur_pos, "failed_attempts" = 0, "action" = action} + --output_pos(cur_pos, i) + end + output_enriched(wp_out) + return wp_out +end + +local last_pathing_time = os.time() + +function mob_class:ready_to_path(prioritised) + mcl_log("Check ready to path") + if self._pf_last_failed and (os.time() - self._pf_last_failed) < PATHFINDING_FAIL_WAIT then + mcl_log("Not ready to path as last fail is less than threshold: " .. (os.time() - self._pf_last_failed)) + return false + else + local time_since_path_start = os.time() - last_pathing_time + mcl_log("time_since_path_start: " .. tostring(time_since_path_start)) + if prioritised or (time_since_path_start) > PATHING_START_DELAY then + mcl_log("We are ready to pathfind, no previous fail or we are past threshold") + return true + end + end +end + +-- This function is used to see if we can path. We could use to check a route, rather than making people move. +local function calculate_path_through_door (p, cur_door_pos, t) + if t then + mcl_log("Plot route through door from pos: " .. minetest.pos_to_string(p) .. ", to target: " .. minetest.pos_to_string(t)) + else + mcl_log("Plot route through door from pos: " .. minetest.pos_to_string(p)) + end + + local enriched_path = nil + local wp, prospective_wp + + local pos_closest_to_door = nil + local other_side_of_door = nil + + if cur_door_pos then + mcl_log("Found a door near: " .. minetest.pos_to_string(cur_door_pos)) + + for _,v in pairs(plane_adjacents) do + pos_closest_to_door = vector.add(cur_door_pos,v) + other_side_of_door = vector.add(cur_door_pos,-v) + + local n = minetest.get_node(pos_closest_to_door) + + if n.name == "air" then + mcl_log("We have air space next to door at: " .. minetest.pos_to_string(pos_closest_to_door)) + + prospective_wp = minetest.find_path(p, pos_closest_to_door, PATHFINDING_SEARCH_DISTANCE, 1, 4) + + if prospective_wp then + mcl_log("Found a path to next to door".. minetest.pos_to_string(pos_closest_to_door)) + mcl_log("Opposite is: ".. minetest.pos_to_string(other_side_of_door)) + + table.insert(prospective_wp, cur_door_pos) + + if t then + mcl_log("We have t, lets go from door to target") + local wp_otherside_door_to_target = minetest.find_path(other_side_of_door, t, PATHFINDING_SEARCH_DISTANCE, 1, 4) + + if wp_otherside_door_to_target and #wp_otherside_door_to_target > 0 then + append_paths (prospective_wp, wp_otherside_door_to_target) + + wp = prospective_wp + mcl_log("We have a path from outside door to target") + else + mcl_log("We cannot path from outside door to target") + end + else + mcl_log("No t, just add other side of door") + table.insert(prospective_wp, other_side_of_door) + wp = prospective_wp + end + + if wp then + enriched_path = generate_enriched_path(wp, pos_closest_to_door, other_side_of_door, cur_door_pos) + break + end + else + mcl_log("Cannot path to this air block next to door.") + end + end + end + else + mcl_log("No door found") + end + + if wp and not enriched_path then + mcl_log("Wp but not enriched") + enriched_path = generate_enriched_path(wp) + end + return enriched_path +end + + + +function mob_class:gopath(target, callback_arrived, prioritised) + if self.state == PATHFINDING then mcl_log("Already pathfinding, don't set another until done.") return end + if not self:ready_to_path(prioritised) then return end + + last_pathing_time = os.time() + + self.order = nil + + local p = self.object:get_pos() + local t = vector.offset(target,0,1,0) + + --Check direct route + local wp = minetest.find_path(p, t, PATHFINDING_SEARCH_DISTANCE, 1, 4) + + if not wp then + mcl_log("### No direct path. Path through door closest to target.") + local door_near_target = minetest.find_node_near(target, 16, {"group:door"}) + wp = calculate_path_through_door(p, door_near_target, t) + + if not wp then + mcl_log("### No path though door closest to target. Try door closest to origin.") + local door_closest = minetest.find_node_near(p, 16, {"group:door"}) + wp = calculate_path_through_door(p, door_closest, t) + + -- Path through 2 doors + if not wp then + mcl_log("### Still not wp. Need to path through 2 doors.") + local path_through_closest_door = calculate_path_through_door(p, door_closest) + + if path_through_closest_door and #path_through_closest_door > 0 then + mcl_log("We have path through first door") + mcl_log("Number of pos in path through door: " .. tostring(#path_through_closest_door)) + + local pos_after_door_entry = path_through_closest_door[#path_through_closest_door] + if pos_after_door_entry then + local pos_after_door = vector.add(pos_after_door_entry["pos"], one_up) + mcl_log("pos_after_door: " .. minetest.pos_to_string(pos_after_door)) + local path_after_door = calculate_path_through_door(pos_after_door, door_near_target, t) + if path_after_door and #path_after_door > 1 then + mcl_log("We have path after first door") + table.remove(path_after_door, 1) -- Remove duplicate + wp = path_through_closest_door + append_paths (wp, path_after_door) + else + mcl_log("Path after door is not good") + end + else + mcl_log("No pos after door") + end + else + mcl_log("Path through closest door empty or null") + end + else + mcl_log("ok, we have a path through 1 door") + end + end + else + wp = generate_enriched_path(wp) + mcl_log("We have a direct route") + end + + if not wp then + mcl_log("Could not calculate path") + self._pf_last_failed = os.time() + -- If cannot path, don't immediately try again + end + + if wp and #wp > 0 then + --output_table(wp) + self._target = t + self.callback_arrived = callback_arrived + local current_location = table.remove(wp,1) + if current_location and current_location["pos"] then + mcl_log("Removing first co-ord? " .. tostring(current_location["pos"])) + else + mcl_log("Nil pos") + end + self.current_target = current_location + self.waypoints = wp + self.state = PATHFINDING + return true + else + self.state = "walk" + self.waypoints = nil + self.current_target = nil + -- minetest.log("no path found") + end +end + +function mob_class:interact_with_door(action, target) + local p = self.object:get_pos() + --local t = minetest.get_timeofday() + --local dd = minetest.find_nodes_in_area(vector.offset(p,-1,-1,-1),vector.offset(p,1,1,1),{"group:door"}) + --for _,d in pairs(dd) do + if target then + mcl_log("Door target is: ".. minetest.pos_to_string(target)) + + local n = minetest.get_node(target) + if n.name:find("_b_") or n.name:find("_t_") then + mcl_log("Door") + local def = minetest.registered_nodes[n.name] + local closed = n.name:find("_b_1") or n.name:find("_t_1") + --if self.state == PATHFINDING then + if closed and action == "open" and def.on_rightclick then + mcl_log("Open door") + def.on_rightclick(target,n,self) + end + if not closed and action == "close" and def.on_rightclick then + mcl_log("Close door") + def.on_rightclick(target,n,self) + end + --else + else + mcl_log("Not door") + end + else + mcl_log("no target. cannot try and open or close door") + end + --end +end + +function mob_class:do_pathfind_action(action) + if action then + mcl_log("Action present") + local type = action["type"] + local action_val = action["action"] + local target = action["target"] + if target then + mcl_log("Target: ".. minetest.pos_to_string(target)) + end + if type and type == "door" then + mcl_log("Type is door") + self:interact_with_door(action_val, target) + end + end +end + +function mob_class:check_gowp(dtime) + local p = self.object:get_pos() + + -- no destination + if not p or not self._target then + mcl_log("p: ".. tostring(p)) + mcl_log("self._target: ".. tostring(self._target)) + return + end + + -- arrived at location, finish gowp + local distance_to_targ = vector.distance(p,self._target) + --mcl_log("Distance to targ: ".. tostring(distance_to_targ)) + if distance_to_targ < 1.8 then + mcl_log("Arrived at _target") + self.waypoints = nil + self._target = nil + self.current_target = nil + self.state = "stand" + self.order = "stand" + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + if self.callback_arrived then return self.callback_arrived(self) end + return true + elseif not self.current_target then + mcl_log("Not close enough to targ: ".. tostring(distance_to_targ)) + end + + -- More pathing to be done + local distance_to_current_target = 50 + if self.current_target and self.current_target["pos"] then + distance_to_current_target = vector.distance(p,self.current_target["pos"]) + end + + -- 0.6 is working but too sensitive. sends villager back too frequently. 0.7 is quite good, but not with heights + -- 0.8 is optimal for 0.025 frequency checks and also 1... Actually. 0.8 is winning + -- 0.9 and 1.0 is also good. Stick with unless door open or closing issues + if self.waypoints and #self.waypoints > 0 and ( not self.current_target or not self.current_target["pos"] or distance_to_current_target < 0.9 ) then + -- We have waypoints, and are at current_target or have no current target. We need a new current_target. + self:do_pathfind_action (self.current_target["action"]) + + local failed_attempts = self.current_target["failed_attempts"] + mcl_log("There after " .. failed_attempts .. " failed attempts. current target:".. minetest.pos_to_string(self.current_target["pos"]) .. ". Distance: " .. distance_to_current_target) + + self.current_target = table.remove(self.waypoints, 1) + self:go_to_pos(self.current_target["pos"]) + return + elseif self.current_target and self.current_target["pos"] then + -- No waypoints left, but have current target and not close enough. Potentially last waypoint to go to. + + self.current_target["failed_attempts"] = self.current_target["failed_attempts"] + 1 + local failed_attempts = self.current_target["failed_attempts"] + if failed_attempts >= PATHFINDING_FAIL_THRESHOLD then + mcl_log("Failed to reach position (" .. minetest.pos_to_string(self.current_target["pos"]) .. ") too many times. Abandon route. Times tried: " .. failed_attempts) + self.state = "stand" + self.current_target = nil + self.waypoints = nil + self._target = nil + self._pf_last_failed = os.time() + self.object:set_velocity({x = 0, y = 0, z = 0}) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + return + end + + --mcl_log("Not at pos with failed attempts ".. failed_attempts ..": ".. minetest.pos_to_string(p) .. "self.current_target: ".. minetest.pos_to_string(self.current_target["pos"]) .. ". Distance: ".. distance_to_current_target) + self:go_to_pos(self.current_target["pos"]) + -- Do i just delete current_target, and return so we can find final path. + else + -- Not at target, no current waypoints or current_target. Through the door and should be able to path to target. + -- Is a little sensitive and could take 1 - 7 times. A 10 fail count might be a good exit condition. + + mcl_log("We don't have waypoints or a current target. Let's try to path to target") + + if self.waypoints then + mcl_log("WP: " .. tostring(self.waypoints)) + mcl_log("WP num: " .. tostring(#self.waypoints)) + else + mcl_log("No wp set") + end + if self.current_target then + mcl_log("Current target: " .. tostring(self.current_target)) + else + mcl_log("No current target") + end + + local final_wp = minetest.find_path(p, self._target, PATHFINDING_SEARCH_DISTANCE, 1, 4) + if final_wp then + mcl_log("We can get to target here.") + -- self.waypoints = final_wp + self:go_to_pos(self._target) + else + -- Abandon route? + mcl_log("Cannot plot final route to target") + end + end + + -- I don't think we need the following anymore, but test first. + -- Maybe just need something to path to target if no waypoints left + if self.current_target and self.current_target["pos"] and (self.waypoints and #self.waypoints == 0) then + local updated_p = self.object:get_pos() + local distance_to_cur_targ = vector.distance(updated_p,self.current_target["pos"]) + + mcl_log("Distance to current target: ".. tostring(distance_to_cur_targ)) + mcl_log("Current p: ".. minetest.pos_to_string(updated_p)) + + -- 1.6 is good. is 1.9 better? It could fail less, but will it path to door when it isn't after door + if distance_to_cur_targ > 1.9 then + mcl_log("not close to current target: ".. minetest.pos_to_string(self.current_target["pos"])) + self:go_to_pos(self._current_target) + else + mcl_log("close to current target: ".. minetest.pos_to_string(self.current_target["pos"])) + mcl_log("target is: ".. minetest.pos_to_string(self._target)) + self.current_target = nil + end + return + end +end diff --git a/mods/ENTITIES/mcl_mobs/physics.lua b/mods/ENTITIES/mcl_mobs/physics.lua new file mode 100644 index 000000000..e1b23d78a --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/physics.lua @@ -0,0 +1,1033 @@ +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +local ENTITY_CRAMMING_MAX = 24 +local CRAMMING_DAMAGE = 3 +local DEATH_DELAY = 0.5 +local DEFAULT_FALL_SPEED = -9.81*1.5 + +local PATHFINDING = "gowp" +local mobs_debug = minetest.settings:get_bool("mobs_debug", false) +local mobs_drop_items = minetest.settings:get_bool("mobs_drop_items") ~= false +local mob_active_range = tonumber(minetest.settings:get("mcl_mob_active_range")) or 48 +local show_health = false + +-- get node but use fallback for nil or unknown +local node_ok = function(pos, fallback) + + fallback = fallback or mcl_mobs.fallback_node + + local node = minetest.get_node_or_nil(pos) + + if node and minetest.registered_nodes[node.name] then + return node + end + + return minetest.registered_nodes[fallback] +end + +-- check if within physical map limits (-30911 to 30927) +local function within_limits(pos, radius) + local wmin, wmax = -30912, 30928 + if mcl_vars then + if mcl_vars.mapgen_edge_min and mcl_vars.mapgen_edge_max then + wmin, wmax = mcl_vars.mapgen_edge_min, mcl_vars.mapgen_edge_max + end + end + if radius then + wmin = wmin - radius + wmax = wmax + radius + end + if not pos then return true end + for _,v in pairs(pos) do + if v < wmin or v > wmax then return false end + end + return true +end + +function mob_class:player_in_active_range() + for _,p in pairs(minetest.get_connected_players()) do + local pos = self.object:get_pos() + if pos and vector.distance(pos, p:get_pos()) <= mob_active_range then return true end + -- slightly larger than the mc 32 since mobs spawn on that circle and easily stand still immediately right after spawning. + end +end + +-- Return true if object is in view_range +function mob_class:object_in_range(object) + if not object then + return false + end + local factor + -- Apply view range reduction for special player armor + if object:is_player() then + local factors = mcl_armor.player_view_range_factors[object] + factor = factors and factors[self.name] + end + -- Distance check + local dist + if factor and factor == 0 then + return false + elseif factor then + dist = self.view_range * factor + else + dist = self.view_range + end + + local p1, p2 = self.object:get_pos(), object:get_pos() + return p1 and p2 and (vector.distance(p1, p2) <= dist) +end + +function mob_class:item_drop(cooked, looting_level) + + if not mobs_drop_items then return end + + looting_level = looting_level or 0 + + if (self.child and self.type ~= "monster") then + return + end + + local obj, item, num + local pos = self.object:get_pos() + + self.drops = self.drops or {} + + for n = 1, #self.drops do + local dropdef = self.drops[n] + local chance = 1 / dropdef.chance + local looting_type = dropdef.looting + + if looting_level > 0 then + local chance_function = dropdef.looting_chance_function + if chance_function then + chance = chance_function(looting_level) + elseif looting_type == "rare" then + chance = chance + (dropdef.looting_factor or 0.01) * looting_level + end + end + + local num = 0 + local do_common_looting = (looting_level > 0 and looting_type == "common") + if math.random() < chance then + num = math.random(dropdef.min or 1, dropdef.max or 1) + elseif not dropdef.looting_ignore_chance then + do_common_looting = false + end + + if do_common_looting then + num = num + math.floor(math.random(0, looting_level) + 0.5) + end + + if num > 0 then + item = dropdef.name + + if cooked then + + local output = minetest.get_craft_result({ + method = "cooking", width = 1, items = {item}}) + + if output and output.item and not output.item:is_empty() then + item = output.item:get_name() + end + end + + for x = 1, num do + obj = minetest.add_item(pos, ItemStack(item .. " " .. 1)) + end + + if obj and obj:get_luaentity() then + + obj:set_velocity({ + x = math.random(-10, 10) / 9, + y = 6, + z = math.random(-10, 10) / 9, + }) + elseif obj then + obj:remove() -- item does not exist + end + end + end + + self.drops = {} +end + +-- collision function borrowed amended from jordan4ibanez open_ai mod +function mob_class:collision() + local pos = self.object:get_pos() + if not pos then return {0,0} end + local vel = self.object:get_velocity() + local x = 0 + local z = 0 + local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do + + local ent = object:get_luaentity() + if object:is_player() or (ent and ent.is_mob and object ~= self.object) then + + if object:is_player() and mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(object, 4) + end + + local pos2 = object:get_pos() + local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} + local force = (width + 0.5) - vector.distance( + {x = pos.x, y = 0, z = pos.z}, + {x = pos2.x, y = 0, z = pos2.z}) + + x = x + (vec.x * force) + z = z + (vec.z * force) + end + end + + return({x,z}) +end + +function mob_class:check_death_and_slow_mob() + local d = 0.7 + local dying = self:check_dying() + if dying then d = 0.92 end + + local v = self.object:get_velocity() + if v then + --diffuse object velocity + self.object:set_velocity({x = v.x*d, y = v.y, z = v.z*d}) + end + return dying +end + +-- move mob in facing direction +function mob_class:set_velocity(v) + if not v then return end + + local c_x, c_y = 0, 0 + + -- can mob be pushed, if so calculate direction + if self.pushable then + c_x, c_y = unpack(self:collision()) + end + + -- halt mob if it has been ordered to stay + if self.order == "stand" or self.order == "sit" then + self.acc = vector.zero() + return + end + + local yaw = (self.object:get_yaw() or 0) + self.rotate + local vv = self.object:get_velocity() + + if vv and yaw then + self.acc = vector.new(((math.sin(yaw) * -v) + c_x) * .4, 0, ((math.cos(yaw) * v) + c_y) * .4) + end +end + +-- calculate mob velocity +function mob_class:get_velocity() + local v = self.object:get_velocity() + if v then + return (v.x * v.x + v.z * v.z) ^ 0.5 + end + + return 0 +end + +function mob_class:update_roll() + local is_Fleckenstein = self.nametag == "Fleckenstein" + local was_Fleckenstein = false + + local rot = self.object:get_rotation() + rot.z = is_Fleckenstein and pi or 0 + self.object:set_rotation(rot) + + local cbox = table.copy(self.collisionbox) + local acbox = self.object:get_properties().collisionbox + + if math.abs(cbox[2] - acbox[2]) > 0.1 then + was_Fleckenstein = true + end + + if is_Fleckenstein ~= was_Fleckenstein then + local pos = self.object:get_pos() + pos.y = pos.y + (acbox[2] + acbox[5]) + self.object:set_pos(pos) + end + + if is_Fleckenstein then + cbox[2], cbox[5] = -cbox[5], -cbox[2] + self.object:set_properties({collisionbox = cbox}) + -- This leads to child mobs having the wrong collisionbox + -- and seeing as it seems to be nothing but an easter egg + -- i've put it inside the if. Which just makes it be upside + -- down lol. + end + +end + +local function shortest_term_of_yaw_rotation(self, rot_origin, rot_target, nums) + + if not rot_origin or not rot_target then + return + end + + rot_origin = math.deg(rot_origin) + rot_target = math.deg(rot_target) + + if rot_origin < rot_target then + if math.abs(rot_origin-rot_target)<180 then + if nums then + return rot_target-rot_origin + else + return 1 + end + else + if nums then + return -(rot_origin-(rot_target-360)) + else + return -1 + end + end + else + if math.abs(rot_origin-rot_target)<180 then + if nums then + return rot_target-rot_origin + else + return -1 + end + else + if nums then + return (rot_target-(rot_origin-360)) + else + return 1 + end + end + end + +end + + + +-- set and return valid yaw +function mob_class:set_yaw(yaw, delay, dtime) + if self.noyaw then return end + + if not self.object:get_yaw() or not self.object:get_pos() then return end + + if self.state ~= PATHFINDING then + self._turn_to = yaw + end + + --mcl_log("Yaw is: \t\t" .. tostring(math.deg(yaw))) + --mcl_log("self.object:get_yaw() is: \t" .. tostring(math.deg(self.object:get_yaw()))) + + --clamp our yaw to a 360 range + if math.deg(self.object:get_yaw()) > 360 then + self.object:set_yaw(math.rad(0)) + elseif math.deg(self.object:get_yaw()) < 0 then + self.object:set_yaw(math.rad(360)) + end + + if math.deg(yaw) > 360 then + yaw=math.rad(math.deg(yaw)%360) + elseif math.deg(yaw) < 0 then + yaw=math.rad(((360*5)-math.deg(yaw))%360) + end + + --calculate the shortest way to turn to find our target + local target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), yaw, false) + local target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), yaw, true) + + --turn in the shortest path possible toward our target. if we are attacking, don't dance. + if (math.abs(target_shortest_path) > 50 and not self._kb_turn) and (self.attack and self.attack:get_pos() or self.following and self.following:get_pos()) then + if self.following then + target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.following:get_pos())), true) + target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.following:get_pos())), false) + else + target_shortest_path = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())), true) + target_shortest_path_nums = shortest_term_of_yaw_rotation(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())), false) + end + end + + local ddtime = 0.05 --set_tick_rate + + if dtime then + ddtime = dtime + end + + 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 + self.acc=vector.rotate_around_axis(self.acc,vector.new(0,1,0), target_shortest_path*(3.6*ddtime)) + end + end + + delay = delay or 0 + + yaw = self.object:get_yaw() + + if delay == 0 then + if self.shaking and dtime then + yaw = yaw + (math.random() * 2 - 1) * 5 * dtime + end + --self:update_roll() + return yaw + end + + self.target_yaw = yaw + self.delay = delay + + return self.target_yaw +end + +-- global function to set mob yaw +function mcl_mobs.yaw(self, yaw, delay, dtime) + return mob_class.set_yaw(self, yaw, delay, dtime) +end + +-- are we flying in what we are suppose to? (taikedz) +function mob_class:flight_check() + + local nod = self.standing_in + local def = minetest.registered_nodes[nod] + + if not def then return false end -- nil check + + local fly_in + if type(self.fly_in) == "string" then + fly_in = { self.fly_in } + elseif type(self.fly_in) == "table" then + fly_in = self.fly_in + else + return false + end + + for _,checknode in pairs(fly_in) do + if nod == checknode or nod == "ignore" then + return true + end + end + + return false +end + +-- check if mob is dead or only hurt +function mob_class:check_for_death(cause, cmi_cause) + + if self.state == "die" then + return true + end + + -- has health actually changed? + if self.health == self.old_health and self.health > 0 then + return false + end + + local damaged = self.health < self.old_health + self.old_health = self.health + + -- still got some health? + if self.health > 0 then + + -- make sure health isn't higher than max + if self.health > self.hp_max then + self.health = self.hp_max + end + + -- play damage sound if health was reduced and make mob flash red. + if damaged then + self:add_texture_mod("^[colorize:#d42222:175") + minetest.after(1, function(self) + if self and self.object then + self:remove_texture_mod("^[colorize:#d42222:175") + end + end, self) + self:mob_sound("damage") + end + + -- backup nametag so we can show health stats + if not self.nametag2 then + self.nametag2 = self.nametag or "" + end + + if show_health + and (cmi_cause and cmi_cause.type == "punch") then + + self.htimer = 2 + self.nametag = "♥ " .. self.health .. " / " .. self.hp_max + + self:update_tag() + end + + return false + end + + self:mob_sound("death") + + local function death_handle(self) + if cmi_cause and cmi_cause["type"] then + --minetest.log("cmi_cause: " .. tostring(cmi_cause["type"])) + end + --minetest.log("cause: " .. tostring(cause)) + + -- TODO other env damage shouldn't drop xp + -- "rain", "water", "drowning", "suffocation" + + -- dropped cooked item if mob died in fire or lava + if cause == "lava" or cause == "fire" then + self:item_drop(true, 0) + else + local wielditem = ItemStack() + if cause == "hit" then + local puncher = cmi_cause.puncher + if puncher then + wielditem = puncher:get_wielded_item() + end + end + local cooked = mcl_burning.is_burning(self.object) or mcl_enchanting.has_enchantment(wielditem, "fire_aspect") + local looting = mcl_enchanting.get_enchantment(wielditem, "looting") + self:item_drop(cooked, looting) + + if ((not self.child) or self.type ~= "animal") and (minetest.get_us_time() - self.xp_timestamp <= math.huge) then + local pos = self.object:get_pos() + local xp_amount = math.random(self.xp_min, self.xp_max) + + if not mcl_sculk.handle_death(pos, xp_amount) then + --minetest.log("Xp not thrown") + if minetest.is_creative_enabled("") ~= true then + mcl_experience.throw_xp(pos, xp_amount) + end + else + --minetest.log("xp thrown") + end + end + end + + + end + + -- execute custom death function + if self.on_die then + + local pos = self.object:get_pos() + local on_die_exit = self.on_die(self, pos, cmi_cause) + if on_die_exit ~= true then + death_handle(self) + end + + if on_die_exit == true then + self.state = "die" + mcl_burning.extinguish(self.object) + self.object:remove() + return true + end + end + + if self.jockey or self.riden_by_jock then + self.riden_by_jock = nil + self.jockey = nil + end + + + local collisionbox + if self.collisionbox then + collisionbox = table.copy(self.collisionbox) + end + + self.state = "die" + self.attack = nil + self.v_start = false + self.fall_speed = DEFAULT_FALL_SPEED + self.timer = 0 + self.blinktimer = 0 + self:remove_texture_mod("^[colorize:#FF000040") + self:remove_texture_mod("^[brighten") + self.passive = true + + self.object:set_properties({ + pointable = false, + collide_with_objects = false, + }) + + self:set_velocity(0) + local acc = self.object:get_acceleration() + if acc then + acc.x, acc.y, acc.z = 0, DEFAULT_FALL_SPEED, 0 + self.object:set_acceleration(acc) + end + + local length + -- default death function and die animation (if defined) + if self.instant_death then + length = 0 + elseif self.animation and self.animation.die_start and self.animation.die_end then + local frames = self.animation.die_end - self.animation.die_start + local speed = self.animation.die_speed or 15 + length = math.max(frames / speed, 0) + DEATH_DELAY + self:set_animation( "die") + else + length = 1 + DEATH_DELAY + self:set_animation( "stand", true) + end + + + -- Remove body after a few seconds and drop stuff + local kill = function(self) + if not self.object:get_luaentity() then + return + end + death_handle(self) + local dpos = self.object:get_pos() + local cbox = self.collisionbox + local yaw = self.object:get_rotation().y + mcl_burning.extinguish(self.object) + self.object:remove() + mcl_mobs.death_effect(dpos, yaw, cbox, not self.instant_death) + end + + if length <= 0 then + kill(self) + else + minetest.after(length, kill, self) + end + + return true +end + +-- Deal light damage to mob, returns true if mob died +function mob_class:deal_light_damage(pos, damage) + if not ((mcl_weather.rain.raining or mcl_weather.state == "snow") and mcl_weather.is_outdoor(pos)) then + self.health = self.health - damage + + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png") + + if self:check_for_death("light", {type = "light"}) then + return true + end + end +end + +-- environmental damage (water, lava, fire, light etc.) +function mob_class:do_env_damage() + -- feed/tame text timer (so mob 'full' messages dont spam chat) + if self.htimer > 0 then + self.htimer = self.htimer - 1 + end + + -- reset nametag after showing health stats + if self.htimer < 1 and self.nametag2 then + + self.nametag = self.nametag2 + self.nametag2 = nil + + self:update_tag() + end + + local pos = self.object:get_pos() + if not pos then return end + + self.time_of_day = minetest.get_timeofday() + + -- remove mob if beyond map limits + if not within_limits(pos, 0) then + mcl_burning.extinguish(self.object) + self.object:remove() + return true + end + + local node = minetest.get_node(pos) + if node then + if node.name ~= "ignore" then + -- put below code in this block if we can prove that unloaded maps are causing crash. + -- it should warn then error + else + --minetest.log("warning", "Pos is ignored: " .. dump(pos)) + end + + local sunlight = mcl_util.get_natural_light(pos, self.time_of_day) + + if self.light_damage ~= 0 and (sunlight or 0) > 12 then + if self:deal_light_damage(pos, self.light_damage) then + return true + end + end + local _, dim = mcl_worlds.y_to_layer(pos.y) + if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then + if self.armor_list and not self.armor_list.helmet or not self.armor_list or self.armor_list and self.armor_list.helmet and self.armor_list.helmet == "" then + if self.ignited_by_sunlight then + mcl_burning.set_on_fire(self.object, 10) + else + self:deal_light_damage(pos, self.sunlight_damage) + return true + end + end + end + + end + + local y_level = self.collisionbox[2] + + if self.child then + y_level = self.collisionbox[2] * 0.5 + end + + -- what is mob standing in? + pos.y = pos.y + y_level + 0.25 -- foot level + local pos2 = {x=pos.x, y=pos.y-1, z=pos.z} + self.standing_in = node_ok(pos, "air").name + self.standing_on = node_ok(pos2, "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}) + end + + local nodef = minetest.registered_nodes[self.standing_in] + local nodef2 = minetest.registered_nodes[self.standing_on] + + -- rain + if self.rain_damage > 0 then + if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then + self.health = self.health - self.rain_damage + + if self:check_for_death("rain", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + end + + pos.y = pos.y + 1 -- for particle effect position + + -- water damage + if self.water_damage > 0 and nodef.groups.water then + if self.water_damage ~= 0 then + self.health = self.health - self.water_damage + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png", nil, nil, 1, nil) + + if self:check_for_death("water", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + elseif self.lava_damage > 0 and (nodef.groups.lava) then + -- lava damage + if self.lava_damage ~= 0 then + self.health = self.health - self.lava_damage + mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 10) + + if self:check_for_death("lava", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + elseif self.fire_damage > 0 and (nodef2.groups.fire) then + -- magma damage + if self.fire_damage ~= 0 then + self.health = self.health - self.fire_damage + + if self:check_for_death("fire", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + elseif self.fire_damage > 0 and (nodef.groups.fire) then + -- fire damage + if self.fire_damage ~= 0 then + self.health = self.health - self.fire_damage + mcl_mobs.effect(pos, 5, "fire_basic_flame.png", nil, nil, 1, nil) + mcl_burning.set_on_fire(self.object, 5) + + if self:check_for_death("fire", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + elseif nodef.damage_per_second ~= 0 and not nodef.groups.lava and not nodef.groups.fire then + -- damage_per_second node check + self.health = self.health - nodef.damage_per_second + mcl_mobs.effect(pos, 5, "mcl_particles_smoke.png") + + if self:check_for_death("dps", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + + -- Drowning damage + if self.breath_max ~= -1 then + local drowning = false + + if self.breathes_in_water then + if minetest.get_item_group(self.standing_in, "water") == 0 then + drowning = true + end + elseif nodef.drowning > 0 then + drowning = true + end + + if drowning then + self.breath = math.max(0, self.breath - 1) + mcl_mobs.effect(pos, 2, "bubble.png", nil, nil, 1, nil) + if self.breath <= 0 then + local dmg + if nodef.drowning > 0 then + dmg = nodef.drowning + else + dmg = 4 + end + self:damage_effect(dmg) + self.health = self.health - dmg + end + if self:check_for_death("drowning", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + else + self.breath = math.min(self.breath_max, self.breath + 1) + end + end + + --- suffocation inside solid node + -- FIXME: Redundant with mcl_playerplus + if (self.suffocation == true) + and (nodef.walkable == nil or nodef.walkable == true) + and (nodef.collision_box == nil or nodef.collision_box.type == "regular") + and (nodef.node_box == nil or nodef.node_box.type == "regular") + and (nodef.groups.disable_suffocation ~= 1) + and (nodef.groups.opaque == 1) then + + -- Short grace period before starting to take suffocation damage. + -- This is different from players, who take damage instantly. + -- This has been done because mobs might briefly be inside solid nodes + -- when e.g. climbing up stairs. + -- This is a bit hacky because it assumes that do_env_damage + -- is called roughly every second only. + self.suffocation_timer = self.suffocation_timer + 1 + if self.suffocation_timer >= 3 then + -- 2 damage per second + -- TODO: Deal this damage once every 1/2 second + self.health = self.health - 2 + + if self:check_for_death("suffocation", {type = "environment", + pos = pos, node = self.standing_in}) then + return true + end + end + else + self.suffocation_timer = 0 + end + + return self:check_for_death("unknown", {type = "unknown"}) +end + +function mob_class:step_damage (dtime, pos) + if not self.fire_resistant then + mcl_burning.tick(self.object, dtime, self) + if not self.object:get_pos() then return true end -- mcl_burning.tick may remove object immediately + + if self:check_for_death("fire", {type = "fire"}) then + return true + end + end + + -- environmental damage timer (every 1 second) + self.env_damage_timer = self.env_damage_timer + dtime + + if self.env_damage_timer > 1 then + self.env_damage_timer = 0 + + self:check_entity_cramming() + + -- check for environmental damage (water, fire, lava etc.) + if self:do_env_damage() then + return true + end + + self:replace_node(pos) -- (sheep eats grass etc.) + end +end + +function mob_class:damage_mob(reason,damage) + if not self.health then return end + damage = math.floor(damage) + if damage > 0 then + self.health = self.health - damage + + mcl_mobs.effect(self.object:get_pos(), 5, "mcl_particles_smoke.png", 1, 2, 2, nil) + + if self:check_for_death(reason, {type = reason}) then + return true + end + end +end + +function mob_class:check_entity_cramming() + local p = self.object:get_pos() + if not p then return end + local oo = minetest.get_objects_inside_radius(p,1) + local mobs = {} + for _,o in pairs(oo) do + local l = o:get_luaentity() + if l and l.is_mob and l.health > 0 then table.insert(mobs,l) end + end + local clear = #mobs < ENTITY_CRAMMING_MAX + local ncram = {} + for _,l in pairs(mobs) do + if l then + if clear then + l.cram = nil + elseif l.cram == nil and not self.child then + table.insert(ncram,l) + elseif l.cram then + l:damage_mob("cramming",CRAMMING_DAMAGE) + end + end + end + for i,l in pairs(ncram) do + if i > ENTITY_CRAMMING_MAX then + l.cram = true + else + l.cram = nil + end + end +end + +-- falling and fall damage +-- returns true if mob died +function mob_class:falling(pos) + + if self.fly and self.state ~= "die" then + return + end + + if not self.fall_speed then self.fall_speed = DEFAULT_FALL_SPEED end + + if mcl_portals ~= nil then + if mcl_portals.nether_portal_cooloff(self.object) then + return false -- mob has teleported through Nether portal - it's 99% not falling + end + end + + -- floating in water (or falling) + local v = self.object:get_velocity() + if v then + local new_acceleration + + if v.y > 0 then + -- apply gravity when moving up + new_acceleration = vector.new(0, DEFAULT_FALL_SPEED, 0) + elseif v.y <= 0 and v.y > self.fall_speed then + -- fall downwards at set speed + new_acceleration = vector.new(0, self.fall_speed, 0) + else + -- stop accelerating once max fall speed hit + new_acceleration =vector.zero() + end + + self.object:set_acceleration(new_acceleration) + end + + local acc = self.object:get_acceleration() + + local registered_node = minetest.registered_nodes[node_ok(pos).name] + + if registered_node.groups.lava then + if acc and self.floats_on_lava == 1 then + self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0)) + end + end + + -- in water then float up + if registered_node.groups.water then + if acc and self.floats == 1 then + self.object:set_acceleration(vector.new(0, -self.fall_speed / (math.max(1, v.y) ^ 2), 0)) + end + else + -- fall damage onto solid ground + if self.fall_damage == 1 and self.object:get_velocity().y == 0 then + local n = node_ok(vector.offset(pos,0,-1,0)).name + local d = (self.old_y or 0) - self.object:get_pos().y + + if d > 5 and n ~= "air" and n ~= "ignore" then + local add = minetest.get_item_group(self.standing_on, "fall_damage_add_percent") + local damage = d - 5 + if add ~= 0 then + damage = damage + damage * (add/100) + end + self:damage_mob("fall",damage) + end + + self.old_y = self.object:get_pos().y + end + end +end + +function mob_class:check_water_flow() + -- Add water flowing for mobs from mcl_item_entity + local p, node, nn, def + p = self.object:get_pos() + node = minetest.get_node_or_nil(p) + if node then + nn = node.name + def = minetest.registered_nodes[nn] + end + + -- Move item around on flowing liquids + if def and def.liquidtype == "flowing" then + + --[[ Get flowing direction (function call from flowlib), if there's a liquid. + NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7. + Luckily, this is exactly what we need if we only care about water, which has this flowing distance. ]] + local vec = flowlib.quick_flow(p, node) + -- Just to make sure we don't manipulate the speed for no reason + if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then + -- Minecraft Wiki: Flowing speed is "about 1.39 meters per second" + local f = 1.39 + -- Set new item moving speed into the direciton of the liquid + local newv = vector.multiply(vec, f) + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_velocity({x = newv.x, y = -0.22, z = newv.z}) + + self.physical_state = true + self._flowing = true + self.object:set_properties({ + physical = true + }) + return + end + elseif self._flowing == true then + -- Disable flowing physics if not on/in flowing liquid + self._flowing = false + return + end +end + +function mob_class:check_dying() + if ((self.state and self.state=="die") or self:check_for_death()) and not self.animation.die_end then + local rot = self.object:get_rotation() + if rot then + rot.z = ((math.pi/2-rot.z)*.2)+rot.z + self.object:set_rotation(rot) + end + return true + end +end + +function mob_class:check_suspend(player_in_active_range) + local pos = self.object:get_pos() + + if pos and not player_in_active_range then + local node_under = node_ok(vector.offset(pos,0,-1,0)).name + + self:set_animation( "stand", true) + + local acc = self.object:get_acceleration() + if acc then + if acc.y > 0 or node_under ~= "air" then + self.object:set_acceleration(vector.zero()) + self.object:set_velocity(vector.zero()) + end + end + return true + end +end diff --git a/mods/ENTITIES/mcl_mobs/spawning.lua b/mods/ENTITIES/mcl_mobs/spawning.lua new file mode 100644 index 000000000..c677aeacf --- /dev/null +++ b/mods/ENTITIES/mcl_mobs/spawning.lua @@ -0,0 +1,1171 @@ +--lua locals +local math, vector, minetest, mcl_mobs = math, vector, minetest, mcl_mobs +local mob_class = mcl_mobs.mob_class + +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 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 +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 vector_distance = vector.distance +local vector_new = vector.new +local vector_floor = vector.floor + +local table_copy = table.copy +local table_remove = table.remove +local pairs = pairs + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_spawning", false) +local function mcl_log (message, property) + if LOGGING_ON then + if property then + message = message .. ": " .. dump(property) + end + mcl_util.mcl_log (message, "[Mobs spawn]", true) + end +end + +local dbg_spawn_attempts = 0 +local dbg_spawn_succ = 0 +local dbg_spawn_counts = {} + +local remove_far = true + +local WAIT_FOR_SPAWN_ATTEMPT = 10 +local FIND_SPAWN_POS_RETRIES = 16 +local FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN = 8 + +local MOB_SPAWN_ZONE_INNER = 24 +local MOB_SPAWN_ZONE_MIDDLE = 32 +local MOB_SPAWN_ZONE_OUTER = 128 + +-- range for mob count +local MOB_CAP_INNER_RADIUS = 32 +local aoc_range = 136 + +local MISSING_CAP_DEFAULT = 15 +local MOBS_CAP_CLOSE = 10 + +local SPAWN_MAPGEN_LIMIT = mcl_vars.mapgen_limit - 150 + +local mob_cap = { + hostile = tonumber(minetest.settings:get("mcl_mob_cap_monster")) or 70, + passive = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10, + ambient = tonumber(minetest.settings:get("mcl_mob_cap_ambient")) or 15, + water = tonumber(minetest.settings:get("mcl_mob_cap_water")) or 8, + water_ambient = tonumber(minetest.settings:get("mcl_mob_cap_water_ambient")) or 20, + water_underground = tonumber(minetest.settings:get("mcl_mob_cap_water_underground")) or 5, + axolotl = tonumber(minetest.settings:get("mcl_mob_cap_axolotl")) or 2, -- TODO should be 5 when lush caves added + player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75, + global_hostile = tonumber(minetest.settings:get("mcl_mob_cap_hostile")) or 300, + global_non_hostile = tonumber(minetest.settings:get("mcl_mob_cap_non_hostile")) or 300, + total = tonumber(minetest.settings:get("mcl_mob_cap_total")) or 500, +} + +local peaceful_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_peaceful_percentage_spawned")) or 30 +local peaceful_group_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_peaceful_group_percentage_spawned")) or 15 +local hostile_group_percentage_spawned = tonumber(minetest.settings:get("mcl_mob_hostile_group_percentage_spawned")) or 20 + +mcl_log("Mob cap hostile: " .. mob_cap.hostile) +mcl_log("Mob cap water: " .. mob_cap.water) +mcl_log("Mob cap passive: " .. mob_cap.passive) + +mcl_log("Percentage of peacefuls spawned: " .. peaceful_percentage_spawned) +mcl_log("Percentage of peaceful spawns are group: " .. peaceful_group_percentage_spawned) +mcl_log("Percentage of hostile spawns are group: " .. hostile_group_percentage_spawned) + +--do mobs spawn? +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! + +local list_of_all_biomes = { + + -- underground: + + "FlowerForest_underground", + "JungleEdge_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + "MangroveSwamp_underground", + + -- ocean: + + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean", + "MangroveSwamp_ocean", + "MangroveSwamp_deep_ocean", + + -- water or beach? + + "MesaPlateauFM_sandlevel", + "MesaPlateauF_sandlevel", + "MesaBryce_sandlevel", + "Mesa_sandlevel", + + -- beach: + + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore", + "BambooJungleM_shore", + "BambooJungle_shore", + "MangroveSwamp_shore", + + -- dimension biome: + + "Nether", + "BasaltDelta", + "CrimsonForest", + "WarpedForest", + "SoulsandValley", + "End", + + -- Overworld regular: + + "Mesa", + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "ExtremeHillsM", + "ExtremeHills+_snowtop", + "Jungle", + "Savanna", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "Desert", + "ColdTaiga", + "MushroomIsland", + "IcePlainsSpikes", + "SunflowerPlains", + "IcePlains", + "RoofedForest", + "ExtremeHills+_snowtop", + "MesaPlateauFM_grasstop", + "JungleEdgeM", + "JungleM", + "BirchForestM", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "JungleEdge", + "SavannaM", + "MangroveSwamp", + "BambooJungle", + "BambooJungleEdge", + "BambooJungleEdgeM", + "BambooJungleM", +} + +-- count how many mobs are in an area +local function count_mobs(pos,r,mob_type) + local num = 0 + for _,l in pairs(minetest.luaentities) do + if l and l.is_mob and (mob_type == nil or l.type == mob_type) then + local p = l.object:get_pos() + if p and vector_distance(p,pos) < r then + num = num + 1 + end + end + end + return num +end + +local function count_mobs_total(mob_type) + local num = 0 + for _,l in pairs(minetest.luaentities) do + if l.is_mob then + if mob_type == nil or l.type == mob_type then + num = num + 1 + end + end + end + return num +end + +local function count_mobs_add_entry (mobs_list, mob_cat) + if mobs_list[mob_cat] then + mobs_list[mob_cat] = mobs_list[mob_cat] + 1 + else + mobs_list[mob_cat] = 1 + end +end + +--categorise_by can be name or type or spawn_class +local function count_mobs_all(categorise_by, pos) + local mobs_found_wide = {} + local mobs_found_close = {} + + local num = 0 + for _,entity in pairs(minetest.luaentities) do + if entity and entity.is_mob then + + local add_entry = false + --local mob_type = entity.type -- animal / monster / npc + local mob_cat = entity[categorise_by] + + if pos then + local mob_pos = entity.object:get_pos() + if mob_pos then + local distance = vector.distance(pos, mob_pos) + --mcl_log("distance: ".. distance) + if distance <= MOB_SPAWN_ZONE_MIDDLE then + --mcl_log("distance is close") + count_mobs_add_entry (mobs_found_close, mob_cat) + count_mobs_add_entry (mobs_found_wide, mob_cat) + add_entry = true + elseif distance <= MOB_SPAWN_ZONE_OUTER then + --mcl_log("distance is wide") + count_mobs_add_entry (mobs_found_wide, mob_cat) + add_entry = true + else + --mcl_log("mob_pos: " .. minetest.pos_to_string(mob_pos)) + end + end + else + count_mobs_add_entry (mobs_found_wide, mob_cat) + add_entry = true + end + + + if add_entry then + num = num + 1 + end + end + end + --mcl_log("num: ".. num) + return mobs_found_close, mobs_found_wide, num +end + +local function count_mobs_total_cap(mob_type) + local total = 0 + local num = 0 + local hostile = 0 + local non_hostile = 0 + for _,l in pairs(minetest.luaentities) do + if l.is_mob then + total = total + 1 + local nametagged = l.nametag and l.nametag ~= "" + if ( mob_type == nil or l.type == mob_type ) and not nametagged then + if l.spawn_class == "hostile" then + hostile = hostile + 1 + else + non_hostile = non_hostile + 1 + end + num = num + 1 + else + mcl_log("l.name", l.name) + mcl_log("l.nametag", l.nametag) + + end + end + end + mcl_log("Total mobs", total) + mcl_log("hostile", hostile) + mcl_log("non_hostile", non_hostile) + return num, non_hostile, hostile +end + +local function output_mob_stats(mob_counts, total_mobs, chat_display) + if (total_mobs) then + local total_output = "Total mobs found: " .. total_mobs + if chat_display then + minetest.log(total_output) + else + minetest.log("action", total_output) + end + + end + local detailed = "" + if mob_counts then + for k, v1 in pairs(mob_counts) do + detailed = detailed .. tostring(k) .. ": " .. tostring(v1) .. "; " + end + end + if detailed and detailed ~= "" then + if chat_display then + minetest.log(detailed) + else + minetest.log("action", detailed) + end + end +end + + +-- global functions + +function mcl_mobs:spawn_abm_check(pos, node, name) + -- global function to add additional spawn checks + -- return true to stop spawning mob +end + + +--[[ + Custom elements changed: + +name: +the mobs name + +dimension: +"overworld" +"nether" +"end" + +types of spawning: +"water" +"ground" +"lava" + +biomes: tells the spawner to allow certain mobs to spawn in certain biomes +{"this", "that", "grasslands", "whatever"} + + +what is aoc??? objects in area + +WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua?? +]]-- + + +--this is where all of the spawning information is kept +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 + + if not def then + minetest.log("warning", "Empty mob spawn setup definition") + return + end + + local name = def.name + if not name then + minetest.log("warning", "Missing mob name") + return + end + + local dimension = def.dimension or "overworld" + local type_of_spawning = def.type_of_spawning or "ground" + local biomes = def.biomes or list_of_all_biomes + local min_light = def.min_light or 0 + local max_light = def.max_light or (minetest.LIGHT_MAX + 1) + local chance = def.chance or 1000 + local aoc = def.aoc or aoc_range + local min_height = def.min_height or mcl_mapgen.overworld.min + local max_height = def.max_height or mcl_mapgen.overworld.max + local day_toggle = def.day_toggle + local on_spawn = def.on_spawn + local check_position = def.check_position + + -- chance/spawn number override in minetest.conf for registered mob + local numbers = minetest.settings:get(name) + if numbers then + numbers = numbers:split(",") + chance = tonumber(numbers[1]) or chance + aoc = tonumber(numbers[2]) or aoc + if chance == 0 then + minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name)) + return + end + minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) + end + + if chance < 1 then + chance = 1 + minetest.log("warning", "Chance shouldn't be less than 1 (mob name: " .. name ..")") + end + + spawn_dictionary[#spawn_dictionary + 1] = { + name = name, + dimension = dimension, + type_of_spawning = type_of_spawning, + biomes = biomes, + min_light = min_light, + max_light = max_light, + chance = chance, + aoc = aoc, + min_height = min_height, + max_height = max_height, + day_toggle = day_toggle, + check_position = check_position, + on_spawn = on_spawn, + } + summary_chance = summary_chance + chance +end + +function mcl_mobs:mob_light_lvl(mob_name, dimension) + local spawn_dictionary_consolidated = {} + + if non_spawn_dictionary[mob_name] then + local mob_dimension = non_spawn_dictionary[mob_name][dimension] + if mob_dimension then + --minetest.log("Found in non spawn dictionary for dimension") + return mob_dimension.min_light, mob_dimension.max_light + else + --minetest.log("Found in non spawn dictionary but not for dimension") + local overworld_non_spawn_def = non_spawn_dictionary[mob_name]["overworld"] + if overworld_non_spawn_def then + return overworld_non_spawn_def.min_light, overworld_non_spawn_def.max_light + end + end + else + --minetest.log("must be in spawning dictionary") + for i,v in pairs(spawn_dictionary) do + local current_mob_name = spawn_dictionary[i].name + local current_mob_dim = spawn_dictionary[i].dimension + if mob_name == current_mob_name then + if not spawn_dictionary_consolidated[current_mob_name] then + spawn_dictionary_consolidated[current_mob_name] = {} + end + spawn_dictionary_consolidated[current_mob_name][current_mob_dim] = { + ["min_light"] = spawn_dictionary[i].min_light, + ["max_light"] = spawn_dictionary[i].max_light + } + end + end + + if spawn_dictionary_consolidated[mob_name] then + --minetest.log("is in consolidated") + local mob_dimension = spawn_dictionary_consolidated[mob_name][dimension] + if mob_dimension then + --minetest.log("found for dimension") + return mob_dimension.min_light, mob_dimension.max_light + else + --minetest.log("not found for dimension, use overworld def") + local mob_dimension_default = spawn_dictionary_consolidated[mob_name]["overworld"] + if mob_dimension_default then + return mob_dimension_default.min_light, mob_dimension_default.max_light + end + end + else + --minetest.log("not in consolidated") + end + end + + minetest.log("action", "There are no light levels for mob (" .. tostring(mob_name) .. ") in dimension (" .. tostring(dimension) .. "). Return defaults") + return 0, minetest.LIGHT_MAX+1 +end + +function mcl_mobs:non_spawn_specific(mob_name,dimension,min_light,max_light) + table.insert(non_spawn_dictionary, mob_name) + non_spawn_dictionary[mob_name] = { + [dimension] = { + min_light = min_light , max_light = max_light + } + } +end + +function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn, check_position) + + -- Do mobs spawn at all? + if not mobs_spawn then + return + end + + -- chance/spawn number override in minetest.conf for registered mob + local numbers = minetest.settings:get(name) + + if numbers then + numbers = numbers:split(",") + chance = tonumber(numbers[1]) or chance + aoc = tonumber(numbers[2]) or aoc + + if chance == 0 then + minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name)) + return + end + + minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc)) + end + + --load information into the spawn dictionary + local key = #spawn_dictionary + 1 + spawn_dictionary[key] = {} + spawn_dictionary[key]["name"] = name + spawn_dictionary[key]["dimension"] = dimension + spawn_dictionary[key]["type_of_spawning"] = type_of_spawning + spawn_dictionary[key]["biomes"] = biomes + spawn_dictionary[key]["min_light"] = min_light + spawn_dictionary[key]["max_light"] = max_light + spawn_dictionary[key]["chance"] = chance + spawn_dictionary[key]["aoc"] = aoc + spawn_dictionary[key]["min_height"] = min_height + 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 + + +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 + + -- 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 + +local function decypher_limits(posy) + posy = math_floor(posy) + return posy - MOB_SPAWN_ZONE_MIDDLE, posy + MOB_SPAWN_ZONE_MIDDLE +end + +--a simple helper function for mob_spawn +local function biome_check(biome_list, biome_goal) + for _, data in pairs(biome_list) do + if data == biome_goal then + return true + end + end + + return false +end + +local function is_farm_animal(n) + return n == "mobs_mc:pig" or n == "mobs_mc:cow" or n == "mobs_mc:sheep" or n == "mobs_mc:chicken" or n == "mobs_mc:horse" or n == "mobs_mc:donkey" +end + +local function get_water_spawn(p) + local nn = minetest.find_nodes_in_area(vector.offset(p,-2,-1,-2),vector.offset(p,2,-15,2),{"group:water"}) + if nn and #nn > 0 then + return nn[math.random(#nn)] + end +end + +local function has_room(self,pos) + local cb = self.collisionbox + local nodes = {} + if self.fly_in then + local t = type(self.fly_in) + if t == "table" then + nodes = table.copy(self.fly_in) + elseif t == "string" then + table.insert(nodes,self.fly_in) + end + end + table.insert(nodes,"air") + local x = cb[4] - cb[1] + local y = cb[5] - cb[2] + local z = cb[6] - cb[3] + local r = math.ceil(x * y * z) + local p1 = vector.offset(pos,cb[1],cb[2],cb[3]) + local p2 = vector.offset(pos,cb[4],cb[5],cb[6]) + local n = #minetest.find_nodes_in_area(p1,p2,nodes) or 0 + if r > n then + minetest.log("warning","[mcl_mobs] No room for mob "..self.name.." at "..minetest.pos_to_string(vector.round(pos))) + return false + end + return true +end + + + +local function spawn_check(pos, spawn_def) + if not spawn_def or not pos then return end + + dbg_spawn_attempts = dbg_spawn_attempts + 1 + local dimension = mcl_worlds.pos_to_dimension(pos) + 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 or not gotten_biome then return end + + gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with + + local is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0 + if not is_ground then + pos.y = pos.y - 1 + gotten_node = get_node(pos).name + is_ground = minetest.get_item_group(gotten_node,"solid") ~= 0 + end + pos.y = pos.y + 1 + local is_water = get_item_group(gotten_node, "water") ~= 0 + local is_lava = get_item_group(gotten_node, "lava") ~= 0 + local is_leaf = get_item_group(gotten_node, "leaves") ~= 0 + local is_bedrock = gotten_node == "mcl_core:bedrock" + local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0 + + 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) + + 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) + and (spawn_def.type_of_spawning ~= "water" or is_water) + and not is_bedrock + and has_room(mob_def,pos) + 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") + + 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 + else + --mcl_log("Spawn check level 3 failed") + end + else + --mcl_log("Spawn check level 2 failed") + end + else + --mcl_log("Spawn check level 1 failed") + end + return false +end + +function mcl_mobs.spawn(pos,id) + local def = minetest.registered_entities[id] or minetest.registered_entities["mobs_mc:"..id] or minetest.registered_entities["extra_mobs:"..id] + if not def or (def.can_spawn and not def.can_spawn(pos)) or not def.is_mob then + return false + end + if not dbg_spawn_counts[def.name] then + dbg_spawn_counts[def.name] = 1 + else + dbg_spawn_counts[def.name] = dbg_spawn_counts[def.name] + 1 + end + return minetest.add_entity(pos, def.name) +end + + +local function spawn_group(p,mob,spawn_on,amount_to_spawn) + local nn= minetest.find_nodes_in_area_under_air(vector.offset(p,-5,-3,-5),vector.offset(p,5,3,5),spawn_on) + local o + table.shuffle(nn) + if not nn or #nn < 1 then + nn = {} + table.insert(nn,p) + end + + for i = 1, amount_to_spawn do + local sp = vector.offset(nn[math.random(#nn)],0,1,0) + if spawn_check(nn[math.random(#nn)],mob) then + if mob.type_of_spawning == "water" then + sp = get_water_spawn(sp) + end + o = mcl_mobs.spawn(sp,mob.name) + if o then dbg_spawn_succ = dbg_spawn_succ + 1 end + end + end + return o +end + +mcl_mobs.spawn_group = spawn_group + +local S = minetest.get_translator("mcl_mobs") + +minetest.register_chatcommand("spawn_mob",{ + privs = { debug = true }, + description=S("spawn_mob is a chatcommand that allows you to type in the name of a mob without 'typing mobs_mc:' all the time like so; 'spawn_mob spider'. however, there is more you can do with this special command, currently you can edit any number, boolean, and string variable you choose with this format: spawn_mob 'any_mob:var:'. any_mob being your mob of choice, mobs_variable being the variable, and variable value being the value of the chosen variable. and example of this format: \n spawn_mob skeleton:var:\n this would spawn a skeleton that wouldn't attack you. REMEMBER-THIS> when changing a number value always prefix it with 'NUM', example: \n spawn_mob skeleton:var:\n this setting the skelly's jump height to 10. if you want to make multiple changes to a mob, you can, example: \n spawn_mob skeleton:var::var::var::var:\n etc."), + func = function(n,param) + local pos = minetest.get_player_by_name(n):get_pos() + + local modifiers = {} + for capture in string.gmatch(param, "%:(.-)%:") do + table.insert(modifiers, ":"..capture) + end + + local mod1 = string.find(param, ":") + + + + local mobname = param + if mod1 then + mobname = string.sub(param, 1, mod1-1) + end + + local mob = mcl_mobs.spawn(pos,mobname) + + if mob then + for c=1, #modifiers do + modifs = modifiers[c] + + local mod1 = string.find(modifs, ":") + local mod_start = string.find(modifs, "<") + local mod_vals = string.find(modifs, "=") + local mod_end = string.find(modifs, ">") + local mob_entity = mob:get_luaentity() + if string.sub(modifs, mod1+1, mod1+3) == "var" then + if mod1 and mod_start and mod_vals and mod_end then + local variable = string.sub(modifs, mod_start+1, mod_vals-1) + local value = string.sub(modifs, mod_vals+1, mod_end-1) + + number_tag = string.find(value, "NUM") + if number_tag then + value = tonumber(string.sub(value, 4, -1)) + end + + if value == "true" then + value = true + elseif value == "false" then + value = false + end + + if not mob_entity[variable] then + minetest.log("warning", n.." mob variable "..variable.." previously unset") + end + + mob_entity[variable] = value + + else + minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing paramaters") + end + else + minetest.log("warning", n.." couldn't modify "..mobname.." at "..minetest.pos_to_string(pos).. ", missing modification type") + end + end + + minetest.log("action", n.." spawned "..mobname.." at "..minetest.pos_to_string(pos)) + return true, mobname.." spawned at "..minetest.pos_to_string(pos) + else + return false, "Couldn't spawn "..mobname + end + end +}) + +if mobs_spawn then + + local perlin_noise + + -- Get pos to spawn, x and z are randomised, y is range + + + local function mob_cap_space (pos, mob_type, mob_counts_close, mob_counts_wide, cap_space_hostile, cap_space_non_hostile) + + -- Some mob examples + --type = "monster", spawn_class = "hostile", + --type = "animal", spawn_class = "passive", + --local cod = { type = "animal", spawn_class = "water", + + local type_cap = mob_cap[mob_type] or MISSING_CAP_DEFAULT + local close_zone_cap = MOBS_CAP_CLOSE + + local mob_total_wide = mob_counts_wide[mob_type] + if not mob_total_wide then + --mcl_log("none of type found. set as 0") + mob_total_wide = 0 + end + + local cap_space_wide = math.max(type_cap - mob_total_wide, 0) + + mcl_log("mob_type", mob_type) + mcl_log("cap_space_wide", cap_space_wide) + + local cap_space_available = 0 + if mob_type == "hostile" then + mcl_log("cap_space_global", cap_space_hostile) + cap_space_available = math.min(cap_space_hostile, cap_space_wide) + else + mcl_log("cap_space_global", cap_space_non_hostile) + cap_space_available = math.min(cap_space_non_hostile, cap_space_wide) + end + + local mob_total_close = mob_counts_close[mob_type] + if not mob_total_close then + --mcl_log("none of type found. set as 0") + mob_total_close = 0 + end + + local cap_space_close = math.max(close_zone_cap - mob_total_close, 0) + cap_space_available = math.min(cap_space_available, cap_space_close) + + mcl_log("cap_space_close", cap_space_close) + mcl_log("cap_space_available", cap_space_available) + + if false and mob_type == "water" then + mcl_log("mob_type: " .. mob_type .. " and pos: " .. minetest.pos_to_string(pos)) + mcl_log("wide: " .. mob_total_wide .. "/" .. type_cap) + mcl_log("cap_space_wide: " .. cap_space_wide) + mcl_log("close: " .. mob_total_close .. "/" .. close_zone_cap) + mcl_log("cap_space_close: " .. cap_space_close) + end + + return cap_space_available + end + + 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) + + --mcl_log("mapgen_limit: " .. SPAWN_MAPGEN_LIMIT) + local i = 0 + repeat + local goal_pos = get_next_mob_spawn_pos(pos) + + 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 + + else + mcl_log("Pos outside mapgen limits: " .. minetest.pos_to_string(goal_pos)) + 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 + + 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 + minetest.log("action", "[Mobs spawn] Cannot find a valid spawn position after retries: " .. FIND_SPAWN_POS_RETRIES) + return + end + + local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("spawn_class", spawning_position) + --output_mob_stats(mob_counts_close, total_mobs) + --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 + + 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 + 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 + end + --minetest.log(mob_def.name.." "..step_chance.. " "..mob_chance) + + local mob_def = mob_library_worker_table[mob_index] + if mob_def and mob_def.name and minetest.registered_entities[mob_def.name] then + + local mob_def_ent = minetest.registered_entities[mob_def.name] + local mob_spawn_class = mob_def_ent.spawn_class + + local cap_space_available = mob_cap_space (spawning_position, mob_spawn_class, mob_counts_close, mob_counts_wide, cap_space_hostile, cap_space_non_hostile) + + if cap_space_available > 0 then + --mcl_log("Cap space available") + + -- Spawn caps for animals and water creatures fill up rapidly. Need to throttle this somewhat + -- for performance and for early game challenge. We don't want to reduce hostiles though. + local spawn_hostile = (mob_spawn_class == "hostile") + local spawn_passive = (mob_spawn_class ~= "hostile") and math.random(100) < peaceful_percentage_spawned + + --mcl_log("Spawn_passive: " .. tostring(spawn_passive)) + --mcl_log("Spawn_hostile: " .. tostring(spawn_hostile)) + + if (spawn_hostile or spawn_passive) and spawn_check(spawning_position,mob_def) then + if mob_def.type_of_spawning == "water" then + spawning_position = get_water_spawn(spawning_position) + if not spawning_position then + minetest.log("warning","[mcl_mobs] no water spawn for mob "..mob_def.name.." found at "..minetest.pos_to_string(vector.round(pos))) + return + end + end + if mob_def_ent.can_spawn and not mob_def_ent.can_spawn(spawning_position) then + minetest.log("warning","[mcl_mobs] mob "..mob_def.name.." refused to spawn at "..minetest.pos_to_string(vector.round(spawning_position))) + return + end + + --everything is correct, spawn mob + local spawn_in_group = mob_def_ent.spawn_in_group or 4 + + local spawn_group_hostile = (mob_spawn_class == "hostile") and (math.random(100) < hostile_group_percentage_spawned) + local spawn_group_passive = (mob_spawn_class ~= "hostile") and (math.random(100) < peaceful_group_percentage_spawned) + + mcl_log("spawn_group_hostile: " .. tostring(spawn_group_hostile)) + mcl_log("spawn_group_passive: " .. tostring(spawn_group_passive)) + + local spawned + if spawn_in_group and (spawn_group_hostile or spawn_group_passive) then + local group_min = mob_def_ent.spawn_in_group_min or 1 + if not group_min then group_min = 1 end + + local amount_to_spawn = math.random(group_min, spawn_in_group) + mcl_log("Spawning quantity: " .. amount_to_spawn) + amount_to_spawn = math.min(amount_to_spawn, cap_space_available) + mcl_log("throttled spawning quantity: " .. amount_to_spawn) + + if logging then + minetest.log("action", "[mcl_mobs] A group of " ..amount_to_spawn .. " " .. mob_def.name .. " mob spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at " .. minetest.pos_to_string(spawning_position, 1)) + end + spawned = spawn_group(spawning_position,mob_def,{minetest.get_node(vector.offset(spawning_position,0,-1,0)).name}, amount_to_spawn) + else + if logging then + minetest.log("action", "[mcl_mobs] Mob " .. mob_def.name .. " spawns on " ..minetest.get_node(vector.offset(spawning_position,0,-1,0)).name .." at ".. minetest.pos_to_string(spawning_position, 1)) + end + spawned = mcl_mobs.spawn(spawning_position, mob_def.name) + end + + if spawned then + --mcl_log("We have spawned") + mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("spawn_class", pos) + local new_spawning_position = find_spawning_position(pos, FIND_SPAWN_POS_RETRIES_SUCCESS_RESPIN) + if new_spawning_position then + mcl_log("Setting new spawning position") + spawning_position = new_spawning_position + else + mcl_log("Cannot set new spawning position") + end + end + else + --mcl_log("Spawn check failed") + end + else + --mcl_log("Cap space full") + end + + end + current_summary_chance = current_summary_chance - mob_chance + table_remove(mob_library_worker_table, mob_index) + end + end + + + --MAIN LOOP + + local timer = 0 + minetest.register_globalstep(function(dtime) + + timer = timer + dtime + if timer < WAIT_FOR_SPAWN_ATTEMPT then return end + timer = 0 + + local players = get_connected_players() + local total_mobs, total_non_hostile, total_hostile = count_mobs_total_cap() + + local cap_space_hostile = math.max(mob_cap.global_hostile - total_hostile, 0) + local cap_space_non_hostile = math.max(mob_cap.global_non_hostile - total_non_hostile, 0) + mcl_log("global cap_space_hostile", cap_space_hostile) + mcl_log("global cap_space_non_hostile", cap_space_non_hostile) + + if total_mobs > mob_cap.total or total_mobs > #players * mob_cap.player then + minetest.log("action","[mcl_mobs] global mob cap reached. no cycle spawning.") + return + end --mob cap per player + + for _, player in pairs(players) do + local pos = player:get_pos() + local dimension = mcl_worlds.pos_to_dimension(pos) + -- ignore void and unloaded area + if dimension ~= "void" and dimension ~= "default" then + spawn_a_mob(pos, cap_space_hostile, cap_space_non_hostile) + end + end + end) +end + +local function despawn_allowed(self) + local nametag = self.nametag and self.nametag ~= "" + local not_busy = self.state ~= "attack" and self.following == nil + if self.can_despawn == true then + if not nametag and not_busy and not self.tamed == true and not self.persistent == true then + return true + end + end + return false +end + +function mob_class:despawn_allowed() + despawn_allowed(self) +end + + +assert(despawn_allowed({can_despawn=false}) == false, "despawn_allowed - can_despawn false failed") +assert(despawn_allowed({can_despawn=true}) == true, "despawn_allowed - can_despawn true failed") + +assert(despawn_allowed({can_despawn=true, nametag=""}) == true, "despawn_allowed - blank nametag failed") +assert(despawn_allowed({can_despawn=true, nametag=nil}) == true, "despawn_allowed - nil nametag failed") +assert(despawn_allowed({can_despawn=true, nametag="bob"}) == false, "despawn_allowed - nametag failed") + +assert(despawn_allowed({can_despawn=true, state="attack"}) == false, "despawn_allowed - attack state failed") +assert(despawn_allowed({can_despawn=true, following="blah"}) == false, "despawn_allowed - following state failed") + +assert(despawn_allowed({can_despawn=true, tamed=false}) == true, "despawn_allowed - not tamed") +assert(despawn_allowed({can_despawn=true, tamed=true}) == false, "despawn_allowed - tamed") + +assert(despawn_allowed({can_despawn=true, persistent=true}) == false, "despawn_allowed - persistent") +assert(despawn_allowed({can_despawn=true, persistent=false}) == true, "despawn_allowed - not persistent") + +function mob_class:check_despawn(pos, dtime) + self.lifetimer = self.lifetimer - dtime + + -- Despawning: when lifetimer expires, remove mob + if remove_far and despawn_allowed(self) then + if self.despawn_immediately or self.lifetimer <= 0 then + if logging then + minetest.log("action", "[mcl_mobs] Mob "..self.name.." despawns at "..minetest.pos_to_string(pos, 1) .. " lifetimer ran out") + end + mcl_burning.extinguish(self.object) + self.object:remove() + return true + elseif self.lifetimer <= 10 then + if math.random(10) < 4 then + self.despawn_immediately = true + else + self.lifetimer = 20 + end + end + end +end + + +minetest.register_chatcommand("mobstats",{ + privs = { debug = true }, + func = function(n,param) + --minetest.chat_send_player(n,dump(dbg_spawn_counts)) + local pos = minetest.get_player_by_name(n):get_pos() + minetest.chat_send_player(n,"mobs: within 32 radius of player/total loaded :"..count_mobs(pos,MOB_CAP_INNER_RADIUS) .. "/" .. count_mobs_total()) + minetest.chat_send_player(n,"spawning attempts since server start:" .. dbg_spawn_succ .. "/" .. dbg_spawn_attempts) + + local mob_counts_close, mob_counts_wide, total_mobs = count_mobs_all("name") -- Can use "type" + output_mob_stats(mob_counts_wide, total_mobs, true) + end +}) diff --git a/mods/ENTITIES/mcl_mobs/textures/mobs_blood.png b/mods/ENTITIES/mcl_mobs/textures/mobs_blood.png deleted file mode 100644 index aa4a6123c..000000000 Binary files a/mods/ENTITIES/mcl_mobs/textures/mobs_blood.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_paintings/init.lua b/mods/ENTITIES/mcl_paintings/init.lua index 25811d87d..26bd2c61b 100644 --- a/mods/ENTITIES/mcl_paintings/init.lua +++ b/mods/ENTITIES/mcl_paintings/init.lua @@ -1,12 +1,15 @@ mcl_paintings = {} -dofile(minetest.get_modpath(minetest.get_current_modname()).."/paintings.lua") +local modname = minetest.get_current_modname() +dofile(minetest.get_modpath(modname).."/paintings.lua") -local S = minetest.get_translator("mcl_paintings") +local S = minetest.get_translator(modname) + +local math = math local wood = "[combine:16x16:-192,0=mcl_paintings_paintings.png" -local is_protected = function(pos, name) +local function is_protected(pos, name) if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return true @@ -17,7 +20,7 @@ end -- Check if there's a painting for provided painting size. -- If yes, returns the arguments. -- If not, returns the next smaller available painting. -local shrink_painting = function(x, y) +local function shrink_painting(x, y) if x > 4 or y > 4 then return nil end @@ -43,7 +46,7 @@ local shrink_painting = function(x, y) end end -local get_painting = function(x, y, motive) +local function get_painting(x, y, motive) local painting = mcl_paintings.paintings[y] and mcl_paintings.paintings[y][x] and mcl_paintings.paintings[y][x][motive] if not painting then return nil @@ -53,7 +56,7 @@ local get_painting = function(x, y, motive) return "[combine:"..sx.."x"..sy..":"..px..","..py.."=mcl_paintings_paintings.png" end -local get_random_painting = function(x, y) +local function get_random_painting(x, y) if not mcl_paintings.paintings[y] or not mcl_paintings.paintings[y][x] then return nil end @@ -65,7 +68,7 @@ local get_random_painting = function(x, y) return get_painting(x, y, r), r end -local size_to_minmax = function(size) +--[[local function size_to_minmax(size) local min, max if size == 2 then min = -0.5 @@ -81,13 +84,13 @@ local size_to_minmax = function(size) max = 0.5 end return min, max -end +end]] -local size_to_minmax_entity = function(size) +local function size_to_minmax_entity(size) return -size/2, size/2 end -local set_entity = function(object) +local function set_entity(object) local ent = object:get_luaentity() local wallm = ent._facing local xsize = ent._xsize @@ -143,6 +146,7 @@ minetest.register_entity("mcl_paintings:painting", { _xsize = 1, _ysize = 1, on_activate = function(self, staticdata) + self.object:set_armor_groups({immortal = 1}) if staticdata and staticdata ~= "" then local data = minetest.deserialize(staticdata) if data then @@ -165,18 +169,20 @@ minetest.register_entity("mcl_paintings:painting", { } return minetest.serialize(data) end, - on_death = function(self, killer) - -- Drop as item on death - local kname = "" - if killer and killer:is_player() then - kname = killer:get_player_name() - end - if not minetest.is_creative_enabled(kname) then + on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + -- Drop as item on punch + if puncher and puncher:is_player() then + local kname = puncher:get_player_name() local pos = self._pos if not pos then pos = self.object:get_pos() end - minetest.add_item(pos, "mcl_paintings:painting") + if not minetest.is_protected(pos, kname) then + self.object:remove() + if not minetest.is_creative_enabled(kname) then + minetest.add_item(pos, "mcl_paintings:painting") + end + end end end, }) @@ -188,6 +194,14 @@ minetest.register_craftitem("mcl_paintings:painting", { if pointed_thing.type ~= "node" then return itemstack end + + 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 + local dir = vector.subtract(pointed_thing.above, pointed_thing.under) dir = vector.normalize(dir) if dir.y ~= 0 then @@ -290,6 +304,8 @@ minetest.register_craftitem("mcl_paintings:painting", { end, }) +mcl_wip.register_wip_item("mcl_paintings:painting") + minetest.register_craft({ output = "mcl_paintings:painting", recipe = { diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.dk.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.dk.tr new file mode 100644 index 000000000..3c2844d01 --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.dk.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=Maleri diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.es.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.es.tr new file mode 100644 index 000000000..d1e4d3f24 --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.es.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=Cuadro diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr new file mode 100644 index 000000000..6b35b9edb --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.ja.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=絵画 diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pl.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pl.tr new file mode 100644 index 000000000..473540dda --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.pl.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=Obraz diff --git a/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.zh_TW.tr b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.zh_TW.tr new file mode 100644 index 000000000..d4b792185 --- /dev/null +++ b/mods/ENTITIES/mcl_paintings/locale/mcl_paintings.zh_TW.tr @@ -0,0 +1,2 @@ +# textdomain:mcl_paintings +Painting=畫 diff --git a/mods/ENTITIES/mcl_paintings/mod.conf b/mods/ENTITIES/mcl_paintings/mod.conf index ea1d61c3d..2c6955360 100644 --- a/mods/ENTITIES/mcl_paintings/mod.conf +++ b/mods/ENTITIES/mcl_paintings/mod.conf @@ -1 +1,5 @@ name = mcl_paintings +author = Wuzzy +description = The paintings mod for MCL2 +depends = mcl_wip + diff --git a/mods/ENTITIES/mcl_paintings/paintings.lua b/mods/ENTITIES/mcl_paintings/paintings.lua index d606306c2..ccf584364 100644 --- a/mods/ENTITIES/mcl_paintings/paintings.lua +++ b/mods/ENTITIES/mcl_paintings/paintings.lua @@ -3,7 +3,7 @@ local TS = 16 -- texture size mcl_paintings.paintings = { [1] = { [1] = { - { cx = 0, cy = 0 }, + { cx = 0, cy = 0 }, { cx = TS, cy = 0 }, { cx = 2*TS, cy = 0 }, { cx = 3*TS, cy = 0 }, @@ -26,7 +26,7 @@ mcl_paintings.paintings = { { cx = 0, cy = 4*TS }, { cx = TS, cy = 4*TS }, }, - [2] = { + [2] = { { cx = 0, cy = 8*TS }, { cx = 2*TS, cy = 8*TS }, { cx = 4*TS, cy = 8*TS }, @@ -35,7 +35,7 @@ mcl_paintings.paintings = { { cx = 10*TS, cy = 8*TS }, }, [3] = 2, - [4] = { + [4] = { { cx = 0, cy = 6*TS }, }, }, diff --git a/mods/ENTITIES/mcl_paintings/textures/mcl_paintings_painting.png b/mods/ENTITIES/mcl_paintings/textures/mcl_paintings_painting.png deleted file mode 100644 index afaaa935d..000000000 Binary files a/mods/ENTITIES/mcl_paintings/textures/mcl_paintings_painting.png and /dev/null differ diff --git a/mods/ENTITIES/mcl_wither_spawning/init.lua b/mods/ENTITIES/mcl_wither_spawning/init.lua new file mode 100644 index 000000000..74cd1e6e2 --- /dev/null +++ b/mods/ENTITIES/mcl_wither_spawning/init.lua @@ -0,0 +1,60 @@ +local dim = {"x", "z"} + +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +local function load_schem(filename) + local file = io.open(modpath .. "/schems/" .. filename, "r") + local data = minetest.deserialize(file:read()) + file:close() + return data +end + +local wither_spawn_schems = {} + +for _, d in pairs(dim) do + wither_spawn_schems[d] = load_schem("wither_spawn_" .. d .. ".we") +end + +local function check_schem(pos, schem) + for _, n in pairs(schem) do + if minetest.get_node(vector.add(pos, n)).name ~= n.name then + return false + end + end + return true +end + +local function remove_schem(pos, schem) + for _, n in pairs(schem) do + minetest.remove_node(vector.add(pos, n)) + end +end + +local function wither_spawn(pos) + 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 + remove_schem(p, schem) + minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither") + local objects = minetest.get_objects_inside_radius(pos, 20) + for _, players in ipairs(objects) do + if players:is_player() then + awards.unlock(players:get_player_name(), "mcl:witheringHeights") + end + end + end + end + end +end + +local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"] +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) + end + return old_on_place(itemstack, placer, pointed) +end diff --git a/mods/ENTITIES/mcl_wither_spawning/mod.conf b/mods/ENTITIES/mcl_wither_spawning/mod.conf new file mode 100644 index 000000000..d144bb1ea --- /dev/null +++ b/mods/ENTITIES/mcl_wither_spawning/mod.conf @@ -0,0 +1,4 @@ +name = mcl_wither_spawning +description = Wither Spawning for MineClone2 +author = Fleckenstein +depends = mobs_mc, mcl_heads diff --git a/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_x.we b/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_x.we new file mode 100644 index 000000000..6394bdc3f --- /dev/null +++ b/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_x.we @@ -0,0 +1 @@ +return {{["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 0, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 1, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 1, ["x"] = 2, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 2, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}} diff --git a/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_z.we b/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_z.we new file mode 100644 index 000000000..6b1775773 --- /dev/null +++ b/mods/ENTITIES/mcl_wither_spawning/schems/wither_spawn_z.we @@ -0,0 +1 @@ +return {{["y"] = 0, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 2}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 1, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 2, ["param2"] = 1, ["param1"] = 15}} diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua deleted file mode 100644 index 74c92d415..000000000 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ /dev/null @@ -1,333 +0,0 @@ ---[[ This table contains the concrete itemstrings to be used by this mod. -All mobs in this mod must use variables in this table, instead -of hardcoding the itemstring. -This way, external mods are enabled to replace the itemstrings to provide -their own items and game integration is made much simpler. - -An item IDs is supposed to be overwritten by adding -mobs_mc.override.items["example:item"] in a game mod -with name "mobs_mc_gameconfig". ]] - - --- Standard items - --- If true, mobs_mc adds the monster egg nodes (needs default mod). --- Set to false in your gameconfig mod if you create your own monster egg nodes. -mobs_mc.create_monster_egg_nodes = true - -mobs_mc.items = {} - -mobs_mc.items = { - -- Items defined in mobs_mc - blaze_rod = "mobs_mc:blaze_rod", - blaze_powder = "mobs_mc:blaze_powder", - chicken_raw = "mobs_mc:chicken_raw", - chicken_cooked = "mobs_mc:chicken_cooked", - feather = "mobs_mc:feather", - beef_raw = "mobs_mc:beef_raw", - beef_cooked = "mobs_mc:beef_cooked", - bowl = "mobs_mc:bowl", - mushroom_stew = "mobs_mc:mushroom_stew", - milk = "mobs_mc:milk_bucket", - dragon_egg = "mobs_mc:dragon_egg", - egg = "mobs_mc:egg", - ender_eye = "mobs_mc:ender_eye", - ghast_tear = "mobs_mc:ghast_tear", - saddle = "mobs:saddle", - iron_horse_armor = "mobs_mc:iron_horse_armor", - gold_horse_armor = "mobs_mc:gold_horse_armor", - diamond_horse_armor = "mobs_mc:diamond_horse_armor", - porkchop_raw = "mobs_mc:porkchop_raw", - porkchop_cooked = "mobs_mc:porkchop_cooked", - carrot_on_a_stick = "mobs_mc:carrot_on_a_stick", - rabbit_raw = "mobs_mc:rabbit_raw", - rabbit_cooked = "mobs_mc:rabbit_cooked", - rabbit_hide = "mobs_mc:rabbit_hide", - mutton_raw = "mobs_mc:mutton_raw", - mutton_cooked = "mobs_mc:mutton_cooked", - shulker_shell = "mobs_mc:shulker_shell", - magma_cream = "mobs_mc:magma_cream", - spider_eye = "mobs_mc:spider_eye", - snowball = "mobs_mc:snowball", - totem = "mobs_mc:totem", - rotten_flesh = "mobs_mc:rotten_flesh", - nether_star = "mobs_mc:nether_star", - bone = "mobs_mc:bone", - slimeball = "mobs_mc:slimeball", - arrow = "mobs_mc:arrow", - bow = "mobs_mc:bow_wood", - head_creeper = "mobs_mc:head_creeper", - head_zombie = "mobs_mc:head_zombie", - head_skeleton = "mobs_mc:head_skeleton", - head_wither_skeleton = "mobs_mc:head_wither_skeleton", - - -- External items - -- Mobs Redo - leather = "mobs:leather", - shears = "mobs:shears", - - -- Minetest Game - top_snow = "default:snow", - snow_block = "default:snowblock", - mushroom_red = "flowers:mushroom_red", - bucket = "bucket:bucket_empty", - grass_block = "default:dirt_with_grass", - string = "farming:string", - stick = "default:stick", - flint = "default:flint", - iron_ingot = "default:steel_ingot", - iron_block = "default:steelblock", - fire = "fire:basic_flame", - gunpowder = "tnt:gunpowder", - flint_and_steel = "fire:flint_and_steel", - water_source = "default:water_source", - river_water_source = "default:river_water_source", - black_dye = "dye:black", - poppy = "flowers:rose", - dandelion = "flowers:dandelion_yellow", - coal = "default:coal_lump", - emerald = "default:diamond", - iron_axe = "default:axe_steel", - gold_sword = "default:sword_mese", - gold_ingot = "default:gold_ingot", - gold_nugget = "default:gold_lump", - glowstone_dust = "default:mese_crystal_fragment", - redstone = "default:mese_crystal_fragment", - glass_bottle = "vessels:glass_bottle", - sugar = "default:papyrus", - wheat = "farming:wheat", - hay_bale = "farming:straw", - prismarine_shard = "default:mese_crystal_fragment", - prismarine_crystals = "default:mese_crystal", - apple = "default:apple", - golden_apple = "default:apple", - rabbit_foot = "mobs_mc:rabbit_foot", - - -- Boss items - wet_sponge = "default:gold_block", -- only dropped by elder guardian; there is no equivalent block in Minetest Game - - -- Other - nether_brick_block = "nether:brick", - mycelium = "ethereal:mushroom_dirt", - carrot = "farming:carrot", - potato = "farming:potato", - golden_carrot = "farming:carrot_gold", - fishing_rod = "fishing:pole_wood", - fish_raw = "fishing:fish_raw", - salmon_raw = "fishing:carp_raw", - clownfish_raw = "fishing:clownfish_raw", - pufferfish_raw = "fishing:pike_raw", - - cookie = "farming:cookie", - - - -- TODO: Add actual ender pearl - ender_pearl = "farorb:farorb", - - nether_portal = "nether:portal", - netherrack = "nether:rack", - nether_brick_block = "nether:brick", - - -- Wool (Minecraft color scheme) - wool_white = "wool:white", - wool_light_grey = "wool:grey", - wool_grey = "wool:dark_grey", - wool_blue = "wool:blue", - wool_lime = "wool:green", - wool_green = "wool:dark_green", - wool_purple = "wool:violet", - wool_pink = "wool:pink", - wool_yellow = "wool:yellow", - wool_orange = "wool:orange", - wool_brown = "wool:brown", - wool_red = "wool:red", - wool_cyan = "wool:cyan", - wool_magenta = "wool:magenta", - wool_black = "wool:black", - -- Light blue intentionally missing - - -- Special items - music_discs = {}, -- No music discs by default; used by creeper. Override this if your game has music discs. -} - --- Tables for attracting, feeding and breeding mobs -mobs_mc.follow = { - sheep = { mobs_mc.items.wheat }, - cow = { mobs_mc.items.wheat }, - chicken = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general - parrot = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general - horse = { mobs_mc.items.apple, mobs_mc.items.sugar, mobs_mc.items.wheat, mobs_mc.items.hay_bale, mobs_mc.items.golden_apple, mobs_mc.items.golden_carrot }, - llama = { mobs_mc.items.wheat, mobs_mc.items.hay_bale, }, - pig = { mobs_mc.items.potato, mobs_mc.items.carrot, mobs_mc.items.carrot_on_a_stick, - mobs_mc.items.apple, -- Minetest Game extra - }, - rabbit = { mobs_mc.items.dandelion, mobs_mc.items.carrot, mobs_mc.items.golden_carrot, "farming_plus:carrot_item", }, - ocelot = { mobs_mc.items.fish_raw, mobs_mc.items.salmon_raw, mobs_mc.items.clownfish_raw, mobs_mc.items.pufferfish_raw, - mobs_mc.items.chicken_raw, -- Minetest Game extra - }, - wolf = { mobs_mc.items.bone }, - dog = { mobs_mc.items.rabbit_raw, mobs_mc.items.rabbit_cooked, mobs_mc.items.mutton_raw, mobs_mc.items.mutton_cooked, mobs_mc.items.beef_raw, mobs_mc.items.beef_cooked, mobs_mc.items.chicken_raw, mobs_mc.items.chicken_cooked, mobs_mc.items.rotten_flesh, - -- Mobs Redo items - "mobs:meat", "mobs:meat_raw" }, -} - --- Contents for replace_what -mobs_mc.replace = { - -- Rabbits reduce carrot growth stage by 1 - rabbit = { - -- Farming Redo carrots - {"farming:carrot_8", "farming:carrot_7", 0}, - {"farming:carrot_7", "farming:carrot_6", 0}, - {"farming:carrot_6", "farming:carrot_5", 0}, - {"farming:carrot_5", "farming:carrot_4", 0}, - {"farming:carrot_4", "farming:carrot_3", 0}, - {"farming:carrot_3", "farming:carrot_2", 0}, - {"farming:carrot_2", "farming:carrot_1", 0}, - {"farming:carrot_1", "air", 0}, - -- Farming Plus carrots - {"farming_plus:carrot", "farming_plus:carrot_7", 0}, - {"farming_plus:carrot_6", "farming_plus:carrot_5", 0}, - {"farming_plus:carrot_5", "farming_plus:carrot_4", 0}, - {"farming_plus:carrot_4", "farming_plus:carrot_3", 0}, - {"farming_plus:carrot_3", "farming_plus:carrot_2", 0}, - {"farming_plus:carrot_2", "farming_plus:carrot_1", 0}, - {"farming_plus:carrot_1", "air", 0}, - }, - -- Sheep eat grass - sheep = { - -- Grass Block - { "default:dirt_with_grass", "default:dirt", -1 }, - -- “Tall Grass” - { "default:grass_5", "air", 0 }, - { "default:grass_4", "air", 0 }, - { "default:grass_3", "air", 0 }, - { "default:grass_2", "air", 0 }, - { "default:grass_1", "air", 0 }, - }, - -- Silverfish populate stone, etc. with monster eggs - silverfish = { - {"default:stone", "mobs_mc:monster_egg_stone", -1}, - {"default:cobble", "mobs_mc:monster_egg_cobble", -1}, - {"default:mossycobble", "mobs_mc:monster_egg_mossycobble", -1}, - {"default:stonebrick", "mobs_mc:monster_egg_stonebrick", -1}, - {"default:stone_block", "mobs_mc:monster_egg_stone_block", -1}, - }, -} - --- List of nodes which endermen can take -mobs_mc.enderman_takable = { - -- Generic handling, useful for entensions - "group:enderman_takable", - - -- Generic nodes - "group:sand", - "group:flower", - - -- Minetest Game - "default:dirt", - "default:dirt_with_grass", - "default:dirt_with_dry_grass", - "default:dirt_with_snow", - "default:dirt_with_rainforest_litter", - "default:dirt_with_grass_footsteps", --- FIXME: For some reason, Minetest has a Lua error when an enderman tries to place a Minetest Game cactus. --- Maybe this is because default:cactus has rotate_and_place? --- "default:cactus", -- TODO: Re-enable cactus when it works again - "default:gravel", - "default:clay", - "flowers:mushroom_red", - "flowers:mushroom_brown", - "tnt:tnt", - - -- Nether mod - "nether:rack", -} - ---[[ Table of nodes to replace when an enderman takes it. -If the enderman takes an indexed node, it the enderman will get the item in the value. -Table indexes: Original node, taken by enderman. -Table values: The item which the enderman *actually* gets -Example: - mobs_mc.enderman_node_replace = { - ["default:dirt_with_dry_grass"] = "default_dirt_with_grass", - } --- This means, if the enderman takes a dirt with dry grass, he will get a dirt with grass --- on his hand instead. -]] -mobs_mc.enderman_replace_on_take = {} -- no replacements by default - --- A table which can be used to override block textures of blocks carried by endermen. --- Only works for cube-shaped nodes and nodeboxes. --- Key: itemstrings of the blocks to replace --- Value: A table with the texture overrides (6 textures) -mobs_mc.enderman_block_texture_overrides = { -} - --- List of nodes on which mobs can spawn -mobs_mc.spawn = { - solid = { "group:cracky", "group:crumbly", "group:shovely", "group:pickaxey" }, -- spawn on "solid" nodes (this is mostly just guessing) - - grassland = { mobs_mc.items.grass_block, "ethereal:prairie_dirt" }, - savanna = { "default:dirt_with_dry_grass" }, - grassland_savanna = { mobs_mc.items.grass_block, "default:dirt_with_dry_grass" }, - desert = { "default:desert_sand", "group:sand" }, - jungle = { "default:dirt_with_rainforest_litter", "default:jungleleaves", "default:junglewood", "mcl_core:jungleleaves", "mcl_core:junglewood" }, - snow = { "default:snow", "default:snowblock", "default:dirt_with_snow" }, - end_city = { "default:sandstonebrick", "mcl_end:purpur_block", "mcl_end:end_stone" }, - wolf = { mobs_mc.items.grass_block, "default:dirt_with_rainforest_litter", "default:dirt", "default:dirt_with_snow", "default:snow", "default:snowblock" }, - village = { "mg_villages:road" }, - - -- These probably don't need overrides - mushroom_island = { mobs_mc.items.mycelium, "mcl_core:mycelium" }, - nether_fortress = { mobs_mc.items.nether_brick_block, "mcl_nether:nether_brick", }, - nether = { mobs_mc.items.netherrack, "mcl_nether:netherrack", }, - nether_portal = { mobs_mc.items.nether_portal, "mcl_portals:portal" }, - water = { mobs_mc.items.water_source, "mcl_core:water_source", "default:water_source" }, -} - --- This table contains important spawn height references for the mob spawn height. --- Please base your mob spawn height on these numbers to keep things clean. -mobs_mc.spawn_height = { - water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld - - -- Overworld boundaries (inclusive) - overworld_min = -2999, - overworld_max = 31000, - - -- Nether boundaries (inclusive) - nether_min = -3369, - nether_max = -3000, - - -- End boundaries (inclusive) - end_min = -6200, - end_max = -6000, -} - -mobs_mc.misc = { - shears_wear = 276, -- Wear to add per shears usage (238 uses) - totem_fail_nodes = {} -- List of nodes in which the totem of undying fails -} - --- Item name overrides from mobs_mc_gameconfig (if present) -if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override then - local tables = {"items", "follow", "replace", "spawn", "spawn_height", "misc"} - for t=1, #tables do - local tbl = tables[t] - if mobs_mc.override[tbl] then - for k, v in pairs(mobs_mc.override[tbl]) do - mobs_mc[tbl][k] = v - end - end - end - - if mobs_mc.override.enderman_takable then - mobs_mc.enderman_takable = mobs_mc.override.enderman_takable - end - if mobs_mc.override.enderman_replace_on_take then - mobs_mc.enderman_replace_on_take = mobs_mc.override.enderman_replace_on_take - end - if mobs_mc.enderman_block_texture_overrides then - mobs_mc.enderman_block_texture_overrides = mobs_mc.override.enderman_block_texture_overrides - end -end - diff --git a/mods/ENTITIES/mobs_mc/1_items_default.lua b/mods/ENTITIES/mobs_mc/1_items_default.lua deleted file mode 100644 index ddcc290c7..000000000 --- a/mods/ENTITIES/mobs_mc/1_items_default.lua +++ /dev/null @@ -1,647 +0,0 @@ ---MCmobs v0.5 ---maikerumine ---made for MC like Survival game ---License for code WTFPL and otherwise stated in readmes - ---THIS IS THE MASTER ITEM LIST TO USE WITH DEFAULT - --- NOTE: Most strings intentionally not marked for translation, other mods already have these items. --- TODO: Remove this file eventually, most items are already outsourced in other mods. - -local S = minetest.get_translator("mobs_mc") - -local c = mobs_mc.is_item_variable_overridden - --- Blaze -if c("blaze_rod") then - minetest.register_craftitem("mobs_mc:blaze_rod", { - description = "Blaze Rod", - _doc_items_longdesc = "This is a crafting component dropped from dead blazes.", - wield_image = "mcl_mobitems_blaze_rod.png", - inventory_image = "mcl_mobitems_blaze_rod.png", - }) - - -- Make blaze rod furnace-burnable. 1.5 times the burn time of a coal lump - local coalcraft, burntime - if minetest.get_modpath("default") then - coalcraft = minetest.get_craft_result({method="fuel", width=1, items={"default:coal_lump"}}) - end - if coalcraft then - burntime = math.floor(coalcraft.time * 1.5) - end - if burntime == nil or burntime == 0 then - burntime = 60 - end - - minetest.register_craft({ - type = "fuel", - burntime = burntime, - recipe = "mobs_mc:blaze_rod", - }) -end - -if c("blaze_powder") then - minetest.register_craftitem("mobs_mc:blaze_powder", { - description = "Blaze Powder", - _doc_items_longdesc = "This item is mainly used for brewing potions and crafting.", - wield_image = "mcl_mobitems_blaze_powder.png", - inventory_image = "mcl_mobitems_blaze_powder.png", - }) -end - -if c("blaze_rod") and c("blaze_powder") then - minetest.register_craft({ - output = "mobs_mc:blaze_powder 2", - recipe = {{ "mobs_mc:blaze_rod" }}, - }) -end - --- Chicken -if c("chicken_raw") then - minetest.register_craftitem("mobs_mc:chicken_raw", { - description = "Raw Chicken", - _doc_items_longdesc = "Raw chicken is a food item and can be eaten safely. Cooking it will increase its nutritional value.", - inventory_image = "mcl_mobitems_chicken_raw.png", - groups = { food = 2, eatable = 2 }, - on_use = minetest.item_eat(2), - }) -end - -if c("chicken_cooked") then - minetest.register_craftitem("mobs_mc:chicken_cooked", { - description = "Cooked Chicken", - _doc_items_longdesc = "A cooked chicken is a healthy food item which can be eaten.", - inventory_image = "mcl_mobitems_chicken_cooked.png", - groups = { food = 2, eatable = 6 }, - on_use = minetest.item_eat(6), - }) -end - -if c("chicken_raw") and c("chicken_cooked") then - minetest.register_craft({ - type = "cooking", - output = "mobs_mc:chicken_cooked", - recipe = "mobs_mc:chicken_raw", - cooktime = 5, - }) -end - -if c("feather") then - minetest.register_craftitem("mobs_mc:feather", { - description = "Feather", - _doc_items_longdesc = "Feathers are used in crafting and are dropped from chickens.", - inventory_image = "mcl_mobitems_feather.png", - }) -end - --- Cow and mooshroom -if c("beef_raw") then - minetest.register_craftitem("mobs_mc:beef_raw", { - description = "Raw Beef", - _doc_items_longdesc = "Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.", - inventory_image = "mcl_mobitems_beef_raw.png", - groups = { food = 2, eatable = 3 }, - on_use = minetest.item_eat(3), - }) -end - -if c("beef_cooked") then - minetest.register_craftitem("mobs_mc:beef_cooked", { - description = "Steak", - _doc_items_longdesc = "Steak is cooked beef from cows and can be eaten.", - inventory_image = "mcl_mobitems_beef_cooked.png", - groups = { food = 2, eatable = 8 }, - on_use = minetest.item_eat(8), - }) -end - -if c("beef_raw") and c("beef_cooked") then - minetest.register_craft({ - type = "cooking", - output = "mobs_mc:beef_cooked", - recipe = "mobs_mc:beef_raw", - cooktime = 5, - }) -end - - -if c("milk") then - -- milk - minetest.register_craftitem("mobs_mc:milk_bucket", { - description = "Milk", - _doc_items_longdesc = "Milk is a food item obtained by using a bucket on a cow.", - inventory_image = "mobs_bucket_milk.png", - groups = { food = 3, eatable = 1 }, - on_use = minetest.item_eat(1, "bucket:bucket_empty"), - stack_max = 1, - }) -end - -if c("bowl") then - minetest.register_craftitem("mobs_mc:bowl", { - description = "Bowl", - _doc_items_longdesc = "Bowls are mainly used to hold tasty soups.", - inventory_image = "mcl_core_bowl.png", - }) - - minetest.register_craft({ - output = "mobs_mc:bowl", - recipe = { - { "group:wood", "", "group:wood" }, - { "", "group:wood", "", }, - } - }) - - minetest.register_craft({ - type = "fuel", - recipe = "mobs_mc:bowl", - burntime = 5, - }) -end - -if c("mushroom_stew") then - minetest.register_craftitem("mobs_mc:mushroom_stew", { - description = "Mushroom Stew", - _doc_items_longdesc = "Mushroom stew is a healthy soup.", - inventory_image = "farming_mushroom_stew.png", - groups = { food = 3, eatable = 6 }, - on_use = minetest.item_eat(6, "mobs_mc:bowl"), - stack_max = 1, - }) -end - --- Ender dragon -if c("dragon_egg") then - - local dragon_egg_sounds - if minetest.get_modpath("default") then - dragon_egg_sounds = default.node_sound_stone_defaults() - end - - --ender dragon - minetest.register_node("mobs_mc:dragon_egg", { - description = "Dragon Egg", - tiles = { - "mcl_end_dragon_egg.png", - "mcl_end_dragon_egg.png", - "mcl_end_dragon_egg.png", - "mcl_end_dragon_egg.png", - "mcl_end_dragon_egg.png", - "mcl_end_dragon_egg.png", - }, - drawtype = "nodebox", - is_ground_content = false, - paramtype = "light", - light_source = 1, - node_box = { - type = "fixed", - fixed = { - {-0.375, -0.5, -0.375, 0.375, -0.4375, 0.375}, - {-0.5, -0.4375, -0.5, 0.5, -0.1875, 0.5}, - {-0.4375, -0.1875, -0.4375, 0.4375, 0, 0.4375}, - {-0.375, 0, -0.375, 0.375, 0.125, 0.375}, - {-0.3125, 0.125, -0.3125, 0.3125, 0.25, 0.3125}, - {-0.25, 0.25, -0.25, 0.25, 0.3125, 0.25}, - {-0.1875, 0.3125, -0.1875, 0.1875, 0.375, 0.1875}, - {-0.125, 0.375, -0.125, 0.125, 0.4375, 0.125}, - {-0.0625, 0.4375, -0.0625, 0.0625, 0.5, 0.0625}, - } - }, - selection_box = { - type = "regular", - }, - groups = {snappy = 1, falling_node = 1, deco_block = 1, not_in_creative_inventory = 1, dig_by_piston = 1 }, - sounds = dragon_egg_sounds, - -- TODO: Make dragon egg teleport on punching - }) -end - -local longdesc_craftitem -if minetest.get_modpath("doc_items") then - longdesc_craftitem = doc.sub.items.temp.craftitem -end - --- Enderman -if c("ender_eye") then - minetest.register_craftitem("mobs_mc:ender_eye", { - description = "Eye of Ender", - _doc_items_longdesc = longdesc_craftitem, - inventory_image = "mcl_end_ender_eye.png", - groups = { craftitem = 1 }, - }) -end - -if c("ender_eye") and c("blaze_powder") and c("blaze_rod") then - minetest.register_craft({ - type = "shapeless", - output = 'mobs_mc:ender_eye', - recipe = { 'mobs_mc:blaze_powder', 'mobs_mc:blaze_rod'}, - }) -end - --- Ghast -if c("ghast_tear") then - minetest.register_craftitem("mobs_mc:ghast_tear", { - description = "Ghast Tear", - _doc_items_longdesc = "A ghast tear is an item used in potion brewing. It is dropped from dead ghasts.", - wield_image = "mcl_mobitems_ghast_tear.png", - inventory_image = "mcl_mobitems_ghast_tear.png", - groups = { brewitem = 1 }, - }) -end - --- Saddle -if c("saddle") then - -- Overwrite the saddle from Mobs Redo - minetest.register_craftitem(":mobs:saddle", { - description = "Saddle", - _doc_items_longdesc = "Saddles can be put on horses, donkeys, mules and pigs in order to mount them.", - _doc_items_usagehelp = "Rightclick an animal while holding a saddle to put on the saddle. You can now mount the animal by rightclicking it again.", - inventory_image = "mcl_mobitems_saddle.png", - stack_max = 1, - }) -end - --- Horse Armor -local horse_armor_use = S("Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.") --- TODO: Balance the horse armor strength, compare with MC armor strength -if c("iron_horse_armor") then - minetest.register_craftitem("mobs_mc:iron_horse_armor", { - description = S("Iron Horse Armor"), - _doc_items_longdesc = S("Iron horse armor can be worn by horses to increase their protection from harm a bit."), - _doc_items_usagehelp = horse_armor_use, - inventory_image = "mobs_mc_iron_horse_armor.png", - _horse_overlay_image = "mobs_mc_horse_armor_iron.png", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - }, - stack_max = 1, - groups = { horse_armor = 85 }, - }) -end -if c("gold_horse_armor") then - minetest.register_craftitem("mobs_mc:gold_horse_armor", { - description = S("Golden Horse Armor"), - _doc_items_longdesc = S("Golden horse armor can be worn by horses to increase their protection from harm."), - _doc_items_usagehelp = horse_armor_use, - inventory_image = "mobs_mc_gold_horse_armor.png", - _horse_overlay_image = "mobs_mc_horse_armor_gold.png", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - }, - stack_max = 1, - groups = { horse_armor = 60 }, - }) -end -if c("diamond_horse_armor") then - minetest.register_craftitem("mobs_mc:diamond_horse_armor", { - description = S("Diamond Horse Armor"), - _doc_items_longdesc = S("Diamond horse armor can be worn by horses to greatly increase their protection from harm."), - _doc_items_usagehelp = horse_armor_use, - inventory_image = "mobs_mc_diamond_horse_armor.png", - _horse_overlay_image = "mobs_mc_horse_armor_diamond.png", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - }, - stack_max = 1, - groups = { horse_armor = 45 }, - }) -end - --- Pig -if c("porkchop_raw") then - minetest.register_craftitem("mobs_mc:porkchop_raw", { - description = "Raw Porkchop", - _doc_items_longdesc = "A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.", - inventory_image = "mcl_mobitems_porkchop_raw.png", - groups = { food = 2, eatable = 3 }, - on_use = minetest.item_eat(3), - }) -end - -if c("porkchop_cooked") then - minetest.register_craftitem("mobs_mc:porkchop_cooked", { - description = "Cooked Porkchop", - _doc_items_longdesc = "Cooked porkchop is the cooked flesh of a pig and is used as food.", - inventory_image = "mcl_mobitems_porkchop_cooked.png", - groups = { food = 2, eatable = 8 }, - on_use = minetest.item_eat(8), - }) -end - -if c("porkchop_raw") and c("porkchop_cooked") then - minetest.register_craft({ - type = "cooking", - output = "mobs_mc:porkchop_cooked", - recipe = "mobs_mc:porkchop_raw", - cooktime = 5, - }) -end - -if c("carrot_on_a_stick") then - minetest.register_tool("mobs_mc:carrot_on_a_stick", { - description = "Carrot on a Stick", - _doc_items_longdesc = "A carrot on a stick can be used on saddled pigs to ride them. Pigs will also follow anyone who holds a carrot on a stick near them.", - _doc_items_usagehelp = "Rightclick a saddled pig with the carrot on a stick to mount it. You can now ride it like a horse.", - wield_image = "mcl_mobitems_carrot_on_a_stick.png", - inventory_image = "mcl_mobitems_carrot_on_a_stick.png", - sounds = { breaks = "default_tool_breaks" }, - }) -end - --- Poor-man's recipes for carrot on a stick -if c("carrot_on_a_stick") and c("stick") and c("string") and minetest.get_modpath("farming") then - minetest.register_craft({ - output = "mobs_mc:carrot_on_a_stick", - recipe = { - {"", "", "farming:string" }, - {"", "group:stick", "farming:string" }, - {"group:stick", "", "farming:bread" }, - } - }) - --- FIXME: Identify correct farming mod (check if it includes the carrot item) - minetest.register_craft({ - output = "mobs_mc:carrot_on_a_stick", - recipe = { - {"", "", "farming:string" }, - {"", "group:stick", "farming:string" }, - {"group:stick", "", "farming:carrot" }, - } - }) -end - -if c("carrot_on_a_stick") and c("stick") and c("string") and minetest.get_modpath("fishing") and minetest.get_modpath("farming") then - minetest.register_craft({ - type = "shapeless", - output = "mobs_mc:carrot_on_a_stick", - recipe = {"fishing:pole_wood", "farming:carrot"}, - }) -end - --- Rabbit -if c("rabbit_raw") then - minetest.register_craftitem("mobs_mc:rabbit_raw", { - description = "Raw Rabbit", - _doc_items_longdesc = "Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.", - inventory_image = "mcl_mobitems_rabbit_raw.png", - groups = { food = 2, eatable = 3 }, - on_use = minetest.item_eat(3), - }) -end - -if c("rabbit_cooked") then - minetest.register_craftitem("mobs_mc:rabbit_cooked", { - description = "Cooked Rabbit", - _doc_items_longdesc = "This is a food item which can be eaten.", - inventory_image = "mcl_mobitems_rabbit_cooked.png", - groups = { food = 2, eatable = 5 }, - on_use = minetest.item_eat(5), - }) -end - -if c("rabbit_raw") and c("rabbit_cooked") then - minetest.register_craft({ - type = "cooking", - output = "mobs_mc:rabbit_cooked", - recipe = "mobs_mc:rabbit_raw", - cooktime = 5, - }) -end - -if c("rabbit_hide") then - minetest.register_craftitem("mobs_mc:rabbit_hide", { - description = "Rabbit Hide", - _doc_items_longdesc = "Rabbit hide is used to create leather.", - inventory_image = "mcl_mobitems_rabbit_hide.png" - }) -end - -if c("leather") and c("rabbit_hide") then - minetest.register_craft({ - output = "mobs:leather", - recipe = { - { "mobs_mc:rabbit_hide", "mobs_mc:rabbit_hide" }, - { "mobs_mc:rabbit_hide", "mobs_mc:rabbit_hide" }, - } - }) -end - -if c("rabbit_foot") then - minetest.register_craftitem("mobs_mc:rabbit_foot", { - description = "Rabbit's Foot", - _doc_items_longdesc = "This item is used in brewing.", - inventory_image = "mcl_mobitems_rabbit_foot.png" - }) -end - --- Sheep -if c("mutton_raw") then - minetest.register_craftitem("mobs_mc:mutton_raw", { - description = "Raw Mutton", - _doc_items_longdesc = "Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.", - inventory_image = "mcl_mobitems_mutton_raw.png", - groups = { food = 2, eatable = 4 }, - on_use = minetest.item_eat(4), - }) -end - -if c("mutton_cooked") then - minetest.register_craftitem("mobs_mc:mutton_cooked", { - description = "Cooked Mutton", - _doc_items_longdesc = "Cooked mutton is the cooked flesh from a sheep and is used as food.", - inventory_image = "mcl_mobitems_mutton_cooked.png", - groups = { food = 2, eatable = 8 }, - on_use = minetest.item_eat(8), - }) -end - -if c("mutton_raw") and c("mutton_cooked") then - minetest.register_craft({ - type = "cooking", - output = "mobs_mc:mutton_cooked", - recipe = "mobs_mc:mutton_raw", - cooktime = 5, - }) -end - --- Shulker -if c("shulker_shell") then - minetest.register_craftitem("mobs_mc:shulker_shell", { - description = "Shulker Shell", - _doc_items_longdesc = "Shulker shells are used in crafting. They are dropped from dead shulkers.", - inventory_image = "mcl_mobitems_shulker_shell.png", - groups = { craftitem = 1 }, - }) -end - --- Magma cube -if c("magma_cream") then - minetest.register_craftitem("mobs_mc:magma_cream", { - description = "Magma Cream", - _doc_items_longdesc = "Magma cream is a crafting component.", - wield_image = "mcl_mobitems_magma_cream.png", - inventory_image = "mcl_mobitems_magma_cream.png", - groups = { brewitem = 1 }, - }) -end - --- Slime -if c("slimeball") then - minetest.register_craftitem("mobs_mc:slimeball", { - description = "Slimeball", - _doc_items_longdesc = "Slimeballs are used in crafting. They are dropped from slimes.", - inventory_image = "mcl_mobitems_slimeball.png" - }) - if minetest.get_modpath("mesecons_materials") then - minetest.register_craft({ - output = "mesecons_materials:glue", - recipe = {{ "mobs_mc:slimeball" }}, - }) - end -end - --- Spider -if c("spider_eye") then - minetest.register_craftitem("mobs_mc:spider_eye", { - description = "Spider Eye", - _doc_items_longdesc = "Spider eyes are used mainly in crafting and brewing. Spider eyes can be eaten, but they poison you and reduce your health by 2 hit points.", - inventory_image = "mcl_mobitems_spider_eye.png", - wield_image = "mcl_mobitems_spider_eye.png", - -- Simplified poisonous food - groups = { food = 2, eatable = -2 }, - on_use = minetest.item_eat(-2), - }) -end - --- Evoker -if c("totem") then - local hud_totem = {} - - -- Totem of Undying - minetest.register_craftitem("mobs_mc:totem", { - description = S("Totem of Undying"), - _tt_help = minetest.colorize("#00FF00", S("Protects you from death while wielding it")), - _doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."), - _doc_items_usagehelp = S("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."), - inventory_image = "mcl_totems_totem.png", - wield_image = "mcl_totems_totem.png", - stack_max = 1, - }) - - minetest.register_on_leaveplayer(function(player) - hud_totem[player:get_player_name()] = nil - end) - - -- Save the player from death when holding totem of undying in hand - minetest.register_on_player_hpchange(function(player, hp_change) - local hp = player:get_hp() - -- Fatal damage? - if hp + hp_change <= 0 then - local wield = player:get_wielded_item() - if wield:get_name() == "mobs_mc:totem" then - local ppos = player:get_pos() - local pnname = minetest.get_node(ppos).name - -- Some exceptions when _not_ to save the player - for n=1, #mobs_mc.misc.totem_fail_nodes do - if pnname == mobs_mc.misc.totem_fail_nodes[n] then - return hp_change - end - end - -- Reset breath as well - if player:get_breath() < 11 then - player:set_breath(10) - end - if not minetest.is_creative_enabled(player:get_player_name()) then - wield:take_item() - player:set_wielded_item(wield) - end - -- Effects - minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) - - -- Big totem overlay - if not hud_totem[player:get_player_name()] then - hud_totem[player:get_player_name()] = player:hud_add({ - hud_elem_type = "image", - text = "mcl_totems_totem.png", - position = { x=0.5, y=1 }, - scale = { x=17, y=17 }, - offset = { x=0, y=-178 }, - z_index = 100, - }) - minetest.after(3, function(name) - local player = minetest.get_player_by_name(name) - if player and player:is_player() then - local name = player:get_player_name() - if hud_totem[name] then - player:hud_remove(hud_totem[name]) - hud_totem[name] = nil - end - end - end, player:get_player_name()) - end - - -- Set HP to exactly 1 - return -hp + 1 - end - end - return hp_change - end, true) -end - --- Rotten flesh -if c("rotten_flesh") then - minetest.register_craftitem("mobs_mc:rotten_flesh", { - description = "Rotten Flesh", - _doc_items_longdesc = "Yuck! This piece of flesh clearly has seen better days. Eating it will only poison you and reduces your health by 4 hit points. But tamed wolves can eat it just fine.", - inventory_image = "mcl_mobitems_rotten_flesh.png", - -- Simplified poisonous food - groups = { food = 2, eatable = -4 }, - on_use = minetest.item_eat(-4), - }) -end - --- Misc. -if c("nether_star") then - minetest.register_craftitem("mobs_mc:nether_star", { - description = "Nether Star", - _doc_items_longdesc = "A nether star is a crafting component. It is dropped from the Wither.", - inventory_image = "mcl_mobitems_nether_star.png" - }) -end - -if c("snowball") and minetest.get_modpath("default") then - minetest.register_craft({ - output = "mobs_mc:snowball 2", - recipe = { - {"default:snow"}, - }, - }) - minetest.register_craft({ - output = "default:snow 2", - recipe = { - {"mobs_mc:snowball", "mobs_mc:snowball"}, - {"mobs_mc:snowball", "mobs_mc:snowball"}, - }, - }) - -- Change the appearance of default snow to avoid confusion with snowball - minetest.override_item("default:snow", { - inventory_image = "", - wield_image = "", - }) -end - -if c("bone") then - minetest.register_craftitem("mobs_mc:bone", { - description = "Bone", - _doc_items_longdesc = "Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient.", - _doc_items_usagehelp = "Hold the bone in your hand near wolves to attract them. Rightclick the wolf to give it a bone and tame it.", - inventory_image = "mcl_mobitems_bone.png" - }) - if minetest.get_modpath("bones") then - minetest.register_craft({ - output = "mobs_mc:bone 3", - recipe = {{ "bones:bones" }}, - }) - end -end diff --git a/mods/ENTITIES/mobs_mc/2_throwing.lua b/mods/ENTITIES/mobs_mc/2_throwing.lua deleted file mode 100644 index e868cb060..000000000 --- a/mods/ENTITIES/mobs_mc/2_throwing.lua +++ /dev/null @@ -1,401 +0,0 @@ ---MCmobs v0.5 ---maikerumine ---made for MC like Survival game ---License for code WTFPL and otherwise stated in readmes - --- NOTE: Strings intentionally not marked for translation, other mods already have these items. --- TODO: Remove this file eventually, all items here are already outsourced in other mods. - -local S = minetest.get_translator("mobs_mc") - ---maikerumines throwing code ---arrow (weapon) - -local c = mobs_mc.is_item_variable_overridden - -minetest.register_node("mobs_mc:arrow_box", { - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - -- Shaft - {-6.5/17, -1.5/17, -1.5/17, -4.5/17, 1.5/17, 1.5/17}, - {-4.5/17, -0.5/17, -0.5/17, 5.5/17, 0.5/17, 0.5/17}, - {5.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, - -- Tip - {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, - {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, - -- Fletching - {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, - {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, - {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, - {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, - - {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, - {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, - {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, - {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, - } - }, - tiles = {"mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow_back.png", "mcl_bows_arrow_front.png", "mcl_bows_arrow.png", "mcl_bows_arrow.png^[transformFX"}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = {not_in_creative_inventory=1, dig_immediate=3}, - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mobs_mc] Trying to construct mobs_mc:arrow_box at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, - drop = "", -}) - -local THROWING_ARROW_ENTITY={ - physical = false, - timer=0, - visual = "wielditem", - visual_size = {x=0.1, y=0.1}, - textures = {"mobs_mc:arrow_box"}, - velocity = 10, - lastpos={}, - collisionbox = {0,0,0,0,0,0}, -} - ---ARROW CODE -THROWING_ARROW_ENTITY.on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - - minetest.add_particle({ - pos = pos, - velocity = {x=0, y=0, z=0}, - acceleration = {x=0, y=0, z=0}, - expirationtime = .3, - size = 1, - collisiondetection = false, - vertical = false, - texture = "mobs_mc_arrow_particle.png", - }) - - if self.timer>0.2 then - local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5) - for k, obj in pairs(objs) do - if obj:get_luaentity() ~= nil then - if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then - local damage = 3 - minetest.sound_play("damage", {pos = pos}, true) - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=damage}, - }, nil) - self.object:remove() - end - else - local damage = 3 - minetest.sound_play("damage", {pos = pos}, true) - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=damage}, - }, nil) - self.object:remove() - end - end - end - - if self.lastpos.x~=nil then - if node.name ~= "air" then - minetest.sound_play("bowhit1", {pos = pos}, true) - minetest.add_item(self.lastpos, 'mobs_mc:arrow') - self.object:remove() - end - end - self.lastpos={x=pos.x, y=pos.y, z=pos.z} -end - -minetest.register_entity("mobs_mc:arrow_entity", THROWING_ARROW_ENTITY) - -local arrows = { - {"mobs_mc:arrow", "mobs_mc:arrow_entity" }, -} - -local throwing_shoot_arrow = function(itemstack, player) - for _,arrow in ipairs(arrows) do - if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then - if not minetest.is_creative_enabled(player:get_player_name()) then - player:get_inventory():remove_item("main", arrow[1]) - end - local playerpos = player:get_pos() - local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow[2]) --mc - local dir = player:get_look_dir() - obj:set_velocity({x=dir.x*22, y=dir.y*22, z=dir.z*22}) - obj:set_acceleration({x=dir.x*-3, y=-10, z=dir.z*-3}) - obj:set_yaw(player:get_look_yaw()+math.pi) - minetest.sound_play("throwing_sound", {pos=playerpos}, true) - if obj:get_luaentity().player == "" then - obj:get_luaentity().player = player - end - obj:get_luaentity().node = player:get_inventory():get_stack("main", 1):get_name() - return true - end - end - return false -end - -if c("arrow") then - minetest.register_craftitem("mobs_mc:arrow", { - description = "Arrow", - _doc_items_longdesc = "Arrows are ammunition for bows.", - _doc_items_usagehelp = "To use arrows as ammunition for a bow, put them in the inventory slot following the bow. Slots are counted left to right, top to bottom.", - inventory_image = "mcl_bows_arrow_inv.png", - }) -end - -if c("arrow") and c("flint") and c("feather") and c("stick") then - minetest.register_craft({ - output = 'mobs_mc:arrow 4', - recipe = { - {mobs_mc.items.flint}, - {mobs_mc.items.stick}, - {mobs_mc.items.feather}, - } - }) -end - -if c("bow") then - minetest.register_tool("mobs_mc:bow_wood", { - description = "Bow", - _doc_items_longdesc = "Bows are ranged weapons to shoot arrows at your foes.", - _doc_items_usagehelp = "To use the bow, you first need to have at least one arrow in slot following the bow. Leftclick to shoot. Each hit deals 3 damage.", - inventory_image = "mcl_bows_bow.png", - on_use = function(itemstack, user, pointed_thing) - if throwing_shoot_arrow(itemstack, user, pointed_thing) then - if not minetest.is_creative_enabled(user:get_player_name()) then - itemstack:add_wear(65535/50) - end - end - return itemstack - end, - }) - - minetest.register_craft({ - output = 'mobs_mc:bow_wood', - recipe = { - {mobs_mc.items.string, mobs_mc.items.stick, ''}, - {mobs_mc.items.string, '', mobs_mc.items.stick}, - {mobs_mc.items.string, mobs_mc.items.stick, ''}, - } - }) -end - -local how_to_throw = "Hold it in your and and leftclick to throw." - --- egg throwing item --- egg entity -if c("egg") then - local egg_GRAVITY = 9 - local egg_VELOCITY = 19 - - mobs:register_arrow("mobs_mc:egg_entity", { - visual = "sprite", - visual_size = {x=.5, y=.5}, - textures = {"mobs_chicken_egg.png"}, - velocity = egg_VELOCITY, - - hit_player = function(self, player) - player:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {}, - }, nil) - end, - - hit_mob = function(self, mob) - mob:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {}, - }, nil) - end, - - hit_node = function(self, pos, node) - - if math.random(1, 10) > 1 then - return - end - - pos.y = pos.y + 1 - - local nod = minetest.get_node_or_nil(pos) - - if not nod - or not minetest.registered_nodes[nod.name] - or minetest.registered_nodes[nod.name].walkable == true then - return - end - - local mob = minetest.add_entity(pos, "mobs_mc:chicken") - local ent2 = mob:get_luaentity() - - mob:set_properties({ - visual_size = { - x = ent2.base_size.x / 2, - y = ent2.base_size.y / 2 - }, - collisionbox = { - ent2.base_colbox[1] / 2, - ent2.base_colbox[2] / 2, - ent2.base_colbox[3] / 2, - ent2.base_colbox[4] / 2, - ent2.base_colbox[5] / 2, - ent2.base_colbox[6] / 2 - }, - }) - - ent2.child = true - ent2.tamed = true - ent2.owner = self.playername - end - }) - - -- shoot egg - local mobs_shoot_egg = function (item, player, pointed_thing) - - local playerpos = player:get_pos() - - minetest.sound_play("default_place_node_hard", { - pos = playerpos, - gain = 1.0, - max_hear_distance = 5, - }, true) - - local obj = minetest.add_entity({ - x = playerpos.x, - y = playerpos.y +1.5, - z = playerpos.z - }, "mobs_mc:egg_entity") - - local ent = obj:get_luaentity() - local dir = player:get_look_dir() - - ent.velocity = egg_VELOCITY -- needed for api internal timing - ent.switch = 1 -- needed so that egg doesn't despawn straight away - - obj:set_velocity({ - x = dir.x * egg_VELOCITY, - y = dir.y * egg_VELOCITY, - z = dir.z * egg_VELOCITY - }) - - obj:set_acceleration({ - x = dir.x * -3, - y = -egg_GRAVITY, - z = dir.z * -3 - }) - - -- pass player name to egg for chick ownership - local ent2 = obj:get_luaentity() - ent2.playername = player:get_player_name() - - if not minetest.is_creative_enabled(player:get_player_name()) then - item:take_item() - end - - return item - end - - minetest.register_craftitem("mobs_mc:egg", { - description = "Egg", - _doc_items_longdesc = "Eggs can be thrown and break on impact. There is a small chance that 1 or even 4 chicks will pop out", - _doc_items_usagehelp = how_to_throw, - inventory_image = "mobs_chicken_egg.png", - on_use = mobs_shoot_egg, - }) -end - --- Snowball - -local snowball_GRAVITY = 9 -local snowball_VELOCITY = 19 - -mobs:register_arrow("mobs_mc:snowball_entity", { - visual = "sprite", - visual_size = {x=.5, y=.5}, - textures = {"mcl_throwing_snowball.png"}, - velocity = snowball_VELOCITY, - - hit_player = function(self, player) - -- FIXME: No knockback - player:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = {}, - }, nil) - end, - - hit_mob = function(self, mob) - -- Hurt blazes, but not damage to anything else - local dmg = {} - if mob:get_luaentity().name == "mobs_mc:blaze" then - dmg = {fleshy = 3} - end - -- FIXME: No knockback - mob:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = dmg, - }, nil) - end, - -}) - -if c("snowball") then - -- shoot snowball - local mobs_shoot_snowball = function (item, player, pointed_thing) - - local playerpos = player:get_pos() - - local obj = minetest.add_entity({ - x = playerpos.x, - y = playerpos.y +1.5, - z = playerpos.z - }, "mobs_mc:snowball_entity") - - local ent = obj:get_luaentity() - local dir = player:get_look_dir() - - ent.velocity = snowball_VELOCITY -- needed for api internal timing - ent.switch = 1 -- needed so that egg doesn't despawn straight away - - obj:set_velocity({ - x = dir.x * snowball_VELOCITY, - y = dir.y * snowball_VELOCITY, - z = dir.z * snowball_VELOCITY - }) - - obj:set_acceleration({ - x = dir.x * -3, - y = -snowball_GRAVITY, - z = dir.z * -3 - }) - - -- pass player name to egg for chick ownership - local ent2 = obj:get_luaentity() - ent2.playername = player:get_player_name() - - if not minetest.is_creative_enabled(player:get_player_name()) then - item:take_item() - end - - return item - end - - - -- Snowball - minetest.register_craftitem("mobs_mc:snowball", { - description = "Snowball", - _doc_items_longdesc = "Snowballs can be thrown at your enemies. A snowball deals 3 damage to blazes, but is harmless to anything else.", - _doc_items_usagehelp = how_to_throw, - inventory_image = "mcl_throwing_snowball.png", - on_use = mobs_shoot_snowball, - }) -end - ---end maikerumine code diff --git a/mods/ENTITIES/mobs_mc/3_shared.lua b/mods/ENTITIES/mobs_mc/3_shared.lua deleted file mode 100644 index fce0850b4..000000000 --- a/mods/ENTITIES/mobs_mc/3_shared.lua +++ /dev/null @@ -1,63 +0,0 @@ -local pr = PseudoRandom(os.time()*5) - -local offsets = {} -for x=-2, 2 do - for z=-2, 2 do - table.insert(offsets, {x=x, y=0, z=z}) - end -end - ---[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and -the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1. -Larger mobs might have space problems after teleportation. - -* dist: Minimum required distance from owner to teleport. Default: 12 -* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]] -mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval) - return function(self, dtime) - -- No teleportation if no owner or if sitting - if not self.owner or self.order == "sit" then - return - end - if not teleport_check_interval then - teleport_check_interval = 4 - end - if not dist then - dist = 12 - end - if self._teleport_timer == nil then - self._teleport_timer = teleport_check_interval - return - end - self._teleport_timer = self._teleport_timer - dtime - if self._teleport_timer <= 0 then - self._teleport_timer = teleport_check_interval - local mob_pos = self.object:get_pos() - local owner = minetest.get_player_by_name(self.owner) - if not owner then - -- No owner found, no teleportation - return - end - local owner_pos = owner:get_pos() - local dist_from_owner = vector.distance(owner_pos, mob_pos) - if dist_from_owner > dist then - -- Check for nodes below air in a 5×1×5 area around the owner position - local check_offsets = table.copy(offsets) - -- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node. - while #check_offsets > 0 do - local r = pr:next(1, #check_offsets) - local telepos = vector.add(owner_pos, check_offsets[r]) - local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z} - table.remove(check_offsets, r) - -- Long story short, spawn on a platform - if minetest.registered_nodes[minetest.get_node(telepos).name].walkable == false and - minetest.registered_nodes[minetest.get_node(telepos_below).name].walkable == true then - -- Correct position found! Let's teleport. - self.object:set_pos(telepos) - return - end - end - end - end - end -end diff --git a/mods/ENTITIES/mobs_mc/4_heads.lua b/mods/ENTITIES/mobs_mc/4_heads.lua deleted file mode 100644 index 01b8ee577..000000000 --- a/mods/ENTITIES/mobs_mc/4_heads.lua +++ /dev/null @@ -1,62 +0,0 @@ ---MC Heads for minetest ---maikerumine - --- NOTE: Strings intentionally not marked for translation, other mods already have these items. --- TODO: Remove this file eventually, all items here are already outsourced in other mods. - -local S = minetest.get_translator("mobs_mc") - --- Heads system - -local sounds -if minetest.get_modpath("default") then - sounds = default.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }) -end - -local function addhead(mobname, desc, longdesc) - if not mobs_mc.is_item_variable_overridden("head_"..mobname) then - return - end - minetest.register_node("mobs_mc:head_"..mobname, { - description = desc, - _doc_items_longdesc = longdesc, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - }, - groups = { oddly_breakable_by_hand=3, head=1, }, - -- The head textures are based off the textures of an actual mob. - -- FIXME: This code assumes 16×16 textures for the mob textures! - tiles = { - -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. - -- This is required for skeleton skull and wither skeleton skull. - "[combine:16x16:-4,4=mobs_mc_"..mobname..".png", -- top - "([combine:16x16:-4,4=mobs_mc_"..mobname..".png)^([combine:16x16:-12,4=mobs_mc_"..mobname..".png)", -- bottom - "[combine:16x16:-12,0=mobs_mc_"..mobname..".png", -- left - "[combine:16x16:4,0=mobs_mc_"..mobname..".png", -- right - "[combine:16x16:-20,0=mobs_mc_"..mobname..".png", -- back - "[combine:16x16:-4,0=mobs_mc_"..mobname..".png", -- front - }, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - sounds = sounds, - selection_box = { - type = "fixed", - fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - }) -end - --- Add heads -addhead("zombie", "Zombie Head", "A zombie head is a small decorative block which resembles the head of a zombie.") -addhead("creeper", "Creeper Head", "A creeper head is a small decorative block which resembles the head of a creeper.") -addhead("skeleton", "Skeleton Skull", "A skeleton skull is a small decorative block which resembles the skull of a skeleton.") -addhead("wither_skeleton", "Wither Skeleton Skull", "A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton.") diff --git a/mods/ENTITIES/mobs_mc/5_spawn_abm_check.lua b/mods/ENTITIES/mobs_mc/5_spawn_abm_check.lua deleted file mode 100644 index 85886a995..000000000 --- a/mods/ENTITIES/mobs_mc/5_spawn_abm_check.lua +++ /dev/null @@ -1,20 +0,0 @@ -local function is_forbidden_node(pos, node) - node = node or minetest.get_node(pos) - return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0 -end - -function mobs:spawn_abm_check(pos, node, name) - -- Don't spawn monsters on mycelium - if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then - return true - --Don't Spawn mobs on stairs, slabs, or carpets - elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then - return true - -- Spawn on opaque or liquid nodes - elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" then - return false - end - - -- Reject everything else - return true -end diff --git a/mods/ENTITIES/mobs_mc/LICENSE-media.md b/mods/ENTITIES/mobs_mc/LICENSE-media.md index dad31abb8..4e3de49f1 100644 --- a/mods/ENTITIES/mobs_mc/LICENSE-media.md +++ b/mods/ENTITIES/mobs_mc/LICENSE-media.md @@ -75,6 +75,7 @@ Origin of those models: * `mobs_mc_mushroom_brown.png` (CC0) * “Spawn egg” textures (`mobs_mc_spawn_icon_*`) by 22i +* Llama decor (carpet) textures (`mobs_mc_llama_decor_*`) by erlehmann and rudzik8 * Any other texture not mentioned here are licensed under the MIT License ## Sounds diff --git a/mods/ENTITIES/mobs_mc/README.md b/mods/ENTITIES/mobs_mc/README.md index d3ac29a16..bdc561295 100644 --- a/mods/ENTITIES/mobs_mc/README.md +++ b/mods/ENTITIES/mobs_mc/README.md @@ -17,11 +17,6 @@ This mod adds mobs which closely resemble the mobs from the game Minecraft, vers * Code: GNU General Public License, version 3 (see `LICENSE`) * Media: MIT, CC0, CC BY 3.0 CC BY-SA 4.0, LGPLv2.1, GPLv3. See `LICENSE_media.md` for details -## Useful information for developers - -### Game integration -Want to include this mod in your game? Read `gameconfig.md`. - ### Links * [`mobs_mc`](https://github.com/maikerumine/mobs_mc) @@ -44,7 +39,7 @@ Want to include this mod in your game? Read `gameconfig.md`. * Cave Spider * Enderman * Zombie Villager -* Zombie Pigman +* Zombie Piglin * Wither Skeleton * Magma Cube * Blaze @@ -63,6 +58,7 @@ Want to include this mod in your game? Read `gameconfig.md`. ### Peaceful mobs +* Axolotl * Chicken * Cow * Pig diff --git a/mods/ENTITIES/mobs_mc/agent.lua b/mods/ENTITIES/mobs_mc/agent.lua deleted file mode 100644 index 8fa7314cf..000000000 --- a/mods/ENTITIES/mobs_mc/agent.lua +++ /dev/null @@ -1,39 +0,0 @@ ---################### ---################### AGENT ---################### - -local S = minetest.get_translator("mobs_mc") - -mobs:register_mob("mobs_mc:agent", { - type = "npc", - spawn_class = "passive", - passive = true, - hp_min = 20, - hp_max = 20, - armor = 100, - collisionbox = {-0.35, -0.01, -0.35, 0.35, 1, 0.35}, - visual = "mesh", - mesh = "mobs_mc_agent.b3d", - textures = { - {"mobs_mc_agent.png"}, - }, - -- TODO: sounds - visual_size = {x=3, y=3}, - walk_chance = 0, - walk_velocity = 0.6, - run_velocity = 2, - jump = true, - animation = { - stand_speed = 25, - walk_speed = 25, - run_speed = 50, - stand_start = 20, - stand_end = 60, - walk_start = 0, - walk_end = 20, - run_start = 0, - run_end = 20, - }, -}) - -mobs:register_egg("mobs_mc:agent", S("Agent"), "mobs_mc_spawn_icon_agent.png", 0) diff --git a/mods/ENTITIES/mobs_mc/axolotl.lua b/mods/ENTITIES/mobs_mc/axolotl.lua new file mode 100644 index 000000000..087f201c7 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/axolotl.lua @@ -0,0 +1,181 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local axolotl = { + type = "animal", + spawn_class = "axolotl", + can_despawn = true, + passive = false, + hp_min = 14, + hp_max = 14, + xp_min = 1, + xp_max = 7, + + head_swivel = "head.control", + bone_eye_height = -1, + head_eye_height = -0.5, + horrizonatal_head_height = 0, + curiosity = 10, + head_yaw="z", + + armor = 100, + rotate = 180, + spawn_in_group_min = 1, + spawn_in_group = 4, + tilt_swim = true, + collisionbox = {-0.5, 0.0, -0.5, 0.5, 0.8, 0.5}, + visual = "mesh", + mesh = "mobs_mc_axolotl.b3d", + textures = { + {"mobs_mc_axolotl_brown.png"}, + {"mobs_mc_axolotl_yellow.png"}, + {"mobs_mc_axolotl_green.png"}, + {"mobs_mc_axolotl_pink.png"}, + {"mobs_mc_axolotl_black.png"}, + {"mobs_mc_axolotl_purple.png"}, + {"mobs_mc_axolotl_white.png"} + }, + sounds = { + random = "mobs_mc_axolotl", + damage = "mobs_mc_axolotl_hurt", + distance = 16, + }, + animation = {-- Stand: 1-20; Walk: 20-60; Swim: 61-81 + stand_start = 61, stand_end = 81, stand_speed = 15, + walk_start = 61, walk_end = 81, walk_speed = 15, + run_start = 61, run_end = 81, run_speed = 20, + }, + + follow = { + "mcl_fishing:clownfish_raw" + }, + + view_range = 16, + fear_height = 4, + + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + if clicker:set_wielded_item("mcl_buckets:bucket_axolotl") then + local it = clicker:get_wielded_item() + local m = it:get_meta() + m:set_string("properties",minetest.serialize(self.object:get_properties())) + clicker:set_wielded_item(it) + self.object:remove() + end + awards.unlock(clicker:get_player_name(), "mcl:cutestPredator") + return + end + if self:feed_tame(clicker, 1, true, false) then return end + end, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = true, + damage = 2, + reach = 2, + attack_type = "dogfight", + attack_animals = true, + specific_attack = { + "extra_mobs_cod", + "mobs_mc:sheep", + "extra_mobs_glow_squid", + "extra_mobs_salmon", + "extra_mobs_tropical_fish", + "mobs_mc_squid" + }, + runaway = true, +} + +mcl_mobs.register_mob("mobs_mc:axolotl", axolotl) + +local water = 0 + +mcl_mobs:spawn_specific( +"mobs_mc:axolotl", +"overworld", +"water", +{ +"Swampland", +"MushroomIsland", +"RoofedForest", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"SunflowerPlains_ocean", +"Swampland_ocean", +"ExtremeHillsM_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"SavannaM_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"FlowerForest_ocean", +"Desert_ocean", +"Taiga_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"LushCaves", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:axolotl", S("Axolotl"), "#e890bf", "#b83D7e", 0) diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 103579b67..b5532e2ee 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -2,10 +2,12 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:bat", { +mcl_mobs.register_mob("mobs_mc:bat", { + description = S("Bat"), type = "animal", spawn_class = "ambient", can_despawn = true, + spawn_in_group = 8, passive = true, hp_min = 6, hp_max = 6, @@ -64,8 +66,82 @@ else end -- Spawn on solid blocks at or below Sea level and the selected light level -mobs:spawn_specific("mobs_mc:bat", mobs_mc.spawn.solid, {"air"}, 0, maxlight, 20, 5000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-1) +mcl_mobs:spawn_specific( +"mobs_mc:bat", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +}, +0, +maxlight, +20, +5000, +2, +mcl_vars.mg_overworld_min, +mobs_mc.water_level-1) -- spawn eggs -mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 0) +mcl_mobs.register_egg("mobs_mc:bat", S("Bat"), "#4c3e30", "#0f0f0f", 0) diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 00988a903..6d92de210 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -1,18 +1,23 @@ -- daufinsyd -- My work is under the LGPL terms --- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models +-- Model and mobs_blaze.png see https://github.com/22i/minecraft-voxel-blender-models -hi 22i ~jordan4ibanez -- blaze.lua partial copy of mobs_mc/ghast.lua local S = minetest.get_translator("mobs_mc") +local mod_target = minetest.get_modpath("mcl_target") + --################### --################### BLAZE --################### -mobs:register_mob("mobs_mc:blaze", { +mcl_mobs.register_mob("mobs_mc:blaze", { + description = S("Blaze"), type = "monster", spawn_class = "hostile", + spawn_in_group_min = 2, + spawn_in_group = 3, hp_min = 20, hp_max = 20, xp_min = 10, @@ -21,6 +26,12 @@ mobs:register_mob("mobs_mc:blaze", { rotate = -180, visual = "mesh", mesh = "mobs_mc_blaze.b3d", + head_swivel = "head.control", + bone_eye_height = 4, + head_eye_height = 3.5, + curiosity = 10, + head_yaw_offset = 180, + head_pitch_multiplier=-1, textures = { {"mobs_mc_blaze.png"}, }, @@ -38,7 +49,7 @@ mobs:register_mob("mobs_mc:blaze", { reach = 2, pathfinding = 1, drops = { - {name = mobs_mc.items.blaze_rod, + {name = "mcl_mobitems:blaze_rod", chance = 1, min = 0, max = 1, @@ -75,23 +86,83 @@ mobs:register_mob("mobs_mc:blaze", { fear_height = 0, glow = 14, fire_resistant = true, + do_custom = function(self) + if self.state == "attack" and self.attack:get_pos() and vector.distance(self.object:get_pos(), self.attack:get_pos()) < 1.2 then + mcl_burning.set_on_fire(self.attack, 5) + end + local pos = self.object:get_pos() + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#2c2c2c:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#424242:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + minetest.add_particle({ + pos = {x=pos.x+math.random(-0.7,0.7)*math.random()/2,y=pos.y+math.random(0.7,1.2),z=pos.z+math.random(-0.7,0.7)*math.random()/2}, + velocity = {x=0, y=math.random(1,1), z=0}, + expirationtime = math.random(), + size = math.random(1, 4), + collisiondetection = true, + vertical = false, + texture = "mcl_particles_smoke_anim.png^[colorize:#0f0f0f:255", + animation = { + type = "vertical_frames", + aspect_w = 8, + aspect_h = 8, + length = 2.05, + }, + }) + end, }) -mobs:spawn_specific("mobs_mc:blaze", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mcl_mobs:spawn_specific( +"mobs_mc:blaze", +"nether", +"ground", +{"Nether"}, +0, +minetest.LIGHT_MAX+1, +30, +5000, +3, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) -- Blaze fireball -mobs:register_arrow("mobs_mc:blaze_fireball", { +mcl_mobs.register_arrow("mobs_mc:blaze_fireball", { visual = "sprite", visual_size = {x = 0.3, y = 0.3}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, + _is_fireball = true, -- Direct hit, no fire... just plenty of pain hit_player = function(self, player) - if rawget(_G, "armor") and armor.last_damage_types then - armor.last_damage_types[player:get_player_name()] = "fireball" - end - mcl_burning.set_on_fire(player, 5, 1, "blaze") + mcl_burning.set_on_fire(player, 5) player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 5}, @@ -117,21 +188,25 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { -- Node hit, make fire hit_node = function(self, pos, node) - if node.name == "air" then - minetest.set_node(pos_above, {name=mobs_mc.items.fire}) + if node == "air" then + minetest.set_node(pos, {name = "mcl_fire:fire"}) else - local v = self.object:get_velocity() - v = vector.normalize(v) + if self._shot_from_dispenser and mod_target and node == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + end + local v = vector.normalize(self.object:get_velocity()) local crashpos = vector.subtract(pos, v) local crashnode = minetest.get_node(crashpos) + local cndef = minetest.registered_nodes[crashnode.name] -- Set fire if node is air, or a replacable flammable node (e.g. a plant) if crashnode.name == "air" or - (minetest.registered_nodes[crashnode.name].buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then - minetest.set_node(crashpos, {name=mobs_mc.items.fire}) + (cndef and cndef.buildable_to and minetest.get_item_group(crashnode.name, "flammable") >= 1) then + minetest.set_node(crashpos, {name = "mcl_fire:fire"}) end end end }) --- spawn eggs -mobs:register_egg("mobs_mc:blaze", S("Blaze"), "mobs_mc_spawn_icon_blaze.png", 0) +mcl_mobs:non_spawn_specific("mobs_mc:blaze", "overworld", 0, 11) +-- spawn eggs. +mcl_mobs.register_egg("mobs_mc:blaze", S("Blaze"), "#f6b201", "#fff87e", 0) diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 325371e2b..ca942d355 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -8,33 +8,40 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:chicken", { +mcl_mobs.register_mob("mobs_mc:chicken", { + description = S("Chicken"), type = "animal", spawn_class = "passive", - + passive = true, + runaway = true, hp_min = 4, hp_max = 4, xp_min = 1, xp_max = 3, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2}, - runaway = true, floats = 1, + head_swivel = "head.control", + bone_eye_height = 4, + head_eye_height = 1.5, + horrizonatal_head_height = -.3, + curiosity = 10, + head_yaw="z", + visual_size = {x=1,y=1}, visual = "mesh", mesh = "mobs_mc_chicken.b3d", textures = { {"mobs_mc_chicken.png"}, }, - visual_size = {x=2.2, y=2.2}, makes_footstep_sound = true, walk_velocity = 1, drops = { - {name = mobs_mc.items.chicken_raw, + {name = "mcl_mobitems:chicken", chance = 1, min = 1, max = 1, looting = "common",}, - {name = mobs_mc.items.feather, + {name = "mcl_mobitems:feather", chance = 1, min = 0, max = 2, @@ -57,20 +64,28 @@ mobs:register_mob("mobs_mc:chicken", { distance = 16, }, animation = { - stand_speed = 25, walk_speed = 25, run_speed = 50, - stand_start = 0, stand_end = 0, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 20, walk_speed = 25, + run_start = 0, run_end = 20, run_speed = 50, + }, + child_animations = { + stand_start = 31, stand_end = 31, + walk_start = 31, walk_end = 51, walk_speed = 37, + run_start = 31, run_end = 51, run_speed = 75, + }, + follow = { + "mcl_farming:wheat_seeds", + "mcl_farming:melon_seeds", + "mcl_farming:pumpkin_seeds", + "mcl_farming:beetroot_seeds", }, - - follow = mobs_mc.follow.chicken, view_range = 16, fear_height = 4, on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end - if mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:protect(self, clicker) then return end + if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end end, do_custom = function(self, dtime) @@ -88,19 +103,64 @@ mobs:register_mob("mobs_mc:chicken", { local pos = self.object:get_pos() - minetest.add_item(pos, mobs_mc.items.egg) + minetest.add_item(pos, "mcl_throwing:egg") minetest.sound_play("mobs_mc_chicken_lay_egg", { pos = pos, gain = 1.0, max_hear_distance = 16, }, true) - end, - + end, + }) --spawn -mobs:spawn_specific("mobs_mc:chicken", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:chicken", +"overworld", +"ground", +{ + "flat", + "IcePlainsSpikes", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", + "ExtremeHills+", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", + "BirchForestM", + "RoofedForest", + "Savanna", + "Savanna_beach", + "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" +}, +9, +minetest.LIGHT_MAX+1, +30, 17000, +3, +mobs_mc.water_level, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0) +mcl_mobs.register_egg("mobs_mc:chicken", S("Chicken"), "#a1a1a1", "#ff0000", 0) diff --git a/mods/ENTITIES/mobs_mc/cod.lua b/mods/ENTITIES/mobs_mc/cod.lua new file mode 100644 index 000000000..656b2c14c --- /dev/null +++ b/mods/ENTITIES/mobs_mc/cod.lua @@ -0,0 +1,275 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local pi = math.pi +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +local dir_to_pitch = function(dir) + local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function degrees(rad) + return rad * 180.0 / math.pi +end + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### cod +--################### + +local cod = { + type = "animal", + spawn_class = "water_ambient", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + rotate = 180, + spawn_in_group_min = 2, -- was 3 + spawn_in_group = 4, -- was 8 nerfed until we can cap them properly locally. this is a group size, not a per spawn attempt + tilt_swim = true, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3}, + visual = "mesh", + mesh = "extra_mobs_cod.b3d", + textures = { + {"mobs_mc_cod.png"} + }, + sounds = { + }, + animation = { + stand_start = 1, + stand_end = 20, + walk_start = 1, + walk_end = 20, + run_start = 1, + run_end = 20, + }, + drops = { + {name = "mcl_fishing:fish_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + do_custom = function(self) + --[[ this is supposed to make them jump out the water but doesn't appear to work very well + self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) + if minetest.get_item_group(self.standing_in, "water") ~= 0 then + if self.object:get_velocity().y < 5 then + self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 }) + end + end +--]] + for _,object in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 10)) do + local lp = object:get_pos() + local s = self.object:get_pos() + local vec = { + x = lp.x - s.x, + y = lp.y - s.y, + z = lp.z - s.z + } + if object and not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "mobs_mc:cod" then + self.state = "runaway" + self.object:set_rotation({x=0,y=(atan(vec.z / vec.x) + 3 * pi / 2) - self.rotate,z=0}) + end + end + end, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + self.object:remove() + clicker:set_wielded_item("mcl_buckets:bucket_cod") + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end +} + +mcl_mobs.register_mob("mobs_mc:cod", cod) + + +--spawning TODO: in schools + +local water = 0 + +mcl_mobs:spawn_specific( +"mobs_mc:cod", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:cod", S("Cod"), "#c1a76a", "#e5c48b", 0) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 005af2980..64f74c516 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -3,35 +3,44 @@ local S = minetest.get_translator("mobs_mc") local cow_def = { + description = S("Cow"), type = "animal", spawn_class = "passive", + passive = true, + runaway = true, hp_min = 10, hp_max = 10, xp_min = 1, xp_max = 3, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45}, + spawn_in_group = 4, + spawn_in_group_min = 2, visual = "mesh", mesh = "mobs_mc_cow.b3d", textures = { { "mobs_mc_cow.png", "blank.png", }, }, - visual_size = {x=2.8, y=2.8}, + head_swivel = "head.control", + bone_eye_height = 10, + head_eye_height = 1.1, + horrizonatal_head_height=-1.8, + curiosity = 2, + head_yaw="z", makes_footstep_sound = true, walk_velocity = 1, drops = { - {name = mobs_mc.items.beef_raw, + {name = "mcl_mobitems:beef", chance = 1, min = 1, max = 3, looting = "common",}, - {name = mobs_mc.items.leather, + {name = "mcl_mobitems:leather", chance = 1, min = 0, max = 2, looting = "common",}, }, - runaway = true, sounds = { random = "mobs_mc_cow", damage = "mobs_mc_cow_hurt", @@ -40,67 +49,70 @@ local cow_def = { distance = 16, }, animation = { - stand_speed = 25, walk_speed = 40, - run_speed = 60, stand_start = 0, - stand_end = 0, walk_start = 0, - walk_end = 40, run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 30, + run_start = 0, run_end = 40, run_speed = 40, + }, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 45, + run_start = 41, run_end = 81, run_speed = 60, }, - follow = mobs_mc.follow.cow, on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:protect(self, clicker) then return end if self.child then return end local item = clicker:get_wielded_item() - if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then + if item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then local inv = clicker:get_inventory() - inv:remove_item("main", mobs_mc.items.bucket) + inv:remove_item("main", "mcl_buckets:bucket_empty") minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6}) -- if room add bucket of milk to inventory, otherwise drop as item - if inv:room_for_item("main", {name=mobs_mc.items.milk}) then - clicker:get_inventory():add_item("main", mobs_mc.items.milk) + if inv:room_for_item("main", {name = "mcl_mobitems:milk_bucket"}) then + clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket") else local pos = self.object:get_pos() pos.y = pos.y + 0.5 - minetest.add_item(pos, {name = mobs_mc.items.milk}) + minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"}) end return end - mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end, - follow = mobs_mc.items.wheat, + follow = "mcl_farming:wheat_item", view_range = 10, fear_height = 4, } -mobs:register_mob("mobs_mc:cow", cow_def) +mcl_mobs.register_mob("mobs_mc:cow", cow_def) -- Mooshroom local mooshroom_def = table.copy(cow_def) - -mooshroom_def.mesh = "mobs_mc_cow.b3d" +mooshroom_def.description = S("Mooshroom") +mooshroom_def.spawn_in_group_min = 2 +mooshroom_def.spawn_in_group = 4 mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } } mooshroom_def.on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:protect(self, clicker) then return end if self.child then return end local item = clicker:get_wielded_item() -- Use shears to get mushrooms and turn mooshroom into cow - if item:get_name() == mobs_mc.items.shears then + if item:get_name() == "mcl_tools:shears" then local pos = self.object:get_pos() minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then - minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_brown .. " 5") + minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_brown 5") else - minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_red .. " 5") + minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_red 5") end local oldyaw = self.object:get_yaw() @@ -109,45 +121,115 @@ mooshroom_def.on_rightclick = function(self, clicker) cow:set_yaw(oldyaw) if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:add_wear(mobs_mc.misc.shears_wear) + item:add_wear(mobs_mc.shears_wear) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end -- Use bucket to milk - elseif item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then + elseif item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then local inv = clicker:get_inventory() - inv:remove_item("main", mobs_mc.items.bucket) + inv:remove_item("main", "mcl_buckets:bucket_empty") minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6}) -- If room, add milk to inventory, otherwise drop as item - if inv:room_for_item("main", {name=mobs_mc.items.milk}) then - clicker:get_inventory():add_item("main", mobs_mc.items.milk) + if inv:room_for_item("main", {name="mcl_mobitems:milk_bucket"}) then + clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket") else local pos = self.object:get_pos() pos.y = pos.y + 0.5 - minetest.add_item(pos, {name = mobs_mc.items.milk}) + minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"}) end -- Use bowl to get mushroom stew - elseif item:get_name() == mobs_mc.items.bowl and clicker:get_inventory() then + elseif item:get_name() == "mcl_core:bowl" and clicker:get_inventory() then local inv = clicker:get_inventory() - inv:remove_item("main", mobs_mc.items.bowl) + inv:remove_item("main", "mcl_core:bowl") minetest.sound_play("mobs_mc_cow_mushroom_stew", {pos=self.object:get_pos(), gain=0.6}) -- If room, add mushroom stew to inventory, otherwise drop as item - if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then - clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew) + if inv:room_for_item("main", {name="mcl_mushrooms:mushroom_stew"}) then + clicker:get_inventory():add_item("main", "mcl_mushrooms:mushroom_stew") else local pos = self.object:get_pos() pos.y = pos.y + 0.5 - minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew}) + minetest.add_item(pos, {name = "mcl_mushrooms:mushroom_stew"}) end end - mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end -mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) + +mooshroom_def.on_lightning_strike = function(self, pos, pos2, objects) + if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then + self.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } + else + self.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } + end + self.object:set_properties({ textures = self.base_texture }) + return true +end +mcl_mobs.register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning -mobs:spawn_specific("mobs_mc:cow", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 10, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:mooshroom", mobs_mc.spawn.mushroom_island, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 17000, 5, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:cow", +"overworld", +"ground", +{ + "flat", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", + "ExtremeHills+", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", + "BirchForestM", + "RoofedForest", + "Savanna", + "Savanna_beach", + "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" +}, +9, +minetest.LIGHT_MAX+1, +30, +17000, +10, +mobs_mc.water_level, +mcl_vars.mg_overworld_max) + + + +mcl_mobs:spawn_specific( +"mobs_mc:mooshroom", +"overworld", +"ground", +{ +"MushroomIslandShore", +"MushroomIsland" +}, +9, +minetest.LIGHT_MAX+1, +30, +17000, +5, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- spawn egg -mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0) -mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.png", 0) +mcl_mobs.register_egg("mobs_mc:cow", S("Cow"), "#443626", "#a1a1a1", 0) +mcl_mobs.register_egg("mobs_mc:mooshroom", S("Mooshroom"), "#a00f10", "#b7b7b7", 0) diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index f1648525a..f751b1240 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -9,9 +9,11 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:creeper", { +mcl_mobs.register_mob("mobs_mc:creeper", { + description = S("Creeper"), type = "monster", spawn_class = "hostile", + spawn_in_group = 1, hp_min = 20, hp_max = 20, xp_min = 5, @@ -20,8 +22,12 @@ mobs:register_mob("mobs_mc:creeper", { pathfinding = 1, visual = "mesh", mesh = "mobs_mc_creeper.b3d", + head_swivel = "Head_Control", + bone_eye_height = 2.35, + curiosity = 2, textures = { - {"mobs_mc_creeper.png"}, + {"mobs_mc_creeper.png", + "mobs_mc_empty.png"}, }, visual_size = {x=3, y=3}, sounds = { @@ -34,12 +40,17 @@ mobs:register_mob("mobs_mc:creeper", { }, makes_footstep_sound = true, walk_velocity = 1.05, - run_velocity = 2.1, + run_velocity = 2.0, runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, attack_type = "explode", + --hssssssssssss + explosion_strength = 3, - reach = 4, + explosion_radius = 3.5, + explosion_damage_radius = 3.5, + explosiontimer_reset_radius = 6, + reach = 3, explosion_timer = 1.5, allow_fuse_reset = true, stop_to_explode = true, @@ -52,7 +63,7 @@ mobs:register_mob("mobs_mc:creeper", { return end local item = clicker:get_wielded_item() - if item:get_name() == mobs_mc.items.flint_and_steel then + if item:get_name() == "mcl_fire:flint_and_steel" then if not minetest.is_creative_enabled(clicker:get_player_name()) then -- Wear tool local wdef = item:get_definition() @@ -71,8 +82,7 @@ mobs:register_mob("mobs_mc:creeper", { if self._forced_explosion_countdown_timer ~= nil then self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime if self._forced_explosion_countdown_timer <= 0 then - mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength) - self.object:remove() + self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) end end end, @@ -83,14 +93,14 @@ mobs:register_mob("mobs_mc:creeper", { if luaentity and luaentity.name:find("arrow") then local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity() if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then - minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)]) + minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9)) end end end end, maxdrops = 2, drops = { - {name = mobs_mc.items.gunpowder, + {name = "mcl_mobitems:gunpowder", chance = 1, min = 0, max = 2, @@ -98,7 +108,7 @@ mobs:register_mob("mobs_mc:creeper", { -- Head -- TODO: Only drop if killed by charged creeper - {name = mobs_mc.items.head_creeper, + {name = "mcl_heads:creeper", chance = 200, -- 0.5% min = 1, max = 1,}, @@ -124,8 +134,282 @@ mobs:register_mob("mobs_mc:creeper", { view_range = 16, }) +mcl_mobs.register_mob("mobs_mc:creeper_charged", { + description = S("Creeper"), + type = "monster", + spawn_class = "hostile", + hp_min = 20, + hp_max = 20, + xp_min = 5, + xp_max = 5, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3}, + pathfinding = 1, + visual = "mesh", + mesh = "mobs_mc_creeper.b3d", -mobs:spawn_specific("mobs_mc:creeper", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 16500, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) + --BOOM + + textures = { + {"mobs_mc_creeper.png", + "mobs_mc_creeper_charge.png"}, + }, + visual_size = {x=3, y=3}, + sounds = { + attack = "tnt_ignite", + death = "mobs_mc_creeper_death", + damage = "mobs_mc_creeper_hurt", + fuse = "tnt_ignite", + explode = "tnt_explode", + distance = 16, + }, + makes_footstep_sound = true, + walk_velocity = 1.05, + run_velocity = 2.1, + runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" }, + attack_type = "explode", + + explosion_strength = 6, + explosion_radius = 8, + explosion_damage_radius = 8, + explosiontimer_reset_radius = 6, + 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. + -- TODO: Test and debug this code. + on_rightclick = function(self, clicker) + if self._forced_explosion_countdown_timer ~= nil then + return + end + local item = clicker:get_wielded_item() + if item:get_name() == "mcl_fire:flint_and_steel" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + -- Wear tool + local wdef = item:get_definition() + item:add_wear(1000) + -- Tool break sound + if item:get_count() == 0 and wdef.sound and wdef.sound.breaks then + minetest.sound_play(wdef.sound.breaks, {pos = clicker:get_pos(), gain = 0.5}, true) + end + clicker:set_wielded_item(item) + end + self._forced_explosion_countdown_timer = self.explosion_timer + minetest.sound_play(self.sounds.attack, {pos = self.object:get_pos(), gain = 1, max_hear_distance = 16}, true) + end + end, + do_custom = function(self, dtime) + if self._forced_explosion_countdown_timer ~= nil then + self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime + if self._forced_explosion_countdown_timer <= 0 then + self:boom(mcl_util.get_object_center(self.object), self.explosion_strength) + end + end + end, + on_die = function(self, pos, cmi_cause) + -- Drop a random music disc when killed by skeleton or stray + if cmi_cause and cmi_cause.type == "punch" then + local luaentity = cmi_cause.puncher and cmi_cause.puncher:get_luaentity() + if luaentity and luaentity.name:find("arrow") then + local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity() + if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then + minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9)) + end + end + end + end, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:creeper_charged") + return true + end, + maxdrops = 2, + drops = { + {name = "mcl_mobitems:gunpowder", + chance = 1, + min = 0, + max = 2, + looting = "common",}, + + -- Head + -- TODO: Only drop if killed by charged creeper + {name = "mcl_heads:creeper", + chance = 200, -- 0.5% + min = 1, + max = 1,}, + }, + animation = { + speed_normal = 24, + speed_run = 48, + 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, + }, + floats = 1, + fear_height = 4, + view_range = 16, + --Having trouble when fire is placed with lightning + fire_resistant = true, + glow = 3, +}) + +mcl_mobs:spawn_specific( +"mobs_mc:creeper", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +20, +16500, +2, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0) +mcl_mobs.register_egg("mobs_mc:creeper", S("Creeper"), "#0da70a", "#000000", 0) diff --git a/mods/ENTITIES/mobs_mc/depends.txt b/mods/ENTITIES/mobs_mc/depends.txt deleted file mode 100644 index 4a2756661..000000000 --- a/mods/ENTITIES/mobs_mc/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_init -mcl_particles -default? -mcl_mobs -mcl_tnt? -mcl_bows? -mcl_throwing? -mcl_fishing? -bones? -mesecons_materials? -mobs_mc_gameconfig? -doc_items? diff --git a/mods/ENTITIES/mobs_mc/description.txt b/mods/ENTITIES/mobs_mc/description.txt deleted file mode 100644 index c57195fea..000000000 --- a/mods/ENTITIES/mobs_mc/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds Minecraft-like monsters and animals. diff --git a/mods/ENTITIES/mobs_mc/dolphin.lua b/mods/ENTITIES/mobs_mc/dolphin.lua new file mode 100644 index 000000000..153734c39 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/dolphin.lua @@ -0,0 +1,253 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local pi = math.pi +local atann = math.atan +local atan = function(x) + if not x or x ~= x then + return 0 + else + return atann(x) + end +end + +local dir_to_pitch = function(dir) + local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function degrees(rad) + return rad * 180.0 / math.pi +end + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### dolphin +--################### + +local dolphin = { + type = "animal", + spawn_class = "water", + can_despawn = true, + passive = true, + hp_min = 10, + hp_max = 10, + xp_min = 1, + xp_max = 3, + armor = 100, + walk_chance = 100, + breath_max = 120, + rotate = 180, + spawn_in_group_min = 2, -- was 3 + spawn_in_group = 4, -- was 4. nerfed until water has own cap, and it represents max pack size rather than per spawn attempt + tilt_swim = true, + collisionbox = {-0.3, 0.0, -0.3, 0.3, 0.79, 0.3}, + visual = "mesh", + mesh = "extra_mobs_dolphin.b3d", + textures = { + {"extra_mobs_dolphin.png"} + }, + sounds = { + }, + animation = { + stand_start = 20, + stand_end = 20, + walk_start = 0, + walk_end = 15, + run_start = 30, + run_end = 45, + }, + drops = { + {name = "mcl_fishing:fish_raw", + chance = 1, + min = 0, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + breathes_in_water = true, + jump = false, + view_range = 16, + fear_height = 4, + walk_velocity = 3, + run_velocity = 6, + reach = 2, + damage = 2.5, + attack_type = "dogfight", + do_custom = function(self,dtime) + --[[ this is supposed to make them jump out the water but doesn't appear to work very well + self.object:set_bone_position("body", vector.new(0,1,0), vector.new(degrees(dir_to_pitch(self.object:get_velocity())) * -1 + 90,0,0)) + if minetest.get_item_group(self.standing_in, "water") ~= 0 then + if self.object:get_velocity().y < 5 then + self.object:add_velocity({ x = 0 , y = math.random(-.007, .007), z = 0 }) + end + end + --]] + end, +} + +mcl_mobs.register_mob("mobs_mc:dolphin", dolphin) + + +--spawning TO DO: in schools +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:dolphin", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:dolphin", S("Dolphin"), "#223b4d", "#f9f9f9", 0) diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index c579213a0..fb92f51c4 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -4,7 +4,52 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:enderdragon", { +local BEAM_CHECK_FREQUENCY = 2 +local POS_CHECK_FREQUENCY = 15 +local HEAL_AMMOUNT = 37 + +local function heal(self) + local o = self.object + self.health = math.min(self.hp_max,self.health + HEAL_AMMOUNT) +end +local function check_beam(self) + for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 80)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_end:crystal" then + if luaentity.beam then + if luaentity.beam == self.beam then + heal(self) + break + end + else + if self.beam then + self.beam:remove() + end + minetest.add_entity(self.object:get_pos(), "mcl_end:crystal_beam"):get_luaentity():init(self.object, obj) + break + end + end + end +end + +local function check_pos(self) + if self._portal_pos then + -- migrate old format + if type(self._portal_pos) == "string" then + self._portal_pos = minetest.string_to_pos(self._portal_pos) + end + local portal_center = vector.add(self._portal_pos, vector.new(0, 11, 0)) + local pos = self.object:get_pos() + if vector.distance(pos, portal_center) > 50 then + self.object:set_pos(self._last_good_pos or portal_center) + else + self._last_good_pos = pos + end + end +end + +mcl_mobs.register_mob("mobs_mc:enderdragon", { + description = S("Ender Dragon"), type = "monster", spawn_class = "hostile", pathfinding = 1, @@ -22,9 +67,10 @@ mobs:register_mob("mobs_mc:enderdragon", { {"mobs_mc_dragon.png"}, }, visual_size = {x=3, y=3}, - view_range = 35, + view_range = 64, walk_velocity = 6, run_velocity = 6, + can_despawn = false, sounds = { -- TODO: more sounds shoot_attack = "mobs_mc_ender_dragon_shoot", @@ -33,6 +79,7 @@ mobs:register_mob("mobs_mc:enderdragon", { }, physical = true, damage = 10, + knock_back = false, jump = true, jump_height = 14, fly = true, @@ -49,8 +96,8 @@ mobs:register_mob("mobs_mc:enderdragon", { arrow = "mobs_mc:dragon_fireball", shoot_interval = 0.5, shoot_offset = -1.0, - xp_min = 12000, - xp_max = 12000, + xp_min = 500, + xp_max = 500, animation = { fly_speed = 8, stand_speed = 8, stand_start = 0, stand_end = 20, @@ -58,15 +105,35 @@ mobs:register_mob("mobs_mc:enderdragon", { run_start = 0, run_end = 20, }, ignores_nametag = true, - on_die = function(self, own_pos) - if self._egg_spawn_pos then - local pos = minetest.string_to_pos(self._egg_spawn_pos) - --if minetest.get_node(pos).buildable_to then - minetest.set_node(pos, {name = mobs_mc.items.dragon_egg}) - return - --end + do_custom = function(self,dtime) + mcl_bossbars.update_boss(self.object, "Ender Dragon", "light_purple") + if self._pos_timer == nil or self._pos_timer > POS_CHECK_FREQUENCY then + self._pos_timer = 0 + check_pos(self) + end + if self._beam_timer == nil or self._beam_timer > BEAM_CHECK_FREQUENCY then + self._beam_timer = 0 + check_beam(self) + end + self._beam_timer = self._beam_timer + dtime + self._pos_timer = self._pos_timer + dtime + end, + on_die = function(self, pos, cmi_cause) + if self._portal_pos then + mcl_portals.spawn_gateway_portal() + mcl_structures.place_structure(self._portal_pos,mcl_structures.registered_structures["end_exit_portal_open"],PseudoRandom(minetest.get_mapgen_setting("seed")),-1) + if self._initial then + mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000 + 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 + awards.unlock(players:get_player_name(), "mcl:freeTheEnd") + end end - minetest.add_item(own_pos, mobs_mc.items.dragon_egg) end, fire_resistant = true, }) @@ -75,7 +142,7 @@ mobs:register_mob("mobs_mc:enderdragon", { local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false -- dragon fireball (projectile) -mobs:register_arrow("mobs_mc:dragon_fireball", { +mcl_mobs.register_arrow("mobs_mc:dragon_fireball", { visual = "sprite", visual_size = {x = 1.25, y = 1.25}, textures = {"mobs_mc_dragon_fireball.png"}, @@ -99,8 +166,12 @@ mobs:register_arrow("mobs_mc:dragon_fireball", { -- node hit, explode hit_node = function(self, pos, node) - mobs:boom(self, pos, 2) + mcl_mobs.mob_class.boom(self,pos, 2) end }) -mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true) +mcl_mobs.register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "#252525", "#b313c9", 0, true) + + +mcl_wip.register_wip_item("mobs_mc:enderdragon") +mcl_mobs:non_spawn_specific("mobs_mc:enderdragon","overworld",0,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index b2971ae45..a57160e4d 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -24,7 +24,31 @@ -- added rain damage. -- fixed the grass_with_dirt issue. +-- How freqeuntly to take and place blocks, in seconds +local take_frequency_min = 235 +local take_frequency_max = 245 +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 + end, + glow = 50, +}) + local S = minetest.get_translator("mobs_mc") +local enable_damage = minetest.settings:get_bool("enable_damage") local telesound = function(pos, is_source) local snd @@ -42,11 +66,35 @@ end local pr = PseudoRandom(os.time()*(-334)) --- How freqeuntly to take and place blocks, in seconds -local take_frequency_min = 235 -local take_frequency_max = 245 -local place_frequency_min = 235 -local place_frequency_max = 245 +-- 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). @@ -69,9 +117,9 @@ local create_enderman_textures = function(block_type, itemstring) local tiles = minetest.registered_nodes[itemstring].tiles local textures = {} local last - if mobs_mc.enderman_block_texture_overrides[itemstring] then + if block_texture_overrides[itemstring] then -- Texture override available? Use these instead! - textures = mobs_mc.enderman_block_texture_overrides[itemstring] + textures = block_texture_overrides[itemstring] else -- Extract the texture names for i = 1, 6 do @@ -188,10 +236,29 @@ local select_enderman_animation = function(animation_type) end local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false +local psdefs = {{ + amount = 5, + minpos = vector.new(-0.6,0,-0.6), + maxpos = vector.new(0.6,3,0.6), + minvel = vector.new(-0.25,-0.25,-0.25), + maxvel = vector.new(0.25,0.25,0.25), + minacc = vector.new(-0.5,-0.5,-0.5), + maxacc = vector.new(0.5,0.5,0.5), + minexptime = 0.2, + maxexptime = 3, + minsize = 0.2, + maxsize = 1.2, + collisiondetection = true, + vertical = false, + time = 0, + texture = "mcl_portals_particle"..math.random(1, 5)..".png", +}} -mobs:register_mob("mobs_mc:enderman", { +mcl_mobs.register_mob("mobs_mc:enderman", { + description = S("Enderman"), type = "monster", spawn_class = "passive", + can_despawn = true, passive = true, pathfinding = 1, hp_min = 40, @@ -204,6 +271,19 @@ mobs:register_mob("mobs_mc:enderman", { textures = create_enderman_textures(), visual_size = {x=3, y=3}, 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", @@ -216,8 +296,9 @@ mobs:register_mob("mobs_mc:enderman", { run_velocity = 3.4, damage = 7, reach = 2, + particlespawners = psdefs, drops = { - {name = mobs_mc.items.ender_pearl, + {name = "mcl_throwing:ender_pearl", chance = 1, min = 0, max = 1, @@ -225,74 +306,71 @@ mobs:register_mob("mobs_mc:enderman", { }, animation = select_enderman_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 + end, do_custom = function(self, dtime) - -- PARTICLE BEHAVIOUR HERE. - local enderpos = self.object:get_pos() - local chanceOfParticle = math.random(0, 1) - if chanceOfParticle == 1 then - minetest.add_particle({ - pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2}, - velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)}, - acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)}, - expirationtime = math.random(), - size = math.random(), - collisiondetection = true, - vertical = false, - texture = "mcl_portals_particle"..math.random(1, 5)..".png", - }) - end -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. - if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then - local damage = true - local enderpos = self.object:get_pos() - enderpos.y = enderpos.y+2.89 - local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z} - local ray = minetest.raycast(enderpos, height, true) - -- Check for blocks above enderman. - for pointed_thing in ray do - if pointed_thing.type == "node" then - local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name - local def = minetest.registered_nodes[nn] - if (not def) or def.walkable then - -- There's a node in the way. Delete arrow without damage - damage = false - break - end - end - end - - if damage == true then - self.state = "" - --rain hurts enderman - self.object:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=self._damage}, - }, nil) - --randomly teleport hopefully under something. - self:teleport(nil) - end - end - -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. - if self.state == "attack" then - --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then - --self:teleport(nil) - --self.state = "" - --else - if self.attack then - local target = self.attack - local pos = target:get_pos() - if pos ~= nil then - if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then - self:teleport(target) + local enderpos = self.object:get_pos() + local dim = mcl_worlds.pos_to_dimension(enderpos) + if dim == "overworld" then + if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then + local damage = true + local enderpos = self.object:get_pos() + enderpos.y = enderpos.y+2.89 + local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z} + local ray = minetest.raycast(enderpos, height, true) + -- Check for blocks above enderman. + for pointed_thing in ray do + if pointed_thing.type == "node" then + local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name + local def = minetest.registered_nodes[nn] + if (not def) or def.walkable then + -- There's a node in the way. Delete arrow without damage + damage = false + break end end end - --end + + if damage == true then + self.state = "" + --rain hurts enderman + self.object:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, nil) + --randomly teleport hopefully under something. + self:teleport(nil) + end + end + end + + -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. + if self.state == "attack" then + if self.attack then + local target = self.attack + local pos = target:get_pos() + if pos ~= nil then + if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then + self:teleport(target) + end + end + end + else --if not attacking try to tp to the dark + if dim == 'overworld' then + local light = minetest.get_node_light(enderpos) + if light and light > minetest.LIGHT_MAX then + self:teleport(nil) + end + end end -- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE. -- Check for arrows and people nearby. - local enderpos = self.object:get_pos() - local objs = minetest.get_objects_inside_radius(enderpos, 4) + + enderpos = self.object:get_pos() + enderpos.y = enderpos.y + 1.5 + local objs = minetest.get_objects_inside_radius(enderpos, 2) for n = 1, #objs do local obj = objs[n] if obj then @@ -304,13 +382,14 @@ mobs:register_mob("mobs_mc:enderman", { else local lua = obj:get_luaentity() if lua then - if lua.name == "mcl_bows:arrow_entity" then + if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then self:teleport(nil) end end end end end + -- PROVOKED BEHAVIOUR HERE. local enderpos = self.object:get_pos() if self.provoked == "broke_contact" then @@ -319,45 +398,71 @@ mobs:register_mob("mobs_mc:enderman", { -- self:teleport(nil) -- self.state = "" --else - if self.attack ~= nil then + if self.attack ~= nil and enable_damage then self.state = 'attack' end --end end -- Check to see if people are near by enough to look at us. - local objs = minetest.get_objects_inside_radius(enderpos, 64) - local obj - for n = 1, #objs do - obj = objs[n] - if obj then - if minetest.is_player(obj) then + for _,obj in pairs(minetest.get_connected_players()) do + + --check if they are within radius + local player_pos = obj:get_pos() + if player_pos then -- prevent crashing in 1 in a million scenario + + local ender_distance = vector.distance(enderpos, player_pos) + if ender_distance <= 64 then + -- Check if they are looking at us. - local player_pos = obj:get_pos() local look_dir_not_normalized = obj:get_look_dir() local look_dir = vector.normalize(look_dir_not_normalized) - local look_pos = vector.new({x = look_dir.x+player_pos.x, y = look_dir.y+player_pos.y + 1.5, z = look_dir.z+player_pos.z}) -- Arbitrary value (1.5) is head level according to player info mod. - -- Cast up to 64 to see if player is looking at enderman. - for n = 1,64,.25 do - local node = minetest.get_node(look_pos) - if node.name ~= "air" then - break - end - if look_pos.x-1enderpos.x and look_pos.y-2.89enderpos.y and look_pos.z-1enderpos.z then + local player_eye_height = obj:get_properties().eye_height + + --skip player if they have no data - log it + if not player_eye_height then + minetest.log("error", "Enderman at location: ".. dump(enderpos).." has indexed a null player!") + else + + --calculate very quickly the exact location the player is looking + --within the distance between the two "heads" (player and enderman) + local look_pos = vector.new(player_pos.x, player_pos.y + player_eye_height, player_pos.z) + local look_pos_base = look_pos + local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) + local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) + look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) + + --if looking in general head position, turn hostile + if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then self.provoked = "staring" self.attack = minetest.get_player_by_name(obj:get_player_name()) break - else + else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez if self.provoked == "staring" then self.provoked = "broke_contact" end end - look_pos.x = look_pos.x + (.25 * look_dir.x) - look_pos.y = look_pos.y + (.25 * look_dir.y) - look_pos.z = look_pos.z + (.25 * look_dir.z) + end end end end + + -- ATTACK ENDERMITE + local enderpos = self.object:get_pos() + if math.random(1,140) == 1 then + local mobsnear = minetest.get_objects_inside_radius(enderpos, 64) + for n=1, #mobsnear do + local mob = mobsnear[n] + if mob then + local entity = mob:get_luaentity() + if entity and entity.name == "mobs_mc:endermite" then + self.attack = mob + self.state = 'attack' + end + end + end + end + -- TAKE AND PLACE STUFF BEHAVIOUR BELOW. if not mobs_griefing then return @@ -374,20 +479,18 @@ mobs:register_mob("mobs_mc:enderman", { self._take_place_timer = 0 self._next_take_place_time = math.random(place_frequency_min, place_frequency_max) local pos = self.object:get_pos() - local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, mobs_mc.enderman_takable) + local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, "group:enderman_takable") if #takable_nodes >= 1 then local r = pr:next(1, #takable_nodes) local take_pos = takable_nodes[r] local node = minetest.get_node(take_pos) -- Don't destroy protected stuff. if not minetest.is_protected(take_pos, "") then - local dug = minetest.dig_node(take_pos) - if dug then - if mobs_mc.enderman_replace_on_take[node.name] then - self._taken_node = mobs_mc.enderman_replace_on_take[node.name] - else - self._taken_node = node.name - end + 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 @@ -416,7 +519,7 @@ mobs:register_mob("mobs_mc:enderman", { 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") - mobs:set_animation(self, self.animation.current) + self:set_animation(self.animation.current) if def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true) end @@ -438,8 +541,9 @@ mobs:register_mob("mobs_mc:enderman", { if success then local def = minetest.registered_nodes[self._taken_node] -- Update animation accordingly (removes visible block) + self.persistent = false self.animation = select_enderman_animation("normal") - mobs:set_animation(self, self.animation.current) + self:set_animation(self.animation.current) if def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true) end @@ -464,7 +568,8 @@ mobs:register_mob("mobs_mc:enderman", { -- Selected node needs to have 3 nodes of free space above for u=1, 3 do local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z}) - if minetest.registered_nodes[node.name].walkable then + local ndef = minetest.registered_nodes[node.name] + if ndef and ndef.walkable then node_ok = false break end @@ -498,7 +603,8 @@ mobs:register_mob("mobs_mc:enderman", { node_ok = true for u=1, 3 do local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z}) - if minetest.registered_nodes[node.name].walkable then + local ndef = minetest.registered_nodes[node.name] + if ndef and ndef.walkable then node_ok = false break end @@ -531,9 +637,11 @@ mobs:register_mob("mobs_mc:enderman", { --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then -- self:teleport(nil) --else + if pr:next(1, 8) == 8 then --FIXME: real mc rate self:teleport(hitter) - self.attack=hitter - self.state="attack" + end + self.attack=hitter + self.state="attack" --end end end, @@ -544,13 +652,207 @@ mobs:register_mob("mobs_mc:enderman", { attack_type = "dogfight", }) - -- End spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mcl_mobs:spawn_specific( +"mobs_mc:enderman", +"end", +"ground", +{ +"End", +"EndIsland", +"EndMidlands", +"EndBarrens", +"EndBorder", +"EndSmallIslands" +}, +0, +minetest.LIGHT_MAX+1, +30, +3000, +12, +mcl_vars.mg_end_min, +mcl_vars.mg_end_max) -- Overworld spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 19000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:enderman", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +30, +19000, +2, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) + -- Nether spawn (rare) -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 27500, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mcl_mobs:spawn_specific( +"mobs_mc:enderman", +"nether", +"ground", +{ +"Nether", +"SoulsandValley", +}, +0, +11, +30, +27500, +4, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) + +-- Warped Forest spawn (common) +mcl_mobs:spawn_specific( +"mobs_mc:enderman", +"nether", +"ground", +{ +"WarpedForest" +}, +0, +11, +30, +5000, +4, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) -- spawn eggs -mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0) +mcl_mobs.register_egg("mobs_mc:enderman", S("Enderman"), "#252525", "#151515", 0) diff --git a/mods/ENTITIES/mobs_mc/endermite.lua b/mods/ENTITIES/mobs_mc/endermite.lua index da3922a10..7542f267b 100644 --- a/mods/ENTITIES/mobs_mc/endermite.lua +++ b/mods/ENTITIES/mobs_mc/endermite.lua @@ -4,7 +4,8 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:endermite", { +mcl_mobs.register_mob("mobs_mc:endermite", { + description = S("Endermite"), type = "monster", spawn_class = "hostile", passive = false, @@ -37,4 +38,5 @@ mobs:register_mob("mobs_mc:endermite", { reach = 1, }) -mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 0) +mcl_mobs.register_egg("mobs_mc:endermite", S("Endermite"), "#161616", "#6d6d6d", 0) +mcl_mobs:non_spawn_specific("mobs_mc:endermite","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/gameconfig.md b/mods/ENTITIES/mobs_mc/gameconfig.md deleted file mode 100644 index 8394a053c..000000000 --- a/mods/ENTITIES/mobs_mc/gameconfig.md +++ /dev/null @@ -1,59 +0,0 @@ -# Game integration help - -This mod has been designed to make game integration rather easy. Ideally, it should be possible to include this mod verbatim in your game, with modifications only done by an external mod. - -To integrate this mod in a game, you have to do 2 things: Adding the mod, and adding another mod which tells `mobs_mc` which items to use. The idea is that `mobs_mc` should work with any items. Specifically, these are the steps you need to follow: - -* Add the `mobs_mc` mod and its dependencies -* Add a mod with name “`mobs_mc_gameconfig`” -* In this mod, do this: - * Do *not* depend on `mobs_mc` - * Create the table `mobs_mc` - * Create the table `mobs_mc.override` - * In `mobs_mc.override`, create subtables (`items`, `spawn`, etc.) like in `0_gameconfig.lua`, defining the na - * Read `0_gameconfig.lua` to see which items you can override (and more explanations) -* In `on_construct` of a pumpkin or jack'o lantern node, call: - * `mobs_mc.tools.check_iron_golem_summon(pos)` - * `mobs_mc.tools.check_snow_golem_summon(pos)` - * For more information, see `snowman.lua` and `iron_golem.lua` - -Some things to note: - -* Every override is optional, but explicitly setting all the item overrides is strongly recommended -* `mobs_mc` ships many (but not all) items on its own. If not item name override is set, the `mobs_mc` item is used - * You decide whether your game defines its own items, outside of `mobs_mc` or if you let `mobs_mc` do the work. -* Make sure to avoid duplicate items! -* After finishing this, throughly test this -* Without `mobs_mc_gameconfig`, the mod assumes Minetest Game items -* `mobs_mc` optionally depends on `mobs_mc_gameconfig` - -## Example `init.lua` in `mobs_mc_gameconfig` -``` -mobs_mc = {} - -mobs_mc.override = {} - --- Set the item names here -mobs_mc.override.items = { - blaze_rod = "mcl_mobitems:blaze_rod", - blaze_powder = "mcl_mobitems:blaze_powder", - chicken_raw = "mcl_mobitems:chicken", - -- And so on ... -} - --- Set the “follow” field of mobs (used for attracting mob, feeding and breeding) -mobs_mc.override.follow = { - chicken = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", "mcl_farming:pumpkin_seeds", "mcl_farming:beetroot_seeds", }, - horse = { "mcl_core:apple", mobs_mc.override.items.wheat }, -- TODO - pig = { "mcl_farming:potato", mobs_mc.override.items.carrot, mobs_mc.override.items.carrot_on_a_stick}, - -- And so on ... -} - --- Custom spawn nodes -mobs_mc.override.spawn = { - snow = { "example:snow", "example:snow2" }, - -- And so on ... -} - --- Take a look at the other possible tables, see 0_gameconfig.lua -``` diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 679a28c13..1a3d34e1b 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -10,7 +10,8 @@ local S = minetest.get_translator("mobs_mc") --################### -mobs:register_mob("mobs_mc:ghast", { +mcl_mobs.register_mob("mobs_mc:ghast", { + description = S("Ghast"), type = "monster", spawn_class = "hostile", pathfinding = 1, @@ -22,6 +23,7 @@ mobs:register_mob("mobs_mc:ghast", { collisionbox = {-2, 5, -2, 2, 9, 2}, visual = "mesh", mesh = "mobs_mc_ghast.b3d", + spawn_in_group = 1, textures = { {"mobs_mc_ghast.png"}, }, @@ -38,8 +40,8 @@ mobs:register_mob("mobs_mc:ghast", { walk_velocity = 1.6, run_velocity = 3.2, drops = { - {name = mobs_mc.items.gunpowder, chance = 1, min = 0, max = 2, looting = "common"}, - {name = mobs_mc.items.ghast_tear, chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true}, + {name = "mcl_mobitems:gunpowder", chance = 1, min = 0, max = 2, looting = "common"}, + {name = "mcl_mobitems:ghast_tear", chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true}, }, animation = { stand_speed = 50, walk_speed = 50, run_speed = 50, @@ -63,27 +65,63 @@ mobs:register_mob("mobs_mc:ghast", { makes_footstep_sound = false, instant_death = true, fire_resistant = true, + can_spawn = function(pos) + if not minetest.get_item_group(minetest.get_node(pos).name,"solid") then return false end + local p1=vector.offset(pos,-2,1,-2) + local p2=vector.offset(pos,2,5,2) + local nn = minetest.find_nodes_in_area(p1,p2,{"air"}) + if #nn< 41 then return false end + return true + end, + do_custom = function(self) + if self.firing == true then + self.base_texture = {"mobs_mc_ghast_firing.png"} + self.object:set_properties({textures=self.base_texture}) + else + self.base_texture = {"mobs_mc_ghast.png"} + self.object:set_properties({textures=self.base_texture}) + end + end, }) -mobs:spawn_specific("mobs_mc:ghast", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 18000, 2, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mcl_mobs:spawn_specific( +"mobs_mc:ghast", +"nether", +"ground", +{ +"Nether", +"SoulsandValley", +"BasaltDelta", +}, +0, +7, +30, +72000, +2, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) -- fireball (projectile) -mobs:register_arrow("mobs_mc:fireball", { +mcl_mobs.register_arrow("mobs_mc:fireball", { visual = "sprite", visual_size = {x = 1, y = 1}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, + collisionbox = {-.5, -.5, -.5, .5, .5, .5}, + _is_fireball = true, hit_player = function(self, player) - if rawget(_G, "armor") and armor.last_damage_types then - armor.last_damage_types[player:get_player_name()] = "fireball" - end player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, }, nil) - mobs:boom(self, self.object:get_pos(), 1, true) + local p = self.object:get_pos() + if p then + mcl_mobs.mob_class.boom(self,p, 1, true) + else + mcl_mobs.mob_class.boom(self,player:get_pos(), 1, true) + end end, hit_mob = function(self, mob) @@ -91,16 +129,16 @@ mobs:register_arrow("mobs_mc:fireball", { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, }, nil) - mobs:boom(self, self.object:get_pos(), 1, true) + mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1, true) end, hit_node = function(self, pos, node) - mobs:boom(self, pos, 1, true) + mcl_mobs.mob_class.boom(self,pos, 1, true) end }) - +mcl_mobs:non_spawn_specific("mobs_mc:ghast","overworld","0","7") -- spawn eggs -mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0) +mcl_mobs.register_egg("mobs_mc:ghast", S("Ghast"), "#f9f9f9", "#bcbcbc", 0) diff --git a/mods/ENTITIES/mobs_mc/glow_squid.lua b/mods/ENTITIES/mobs_mc/glow_squid.lua new file mode 100644 index 000000000..2d3f19270 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/glow_squid.lua @@ -0,0 +1,246 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +local base_psdef = { + amount = 8, + time=0, + minpos = vector.new(-1,-1,-1), + maxpos = vector.new(1,1,1), + minvel = vector.new(-0.25,-0.25,-0.25), + maxvel = vector.new(0.25,0.25,0.25), + minacc = vector.new(-0.5,-0.5,-0.5), + maxacc = vector.new(0.5,0.5,0.5), + minexptime = 1, + maxexptime = 2, + minsize = 0.8, + maxsize= 1.5, + glow = 5, + collisiondetection = true, + collision_removal = true, +} +local psdefs = {} +for i=1,4 do + local p = table.copy(base_psdef) + p.texture = "mobs_mc_glow_squid_glint"..i..".png" + table.insert(psdefs,p) +end + +mcl_mobs.register_mob("mobs_mc:glow_squid", { + type = "animal", + spawn_class = "water_underground", + can_despawn = true, + passive = true, + hp_min = 10, + hp_max = 10, + xp_min = 1, + xp_max = 3, + armor = 100, + rotate = 0, + -- tilt_swim breaks the animations. + --tilt_swim = true, + -- FIXME: If the qlow squid is near the floor, it turns black + collisionbox = { -0.4, 0.0, -0.4, 0.4, 0.9, 0.4 }, + visual = "mesh", + mesh = "extra_mobs_glow_squid.b3d", + textures = { + { "mobs_mc_glow_squid.png" } + }, + sounds = { + damage = { name = "mobs_mc_squid_hurt", gain = 0.3 }, + death = { name = "mobs_mc_squid_death", gain = 0.4 }, + flop = "mobs_mc_squid_flop", + distance = 16, + }, + animation = { + stand_start = 1, + stand_end = 60, + walk_start = 1, + walk_end = 60, + run_start = 1, + run_end = 60, + }, + drops = { + { name = "mcl_mobitems:glow_ink_sac", + chance = 1, + min = 1, + max = 3, + looting = "common", }, + }, + visual_size = { x = 3, y = 3 }, + makes_footstep_sound = false, + swim = true, + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + fly = true, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, + -- don't add "mcl_core:water_flowing", or it won't move vertically. + + glow = minetest.LIGHT_MAX, + particlespawners = psdefs, +}) + +-- spawning +local water = mobs_mc.water_level - 1 +-- local water = mobs_mc.spawn_height.water + 1 +mcl_mobs:spawn_specific( + "mobs_mc:glow_squid", + "overworld", + "water", + { + "Mesa", + "FlowerForest", + "Swampland", + "Taiga", + "ExtremeHills", + "Jungle", + "Savanna", + "BirchForest", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "Forest", + "Plains", + "Desert", + "ColdTaiga", + "MushroomIsland", + "IcePlainsSpikes", + "SunflowerPlains", + "IcePlains", + "RoofedForest", + "ExtremeHills+_snowtop", + "MesaPlateauFM_grasstop", + "JungleEdgeM", + "ExtremeHillsM", + "JungleM", + "BirchForestM", + "MesaPlateauF", + "MesaPlateauFM", + "MesaPlateauF_grasstop", + "MesaBryce", + "JungleEdge", + "SavannaM", + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore", + "MesaPlateauFM_sandlevel", + "MesaPlateauF_sandlevel", + "MesaBryce_sandlevel", + "Mesa_sandlevel", + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean", + "FlowerForest_underground", + "JungleEdge_underground", + "StoneBeach_underground", + "MesaBryce_underground", + "Mesa_underground", + "RoofedForest_underground", + "Jungle_underground", + "Swampland_underground", + "MushroomIsland_underground", + "BirchForest_underground", + "Plains_underground", + "MesaPlateauF_underground", + "ExtremeHills_underground", + "MegaSpruceTaiga_underground", + "BirchForestM_underground", + "SavannaM_underground", + "MesaPlateauFM_underground", + "Desert_underground", + "Savanna_underground", + "Forest_underground", + "SunflowerPlains_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + }, + 0, + minetest.LIGHT_MAX + 1, + 30, + 10000, + 3, + water - 16, + water) + +-- spawn egg +mcl_mobs.register_egg("mobs_mc:glow_squid", S("Glow Squid"), "#095757", "#87f6c0", 0) diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index 13c857ea3..f2addbfa0 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -4,15 +4,18 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:guardian", { +mcl_mobs.register_mob("mobs_mc:guardian", { + description = S("Guardian"), type = "monster", spawn_class = "hostile", + spawn_in_group_min = 2, + spawn_in_group = 4, hp_min = 30, hp_max = 30, xp_min = 10, xp_max = 10, breath_max = -1, - passive = false, + passive = false, attack_type = "dogfight", pathfinding = 1, view_range = 16, @@ -43,7 +46,7 @@ mobs:register_mob("mobs_mc:guardian", { }, drops = { -- Greatly increased amounts of prismarine - {name = mobs_mc.items.prismarine_shard, + {name = "mcl_ocean:prismarine_shard", chance = 1, min = 0, max = 32, @@ -52,37 +55,37 @@ mobs:register_mob("mobs_mc:guardian", { -- The following drops are approximations -- Fish / prismarine crystal - {name = mobs_mc.items.fish_raw, + {name = "mcl_fishing:fish_raw", chance = 4, min = 1, max = 1, looting = "common",}, - {name = mobs_mc.items.prismarine_crystals, + {name = "mcl_ocean:prismarine_crystals", chance = 4, min = 1, max = 2, looting = "common",}, -- Rare drop: fish - {name = mobs_mc.items.fish_raw, + {name = "mcl_fishing:fish_raw", chance = 160, -- 2.5% / 4 min = 1, max = 1, looting = "rare", looting_factor = 0.0025,}, - {name = mobs_mc.items.salmon_raw, + {name = "mcl_fishing:salmon_raw", chance = 160, min = 1, max = 1, looting = "rare", looting_factor = 0.0025,}, - {name = mobs_mc.items.clownfish_raw, + {name = "mcl_fishing:clownfish_raw", chance = 160, min = 1, max = 1, looting = "rare", looting_factor = 0.0025,}, - {name = mobs_mc.items.pufferfish_raw, + {name = "mcl_fishing:pufferfish_raw", chance = 160, min = 1, max = 1, @@ -91,14 +94,14 @@ mobs:register_mob("mobs_mc:guardian", { }, fly = true, makes_footstep_sound = false, - fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, jump = false, view_range = 16, }) -- Spawning disabled due to size issues -- TODO: Re-enable spawning ---mobs:spawn_specific("mobs_mc:guardian", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water - 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) +mcl_mobs:non_spawn_specific("mobs_mc:guardian","overworld",0,minetest.LIGHT_MAX+1) -- spawn eggs -mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0) +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 a58a4a5b7..094c0513c 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -6,7 +6,8 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:guardian_elder", { +mcl_mobs.register_mob("mobs_mc:guardian_elder", { + description = S("Elder Guardian"), type = "monster", spawn_class = "hostile", hp_min = 80, @@ -48,51 +49,51 @@ mobs:register_mob("mobs_mc:guardian_elder", { -- TODO: Reduce # of drops when ocean monument is ready. -- Greatly increased amounts of prismarine - {name = mobs_mc.items.prismarine_shard, + {name = "mcl_ocean:prismarine_shard", chance = 1, min = 1, max = 64, looting = "common",}, -- TODO: Only drop if killed by player - {name = mobs_mc.items.wet_sponge, + {name = "mcl_sponges:sponge_wet", chance = 1, min = 1, max = 1,}, -- The following drops are approximations -- Fish / prismarine crystal - {name = mobs_mc.items.fish_raw, + {name = "mcl_fishing:fish_raw", chance = 4, min = 1, max = 1, looting = "common",}, - {name = mobs_mc.items.prismarine_crystals, + {name = "mcl_ocean:prismarine_crystals", chance = 1, min = 1, max = 10, looting = "common",}, -- Rare drop: fish - {name = mobs_mc.items.fish_raw, + {name = "mcl_fishing:fish_raw", chance = 160, -- 2.5% / 4 min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 4,}, - {name = mobs_mc.items.salmon_raw, + {name = "mcl_fishing:salmon_raw", chance = 160, min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 4,}, - {name = mobs_mc.items.clownfish_raw, + {name = "mcl_fishing:clownfish_raw", chance = 160, min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 4,}, - {name = mobs_mc.items.pufferfish_raw, + {name = "mcl_fishing:pufferfish_raw", chance = 160, min = 1, max = 1, @@ -101,15 +102,15 @@ mobs:register_mob("mobs_mc:guardian_elder", { }, fly = true, makes_footstep_sound = false, - fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, jump = false, view_range = 16, }) --- Spawning disabled due to size issues +-- Spawning disabled due to size issues <- what do you mean? -j4i -- TODO: Re-enable spawning --- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-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) -- spawn eggs -mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0) - +mcl_mobs.register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "#ceccba", "#747693", 0) +mcl_mobs:non_spawn_specific("mobs_mc:guardian_elder","overworld",0,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua new file mode 100644 index 000000000..8f8590933 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/hoglin+zoglin.lua @@ -0,0 +1,140 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +--################### +--################### hoglin +--################### + +local hoglin = { + description = S("Hoglin"), + type = "monster", + passive = false, + spawn_class = "hostile", + hp_min = 40, + hp_max = 40, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + attack_type = "dogfight", + attack_frequency = 3; + damage = 4, + reach = 1.9, + collisionbox = {-.6, -0.01, -.6, .6, 1.4, .6}, + visual = "mesh", + mesh = "extra_mobs_hoglin.b3d", + textures = { { + "extra_mobs_hoglin.png", + } }, + visual_size = {x=3, y=3}, + sounds = { + random = "extra_mobs_hoglin", + damage = "extra_mobs_hoglin_hurt", + distance = 16, + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 1, + run_velocity = 2.8, + drops = { + {name = "mobs_mcitems:leather", + chance = 1, + min = 0, + max = 1,}, + }, + drops = { + {name = "mcl_mobitems:porkchop", + chance = 1, + min = 2, + max = 4,}, + }, + animation = { + stand_speed = 7, + walk_speed = 7, + run_speed = 15, + stand_start = 24, + stand_end = 24, + walk_start = 11, + walk_end = 21, + run_start = 1, + run_end = 10, + punch_start = 22, + punch_end = 32, + }, + fear_height = 4, + view_range = 16, + floats = 0, + custom_attack = function(self) + if self.state == "attack" and self.reach > vector.distance(self.object:get_pos(), self.attack:get_pos()) then + self.attack:add_velocity({x=0,y=13,z=0}) + self.attack:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = self.damage} + }, nil) + end + end, + do_custom = function(self) + if self.object:get_pos().y > -100 then + local zog = minetest.add_entity(self.object:get_pos(), "mobs_mc:zoglin") + zog:set_rotation(self.object:get_rotation()) + self.object:remove() + end + end, + attack_animals = true, +} + +mcl_mobs.register_mob("mobs_mc:hoglin", hoglin) + +local zoglin = table.copy(hoglin) +zoglin.description = S("Zoglin") +zoglin.fire_resistant = 1 +zoglin.textures = {"extra_mobs_zoglin.png"} +zoglin.do_custom = function() + return +end +zoglin.attacks_monsters = true +zoglin.lava_damage = 0 +zoglin.fire_damage = 0 +mcl_mobs.register_mob("mobs_mc:zoglin", zoglin) + +-- Baby hoglin. + +local baby_hoglin = table.copy(hoglin) +baby_hoglin.description = S("Baby hoglin") +baby_hoglin.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3} +baby_hoglin.xp_min = 20 +baby_hoglin.xp_max = 20 +baby_hoglin.visual_size = {x=hoglin.visual_size.x/2, y=hoglin.visual_size.y/2} +textures = { { + "extra_mobs_hoglin.png", + "extra_mobs_trans.png", +} } +baby_hoglin.walk_velocity = 1.2 +baby_hoglin.run_velocity = 2.4 +baby_hoglin.child = 1 + +mcl_mobs.register_mob("mobs_mc:baby_hoglin", baby_hoglin) + +-- Regular spawning in the Nether +mcl_mobs:spawn_specific( +"mobs_mc:hoglin", +"nether", +"ground", +{ +"CrimsonForest" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) + +mcl_mobs:non_spawn_specific("mobs_mc:hoglin","overworld",0,7) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:hoglin", S("Hoglin"), "#85682e", "#2b2140", 0) diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index b9d82660c..07aa58572 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -34,6 +34,30 @@ local horse_extra_texture = function(horse) return textures end + +local function get_drops(self) + self.drops = {} + table.insert(self.drops, + {name = "mcl_mobitems:leather", + chance = 1, + min = 0, + 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 local can_equip_horse_armor = function(entity_id) return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse" @@ -81,10 +105,27 @@ for b=1, #horse_base do end end +-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems +-- this results in existing horses wearing armor would still have the old texture filename in their +-- properties this function updates them. It should be removed some time in the future when we can be +-- reasonably sure all horses that want it get the new nexture. +local function update_textures(self) + local old = "mobs_mc_horse_armor_" + local txt = self.object:get_properties().textures + if txt[2]:find(old) then + txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_") + self.object:set_properties({textures=txt}) + return + end +end + -- Horse local horse = { + description = S("Horse"), type = "animal", spawn_class = "passive", + spawn_in_group_min = 2, + spawn_in_group = 4, -- was 6. nerfed until group size is a cap rather than per spawn cycle visual = "mesh", mesh = "mobs_mc_horse.b3d", visual_size = {x=3.0, y=3.0}, @@ -113,7 +154,14 @@ local horse = { fly = false, walk_chance = 60, view_range = 16, - follow = mobs_mc.follow.horse, + follow = { + "mcl_core:apple", + "mcl_core:sugar", + "mcl_farming:wheat_item", + "mcl_farming:hay_block", + "mcl_core:apple_gold", + "mcl_farming:carrot_item_gold", + }, passive = true, hp_min = 15, hp_max = 30, @@ -124,15 +172,21 @@ local horse = { jump = true, jump_height = 5.75, -- can clear 2.5 blocks drops = { - {name = mobs_mc.items.leather, + {name = "mcl_mobitems:leather", chance = 1, min = 0, max = 2, looting = "common",}, }, - + on_spawn = update_textures, do_custom = function(self, dtime) + if not self._horse_speed then + self._horse_speed = math.random(486, 1457)/100 + elseif self.run_velocity ~= self._horse_speed then + self.run_velocity = self._horse_speed + end + -- set needed values if not already present if not self._regentimer then self._regentimer = 0 @@ -157,10 +211,31 @@ local horse = { self._regentimer = 0 end - -- if driver present allow control of horse - if self.driver then + -- Some weird human is riding. Buck them off? + if self.driver and not self.tamed and self.buck_off_time <= 0 then + if math.random() < 0.2 then + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + -- TODO bucking animation + else + -- Nah, can't be bothered. Think about it again in one second + self.buck_off_time = 20 + end + end - mobs.drive(self, "walk", "stand", false, dtime) + -- Tick the timer for trying to buck the player off + if self.buck_off_time then + if self.driver then + self.buck_off_time = self.buck_off_time - 1 + else + -- Player isn't riding anymore so no need to count + self.buck_off_time = nil + end + end + + -- if driver present and horse has a saddle allow control of horse + if self.driver and self._saddle then + + mcl_mobs.drive(self, "walk", "stand", false, dtime) return false -- skip rest of mob functions end @@ -172,11 +247,11 @@ local horse = { -- drop saddle when horse is killed while riding if self._saddle then - minetest.add_item(pos, mobs_mc.items.saddle) + minetest.add_item(pos, "mcl_mobitems:saddle") end -- also detach from horse properly if self.driver then - mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) end end, @@ -191,32 +266,97 @@ local horse = { local item = clicker:get_wielded_item() local iname = item:get_name() local heal = 0 - if can_breed(self.name) then - -- Breed horse with golden apple or golden carrot - if (iname == mobs_mc.items.golden_apple) then - heal = 10 - elseif (iname == mobs_mc.items.golden_carrot) then - heal = 4 - end - if heal > 0 and mobs:feed_tame(self, clicker, heal, true, false) then + + if self._inv_id then + if not self._chest and item:get_name() == "mcl_chests:chest" then + item:take_item() + clicker:set_wielded_item(item) + self._chest = true + -- Update texture + if not self._naked_texture then + -- Base horse texture without chest or saddle + self._naked_texture = self.base_texture[2] + end + local tex = horse_extra_texture(self) + self.base_texture = tex + self.object:set_properties({textures = self.base_texture}) + get_drops(self) + return + elseif self._chest and clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker) return end end - -- Feed/tame with anything else - if (iname == mobs_mc.items.sugar) then - heal = 1 - elseif (iname == mobs_mc.items.wheat) then - heal = 2 - elseif (iname == mobs_mc.items.apple) then - heal = 3 - elseif (iname == mobs_mc.items.hay_bale) then - heal = 20 - end - if heal > 0 and mobs:feed_tame(self, clicker, heal, false, true) then + + -- Taming + self.temper = self.temper or (math.random(1,100)) + + if not self.tamed then + local temper_increase = 0 + + -- Feeding, intentionally not using mobs:feed_tame because horse taming is + -- different and more complicated + if (iname == "mcl_core:sugar") then + temper_increase = 3 + elseif (iname == "mcl_farming:wheat_item") then + temper_increase = 3 + elseif (iname == "mcl_core:apple") then + temper_increase = 3 + elseif (iname == "mcl_farming:carrot_item_gold") then + temper_increase = 5 + elseif (iname == "mcl_core:apple_gold") then + temper_increase = 10 + -- Trying to ride + elseif not self.driver then + self.object:set_properties({stepheight = 1.1}) + mcl_mobs.attach(self, clicker) + self.buck_off_time = 40 -- TODO how long does it take in minecraft? + if self.temper > 100 then + self.tamed = true -- NOTE taming can only be finished by riding the horse + if not self.owner or self.owner == "" then + self.owner = clicker:get_player_name() + end + end + temper_increase = 5 + + -- Clicking on the horse while riding ==> unmount + elseif self.driver and self.driver == clicker then + mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1}) + end + + -- If nothing happened temper_increase = 0 and addition does nothing + self.temper = self.temper + temper_increase + return end - if mobs:protect(self, clicker) then + if can_breed(self.name) then + -- Breed horse with golden apple or golden carrot + if (iname == "mcl_core:apple_gold") then + heal = 10 + elseif (iname == "mcl_farming:carrot_item_gold") then + heal = 4 + end + if heal > 0 and self:feed_tame(clicker, heal, true, false) then + return + end + end + -- Feed with anything else + -- TODO heal amounts don't work + if (iname == "mcl_core:sugar") then + heal = 1 + elseif (iname == "mcl_farming:wheat_item") then + heal = 2 + elseif (iname == "mcl_core:apple") then + heal = 3 + elseif (iname == "mcl_farming:hay_block") then + heal = 20 + end + if heal > 0 and self:feed_tame(clicker, heal, false, false) then + return + end + + if mcl_mobs:protect(self, clicker) then return end @@ -228,11 +368,11 @@ local horse = { -- detatch player already riding horse if self.driver and clicker == self.driver then - mobs.detach(clicker, {x = 1, y = 0, z = 1}) + mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1}) -- Put on saddle if tamed elseif not self.driver and not self._saddle - and iname == mobs_mc.items.saddle then + and iname == "mcl_mobitems:saddle" then -- Put on saddle and take saddle from player's inventory local w = clicker:get_wielded_item() @@ -251,6 +391,7 @@ local horse = { self.base_texture = tex self.object:set_properties({textures = self.base_texture}) minetest.sound_play({name = "mcl_armor_equip_leather"}, {gain=0.5, max_hear_distance=12, pos=self.object:get_pos()}, true) + get_drops(self) -- Put on horse armor if tamed elseif can_equip_horse_armor(self.name) and not self.driver and not self._horse_armor @@ -289,18 +430,18 @@ local horse = { elseif not self.driver and self._saddle then self.object:set_properties({stepheight = 1.1}) - mobs.attach(self, clicker) + mcl_mobs.attach(self, clicker) -- Used to capture horse elseif not self.driver and iname ~= "" then - mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end end end, on_breed = function(parent1, parent2) local pos = parent1.object:get_pos() - local child = mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() local p = math.random(1, 2) @@ -349,15 +490,16 @@ local horse = { end, } -mobs:register_mob("mobs_mc:horse", horse) +mcl_mobs.register_mob("mobs_mc:horse", horse) -- Skeleton horse local skeleton_horse = table.copy(horse) +skeleton_horse.description = S("Skeleton Horse") skeleton_horse.breath_max = -1 skeleton_horse.armor = {undead = 100, fleshy = 100} skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}} skeleton_horse.drops = { - {name = mobs_mc.items.bone, + {name = "mcl_mobitems:bone", chance = 1, min = 0, max = 2,}, @@ -371,15 +513,16 @@ skeleton_horse.sounds = { distance = 16, } skeleton_horse.harmed_by_heal = true -mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse) +mcl_mobs.register_mob("mobs_mc:skeleton_horse", skeleton_horse) -- Zombie horse local zombie_horse = table.copy(horse) +zombie_horse.description = S("Zombie Horse") zombie_horse.breath_max = -1 zombie_horse.armor = {undead = 100, fleshy = 100} zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}} zombie_horse.drops = { - {name = mobs_mc.items.rotten_flesh, + {name = "mcl_mobitems:rotten_flesh", chance = 1, min = 0, max = 2,}, @@ -394,12 +537,15 @@ zombie_horse.sounds = { distance = 16, } zombie_horse.harmed_by_heal = true -mobs:register_mob("mobs_mc:zombie_horse", zombie_horse) +mcl_mobs.register_mob("mobs_mc:zombie_horse", zombie_horse) -- Donkey local d = 0.86 -- donkey scale local donkey = table.copy(horse) +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, @@ -424,11 +570,13 @@ donkey.collisionbox = { donkey.jump = true donkey.jump_height = 3.75 -- can clear 1 block height -mobs:register_mob("mobs_mc:donkey", donkey) +mcl_mobs.register_mob("mobs_mc:donkey", donkey) +mcl_entity_invs.register_inv("mobs_mc:donkey","Donkey",15,true) -- Mule local m = 0.94 local mule = table.copy(donkey) +mule.description = S("Mule") mule.textures = {{"blank.png", "mobs_mc_mule.png", "blank.png"}} mule.visual_size = { x=horse.visual_size.x*m, y=horse.visual_size.y*m } mule.sounds = table.copy(donkey.sounds) @@ -441,16 +589,62 @@ mule.collisionbox = { horse.collisionbox[5] * m, horse.collisionbox[6] * m, } -mobs:register_mob("mobs_mc:mule", mule) +mcl_mobs.register_mob("mobs_mc:mule", mule) +mcl_entity_invs.register_inv("mobs_mc:mule","Mule",15,true) --=========================== --Spawn Function -mobs:spawn_specific("mobs_mc:horse", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:horse", +"overworld", +"ground", +{ + "flat", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Savanna", + "Savanna_beach", + "SavannaM", + "Savanna_beach", + "Plains_beach", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.water_level+3, +mcl_vars.mg_overworld_max) + +mcl_mobs:spawn_specific( +"mobs_mc:donkey", +"overworld", +"ground", +{ + "flat", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Savanna", + "Savanna_beach", + "SavannaM", + "Savanna_beach", + "Plains_beach", +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.water_level+3, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) -mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) -mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) -mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) -mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) +mcl_mobs.register_egg("mobs_mc:horse", S("Horse"), "#c09e7d", "#eee500", 0) +mcl_mobs.register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "#68684f", "#e5e5d8", 0) +--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "#2a5a37", "#84d080", 0) +mcl_mobs.register_egg("mobs_mc:donkey", S("Donkey"), "#534539", "#867566", 0) +mcl_mobs.register_egg("mobs_mc:mule", S("Mule"), "#1b0200", "#51331d", 0) +mcl_mobs:non_spawn_specific("mobs_mc:mule","overworld",9,minetest.LIGHT_MAX+1) +mcl_mobs:non_spawn_specific("mobs_mc:skeleton_horse","overworld",9,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/init.lua b/mods/ENTITIES/mobs_mc/init.lua index 58006fe90..483efdcb4 100644 --- a/mods/ENTITIES/mobs_mc/init.lua +++ b/mods/ENTITIES/mobs_mc/init.lua @@ -2,45 +2,101 @@ --maikerumine --made for MC like Survival game --License for code WTFPL and otherwise stated in readmes +mobs_mc = {} -local path = minetest.get_modpath("mobs_mc") +local pr = PseudoRandom(os.time()*5) -if not minetest.get_modpath("mobs_mc_gameconfig") then - mobs_mc = {} +local offsets = {} +for x=-2, 2 do + for z=-2, 2 do + table.insert(offsets, {x=x, y=0, z=z}) + end end --- For utility functions -mobs_mc.tools = {} +--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and +the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1. +Larger mobs might have space problems after teleportation. --- This function checks if the item ID has been overwritten and returns true if it is unchanged -if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override and mobs_mc.override.items then - mobs_mc.is_item_variable_overridden = function(id) - return mobs_mc.override.items[id] == nil +* dist: Minimum required distance from owner to teleport. Default: 12 +* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]] +mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval) + return function(self, dtime) + -- No teleportation if no owner or if sitting + if not self.owner or self.order == "sit" then + return + end + if not teleport_check_interval then + teleport_check_interval = 4 + end + if not dist then + dist = 12 + end + if self._teleport_timer == nil then + self._teleport_timer = teleport_check_interval + return + end + self._teleport_timer = self._teleport_timer - dtime + if self._teleport_timer <= 0 then + self._teleport_timer = teleport_check_interval + local mob_pos = self.object:get_pos() + local owner = minetest.get_player_by_name(self.owner) + if not owner then + -- No owner found, no teleportation + return + end + local owner_pos = owner:get_pos() + local dist_from_owner = vector.distance(owner_pos, mob_pos) + if dist_from_owner > dist then + -- Check for nodes below air in a 5×1×5 area around the owner position + local check_offsets = table.copy(offsets) + -- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node. + while #check_offsets > 0 do + local r = pr:next(1, #check_offsets) + local telepos = vector.add(owner_pos, check_offsets[r]) + local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z} + table.remove(check_offsets, r) + -- Long story short, spawn on a platform + local trynode = minetest.registered_nodes[minetest.get_node(telepos).name] + local trybelownode = minetest.registered_nodes[minetest.get_node(telepos_below).name] + if trynode and not trynode.walkable and + trybelownode and trybelownode.walkable then + -- Correct position found! Let's teleport. + self.object:set_pos(telepos) + return + end + end + end + end end -else - -- No items are overwritten, so always return true - mobs_mc.is_item_variable_overridden = function(id) +end + +local function is_forbidden_node(pos, node) + node = node or minetest.get_node(pos) + return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0 +end + +function mcl_mobs:spawn_abm_check(pos, node, name) + -- Don't spawn monsters on mycelium + if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then return true + --Don't Spawn mobs on stairs, slabs, or carpets + elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then + return true + -- Spawn on opaque or liquid nodes + elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" or node.name == "mcl_core:grass_path" then + return false end + + -- Reject everything else + return true end ---MOB ITEMS SELECTOR SWITCH -dofile(path .. "/0_gameconfig.lua") ---Items -dofile(path .. "/1_items_default.lua") - --- Bow, arrow and throwables -dofile(path .. "/2_throwing.lua") - --- Shared functions -dofile(path .. "/3_shared.lua") - ---Mob heads -dofile(path .. "/4_heads.lua") - -dofile(path .. "/5_spawn_abm_check.lua") +mobs_mc.shears_wear = 276 +mobs_mc.water_level = tonumber(minetest.settings:get("water_level")) or 0 -- Animals +local path = minetest.get_modpath("mobs_mc") +dofile(path .. "/axolotl.lua") -- Mesh and animation by JoeEnderman, Textures by Nova Wustra, modified by JoeEnderman dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S @@ -57,10 +113,9 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd -- NPCs dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i --- Agent texture missing ---dofile(path .. "/agent.lua") -- Mesh and animation by toby109tt / https://github.com/22i -- Illagers and witch +dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i @@ -84,17 +139,20 @@ dofile(path .. "/silverfish.lua") -- maikerumine Mesh and animation by toby109tt 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 .. "/zombie.lua") -- Mesh by Morn76 Animation by Pavel_S -dofile(path .. "/zombiepig.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) dofile(path .. "/vex.lua") -- KrupnoPavel dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i ---NOTES: --- ---[[ -COLISIONBOX in minetest press f5 to see where you are looking at then put these wool collor nodes on the ground in direction of north/east/west... to make colisionbox editing easier -#1west-pink/#2down/#3south-blue/#4east-red/#5up/#6north-yelow -{-1, -0.5, -1, 1, 3, 1}, Right, Bottom, Back, Left, Top, Front ---]] --- --- + +dofile(path .. "/cod.lua") +dofile(path .. "/salmon.lua") +dofile(path .. "/tropical_fish.lua") +dofile(path .. "/dolphin.lua") + + +dofile(path .. "/glow_squid.lua") + +dofile(path .. "/piglin.lua") -- "mobs_mc_zombie_pigman.b3d" Mesh by Morn76 Animation by Pavel_S +dofile(path .. "/hoglin+zoglin.lua") + +dofile(path .. "/strider.lua") diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 2ccee2d0a..6b428c6f8 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -9,18 +9,22 @@ local S = minetest.get_translator("mobs_mc") --################### IRON GOLEM --################### +local etime = 0 - -mobs:register_mob("mobs_mc:iron_golem", { +mcl_mobs.register_mob("mobs_mc:iron_golem", { + description = S("Iron Golem"), type = "npc", spawn_class = "passive", - passive = true, + passive = false, hp_min = 100, hp_max = 100, breath_max = -1, collisionbox = {-0.7, -0.01, -0.7, 0.7, 2.69, 0.7}, visual = "mesh", mesh = "mobs_mc_iron_golem.b3d", + head_swivel = "head.control", + bone_eye_height = 3.38, + curiosity = 10, textures = { {"mobs_mc_iron_golem.png"}, }, @@ -36,16 +40,38 @@ mobs:register_mob("mobs_mc:iron_golem", { run_velocity = 1.2, -- Approximation damage = 14, + knock_back = false, reach = 3, - group_attack = true, + group_attack = { "mobs_mc:villager" }, attacks_monsters = true, attack_type = "dogfight", + _got_poppy = false, + pick_up = {"mcl_flowers:poppy"}, + on_pick_up = function(self,n) + local it = ItemStack(n.itemstring) + if it:get_name() == "mcl_flowers:poppy" then + if not self._got_poppy then + self._got_poppy=true + it:take_item(1) + end + end + return it + end, + replace_what = {"mcl_flowers:poppy"}, + replace_with = {"air"}, + on_replace = function(self, pos, oldnode, newnode) + if not self.got_poppy and oldnode.name == "mcl_flowers:poppy" then + self._got_poppy=true + return + end + return false + end, drops = { - {name = mobs_mc.items.iron_ingot, + {name = "mcl_core:iron_ingot", chance = 1, min = 3, max = 5,}, - {name = mobs_mc.items.poppy, + {name = "mcl_flowers:poppy", chance = 1, min = 0, max = 2,}, @@ -59,12 +85,19 @@ 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) + end + end + end, }) -- spawn eggs -mobs:register_egg("mobs_mc:iron_golem", S("Iron Golem"), "mobs_mc_spawn_icon_iron_golem.png", 0) - +mcl_mobs.register_egg("mobs_mc:iron_golem", S("Iron Golem"), "#3b3b3b", "#f57223", 0) --[[ This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function of the node. This summons an iron golen if placing the pumpkin created an iron golem summon pattern: @@ -78,7 +111,7 @@ I = Iron block . = Air ]] -mobs_mc.tools.check_iron_golem_summon = function(pos) +function mobs_mc.check_iron_golem_summon(pos) local checks = { -- These are the possible placement patterns, with offset from the pumpkin block. -- These tables include the positions of the iron blocks (1-4) and air blocks (5-8) @@ -136,7 +169,7 @@ mobs_mc.tools.check_iron_golem_summon = function(pos) for i=1, 4 do local cpos = vector.add(pos, checks[c][i]) local node = minetest.get_node(cpos) - if node.name ~= mobs_mc.items.iron_block then + if node.name ~= "mcl_core:ironblock" then ok = false break end @@ -173,3 +206,4 @@ mobs_mc.tools.check_iron_golem_summon = function(pos) end end end +mcl_mobs:non_spawn_specific("mobs_mc:iron_golem","overworld",0,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 36d020a65..32bfc97ea 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -24,14 +24,52 @@ local carpets = { unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" }, } -mobs:register_mob("mobs_mc:llama", { +local function get_drops(self) + self.drops = {} + table.insert(self.drops, + {name = "mcl_mobitems:leather", + chance = 1, + min = 0, + max = 2, + looting = "common", + }) + if self.carpet then + table.insert(self.drops,{name = self.carpet, + chance = 1, + min = 1, + max = 1,}) + end + if self._has_chest then + table.insert(self.drops,{name = "mcl_chests:chest", + chance = 1, + min = 1, + max = 1,}) + end +end + +mcl_mobs.register_mob("mobs_mc:llama", { + description = S("Llama"), type = "animal", spawn_class = "passive", + passive = false, + attack_type = "shoot", + shoot_interval = 5.5, + arrow = "mobs_mc:llamaspit", + shoot_offset = 1, --3.5 *would* be a good value visually but it somehow messes with the projectiles trajectory + spawn_in_group_min = 2, -- was 4 + spawn_in_group = 4, -- was 6 nerfed until we can cap them properly locally. this is a group size, not a per spawn attempt + + head_swivel = "head.control", + bone_eye_height = 11, + head_eye_height = 3, + horrizonatal_head_height=0, + curiosity = 60, + head_yaw = "z", + hp_min = 15, hp_max = 30, xp_min = 1, xp_max = 3, - passive = false, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.86, 0.45}, visual = "mesh", mesh = "mobs_mc_llama.b3d", @@ -41,17 +79,15 @@ mobs:register_mob("mobs_mc:llama", { {"blank.png", "blank.png", "mobs_mc_llama_gray.png"}, {"blank.png", "blank.png", "mobs_mc_llama_white.png"}, {"blank.png", "blank.png", "mobs_mc_llama.png"}, - -- TODO: Add llama carpet textures (Pixel Perfection seems to use verbatim copy from Minecraft :-( ) }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, - runaway = true, + runaway = false, walk_velocity = 1, run_velocity = 4.4, follow_velocity = 4.4, floats = 1, drops = { - {name = mobs_mc.items.leather, + {name = "mcl_mobitems:leather", chance = 1, min = 0, max = 2, @@ -65,43 +101,35 @@ mobs:register_mob("mobs_mc:llama", { distance = 16, }, animation = { - speed_normal = 24, - run_speed = 60, - run_start = 0, - run_end = 40, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - hurt_start = 118, - hurt_end = 154, - death_start = 154, - death_end = 179, - eat_start = 49, - eat_end = 78, - look_start = 78, - look_end = 108, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 35, + run_start = 0, run_end = 40, run_speed = 50, }, - follow = mobs_mc.follow.llama, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 50, + run_start = 41, run_end = 81, run_speed = 75, + }, + follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" }, view_range = 16, do_custom = function(self, dtime) -- set needed values if not already present - if not self.v2 then - self.v2 = 0 + if not self.v3 then + self.v3 = 0 self.max_speed_forward = 4 self.max_speed_reverse = 2 self.accel = 4 self.terrain_type = 3 - self.driver_attach_at = {x = 0, y = 4.17, z = -1.5} - self.driver_eye_offset = {x = 0, y = 3, z = 0} + self.driver_attach_at = {x = 0, y = 12.7, z = -5} + self.driver_eye_offset = {x = 0, y = 6, z = 0} self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} end -- if driver present allow control of llama if self.driver then - mobs.drive(self, "walk", "stand", false, dtime) + mcl_mobs.drive(self, "walk", "stand", false, dtime) return false -- skip rest of mob functions end @@ -113,7 +141,7 @@ mobs:register_mob("mobs_mc:llama", { -- detach from llama properly if self.driver then - mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) end end, @@ -126,20 +154,32 @@ mobs:register_mob("mobs_mc:llama", { end local item = clicker:get_wielded_item() - if item:get_name() == mobs_mc.items.hay_bale then + if item:get_name() == "mcl_farming:hay_block" then -- Breed with hay bale - if mobs:feed_tame(self, clicker, 1, true, false) then return end + if self:feed_tame(clicker, 1, true, false) then return end + elseif not self._has_chest and item:get_name() == "mcl_chests:chest" then + item:take_item() + clicker:set_wielded_item(item) + self._has_chest = true + self.base_texture = table.copy(self.base_texture) + self.base_texture[1] = self.base_texture[3] + self.object:set_properties({ + textures = self.base_texture, + }) + get_drops(self) + return + elseif self._has_chest and clicker:get_player_control().sneak then + mcl_entity_invs.show_inv_form(self,clicker," - Strength "..math.floor(self._inv_size / 3)) + return else -- Feed with anything else - if mobs:feed_tame(self, clicker, 1, false, true) then return end + if self:feed_tame(clicker, 1, false, true) then return end end - if mobs:protect(self, clicker) then return end + if mcl_mobs:protect(self, clicker) then return end -- Make sure tamed llama is mature and being clicked by owner only if self.tamed and not self.child and self.owner == clicker:get_player_name() then - -- Place carpet - --[[ TODO: Re-enable this code when carpet textures arrived. if minetest.get_item_group(item:get_name(), "carpet") == 1 and not self.carpet then for group, carpetdata in pairs(carpets) do if minetest.get_item_group(item:get_name(), group) == 1 then @@ -155,42 +195,23 @@ mobs:register_mob("mobs_mc:llama", { textures = self.base_texture, }) self.carpet = item:get_name() - self.drops = { - {name = mobs_mc.items.leather, - chance = 1, - min = 0, - max = 2,}, - {name = item:get_name(), - chance = 1, - min = 1, - max = 1,}, - } + get_drops(self) return end end end - ]] -- detatch player already riding llama if self.driver and clicker == self.driver then - - mobs.detach(clicker, {x = 1, y = 0, z = 1}) - + mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1}) -- attach player to llama elseif not self.driver then - self.object:set_properties({stepheight = 1.1}) - mobs.attach(self, clicker) + mcl_mobs.attach(self, clicker) end - - -- Used to capture llama - elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then - mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end end, - --[[ - TODO: Enable this code when carpet textures arrived. on_breed = function(parent1, parent2) -- When breeding, make sure the child has no carpet local pos = parent1.object:get_pos() @@ -200,7 +221,7 @@ mobs:register_mob("mobs_mc:llama", { else parent = parent2 end - child = mobs:spawn_child(pos, parent.name) + child = mcl_mobs.spawn_child(pos, parent.name) if child then local ent_c = child:get_luaentity() ent_c.base_texture = table.copy(ent_c.base_texture) @@ -212,12 +233,68 @@ mobs:register_mob("mobs_mc:llama", { return false end end, - ]] + on_spawn = function(self) + if not self._inv_size then + local r = math.random(1000) + if r < 80 then + self._inv_size = 15 + elseif r < 160 then + self._inv_size = 12 + elseif r < 488 then + self._inv_size = 9 + elseif r < 816 then + self._inv_size = 6 + else + self._inv_size = 3 + end + end + end, +}) +mcl_entity_invs.register_inv("mobs_mc:llama","Llama",nil,true) + +-- spit arrow (weapon) +mcl_mobs.register_arrow("mobs_mc:llamaspit", { + visual = "sprite", + visual_size = {x = 0.10, y = 0.10}, + textures = {"mobs_mc_llama_spit.png"}, + velocity = 5, + hit_player = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_mob = function(self, mob) + end, + + hit_node = function(self, pos, node) + end }) --spawn -mobs:spawn_specific("mobs_mc:llama", mobs_mc.spawn.savanna, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 5, mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:llama", +"overworld", +"ground", +{ + "Savanna", + "SavannaM", + "SavannaM_beach", + "Savanna_beach", + "Savanna_ocean", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", +}, --FIXME: Needs Windswept Forest when that is added. +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.water_level+15, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0) +mcl_mobs.register_egg("mobs_mc:llama", S("Llama"), "#c09e7d", "#995f40", 0) diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr index 24d3fa324..84aade90e 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr @@ -1,7 +1,4 @@ # textdomain: mobs_mc -Totem of Undying=Totem der Unsterblichkeit -A totem of undying is a rare artifact which may safe you from certain death.=Ein Totem der Unsterblichkeit ist ein seltenes Artefakt, dass Sie vor dem sicheren Tod bewahren kann. -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.=Der Totem funktioniert nur, während Sie ihn halten. Wenn Sie normalerweise tödlich hohen Schaden erhalten, werden Sie vor dem Tod bewahrt und Sie erhalten eine zweite Chance mit 1 TP. Der Totem wird dabei zerstört. Agent=Akteur Bat=Fledermaus Blaze=Lohe @@ -51,14 +48,7 @@ Wither=Wither Wolf=Wolf Husk=Wüstenzombie Zombie=Zombie -Zombie Pigman=Schweinezombie -Iron Horse Armor=Eisenpferderüstung -Iron horse armor can be worn by horses to increase their protection from harm a bit.=Eine Eisenpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden etwas zu erhöhen. -Golden Horse Armor=Goldpferderüstung -Golden horse armor can be worn by horses to increase their protection from harm.=Eine Goldpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden zu erhöhen. -Diamond Horse Armor=Diamantpferderüstung -Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Eine Diamantpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden beträchtlich zu erhöhen. -Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Platzieren Sie es auf einem Pferd, um die Pferderüstung aufzusetzen. Esel und Maultiere können keine Pferderüstung tragen. +Zombie Piglin=Schweinezombie Farmer=Bauer Fisherman=Fischer Fletcher=Pfeilmacher @@ -72,4 +62,3 @@ Weapon Smith=Waffenschmied Tool Smith=Werkzeugschmied Cleric=Priester Nitwit=Dorftrottel -Protects you from death while wielding it=Schützt vor dem Tod, wenn es gehalten wird diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr new file mode 100644 index 000000000..5df92f2f8 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.dk.tr @@ -0,0 +1,70 @@ +# textdomain: mobs_mc +Agent=Agent +Axolotl=Salamander +Bat=Flagermus +Blaze=Blaze +Chicken=Kylling +Cow=Ko +Mooshroom=Svamp +Creeper=Creeper +Ender Dragon=Enderdrage +Enderman=Enderman +Endermite=Endermide +Ghast=Ghast +Elder Guardian=Gammel beskytter +Guardian=Beskytter +Horse=Hest +Skeleton Horse=Skelethest +Zombie Horse=Zombiehest +Donkey=Æsel +Mule=Muldyr +Iron Golem=Jerngolem +Llama=Lama +Ocelot=Ozelot +Parrot=Papegøje +Pig=Gris +Polar Bear=Isbjørn +Rabbit=Kanin +Killer Bunny=Dræberkanin +Sheep=Får +Shulker=Shulker +Silverfish=Sølvfisk +Skeleton=Skelet +Stray=Omstrejfer +Wither Skeleton=Wither-skelet +Magma Cube=Magmakube +Slime=Slimklump +Snow Golem=Snegolem +Spider=Edderkop +Cave Spider=Huleedderkop +Squid=Blæksprutte +Vex=Vex +Evoker=Fremkalder +Illusioner=Illusionist +Villager=Landsbyboer +Vindicator=Hævner +Zombie Villager=Zombie landsbyboer +Witch=Heks +Wither=Wither +Wolf=Ulv +Husk=Udtørretskal +Zombie=Zombie +Zombie Pigman=Zombificeret piglin +Farmer=Landmand +Fisherman=Fisker +Fletcher=Pilemager +Shepherd=Fårehyrde +Librarian=Bibliotikar +Cartographer=Kartograf +Armorer=Rustningesmed +Leatherworker=Læderarbejder +Butcher=Slagter +Weapon Smith=Våbensmed +Tool Smith=Værktøjssmed +Cleric=Gejstlig +Nitwit=Tåbe +Cod=Torsk +Salmon=Laks +Dolphin=Delfin +Pillager=Plyndrer +Tropical fish=Tropisk fisk \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr index 240e7759f..47e19cc42 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr @@ -1,74 +1,74 @@ # textdomain: mobs_mc -Totem of Undying=Tótem de la inmortalidad -A totem of undying is a rare artifact which may safe you from certain death.=Un tótem de la inmortalidad es un artefacto raro que puede salvarte de una muerte segura. -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.=El tótem solo funciona mientras lo sostienes en tu mano. Si recibes un daño crítico, no mueres y obtienes una segunda oportunidad con 1 HP. Sin embargo, el tótem se destruye en el proceso. -Agent=Agente Bat=Murciélago Blaze=Blaze Chicken=Pollo +Cod=Bacalao Cow=Vaca -Mooshroom=Champiñaca +Mooshroom=Champivaca Creeper=Creeper -Ender Dragon=Enderdragón +Dolphin=Delfín +Ender Dragon=Ender Dragon Enderman=Enderman Endermite=Endermite Ghast=Ghast -Elder Guardian=Gran guardián Guardian=Guardián -Horse=Caballo -Skeleton Horse=Caballo esquelético -Zombie Horse=Caballo zombie +Elder Guardian=Guardián Anciano Donkey=Burro +Horse=Caballo Mule=Mula +Skeleton Horse=Caballo esqueleto +Zombie Horse=Caballo zombi Iron Golem=Golem de hierro Llama=Llama +Cat=Gato Ocelot=Ocelote Parrot=Loro Pig=Cerdo Polar Bear=Oso polar -Rabbit=Conejo Killer Bunny=Conejo asesino +Rabbit=Conejo +Salmon=Salmón Sheep=Oveja Shulker=Shulker Silverfish=Lepisma Skeleton=Esqueleto -Stray=Esqueleto -Wither Skeleton=Esqueleto wither +Stray=Esqueleto glacial +Wither Skeleton=Esqueleto del Wither Magma Cube=Cubo de Magma Slime=Slime Snow Golem=Golem de nieve -Spider=Araña Cave Spider=Araña de las cuevas +Spider=Araña Squid=Calamar Vex=Ánima +Master=Maestro +Villager=Aldeano Evoker=Invocador Illusioner=Illusionista -Villager=Aldeano Vindicator=Vindicador -Zombie Villager=Aldeano zombie +Zombie Villager=Aldeano zombi Witch=Bruja Wither=Wither Wolf=Lobo -Husk=Husk -Zombie=Zombie -Zombie Pigman=Cerdo Zombie -Iron Horse Armor=Armadura de hierro para caballo -Iron horse armor can be worn by horses to increase their protection from harm a bit.=Los caballos pueden usar armadura de caballo de hierro para aumentar un poco su protección contra el daño. -Golden Horse Armor=Armadura de oro para caballo -Golden horse armor can be worn by horses to increase their protection from harm.=Los caballos pueden usar armadura de caballo de oro para aumentar su protección contra el daño. -Diamond Horse Armor=Armadura de diamante para caballo -Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Los caballos pueden usar armadura de caballo de diamante para aumentar en gran medida su protección contra el daño. -Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Colóquelo en un caballo para ponerle la armadura de caballo. Los burros y las mulas no pueden usar armadura de caballo. -Farmer=Granjero -Fisherman=Pescador -Fletcher=Flechador -Shepherd=Sacerdote -Librarian=Bibliotecario +Baby Husk=Bebé Zombi Momificado +Baby Zombie=Bebé Zombi +Husk=Zombi Momificado +Zombie=Zombi +Baby Zombie Piglin=Bebé Hombrecerdo Zombi +Zombie Piglin=Hombrecerdo Zombi Cartographer=Cartógrafo -Armorer=Armero +Armorer=Escudero Leatherworker=Peletero Butcher=Carnicero -Weapon Smith=Herrero de Armas -Tool Smith=Herrero de Herramientas -Cleric=Sacerdote -Nitwit=Simple +Weapon Smith=Armero +Tool Smith=Herrero +Cleric=Clérigo +Nitwit=Holgazán +Cod=Bacalao +Salmon=Salmón +Dolphin=Delfín +Pillager=Saqueador +Tropical fish=Pez tropical +Hoglin=Hoglin +Strider=Lavagante +Glow Squid=Calamar luminoso diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr index ff1e2b9c0..81c93a33b 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr @@ -1,8 +1,6 @@ # textdomain: mobs_mc -Totem of Undying=Totem d'immortalité -A totem of undying is a rare artifact which may safe you from certain death.=Un totem d'immortalité est un artefact rare qui peut vous protéger d'une mort certaine. -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.=Le totem ne fonctionne que lorsque vous le tenez dans votre main. Si vous recevez des dégâts mortels, vous êtes sauvé de la mort et vous obtenez une seconde chance avec 1 HP. Cependant, le totem est détruit. Agent=Agent +Axolotl=Axolotl Bat=Chauve-souris Blaze=Blaze Chicken=Poulet @@ -51,14 +49,7 @@ Wither=Wither Wolf=Loup Husk=Zombie Momifié Zombie=Zombie -Zombie Pigman=Zombie Cochon -Iron Horse Armor=Armure de cheval en fer -Iron horse armor can be worn by horses to increase their protection from harm a bit.=L'armure de cheval en fer peut être portée par les chevaux pour augmenter un peu leur protection contre les dommages. -Golden Horse Armor=Armure de cheval en or -Golden horse armor can be worn by horses to increase their protection from harm.=Une armure de cheval en or peut être portée par les chevaux pour augmenter leur protection contre les dommages. -Diamond Horse Armor=Armure de cheval en diamant -Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Une armure de cheval en diament peut être portée par les chevaux pour augmenter fortement leur protection contre les dommages. -Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Placez-la sur un cheval pour mettre l'armure de cheval. Les ânes et les mules ne peuvent pas porter d'armure de cheval. +Zombie Piglin=Zombie Cochon Farmer=Fermier Fisherman=Pêcheur Fletcher=Archer @@ -72,4 +63,11 @@ Weapon Smith=Fabriquant d'arme Tool Smith=Fabriquant d'outil Cleric=Clerc Nitwit=Crétin -Protects you from death while wielding it=Vous protège de la mort en la maniant +Cod=Morue +Salmon=Saumon +Dolphin=Dauphin +Pillager=Pilleur +Tropical fish=Poisson tropical +Hoglin=Hoglin +Strider=Arpenteur +Glow Squid=Poulpe Brillant \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr new file mode 100644 index 000000000..63d73e222 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ja.tr @@ -0,0 +1,70 @@ +# textdomain: mobs_mc +Agent=エージェント +Axolotl=ウーパールーパー +Bat=コウモリ +Blaze=ブレイズ +Chicken=ニワトリ +Cow=ウシ +Mooshroom=ムーシュルーム +Creeper=クリーパー +Ender Dragon=エンダードラゴン +Enderman=エンダーマン +Endermite=エンダーマイト +Ghast=ガスト +Elder Guardian=エルダーガーディアン +Guardian=ガーディアン +Horse=ウマ +Skeleton Horse=スケルトンホース +Zombie Horse=ゾンビホース +Donkey=ロバ +Mule=ラバ +Iron Golem=アイアンゴーレム +Llama=ラマ +Ocelot=ヤマネコ +Parrot=オウム +Pig=ブタ +Polar Bear=シロクマ +Rabbit=ウサギ +Killer Bunny=殺人ウサギ +Sheep=ヒツジ +Shulker=シュルカー +Silverfish=シルバーフィッシュ +Skeleton=スケルトン +Stray=ストレイ +Wither Skeleton=ウィザースケルトン +Magma Cube=マグマキューブ +Slime=スライム +Snow Golem=スノーゴーレム +Spider=クモ +Cave Spider=洞窟グモ +Squid=イカ +Vex=ヴェックス +Evoker=エヴォーカー +Illusioner=イリュージョナー +Villager=村人 +Vindicator=ヴィンディケーター +Zombie Villager=村人ゾンビ +Witch=魔女 +Wither=ウィザー +Wolf=オオカミ +Husk=ハスク +Zombie=ゾンビ +Zombie Piglin=ゾンビピッグマン +Farmer=農民 +Fisherman=漁師 +Fletcher=矢師 +Shepherd=羊飼い +Librarian=司書 +Cartographer=製図家 +Armorer=防具鍛冶 +Leatherworker=革職人 +Butcher=肉屋 +Weapon Smith=武器鍛冶 +Tool Smith=道具鍛冶 +Cleric=聖職者 +Nitwit=求職者 +Cod=タラ +Salmon=サケ +Dolphin=イルカ +Pillager=ピリジャー +Tropical fish=クマノミ \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr index 73807c001..62fe69a97 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr @@ -1,7 +1,4 @@ # textdomain: mobs_mc -Totem of Undying=Тотем бессмертия -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. Однако тотем при этом уничтожается. Agent=Агент Bat=Летучая мышь Blaze=Ифрит @@ -52,13 +49,6 @@ Wolf=Волк Husk=Кадавр Zombie=Зомби Zombie Pigman=Зомби-свиночеловек -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.=Поместите это на лошадь, чтобы одеть лошадь в доспехи. Ослики и мулы не могут носить лошадиные доспехи. Farmer=Фермер Fisherman=Рыбак Fletcher=Лучник @@ -72,4 +62,3 @@ Weapon Smith=Оружейник Tool Smith=Инструментальщик Cleric=Церковник Nitwit=Нищий -Protects you from death while wielding it=Защищает вас от смерти, пока вы владеете им diff --git a/mods/ENTITIES/mobs_mc/locale/template.txt b/mods/ENTITIES/mobs_mc/locale/template.txt index 04ba9e465..589a1a3c4 100644 --- a/mods/ENTITIES/mobs_mc/locale/template.txt +++ b/mods/ENTITIES/mobs_mc/locale/template.txt @@ -1,8 +1,6 @@ # textdomain: mobs_mc -Totem of Undying= -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.= Agent= +Axolotl= Bat= Blaze= Chicken= @@ -51,14 +49,12 @@ Wither= Wolf= Husk= Zombie= -Zombie Pigman= -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.= +Piglin= +Baby Piglin= +Zombie Piglin= +Baby Zombie Piglin= +Sword Piglin= +Piglin Brute= Farmer= Fisherman= Fletcher= @@ -72,4 +68,11 @@ Weapon Smith= Tool Smith= Cleric= Nitwit= -Protects you from death while wielding it= +Cod= +Salmon= +Dolphin= +Pillager= +Tropical fish= +Hoglin= +Strider= +Glow Squid= \ No newline at end of file diff --git a/mods/ENTITIES/mobs_mc/mod.conf b/mods/ENTITIES/mobs_mc/mod.conf index cd4f98c75..5b94879b2 100644 --- a/mods/ENTITIES/mobs_mc/mod.conf +++ b/mods/ENTITIES/mobs_mc/mod.conf @@ -1 +1,5 @@ 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 diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d new file mode 100644 index 000000000..c7e60e12c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_cod.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d new file mode 100644 index 000000000..37e2e96ae Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_dolphin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d new file mode 100644 index 000000000..887576b28 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_glow_squid.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d new file mode 100644 index 000000000..d3886e089 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_hoglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d new file mode 100644 index 000000000..e07bd15aa Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_piglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d new file mode 100644 index 000000000..50180af95 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_salmon.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d new file mode 100644 index 000000000..72f4e254e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_strider.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d new file mode 100644 index 000000000..1988f4082 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_sword_piglin.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d new file mode 100644 index 000000000..2131319fa Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_a.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d new file mode 100644 index 000000000..b97bfb228 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/extra_mobs_tropical_fish_b.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d deleted file mode 100644 index 3e79c009b..000000000 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_agent.b3d and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d new file mode 100644 index 000000000..3e4c8119e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_axolotl.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d index 2328c8a64..7593baa2f 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_blaze.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d index 9ab4fc10c..84cc91652 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_cat.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d index 6d839a459..623a467b9 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_chicken.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d index 2f13ba9c4..f29c6a961 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_cow.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d index bfeb5a6b6..72887d8d4 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_creeper.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d index 6e1017e0c..4a429f7c3 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_evoker.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d index 7bb719ffb..6bdcbf339 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_illusioner.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d index a7fbd352b..db87e6540 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_iron_golem.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d index 5d6dd6b37..8e1da8b24 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_llama.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d deleted file mode 100644 index 725268ea9..000000000 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_mooshroom.b3d and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d index 7cb326d3d..2f59c313b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_parrot.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d index 8ba5b6a84..4bbaf6e23 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pig.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d new file mode 100644 index 000000000..18c1a06c4 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend new file mode 100644 index 000000000..e0524ab74 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/models/mobs_mc_pillager.blend differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d index bb64b2b79..cbda1f8c9 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_polarbear.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d index ad2067d7b..d28aa5368 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_rabbit.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d index 1db15ddba..31044fbaf 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_sheepfur.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d index be4094c1b..f5e8d4917 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_skeleton.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_slime.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_slime.b3d index 18cc3d629..b426ee23d 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_slime.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_slime.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d index aec461a6b..0d71f6377 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_spider.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d index 1b92adfa5..1d46a162b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d index 9958b281a..a45eac602 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_villager_zombie.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d index ae14e8edb..d220e895c 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_vindicator.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d index 6f78392fe..ec2952cf5 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_witherskeleton.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d index 63db5e097..82684e303 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_wolf.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d index f357f68b5..1da2bc66b 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie.b3d differ diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d index 0b9f4f7c9..0f1d6ea24 100644 Binary files a/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d and b/mods/ENTITIES/mobs_mc/models/mobs_mc_zombie_pigman.b3d differ diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index eca74d3ba..65181a581 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -13,32 +13,39 @@ local pr = PseudoRandom(os.time()*12) local default_walk_chance = 70 --- Returns true if the item is food (taming) for the cat/ocelot -local is_food = function(itemstring) - for f=1, #mobs_mc.follow.ocelot do - if itemstring == mobs_mc.follow.ocelot[f] then - return true - elseif string.sub(itemstring, 1, 6) == "group:" and minetest.get_item_group(itemstring, string.sub(itemstring, 7, -1)) ~= 0 then - return true - end - end - return false +local follow = { + "mcl_fishing:fish_raw", + "mcl_fishing:salmon_raw", + "mcl_fishing:clownfish_raw", + "mcl_fishing:pufferfish_raw", +} + +local function is_food(itemstring) + return table.indexof(follow, itemstring) ~= -1 end -- Ocelot local ocelot = { + description = S("Ocelot"), type = "animal", spawn_class = "passive", can_despawn = true, + spawn_in_group = 3, + spawn_in_group_min = 1, hp_min = 10, hp_max = 10, xp_min = 1, xp_max = 3, + head_swivel = "head.control", + bone_eye_height = 6.2, + head_eye_height = 0.4, + horrizonatal_head_height=-0, + head_yaw="z", + curiosity = 4, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.69, 0.3}, visual = "mesh", mesh = "mobs_mc_cat.b3d", textures = {"mobs_mc_cat_ocelot.png"}, - visual_size = {x=2.0, y=2.0}, makes_footstep_sound = true, walk_chance = default_walk_chance, walk_velocity = 1, @@ -55,16 +62,18 @@ local ocelot = { distance = 16, }, animation = { - speed_normal = 25, - run_speed = 50, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 40, + run_start = 0, run_end = 40, run_speed = 50, + sit_start = 50, sit_end = 50, }, - follow = mobs_mc.follow.ocelot, + child_animations = { + stand_start = 51, stand_end = 51, + walk_start = 51, walk_end = 91, walk_speed = 60, + run_start = 51, run_end = 91, run_speed = 75, + sit_start = 101, sit_end = 101, + }, + follow = follow, view_range = 12, passive = true, attack_type = "dogfight", @@ -98,10 +107,11 @@ local ocelot = { end, } -mobs:register_mob("mobs_mc:ocelot", ocelot) +mcl_mobs.register_mob("mobs_mc:ocelot", ocelot) -- Cat local cat = table.copy(ocelot) +cat.description = S("Cat") cat.textures = {{"mobs_mc_cat_black.png"}, {"mobs_mc_cat_red.png"}, {"mobs_mc_cat_siamese.png"}} cat.can_despawn = false cat.owner = "" @@ -120,9 +130,9 @@ cat.sounds = { distance = 16, } cat.on_rightclick = function(self, clicker) - if mobs:feed_tame(self, clicker, 1, true, false) then return end - if mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end - if mobs:protect(self, clicker) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end + if mcl_mobs:protect(self, clicker) then return end if self.child then return end @@ -147,24 +157,53 @@ cat.on_rightclick = function(self, clicker) end -mobs:register_mob("mobs_mc:cat", cat) +cat.on_spawn = function(self) + if self.owner == "!witch!" then + self._texture = {"mobs_mc_cat_black.png"} + end + if not self._texture then + self._texture = cat.textures[math.random(#cat.textures)] + end + self.object:set_properties({textures = self._texture}) +end + +mcl_mobs.register_mob("mobs_mc:cat", cat) local base_spawn_chance = 5000 -- Spawn ocelot +--they get the same as the llama because I'm trying to rework so much of this code right now -j4i +mcl_mobs:spawn_specific( +"mobs_mc:ocelot", +"overworld", +"ground", +{ +"Jungle", +"JungleEdgeM", +"JungleM", +"JungleEdge", +}, +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.water_level+15, +mcl_vars.mg_overworld_max) +--[[ mobs:spawn({ name = "mobs_mc:ocelot", - nodes = mobs_mc.spawn.jungle, + nodes = { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" }, neighbors = {"air"}, light_max = minetest.LIGHT_MAX+1, light_min = 0, chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate active_object_count = 12, - min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level - max_height = mobs_mc.spawn_height.overworld_max, + min_height = mobs_mc.water_level+1, -- Right above ocean level + max_height = mcl_vars.mg_overworld_max, on_spawn = function(self, pos) - --[[ Note: Minecraft has a 1/3 spawn failure rate. - In this mod it is emulated by reducing the spawn rate accordingly (see above). ]] + Note: Minecraft has a 1/3 spawn failure rate. + In this mod it is emulated by reducing the spawn rate accordingly (see above). -- 1/7 chance to spawn 2 ocelot kittens if pr:next(1,7) == 1 then @@ -207,7 +246,7 @@ mobs:spawn({ end end, }) +]]-- -- spawn eggs --- FIXME: The spawn icon shows a cat texture, not an ocelot texture -mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0) +mcl_mobs.register_egg("mobs_mc:ocelot", S("Ocelot"), "#efde7d", "#564434", 0) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 407cb4466..ed2892aca 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -8,17 +8,137 @@ local S = minetest.get_translator("mobs_mc") --################### --################### PARROT --################### +local shoulders = { + left = vector.new(-3.75,10.5,0), + right = vector.new(3.75,10.5,0) +} +local function table_get_rand(tbl) + local keys = {} + for k in pairs(tbl) do + table.insert(keys, k) + end + return tbl[keys[math.random(#keys)]] +end +local function get_random_mob_sound() + local t = table.copy(minetest.registered_entities) + table.shuffle(t) + for _,e in pairs(t) do + if e.is_mob and e.sounds and #e.sounds > 0 then + return table_get_rand(e.sounds) + end + end + return minetest.registered_entities["mobs_mc:parrot"].sounds.random +end -mobs:register_mob("mobs_mc:parrot", { - type = "npc", +local function imitate_mob_sound(self,mob) + local snd = mob.sounds.random + if not snd or mob.name == "mobs_mc:parrot" or math.random(20) == 1 then + snd = get_random_mob_sound() + end + return minetest.sound_play(snd, { + pos = self.object:get_pos(), + gain = 1.0, + pitch = 2.5, + max_hear_distance = self.sounds and self.sounds.distance or 32 + }, true) +end + +local function check_mobimitate(self,dtime) + if not self._mobimitate_timer or self._mobimitate_timer > 30 then + self._mobimitate_timer = 0 + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),20)) do + local l = o:get_luaentity() + if l and l.is_mob and l.name ~= "mobs_mc:parrot" then + imitate_mob_sound(self,l) + return + end + end + end + self._mobimitate_timer = self._mobimitate_timer + dtime + +end + +--find a free shoulder or return nil +local function get_shoulder(player) + local sh = "left" + for _,o in pairs(player:get_children()) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:parrot" then + local _,_,a = l.object:get_attach() + for _,s in pairs(shoulders) do + if a and vector.equals(a,s) then + if sh == "left" then + sh = "right" + else + return + end + + end + end + end + end + return shoulders[sh] +end + +local function perch(self,player) + if self.tamed and player:get_player_name() == self.owner and not self.object:get_attach() then + local shoulder = get_shoulder(player) + if not shoulder then return true end + self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true) + self:set_animation("stand") + end +end + +local function check_perch(self,dtime) + if self.object:get_attach() then + for _,p in pairs(minetest.get_connected_players()) do + for _,o in pairs(p:get_children()) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:parrot" then + local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name + local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name + local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name + if ( n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0) and + not minetest.is_creative_enabled(p:get_player_name()) then + o:set_detach() + self.detach_timer = 0 + return + end + end + end + end + elseif not self.detach_timer then + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(self.object:get_pos(),p:get_pos()) < 0.5 then + perch(self,p) + return + end + end + elseif self.detach_timer then + if self.detach_timer > 1 then + self.detach_timer = nil + else + self.detach_timer = self.detach_timer + dtime + end + end +end + +mcl_mobs.register_mob("mobs_mc:parrot", { + description = S("Parrot"), + type = "animal", spawn_class = "passive", + passive = true, pathfinding = 1, hp_min = 6, hp_max = 6, xp_min = 1, xp_max = 3, + head_swivel = "head.control", + bone_eye_height = 1.1, + horrizonatal_head_height=0, + curiosity = 10, collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25}, visual = "mesh", mesh = "mobs_mc_parrot.b3d", @@ -34,22 +154,22 @@ mobs:register_mob("mobs_mc:parrot", { distance = 16, }, drops = { - {name = mobs_mc.items.feather, + {name = "mcl_mobitems:feather", chance = 1, min = 1, max = 2, looting = "common",}, }, - animation = { + animation = { stand_speed = 50, walk_speed = 50, fly_speed = 50, - stand_start = 30, - stand_end = 45, + stand_start = 0, + stand_end = 0, fly_start = 30, fly_end = 45, - walk_start = 30, - walk_end = 45, + walk_start = 0, + walk_end = 20, -- TODO: actual walk animation --walk_start = 0, --walk_end = 20, @@ -65,12 +185,17 @@ mobs:register_mob("mobs_mc:parrot", { makes_footstep_sound = false, fear_height = 0, view_range = 16, - follow = mobs_mc.follow.parrot, + follow = { + "mcl_farming:wheat_seeds", + "mcl_farming:melon_seeds", + "mcl_farming:pumpkin_seeds", + "mcl_farming:beetroot_seeds", + }, on_rightclick = function(self, clicker) if self._doomed then return end local item = clicker:get_wielded_item() -- Kill parrot if fed with cookie - if item:get_name() == mobs_mc.items.cookie then + if item:get_name() == "mcl_farming:cookie" then minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true) self.health = 0 -- Doomed to die @@ -81,17 +206,39 @@ mobs:register_mob("mobs_mc:parrot", { end return end - -- Feed to tame, but not breed - if mobs:feed_tame(self, clicker, 1, false, true) then return end - if mobs:protect(self, clicker) then return end - if mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end + if self:feed_tame(clicker, 1, false, true) then return end + perch(self,clicker) + end, + do_custom = function(self,dtime) + check_perch(self,dtime) + check_mobimitate(self,dtime) + end, + do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later.... + if self.object:get_attach() == puncher then + return false --return false explicitly here. mcl_mobs checks for that + end end, - }) --- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* -mobs:spawn_specific("mobs_mc:parrot", {"mcl_core:jungletree", "mcl_core:jungleleaves"}, {"air"}, 0, minetest.LIGHT_MAX+1, 7, 30000, 1, mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) +-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i +mcl_mobs:spawn_specific( +"mobs_mc:parrot", +"overworld", +"ground", +{ +"Jungle", +"JungleEdgeM", +"JungleM", +"JungleEdge", +}, +0, +minetest.LIGHT_MAX+1, +7, +30000, +1, +mobs_mc.water_level+7, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0) +mcl_mobs.register_egg("mobs_mc:parrot", S("Parrot"), "#0da70a", "#ff0000", 0) diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index 38700b6ca..9084c5d4d 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -2,9 +2,11 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:pig", { +mcl_mobs.register_mob("mobs_mc:pig", { + description = S("Pig"), type = "animal", spawn_class = "passive", + passive = true, runaway = true, hp_min = 10, hp_max = 10, @@ -14,17 +16,21 @@ mobs:register_mob("mobs_mc:pig", { visual = "mesh", mesh = "mobs_mc_pig.b3d", textures = {{ - "blank.png", -- baby "mobs_mc_pig.png", -- base "blank.png", -- saddle }}, - visual_size = {x=2.5, y=2.5}, + head_swivel = "head.control", + bone_eye_height = 7.5, + head_eye_height = 0.8, + horrizonatal_head_height=-1, + curiosity = 3, + head_yaw="z", makes_footstep_sound = true, walk_velocity = 1, run_velocity = 3, follow_velocity = 3.4, drops = { - {name = mobs_mc.items.porkchop_raw, + {name = "mcl_mobitems:porkchop", chance = 1, min = 1, max = 3, @@ -39,36 +45,46 @@ mobs:register_mob("mobs_mc:pig", { distance = 16, }, animation = { - stand_speed = 40, - walk_speed = 40, - run_speed = 90, - stand_start = 0, - stand_end = 0, - walk_start = 0, - walk_end = 40, - run_start = 0, - run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 60, + run_start = 0, run_end = 40, run_speed = 90, + }, + child_animations = { + stand_start = 41, stand_end = 41, + walk_start = 41, walk_end = 81, walk_speed = 90, + run_start = 41, run_end = 81, run_speed = 135, + }, + follow = { + "mcl_farming:potato_item", + "mcl_farming:carrot_item", + "mcl_farming:beetroot_item", + "mcl_mobitems:carrot_on_a_stick" }, - follow = mobs_mc.follow.pig, view_range = 8, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:zombified_piglin") + return true + end, do_custom = function(self, dtime) -- set needed values if not already present - if not self.v2 then - self.v2 = 0 + if not self.v3 then + self.v3 = 0 self.max_speed_forward = 4 self.max_speed_reverse = 2 self.accel = 4 self.terrain_type = 3 - self.driver_attach_at = {x = 0.0, y = 2.75, z = -1.5} + self.driver_attach_at = {x = 0.0, y = 6.5, z = -3.75} self.driver_eye_offset = {x = 0, y = 3, z = 0} self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} + self.base_texture = self.texture_list[1] + self.object:set_properties({textures = self.base_texture}) end -- if driver present allow control of horse - if self.driver then + if self.driver and self.driver:get_wielded_item():get_name() == "mcl_mobitems:carrot_on_a_stick" then - mobs.drive(self, "walk", "stand", false, dtime) + mcl_mobs.drive(self, "walk", "stand", false, dtime) return false -- skip rest of mob functions end @@ -81,7 +97,7 @@ mobs:register_mob("mobs_mc:pig", { -- drop saddle when horse is killed while riding -- also detach from horse properly if self.driver then - mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) end end, @@ -92,10 +108,10 @@ mobs:register_mob("mobs_mc:pig", { local wielditem = clicker:get_wielded_item() -- Feed pig - if wielditem:get_name() ~= mobs_mc.items.carrot_on_a_stick then - if mobs:feed_tame(self, clicker, 1, true, true) then return end + if wielditem:get_name() ~= "mcl_mobitems:carrot_on_a_stick" then + if self:feed_tame(clicker, 1, true, false) then return end end - if mobs:protect(self, clicker) then return end + if mcl_mobs:protect(self, clicker) then return end if self.child then return @@ -103,9 +119,8 @@ mobs:register_mob("mobs_mc:pig", { -- Put saddle on pig local item = clicker:get_wielded_item() - if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then + if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then self.base_texture = { - "blank.png", -- baby "mobs_mc_pig.png", -- base "mobs_mc_pig_saddle.png", -- saddle } @@ -115,11 +130,11 @@ mobs:register_mob("mobs_mc:pig", { self.saddle = "yes" self.tamed = true self.drops = { - {name = mobs_mc.items.porkchop_raw, + {name = "mcl_mobitems:porkchop", chance = 1, min = 1, max = 3,}, - {name = mobs_mc.items.saddle, + {name = "mcl_mobitems:saddle", chance = 1, min = 1, max = 1,}, @@ -134,18 +149,14 @@ mobs:register_mob("mobs_mc:pig", { return end - -- Mount or detach player - local name = clicker:get_player_name() - if self.driver and clicker == self.driver then - -- Detach if already attached - mobs.detach(clicker, {x=1, y=0, z=0}) - return - - elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == mobs_mc.items.carrot_on_a_stick then - -- Ride pig if it has a saddle and player uses a carrot on a stick - - mobs.attach(self, clicker) - + -- Should make pig go faster when right clicked with carrot on a stick. + -- FIXME: needs work on the going faster part. + --[[if self.driver and clicker == self.driver and self.driver:get_wielded_item():get_name() == "mcl_mobitems:carrot_on_a_stick" then + if not self.v3 then + self.v3 = 0 + self.max_speed_forward = 100 + self.accel = 10 + end if not minetest.is_creative_enabled(clicker:get_player_name()) then local inv = self.driver:get_inventory() @@ -156,23 +167,36 @@ mobs:register_mob("mobs_mc:pig", { if def.sounds and def.sounds.breaks then minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true) end - wielditem = {name = mobs_mc.items.fishing_rod, count = 1} + wielditem = {name = "mcl_fishing:fishing_rod", count = 1} else wielditem:add_wear(2521) end inv:set_stack("main",self.driver:get_wield_index(), wielditem) end + end]] + + -- Mount or detach player + local name = clicker:get_player_name() + if self.driver and clicker == self.driver then -- and self.driver:get_wielded_item():get_name() ~= "mcl_mobitems:carrot_on_a_stick" then -- Note: This is for when the ability to make the pig go faster is implemented + -- Detach if already attached + mcl_mobs.detach(clicker, {x=1, y=0, z=0}) + return + + elseif not self.driver and self.saddle == "yes" then + -- Ride pig if it has a saddle + + mcl_mobs.attach(self, clicker) return -- Capture pig elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then - mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) + mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil) end end, on_breed = function(parent1, parent2) local pos = parent1.object:get_pos() - local child = mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() ent_c.tamed = true @@ -180,9 +204,64 @@ mobs:register_mob("mobs_mc:pig", { return false end end, + + after_activate = function(self, staticdata, def, dtime) + if self.saddle == "yes" then -- Make saddle load upon rejoin + self.base_texture = { + "mobs_mc_pig.png", -- base + "mobs_mc_pig_saddle.png", -- saddle + } + self.object:set_properties({ + textures = self.base_texture + }) + end + end, }) -mobs:spawn_specific("mobs_mc:pig", mobs_mc.spawn.grassland, {"air"}, 9, minetest.LIGHT_MAX+1, 30, 15000, 8, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:pig", +"overworld", +"ground", +{ + "flat", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", + "ExtremeHills+", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", + "BirchForestM", + "RoofedForest", + "Savanna", + "Savanna_beach", + "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0) +mcl_mobs.register_egg("mobs_mc:pig", S("Pig"), "#f0a5a2", "#db635f", 0) diff --git a/mods/ENTITIES/mobs_mc/piglin.lua b/mods/ENTITIES/mobs_mc/piglin.lua new file mode 100644 index 000000000..4f701b3e9 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/piglin.lua @@ -0,0 +1,456 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local trading_items = { + { itemstring = "mcl_core:obsidian", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gravel", amount_min = 8, amount_max = 16 }, + { itemstring = "mcl_mobitems:leather", amount_min = 4, amount_max = 10 }, + { itemstring = "mcl_nether:soul_sand", amount_min = 4, amount_max = 16 }, + { itemstring = "mcl_nether:nether_brick", amount_min = 4, amount_max = 16 }, + { itemstring = "mcl_mobitems:string", amount_min = 3, amount_max = 9 }, + { itemstring = "mcl_nether:quartz", amount_min = 4, amount_max = 10 }, + { itemstring = "mcl_potions:water", amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:iron_nugget", amount_min = 10, amount_max = 36 }, + { 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 }, +} + +local S = minetest.get_translator("mobs_mc") +local mod_bows = minetest.get_modpath("mcl_bows") ~= nil + +function mobs_mc.player_wears_gold(player) + for i=1, 6 do + local stack = player:get_inventory():get_stack("armor", i) + local item = stack:get_name() + if string.find(item, "mcl_armor:chestplate_gold") + or string.find(item, "mcl_armor:leggings_gold") + or string.find(item, "mcl_armor:helmet_gold") + or string.find(item, "mcl_armor:boots_gold") then + return true + end + end +end + +--################### +--################### piglin +--################### +local piglin = { + description = S("Piglin"), + type = "monster", + passive = false, + spawn_class = "hostile", + group_attack = {"mobs_mc:piglin", "mobs_mc:sword_piglin", "mobs_mc:piglin_brute"}, + hp_min = 16, + hp_max = 16, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + damage = 4, + reach = 3, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, + visual = "mesh", + mesh = "extra_mobs_piglin.b3d", + spawn_in_group = 4, + spawn_in_group_min = 2, + textures = { { + "extra_mobs_piglin.png", + "mcl_bows_bow_2.png", + } }, + visual_size = {x=1, y=1}, + sounds = { + random = "extra_mobs_piglin", + damage = "extra_mobs_piglin_hurt", + distance = 16, + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 1.4, + run_velocity = 2.8, + drops = { + {name = "mcl_bows:crossbow", + chance = 10, + min = 1, + max = 1,}, + }, + animation = { + stand_speed = 30, + walk_speed = 30, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + }, + fear_height = 4, + view_range = 16, + pick_up = {"mcl_core:gold_ingot"}, + on_spawn = function(self) + self.weapon = self.base_texture[2] + self.gold_items = 0 + end, + do_custom = function(self) + if self.object:get_pos().y > mcl_vars.mg_overworld_min then + local zog = minetest.add_entity(self.object:get_pos(), "mobs_mc:zombified_piglin") + zog:set_rotation(self.object:get_rotation()) + self.object:remove() + return + elseif self.trading == true then + self.state = "trading" + self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(20,-20,18)) + self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(-40,0,0)) + self.base_texture[2] = "default_gold_ingot.png" + self.object:set_properties({textures = self.base_texture}) + else + self.object:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + self.base_texture[2] = self.weapon + self.object:set_properties({textures = self.base_texture}) + self.object:set_bone_position("Head", vector.new(0,6.3,0), vector.new(0,0,0)) + self.object:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) + end + + if self.state ~= "attack" then + self._attacked_by_player = false + elseif self.attack:is_player() and mobs_mc.player_wears_gold(self.attack) then + if self._attacked_by_player == false then + self.state = "stand" + end + end + end, + on_pick_up = function(self, itementity) + local item = itementity.itemstring:split(" ")[1] + local it = ItemStack(itementity.itemstring) + if item == "mcl_core:gold_ingot" and self.state ~= "attack" and self.gold_items and self.gold_items < 3 then + it:take_item(1) + self.state = "stand" + self.object:set_animation({x=0,y=79}) + self.trading = true + self.gold_items = self.gold_items + 1 + self.object:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) + minetest.after(5, function() + self.gold_items = self.gold_items - 1 + if self.gold_items == 0 then + self.trading = false + self.state = "stand" + end + 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) + end + end + end) + end + return it + end, + do_punch = function(self, hitter) + if hitter:is_player() then + self._attacked_by_player = true + end + end, + attack_type = "dogshoot", + arrow = "mcl_bows:arrow_entity", + shoot_arrow = function(self, pos, dir) + if mod_bows then + if self.attack then + self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos()))) + end + -- 2-4 damage per arrow + local dmg = math.max(4, math.random(2, 8)) + mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + end + end, + shoot_interval = 2, + shoot_offset = 1.5, + dogshoot_switch = 1, + dogshoot_count_max =1.8, + attacks_monsters = true, + attack_animals = true, + specific_attack = { "player", "mobs_mc:hoglin" }, +} + +mcl_mobs.register_mob("mobs_mc:piglin", piglin) + + +local sword_piglin = table.copy(piglin) +sword_piglin.description = S("Sword Piglin") +sword_piglin.mesh = "extra_mobs_sword_piglin.b3d" +sword_piglin.textures = {"extra_mobs_piglin.png", "default_tool_goldsword.png"} +sword_piglin.on_spawn = function(self) + self.gold_items = 0 + self.weapon = self.base_texture[2] + self.object:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) +end +sword_piglin.drops = { + {name = "mcl_tools:sword_gold", + chance = 10, + min = 1, + max = 1,}, +} +sword_piglin.attack_type = "dogfight" +sword_piglin.animation = { + stand_speed = 30, + walk_speed = 30, + punch_speed = 45, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + punch_start = 189, + punch_end = 198, +} + +mcl_mobs.register_mob("mobs_mc:sword_piglin", sword_piglin) + + +-- Zombified Piglin -- + + +local zombified_piglin = { + description = S("Zombie Piglin"), + -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked + type = "animal", + passive = false, + spawn_class = "passive", + hp_min = 20, + hp_max = 20, + xp_min = 6, + xp_max = 6, + armor = {undead = 90, fleshy = 90}, + attack_type = "dogfight", + group_attack = {"mobs_mc:zombified_piglin", "mobs_mc:baby_zombified_piglin"}, + damage = 9, + reach = 2, + head_swivel = "head.control", + bone_eye_height = 2.4, + head_eye_height = 1.4, + curiosity = 15, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, -- same + visual = "mesh", + mesh = "mobs_mc_zombie_pigman.b3d", + textures = { { + "blank.png", --baby + "default_tool_goldsword.png", --sword + "mobs_mc_zombie_pigman.png", --pigman + } }, + visual_size = {x=3, y=3}, + sounds = { + random = "mobs_mc_zombiepig_random", + war_cry = "mobs_mc_zombiepig_war_cry", + death = "mobs_mc_zombiepig_death", + damage = "mobs_mc_zombiepig_hurt", + distance = 16, + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = .8, + run_velocity = 2.6, + pathfinding = 1, + drops = { + {name = "mcl_mobitems:rotten_flesh", + chance = 1, + min = 1, + max = 1, + looting = "common"}, + {name = "mcl_core:gold_nugget", + chance = 1, + min = 0, + max = 1, + looting = "common"}, + {name = "mcl_core:gold_ingot", + chance = 40, -- 2.5% + min = 1, + max = 1, + looting = "rare"}, + {name = "mcl_tools:sword_gold", + chance = 100 / 8.5, + min = 1, + max = 1, + looting = "rare"}, + }, + animation = { + stand_speed = 25, + walk_speed = 25, + run_speed = 50, + stand_start = 40, + stand_end = 80, + walk_start = 0, + walk_end = 40, + run_start = 0, + run_end = 40, + punch_start = 90, + punch_end = 130, + }, + lava_damage = 0, + fire_damage = 0, + fear_height = 4, + view_range = 16, + harmed_by_heal = true, + fire_damage_resistant = true, +} + +mcl_mobs.register_mob("mobs_mc:zombified_piglin", zombified_piglin) + +local baby_zombified_piglin = table.copy(zombified_piglin) +baby_zombified_piglin.description = S("Baby Zombie Piglin") +baby_zombified_piglin.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} +baby_zombified_piglin.xp_min = 13 +baby_zombified_piglin.xp_max = 13 +baby_zombified_piglin.textures = { + { + "mobs_mc_zombie_pigman.png", --baby + "default_tool_goldsword.png", --sword + "mobs_mc_zombie_pigman.png", --pigman + } +} +baby_zombified_piglin.walk_velocity = 1.2 +baby_zombified_piglin.run_velocity = 2.4 +baby_zombified_piglin.light_damage = 0 +baby_zombified_piglin.child = 1 + +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) + + +-- Piglin Brute -- + +local piglin_brute = table.copy(piglin) +piglin_brute.description = S("Piglin Brute") +piglin_brute.xp_min = 20 +piglin_brute.xp_max = 20 +piglin_brute.hp_min = 50 +piglin_brute.hp_max = 50 +piglin_brute.fire_resistant = 1 +piglin_brute.do_custom = function() + return +end +piglin_brute.on_spawn = function() + return +end +piglin_brute.on_rightclick = function() + return +end +piglin_brute.attacks_monsters = true +piglin_brute.lava_damage = 0 +piglin_brute.fire_damage = 0 +piglin_brute.attack_animals = true +piglin_brute.mesh = "extra_mobs_sword_piglin.b3d" +piglin_brute.textures = {"extra_mobs_piglin_brute.png", "default_tool_goldaxe.png", "extra_mobs_trans.png"} +piglin_brute.attack_type = "dogfight" +piglin_brute.animation = { + stand_speed = 30, + walk_speed = 30, + punch_speed = 45, + run_speed = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 440, + run_end = 459, + punch_start = 189, + punch_end = 198, +} +piglin_brute.can_despawn = false + +piglin_brute.drops = { + {name = "mcl_tools:axe_gold", + chance = 8.5, + min = 1, + max = 1,}, +} +mcl_mobs.register_mob("mobs_mc:piglin_brute", piglin_brute) + + + +-- Regular spawning in the Nether +mcl_mobs:spawn_specific( +"mobs_mc:piglin", +"nether", +"ground", +{ +"Nether", +"CrimsonForest" +}, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_lava_nether_max, +mcl_vars.mg_nether_max) + +mcl_mobs:spawn_specific( +"mobs_mc:sword_piglin", +"nether", +"ground", +{ + "Nether", + "CrimsonForest" + }, +0, +minetest.LIGHT_MAX+1, +30, +6000, +3, +mcl_vars.mg_lava_nether_max, +mcl_vars.mg_nether_max) + +mcl_mobs:spawn_specific( + "mobs_mc:zombified_piglin", + "nether", + "ground", + { + "Nether", + "CrimsonForest", + }, + 0, + minetest.LIGHT_MAX+1, + 30, + 6000, + 3, + mcl_vars.mg_nether_min, + mcl_vars.mg_nether_max) + +-- Baby zombie is 20 times less likely than regular zombies +mcl_mobs:spawn_specific( + "mobs_mc:baby_zombified_piglin", + "nether", + "ground", + { + "Nether", + "CrimsonForest", + }, + 0, + minetest.LIGHT_MAX+1, + 30, + 100000, + 4, + mcl_vars.mg_nether_min, + mcl_vars.mg_nether_max) + +mcl_mobs:non_spawn_specific("mobs_mc:piglin","overworld",0,7) +mcl_mobs:non_spawn_specific("mobs_mc:sword_piglin","overworld",0,7) +mcl_mobs:non_spawn_specific("mobs_mc:piglin_brute","overworld",0,7) +mcl_mobs:non_spawn_specific("mobs_mc:zombified_piglin","overworld",0,minetest.LIGHT_MAX+1) + +mcl_mobs.register_egg("mobs_mc:piglin", S("Piglin"), "#7b4a17","#d5c381", 0) +mcl_mobs.register_egg("mobs_mc:piglin_brute", S("Piglin Brute"), "#562b0c","#ddc89d", 0) +mcl_mobs.register_egg("mobs_mc:zombified_piglin", S("Zombie Piglin"), "#ea9393", "#4c7129", 0) diff --git a/mods/ENTITIES/mobs_mc/pillager.lua b/mods/ENTITIES/mobs_mc/pillager.lua new file mode 100644 index 000000000..5e07d8dc5 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/pillager.lua @@ -0,0 +1,125 @@ +local S = minetest.get_translator("mobs_mc") + +local function reload(self) + if not self.object:get_pos() then return end + minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + if not props then return end + props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16" + self.object:set_properties(props) +end + +local function reset_animation(self, animation) + if not self.object:get_pos() or self._current_animation ~= animation then return end + self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this + self:set_animation(animation) +end + +pillager = { + description = S("Pillager"), + type = "monster", + spawn_class = "hostile", + hp_min = 24, + hp_max = 24, + xp_min = 6, + xp_max = 6, + breath_max = -1, + eye_height = 1.5, + shoot_interval = 3, + shoot_offset = 1.5, + armor = {fleshy = 100}, + can_despawn = false, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, + pathfinding = 1, + group_attack = true, + visual = "mesh", + mesh = "mobs_mc_pillager.b3d", + visual_size = {x=2.75, y=2.75}, + makes_footstep_sound = true, + walk_velocity = 1.2, + run_velocity = 4, + view_range = 16, + fear_height = 4, + arrow = "mcl_bows:arrow_entity", + attack_type = "dogshoot", -- Alternate punching/shooting + attack_npcs = true, + reach = 0, -- Punching max distance + damage = 0, -- Punching damage + dogshoot_switch = 1, -- Start of shooting + dogshoot_count_max = 5, -- Max time spent shooting (standing) + dogshoot_count2_max = 1, -- Max time spent punching (running) + sounds = { + random = "mobs_mc_pillager_grunt2", + war_cry = "mobs_mc_pillager_grunt1", + death = "mobs_mc_pillager_ow2", + damage = "mobs_mc_pillager_ow1", + distance = 16, + }, + textures = { + { + "mobs_mc_pillager.png", -- Skin + "mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item + } + }, + drops = { + { + name = "mcl_bows:arrow", + chance = 1, + min = 0, + max = 2, + looting = "common", + }, + { + name = "mcl_bows:crossbow", + chance = 100 / 8.5, + min = 1, + max = 1, + looting = "rare", + }, + }, + animation = { + unloaded_walk_start = 1, unloaded_walk_end = 40, + unloaded_stand_start = 41, unloaded_stand_end = 60, + reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20, + stand_start = 101, stand_end = 109, stand_speed = 6, + walk_start = 111, walk_end = 150, walk_speed = 30, + run_start = 111, run_end = 150, run_speed = 50, + reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20, + die_start = 191, die_end = 192, die_speed = 15, + stand_unloaded_start = 40, stand_unloaded_end = 59, + die_loop = false, + }, + shoot_arrow = function(self, pos, dir) + minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true) + local props = self.object:get_properties() + props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16" + self.object:set_properties(props) + local old_anim = self._current_animation + if old_anim == "run" or old_anim == "walk" then + self:set_animation("reload_run") + end + if old_anim == "stand" then + self:set_animation("reload_stand") + end + self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise + minetest.after(1, reload, self) + minetest.after(2, reset_animation, self, old_anim) + + -- 2-4 damage per arrow + local dmg = math.max(4, math.random(2, 8)) + mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg) + + -- While we are at it, change the sounds since there is no way to do this in Mobs Redo + if self.sounds and self.sounds.random then + self.sounds = table.copy(self.sounds) + self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2) + end + + -- Randomize reload time + self.shoot_interval = math.random(3, 4) + end, +} + +mcl_mobs.register_mob("mobs_mc:pillager", pillager) +mcl_mobs.register_egg("mobs_mc:pillager", S("Pillager"), "#532f36", "#959b9b", 0) +mcl_mobs:non_spawn_specific("mobs_mc:pillager","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 459ca29b4..d6667a256 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -7,7 +7,8 @@ local S = minetest.get_translator("mobs_mc") --################### -mobs:register_mob("mobs_mc:polar_bear", { +mcl_mobs.register_mob("mobs_mc:polar_bear", { + description = S("Polar Bear"), type = "animal", spawn_class = "passive", runaway = false, @@ -23,6 +24,12 @@ mobs:register_mob("mobs_mc:polar_bear", { textures = { {"mobs_mc_polarbear.png"}, }, + head_swivel = "head.control", + bone_eye_height = 2.6, + head_eye_height = 1, + horrizonatal_head_height = 0, + curiosity = 20, + head_yaw="z", visual_size = {x=3.0, y=3.0}, makes_footstep_sound = true, damage = 6, @@ -33,13 +40,13 @@ mobs:register_mob("mobs_mc:polar_bear", { attack_type = "dogfight", drops = { -- 3/4 chance to drop raw fish (poor approximation) - {name = mobs_mc.items.fish_raw, + {name = "mcl_fishing:fish_raw", chance = 2, min = 0, max = 2, - looting = "common",}, + looting = "common",}, -- 1/4 to drop raw salmon - {name = mobs_mc.items.salmon_raw, + {name = "mcl_fishing:salmon_raw", chance = 4, min = 0, max = 2, @@ -67,7 +74,22 @@ mobs:register_mob("mobs_mc:polar_bear", { }) -mobs:spawn_specific("mobs_mc:polar_bear", mobs_mc.spawn.snow, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 7000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:polar_bear", +"overworld", +"ground", +{ +"ColdTaiga", +"IcePlainsSpikes", +"IcePlains", +}, +0, +minetest.LIGHT_MAX+1, +30, +7000, +3, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- spawn egg -mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0) +mcl_mobs.register_egg("mobs_mc:polar_bear", S("Polar Bear"), "#f2f2f2", "#959590", 0) diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index e167649f6..6c4317519 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -3,17 +3,24 @@ local S = minetest.get_translator("mobs_mc") local rabbit = { + description = S("Rabbit"), type = "animal", spawn_class = "passive", + spawn_in_group_min = 2, + spawn_in_group = 3, passive = true, reach = 1, - hp_min = 3, hp_max = 3, xp_min = 1, xp_max = 3, collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.49, 0.2}, - + head_swivel = "head.control", + bone_eye_height = 2, + head_eye_height = 0.5, + horrizonatal_head_height = -.3, + curiosity = 20, + head_yaw="z", visual = "mesh", mesh = "mobs_mc_rabbit.b3d", textures = { @@ -24,7 +31,6 @@ local rabbit = { {"mobs_mc_rabbit_salt.png"}, {"mobs_mc_rabbit_black.png"}, }, - visual_size = {x=1.5, y=1.5}, sounds = { random = "mobs_mc_rabbit_random", damage = "mobs_mc_rabbit_hurt", @@ -41,28 +47,45 @@ local rabbit = { runaway = true, jump = true, drops = { - {name = mobs_mc.items.rabbit_raw, chance = 1, min = 0, max = 1, looting = "common",}, - {name = mobs_mc.items.rabbit_hide, chance = 1, min = 0, max = 1, looting = "common",}, - {name = mobs_mc.items.rabbit_foot, chance = 10, min = 0, max = 1, looting = "rare", looting_factor = 0.03,}, + {name = "mcl_mobitems:rabbit", chance = 1, min = 0, max = 1, looting = "common",}, + {name = "mcl_mobitems:rabbit_hide", chance = 1, min = 0, max = 1, looting = "common",}, + {name = "mcl_mobitems:rabbit_foot", chance = 10, min = 0, max = 1, looting = "rare", looting_factor = 0.03,}, }, fear_height = 4, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 0, - walk_start = 0, walk_end = 20, - run_start = 0, run_end = 20, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 20, walk_speed = 20, + run_start = 0, run_end = 20, run_speed = 30, + }, + child_animations = { + stand_start = 21, stand_end = 21, + walk_start = 21, walk_end = 41, walk_speed = 30, + run_start = 21, run_end = 41, run_speed = 45, }, -- Follow (yellow) dangelions, carrots and golden carrots - follow = mobs_mc.follow.rabbit, + follow = { + "mcl_flowers:dandelion", + "mcl_farming:carrot_item", + "mcl_farming:carrot_item_gold", + }, view_range = 8, -- Eat carrots and reduce their growth stage by 1 replace_rate = 10, - replace_what = mobs_mc.replace.rabbit, + replace_what = { + {"mcl_farming:carrot", "mcl_farming:carrot_7", 0}, + {"mcl_farming:carrot_7", "mcl_farming:carrot_6", 0}, + {"mcl_farming:carrot_6", "mcl_farming:carrot_5", 0}, + {"mcl_farming:carrot_5", "mcl_farming:carrot_4", 0}, + {"mcl_farming:carrot_4", "mcl_farming:carrot_3", 0}, + {"mcl_farming:carrot_3", "mcl_farming:carrot_2", 0}, + {"mcl_farming:carrot_2", "mcl_farming:carrot_1", 0}, + {"mcl_farming:carrot_1", "air", 0}, + }, on_rightclick = function(self, clicker) -- Feed, tame protect or capture - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end - if mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:protect(self, clicker) then return end + if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end end, do_custom = function(self) -- Easter egg: Change texture if rabbit is named “Toast” @@ -79,10 +102,11 @@ local rabbit = { end, } -mobs:register_mob("mobs_mc:rabbit", rabbit) +mcl_mobs.register_mob("mobs_mc:rabbit", rabbit) -- The killer bunny (Only with spawn egg) local killer_bunny = table.copy(rabbit) +killer_bunny.description = S("Killer Bunny") killer_bunny.type = "monster" killer_bunny.spawn_class = "hostile" killer_bunny.attack_type = "dogfight" @@ -104,11 +128,32 @@ killer_bunny.do_custom = function(self) end end -mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) +mcl_mobs.register_mob("mobs_mc:killer_bunny", killer_bunny) -- Mob spawning rules. --- Different skins depending on spawn location +-- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out +mcl_mobs:spawn_specific( +"mobs_mc:rabbit", +"overworld", +"ground", +{ +"Desert", +"FlowerForest", +"Taiga", +"MegaSpruceTaiga", +"MegaTaiga", +"ColdTaiga", +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) + +--[[ local spawn = { name = "mobs_mc:rabbit", neighbors = {"air"}, @@ -116,21 +161,21 @@ local spawn = { active_object_count = 10, min_light = 0, max_light = minetest.LIGHT_MAX+1, - min_height = mobs_mc.spawn_height.overworld_min, - max_height = mobs_mc.spawn_height.overworld_max, + min_height = mcl_vars.mg_overworld_min, + max_height = mcl_vars.mg_overworld_max, } local spawn_desert = table.copy(spawn) -spawn_desert.nodes = mobs_mc.spawn.desert +spawn_desert.nodes = { "mcl_core:sand", "mcl_core:sandstone" } spawn_desert.on_spawn = function(self, pos) local texture = "mobs_mc_rabbit_gold.png" self.base_texture = { "mobs_mc_rabbit_gold.png" } self.object:set_properties({textures = self.base_texture}) end -mobs:spawn(spawn_desert) +mcl_mobs:spawn(spawn_desert) local spawn_snow = table.copy(spawn) -spawn_snow.nodes = mobs_mc.spawn.snow +spawn_snow.nodes = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" } spawn_snow.on_spawn = function(self, pos) local texture local r = math.random(1, 100) @@ -144,10 +189,10 @@ spawn_snow.on_spawn = function(self, pos) self.base_texture = { texture } self.object:set_properties({textures = self.base_texture}) end -mobs:spawn(spawn_snow) +mcl_mobs:spawn(spawn_snow) local spawn_grass = table.copy(spawn) -spawn_grass.nodes = mobs_mc.spawn.grassland +spawn_grass.nodes = { "mcl_core:dirt_with_grass" } spawn_grass.on_spawn = function(self, pos) local texture local r = math.random(1, 100) @@ -164,10 +209,12 @@ spawn_grass.on_spawn = function(self, pos) self.base_texture = { texture } self.object:set_properties({textures = self.base_texture}) end -mobs:spawn(spawn_grass) +mcl_mobs:spawn(spawn_grass) +]]-- -- Spawn egg -mobs:register_egg("mobs_mc:rabbit", S("Rabbit"), "mobs_mc_spawn_icon_rabbit.png", 0) +mcl_mobs.register_egg("mobs_mc:rabbit", S("Rabbit"), "#995f40", "#734831", 0) -- Note: This spawn egg does not exist in Minecraft -mobs:register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "mobs_mc_spawn_icon_rabbit.png^[colorize:#FF0000:192", 0) -- TODO: Update inventory image +mcl_mobs.register_egg("mobs_mc:killer_bunny", S("Killer Bunny"), "#f2f2f2", "#ff0000", 0) +mcl_mobs:non_spawn_specific("mobs_mc:killer_bunny","overworld",9,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/salmon.lua b/mods/ENTITIES/mobs_mc/salmon.lua new file mode 100644 index 000000000..f8e0c4e02 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/salmon.lua @@ -0,0 +1,229 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator(minetest.get_current_modname()) + +--################### +--################### salmon +--################### + +local salmon = { + type = "animal", + spawn_class = "water_ambient", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + spawn_in_group = 5, + tilt_swim = true, + collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.79, 0.4}, + visual = "mesh", + mesh = "extra_mobs_salmon.b3d", + textures = { + {"mobs_mc_salmon.png"} + }, + sounds = { + }, + animation = { + stand_start = 1, + stand_end = 20, + walk_start = 1, + walk_end = 20, + run_start = 1, + run_end = 20, + }, + drops = { + {name = "mcl_fishing:salmon_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + swim = true, + fly = true, + fly_in = "mcl_core:water_source", + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + self.object:remove() + clicker:set_wielded_item("mcl_buckets:bucket_salmon") + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end +} + +mcl_mobs.register_mob("mobs_mc:salmon", salmon) + + +--spawning TODO: in schools +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:salmon", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:salmon", S("Salmon"), "#a00f10", "#0e8474", 0) diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index 681c68e1b..6eaffa611 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -6,28 +6,40 @@ local S = minetest.get_translator("mobs_mc") --################### SHEEP --################### +local WOOL_REPLACE_RATE = 80 + local colors = { -- group = { wool, textures } - unicolor_white = { mobs_mc.items.wool_white, "#FFFFFF00" }, - unicolor_dark_orange = { mobs_mc.items.wool_brown, "#502A00D0" }, - unicolor_grey = { mobs_mc.items.wool_light_grey, "#5B5B5BD0" }, - unicolor_darkgrey = { mobs_mc.items.wool_grey, "#303030D0" }, - unicolor_blue = { mobs_mc.items.wool_blue, "#0000CCD0" }, - unicolor_dark_green = { mobs_mc.items.wool_green, "#005000D0" }, - unicolor_green = { mobs_mc.items.wool_lime, "#50CC00D0" }, - unicolor_violet = { mobs_mc.items.wool_purple , "#5000CCD0" }, - unicolor_light_red = { mobs_mc.items.wool_pink, "#FF5050D0" }, - unicolor_yellow = { mobs_mc.items.wool_yellow, "#CCCC00D0" }, - unicolor_orange = { mobs_mc.items.wool_orange, "#CC5000D0" }, - unicolor_red = { mobs_mc.items.wool_red, "#CC0000D0" }, - unicolor_cyan = { mobs_mc.items.wool_cyan, "#00CCCCD0" }, - unicolor_red_violet = { mobs_mc.items.wool_magenta, "#CC0050D0" }, - unicolor_black = { mobs_mc.items.wool_black, "#000000D0" }, + unicolor_white = { "mcl_wool:white", "#FFFFFF00" }, + unicolor_dark_orange = { "mcl_wool:brown", "#502A00D0" }, + unicolor_grey = { "mcl_wool:silver", "#5B5B5BD0" }, + unicolor_darkgrey = { "mcl_wool:grey", "#303030D0" }, + unicolor_blue = { "mcl_wool:blue", "#0000CCD0" }, + unicolor_dark_green = { "mcl_wool:green", "#005000D0" }, + unicolor_green = { "mcl_wool:lime", "#50CC00D0" }, + unicolor_violet = { "mcl_wool:purple" , "#5000CCD0" }, + unicolor_light_red = { "mcl_wool:pink", "#FF5050D0" }, + unicolor_yellow = { "mcl_wool:yellow", "#CCCC00D0" }, + unicolor_orange = { "mcl_wool:orange", "#CC5000D0" }, + unicolor_red = { "mcl_wool:red", "#CC0000D0" }, + unicolor_cyan = { "mcl_wool:cyan", "#00CCCCD0" }, + unicolor_red_violet = { "mcl_wool:magenta", "#CC0050D0" }, + unicolor_black = { "mcl_wool:black", "#000000D0" }, + unicolor_light_blue = { "mcl_wool:light_blue", "#5050FFD0" }, } -if minetest.get_modpath("mcl_wool") ~= nil then - colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" } -end +local rainbow_colors = { + "unicolor_light_red", + "unicolor_red", + "unicolor_orange", + "unicolor_yellow", + "unicolor_green", + "unicolor_dark_green", + "unicolor_light_blue", + "unicolor_blue", + "unicolor_violet", + "unicolor_red_violet" +} local sheep_texture = function(color_group) if not color_group then @@ -42,25 +54,33 @@ end local gotten_texture = { "blank.png", "mobs_mc_sheep.png" } --mcsheep -mobs:register_mob("mobs_mc:sheep", { +mcl_mobs.register_mob("mobs_mc:sheep", { + description = S("Sheep"), type = "animal", spawn_class = "passive", + passive = true, hp_min = 8, hp_max = 8, xp_min = 1, xp_max = 3, collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45}, - + head_swivel = "head.control", + bone_eye_height = 3.3, + head_eye_height = 1.1, + horrizonatal_head_height=-.7, + curiosity = 6, + head_yaw="z", visual = "mesh", - visual_size = {x=3, y=3}, mesh = "mobs_mc_sheepfur.b3d", textures = { sheep_texture("unicolor_white") }, gotten_texture = gotten_texture, color = "unicolor_white", makes_footstep_sound = true, walk_velocity = 1, + runaway = true, + runaway_from = {"mobs_mc:wolf"}, drops = { - {name = mobs_mc.items.mutton_raw, + {name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2, @@ -80,39 +100,69 @@ mobs:register_mob("mobs_mc:sheep", { distance = 16, }, animation = { - speed_normal = 25, run_speed = 65, - stand_start = 40, stand_end = 80, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 30, + run_start = 0, run_end = 40, run_speed = 40, + eat_start = 40, eat_end = 80, eat_loop = false, }, - follow = mobs_mc.follow.sheep, + child_animations = { + stand_start = 81, stand_end = 81, + walk_start = 81, walk_end = 121, walk_speed = 45, + run_start = 81, run_end = 121, run_speed = 60, + eat_start = 121, eat_start = 161, eat_loop = false, + }, + follow = { "mcl_farming:wheat_item" }, view_range = 12, -- Eat grass - replace_rate = 20, - replace_what = mobs_mc.replace.sheep, + replace_rate = WOOL_REPLACE_RATE, + replace_delay = 1.3, + replace_what = { + { "mcl_core:dirt_with_grass", "mcl_core:dirt", -1 }, + { "mcl_flowers:tallgrass", "air", 0 }, + }, -- Properly regrow wool after eating grass on_replace = function(self, pos, oldnode, newnode) if not self.color or not colors[self.color] then self.color = "unicolor_white" end - self.gotten = false self.base_texture = sheep_texture(self.color) - self.object:set_properties({ textures = self.base_texture }) + self.drops = { - {name = mobs_mc.items.mutton_raw, - chance = 1, - min = 1, - max = 2,}, + {name = "mcl_mobitems:mutton", + chance = 1, + min = 1, + max = 2,}, {name = colors[self.color][1], - chance = 1, - min = 1, - max = 1,}, + chance = 1, + min = 1, + max = 1,}, } + + self.state = "eat" + self:set_animation("eat") + self:set_velocity(0) + + + + minetest.after(self.replace_delay, function() + if self and self.object and self.object:get_velocity() and self.health > 0 then + self.object:set_velocity(vector.zero()) + self.gotten = false + self.object:set_properties({ textures = self.base_texture }) + end + end) + + minetest.after(2.5, function() + if self and self.object and self.state == 'eat' and self.health > 0 then + self.state = "walk" + end + end) + end, -- Set random color on spawn - do_custom = function(self) + do_custom = function(self, dtime) if not self.initial_color_set then local r = math.random(0,100000) local textures @@ -138,7 +188,7 @@ mobs:register_mob("mobs_mc:sheep", { self.base_texture = sheep_texture(self.color) self.object:set_properties({ textures = self.base_texture }) self.drops = { - {name = mobs_mc.items.mutton_raw, + {name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2,}, @@ -149,15 +199,42 @@ mobs:register_mob("mobs_mc:sheep", { } self.initial_color_set = true end + + local is_kay27 = self.nametag == "kay27" + + if self.color_change_timer then + local old_color = self.color + if is_kay27 then + self.color_change_timer = self.color_change_timer - dtime + if self.color_change_timer < 0 then + self.color_change_timer = 0.5 + self.color_index = (self.color_index + 1) % #rainbow_colors + self.color = rainbow_colors[self.color_index + 1] + end + else + self.color_change_timer = nil + self.color_index = nil + self.color = self.initial_color + end + + if old_color ~= self.color then + self.base_texture = sheep_texture(self.color) + self.object:set_properties({textures = self.base_texture}) + end + elseif is_kay27 then + self.initial_color = self.color + self.color_change_timer = 0 + self.color_index = -1 + end end, - + on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end + if self:feed_tame(clicker, 1, true, false) then return end + if mcl_mobs:protect(self, clicker) then return end - if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then + if item:get_name() == "mcl_tools:shears" 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) @@ -171,15 +248,9 @@ mobs:register_mob("mobs_mc:sheep", { textures = self.base_texture, }) if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:add_wear(mobs_mc.misc.shears_wear) + item:add_wear(mobs_mc.shears_wear) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end - self.drops = { - {name = mobs_mc.items.mutton_raw, - chance = 1, - min = 1, - max = 2,}, - } return end -- Dye sheep @@ -197,7 +268,7 @@ mobs:register_mob("mobs_mc:sheep", { }) self.color = group self.drops = { - {name = mobs_mc.items.mutton_raw, + {name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2,}, @@ -211,12 +282,12 @@ mobs:register_mob("mobs_mc:sheep", { end return end - if mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end + if mcl_mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end end, on_breed = function(parent1, parent2) -- Breed sheep and choose a fur color for the child. local pos = parent1.object:get_pos() - local child = mobs:spawn_child(pos, parent1.name) + local child = mcl_mobs.spawn_child(pos, parent1.name) if child then local ent_c = child:get_luaentity() local color1 = parent1.color @@ -263,7 +334,55 @@ mobs:register_mob("mobs_mc:sheep", { end end, }) -mobs:spawn_specific("mobs_mc:sheep", mobs_mc.spawn.grassland, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 3, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:sheep", +"overworld", +"ground", +{ + "flat", + "IcePlainsSpikes", + "ColdTaiga", + "ColdTaiga_beach", + "ColdTaiga_beach_water", + "MegaTaiga", + "MegaSpruceTaiga", + "ExtremeHills", + "ExtremeHills_beach", + "ExtremeHillsM", + "ExtremeHills+", + "ExtremeHills+_snowtop", + "StoneBeach", + "Plains", + "Plains_beach", + "SunflowerPlains", + "Taiga", + "Taiga_beach", + "Forest", + "Forest_beach", + "FlowerForest", + "FlowerForest_beach", + "BirchForest", + "BirchForestM", + "RoofedForest", + "Savanna", + "Savanna_beach", + "SavannaM", + "Jungle", + "Jungle_shore", + "JungleM", + "JungleM_shore", + "JungleEdge", + "JungleEdgeM", + "Swampland", + "Swampland_shore" +}, +9, +minetest.LIGHT_MAX+1, +30, +15000, +3, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0) +mcl_mobs.register_egg("mobs_mc:sheep", S("Sheep"), "#e7e7e7", "#ffb5b5", 0) diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index faaf2ac40..ecf60debd 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -9,9 +9,29 @@ local S = minetest.get_translator("mobs_mc") --################### SHULKER --################### +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,1,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} +local function check_spot(pos) + pos = vector.offset(pos,0,0.5,0) + local n = minetest.get_node(pos) + if n.name ~="air" then return false end + for _,a in pairs(adjacents) do + local p = vector.add(pos,a) + local pn = minetest.get_node(p) + if minetest.get_item_group(pn.name,"solid") > 0 then return true end + end + return false +end +local pr = PseudoRandom(os.time()*(-334)) -- animation 45-80 is transition between passive and attack stance - -mobs:register_mob("mobs_mc:shulker", { +mcl_mobs.register_mob("mobs_mc:shulker", { + description = S("Shulker"), type = "monster", spawn_class = "hostile", attack_type = "shoot", @@ -32,9 +52,12 @@ mobs:register_mob("mobs_mc:shulker", { -- TODO: Make shulker dye-able visual_size = {x=3, y=3}, walk_chance = 0, + knock_back = false, jump = false, + can_despawn = false, + fall_speed = 0, drops = { - {name = mobs_mc.items.shulker_shell, + {name = "mcl_mobitems:shulker_shell", chance = 2, min = 1, max = 1, @@ -42,19 +65,94 @@ mobs:register_mob("mobs_mc:shulker", { looting_factor = 0.0625}, }, animation = { - stand_speed = 25, walk_speed = 25, run_speed = 50, punch_speed = 25, + stand_speed = 25, walk_speed = 0, run_speed = 50, punch_speed = 25, speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 45, - walk_start = 0, walk_end = 45, - run_start = 0, run_end = 45, + stand_start = 0, stand_end = 25, + walk_start = 25, walk_end = 45, + run_start = 45, run_end = 85, punch_start = 80, punch_end = 100, }, view_range = 16, - fear_height = 4, + fear_height = 0, + noyaw = true, + do_custom = function(self,dtime) + local pos = self.object:get_pos() + if math.floor(self.object:get_yaw()) ~=0 then + 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") + end + self.path.way = false + self.look_at_players = false + if not check_spot(pos) then + self:teleport(nil) + end + end, + do_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) + self:teleport(puncher) + end, + do_teleport = function(self, target) + if target ~= nil then + local target_pos = target:get_pos() + -- Find all solid nodes below air in a 10×10×10 cuboid centered on the target + local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"}) + local telepos + if nodes ~= nil then + if #nodes > 0 then + -- Up to 64 attempts to teleport + for n=1, math.min(64, #nodes) do + local r = pr:next(1, #nodes) + local nodepos = nodes[r] + local tg = vector.offset(nodepos,0,1,0) + if check_spot(tg) then + telepos = tg + node_ok = true + end + end + if telepos then + self.object:set_pos(telepos) + end + end + end + else + local pos = self.object:get_pos() + -- Up to 8 top-level attempts to teleport + for n=1, 8 do + local node_ok = false + -- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract(): + local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) ) + local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"}) + if nodes ~= nil then + if #nodes > 0 then + -- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport + for n=1, math.min(8, #nodes) do + local r = pr:next(1, #nodes) + local nodepos = nodes[r] + local tg = vector.offset(nodepos,0,0.5,0) + if check_spot(tg) then + self.object:set_pos(tg) + node_ok = true + break + end + end + end + end + if node_ok then + break + end + end + end + end, }) -- bullet arrow (weapon) -mobs:register_arrow("mobs_mc:shulkerbullet", { +mcl_mobs.register_arrow("mobs_mc:shulkerbullet", { visual = "sprite", visual_size = {x = 0.25, y = 0.25}, textures = {"mobs_mc_shulkerbullet.png"}, @@ -79,6 +177,21 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { }) -mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) - -mobs:spawn_specific("mobs_mc:shulker", mobs_mc.spawn.end_city, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 5000, 2, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +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) +--[[ +mcl_mobs:spawn_specific( +"mobs_mc:shulker", +"end", +"ground", +{ +"End" +}, +0, +minetest.LIGHT_MAX+1, +30, +5000, +2, +mcl_vars.mg_end_min, +mcl_vars.mg_end_max) +--]] diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 433211503..ab659a2a0 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -4,7 +4,8 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:silverfish", { +mcl_mobs.register_mob("mobs_mc:silverfish", { + description = S("Silverfish"), type = "monster", spawn_class = "hostile", passive = false, @@ -22,7 +23,7 @@ mobs:register_mob("mobs_mc:silverfish", { {"mobs_mc_silverfish.png"}, }, pathfinding = 1, - visual_size = {x=3, y=3}, + visual_size = {x = 3, y = 3}, sounds = { random = "mobs_mc_silverfish_idle", death = "mobs_mc_silverfish_death", @@ -34,99 +35,25 @@ mobs:register_mob("mobs_mc:silverfish", { run_velocity = 2, jump = true, fear_height = 4, - replace_what = mobs_mc.replace.silverfish, + replace_what = { + {"mcl_core:stone", "mcl_monster_eggs:monster_egg_stone", -1}, + {"mcl_core:cobble", "mcl_monster_eggs:monster_egg_cobble", -1}, + {"mcl_core:stonebrick", "mcl_monster_eggs:monster_egg_stonebrick", -1}, + {"mcl_core:stonebrickmossy", "mcl_monster_eggs:monster_egg_stonebrickmossy", -1}, + {"mcl_core:stonebrickcracked", "mcl_monster_eggs:monster_egg_stonebrickcracked", -1}, + {"mcl_core:stonebrickcarved", "mcl_monster_eggs:monster_egg_stonebrickcarved", -1}, + }, replace_rate = 2, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 0, stand_end = 20, - walk_start = 0, walk_end = 20, - run_start = 0, run_end = 20, + speed_normal = 25, speed_run = 50, + stand_start = 0, stand_end = 20, + walk_start = 0, walk_end = 20, + run_start = 0, run_end = 20, }, view_range = 16, attack_type = "dogfight", damage = 1, - reach = 1, }) -mobs:register_egg("mobs_mc:silverfish", S("Silverfish"), "mobs_mc_spawn_icon_silverfish.png", 0) - --- Monster egg blocks (Minetest Game) -if minetest.get_modpath("default") and mobs_mc.create_monster_egg_nodes then - local spawn_silverfish = function(pos, oldnode, oldmetadata, digger) - if not minetest.is_creative_enabled(digger:get_player_name()) then - minetest.add_entity(pos, "mobs_mc:silverfish") - end - end - minetest.register_node("mobs_mc:monster_egg_stone", { - description = "Stone Monster Egg", - tiles = {"default_stone.png"}, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - is_ground_content = true, - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_cobble", { - description = "Cobblestone Monster Egg", - tiles = {"default_cobble.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_mossycobble", { - description = "Mossy Cobblestone Monster Egg", - tiles = {"default_mossycobble.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_stonebrick", { - description = "Stone Brick Monster Egg", - paramtype2 = "facedir", - place_param2 = 0, - tiles = {"default_stone_brick.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - minetest.register_node("mobs_mc:monster_egg_stone_block", { - description = "Stone Block Monster Egg", - tiles = {"default_stone_block.png"}, - is_ground_content = false, - groups = {oddly_breakable_by_hand = 2, spawns_silverfish = 1}, - drop = '', - sounds = default.node_sound_stone_defaults(), - after_dig_node = spawn_silverfish, - }) - - -- Randomly spawn stone monster eggs in the world - local mg_name = minetest.get_mapgen_setting("mg_name") - local scarcity - if mg_name == "v6" then - scarcity = 28 * 28 * 28 - else - scarcity = 22 * 22 * 22 - end - minetest.register_ore({ - ore_type = "scatter", - ore = "mobs_mc:monster_egg_stone", - wherein = "default:stone", - clust_scarcity = scarcity, - clust_num_ores = 3, - clust_size = 2, - y_min = -31000, - y_max = 31000, - biomes = { "grassland" }, - }) - -end +mcl_mobs.register_egg("mobs_mc:silverfish", S("Silverfish"), "#6d6d6d", "#313131", 0) +mcl_mobs:non_spawn_specific("mobs_mc:silverfish","overworld",0,11) diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index cb12e905d..215047fdd 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -13,6 +13,7 @@ local mod_bows = minetest.get_modpath("mcl_bows") ~= nil local skeleton = { + description = S("Skeleton"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -24,36 +25,41 @@ local skeleton = { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3}, pathfinding = 1, group_attack = true, + head_swivel = "Head_Control", + bone_eye_height = 2.38, + curiosity = 6, visual = "mesh", mesh = "mobs_mc_skeleton.b3d", + shooter_avoid_enemy = true, + strafes = true, textures = { { "mcl_bows_bow_0.png", -- bow "mobs_mc_skeleton.png", -- skeleton } }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, - sounds = { - random = "mobs_mc_skeleton_random", - death = "mobs_mc_skeleton_death", - damage = "mobs_mc_skeleton_hurt", - distance = 16, + textures = { + { + "mobs_mc_empty.png", -- armor + "mobs_mc_skeleton.png", -- texture + "mcl_bows_bow_0.png", -- wielded_item + } }, walk_velocity = 1.2, - run_velocity = 2.4, + run_velocity = 2.0, damage = 2, reach = 2, drops = { - {name = mobs_mc.items.arrow, + {name = "mcl_bows:arrow", chance = 1, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.bow, + {name = "mcl_bows:bow", chance = 100 / 8.5, min = 1, max = 1, looting = "rare",}, - {name = mobs_mc.items.bone, + {name = "mcl_mobitems:bone", chance = 1, min = 0, max = 2, @@ -61,7 +67,7 @@ local skeleton = { -- Head -- TODO: Only drop if killed by charged creeper - {name = mobs_mc.items.head_skeleton, + {name = "mcl_heads:skeleton", chance = 200, -- 0.5% chance min = 1, max = 1,}, @@ -76,11 +82,19 @@ local skeleton = { run_speed = 30, shoot_start = 70, shoot_end = 90, + jockey_start = 172, + jockey_end = 172, die_start = 160, die_end = 170, die_speed = 15, die_loop = false, }, + on_spawn = function(self) + if math.random(100) == 1 then + self:jock_to("mobs_mc:spider", vector.zero(), vector.zero()) + end + return true + end, ignited_by_sunlight = true, view_range = 16, fear_height = 4, @@ -88,8 +102,10 @@ local skeleton = { arrow = "mcl_bows:arrow_entity", shoot_arrow = function(self, pos, dir) if mod_bows then - -- 2-4 damage per arrow - local dmg = math.max(4, math.random(2, 8)) + if self.attack then + 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) end end, @@ -100,7 +116,7 @@ local skeleton = { harmed_by_heal = true, } -mobs:register_mob("mobs_mc:skeleton", skeleton) +mcl_mobs.register_mob("mobs_mc:skeleton", skeleton) --################### @@ -108,12 +124,13 @@ mobs:register_mob("mobs_mc:skeleton", skeleton) --################### local stray = table.copy(skeleton) -stray.mesh = "mobs_mc_stray.b3d" +stray.description = S("Stray") +stray.mesh = "mobs_mc_skeleton.b3d" stray.textures = { { - "mcl_bows_bow_0.png", - "mobs_mc_stray.png", "mobs_mc_stray_overlay.png", + "mobs_mc_stray.png", + "mcl_bows_bow_0.png", }, } -- TODO: different sound (w/ echo) @@ -136,18 +153,196 @@ table.insert(stray.drops, { end, }) -mobs:register_mob("mobs_mc:stray", stray) +mcl_mobs.register_mob("mobs_mc:stray", stray) -- Overworld spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.solid, {"air"}, 0, 7, 20, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:skeleton", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +20, +17000, +2, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) + + -- Nether spawn -mobs:spawn_specific("mobs_mc:skeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 10000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) +mcl_mobs:spawn_specific( +"mobs_mc:skeleton", +"nether", +"ground", +{ +"SoulsandValley", +}, +0, +minetest.LIGHT_MAX+1, +30, +10000, +3, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) -- Stray spawn -- TODO: Spawn directly under the sky -mobs:spawn_specific("mobs_mc:stray", mobs_mc.spawn.snow, {"air"}, 0, 7, 20, 19000, 2, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:stray", +"overworld", +"ground", +{ +"ColdTaiga", +"IcePlainsSpikes", +"IcePlains", +"ExtremeHills+_snowtop", +}, +0, +7, +20, +19000, +2, +mobs_mc.water_level, +mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0) -mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0) +mcl_mobs.register_egg("mobs_mc:skeleton", S("Skeleton"), "#c1c1c1", "#494949", 0) + +mcl_mobs.register_egg("mobs_mc:stray", S("Stray"), "#5f7476", "#dae8e7", 0) diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index e4a1f86fc..314260581 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -9,7 +9,8 @@ local S = minetest.get_translator("mobs_mc") --################### WITHER SKELETON --################### -mobs:register_mob("mobs_mc:witherskeleton", { +mcl_mobs.register_mob("mobs_mc:witherskeleton", { + description = S("Wither Skeleton"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -23,13 +24,17 @@ mobs:register_mob("mobs_mc:witherskeleton", { collisionbox = {-0.35, -0.01, -0.35, 0.35, 2.39, 0.35}, visual = "mesh", mesh = "mobs_mc_witherskeleton.b3d", + head_swivel = "head.control", + bone_eye_height = 2.38, + curiosity = 60, textures = { { + "mobs_mc_empty.png", -- armor "default_tool_stonesword.png", -- sword "mobs_mc_wither_skeleton.png", -- wither skeleton } }, - visual_size = {x=3.6, y=3.6}, + visual_size = {x=1.2, y=1.2}, makes_footstep_sound = true, sounds = { random = "mobs_mc_skeleton_random", @@ -38,23 +43,23 @@ mobs:register_mob("mobs_mc:witherskeleton", { distance = 16, }, walk_velocity = 1.2, - run_velocity = 2.4, + run_velocity = 2.0, damage = 7, reach = 2, drops = { - {name = mobs_mc.items.coal, + {name = "mcl_core:coal_lump", chance = 1, min = 0, max = 1, looting = "common",}, - {name = mobs_mc.items.bone, + {name = "mcl_mobitems:bone", chance = 1, min = 0, max = 2, looting = "common",}, -- Head - {name = mobs_mc.items.head_wither_skeleton, + {name = "mcl_heads:wither_skeleton", chance = 40, -- 2.5% chance min = 1, max = 1, @@ -94,7 +99,23 @@ mobs:register_mob("mobs_mc:witherskeleton", { }) --spawn -mobs:spawn_specific("mobs_mc:witherskeleton", mobs_mc.spawn.nether_fortress, {"air"}, 0, 7, 30, 5000, 5, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) - +--[[] +mcl_mobs:spawn_specific( +"mobs_mc:witherskeleton", +"nether", +"ground", +{ +"Nether", +"SoulsandValley", +}, +0, +7, +30, +5000, +5, +mcl_vars.mg_nether_min, +mcl_vars.mg_nether_max) +--]] -- spawn eggs -mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0) +mcl_mobs.register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "#141414", "#474d4d", 0) +mcl_mobs:non_spawn_specific("mobs_mc:witherskeleton","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 98c29870c..c07afb6b1 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -1,65 +1,171 @@ --License for code WTFPL and otherwise stated in readmes - local S = minetest.get_translator("mobs_mc") +local MAPBLOCK_SIZE = 16 + +local seed = minetest.get_mapgen_setting("seed") + +local slime_chunk_match +local x_modifier +local z_modifier + +local function split_by_char (inputstr, sep, limit) + if sep == nil then + sep = "%d" + end + local t = {} + + local i = 0 + for str in string.gmatch(inputstr, "(["..sep.."])") do + i = i --+ 1 + table.insert(t, tonumber(str)) + if limit and i >= limit then + break + end + end + return t +end + +--Seed: "16002933932875202103" == random seed +--Seed: "1807191622654296300" == cheese +--Seed: "1" = 1 +local function process_seed (seed) + --minetest.log("seed: " .. seed) + + local split_chars = split_by_char(tostring(seed), nil, 10) + + slime_chunk_match = split_chars[1] + x_modifier = split_chars[2] + z_modifier = split_chars[3] + + --minetest.log("x_modifier: " .. tostring(x_modifier)) + --minetest.log("z_modifier: " .. tostring(z_modifier)) + --minetest.log("slime_chunk_match: " .. tostring(slime_chunk_match)) +end + +local processed = process_seed (seed) + + +local function convert_to_chunk_value (co_ord, modifier) + local converted = math.floor(math.abs(co_ord) / MAPBLOCK_SIZE) + + if modifier then + converted = (converted + modifier) + end + converted = converted % 10 + + --minetest.log("co_ord: " .. co_ord) + --minetest.log("converted: " .. converted) + return converted +end + +assert(convert_to_chunk_value(-16) == 1, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(-15) == 0, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(-1) == 0, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(0) == 0, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(1) == 0, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(15) == 0, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(16) == 1, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(31) == 1, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(32) == 2, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(1599) == 9, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(1600) == 0, "Incorrect convert_to_chunk_value result") + +assert(convert_to_chunk_value(0,9) == 9, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(16,5) == 6, "Incorrect convert_to_chunk_value result") +assert(convert_to_chunk_value(1599,4) == 3, "Incorrect convert_to_chunk_value result") + +local function calculate_chunk_value (pos, x_mod, z_mod) + local chunk_val = math.abs(convert_to_chunk_value(pos.x, x_mod) - convert_to_chunk_value(pos.z, z_mod)) % 10 + return chunk_val +end + +assert(calculate_chunk_value(vector.new(0,0,0)) == 0, "calculate_chunk_value failed") +assert(calculate_chunk_value(vector.new(0,0,0), 1, 1) == 0, "calculate_chunk_value failed") +assert(calculate_chunk_value(vector.new(0,0,0), 2, 1) == 1, "calculate_chunk_value failed") +assert(calculate_chunk_value(vector.new(64,0,16)) == (4-1), "calculate_chunk_value failed") +assert(calculate_chunk_value(vector.new(16,0,64)) == (3), "calculate_chunk_value failed") +assert(calculate_chunk_value(vector.new(-160,0,-160)) == 0, "calculate_chunk_value failed") + +local function is_slime_chunk(pos) + if not pos then return end + + local chunk_val = calculate_chunk_value (pos, x_modifier, z_modifier) + local slime_chunk = chunk_val == slime_chunk_match + + --minetest.log("x: " ..pos.x .. ", z:" .. pos.z) + + --minetest.log("seed slime_chunk_match: " .. tostring(slime_chunk_match)) + --minetest.log("chunk_val: " .. tostring(chunk_val)) + --minetest.log("Is slime chunk: " .. tostring(slime_chunk)) + return slime_chunk +end + +local check_position = function (pos) + return is_slime_chunk(pos) +end + + -- Returns a function that spawns children in a circle around pos. -- To be used as on_die callback. -- self: mob reference -- pos: position of "mother" mob -- child_mod: Mob to spawn --- children_count: Number of children to spawn -- spawn_distance: Spawn distance from "mother" mob -- eject_speed: Initial speed of child mob away from "mother" mob -local spawn_children_on_die = function(child_mob, children_count, spawn_distance, eject_speed) +local spawn_children_on_die = function(child_mob, spawn_distance, eject_speed) return function(self, pos) - local angle, posadd, newpos, dir + local posadd, newpos, dir if not eject_speed then eject_speed = 1 end - local mother_stuck = minetest.registered_nodes[minetest.get_node(pos).name].walkable - angle = math.random(0, math.pi*2) + local mndef = minetest.registered_nodes[minetest.get_node(pos).name] + local mother_stuck = mndef and mndef.walkable + local angle = math.random(0, math.pi*2) local children = {} - for i=1,children_count do - dir = {x=math.cos(angle),y=0,z=math.sin(angle)} - posadd = vector.multiply(vector.normalize(dir), spawn_distance) - newpos = vector.add(pos, posadd) + local spawn_count = math.random(2, 4) + for i = 1, spawn_count do + dir = vector.new(math.cos(angle), 0, math.sin(angle)) + posadd = vector.normalize(dir) * spawn_distance + newpos = pos + posadd -- If child would end up in a wall, use position of the "mother", unless -- the "mother" was stuck as well - local speed_penalty = 1 - if (not mother_stuck) and minetest.registered_nodes[minetest.get_node(newpos).name].walkable then - newpos = pos - speed_penalty = 0.5 + if not mother_stuck then + local cndef = minetest.registered_nodes[minetest.get_node(newpos).name] + if cndef and cndef.walkable then + newpos = pos + eject_speed = eject_speed * 0.5 + end end local mob = minetest.add_entity(newpos, child_mob) - if (not mother_stuck) then - mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty)) + if not mother_stuck then + mob:set_velocity(dir * eject_speed) end mob:set_yaw(angle - math.pi/2) table.insert(children, mob) - angle = angle + (math.pi*2)/children_count + angle = angle + (math.pi*2) / spawn_count end -- If mother was murdered, children attack the killer after 1 second if self.state == "attack" then minetest.after(1.0, function(children, enemy) - for c=1, #children do - local child = children[c] - local le = child:get_luaentity() - if le ~= nil then + local le + for c = 1, #children do + le = children[c]:get_luaentity() + if le then le.state = "attack" le.attack = enemy end end end, children, self.attack) end - return true end end -- Slime local slime_big = { + description = S("Slime"), type = "monster", spawn_class = "hostile", - pathfinding = 1, group_attack = { "mobs_mc:slime_big", "mobs_mc:slime_small", "mobs_mc:slime_tiny" }, hp_min = 16, hp_max = 16, @@ -67,7 +173,7 @@ local slime_big = { xp_max = 4, collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, visual_size = {x=12.5, y=12.5}, - textures = {{"mobs_mc_slime.png"}}, + textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}}, visual = "mesh", mesh = "mobs_mc_slime.b3d", makes_footstep_sound = true, @@ -84,34 +190,31 @@ local slime_big = { drops = {}, -- TODO: Fix animations animation = { - speed_normal = 24, - speed_run = 48, - stand_start = 0, - stand_end = 23, - walk_start = 24, - walk_end = 47, - run_start = 48, - run_end = 62, - hurt_start = 64, - hurt_end = 86, - death_start = 88, - death_end = 118, + jump_speed = 17, + stand_speed = 17, + walk_speed = 17, + jump_start = 1, + jump_end = 20, + stand_start = 1, + stand_end = 20, + walk_start = 1, + walk_end = 20, }, fall_damage = 0, view_range = 16, attack_type = "dogfight", passive = false, jump = true, - walk_velocity = 2.5, - run_velocity = 2.5, + walk_velocity = 1.9, + run_velocity = 1.9, walk_chance = 0, jump_height = 5.2, fear_height = 0, spawn_small_alternative = "mobs_mc:slime_small", - on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), - fire_resistant = true, + on_die = spawn_children_on_die("mobs_mc:slime_small", 1.0, 1.5), + use_texture_alpha = true, } -mobs:register_mob("mobs_mc:slime_big", slime_big) +mcl_mobs.register_mob("mobs_mc:slime_big", slime_big) local slime_small = table.copy(slime_big) slime_small.sounds.base_pitch = 1.15 @@ -123,12 +226,12 @@ slime_small.collisionbox = {-0.51, -0.01, -0.51, 0.51, 1.00, 0.51} slime_small.visual_size = {x=6.25, y=6.25} slime_small.damage = 3 slime_small.reach = 2.75 -slime_small.walk_velocity = 1.3 -slime_small.run_velocity = 1.3 +slime_small.walk_velocity = 1.8 +slime_small.run_velocity = 1.8 slime_small.jump_height = 4.3 slime_small.spawn_small_alternative = "mobs_mc:slime_tiny" -slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0) -mobs:register_mob("mobs_mc:slime_small", slime_small) +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.sounds.base_pitch = 1.3 @@ -142,28 +245,146 @@ slime_tiny.damage = 0 slime_tiny.reach = 2.5 slime_tiny.drops = { -- slimeball - {name = mobs_mc.items.slimeball, + {name = "mcl_mobitems:slimeball", chance = 1, min = 0, max = 2,}, } -slime_tiny.walk_velocity = 0.7 -slime_tiny.run_velocity = 0.7 +slime_tiny.walk_velocity = 1.7 +slime_tiny.run_velocity = 1.7 slime_tiny.jump_height = 3 slime_tiny.spawn_small_alternative = nil slime_tiny.on_die = nil -mobs:register_mob("mobs_mc:slime_tiny", slime_tiny) +mcl_mobs.register_mob("mobs_mc:slime_tiny", slime_tiny) -local smin = mobs_mc.spawn_height.overworld_min -local smax = mobs_mc.spawn_height.water - 23 +local water_level = mobs_mc.water_level -mobs:spawn_specific("mobs_mc:slime_tiny", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 12000, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_small", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8500, 4, smin, smax) -mobs:spawn_specific("mobs_mc:slime_big", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 10000, 4, smin, smax) +local cave_biomes = { + "FlowerForest_underground", + "JungleEdge_underground", + "StoneBeach_underground", + "MesaBryce_underground", + "Mesa_underground", + "RoofedForest_underground", + "Jungle_underground", + "Swampland_underground", + "BirchForest_underground", + "Plains_underground", + "MesaPlateauF_underground", + "ExtremeHills_underground", + "MegaSpruceTaiga_underground", + "BirchForestM_underground", + "SavannaM_underground", + "MesaPlateauFM_underground", + "Desert_underground", + "Savanna_underground", + "Forest_underground", + "SunflowerPlains_underground", + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "ExtremeHills+_underground", + "JungleM_underground", + "ExtremeHillsM_underground", + "JungleEdgeM_underground", + "MangroveSwamp_underground" +} + +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 + +mcl_mobs:spawn_specific( +"mobs_mc:slime_tiny", +"overworld", +"ground", +cave_biomes, +0, +minetest.LIGHT_MAX+1, +30, +12000, +4, +cave_min, +cave_max, +nil, nil, check_position) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_tiny", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +12000, +4, +swamp_min, +swamp_max) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_small", +"overworld", +"ground", +cave_biomes, +0, +minetest.LIGHT_MAX+1, +30, +8500, +4, +cave_min, +cave_max, +nil, nil, check_position) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_small", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +8500, +4, +swamp_min, +swamp_max) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_big", +"overworld", +"ground", +cave_biomes, +0, +minetest.LIGHT_MAX+1, +30, +10000, +4, +cave_min, +cave_max, +nil, nil, check_position) + +mcl_mobs:spawn_specific( +"mobs_mc:slime_big", +"overworld", +"ground", +swampy_biomes, +0, +swamp_light_max, +30, +10000, +4, +swamp_min, +swamp_max) -- Magma cube local magma_cube_big = { + description = S("Magma Cube"), type = "monster", spawn_class = "hostile", hp_min = 16, @@ -172,7 +393,7 @@ local magma_cube_big = { xp_max = 4, collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02}, visual_size = {x=12.5, y=12.5}, - textures = {{ "mobs_mc_magmacube.png" }}, + textures = {{ "mobs_mc_magmacube.png", "mobs_mc_magmacube.png" }}, visual = "mesh", mesh = "mobs_mc_magmacube.b3d", makes_footstep_sound = true, @@ -182,31 +403,28 @@ local magma_cube_big = { attack = "mobs_mc_magma_cube_attack", distance = 16, }, - walk_velocity = 4, - run_velocity = 4, + walk_velocity = 2.5, + run_velocity = 2.5, damage = 6, reach = 3, armor = 53, drops = { - {name = mobs_mc.items.magma_cream, + {name = "mcl_mobitems:magma_cream", chance = 4, min = 1, max = 1,}, }, -- TODO: Fix animations animation = { - speed_normal = 24, - speed_run = 48, - stand_start = 0, - stand_end = 23, - walk_start = 24, - walk_end = 47, - run_start = 48, - run_end = 62, - hurt_start = 64, - hurt_end = 86, - death_start = 88, - death_end = 118, + jump_speed = 20, + stand_speed = 20, + walk_speed = 20, + jump_start = 1, + jump_end = 40, + stand_start = 1, + stand_end = 1, + walk_start = 1, + walk_end = 40, }, water_damage = 0, lava_damage = 0, @@ -221,10 +439,10 @@ local magma_cube_big = { walk_chance = 0, fear_height = 0, spawn_small_alternative = "mobs_mc:magma_cube_small", - on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5), + on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 0.8, 1.5), fire_resistant = true, } -mobs:register_mob("mobs_mc:magma_cube_big", 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.sounds.jump = "mobs_mc_magma_cube_small" @@ -238,14 +456,14 @@ 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.walk_velocity = .8 -magma_cube_small.run_velocity = 2.6 +magma_cube_small.run_velocity = 2.0 magma_cube_small.jump_height = 6 magma_cube_small.damage = 4 magma_cube_small.reach = 2.75 magma_cube_small.armor = 66 magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny" -magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0) -mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small) +magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 0.6, 1.0) +mcl_mobs.register_mob("mobs_mc:magma_cube_small", magma_cube_small) local magma_cube_tiny = table.copy(magma_cube_big) magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small" @@ -267,21 +485,60 @@ magma_cube_tiny.drops = {} magma_cube_tiny.spawn_small_alternative = nil magma_cube_tiny.on_die = nil -mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) +mcl_mobs.register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny) -local mmin = mobs_mc.spawn_height.nether_min -local mmax = mobs_mc.spawn_height.nether_max +local magma_cube_biomes = {"Nether", "BasaltDelta"} +local nether_min = mcl_vars.mg_nether_min +local nether_max = mcl_vars.mg_nether_max -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 15500, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 16000, 4, mmin, mmax) +mcl_mobs:spawn_specific( +"mobs_mc:magma_cube_tiny", +"nether", +"ground", +magma_cube_biomes, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +nether_min, +nether_max) -mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax) -mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax) +mcl_mobs:spawn_specific( +"mobs_mc:magma_cube_small", +"nether", +"ground", +magma_cube_biomes, +0, +minetest.LIGHT_MAX+1, +30, +15500, +4, +nether_min, +nether_max) +mcl_mobs:spawn_specific( +"mobs_mc:magma_cube_big", +"nether", +"ground", +magma_cube_biomes, +0, +minetest.LIGHT_MAX+1, +30, +16000, +4, +nether_min, +nether_max) -- spawn eggs -mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png") -mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png") +mcl_mobs.register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "#350000", "#fcfc00") + +-- non_spawn_specific is typically for mobs who don't spawn in the overworld, or mobs that don't spawn +-- naturally. However, slimes are a particular case where they spawn under different conditions in the same +-- dimension. +mcl_mobs:non_spawn_specific("mobs_mc:slime_big","overworld",0,minetest.LIGHT_MAX+1) +mcl_mobs:non_spawn_specific("mobs_mc:magma_cube_big","overworld",0, minetest.LIGHT_MAX+1) +mcl_mobs.register_egg("mobs_mc:slime_big", S("Slime"), "#52a03e", "#7ebf6d") + +-- FIXME: add spawn eggs for small and tiny slimes and magma cubes diff --git a/mods/ENTITIES/mobs_mc/snowman.lua b/mods/ENTITIES/mobs_mc/snowman.lua index 1ee88b362..ec2a14675 100644 --- a/mods/ENTITIES/mobs_mc/snowman.lua +++ b/mods/ENTITIES/mobs_mc/snowman.lua @@ -20,7 +20,8 @@ local gotten_texture = { "blank.png", } -mobs:register_mob("mobs_mc:snowman", { +mcl_mobs.register_mob("mobs_mc:snowman", { + description = S("Snow Golem"), type = "npc", spawn_class = "passive", passive = true, @@ -51,7 +52,7 @@ mobs:register_mob("mobs_mc:snowman", { "farming_pumpkin_top.png", --left }, gotten_texture = gotten_texture, - drops = {{ name = mobs_mc.items.snowball, chance = 1, min = 0, max = 15 }}, + drops = {{ name = "mcl_throwing:snowball", chance = 1, min = 0, max = 15 }}, visual_size = {x=3, y=3}, walk_velocity = 0.6, run_velocity = 2, @@ -105,7 +106,7 @@ mobs:register_mob("mobs_mc:snowman", { local belowdef = minetest.registered_nodes[minetest.get_node(below).name] if belowdef and belowdef.walkable and (belowdef.node_box == nil or belowdef.node_box.type == "regular") then -- Place top snow - minetest.set_node(pos, {name = mobs_mc.items.top_snow}) + minetest.set_node(pos, {name = "mcl_core:snow"}) end end end @@ -113,7 +114,7 @@ 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() == mobs_mc.items.shears then + if self.gotten ~= true and item:get_name() == "mcl_tools:shears" then -- Remove pumpkin self.gotten = true self.object:set_properties({ @@ -123,9 +124,13 @@ mobs:register_mob("mobs_mc:snowman", { local pos = self.object:get_pos() minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true) + if minetest.registered_items["mcl_farming:pumpkin_face"] then + minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_farming:pumpkin_face") + end + -- Wear out if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:add_wear(mobs_mc.misc.shears_wear) + item:add_wear(mobs_mc.shears_wear) clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item) end end @@ -155,7 +160,7 @@ end -- This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function -- of the node. -- This summons a snow golen when pos is next to a row of two snow blocks. -mobs_mc.tools.check_snow_golem_summon = function(pos) +function mobs_mc.check_snow_golem_summon(pos) local checks = { -- These are the possible placement patterns -- { snow block pos. 1, snow block pos. 2, snow golem spawn position } @@ -173,7 +178,7 @@ mobs_mc.tools.check_snow_golem_summon = function(pos) local place = checks[c][3] local b1n = minetest.get_node(b1) local b2n = minetest.get_node(b2) - if b1n.name == mobs_mc.items.snow_block and b2n.name == mobs_mc.items.snow_block then + if b1n.name == "mcl_core:snowblock" and b2n.name == "mcl_core:snowblock" then -- Remove the pumpkin and both snow blocks and summon the snow golem minetest.remove_node(pos) minetest.remove_node(b1) @@ -191,4 +196,5 @@ mobs_mc.tools.check_snow_golem_summon = function(pos) end -- Spawn egg -mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0) +mcl_mobs.register_egg("mobs_mc:snowman", S("Snow Golem"), "#f2f2f2", "#fd8f47", 0) +mcl_mobs:non_spawn_specific("mobs_mc:snowman","overworld",0,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg new file mode 100644 index 000000000..b3d9c5967 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg new file mode 100644 index 000000000..11141f6cc Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg new file mode 100644 index 000000000..dddf298b6 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_axolotl_hurt.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg new file mode 100644 index 000000000..38ef59445 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg new file mode 100644 index 000000000..b5766734e Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_grunt2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg new file mode 100644 index 000000000..37e7620ef Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg new file mode 100644 index 000000000..0983ae4bb Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_pillager_ow2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg new file mode 100644 index 000000000..beae2bf1f Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg new file mode 100644 index 000000000..39939308c Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg new file mode 100644 index 000000000..148fbd48b Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg new file mode 100644 index 000000000..a1c5c24dd Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.4.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg new file mode 100644 index 000000000..5b436af59 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.5.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg new file mode 100644 index 000000000..50c4fa99a Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.6.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg new file mode 100644 index 000000000..8054e1349 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager.7.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg new file mode 100644 index 000000000..b72b8b83f Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg new file mode 100644 index 000000000..6de7085b0 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_accept.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg new file mode 100644 index 000000000..6c96f57b8 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg new file mode 100644 index 000000000..a7568a3d6 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_hurt.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg new file mode 100644 index 000000000..f17771367 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.1.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg new file mode 100644 index 000000000..763bf9132 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.2.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg new file mode 100644 index 000000000..e012ed349 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.3.ogg differ diff --git a/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg new file mode 100644 index 000000000..51d808f52 Binary files /dev/null and b/mods/ENTITIES/mobs_mc/sounds/mobs_mc_villager_trade.4.ogg differ diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index 0bb03a9c7..65d3a2d21 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -11,8 +11,26 @@ local S = minetest.get_translator("mobs_mc") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture) +minetest.register_entity("mobs_mc:spider_eyes", { + pointable = false, + visual = "mesh", + mesh = "mobs_mc_spider.b3d", + visual_size = {x=1.01/3, y=1.01/3}, + textures = { + "mobs_mc_spider_eyes.png", + }, + on_step = function(self) + if self and self.object then + if not self.object:get_attach() then + self.object:remove() + end + end + end, + glow = 50, +}) local spider = { + description = S("Spider"), type = "monster", spawn_class = "hostile", passive = false, @@ -26,13 +44,35 @@ local spider = { xp_min = 5, xp_max = 5, armor = {fleshy = 100, arthropod = 100}, + on_spawn = function(self) + self.object:set_properties({visual_size={x=1,y=1}}) + 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:spider_eyes" then + spider_eyes = true + end + end + if not spider_eyes then + minetest.add_entity(self.object:get_pos(), "mobs_mc:spider_eyes"):set_attach(self.object, "body.head", vector.new(0,-0.98,2), vector.new(90,180,180)) + end + end, + on_die=function(self) + if self.object:get_children() and self.object:get_children()[1] then + self.object:get_children()[1]:set_detach() + end + end, + head_swivel = "Head_Control", + bone_eye_height = 1, + curiosity = 10, + head_yaw="z", collisionbox = {-0.7, -0.01, -0.7, 0.7, 0.89, 0.7}, visual = "mesh", mesh = "mobs_mc_spider.b3d", textures = { - {"mobs_mc_spider.png^(mobs_mc_spider_eyes.png^[makealpha:0,0,0)"}, + {"mobs_mc_spider.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=1, y=1}, makes_footstep_sound = false, sounds = { random = "mobs_mc_spider_random", @@ -43,14 +83,14 @@ local spider = { distance = 16, }, walk_velocity = 1.3, - run_velocity = 2.8, + run_velocity = 2.4, jump = true, jump_height = 4, view_range = 16, floats = 1, drops = { - {name = mobs_mc.items.string, chance = 1, min = 0, max = 2, looting = "common"}, - {name = mobs_mc.items.spider_eye, chance = 3, min = 1, max = 1, looting = "common", looting_chance_function = function(lvl) + {name = "mcl_mobitems:string", chance = 1, min = 0, max = 2, looting = "common"}, + {name = "mcl_mobitems:spider_eye", chance = 3, min = 1, max = 1, looting = "common", looting_chance_function = function(lvl) return 1 - 2 / (lvl + 3) end}, }, @@ -68,27 +108,189 @@ local spider = { run_end = 20, }, } -mobs:register_mob("mobs_mc:spider", spider) +mcl_mobs.register_mob("mobs_mc:spider", spider) -- Cave 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.hp_min = 1 cave_spider.hp_max = 12 -cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.49, 0.35} -cave_spider.visual_size = {x=1.66666, y=1.5} +cave_spider.collisionbox = {-0.35, -0.01, -0.35, 0.35, 0.46, 0.35} +cave_spider.visual_size = {x=0.55,y=0.5} +cave_spider.on_spawn = function(self) + self.object:set_properties({visual_size={x=0.55,y=0.5}}) + 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:spider_eyes" then + spider_eyes = true + end + end + if not spider_eyes then + minetest.add_entity(self.object:get_pos(), "mobs_mc:spider_eyes"):set_attach(self.object, "body.head", vector.new(0,-0.98,2), vector.new(90,180,180)) + end +end 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 -mobs:register_mob("mobs_mc:cave_spider", cave_spider) +mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider) -mobs:spawn_specific("mobs_mc:spider", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 17000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:spider", +"overworld", +"ground", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +7, +30, +17000, +2, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) + +mcl_mobs:non_spawn_specific("mobs_mc:cave_spider","overworld",0,7) -- spawn eggs -mobs:register_egg("mobs_mc:spider", S("Spider"), "mobs_mc_spawn_icon_spider.png", 0) -mobs:register_egg("mobs_mc:cave_spider", S("Cave Spider"), "mobs_mc_spawn_icon_cave_spider.png", 0) +mcl_mobs.register_egg("mobs_mc:spider", S("Spider"), "#342d26", "#a80e0e", 0) +mcl_mobs.register_egg("mobs_mc:cave_spider", S("Cave Spider"), "#0c424e", "#a80e0e", 0) diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index 1877a2104..a692fd8d4 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -6,7 +6,8 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:squid", { +mcl_mobs.register_mob("mobs_mc:squid", { + description = S("Squid"), type = "animal", spawn_class = "water", can_despawn = true, @@ -39,7 +40,7 @@ mobs:register_mob("mobs_mc:squid", { run_end = 60, }, drops = { - {name = mobs_mc.items.black_dye, + {name = "mcl_mobitems:ink_sac", chance = 1, min = 1, max = 3, @@ -48,7 +49,7 @@ mobs:register_mob("mobs_mc:squid", { visual_size = {x=3, y=3}, makes_footstep_sound = false, fly = true, - fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source }, + fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" }, breathes_in_water = true, jump = false, view_range = 16, @@ -60,9 +61,160 @@ mobs:register_mob("mobs_mc:squid", { -- Spawn near the water surface -local water = mobs_mc.spawn_height.water +local water = mobs_mc.water_level --name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height -mobs:spawn_specific("mobs_mc:squid", mobs_mc.spawn.water, {mobs_mc.items.water_source}, 0, minetest.LIGHT_MAX+1, 30, 5500, 3, water-16, water) +mcl_mobs:spawn_specific( +"mobs_mc:squid", +"overworld", +"water", +{ +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"MushroomIsland", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"MushroomIslandShore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"RoofedForest_ocean", +"JungleEdgeM_ocean", +"BirchForestM_ocean", +"BirchForest_ocean", +"IcePlains_deep_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"ExtremeHillsM_deep_ocean", +"Savanna_deep_ocean", +"SunflowerPlains_ocean", +"Swampland_deep_ocean", +"Swampland_ocean", +"MegaSpruceTaiga_deep_ocean", +"ExtremeHillsM_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"BirchForest_deep_ocean", +"IcePlainsSpikes_ocean", +"Mesa_ocean", +"StoneBeach_ocean", +"Plains_deep_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"ColdTaiga_deep_ocean", +"Plains_ocean", +"MesaPlateauFM_ocean", +"Forest_deep_ocean", +"JungleM_deep_ocean", +"FlowerForest_deep_ocean", +"MushroomIsland_ocean", +"MegaTaiga_ocean", +"StoneBeach_deep_ocean", +"IcePlainsSpikes_deep_ocean", +"ColdTaiga_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"ExtremeHills+_deep_ocean", +"ExtremeHills_ocean", +"MushroomIsland_deep_ocean", +"Forest_ocean", +"MegaTaiga_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"MegaSpruceTaiga_ocean", +"ExtremeHills+_ocean", +"Jungle_ocean", +"RoofedForest_deep_ocean", +"IcePlains_ocean", +"FlowerForest_ocean", +"ExtremeHills_deep_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"Taiga_ocean", +"BirchForestM_deep_ocean", +"Taiga_deep_ocean", +"JungleM_ocean", +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"MushroomIsland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +5500, +3, +water-16, +water+1) -- spawn eggs -mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0) +mcl_mobs.register_egg("mobs_mc:squid", S("Squid"), "#223b4d", "#708999", 0) diff --git a/mods/ENTITIES/mobs_mc/strider.lua b/mods/ENTITIES/mobs_mc/strider.lua new file mode 100644 index 000000000..142025e06 --- /dev/null +++ b/mods/ENTITIES/mobs_mc/strider.lua @@ -0,0 +1,249 @@ +--MCmobs v0.4 +--maikerumine +--made for MC like Survival game +--License for code WTFPL and otherwise stated in readmes + +local S = minetest.get_translator("mobs_mc") + +--################### +--################### STRIDER +--################### + + +local strider = { + type = "animal", + passive = true, + spawn_class = "passive", + hp_min = 20, + hp_max = 20, + xp_min = 9, + xp_max = 9, + armor = {fleshy = 90}, + attack_type = "dogfight", + damage = 2, + reach = 2, + collisionbox = {-.6, -0.01, -.6, .6, 1.94, .6}, + visual = "mesh", + mesh = "extra_mobs_strider.b3d", + textures = { { + "extra_mobs_strider.png", + } }, + visual_size = {x=3, y=3}, + sounds = { + }, + jump = true, + makes_footstep_sound = true, + walk_velocity = 2, + run_velocity = 4, + runaway = true, + drops = { + {name = "mcl_mobsitems:string", + chance = 1, + min = 2, + max = 5,}, + }, + animation = { + stand_speed = 15, + walk_speed = 15, + run_speed = 30, + stand_start = 5, + stand_end = 5, + walk_start = 1, + walk_end = 20, + }, + lava_damage = 0, + fire_damage = 0, + light_damage = 0, + water_damage = 5, + fear_height = 4, + view_range = 16, + fire_resistant = true, + floats_on_lava = 1, + floats = 0, + can_spawn = function(pos) + local l = minetest.find_node_near(pos,2,{"mcl_nether:nether_lava_source","mcl_nether:nether_lava_flowing"}) + return l ~= nil + end, + 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 + self.base_texture[1] = "extra_mobs_strider.png" + self.shaking = false + else + self.base_texture[1] = "extra_mobs_strider_cold.png" + self.walk_velocity = .5 + self.run_velocity = 1 + self.shaking = true + end + + self.object:set_properties({textures=self.base_texture, shaking=self.shaking, run_velocity=self.run_velocity, walk_velocity=self.walk_velocity}) + + -- set needed values if not already present + if not self.v2 then + self.v2 = 0 + self.max_speed_forward = 8 + self.max_speed_reverse = 4 + self.accel = 2 + self.terrain_type = 3 + self.driver_attach_at = {x = 0, y = 5.5, z = -1.75} + self.driver_eye_offset = {x = 0, y = 10, z = 0} + self.driver_scale = {x = 1/self.visual_size.x, y = 1/self.visual_size.y} + end + + -- if driver present allow control of horse + if self.driver then + local pos = self.object:get_pos() + local v = self.object:get_velocity() + self.object:set_velocity(vector.new(v.x,0,v.z)) + mcl_mobs.drive(self, "walk", "stand", false, dtime) + local l = minetest.find_node_near(pos,2,{"group:lava"}) + if l then self.object:set_pos(vector.new(pos.x,l.y+0.5,pos.z)) end + return false -- skip rest of mob functions + end + + return true + end, + + on_die = function(self, pos) + + -- drop saddle when horse is killed while riding + -- also detach from horse properly + if self.driver then + mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1}) + end + end, + + on_rightclick = function(self, clicker) + if not clicker or not clicker:is_player() then + return + end + + local wielditem = clicker:get_wielded_item() + + if wielditem:get_name() ~= "mcl_crimson:warped_fungus" then + if self:feed_tame(clicker, 1, true, true) then return end + end + + if self.child then + return + end + + local item = clicker:get_wielded_item() + if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then + self.base_texture = { + "extra_mobs_strider.png", + "mobs_mc_pig_saddle.png", -- saddle + } + self.object:set_properties({ + textures = self.base_texture + }) + self.saddle = "yes" + self.tamed = true + self.drops = { + {name = "mcl_mobitems:string", + chance = 1, + min = 1, + max = 3,}, + {name = "mcl_mobitems:saddle", + chance = 1, + min = 1, + max = 1,}, + } + if not minetest.is_creative_enabled(clicker:get_player_name()) then + wielditem:take_item(1) + clicker:get_inventory():set_stack("main", clicker:get_wield_index(), wielditem) + end + minetest.sound_play({name = "mcl_armor_equip_leather"}, {gain=0.5, max_hear_distance=8, pos=self.object:get_pos()}, true) + return + end + + -- Mount or detach player + local name = clicker:get_player_name() + if self.driver and clicker == self.driver then + -- Detach if already attached + mcl_mobs.detach(clicker, {x=1, y=0, z=0}) + return + + elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == "mcl_mobitems:warped_fungus_on_a_stick" then + -- Ride pig if it has a saddle and player uses a carrot on a stick + + mcl_mobs.attach(self, clicker) + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + + local inv = self.driver:get_inventory() + -- 26 uses + if wielditem:get_wear() > 63000 then + -- Break carrot on a stick + local def = wielditem:get_definition() + if def.sounds and def.sounds.breaks then + minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true) + end + wielditem = {name = mobs_mc.items.fishing_rod, count = 1} + else + wielditem:add_wear(2521) + end + inv:set_stack("main",self.driver:get_wield_index(), wielditem) + end + return + end + end, +} + +mcl_mobs.register_mob("mobs_mc:strider", strider) + +-- Baby strider. + +local baby_strider = table.copy(strider) +baby_strider.collisionbox = {-.3, -0.01, -.3, .3, 0.94, .3} +baby_strider.xp_min = 13 +baby_strider.xp_max = 13 +textures = { { + "extra_mobs_strider.png", + "extra_mobs_trans.png", +} } +baby_strider.walk_velocity = 1.2 +baby_strider.run_velocity = 2.4 +baby_strider.child = 1 + +mcl_mobs.register_mob("mobs_mc:baby_strider", baby_strider) + +-- Regular spawning in the Nether + +mcl_mobs:spawn_setup({ + name = "mobs_mc:strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether", + "BasaltDelta", + "WarpedForest", + "CrimsonForest", + "SoulsandValley" + }, + min_height = mcl_vars.mg_nether_min, + max_height = mcl_vars.mg_nether_max, + chance = 2000, +}) + +mcl_mobs:spawn_setup({ + name = "mobs_mc:baby_strider", + type_of_spawning = "lava", + dimension = "nether", + biomes = { + "Nether", + "BasaltDelta", + "WarpedForest", + "CrimsonForest", + "SoulsandValley" + }, + min_height = mcl_vars.mg_nether_min, + max_height = mcl_vars.mg_nether_max, + chance = 100, +}) + +-- spawn eggs +mcl_mobs.register_egg("mobs_mc:strider", S("Strider"), "#000000", "#FF0000", 0) +mcl_mobs:non_spawn_specific("mobs_mc:strider","overworld",0,minetest.LIGHT_MAX+1) diff --git a/mods/ENTITIES/mobs_mc/textures/mcl_totems_totem.png b/mods/ENTITIES/mobs_mc/textures/mcl_totems_totem.png deleted file mode 100644 index 603a86768..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mcl_totems_totem.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png b/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png deleted file mode 100644 index 9c6545452..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_chicken_egg.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png deleted file mode 100644 index df8b24c12..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_TEMP_wither_projectile.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png deleted file mode 100644 index 1d0cd9b1c..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_arrow_particle.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png deleted file mode 100644 index d6e54c7a1..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_black.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png deleted file mode 100644 index b9d69278e..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_chicken.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png deleted file mode 100644 index e3f04ffd3..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_donkey.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png deleted file mode 100644 index 69e643b13..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon_fireball.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png deleted file mode 100644 index 97d949d8a..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_block.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png deleted file mode 100644 index eec707c5c..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_evoker.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png deleted file mode 100644 index dc2addc1d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_ghast.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png deleted file mode 100644 index 91159c9d8..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_black.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png deleted file mode 100644 index 2d1733af9..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_brown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png deleted file mode 100644 index ef051a009..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_chestnut.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png deleted file mode 100644 index 5fa6dd45a..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_darkbrown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png deleted file mode 100644 index fb6c1c6b6..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_gray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png deleted file mode 100644 index 7fa9ce1de..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_skeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png deleted file mode 100644 index 264fffd26..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_white.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png deleted file mode 100644 index 846769e23..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_zombie.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png deleted file mode 100644 index e6a0f86a6..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_illusionist.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png deleted file mode 100644 index 4a08544cf..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png deleted file mode 100644 index 6cf366deb..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_brown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png deleted file mode 100644 index e1df4612f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_creamy.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_gray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_gray.png deleted file mode 100644 index b0830e087..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_gray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_white.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_white.png deleted file mode 100644 index 85c291d7e..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_llama_white.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png deleted file mode 100644 index 115416a53..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom_brown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png deleted file mode 100644 index 328018f5d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mule.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png deleted file mode 100644 index fac0f56ef..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_brown.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png deleted file mode 100644 index 8c22bd62a..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mushroom_red.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png deleted file mode 100644 index 9181de260..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_blue.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png deleted file mode 100644 index 152acb8f4..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_green.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png deleted file mode 100644 index ce723561c..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_grey.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png deleted file mode 100644 index 2f14ef1a5..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_red_blue.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png deleted file mode 100644 index f35adfd02..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_parrot_yellow_blue.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png deleted file mode 100644 index 13496a3c5..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png deleted file mode 100644 index fa447031d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_sheep_fur.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png deleted file mode 100644 index 956af9ce7..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_silverfish.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png deleted file mode 100644 index 82ed08719..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_slime.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png deleted file mode 100644 index 9720b7679..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_bat.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png deleted file mode 100644 index aaa8de0ae..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_blaze.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png deleted file mode 100644 index 3f975c19d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cat.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png deleted file mode 100644 index dea6dc92b..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cave_spider.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png deleted file mode 100644 index 58fc64136..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_chicken.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png deleted file mode 100644 index ac3e7a2d1..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_cow.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png deleted file mode 100644 index 99b766881..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_creeper.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png deleted file mode 100644 index 10bd751fb..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_donkey.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png deleted file mode 100644 index 5519d4de7..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_dragon.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png deleted file mode 100644 index 36983ce33..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_enderman.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png deleted file mode 100644 index f2d3b4065..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_endermite.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png deleted file mode 100644 index c6aec4f43..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_evoker.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png deleted file mode 100644 index 3c0422cae..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_ghast.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png deleted file mode 100644 index 10bcbcffb..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png deleted file mode 100644 index fac4ac819..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_guardian_elder.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png deleted file mode 100644 index 38d88e8b6..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png deleted file mode 100644 index bea0c518d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_skeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png deleted file mode 100644 index ab981289b..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_horse_zombie.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png deleted file mode 100644 index 48945d89e..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_husk.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png deleted file mode 100644 index 7b9dc99e3..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_illusioner.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png deleted file mode 100644 index 6de2cccb9..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_iron_golem.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png deleted file mode 100644 index f3daba200..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_llama.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png deleted file mode 100644 index 9c38e1b38..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_magmacube.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png deleted file mode 100644 index 552b70389..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mooshroom.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png deleted file mode 100644 index 741df99f3..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_mule.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png deleted file mode 100644 index b52c390f7..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_parrot.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png deleted file mode 100644 index 692d1714d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_pig.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png deleted file mode 100644 index 7570cacc8..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_polarbear.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png deleted file mode 100644 index 1c77e4199..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_rabbit.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png deleted file mode 100644 index 72ddb1702..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_sheep.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png deleted file mode 100644 index 491f840d6..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_shulker.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png deleted file mode 100644 index d0bca5664..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_silverfish.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png deleted file mode 100644 index d0225da21..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_skeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png deleted file mode 100644 index 0366bd267..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_slime.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png deleted file mode 100644 index f518f0cfe..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_snowman.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png deleted file mode 100644 index 7877d0bb0..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_spider.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png deleted file mode 100644 index 40fa44080..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_squid.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png deleted file mode 100644 index 67e5bbe3c..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_stray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png deleted file mode 100644 index 93bfa7b92..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vex.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png deleted file mode 100644 index cf8ce28cc..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_villager.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png deleted file mode 100644 index 24316e0f9..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_vindicator.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png deleted file mode 100644 index cd1db520f..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witch.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png deleted file mode 100644 index 5ce5c44bf..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wither.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png deleted file mode 100644 index 9055548bb..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_witherskeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png deleted file mode 100644 index 7098285b6..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_wolf.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png deleted file mode 100644 index 0b4da4163..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png deleted file mode 100644 index ba27c85d3..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_pigman.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png deleted file mode 100644 index 9430af7ef..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spawn_icon_zombie_villager.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png deleted file mode 100644 index 21f15614d..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png deleted file mode 100644 index ab00032b2..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_stray_overlay.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png deleted file mode 100644 index e271ddb24..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_bg.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_butcher.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_butcher.png deleted file mode 100644 index e8529c459..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_butcher.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_farmer.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_farmer.png deleted file mode 100644 index 62c98bcda..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_farmer.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_librarian.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_librarian.png deleted file mode 100644 index 66b5c2929..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_librarian.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_priest.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_priest.png deleted file mode 100644 index 79682c2c8..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_priest.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_smith.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_smith.png deleted file mode 100644 index 53a0e3888..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_smith.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png deleted file mode 100644 index 512eae60a..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vindicator.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png deleted file mode 100644 index acdf2ff93..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_witch.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png deleted file mode 100644 index d0b299ee9..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png deleted file mode 100644 index d0d6afe77..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wither_skeleton.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png deleted file mode 100644 index fc09566a5..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_roam.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png deleted file mode 100644 index 7dde7e5a8..000000000 Binary files a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_icon_sit.png and /dev/null differ diff --git a/mods/ENTITIES/mobs_mc/tropical_fish.lua b/mods/ENTITIES/mobs_mc/tropical_fish.lua new file mode 100644 index 000000000..79b32bb8b --- /dev/null +++ b/mods/ENTITIES/mobs_mc/tropical_fish.lua @@ -0,0 +1,192 @@ +--Tropical Fish by cora +local S = minetest.get_translator(minetest.get_current_modname()) + +local base_colors = { + "#FF3855", + "#FFF700", + "#A7F432", + "#FF5470", + "#5DADEC", + "#A83731", + "#87FF2A", + "#E936A7", + "#FF007C", + "#9C51B6", + "#66FF66", + "#AAF0D1", + "#50BFE6", + "#FFFF66", + "#FF9966", + "#FF00CC", +} +local pattern_colors = { + "#FF3855", + "#FFF700", + "#A7F432", + "#FF5470", + "#5DADEC", + "#A83731", + "#87FF2A", + "#E936A7", + "#FF007C", + "#9C51B6", + "#66FF66", + "#AAF0D1", + "#50BFE6", + "#FFFF66", + "#FF9966", + "#FF00CC", +} + +local function set_textures(self) + if not self._type then + self._type = "a" + if math.random(2) == 1 then + self.object:set_properties({}) + self._type="b" + end + self._base_color = base_colors[math.random(#base_colors)] + self._pattern_color = pattern_colors[math.random(#pattern_colors)] + self._pattern = "extra_mobs_tropical_fish_pattern_"..self._type.."_"..math.random(6)..".png" + end + self.object:set_properties({ + textures = { + "(extra_mobs_tropical_fish_"..self._type..".png^[colorize:"..self._base_color..":127)^("..self._pattern.."^[colorize:"..self._pattern_color..")", + }, + mesh="extra_mobs_tropical_fish_"..self._type..".b3d" + }) +end + +local tropical_fish = { + type = "animal", + spawn_class = "water_ambient", + can_despawn = true, + passive = true, + hp_min = 3, + hp_max = 3, + xp_min = 1, + xp_max = 3, + armor = 100, + spawn_in_group = 4, -- was 9. nerfed until aquatics use own cap rather than animal, and it represents pack size, not per spawn attempt + tilt_swim = true, + collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2}, + visual = "mesh", + mesh = "extra_mobs_tropical_fish_a.b3d", + textures = { "extra_mobs_tropical_fish_a.png" }, -- to be populated on_spawn + sounds = {}, + animation = { + stand_start = 0, + stand_end = 20, + walk_start = 20, + walk_end = 40, + run_start = 20, + run_end = 40, + }, + drops = { + {name = "mcl_fishing:clownfish_raw", + chance = 1, + min = 1, + max = 1,}, + {name = "mcl_bone_meal:bone_meal", + chance = 20, + min = 1, + max = 1,}, + }, + visual_size = {x=3, y=3}, + makes_footstep_sound = false, + swim = true, + fly = true, + fly_in = "mcl_core:water_source", + breathes_in_water = true, + jump = false, + view_range = 16, + runaway = true, + fear_height = 4, + on_rightclick = function(self, clicker) + local bn = clicker:get_wielded_item():get_name() + if bn == "mcl_buckets:bucket_water" or bn == "mcl_buckets:bucket_river_water" then + if clicker:set_wielded_item("mcl_buckets:bucket_tropical_fish") then + local it = clicker:get_wielded_item() + local m = it:get_meta() + m:set_string("properties",minetest.serialize(self.object:get_properties())) + clicker:set_wielded_item(it) + self.object:remove() + end + awards.unlock(clicker:get_player_name(), "mcl:tacticalFishing") + end + end, + on_spawn = set_textures, +} + +mcl_mobs.register_mob("mobs_mc:tropical_fish", tropical_fish) + +local water = 0 +mcl_mobs:spawn_specific( +"mobs_mc:tropical_fish", +"overworld", +"water", +{ +"Mesa", +"Jungle", +"Savanna", +"Desert", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"JungleM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"Savanna_beach", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +"JungleEdgeM_ocean", +"Jungle_deep_ocean", +"Savanna_ocean", +"MesaPlateauF_ocean", +"Savanna_deep_ocean", +"JungleEdgeM_deep_ocean", +"SunflowerPlains_deep_ocean", +"Mesa_ocean", +"JungleEdge_deep_ocean", +"SavannaM_deep_ocean", +"Desert_deep_ocean", +"Mesa_deep_ocean", +"MesaPlateauFM_ocean", +"JungleM_deep_ocean", +"SavannaM_ocean", +"MesaPlateauF_deep_ocean", +"MesaBryce_deep_ocean", +"JungleEdge_ocean", +"MesaBryce_ocean", +"Jungle_ocean", +"MesaPlateauFM_deep_ocean", +"Desert_ocean", +"JungleM_ocean", +"MesaBryce_underground", +"Mesa_underground", +"Jungle_underground", +"MesaPlateauF_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"JungleM_underground", +"JungleEdgeM_underground", +}, +0, +minetest.LIGHT_MAX+1, +30, +4000, +3, +water-16, +water+1) + +--spawn egg +mcl_mobs.register_egg("mobs_mc:tropical_fish", S("Tropical fish"), "#ef6915", "#fff9ef", 0) diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua index cccdebe7a..fbb33804d 100644 --- a/mods/ENTITIES/mobs_mc/vex.lua +++ b/mods/ENTITIES/mobs_mc/vex.lua @@ -9,7 +9,8 @@ local S = minetest.get_translator("mobs_mc") --################### VEX --################### -mobs:register_mob("mobs_mc:vex", { +mcl_mobs.register_mob("mobs_mc:vex", { + description = S("Vex"), type = "monster", spawn_class = "hostile", pathfinding = 1, @@ -93,4 +94,5 @@ mobs:register_mob("mobs_mc:vex", { -- spawn eggs -mobs:register_egg("mobs_mc:vex", S("Vex"), "mobs_mc_spawn_icon_vex.png", 0) +mcl_mobs.register_egg("mobs_mc:vex", S("Vex"), "#7a90a4", "#e8edf1", 0) +mcl_mobs:non_spawn_specific("mobs_mc:vex","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index dc3fbd9ca..8fc18ccab 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -10,14 +10,12 @@ -- TODO: Particles -- TODO: 4s Regeneration I after trade unlock --- TODO: Breeding --- TODO: Baby villagers --- TODO: Spawning in villages -- TODO: Behaviour: --- TODO: Walk around village, but do not leave it intentionally --- TODO: Run into house on rain or danger, open doors --- TODO: Internal inventory, pick up items, trade with other villagers --- TODO: Farm stuff +-- TODO: Run into house on rain or danger, open doors +-- TODO: Internal inventory, trade with other villagers +-- TODO: Schedule stuff (work,sleep,father) + +local weather_mod = minetest.get_modpath("mcl_weather") local S = minetest.get_translator("mobs_mc") local N = function(s) return s end @@ -32,6 +30,10 @@ local DEFAULT_WALK_CHANCE = 33 -- chance to walk in percent, if no player nearby local PLAYER_SCAN_INTERVAL = 5 -- every X seconds, villager looks for players nearby local PLAYER_SCAN_RADIUS = 4 -- scan radius for looking for nearby players +local RESETTLE_DISTANCE = 100 -- If a mob is transported this far from home, it gives up bed and job and resettles + +local PATHFINDING = "gowp" + --[=======[ TRADING ]=======] -- LIST OF VILLAGER PROFESSIONS AND TRADES @@ -44,6 +46,13 @@ local PLAYER_SCAN_RADIUS = 4 -- scan radius for looking for nearby players -- these items should be implemented as single items, then everything -- will be much easier. +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false) +local function mcl_log (message) + if LOGGING_ON then + mcl_util.mcl_log (message, "[Mobs - Villager]", true) + end +end + local COMPASS = "mcl_compass:compass" if minetest.registered_aliases[COMPASS] then COMPASS = minetest.registered_aliases[COMPASS] @@ -61,10 +70,35 @@ if minetest.get_mapgen_setting("mg_name") == "v6" then TRADE_V6_BIRCH_SAPLING = { { "mcl_core:emerald", 8, 11 }, { "mcl_core:birchsapling", 1, 1 } } end +local tiernames = { + "Novice", + "Apprentice", + "Journeyman", + "Expert", + "Master", +} + +local badges = { + "mobs_mc_stone.png", + "mobs_mc_iron.png", + "mobs_mc_gold.png", + "mobs_mc_emerald.png", + "mobs_mc_diamond.png", +} + local professions = { + unemployed = { + name = N("Unemployed"), + textures = { + "mobs_mc_villager.png", + "mobs_mc_villager.png", + }, + trades = nil, + }, farmer = { name = N("Farmer"), texture = "mobs_mc_villager_farmer.png", + jobsite = "mcl_composters:composter", trades = { { { { "mcl_farming:wheat_item", 18, 22, }, E1 }, @@ -74,18 +108,21 @@ local professions = { }, { - { { "mcl_farming:pumpkin_face", 8, 13 }, E1 }, + { { "mcl_farming:pumpkin", 6, 7 }, E1 }, { E1, { "mcl_farming:pumpkin_pie", 2, 3} }, + { E1, { "mcl_core:apple", 2, 3} }, }, { { { "mcl_farming:melon", 7, 12 }, E1 }, - { E1, { "mcl_core:apple", 5, 7 }, }, + { E1, {"mcl_farming:cookie", 5, 7 }, }, }, - { - { E1, { "mcl_farming:cookie", 6, 10 } }, - { 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 } }, TRADE_V6_BIRCH_SAPLING, TRADE_V6_DARK_OAK_SAPLING, TRADE_V6_ACACIA_SAPLING, @@ -94,33 +131,82 @@ local professions = { }, fisherman = { name = N("Fisherman"), - texture = "mobs_mc_villager_farmer.png", + texture = "mobs_mc_villager_fisherman.png", + jobsite = "mcl_barrels:barrel_closed", trades = { { - { { "mcl_fishing:fish_raw", 6, 6, "mcl_core:emerald", 1, 1 }, { "mcl_fishing:fish_cooked", 6, 6 } }, + { { "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:emerald", 3, 11 }, { "mcl_fishing:fishing_rod_enchanted", 1, 1} }, + { { "mcl_core:coal_lump", 10, 15 }, E1 }, + -- FIXME missing: bucket of cod + fish should be cod. + }, + { + { { "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 }, }, }, }, fletcher = { name = N("Fletcher"), - texture = "mobs_mc_villager_farmer.png", + texture = "mobs_mc_villager_fletcher.png", + 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 }, + }, + { + { { "mcl_core:flint", 26, 26 }, E1 }, { { "mcl_core:emerald", 2, 3 }, { "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_core:emerald", 7, 21 } , { "mcl_bows:bow_enchanted", 1, 1 } }, + }, + { + --FIXME: supposed to be tripwire hook{ { "tripwirehook", 24, 24 }, 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 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:night_vision_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:swiftness_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:slowness_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:leaping_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:poison_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:regeneration_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:invisibility_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:water_breathing_arrow", 5, 5 } }, + { { "mcl_core:emerald", 2, 2, "mcl_bows:arrow", 5, 5 }, { "mcl_potions:fire_resistance_arrow", 5, 5 } }, + }, } }, shepherd ={ name = N("Shepherd"), - texture = "mobs_mc_villager_farmer.png", + texture = "mobs_mc_villager_sheperd.png", + jobsite = "mcl_loom:loom", trades = { { { { "mcl_wool:white", 16, 22 }, E1 }, @@ -150,204 +236,1133 @@ local professions = { librarian = { name = N("Librarian"), texture = "mobs_mc_villager_librarian.png", + jobsite = "mcl_lectern:lectern", trades = { { { { "mcl_core:paper", 24, 36 }, E1 }, { { "mcl_books:book", 8, 10 }, E1 }, - { { "mcl_core:emerald", 10, 12 }, { "mcl_compass:compass", 1 ,1 }}, - { { "mcl_core:emerald", 3, 4 }, { "mcl_books:bookshelf", 1 ,1 }}, - { { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "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_books:written_book", 2, 2 }, E1 }, - { { "mcl_core:emerald", 10, 12 }, { "mcl_clock:clock", 1, 1 } }, - { E1, { "mcl_core:glass", 3, 5 } }, - { { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "mcl_core:emerald", 5, 64, "mcl_books:book", 1, 1 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { E1, { "mcl_lanterns:lantern_floor", 1, 1 } }, }, { - { E1, { "mcl_core:glass", 3, 5 } }, - { { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { { "mcl_dye:black", 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 } }, }, { - { { "mcl_core:emerald", 5, 64 }, { "mcl_enchanting:book_enchanted", 1 ,1 }}, + { 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_core:emerald", 5, 5 }, { "mcl_clock:clock", 1, 1 } }, }, { - { { "mcl_core:emerald", 20, 22 }, { "mcl_mobs:nametag", 1, 1 } }, + { { "mcl_core:emerald", 20, 20 }, { "mcl_mobs:nametag", 1, 1 } }, } }, }, cartographer = { name = N("Cartographer"), - texture = "mobs_mc_villager_librarian.png", + texture = "mobs_mc_villager_cartographer.png", + jobsite = "mcl_cartography_table:cartography_table", trades = { { - { { "mcl_core:paper", 24, 36 }, E1 }, + { { "mcl_core:paper", 24, 24 }, E1 }, + { { "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} }, }, - { - -- subject to special checks { { "mcl_compass:compass", 1, 1 }, E1 }, + --{ { "mcl_core:emerald", 13, 13, "mcl_compass:compass", 1, 1 }, { "FIXME:woodland explorer map" 1, 1} }, }, - { - -- TODO: replace with empty map - { { "mcl_core:emerald", 7, 11}, { "mcl_maps:filled_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 } }, + }, -- TODO: special maps }, }, armorer = { name = N("Armorer"), - texture = "mobs_mc_villager_smith.png", + texture = "mobs_mc_villager_armorer.png", + jobsite = "mcl_blast_furnace:blast_furnace", trades = { { - { { "mcl_core:coal_lump", 16, 24 }, E1 }, - { { "mcl_core:emerald", 4, 6 }, { "mcl_armor:helmet_iron", 1, 1 } }, + { { "mcl_core:coal_lump", 15, 15 }, E1 }, + { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_iron", 1, 1 } }, + { { "mcl_core:emerald", 9, 9 }, { "mcl_armor:chestplate_iron", 1, 1 } }, + { { "mcl_core:emerald", 7, 7 }, { "mcl_armor:leggings_iron", 1, 1 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_armor:boots_iron", 1, 1 } }, }, { - { { "mcl_core:iron_ingot", 7, 9 }, E1 }, - { { "mcl_core:emerald", 10, 14 }, { "mcl_armor:chestplate_iron", 1, 1 } }, + { { "mcl_core:iron_ingot", 4, 4 }, E1 }, + { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, + { { "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 }, + { { "mcl_core:emerald", 1, 1 }, { "mcl_armor:helmet_chain", 1, 1 } }, + { { "mcl_core:emerald", 4, 4 }, { "mcl_armor:chestplate_chain", 1, 1 } }, + { { "mcl_core:emerald", 5, 5 }, { "mcl_shields:shield", 1, 1 } }, }, { - { { "mcl_core:diamond", 3, 4 }, E1 }, - { { "mcl_core:emerald", 16, 19 }, { "mcl_armor:chestplate_diamond_enchanted", 1, 1 } }, + { { "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", 5, 7 }, { "mcl_armor:boots_chain", 1, 1 } }, - { { "mcl_core:emerald", 9, 11 }, { "mcl_armor:leggings_chain", 1, 1 } }, - { { "mcl_core:emerald", 5, 7 }, { "mcl_armor:helmet_chain", 1, 1 } }, - { { "mcl_core:emerald", 11, 15 }, { "mcl_armor:chestplate_chain", 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 } }, }, }, }, leatherworker = { name = N("Leatherworker"), - texture = "mobs_mc_villager_butcher.png", + texture = "mobs_mc_villager_leatherworker.png", + jobsite = "mcl_cauldrons:cauldron", trades = { { { { "mcl_mobitems:leather", 9, 12 }, E1 }, - { { "mcl_core:emerald", 2, 4 }, { "mcl_armor:leggings_leather", 2, 4 } }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_leather", 2, 4 } }, + { { "mcl_core:emerald", 7, 7 }, { "mcl_armor:chestplate_leather", 2, 4 } }, }, - { - { { "mcl_core:emerald", 7, 12 }, { "mcl_armor:chestplate_leather_enchanted", 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_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 } }, }, + { + { { "mcl_core:emerald", 6, 6 }, { "mcl_mobitems:saddle", 1, 1 } }, + { { "mcl_core:emerald", 5, 5 }, { "mcl_armor:helmet_leather", 2, 4 } }, + }, }, }, butcher = { name = N("Butcher"), texture = "mobs_mc_villager_butcher.png", + jobsite = "mcl_smoker:smoker", trades = { { - { { "mcl_mobitems:beef", 14, 18 }, E1 }, - { { "mcl_mobitems:chicken", 14, 18 }, E1 }, + { { "mcl_mobitems:beef", 14, 14 }, E1 }, + { { "mcl_mobitems:chicken", 7, 7 }, E1 }, + { { "mcl_mobitems:rabbit", 4, 4 }, E1 }, + { E1, { "mcl_mobitems:rabbit_stew", 1, 1 } }, }, { - { { "mcl_core:coal_lump", 16, 24 }, E1 }, - { E1, { "mcl_mobitems:cooked_beef", 5, 7 } }, - { E1, { "mcl_mobitems:cooked_chicken", 6, 8 } }, + { { "mcl_core:coal_lump", 15, 15 }, E1 }, + { 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 }, }, }, }, weapon_smith = { name = N("Weapon Smith"), - texture = "mobs_mc_villager_smith.png", + texture = "mobs_mc_villager_weaponsmith.png", + jobsite = "mcl_grindstone:grindstone", trades = { { - { { "mcl_core:coal_lump", 16, 24 }, E1 }, - { { "mcl_core:emerald", 6, 8 }, { "mcl_tools:axe_iron", 1, 1 } }, + { { "mcl_core:coal_lump", 15, 15 }, E1 }, + { { "mcl_core:emerald", 3, 3 }, { "mcl_tools:axe_iron", 1, 1 } }, + { { "mcl_core:emerald", 7, 21 }, { "mcl_tools:sword_iron_enchanted", 1, 1 } }, }, { - { { "mcl_core:iron_ingot", 7, 9 }, E1 }, - { { "mcl_core:emerald", 9, 10 }, { "mcl_tools:sword_iron_enchanted", 1, 1 } }, + { { "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:diamond", 7, 9 }, E1 }, + { { "mcl_core:emerald", 17, 31 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } }, }, { - { { "mcl_core:diamond", 3, 4 }, E1 }, - { { "mcl_core:emerald", 12, 15 }, { "mcl_tools:sword_diamond_enchanted", 1, 1 } }, - { { "mcl_core:emerald", 9, 12 }, { "mcl_tools:axe_diamond_enchanted", 1, 1 } }, + { { "mcl_core:emerald", 13, 27 }, { "mcl_tools:sword_diamond_enchanted", 1, 1 } }, }, }, }, tool_smith = { name = N("Tool Smith"), - texture = "mobs_mc_villager_smith.png", + texture = "mobs_mc_villager_toolsmith.png", + jobsite = "mcl_smithing_table:table", trades = { { - { { "mcl_core:coal_lump", 16, 24 }, E1 }, - { { "mcl_core:emerald", 5, 7 }, { "mcl_tools:shovel_iron_enchanted", 1, 1 } }, + { { "mcl_core:coal_lump", 15, 15 }, E1 }, + { E1, { "mcl_tools:axe_stone", 1, 1 } }, + { E1, { "mcl_tools:shovel_stone", 1, 1 } }, + { E1, { "mcl_tools:pick_stone", 1, 1 } }, + { E1, { "mcl_farming:hoe_stone", 1, 1 } }, }, { - { { "mcl_core:iron_ingot", 7, 9 }, E1 }, - { { "mcl_core:emerald", 9, 11 }, { "mcl_tools:pick_iron_enchanted", 1, 1 } }, + { { "mcl_core:iron_ingot", 4, 4 }, E1 }, + { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, }, - { - { { "mcl_core:diamond", 3, 4 }, E1 }, - { { "mcl_core:emerald", 12, 15 }, { "mcl_tools:pick_diamond_enchanted", 1, 1 } }, + { { "mcl_core:flint", 30, 30 }, E1 }, + { { "mcl_core:emerald", 6, 20 }, { "mcl_tools:axe_iron_enchanted", 1, 1 } }, + { { "mcl_core:emerald", 7, 21 }, { "mcl_tools:shovel_iron_enchanted", 1, 1 } }, + { { "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 } }, }, }, }, cleric = { name = N("Cleric"), texture = "mobs_mc_villager_priest.png", + jobsite = "mcl_brewing:stand_000", trades = { { - { { "mcl_mobitems:rotten_flesh", 36, 40 }, E1 }, - { { "mcl_core:gold_ingot", 8, 10 }, E1 }, + { { "mcl_mobitems:rotten_flesh", 32, 32 }, E1 }, + { E1, { "mesecons:redstone", 2, 2 } }, }, - { - { E1, { "mesecons:redstone", 1, 4 } }, - { E1, { "mcl_dye:blue", 1, 2 } }, + { { "mcl_core:gold_ingot", 3, 3 }, E1 }, + { E1, { "mcl_core:lapis", 1, 1 } }, }, - { - { E1, { "mcl_nether:glowstone", 1, 3 } }, - { { "mcl_core:emerald", 4, 7 }, { "mcl_throwing:ender_pearl", 1, 1 } }, + { { "mcl_mobitems:rabbit_foot", 2, 2 }, E1 }, + { E1, { "mcl_nether:glowstone", 4, 4 } }, + }, + { + --{ { "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 } }, }, }, }, + 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 } }, + }, + { + { { "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 } }, + }, + }, + }, nitwit = { name = N("Nitwit"), - texture = "mobs_mc_villager.png", + texture = "mobs_mc_villager_nitwit.png", -- No trades for nitwit trades = nil, } } +local WORK = "work" +local SLEEP = "sleep" +local GATHERING = "gathering" + local profession_names = {} for id, _ in pairs(professions) do table.insert(profession_names, id) end -local stand_still = function(self) +local function populate_jobsites (profession) + if profession then + mcl_log("populate_jobsites: ".. tostring(profession)) + end + local jobsites_requested={} + for _,n in pairs(profession_names) do + if n and professions[n].jobsite then + if not profession or (profession and profession == n) then + --minetest.log("populate_jobsites. Adding: ".. tostring(n)) + table.insert(jobsites_requested,professions[n].jobsite) + end + end + end + return jobsites_requested +end + +jobsites = populate_jobsites() + +local function stand_still(self) self.walk_chance = 0 self.jump = false end -local update_max_tradenum = function(self) +local function init_trader_vars(self) + if not self._max_trade_tier then + self._max_trade_tier = 1 + end + if not self._locked_trades then + self._locked_trades = 0 + end + if not self._trading_players then + self._trading_players = {} + end +end + +local function get_badge_textures(self) + local t = professions[self._profession].texture + if self._profession == "unemployed" then + t = professions[self._profession].textures -- ideally both scenarios should be textures with a list containing 1 or multiple + --mcl_log("t: " .. tostring(t)) + end + + if self._profession == "unemployed" or self._profession == "nitwit" then return t end + local tier = self._max_trade_tier or 1 + return { + t .. "^" .. badges[tier] + } +end + +local function set_textures(self) + local badge_textures = get_badge_textures(self) + --mcl_log("Setting textures: " .. tostring(badge_textures)) + self.object:set_properties({textures=badge_textures}) +end + +-- TODO Pass in self and if nitwit, go to bed later. +local function is_night() + local tod = minetest.get_timeofday() + tod = ( tod * 24000 ) % 24000 + return tod > 17500 or tod < 6500 +end + +function get_activity(tod) + -- night hours = tod > 18541 or tod < 5458 + if not tod then + tod = minetest.get_timeofday() + end + tod = ( tod * 24000 ) % 24000 + + local lunch_start = 11000 + local lunch_end = 13500 + local work_start = 7500 + local work_end = 16000 + + local activity = nil + if weather_mod and mcl_weather.get_weather() == "thunder" then + mcl_log("Better get to bed. Weather is: " .. mcl_weather.get_weather()) + activity = SLEEP + elseif (tod > work_start and tod < lunch_start) or (tod > lunch_end and tod < work_end) then + activity = WORK + elseif is_night() then + activity = SLEEP + elseif tod > lunch_start and tod < lunch_end then + activity = GATHERING + else + activity = "chill" + end + --mcl_log("Time is " .. tod ..". Activity is: ".. activity) + return activity + +end + +local function find_closest_bed (self) + local p = self.object:get_pos() + + --local spawnable_bed={} + --table.insert(spawnable_bed, "mcl_beds:bed_red_bottom") + --local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), spawnable_bed) + --if nn then + -- mcl_log("Red beds: " .. #nn) + --end + + local unclaimed_beds = {} + local nn2 = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), {"group:bed"}) + if nn2 then + --mcl_log("All bed parts: " .. #nn2) + + for a,b in pairs(nn2) do + mcl_log("b: " .. minetest.pos_to_string(b)) + + local bed_node = minetest.get_node(b) + local bed_name = bed_node.name + local is_bed_bottom = string.find(bed_name,"_bottom") + + local bed_meta = minetest.get_meta(b) + local owned_by = bed_meta:get_string("villager") + --mcl_log("Owned by villager: ".. tostring(owned_by)) + + if (owned_by and owned_by == self._id) then + mcl_log("Clear as already owned by me.") + bed_meta:set_string("villager", nil) + owned_by = nil + end + + if is_bed_bottom then + local bed_top = mcl_beds.get_bed_top (b) + mcl_log("bed_top: " .. tostring(bed_top)) + + local bed_top_node = minetest.get_node(bed_top) + if bed_top_node then + mcl_log("There is a block here for bed top: ".. bed_top_node.name) + else + mcl_log("There is no block here for bed top") + end + + local bed_top_meta = minetest.get_meta(bed_top) + local owned_by_player = bed_top_meta:get_string("player") + if bed_top_meta then + mcl_log("Player: " .. tostring(owned_by_player)) + else + mcl_log("No bed top meta") + end + + if owned_by == "" and (not owned_by_player or owned_by_player == "") then + table.insert(unclaimed_beds, b) + mcl_log("is an unowned bed bottom") + else + + end + else + --mcl_log("bed_node name: " .. bed_name) + end + end + end + + local distance_to_closest_block = nil + local closest_block = nil + + if unclaimed_beds then + mcl_log("All unclaimed bed bottoms: " .. #unclaimed_beds) + + for i,b in pairs(unclaimed_beds) do + mcl_log("b: " .. minetest.pos_to_string(b)) + local distance_to_block = vector.distance(p, b) + mcl_log("Distance to block ".. i .. ": ".. distance_to_block) + + if not distance_to_closest_block or distance_to_closest_block > distance_to_block then + mcl_log("This block is closer than the last.") + closest_block = b + distance_to_closest_block = distance_to_block + end + + local bed_node = minetest.get_node(b) + local bed_name = bed_node.name + mcl_log("bed_node name: " .. bed_name) + end + end + + return closest_block +end + +local function find_closest_unclaimed_block (p, requested_block_types) + local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), requested_block_types) + + local distance_to_closest_block = nil + local closest_block = nil + + for i,n in pairs(nn) do + local m = minetest.get_meta(n) + + if m:get_string("villager") == "" then + mcl_log("Block: " .. minetest.pos_to_string(n).. ", owner: ".. m:get_string("villager")) + + local distance_to_block = vector.distance(p, n) + mcl_log("Distance to block ".. i .. ": ".. distance_to_block) + + if not distance_to_closest_block or distance_to_closest_block > distance_to_block then + mcl_log("This block is closer than the last.") + closest_block = n + distance_to_closest_block = distance_to_block + end + end + end + return closest_block +end + +local function check_bed (entity) + local b = entity._bed + if not b then + --minetest.log("No bed set on villager") + return false + end + + local n = minetest.get_node(b) + + local is_bed_bottom = string.find(n.name,"_bottom") + --mcl_log("is bed bottom: " .. tostring(is_bed_bottom)) + if n and not is_bed_bottom then + mcl_log("Where did my bed go?!") + entity._bed = nil --the stormtroopers have killed uncle owen + return false + else + return true + end +end + +local function go_home(entity, sleep) + + if not check_bed (entity) then + mcl_log("Cannot find bed, so cannot go home") + end + + local b = entity._bed + if not b then + return + end + + local bed_node = minetest.get_node(b) + if not bed_node then + entity._bed = nil + mcl_log("Cannot find bed. Unset it") + return + end + + if vector.distance(entity.object:get_pos(),b) < 2 then + if sleep then + entity.order = SLEEP + mcl_log("Sleep time!") + end + else + if sleep and entity.order == SLEEP then + entity.order = nil + return + end + + entity:gopath(b,function(entity,b) + local b = entity._bed + + if not b then + --minetest.log("NO BED, problem") + return false + end + + if not minetest.get_node(b) then + --minetest.log("NO BED NODE, problem") + return false + end + + if vector.distance(entity.object:get_pos(),b) < 2 then + --minetest.log("Managed to walk home callback!") + return true + else + --minetest.log("Need to walk to home") + end + end, true) + end +end + + + +local function take_bed (entity) + if not entity then return end + if not entity:ready_to_path() then return end + + local p = entity.object:get_pos() + + local closest_block = find_closest_bed (entity) + + if closest_block then + mcl_log("Can we path to bed: "..minetest.pos_to_string(closest_block) ) + local distance_to_block = vector.distance(p, closest_block) + mcl_log("Distance: " .. distance_to_block) + if distance_to_block < 2 then + local m = minetest.get_meta(closest_block) + local owner = m:get_string("villager") + mcl_log("owner: ".. owner) + if owner and owner ~= "" and owner ~= entity._id then + mcl_log("Already taken") + if entity.order == "stand" then entity.order = nil end + return + end + + if entity.order ~= SLEEP then + mcl_log("Sleepy time" ) + entity.order = SLEEP + m:set_string("villager", entity._id) + entity._bed = closest_block + else + --entity.order = nil + mcl_log("Set as sleep already..." ) + end + else + local gp = entity:gopath(closest_block,function(self) end) + if gp then + mcl_log("Nice bed. I'll defintely take it as I can path") + else + mcl_log("Awww. I can't find my bed.") + end + end + else + mcl_log("Cannot find a bed to claim.") + if entity.order == "stand" then entity.order = nil end + end +end + +local function has_golem(pos) + local r = false + for _,o in pairs(minetest.get_objects_inside_radius(pos,16)) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:iron_golem" then return true end + end +end + +local function monsters_near(self) + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do + local l = o:get_luaentity() + if l and l.type =="monster" then return true end + end +end + +local function has_summon_participants(self) + local r = 0 + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),10)) do + local l = o:get_luaentity() + --TODO check for gossiping + if l and l.name == "mobs_mc:villager" then r = r + 1 end + end + return r > 2 +end + +local function summon_golem(self) + vector.offset(self.object:get_pos(),-10,-10,-10) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.object:get_pos(),-10,-10,-10),vector.offset(self.object:get_pos(),10,10,10),{"group:solid","group:water"}) + table.shuffle(nn) + for _,n in pairs(nn) do + local up = minetest.find_nodes_in_area(vector.offset(n,0,1,0),vector.offset(n,0,3,0),{"air"}) + if up and #up >= 3 then + minetest.sound_play("mcl_portals_open_end_portal", {pos=n, gain=0.5, max_hear_distance = 16}, true) + return minetest.add_entity(vector.offset(n,0,1,0),"mobs_mc:iron_golem") + end + end +end + +local function check_summon(self,dtime) + -- TODO has selpt in last 20? + if self._summon_timer and self._summon_timer > 30 then + local pos = self.object:get_pos() + self._summon_timer = 0 + if has_golem(pos) then return end + if not monsters_near(self) then return end + if not has_summon_participants(self) then return end + summon_golem(self) + elseif self._summon_timer == nil then + self._summon_timer = 0 + end + self._summon_timer = self._summon_timer + dtime +end + +local function debug_trades(self) + mcl_log("Start debug trades") + if not self or not self._trades then return end + local trades = minetest.deserialize(self._trades) + if trades and type(trades) == "table" then + for trader, trade in pairs(trades) do + --mcl_log("Current record: ".. tostring(trader)) + for tr3, tr4 in pairs (trade) do + mcl_log("Key: ".. tostring(tr3)) + mcl_log("Value: ".. tostring(tr4)) + end + end + end + mcl_log("End debug trades") +end + +local function has_traded (self) + if not self._trades then + mcl_log("No trades set. has_traded is false") + return false + end + local cur_trades_tab = minetest.deserialize(self._trades) + if cur_trades_tab and type(cur_trades_tab) == "table" then + for trader, trades in pairs(cur_trades_tab) do + if trades.traded_once then + mcl_log("Villager has traded before. Returning true") + return true + end + end + end + mcl_log("Villager has not traded before") + return false +end + +local function unlock_trades (self) + if not self._trades then + mcl_log("No trades set. has_traded is false") + return false + end + mcl_log("Unlocking trades") + local has_unlocked = false + + local trades = minetest.deserialize(self._trades) + if trades and type(trades) == "table" then + for trader, trade in pairs(trades) do + local trade_tier_too_high = trade.tier > self._max_trade_tier + --mcl_log("Max trade tier of villager: ".. tostring(self._max_trade_tier)) + --mcl_log("current trade.tier: ".. tostring(trade.tier)) + --mcl_log("trade tier too high: ".. tostring(trade_tier_too_high)) + --mcl_log("locked: ".. tostring(trade["locked"])) + if not trade_tier_too_high then + if trade["locked"] == true then + trade.locked = false + trade.trade_counter = 0 + has_unlocked = true + mcl_log("Villager has a locked trade. Unlocking") + end + end + end + if has_unlocked then + self._trades = minetest.serialize(trades) + end + end +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 + end +end + +local function employ(self,jobsite_pos) + local n = minetest.get_node(jobsite_pos) + local m = minetest.get_meta(jobsite_pos) + local p = get_profession_by_jobsite(n.name) + if p and m:get_string("villager") == "" then + mcl_log("Taking this jobsite") + + m:set_string("villager",self._id) + self._jobsite = jobsite_pos + + if not has_traded(self) then + self._profession=p + set_textures(self) + end + return true + else + mcl_log("I can not steal someone's job!") + end +end + + +local function look_for_job(self, requested_jobsites) + mcl_log("Looking for jobs") + + local p = self.object:get_pos() + + local closest_block = find_closest_unclaimed_block(p, requested_jobsites) + + if closest_block then + mcl_log("It's a free job for me (" .. minetest.pos_to_string(p) .. ")! I might be interested: ".. minetest.pos_to_string(closest_block) ) + + local gp = self:gopath(closest_block,function(self) + mcl_log("Arrived at block callback") + if self and self.state == "stand" then + self.order = WORK + else + mcl_log("no self. passing param to callback failed") + end + end) + + if gp then + if closest_block then + mcl_log("We can path to this block.. " .. tostring(closest_block)) + end + return closest_block + else + mcl_log("We could not path to block or it's not ready to path yet.") + end + else + mcl_log("We don't have a job block to path to") + end + + return nil +end + + +local function get_a_job(self) + if self.order == WORK then self.order = nil end + if not self:ready_to_path() then return end + + mcl_log("I'm unemployed or lost my job block and have traded. Can I get a job?") + + local requested_jobsites = jobsites + if has_traded (self) then + mcl_log("Has traded so look for job of my type") + requested_jobsites = populate_jobsites(self._profession) + -- Only pass in my jobsite to two functions here + end + + local p = self.object:get_pos() + local n = minetest.find_node_near(p,1,requested_jobsites) + if n and employ(self,n) then return true end + + if self.state ~= PATHFINDING then + mcl_log("Nothing near. Need to look for a job") + look_for_job(self, requested_jobsites) + end +end + +local function retrieve_my_jobsite (self) + if not self or not self._jobsite then + mcl_log("find_jobsite. Invalid params. Should not happen") + return + end + local n = mcl_vars.get_node(self._jobsite) + local m = minetest.get_meta(self._jobsite) + if m:get_string("villager") == self._id then + --mcl_log("find_jobsite. is my job.") + return n + else + mcl_log("This isn't my jobsite") + end + return +end + +local function remove_job (self) + self._jobsite = nil + if not has_traded(self) then + mcl_log("Cannot retrieve my jobsite. I am now unemployed.") + self._profession = "unemployed" + self._trades = nil + set_textures(self) + else + mcl_log("Cannot retrieve my jobsite but I've traded so only remove jobsite.") + end +end + +local function validate_jobsite(self) + if self._profession == "unemployed" then return false end + + local job_block = retrieve_my_jobsite (self) + if not job_block then + if self.order == WORK then + self.order = nil + end + + remove_job (self) + return false + else + local resettle = vector.distance(self.object:get_pos(),self._jobsite) > RESETTLE_DISTANCE + mcl_log("Jobsite far, so resettle: " .. tostring(resettle)) + if resettle then + local m = minetest.get_meta(self._jobsite) + m:set_string("villager", nil) + remove_job (self) + return false + end + return true + end +end + +local function do_work (self) + + if not self or self.child then + mcl_log("No self, or a child so don't work") + return + end + + --mcl_log("Time for work") + local jobsite_node = retrieve_my_jobsite (self) + + if jobsite_node then + local jobsite = self._jobsite + + local distance_to_jobsite = vector.distance(self.object:get_pos(), jobsite) + --mcl_log("Villager: ".. minetest.pos_to_string(self.object:get_pos()) .. ", jobsite: " .. minetest.pos_to_string(self._jobsite) .. ", distance to jobsite: ".. distance_to_jobsite) + + if distance_to_jobsite < 2 then + if self.state ~= PATHFINDING and self.order ~= WORK then + mcl_log("Setting order to work.") + self.order = WORK + unlock_trades(self) + else + --mcl_log("Still pathfinding.") + end + else + mcl_log("Not at job block. Need to commute.") + if self.order == WORK then + self.order = nil + return + end + + self:gopath(jobsite, function(self, jobsite) + if not self then + --mcl_log("missing self. not good") + return false + end + if not self._jobsite then + --mcl_log("Jobsite not valid") + return false + end + if vector.distance(self.object:get_pos(),self._jobsite) < 2 then + --mcl_log("Made it to work ok callback!") + return true + else + --mcl_log("Need to walk to work. Not sure we can get here.") + end + end) + end + end + +end + +local below_vec = vector.new(0, -1, 0) + +local function get_ground_below_floating_object (float_pos) + local pos = float_pos + repeat + mcl_log("Current pos: " .. minetest.pos_to_string(pos)) + pos = vector.add(pos, below_vec) + local node = minetest.get_node(pos) + mcl_log("First non air materials: ".. tostring(node.name)) + until node.name ~= "air" + + -- If pos is 1 below float_pos, then just return float_pos as there is no air below it + if pos.y == float_pos.y - 1 then + --mcl_log("pos is only 1 lower than float pos so no air below") + return float_pos + else + --mcl_log("pos is more than 1 lower than float pos so air is below") + return pos + end + + return pos +end + +local function go_to_town_bell(self) + if self.order == GATHERING then return + else mcl_log("Current order" .. self.order) end + + if not self:ready_to_path() then return end + + mcl_log("Go to town bell") + + local looking_for_type={} + table.insert(looking_for_type, "mcl_bells:bell") + + local p = self.object:get_pos() + local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), looking_for_type) + + --Ideally should check for closest available. It'll make pathing easier. + for _,n in pairs(nn) do + mcl_log("Found bell") + local target_point = get_ground_below_floating_object(n) + + local gp = self:gopath(target_point,function(self) + if self then + self.order = GATHERING + mcl_log("Callback has a self") + end + mcl_log("Arrived at block callback") + end) + + if gp then + if n then + mcl_log("We can path to this block.. " .. tostring(n)) + end + return n + else + mcl_log("We could not path to block or it's not ready to path yet.") + end + + end + + return nil +end + +local function validate_bed(self) + if not self or not self._bed then + return false + end + local n = mcl_vars.get_node(self._bed) + if not n then + self._bed = nil + return false + end + + local bed_valid = true + + local m = minetest.get_meta(self._bed) + + local resettle = vector.distance(self.object:get_pos(),self._bed) > RESETTLE_DISTANCE + mcl_log("Bed far, so resettle: " .. tostring(resettle)) + if resettle then + mcl_log("Resettled. Ditch bed.") + m:set_string("villager", nil) + self._bed = nil + bed_valid = false + return false + end + + local owned_by_player = m:get_string("player") + mcl_log("Player owner: " .. owned_by_player) + if owned_by_player ~= "" then + mcl_log("Player owns this. Villager won't take this.") + m:set_string("villager", nil) + self._bed = nil + bed_valid = false + return false + end + + if m:get_string("villager") ~= self._id then + mcl_log("This bed is owned by another player. I'll unclaim.") + self._bed = nil + return false + else + mcl_log("Bed is valid") + return true + end + +end + +local function do_activity (self) + + if self.following then + mcl_log("Following, so do not do activity.") + return + end + if self.state == PATHFINDING then + mcl_log("Pathfinding, so do not do activity.") + return + end + + local jobsite_valid = false + + if not is_night() then + if self.order == SLEEP then self.order = nil end + + if not validate_jobsite(self) then + --debug_trades(self) + if self._profession == "unemployed" or has_traded(self) then + get_a_job(self) + return + end + else + jobsite_valid = true + --mcl_log("My jobsite is valid. Do i need to travel?") + end + else + if self.order == WORK then self.order = nil end + + if not validate_bed(self) then + if self.order == SLEEP then self.order = nil end + mcl_log("Villager at this location has no bed: " .. minetest.pos_to_string(self.object:get_pos())) + take_bed (self) + end + end + + -- Only check in day or during thunderstorm but wandered_too_far code won't work + local wandered_too_far = false + if check_bed (self) then + wandered_too_far = vector.distance(self.object:get_pos(),self._bed) > 50 + end + + if wandered_too_far then + --mcl_log("Wandered too far! Return home ") + go_home(self, false) + elseif get_activity() == SLEEP then + go_home(self, true) + elseif get_activity() == WORK and jobsite_valid then + do_work(self) + elseif get_activity() == GATHERING then + go_to_town_bell(self) + else + mcl_log("No order, so remove it.") + self.order = nil + end + +end + +local function update_max_tradenum(self) if not self._trades then return end @@ -362,31 +1377,7 @@ local update_max_tradenum = function(self) self._max_tradenum = #trades end -local init_trader_vars = function(self) - if not self._profession then - -- Select random profession from all professions with matching clothing - local texture = self.base_texture[1] - local matches = {} - for prof_id, prof in pairs(professions) do - if texture == prof.texture then - table.insert(matches, prof_id) - end - end - local p = math.random(1, #matches) - self._profession = matches[p] - end - if not self._max_trade_tier then - self._max_trade_tier = 1 - end - if not self._locked_trades then - self._locked_trades = 0 - end - if not self._trading_players then - self._trading_players = {} - end -end - -local init_trades = function(self, inv) +local function init_trades(self, inv) local profession = professions[self._profession] local trade_tiers = profession.trades if trade_tiers == nil then @@ -409,9 +1400,10 @@ local init_trades = function(self, inv) local offered_stack = ItemStack({name = offered_item, count = offered_count}) if mcl_enchanting.is_enchanted(offered_item) then if mcl_enchanting.is_book(offered_item) then - offered_stack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}) + offered_stack = mcl_enchanting.enchant_uniform_randomly(offered_stack, {"soul_speed"}) else mcl_enchanting.enchant_randomly(offered_stack, math.random(5, 19), false, false, true) + mcl_enchanting.unload_enchantments(offered_stack) end end @@ -436,13 +1428,13 @@ local init_trades = function(self, inv) minetest.deserialize(self._trades) end -local set_trade = function(trader, player, inv, concrete_tradenum) +local function set_trade(trader, player, inv, concrete_tradenum) local trades = minetest.deserialize(trader._trades) if not trades then init_trades(trader) trades = minetest.deserialize(trader._trades) if not trades then - minetest.log("error", "[mobs_mc] Failed to select villager trade!") + --minetest.log("error", "Failed to select villager trade!") return end end @@ -457,7 +1449,12 @@ local set_trade = function(trader, player, inv, concrete_tradenum) player_tradenum[name] = concrete_tradenum local trade = trades[concrete_tradenum] inv:set_stack("wanted", 1, ItemStack(trade.wanted[1])) - inv:set_stack("offered", 1, ItemStack(trade.offered)) + local offered = ItemStack(trade.offered) + -- Only load enchantments for enchanted items; fixes unnecessary metadata being applied to regular items from villagers. + if mcl_enchanting.is_enchanted(offered:get_name()) then + mcl_enchanting.load_enchantments(offered) + end + inv:set_stack("offered", 1, offered) if trade.wanted[2] then local wanted2 = ItemStack(trade.wanted[2]) inv:set_stack("wanted", 2, wanted2) @@ -508,12 +1505,17 @@ local function show_trade_formspec(playername, trader, tradenum) w2_formspec = "item_image[3,1;1,1;"..wanted2:to_string().."]" .."tooltip[3,1;0.8,0.8;"..F(wanted2:get_description()).."]" end - + local tiername = tiernames[trader._max_trade_tier] + if tiername then + tiername = S(tiername) + else + tiername = S("Master") + end local formspec = "size[9,8.75]" .."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]" ..disabled_img - .."label[4,0;"..F(minetest.colorize("#313131", S(profession))).."]" +.."label[3,0;"..F(minetest.colorize("#313131", S(profession).." - "..tiername)) .."]" .."list[current_player;main;0,4.5;9,3;9]" .."list[current_player;main;0,7.74;9,1;]" ..b_prev..b_next @@ -529,11 +1531,11 @@ local function show_trade_formspec(playername, trader, tradenum) .."listring[current_player;main]" .."listring["..tradeinv..";input]" .."listring[current_player;main]" - minetest.sound_play("mobs_mc_villager_trade", {to_player = playername}, true) + minetest.sound_play("mobs_mc_villager_trade", {to_player = playername,object=trader.object}, true) minetest.show_formspec(playername, tradeinv_name, formspec) end -local update_offer = function(inv, player, sound) +local function update_offer(inv, player, sound) local name = player:get_player_name() local trader = player_trading_with[name] local tradenum = player_tradenum[name] @@ -557,12 +1559,12 @@ local update_offer = function(inv, player, sound) -- compass. -- TODO: Remove these check functions when compass and clock are implemented -- as single items. - local check_special = function(special_item, group, wanted1, wanted2, input1, input2) + local function check_special(special_item, group, wanted1, wanted2, input1, input2) if minetest.registered_aliases[special_item] then special_item = minetest.registered_aliases[special_item] end if wanted1:get_name() == special_item then - local check_input = function(input, wanted, group) + local function check_input(input, wanted, group) return minetest.get_item_group(input:get_name(), group) ~= 0 and input:get_count() >= wanted:get_count() end if check_input(input1, wanted1, group) then @@ -577,7 +1579,7 @@ local update_offer = function(inv, player, sound) end -- Apply above function to all items which we consider special. -- This function succeeds if ANY item check succeeds. - local check_specials = function(wanted1, wanted2, input1, input2) + local function check_specials(wanted1, wanted2, input1, input2) return check_special(COMPASS, "compass", wanted1, wanted2, input1, input2) end -- END OF SPECIAL HANDLING OF COMPASS @@ -591,13 +1593,13 @@ local update_offer = function(inv, player, sound) (trade.locked == false)) then inv:set_stack("output", 1, inv:get_stack("offered", 1)) if sound then - minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true) end return true else inv:set_stack("output", 1, ItemStack("")) if sound then - minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true) end return false end @@ -631,7 +1633,7 @@ local function return_item(itemstack, dropper, pos, inv_p) return itemstack end -local return_fields = function(player) +local function return_fields(player) local name = player:get_player_name() local inv_t = minetest.get_inventory({type="detached", name = "mobs_mc:trade_"..name}) local inv_p = player:get_inventory() @@ -697,7 +1699,7 @@ minetest.register_on_leaveplayer(function(player) end) -- Return true if player is trading with villager, and the villager entity exists -local trader_exists = function(playername) +local function trader_exists(playername) local trader = player_trading_with[playername] return trader ~= nil and trader.object:get_luaentity() ~= nil end @@ -709,6 +1711,11 @@ local trade_inventory = { elseif listname == "output" then if not trader_exists(player:get_player_name()) then return 0 + -- Begin Award Code + -- May need to be moved if award gets unlocked in the wrong cases. + elseif trader_exists(player:get_player_name()) then + awards.unlock(player:get_player_name(), "mcl:whatAdeal") + -- End Award Code end -- Only allow taking full stack local count = stack:get_count() @@ -724,7 +1731,7 @@ local trade_inventory = { wanted1:set_count(wanted1:get_count()*2) wanted2:set_count(wanted2:get_count()*2) -- BEGIN OF SPECIAL HANDLING FOR COMPASS - local special_checks = function(wanted1, input1, input2) + local function special_checks(wanted1, input1, input2) if wanted1:get_name() == COMPASS then local compasses = 0 if (minetest.get_item_group(input1:get_name(), "compass") ~= 0) then @@ -792,7 +1799,8 @@ local trade_inventory = { if not wanted2:is_empty() then inv:remove_item("input", inv:get_stack("wanted", 2)) end - minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name()}, true) + local trader = player_trading_with[name] + minetest.sound_play("mobs_mc_villager_accept", {to_player = player:get_player_name(),object=trader.object}, true) end update_offer(inv, player, true) end, @@ -820,7 +1828,9 @@ local trade_inventory = { -- END OF SPECIAL HANDLING FOR COMPASS local trader = player_trading_with[name] local tradenum = player_tradenum[name] + local trades + trader._traded = true if trader and trader._trades then trades = minetest.deserialize(trader._trades) end @@ -841,6 +1851,10 @@ local trade_inventory = { -- First-time trade unlock all trades and unlock next trade tier if trade.tier + 1 > trader._max_trade_tier then trader._max_trade_tier = trader._max_trade_tier + 1 + if trader._max_trade_tier > 5 then + trader._max_trade_tier = 5 + end + set_textures(trader) update_max_tradenum(trader) update_formspec = true end @@ -854,6 +1868,7 @@ local trade_inventory = { trader.health = math.min(trader.hp_max, trader.health + 4) end 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) if trader._max_tradenum > 1 then if trade.trade_counter >= 12 then @@ -897,10 +1912,11 @@ local trade_inventory = { elseif listname == "input" then update_offer(inv, player, false) end + local trader = player_trading_with[name] if accept then - minetest.sound_play("mobs_mc_villager_accept", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_accept", {to_player = name,object=trader.object}, true) else - minetest.sound_play("mobs_mc_villager_deny", {to_player = name}, true) + minetest.sound_play("mobs_mc_villager_deny", {to_player = name,object=trader.object}, true) end end, } @@ -923,77 +1939,115 @@ end) --[=======[ MOB REGISTRATION AND SPAWNING ]=======] -mobs:register_mob("mobs_mc:villager", { +mcl_mobs.register_mob("mobs_mc:villager", { + description = S("Villager"), type = "npc", spawn_class = "passive", + passive = true, hp_min = 20, hp_max = 20, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 10, + runaway = true, collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_villager.b3d", textures = { - { "mobs_mc_villager.png", "mobs_mc_villager.png", --hat }, - { - "mobs_mc_villager_farmer.png", - "mobs_mc_villager_farmer.png", --hat - }, - { - "mobs_mc_villager_priest.png", - "mobs_mc_villager_priest.png", --hat - }, - { - "mobs_mc_villager_librarian.png", - "mobs_mc_villager_librarian.png", --hat - }, - { - "mobs_mc_villager_butcher.png", - "mobs_mc_villager_butcher.png", --hat - }, - { - "mobs_mc_villager_smith.png", - "mobs_mc_villager_smith.png", --hat - }, - }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, walk_velocity = 1.2, run_velocity = 2.4, drops = {}, can_despawn = false, -- TODO: sounds - animation = { - stand_speed = 25, - stand_start = 40, - stand_end = 59, - walk_speed = 25, - walk_start = 0, - walk_end = 40, - run_speed = 25, - run_start = 0, - run_end = 40, - die_speed = 15, - die_start = 210, - die_end = 220, - die_loop = false, + sounds = { + random = "mobs_mc_villager", + damage = "mobs_mc_villager_hurt", + distance = 10, }, + animation = { + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 25, + run_start = 0, run_end = 40, run_speed = 25, + head_shake_start = 60, head_shake_end = 70, head_shake_loop = false, + head_nod_start = 50, head_nod_end = 60, head_nod_loop = false, + }, + child_animations = { + stand_start = 71, stand_end = 71, + walk_start = 71, walk_end = 111, walk_speed = 37, + run_start = 71, run_end = 111, run_speed = 37, + head_shake_start = 131, head_shake_end = 141, head_shake_loop = false, + head_nod_start = 121, head_nod_end = 131, head_nod_loop = false, + }, + follow = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" }, + nofollow = true, view_range = 16, fear_height = 4, jump = true, walk_chance = DEFAULT_WALK_CHANCE, + _bed = nil, + _id = nil, + _profession = "unemployed", + look_at_player = true, + pick_up = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" }, + can_open_doors = true, + on_pick_up = function(self,itementity) + local clicker + local it = ItemStack(itementity.itemstring) + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(p:get_pos(),self.object:get_pos()) < 10 then + clicker = p + end + end + if clicker and not self.horny then + self:feed_tame(clicker, 1, true, false, true) + it:take_item(1) + end + return it + end, on_rightclick = function(self, clicker) + --minetest.log("In villager right click") + if self.child or self._profession == "unemployed" or self._profession == "nitwit" then + self.order = nil + return + end + + if self.state == PATHFINDING then + self.state = "stand" + end + -- Can we remove now we possibly have fixed root cause + if self.state == "attack" then + mcl_log("Somehow villager got into an invalid attack state. Removed attack state.") + -- Need to stop villager getting in attack state. This is a workaround to allow players to fix broken villager. + self.state = "stand" + self.attack = nil + end + -- Don't do at night. Go to bed? Maybe do_activity needs it's own method + if validate_jobsite(self) and not self.order == WORK then + --self:gopath(self._jobsite,function() + -- minetest.log("sent to jobsite") + --end) + else + self.state = "stand" -- cancel gowp in case it has messed up + --self.order = nil -- cancel work if working + end + -- Initiate trading + init_trader_vars(self) local name = clicker:get_player_name() self._trading_players[name] = true - init_trader_vars(self) - if self._trades == nil then + if self._trades == nil or self._trades == false then + --minetest.log("Trades is nil so init") init_trades(self) end update_max_tradenum(self) if self._trades == false then + --minetest.log("Trades is false. no right click op") -- Villager has no trades, rightclick is a no-op return end @@ -1021,17 +2075,22 @@ mobs:register_mob("mobs_mc:villager", { _player_scan_timer = 0, _trading_players = {}, -- list of playernames currently trading with villager (open formspec) do_custom = function(self, dtime) + check_summon(self,dtime) + -- Stand still if player is nearby. if not self._player_scan_timer then self._player_scan_timer = 0 end self._player_scan_timer = self._player_scan_timer + dtime + -- Check infrequently to keep CPU load low if self._player_scan_timer > PLAYER_SCAN_INTERVAL then + self._player_scan_timer = 0 local selfpos = self.object:get_pos() local objects = minetest.get_objects_inside_radius(selfpos, PLAYER_SCAN_RADIUS) local has_player = false + for o, obj in pairs(objects) do if obj:is_player() then has_player = true @@ -1039,35 +2098,106 @@ mobs:register_mob("mobs_mc:villager", { end end if has_player then - minetest.log("verbose", "[mobs_mc] Player near villager found!") + --minetest.log("verbose", "[mobs_mc] Player near villager found!") stand_still(self) else - minetest.log("verbose", "[mobs_mc] No player near villager found!") + --minetest.log("verbose", "[mobs_mc] No player near villager found!") self.walk_chance = DEFAULT_WALK_CHANCE self.jump = true end + + do_activity (self) + end end, on_spawn = function(self) - init_trader_vars(self) - end, - on_die = function(self, pos) - -- Close open trade formspecs and give input back to players - local trading_players = self._trading_players - for name, _ in pairs(trading_players) do - minetest.close_formspec(name, "mobs_mc:trade_"..name) - local player = minetest.get_player_by_name(name) - if player then - return_fields(player) + if not self._profession then + self._profession = "unemployed" + if math.random(100) == 1 then + self._profession = "nitwit" end end + if self._id then + set_textures(self) + return + end + self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) + set_textures(self) + end, + on_die = function(self, pos, cmi_cause) + -- Close open trade formspecs and give input back to players + local trading_players = self._trading_players + if trading_players then + for name, _ in pairs(trading_players) do + minetest.close_formspec(name, "mobs_mc:trade_"..name) + local player = minetest.get_player_by_name(name) + if player then + return_fields(player) + end + end + end + + local bed = self._bed + if bed then + local bed_meta = minetest.get_meta(bed) + bed_meta:set_string("villager", nil) + mcl_log("Died, so bye bye bed") + end + local jobsite = self._jobsite + if jobsite then + local jobsite_meta = minetest.get_meta(jobsite) + jobsite_meta:set_string("villager", nil) + mcl_log("Died, so bye bye jobsite") + end + + if cmi_cause and cmi_cause.puncher then + local l = cmi_cause.puncher:get_luaentity() + if l and math.random(2) == 1 and( l.name == "mobs_mc:zombie" or l.name == "mobs_mc:baby_zombie" or l.name == "mobs_mc:villager_zombie" or l.name == "mobs_mc:husk") then + mcl_util.replace_mob(self.object,"mobs_mc:villager_zombie") + return true + end + end + end, + on_lightning_strike = function(self, pos, pos2, objects) + mcl_util.replace_mob(self.object, "mobs_mc:witch") + return true end, }) - -mobs:spawn_specific("mobs_mc:villager", mobs_mc.spawn.village, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 8000, 4, mobs_mc.spawn_height.water+1, mobs_mc.spawn_height.overworld_max) - +--[[ +Villager spawning in mcl_villages +mcl_mobs:spawn_specific( +"mobs_mc:villager", +"overworld", +"ground", +{ +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"SunflowerPlains", +"RoofedForest", +"MesaPlateauFM_grasstop", +"ExtremeHillsM", +"BirchForestM", +}, +0, +minetest.LIGHT_MAX+1, +30, +20, +4, +mobs_mc.water_level+1, +mcl_vars.mg_overworld_max) +--]] -- spawn eggs -mobs:register_egg("mobs_mc:villager", S("Villager"), "mobs_mc_spawn_icon_villager.png", 0) +mcl_mobs:non_spawn_specific("mobs_mc:villager","overworld", 0, minetest.LIGHT_MAX+1) +mcl_mobs.register_egg("mobs_mc:villager", S("Villager"), "#563d33", "#bc8b72", 0) diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index 226c82a32..a34f0ffe9 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -11,15 +11,23 @@ local S = minetest.get_translator("mobs_mc") local pr = PseudoRandom(os.time()*666) -mobs:register_mob("mobs_mc:evoker", { +local spawned_vexes = {} --this is stored locally so the mobs engine doesn't try to store it in staticdata + +mcl_mobs.register_mob("mobs_mc:evoker", { + description = S("Evoker"), type = "monster", spawn_class = "hostile", + can_despawn = false, physical = true, pathfinding = 1, hp_min = 24, hp_max = 24, xp_min = 10, xp_max = 10, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 10, collisionbox = {-0.4, -0.01, -0.4, 0.4, 1.95, 0.4}, visual = "mesh", mesh = "mobs_mc_villager.b3d", @@ -28,7 +36,6 @@ mobs:register_mob("mobs_mc:evoker", { "blank.png", --no hat -- TODO: Attack glow } }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, damage = 6, walk_velocity = 0.2, @@ -37,50 +44,50 @@ mobs:register_mob("mobs_mc:evoker", { attack_type = "dogfight", -- Summon vexes custom_attack = function(self, to_attack) - local r = pr:next(2,4) + if not spawned_vexes[self] then spawned_vexes[self] = {} end + if #spawned_vexes[self] >= 7 then return end + for k,v in pairs(spawned_vexes[self]) do + if not v or v.health <= 0 then table.remove(spawned_vexes[self],k) end + end + local r = pr:next(1,4) local basepos = self.object:get_pos() basepos.y = basepos.y + 1 for i=1, r do local spawnpos = vector.add(basepos, minetest.yaw_to_dir(pr:next(0,360))) local vex = minetest.add_entity(spawnpos, "mobs_mc:vex") local ent = vex:get_luaentity() + -- Mark vexes as summoned and start their life clock (they take damage it reaches 0) ent._summoned = true ent._lifetimer = pr:next(33, 108) + + table.insert(spawned_vexes[self],ent) end end, shoot_interval = 15, passive = false, drops = { - {name = mobs_mc.items.emerald, + {name = "mcl_core:emerald", chance = 1, min = 0, max = 1, looting = "common",}, - {name = mobs_mc.items.totem, + {name = "mcl_totems:totem", chance = 1, min = 1, max = 1,}, }, -- TODO: sounds animation = { - stand_speed = 25, - stand_start = 40, - stand_end = 59, - walk_speed = 25, - walk_start = 0, - walk_end = 40, - run_speed = 25, - shoot_start = 120, --magic arm swinging - shoot_end = 140, - die_speed = 15, - die_start = 190, - die_end = 200, - die_loop = false, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 6, + run_start = 0, run_end = 40, run_speed = 24, + shoot_start = 142, shoot_end = 152, -- Magic arm swinging }, view_range = 16, fear_height = 4, }) -- spawn eggs -mobs:register_egg("mobs_mc:evoker", S("Evoker"), "mobs_mc_spawn_icon_evoker.png", 0) +mcl_mobs.register_egg("mobs_mc:evoker", S("Evoker"), "#959b9b", "#1e1c1a", 0) +mcl_mobs:non_spawn_specific("mobs_mc:evoker","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 30e9f6f36..930a1edfe 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -6,7 +6,8 @@ local S = minetest.get_translator("mobs_mc") local mod_bows = minetest.get_modpath("mcl_bows") ~= nil -mobs:register_mob("mobs_mc:illusioner", { +mcl_mobs.register_mob("mobs_mc:illusioner", { + description = S("Illusioner"), type = "monster", spawn_class = "hostile", attack_type = "shoot", @@ -32,11 +33,15 @@ mobs:register_mob("mobs_mc:illusioner", { "mobs_mc_illusionist.png", --hat "mcl_bows_bow.png", }, }, + head_swivel = "head.control", + bone_eye_height = 2.2, + head_eye_height = 2.2, + curiosity = 10, sounds = { -- TODO: more sounds distance = 16, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, walk_velocity = 0.6, run_velocity = 2, jump = true, @@ -60,4 +65,5 @@ mobs:register_mob("mobs_mc:illusioner", { fear_height = 4, }) -mobs:register_egg("mobs_mc:illusioner", S("Illusioner"), "mobs_mc_spawn_icon_illusioner.png", 0) +mcl_mobs.register_egg("mobs_mc:illusioner", S("Illusioner"), "#3f5cbb", "#8a8686", 0) +mcl_mobs:non_spawn_specific("mobs_mc:illusioner","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 3e611acdd..9ccb8509c 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -10,7 +10,8 @@ local S = minetest.get_translator("mobs_mc") --################### -mobs:register_mob("mobs_mc:vindicator", { +mcl_mobs.register_mob("mobs_mc:vindicator", { + description = S("Vindicator"), type = "monster", spawn_class = "hostile", physical = false, @@ -22,28 +23,33 @@ mobs:register_mob("mobs_mc:vindicator", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_vindicator.b3d", - textures = { - { - "mobs_mc_vindicator.png", - "blank.png", --no hat - "default_tool_steelaxe.png", - -- TODO: Glow when attacking (mobs_mc_vindicator.png) - }, - }, - visual_size = {x=3, y=3}, + head_swivel = "head.control", + bone_eye_height = 2.2, + head_eye_height = 2.2, + curiosity = 10, + textures = { + { + "mobs_mc_vindicator.png", + "blank.png", --no hat + "default_tool_steelaxe.png", + -- TODO: Glow when attacking (mobs_mc_vindicator.png) + }, + }, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 13, reach = 2, walk_velocity = 1.2, run_velocity = 2.4, attack_type = "dogfight", + attack_npcs = true, drops = { - {name = mobs_mc.items.emerald, + {name = "mcl_core:emerald", chance = 1, min = 0, max = 1, looting = "common",}, - {name = mobs_mc.items.iron_axe, + {name = "mcl_tools:axe_iron", chance = 100 / 8.5, min = 1, max = 1, @@ -71,4 +77,5 @@ mobs:register_mob("mobs_mc:vindicator", { }) -- spawn eggs -mobs:register_egg("mobs_mc:vindicator", S("Vindicator"), "mobs_mc_spawn_icon_vindicator.png", 0) +mcl_mobs.register_egg("mobs_mc:vindicator", S("Vindicator"), "#959b9b", "#275e61", 0) +mcl_mobs:non_spawn_specific("mobs_mc:vindicator","overworld",0,7) diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index d7f2203e1..5af1fc879 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -25,9 +25,11 @@ local professions = { nitwit = "mobs_mc_villager.png", } -mobs:register_mob("mobs_mc:villager_zombie", { +mcl_mobs.register_mob("mobs_mc:villager_zombie", { + description = S("Zombie Villager"), type = "monster", spawn_class = "hostile", + spawn_in_group = 1, hp_min = 20, hp_max = 20, xp_min = 5, @@ -37,41 +39,44 @@ mobs:register_mob("mobs_mc:villager_zombie", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, visual = "mesh", mesh = "mobs_mc_villager_zombie.b3d", + head_swivel = "Head_Control", + bone_eye_height = 2.35, + curiosity = 2, textures = { {"mobs_mc_zombie_butcher.png"}, {"mobs_mc_zombie_farmer.png"}, {"mobs_mc_zombie_librarian.png"}, {"mobs_mc_zombie_priest.png"}, {"mobs_mc_zombie_smith.png"}, - {"mobs_mc_zombie_villager.png"} + {"mobs_mc_zombie_villager.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 3, reach = 2, walk_velocity = 1.2, - run_velocity = 2.4, + run_velocity = 1.8, attack_type = "dogfight", group_attack = true, drops = { - {name = mobs_mc.items.rotten_flesh, + {name = "mcl_mobitems:rotten_flesh", chance = 1, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.iron_ingot, + {name = "mcl_core:iron_ingot", chance = 120, -- 2.5% / 3 min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 3,}, - {name = mobs_mc.items.carrot, + {name = "mcl_farming:carrot_item", chance = 120, -- 2.5% / 3 min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 3,}, - {name = mobs_mc.items.potato, + {name = "mcl_farming:potato_item", chance = 120, -- 2.5% / 3 min = 1, max = 1, @@ -104,6 +109,7 @@ mobs:register_mob("mobs_mc:villager_zombie", { clicker:set_wielded_item(wielditem) self._curing = math.random(3 * 60, 5 * 60) self.shaking = true + self.persistent = true end end end, @@ -118,20 +124,7 @@ mobs:register_mob("mobs_mc:villager_zombie", { villager_obj:set_yaw(yaw) villager.target_yaw = yaw villager.nametag = self.nametag - local texture = self.base_texture[1]:gsub("zombie", "villager") - if texture == "mobs_mc_villager_villager.png" then - texture = "mobs_mc_villager.png" - end - local textures = {texture} - villager.base_texture = textures - villager_obj:set_properties({textures = textures}) - local matches = {} - for prof, tex in pairs(professions) do - if texture == tex then - table.insert(matches, prof) - end - end - villager._profession = matches[math.random(#matches)] + villager._profession = "unemployed" self._curing = nil mcl_burning.extinguish(obj) obj:remove() @@ -144,11 +137,99 @@ mobs:register_mob("mobs_mc:villager_zombie", { view_range = 16, fear_height = 4, harmed_by_heal = true, + attack_npcs = true, }) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.village, {"air"}, 0, 7, 30, 4090, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:villager_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:villager_zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"Desert", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +4090, +4, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) +--mcl_mobs:spawn_specific("mobs_mc:villager_zombie", "overworld", "ground", 0, 7, 30, 60000, 4, mcl_vars.mg_overworld_min, mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "mobs_mc_spawn_icon_zombie_villager.png", 0) - +mcl_mobs.register_egg("mobs_mc:villager_zombie", S("Zombie Villager"), "#563d33", "#799c66", 0) diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index e95357564..b00a68116 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -12,9 +12,11 @@ local S = minetest.get_translator("mobs_mc") -mobs:register_mob("mobs_mc:witch", { +mcl_mobs.register_mob("mobs_mc:witch", { + description = S("Witch"), type = "monster", spawn_class = "hostile", + can_despawn = false, hp_min = 26, hp_max = 26, xp_min = 5, @@ -25,7 +27,7 @@ mobs:register_mob("mobs_mc:witch", { textures = { {"mobs_mc_witch.png"}, }, - visual_size = {x=3, y=3}, + visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, damage = 2, reach = 2, @@ -41,13 +43,13 @@ mobs:register_mob("mobs_mc:witch", { dogshoot_count_max =1.8, max_drops = 3, drops = { - {name = mobs_mc.items.glass_bottle, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.glowstone_dust, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.gunpowder, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.redstone, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.spider_eye, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.sugar, chance = 8, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.stick, chance = 4, min = 0, max = 2, looting = "common",}, + {name = "mcl_potions:glass_bottle", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mcl_nether:glowstone_dust", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mcl_mobitems:gunpowder", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mesecons:redstone", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mcl_mobitems:spider_eye", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mcl_core:sugar", chance = 8, min = 0, max = 2, looting = "common",}, + {name = "mcl_core:stick", chance = 4, min = 0, max = 2, looting = "common",}, }, -- TODO: sounds animation = { @@ -71,7 +73,7 @@ mobs:register_mob("mobs_mc:witch", { }) -- potion projectile (EXPERIMENTAL) -mobs:register_arrow("mobs_mc:potion_arrow", { +mcl_mobs.register_arrow("mobs_mc:potion_arrow", { visual = "sprite", visual_size = {x = 0.5, y = 0.5}, --textures = {"vessels_glass_bottle.png"}, --TODO fix to else if default @@ -99,8 +101,10 @@ mobs:register_arrow("mobs_mc:potion_arrow", { end }) --- TODO: Spawn when witch works properly ---mobs:spawn_specific("mobs_mc:witch", mobs_mc.spawn.jungle, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.spawn_height.water-6, mobs_mc.spawn_height.overworld_max) +-- TODO: Spawn when witch works properly <- eventually -j4i +--mcl_mobs:spawn_specific("mobs_mc:witch", { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" }, {"air"}, 0, minetest.LIGHT_MAX-6, 12, 20000, 2, mobs_mc.water_level-6, mcl_vars.mg_overworld_max) -- spawn eggs -mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true) +mcl_mobs.register_egg("mobs_mc:witch", S("Witch"), "#340000", "#51a03e", 0, true) +mcl_mobs:non_spawn_specific("mobs_mc:witch","overworld",0,7) +mcl_wip.register_wip_item("mobs_mc:witch") diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 28c1a2138..6b47d601a 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -9,14 +9,15 @@ local S = minetest.get_translator("mobs_mc") --################### WITHER --################### -mobs:register_mob("mobs_mc:wither", { +mcl_mobs.register_mob("mobs_mc:wither", { + description = S("Wither"), type = "monster", spawn_class = "hostile", hp_max = 300, hp_min = 300, xp_min = 50, xp_max = 50, - armor = {undead = 80, fleshy = 80}, + armor = {undead = 80, fleshy = 100}, -- This deviates from MC Wiki's size, which makes no sense collisionbox = {-0.9, 0.4, -0.9, 0.9, 2.45, 0.9}, visual = "mesh", @@ -41,10 +42,11 @@ mobs:register_mob("mobs_mc:wither", { fly = true, makes_footstep_sound = false, dogshoot_switch = 1, - dogshoot_count_max =1, + dogshoot_count_max = 1, attack_animals = true, + can_despawn = false, drops = { - {name = mobs_mc.items.nether_star, + {name = "mcl_mobitems:nether_star", chance = 1, min = 1, max = 1}, @@ -65,14 +67,25 @@ mobs:register_mob("mobs_mc:wither", { run_start = 0, run_end = 20, }, harmed_by_heal = true, + do_custom = function(self) + 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} + end + mcl_bossbars.update_boss(self.object, "Wither", "dark_purple") + end, on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) 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" } -mobs:register_arrow("mobs_mc:wither_skull", { +mcl_mobs.register_arrow("mobs_mc:wither_skull", { visual = "sprite", visual_size = {x = 0.75, y = 0.75}, -- TODO: 3D projectile, replace tetxture @@ -85,7 +98,7 @@ mobs:register_arrow("mobs_mc:wither_skull", { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mobs:boom(self, self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1) end, hit_mob = function(self, mob) @@ -93,15 +106,30 @@ mobs:register_arrow("mobs_mc:wither_skull", { full_punch_interval = 0.5, damage_groups = {fleshy = 8}, }, nil) - mobs:boom(self, self.object:get_pos(), 1) + mcl_mobs.mob_class.boom(self,self.object:get_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 + end end, -- node hit, explode hit_node = function(self, pos, node) - mobs:boom(self, pos, 1) + mcl_mobs.mob_class.boom(self,pos, 1) end }) -- TODO: Add blue wither skull --Spawn egg -mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) +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 fe3031895..7b142086d 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -6,19 +6,9 @@ local default_walk_chance = 50 local pr = PseudoRandom(os.time()*10) -local is_food = function(itemstring) - for f=1, #mobs_mc.follow.dog do - if itemstring == mobs_mc.follow.dog[f] then - return true - elseif string.sub(itemstring, 1, 6) == "group:" and minetest.get_item_group(itemstring, string.sub(itemstring, 7, -1)) ~= 0 then - return true - end - end - return false -end - -- Wolf local wolf = { + description = S("Wolf"), type = "animal", spawn_class = "passive", can_despawn = true, @@ -28,14 +18,20 @@ local wolf = { xp_max = 3, passive = false, group_attack = true, + spawn_in_group = 8, collisionbox = {-0.3, -0.01, -0.3, 0.3, 0.84, 0.3}, visual = "mesh", mesh = "mobs_mc_wolf.b3d", textures = { {"mobs_mc_wolf.png"}, }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, + head_swivel = "head.control", + bone_eye_height = 3.5, + head_eye_height = 1.1, + horrizonatal_head_height=0, + curiosity = 3, + head_yaw="z", sounds = { attack = "mobs_mc_wolf_bark", war_cry = "mobs_mc_wolf_growl", @@ -54,13 +50,13 @@ local wolf = { reach = 2, attack_type = "dogfight", fear_height = 4, - follow = mobs_mc.follow.wolf, + follow = { "mcl_mobitems:bone" }, on_rightclick = function(self, clicker) - -- Try to tame wolf (intentionally does NOT use mobs:feed_tame) + -- Try to tame wolf (intentionally does NOT use mcl_mobs:feed_tame) local tool = clicker:get_wielded_item() local dog, ent - if tool:get_name() == mobs_mc.items.bone then + if tool:get_name() == "mcl_mobitems:bone" then minetest.sound_play("mobs_mc_wolf_take_bone", {object=self.object, max_hear_distance=16}, true) if not minetest.is_creative_enabled(clicker:get_player_name()) then @@ -74,6 +70,11 @@ local wolf = { dog:set_yaw(yaw) ent = dog:get_luaentity() ent.owner = clicker:get_player_name() + ent.tamed = true + ent:set_animation("sit") + ent.walk_chance = 0 + ent.jump = false + ent.health = self.health -- cornfirm taming minetest.sound_play("mobs_mc_wolf_bark", {object=dog, max_hear_distance=16}, true) -- Replace wolf @@ -82,10 +83,16 @@ local wolf = { end end, animation = { - speed_normal = 50, speed_run = 100, - stand_start = 40, stand_end = 45, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 0, stand_end = 0, + walk_start = 0, walk_end = 40, walk_speed = 50, + run_start = 0, run_end = 40, run_speed = 100, + sit_start = 45, sit_end = 45, + }, + child_animations = { + stand_start = 46, stand_end = 46, + walk_start = 46, walk_end = 86, walk_speed = 75, + run_start = 46, run_end = 86, run_speed = 150, + sit_start = 91, sit_end = 91, }, jump = true, attacks_monsters = true, @@ -93,7 +100,7 @@ local wolf = { specific_attack = { "player", "mobs_mc:sheep" }, } -mobs:register_mob("mobs_mc:wolf", wolf) +mcl_mobs.register_mob("mobs_mc:wolf", wolf) -- Tamed wolf @@ -136,43 +143,35 @@ dog.hp_max = 20 dog.textures = get_dog_textures("unicolor_red") dog.owner = "" -- TODO: Start sitting by default -dog.order = "roam" +dog.order = "sit" +dog.state = "stand" dog.owner_loyal = true -dog.follow_velocity = 3.2 +dog.follow_velocity = 3.2 -- Automatically teleport dog to owner dog.do_custom = mobs_mc.make_owner_teleport_function(12) -dog.follow = mobs_mc.follow.dog +dog.follow = { + "mcl_mobitems:rabbit", "mcl_mobitems:cooked_rabbit", + "mcl_mobitems:mutton", "mcl_mobitems:cooked_mutton", + "mcl_mobitems:beef", "mcl_mobitems:cooked_beef", + "mcl_mobitems:chicken", "mcl_mobitems:cooked_chicken", + "mcl_mobitems:porkchop", "mcl_mobitems:cooked_porkchop", + "mcl_mobitems:rotten_flesh", +} dog.attack_animals = nil dog.specific_attack = nil + +local is_food = function(itemstring) + return table.indexof(dog.follow, itemstring) ~= -1 +end + dog.on_rightclick = function(self, clicker) local item = clicker:get_wielded_item() - if mobs:protect(self, clicker) then + if self:feed_tame(clicker, 1, true, false) then return - elseif item:get_name() ~= "" and mobs:capture_mob(self, clicker, 0, 2, 80, false, nil) then + elseif mcl_mobs:protect(self, clicker) then return - elseif is_food(item:get_name()) then - -- Feed to increase health - local hp = self.health - local hp_add = 0 - -- Use eatable group to determine health boost - local eatable = minetest.get_item_group(item, "eatable") - if eatable > 0 then - hp_add = eatable - elseif item:get_name() == mobs_mc.items.rotten_flesh then - hp_add = 4 - else - hp_add = 4 - end - local new_hp = hp + hp_add - if new_hp > self.hp_max then - new_hp = self.hp_max - end - if not minetest.is_creative_enabled(clicker:get_player_name()) then - item:take_item() - clicker:set_wielded_item(item) - end - self.health = new_hp + elseif item:get_name() ~= "" and mcl_mobs:capture_mob(self, clicker, 0, 2, 80, false, nil) then return elseif minetest.get_item_group(item:get_name(), "dye") == 1 then -- Dye (if possible) @@ -195,43 +194,39 @@ dog.on_rightclick = function(self, clicker) end end else - -- Toggle sitting order - if not self.owner or self.owner == "" then - -- Huh? This wolf has no owner? Let's fix this! This should never happen. + -- Huh? This dog has no owner? Let's fix this! This should never happen. self.owner = clicker:get_player_name() end - - local pos = self.object:get_pos() - local particle - if not self.order or self.order == "" or self.order == "sit" then - particle = "mobs_mc_wolf_icon_roam.png" - self.order = "roam" - self.walk_chance = default_walk_chance - self.jump = true - -- TODO: Add sitting model - else - particle = "mobs_mc_wolf_icon_sit.png" - self.order = "sit" - self.walk_chance = 0 - self.jump = false + if not minetest.settings:get_bool("mcl_extended_pet_control",true) then + self:toggle_sit(clicker,-0.4) end - -- Display icon to show current order (sit or roam) - minetest.add_particle({ - pos = vector.add(pos, {x=0,y=1,z=0}), - velocity = {x=0,y=0.2,z=0}, - expirationtime = 1, - size = 4, - texture = particle, - playername = self.owner, - glow = minetest.LIGHT_MAX, - }) end end -mobs:register_mob("mobs_mc:dog", dog) - +mcl_mobs.register_mob("mobs_mc:dog", dog) -- Spawn -mobs:spawn_specific("mobs_mc:wolf", mobs_mc.spawn.wolf, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 9000, 7, mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:wolf", +"overworld", +"ground", +{ + "Taiga", + "MegaSpruceTaiga", + "MegaTaiga", + "Forest", + "ColdTaiga", + "Forest_beach", + "ColdTaiga_beach_water", + "Taiga_beach", + "ColdTaiga_beach", +}, +0, +minetest.LIGHT_MAX+1, +30, +9000, +7, +mobs_mc.water_level+3, +mcl_vars.mg_overworld_max) -mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) +mcl_mobs.register_egg("mobs_mc:wolf", S("Wolf"), "#d7d3d3", "#ceaf96", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index df9727d34..6a4f5d48a 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -10,24 +10,24 @@ local S = minetest.get_translator("mobs_mc") --################### local drops_common = { - {name = mobs_mc.items.rotten_flesh, + {name = "mcl_mobitems:rotten_flesh", chance = 1, min = 0, max = 2, looting = "common",}, - {name = mobs_mc.items.iron_ingot, + {name = "mcl_core:iron_ingot", chance = 120, -- 2.5% / 3 min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 3,}, - {name = mobs_mc.items.carrot, + {name = "mcl_farming:carrot_item", chance = 120, -- 2.5% / 3 min = 1, max = 1, looting = "rare", looting_factor = 0.01 / 3,}, - {name = mobs_mc.items.potato, + {name = "mcl_farming:potato_item", chance = 120, -- 2.5% / 3 min = 1, max = 1, @@ -39,28 +39,37 @@ local drops_zombie = table.copy(drops_common) table.insert(drops_zombie, { -- Zombie Head -- TODO: Only drop if killed by charged creeper - name = mobs_mc.items.head_zombie, + name = "mcl_heads:zombie", chance = 200, -- 0.5% min = 1, max = 1, }) local zombie = { + description = S("Zombie"), type = "monster", spawn_class = "hostile", hp_min = 20, hp_max = 20, xp_min = 5, xp_max = 5, + head_swivel = "head.control", + bone_eye_height = 6.3, + head_eye_height = 2.2, + curiosity = 7, + head_pitch_multiplier=-1, breath_max = -1, + wears_armor = 1, armor = {undead = 90, fleshy = 90}, - collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, + collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.8, 0.3}, visual = "mesh", mesh = "mobs_mc_zombie.b3d", textures = { - {"mobs_mc_zombie.png"}, + { + "mobs_mc_empty.png", -- armor + "mobs_mc_zombie.png", -- texture + } }, - visual_size = {x=3, y=3}, makes_footstep_sound = true, sounds = { random = "mobs_mc_zombie_growl", @@ -70,7 +79,7 @@ local zombie = { distance = 16, }, walk_velocity = .8, - run_velocity = 1.6, + run_velocity = 1.8, damage = 3, reach = 2, fear_height = 4, @@ -80,67 +89,284 @@ local zombie = { group_attack = { "mobs_mc:zombie", "mobs_mc:baby_zombie", "mobs_mc:husk", "mobs_mc:baby_husk" }, drops = drops_zombie, animation = { - speed_normal = 25, speed_run = 50, - stand_start = 40, stand_end = 80, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, + stand_start = 40, stand_end = 49, stand_speed = 2, + walk_start = 0, walk_end = 39, speed_normal = 25, + run_start = 0, run_end = 39, speed_run = 50, + punch_start = 50, punch_end = 59, punch_speed = 20, }, ignited_by_sunlight = true, sunlight_damage = 2, view_range = 16, attack_type = "dogfight", harmed_by_heal = true, + attack_npcs = true, } -mobs:register_mob("mobs_mc:zombie", zombie) +mcl_mobs.register_mob("mobs_mc:zombie", zombie) -- Baby zombie. -- A smaller and more dangerous variant of the zombie local baby_zombie = table.copy(zombie) -baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} +baby_zombie.description = S("Baby Zombie") +baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.98, 0.25} baby_zombie.xp_min = 12 baby_zombie.xp_max = 12 -baby_zombie.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2} baby_zombie.walk_velocity = 1.2 baby_zombie.run_velocity = 2.4 baby_zombie.child = 1 +baby_zombie.reach = 1 +baby_zombie.animation = { + stand_start = 100, stand_end = 109, stand_speed = 2, + walk_start = 60, walk_end = 99, speed_normal = 40, + run_start = 60, run_end = 99, speed_run = 80, + punch_start = 109, punch_end = 119 +} -mobs:register_mob("mobs_mc:baby_zombie", baby_zombie) +mcl_mobs.register_mob("mobs_mc:baby_zombie", baby_zombie) -- Husk. -- Desert variant of the zombie local husk = table.copy(zombie) -husk.textures = {{"mobs_mc_husk.png"}} +husk.description = S("Husk") +husk.textures = { + { + "mobs_mc_empty.png", -- armor + "mobs_mc_husk.png", -- texture + } + } husk.ignited_by_sunlight = false husk.sunlight_damage = 0 husk.drops = drops_common -- TODO: Husks avoid water -mobs:register_mob("mobs_mc:husk", husk) +mcl_mobs.register_mob("mobs_mc:husk", husk) -- Baby husk. -- A smaller and more dangerous variant of the husk -local baby_husk = table.copy(husk) -baby_husk.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} -baby_husk.xp_min = 12 -baby_husk.xp_max = 12 -baby_husk.visual_size = {x=zombie.visual_size.x/2, y=zombie.visual_size.y/2} -baby_husk.walk_velocity = 1.2 -baby_husk.run_velocity = 2.4 -baby_husk.child = 1 +local baby_husk = table.copy(baby_zombie) +baby_husk.description = S("Baby Husk") +baby_husk.textures = {{ + "mobs_mc_empty.png", -- wielded_item + "mobs_mc_husk.png", -- texture +}} +baby_husk.ignited_by_sunlight = false +baby_husk.sunlight_damage = 0 +baby_husk.drops = drops_common -mobs:register_mob("mobs_mc:baby_husk", baby_husk) +mcl_mobs.register_mob("mobs_mc:baby_husk", baby_husk) -- Spawning -mobs:spawn_specific("mobs_mc:zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 6000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +6000, +4, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_zombie", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 60000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 6500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -mobs:spawn_specific("mobs_mc:baby_husk", mobs_mc.spawn.desert, {"air"}, 0, 7, 30, 65000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:baby_zombie", +"overworld", +"ground", +{ +"FlowerForest_underground", +"JungleEdge_underground", +"StoneBeach_underground", +"MesaBryce_underground", +"Mesa_underground", +"RoofedForest_underground", +"Jungle_underground", +"Swampland_underground", +"BirchForest_underground", +"Plains_underground", +"MesaPlateauF_underground", +"ExtremeHills_underground", +"MegaSpruceTaiga_underground", +"BirchForestM_underground", +"SavannaM_underground", +"MesaPlateauFM_underground", +"Desert_underground", +"Savanna_underground", +"Forest_underground", +"SunflowerPlains_underground", +"ColdTaiga_underground", +"IcePlains_underground", +"IcePlainsSpikes_underground", +"MegaTaiga_underground", +"Taiga_underground", +"ExtremeHills+_underground", +"JungleM_underground", +"ExtremeHillsM_underground", +"JungleEdgeM_underground", +"Mesa", +"FlowerForest", +"Swampland", +"Taiga", +"ExtremeHills", +"Jungle", +"Savanna", +"BirchForest", +"MegaSpruceTaiga", +"MegaTaiga", +"ExtremeHills+", +"Forest", +"Plains", +"ColdTaiga", +"IcePlainsSpikes", +"SunflowerPlains", +"IcePlains", +"RoofedForest", +"ExtremeHills+_snowtop", +"MesaPlateauFM_grasstop", +"JungleEdgeM", +"ExtremeHillsM", +"JungleM", +"BirchForestM", +"MesaPlateauF", +"MesaPlateauFM", +"MesaPlateauF_grasstop", +"MesaBryce", +"JungleEdge", +"SavannaM", +"FlowerForest_beach", +"Forest_beach", +"StoneBeach", +"ColdTaiga_beach_water", +"Taiga_beach", +"Savanna_beach", +"Plains_beach", +"ExtremeHills_beach", +"ColdTaiga_beach", +"Swampland_shore", +"JungleM_shore", +"Jungle_shore", +"MesaPlateauFM_sandlevel", +"MesaPlateauF_sandlevel", +"MesaBryce_sandlevel", +"Mesa_sandlevel", +}, +0, +7, +30, +60000, +4, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) + + +mcl_mobs:spawn_specific( +"mobs_mc:husk", +"overworld", +"ground", +{ +"Desert", +}, +0, +7, +30, +6500, +4, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) +mcl_mobs:spawn_specific( +"mobs_mc:baby_husk", +"overworld", +"ground", +{ +"Desert", +}, +0, +7, +30, +65000, +4, +mcl_vars.mg_overworld_min, +mcl_vars.mg_overworld_max) -- Spawn eggs -mobs:register_egg("mobs_mc:husk", S("Husk"), "mobs_mc_spawn_icon_husk.png", 0) -mobs:register_egg("mobs_mc:zombie", S("Zombie"), "mobs_mc_spawn_icon_zombie.png", 0) +mcl_mobs.register_egg("mobs_mc:husk", S("Husk"), "#777361", "#ded88f", 0) +mcl_mobs.register_egg("mobs_mc:zombie", S("Zombie"), "#00afaf", "#799c66", 0) diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua deleted file mode 100644 index 8c29a4bff..000000000 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ /dev/null @@ -1,122 +0,0 @@ ---MCmobs v0.4 ---maikerumine ---made for MC like Survival game ---License for code WTFPL and otherwise stated in readmes - -local S = minetest.get_translator("mobs_mc") - ---################### ---################### ZOMBIE PIGMAN ---################### - - -local pigman = { - -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked - type = "animal", - passive = false, - spawn_class = "passive", - hp_min = 20, - hp_max = 20, - xp_min = 6, - xp_max = 6, - armor = {undead = 90, fleshy = 90}, - attack_type = "dogfight", - group_attack = { "mobs_mc:pigman", "mobs_mc:baby_pigman" }, - damage = 9, - reach = 2, - collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.94, 0.3}, - visual = "mesh", - mesh = "mobs_mc_zombie_pigman.b3d", - textures = { { - "blank.png", --baby - "default_tool_goldsword.png", --sword - "mobs_mc_zombie_pigman.png", --pigman - } }, - visual_size = {x=3, y=3}, - sounds = { - random = "mobs_mc_zombiepig_random", - war_cry = "mobs_mc_zombiepig_war_cry", - death = "mobs_mc_zombiepig_death", - damage = "mobs_mc_zombiepig_hurt", - distance = 16, - }, - jump = true, - makes_footstep_sound = true, - walk_velocity = .8, - run_velocity = 2.6, - pathfinding = 1, - drops = { - {name = mobs_mc.items.rotten_flesh, - chance = 1, - min = 1, - max = 1, - looting = "common"}, - {name = mobs_mc.items.gold_nugget, - chance = 1, - min = 0, - max = 1, - looting = "common"}, - {name = mobs_mc.items.gold_ingot, - chance = 40, -- 2.5% - min = 1, - max = 1, - looting = "rare"}, - {name = mobs_mc.items.gold_sword, - chance = 100 / 8.5, - min = 1, - max = 1, - looting = "rare"}, - }, - animation = { - stand_speed = 25, - walk_speed = 25, - run_speed = 50, - stand_start = 40, - stand_end = 80, - walk_start = 0, - walk_end = 40, - run_start = 0, - run_end = 40, - punch_start = 90, - punch_end = 130, - }, - lava_damage = 0, - fire_damage = 0, - fear_height = 4, - view_range = 16, - harmed_by_heal = true, - fire_damage_resistant = true, -} - -mobs:register_mob("mobs_mc:pigman", pigman) - --- Baby pigman. --- A smaller and more dangerous variant of the pigman - -local baby_pigman = table.copy(pigman) -baby_pigman.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} -baby_pigman.xp_min = 13 -baby_pigman.xp_max = 13 -baby_pigman.visual_size = {x=pigman.visual_size.x/2, y=pigman.visual_size.y/2} -baby_pigman.textures = { { - "mobs_mc_zombie_pigman.png", --baby - "default_tool_goldsword.png", --sword - "mobs_mc_zombie_pigman.png", --pigman -} } -baby_pigman.walk_velocity = 1.2 -baby_pigman.run_velocity = 2.4 -baby_pigman.light_damage = 0 -baby_pigman.child = 1 - -mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) - --- Regular spawning in the Nether -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 6000, 3, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) --- Baby zombie is 20 times less likely than regular zombies -mobs:spawn_specific("mobs_mc:baby_pigman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 100000, 4, mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) - --- Spawning in Nether portals in the Overworld -mobs:spawn_specific("mobs_mc:pigman", mobs_mc.spawn.nether_portal, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 500, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) - --- spawn eggs -mobs:register_egg("mobs_mc:pigman", S("Zombie Pigman"), "mobs_mc_spawn_icon_zombie_pigman.png", 0) diff --git a/mods/ENTITIES/mobs_mc_gameconfig/depends.txt b/mods/ENTITIES/mobs_mc_gameconfig/depends.txt deleted file mode 100644 index 2f89674f3..000000000 --- a/mods/ENTITIES/mobs_mc_gameconfig/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_init -mcl_core diff --git a/mods/ENTITIES/mobs_mc_gameconfig/init.lua b/mods/ENTITIES/mobs_mc_gameconfig/init.lua deleted file mode 100644 index 5f4e37c43..000000000 --- a/mods/ENTITIES/mobs_mc_gameconfig/init.lua +++ /dev/null @@ -1,246 +0,0 @@ -mobs_mc = {} - -mobs_mc.override = {} - -mobs_mc.override.items = { - blaze_rod = "mcl_mobitems:blaze_rod", - blaze_powder = "mcl_mobitems:blaze_powder", - chicken_raw = "mcl_mobitems:chicken", - chicken_cooked = "mcl_mobitems:cooked_chicken", - feather = "mcl_mobitems:feather", - beef_raw = "mcl_mobitems:beef", - beef_cooked = "mcl_mobitems:cooked_beef", - bowl = "mcl_core:bowl", - mushroom_stew = "mcl_mushrooms:mushroom_stew", - milk = "mcl_mobitems:milk_bucket", - dragon_egg = "mcl_end:dragon_egg", - egg = "mcl_throwing:egg", - ender_eye = "mcl_mobitems:ender_eye", - ghast_tear = "mcl_mobitems:ghast_tear", - saddle = "mcl_mobitems:saddle", - porkchop_raw = "mcl_mobitems:porkchop", - porkchop_cooked = "mcl_mobitems:cooked_porkchop", - carrot_on_a_stick = "mcl_mobitems:carrot_on_a_stick", - rabbit_raw = "mcl_mobitems:rabbit", - rabbit_cooked = "mcl_mobitems:cooked_rabbit", - rabbit_hide = "mcl_mobitems:rabbit_hide", - mutton_raw = "mcl_mobitems:mutton", - mutton_cooked = "mcl_mobitems:cooked_mutton", - shulker_shell = "mcl_mobitems:shulker_shell", - magma_cream = "mcl_mobitems:magma_cream", - spider_eye = "mcl_mobitems:spider_eye", - rotten_flesh = "mcl_mobitems:rotten_flesh", - snowball = "mcl_throwing:snowball", - top_snow = "mcl_core:snow", - snow_block = "mcl_core:snowblock", - arrow = "mcl_bows:arrow", - bow = "mcl_bows:bow", - head_zombie = "mcl_heads:zombie", - head_creeper = "mcl_heads:creeper", - head_skeleton = "mcl_heads:skeleton", - head_wither_skeleton = "mcl_heads:wither_skeleton", - - leather = "mcl_mobitems:leather", - shears = "mcl_tools:shears", - - mushroom_red = "mcl_mushrooms:mushroom_red", - mushroom_brown = "mcl_mushrooms:mushroom_brown", - bucket = "mcl_buckets:bucket_empty", - grass_block = "mcl_core:dirt_with_grass", - string = "mcl_mobitems:string", - stick = "mcl_core:stick", - flint = "mcl_core:flint", - iron_ingot = "mcl_core:iron_ingot", - iron_block = "mcl_core:ironblock", - fire = "mcl_fire:fire", - gunpowder = "mcl_mobitems:gunpowder", - flint_and_steel = "mcl_fire:flint_and_steel", - water_source = "mcl_core:water_source", - river_water_source = "mclx_core:river_water_source", - black_dye = "mcl_dye:black", - poppy = "mcl_flowers:poppy", - dandelion = "mcl_flowers:dandelion", - coal = "mcl_core:coal_lump", - emerald = "mcl_core:emerald", - iron_axe = "mcl_tools:axe_iron", - gold_sword = "mcl_tools:sword_gold", - gold_ingot = "mcl_core:gold_ingot", - gold_nugget = "mcl_core:gold_nugget", - glowstone_dust = "mcl_nether:glowstone_dust", - redstone = "mesecons:redstone", - glass_bottle = "mcl_potions:glass_bottle", - sugar = "mcl_core:sugar", - wheat = "mcl_farming:wheat_item", - cookie = "mcl_farming:cookie", - potato = "mcl_farming:potato_item", - hay_bale = "mcl_farming:hay_block", - prismarine_shard = "mcl_ocean:prismarine_shard", - prismarine_crystals = "mcl_ocean:prismarine_crystals", - apple = "mcl_core:apple", - golden_apple = "mcl_core:apple_gold", - rabbit_foot = "mcl_mobitems:rabbit_foot", - wet_sponge = "mcl_sponges:sponge_wet", - - -- Other - nether_brick_block = "mcl_nether:nether_brick", - netherrack = "mcl_nether:netherrack", - nether_star = "mcl_mobitems:nether_star", - nether_portal = "mcl_portals:portal", - mycelium = "mcl_core:mycelium", - carrot = "mcl_farming:carrot_item", - golden_carrot = "mcl_farming:carrot_item_gold", - fishing_rod = "mcl_fishing:fishing_rod", - fish_raw = "mcl_fishing:fish_raw", - salmon_raw = "mcl_fishing:salmon_raw", - clownfish_raw = "mcl_fishing:clownfish_raw", - pufferfish_raw = "mcl_fishing:pufferfish_raw", - bone = "mcl_mobitems:bone", - slimeball = "mcl_mobitems:slimeball", - - ender_pearl = "mcl_throwing:ender_pearl", - - wool_white = "mcl_wool:white", - wool_light_grey = "mcl_wool:silver", - wool_grey = "mcl_wool:grey", - wool_blue = "mcl_wool:blue", - wool_lime = "mcl_wool:lime", - wool_green = "mcl_wool:green", - wool_purple = "mcl_wool:purple", - wool_pink = "mcl_wool:pink", - wool_yellow = "mcl_wool:yellow", - wool_orange = "mcl_wool:orange", - wool_brown = "mcl_wool:brown", - wool_red = "mcl_wool:red", - wool_cyan = "mcl_wool:cyan", - wool_magenta = "mcl_wool:magenta", - wool_black = "mcl_wool:black", - wool_light_blue = "mcl_wool:light_blue", - - music_discs = { - "mcl_jukebox:record_1", - "mcl_jukebox:record_2", - "mcl_jukebox:record_3", - "mcl_jukebox:record_4", - "mcl_jukebox:record_5", - "mcl_jukebox:record_6", - "mcl_jukebox:record_7", - "mcl_jukebox:record_8", - "mcl_jukebox:record_9", - }, -} - ---Horses, Llamas, and Wolves shouldn't follow, but leaving this alone until leads are implemented. -mobs_mc.override.follow = { - chicken = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", "mcl_farming:pumpkin_seeds", "mcl_farming:beetroot_seeds", }, - parrot = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", "mcl_farming:pumpkin_seeds", "mcl_farming:beetroot_seeds", }, - pig = { mobs_mc.override.items.potato, mobs_mc.override.items.carrot, "mcl_farming:beetroot_item", mobs_mc.override.items.carrot_on_a_stick}, - ocelot = { mobs_mc.override.items.fish_raw, mobs_mc.override.items.salmon_raw, mobs_mc.override.items.clownfish_raw, mobs_mc.override.items.pufferfish_raw, }, - sheep = { mobs_mc.override.items.wheat }, - cow = { mobs_mc.override.items.wheat }, - horse = { mobs_mc.override.items.apple, mobs_mc.override.items.sugar, mobs_mc.override.items.wheat, mobs_mc.override.items.hay_bale, mobs_mc.override.items.golden_apple, mobs_mc.override.items.golden_carrot }, - llama = { mobs_mc.override.items.wheat, mobs_mc.override.items.hay_bale }, - rabbit = { mobs_mc.override.items.dandelion, mobs_mc.override.items.carrot, mobs_mc.override.items.golden_carrot }, - wolf = { mobs_mc.override.items.bone }, - dog = { mobs_mc.override.items.rabbit_raw, mobs_mc.override.items.rabbit_cooked, mobs_mc.override.items.mutton_raw, mobs_mc.override.items.mutton_cooked, mobs_mc.override.items.beef_raw, mobs_mc.override.items.beef_cooked, mobs_mc.override.items.chicken_raw, mobs_mc.override.items.chicken_cooked, mobs_mc.override.items.rotten_flesh, mobs_mc.override.items.porkchop_raw, mobs_mc.override.items.porkchop_cooked }, -} - -mobs_mc.override.replace = { - -- Rabbits reduce carrot growth stage by 1 - rabbit = { - {"mcl_farming:carrot", "mcl_farming:carrot_7", 0}, - {"mcl_farming:carrot_7", "mcl_farming:carrot_6", 0}, - {"mcl_farming:carrot_6", "mcl_farming:carrot_5", 0}, - {"mcl_farming:carrot_5", "mcl_farming:carrot_4", 0}, - {"mcl_farming:carrot_4", "mcl_farming:carrot_3", 0}, - {"mcl_farming:carrot_3", "mcl_farming:carrot_2", 0}, - {"mcl_farming:carrot_2", "mcl_farming:carrot_1", 0}, - {"mcl_farming:carrot_1", "air", 0}, - }, - -- Sheep eat grass - sheep = { - { "mcl_core:dirt_with_grass", "mcl_core:dirt", -1 }, - { "mcl_flowers:tallgrass", "air", 0 }, - }, - -- Silverfish populate stone, etc. with monster eggs - silverfish = { - {"mcl_core:stone", "mcl_monster_eggs:monster_egg_stone", -1}, - {"mcl_core:cobble", "mcl_monster_eggs:monster_egg_cobble", -1}, - {"mcl_core:stonebrick", "mcl_monster_eggs:monster_egg_stonebrick", -1}, - {"mcl_core:stonebrickmossy", "mcl_monster_eggs:monster_egg_stonebrickmossy", -1}, - {"mcl_core:stonebrickcracked", "mcl_monster_eggs:monster_egg_stonebrickcracked", -1}, - {"mcl_core:stonebrickcarved", "mcl_monster_eggs:monster_egg_stonebrickcarved", -1}, - }, -} - --- List of nodes which endermen can take -mobs_mc.override.enderman_takable = { - -- Generic handling, useful for entensions - "group:enderman_takable", -} -mobs_mc.override.enderman_replace_on_take = { -} -mobs_mc.override.misc = { - totem_fail_nodes = { "mcl_core:void", "mcl_core:realm_barrier" }, -} - --- Texuture overrides for enderman block. Required for cactus because it's original is a nodebox --- and the textures have tranparent pixels. -local cbackground = "mobs_mc_gameconfig_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 - -mobs_mc.override.enderman_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)"} -} - --- List of nodes on which mobs can spawn -mobs_mc.override.spawn = { - solid = { "group:solid", }, -- spawn on "solid" nodes - grassland = { "mcl_core:dirt_with_grass" }, - savanna = { "mcl_core:dirt_with_grass" }, - grassland_savanna = { "mcl_core:dirt_with_grass" }, - desert = { "mcl_core:sand", "mcl_core:sandstone" }, - jungle = { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" }, - snow = { "mcl_core:snow", "mcl_core:snowblock", "mcl_core:dirt_with_grass_snow" }, - -- End stone added for shulkers because End cities don't generate yet - end_city = { "mcl_end:end_stone", "mcl_end:purpur_block" }, - -- Netherrack added because there are no Nether fortresses yet. TODO: Remove netherrac from list as soon they're available - nether_fortress = { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, - nether_portal = { mobs_mc.override.items.nether_portal }, - wolf = { mobs_mc.override.items.grass_block, "mcl_core:dirt", "mcl_core:dirt_with_grass_snow", "mcl_core:snow", "mcl_core:snowblock", "mcl_core:podzol" }, -} - --- This table contains important spawn height references for the mob spawn height. -mobs_mc.override.spawn_height = { - water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld - - -- Overworld boundaries (inclusive) - overworld_min = mcl_vars.mg_overworld_min, - overworld_max = mcl_vars.mg_overworld_max, - - -- Nether boundaries (inclusive) - nether_min = mcl_vars.mg_nether_min, - nether_max = mcl_vars.mg_nether_max, - - -- End boundaries (inclusive) - end_min = mcl_vars.mg_end_min, - end_max = mcl_vars.mg_end_max, -} - diff --git a/mods/ENTITIES/mobs_mc_gameconfig/textures/mobs_mc_gameconfig_enderman_cactus_background.png b/mods/ENTITIES/mobs_mc_gameconfig/textures/mobs_mc_gameconfig_enderman_cactus_background.png deleted file mode 100644 index e2f7ad9a2..000000000 Binary files a/mods/ENTITIES/mobs_mc_gameconfig/textures/mobs_mc_gameconfig_enderman_cactus_background.png and /dev/null differ diff --git a/mods/ENVIRONMENT/lightning/API.md b/mods/ENVIRONMENT/lightning/API.md new file mode 100644 index 000000000..ad4f0a3b4 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/API.md @@ -0,0 +1,31 @@ +# lightning +Lightning mod for MineClone2 with the following API: + +## lightning.register_on_strike(function(pos, pos2, objects)) +Custom function called when a lightning strikes. + +* `pos`: impact position +* `pos2`: rounded node position where fire is placed +* `objects`: table with ObjectRefs of all objects within a radius of 3.5 around pos2 + +## lightning.strike(pos) +Let a lightning strike. + +* `pos`: optional, if not given a random pos will be chosen +* `returns`: bool - success if a strike happened + + +### Examples: + +``` +lightning.register_on_strike(function(pos, pos2, objects) + for _, obj in pairs(objects) do + obj:remove() + end + minetest.add_entity(pos, "mobs_mc:sheep") +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/depends.txt b/mods/ENVIRONMENT/lightning/depends.txt deleted file mode 100644 index 356c2f185..000000000 --- a/mods/ENVIRONMENT/lightning/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_fire -mcl_death_messages? diff --git a/mods/ENVIRONMENT/lightning/description.txt b/mods/ENVIRONMENT/lightning/description.txt deleted file mode 100644 index 98fdb3626..000000000 --- a/mods/ENVIRONMENT/lightning/description.txt +++ /dev/null @@ -1 +0,0 @@ -A mod that adds thunder and lightning effects. diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 3d6a85e51..59591b061 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -1,6 +1,7 @@ --[[ Copyright (C) 2016 - Auke Kok +Adapted by MineClone2 contributors "lightning" is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as @@ -9,24 +10,36 @@ of the license, or (at your option) any later version. --]] -local S = minetest.get_translator("lightning") +local S = minetest.get_translator(minetest.get_current_modname()) -lightning = {} +local get_connected_players = minetest.get_connected_players +local line_of_sight = minetest.line_of_sight +local get_node = minetest.get_node +local set_node = minetest.set_node +local sound_play = minetest.sound_play +local add_particlespawner = minetest.add_particlespawner +local after = minetest.after +local add_entity = minetest.add_entity +local get_objects_inside_radius = minetest.get_objects_inside_radius +local get_item_group = minetest.get_item_group -lightning.interval_low = 17 -lightning.interval_high = 503 -lightning.range_h = 100 -lightning.range_v = 50 -lightning.size = 100 --- disable this to stop lightning mod from striking -lightning.auto = true +lightning = { + interval_low = 17, + interval_high = 503, + range_h = 100, + range_v = 50, + size = 100, + -- disable this to stop lightning mod from striking + auto = true, + on_strike_functions = {}, +} local rng = PcgRandom(32321123312123) local ps = {} local ttl = -1 -local revertsky = function(dtime) +local function revertsky(dtime) if ttl == 0 then return end @@ -42,10 +55,22 @@ end minetest.register_globalstep(revertsky) +-- lightning strike API + +-- See API.md +--[[ + lightning.register_on_strike(function(pos, pos2, objects) + -- code + end) +]] +function lightning.register_on_strike(func) + table.insert(lightning.on_strike_functions, func) +end + -- select a random strike point, midpoint local function choose_pos(pos) if not pos then - local playerlist = minetest.get_connected_players() + local playerlist = get_connected_players() local playercount = table.getn(playerlist) -- nobody on @@ -67,14 +92,14 @@ local function choose_pos(pos) pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h)) end - local b, pos2 = minetest.line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1) + local b, pos2 = line_of_sight(pos, { x = pos.x, y = pos.y - lightning.range_v, z = pos.z }, 1) -- nothing but air found if b then return nil, nil end - local n = minetest.get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z}) + local n = get_node({ x = pos2.x, y = pos2.y - 1/2, z = pos2.z }) if n.name == "air" or n.name == "ignore" then return nil, nil end @@ -82,35 +107,20 @@ local function choose_pos(pos) return pos, pos2 end --- lightning strike API --- * pos: optional, if not given a random pos will be chosen --- * returns: bool - success if a strike happened -lightning.strike = function(pos) - if lightning.auto then - minetest.after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) - end - - local pos2 - pos, pos2 = choose_pos(pos) - - if not pos then - return false - end - - minetest.add_particlespawner({ +function lightning.strike_func(pos, pos2, objects) + local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0) + local particle_size = lightning.size * 10 + local time = 0.2 + add_particlespawner({ amount = 1, - time = 0.2, + time = time, -- make it hit the top of a block exactly with the bottom - minpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, - maxpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z }, - minvel = {x = 0, y = 0, z = 0}, - maxvel = {x = 0, y = 0, z = 0}, - minacc = {x = 0, y = 0, z = 0}, - maxacc = {x = 0, y = 0, z = 0}, - minexptime = 0.2, - maxexptime = 0.2, - minsize = lightning.size * 10, - maxsize = lightning.size * 10, + minpos = particle_pos, + maxpos = particle_pos, + minexptime = time, + maxexptime = time, + minsize = particle_size, + maxsize = particle_size, collisiondetection = true, vertical = true, -- to make it appear hitting the node that will get set on fire, make sure @@ -120,66 +130,32 @@ lightning.strike = function(pos) glow = minetest.LIGHT_MAX, }) - minetest.sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) + sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) -- damage nearby objects, transform mobs - local objs = minetest.get_objects_inside_radius(pos2, 3.5) - for o=1, #objs do - local obj = objs[o] + for _, obj in pairs(objects) do local lua = obj:get_luaentity() - if obj:is_player() then - -- Player damage - if minetest.get_modpath("mcl_death_messages") then - mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name())) - end - obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) - -- Mobs - elseif lua and lua._cmi_is_mob then - -- pig → zombie pigman (no damage) - if lua.name == "mobs_mc:pig" then - local rot = obj:get_yaw() - obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:pigman") - obj:set_yaw(rot) - -- mooshroom: toggle color red/brown (no damage) - elseif lua.name == "mobs_mc:mooshroom" then - if lua.base_texture[1] == "mobs_mc_mooshroom.png" then - lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } - else - lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } - end - obj:set_properties({textures = lua.base_texture}) - -- villager → witch (no damage) - elseif lua.name == "mobs_mc:villager" then - -- Witches are incomplete, this code is unused - -- TODO: Enable this code when witches are working. - --[[ - local rot = obj:get_yaw() - obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:witch") - obj:set_yaw(rot) - ]] - -- TODO: creeper → charged creeper (no damage) - elseif lua.name == "mobs_mc:creeper" then - - -- Other mobs: Just damage - else - obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) + if lua then + if not lua.on_lightning_strike or ( lua.on_lightning_strike and lua.on_lightning_strike(lua, pos, pos2, objects) ~= true ) then + mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end + else + mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" }) end end - local playerlist = minetest.get_connected_players() + local playerlist = get_connected_players() for i = 1, #playerlist do local player = playerlist[i] local sky = {} + local sky_table = player:get_sky(true) - sky.bgcolor, sky.type, sky.textures = player:get_sky() + sky.bgcolor, sky.type, sky.textures = sky_table.base_color, sky_table.type, sky_table.textures local name = player:get_player_name() if ps[name] == nil then ps[name] = {p = player, sky = sky} - mcl_weather.skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true) + mcl_weather.skycolor.add_layer("lightning", { { r = 255, g = 255, b = 255 } }, true) mcl_weather.skycolor.active = true end end @@ -194,42 +170,74 @@ lightning.strike = function(pos) if rng:next(1,100) <= 3 then skeleton_lightning = true end - if minetest.get_item_group(minetest.get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then - if minetest.get_node(pos2).name == "air" then + if get_item_group(get_node({ x = pos2.x, y = pos2.y - 1, z = pos2.z }).name, "liquid") < 1 then + if get_node(pos2).name == "air" then -- Low chance for a lightning to spawn skeleton horse + skeletons if skeleton_lightning then - minetest.add_entity(pos2, "mobs_mc:skeleton_horse") + add_entity(pos2, "mobs_mc:skeleton_horse") local angle, posadd angle = math.random(0, math.pi*2) for i=1,3 do - posadd = {x=math.cos(angle),y=0,z=math.sin(angle)} + posadd = { x=math.cos(angle),y=0,z=math.sin(angle) } posadd = vector.normalize(posadd) - local mob = minetest.add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") - mob:set_yaw(angle-math.pi/2) + local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") + if mob then + mob:set_yaw(angle-math.pi/2) + end angle = angle + (math.pi*2) / 3 end -- Cause a fire else - minetest.set_node(pos2, {name = "mcl_fire:fire"}) + set_node(pos2, { name = "mcl_fire:fire" }) end end end +end +-- * pos: optional, if not given a random pos will be chosen +-- * returns: bool - success if a strike happened +function lightning.strike(pos) + if lightning.auto then + after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) + end + + local pos2 + pos, pos2 = choose_pos(pos) + + if not pos then + return false + end + local do_strike = true + if lightning.on_strike_functions then + for _, func in pairs(lightning.on_strike_functions) do + -- allow on_strike callbacks to destroy entities by re-obtaining objects for each callback + local objects = get_objects_inside_radius(pos2, 3.5) + local p,stop = func(pos, pos2, objects) + if p then + pos = p + pos2 = choose_pos(p) + end + do_strike = do_strike and not stop + end + end + if do_strike then + lightning.strike_func(pos,pos2,get_objects_inside_radius(pos2, 3.5)) + end end -- if other mods disable auto lightning during initialization, don't trigger the first lightning. -minetest.after(5, function(dtime) +after(5, function(dtime) if lightning.auto then - minetest.after(rng:next(lightning.interval_low, + after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) end end) minetest.register_chatcommand("lightning", { - params = "[ ]", - description = S("Let lightning strike at the specified position or yourself"), + params = "[ | ]", + description = S("Let lightning strike at the specified position or player. No parameter will strike yourself."), privs = { maphack = true }, func = function(name, param) local pos = {} @@ -237,23 +245,22 @@ minetest.register_chatcommand("lightning", { pos.x = tonumber(pos.x) pos.y = tonumber(pos.y) pos.z = tonumber(pos.z) + local player_to_strike if not (pos.x and pos.y and pos.z) then pos = nil + player_to_strike = minetest.get_player_by_name(param) + if not player_to_strike and param == "" then + player_to_strike = minetest.get_player_by_name(name) + end end - if name == "" and pos == nil then + if not player_to_strike and pos == nil then return false, "No position specified and unknown player" end if pos then lightning.strike(pos) - else - local player = minetest.get_player_by_name(name) - if player then - lightning.strike(player:get_pos()) - else - return false, S("No position specified and unknown player") - end + elseif player_to_strike then + lightning.strike(player_to_strike:get_pos()) end return true end, }) - diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.dk.tr b/mods/ENVIRONMENT/lightning/locale/lightning.dk.tr new file mode 100644 index 000000000..4bd4b0992 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.dk.tr @@ -0,0 +1,3 @@ +# textdomain: lightning +Let lightning strike at the specified position or player. No parameter will strike yourself.=Lad lynet slå ned på den angivne position eller spiller. Hvis du ikke skriver et parameter vil lynet ramme dig selv. +No position specified and unknown player=Ingen position og ukendt spiller. diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr b/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr index 18c61d51c..ca0854553 100644 --- a/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr +++ b/mods/ENVIRONMENT/lightning/locale/lightning.fr.tr @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.=@1 a été frappé par la foudre. -Let lightning strike at the specified position or yourself=Laissez la foudre frapper à la position spécifiée ou sur vous-même +Let lightning strike at the specified position or player. No parameter will strike yourself.=Fait frapper la foudre à la position spécifiée ou sur le joueur. Sans paramètre vous vous frapperez vous-même. No position specified and unknown player=Aucune position spécifiée et joueur inconnu diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr b/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr new file mode 100644 index 000000000..b84b27af0 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.ja.tr @@ -0,0 +1,3 @@ +# textdomain: lightning +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/lightning/locale/lightning.pl.tr b/mods/ENVIRONMENT/lightning/locale/lightning.pl.tr new file mode 100644 index 000000000..1b0edbd1f --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.pl.tr @@ -0,0 +1,4 @@ +# textdomain: lightning +@1 was struck by lightning.=@1 została trafiona przez piorun. +Let lightning strike at the specified position or yourself=Pozwala by piorun uderzył we wskazaną pozycję lub ciebie +No position specified and unknown player=Nie wskazano pozycji i nieznany gracz diff --git a/mods/ENVIRONMENT/lightning/locale/lightning.zh_TW.tr b/mods/ENVIRONMENT/lightning/locale/lightning.zh_TW.tr new file mode 100644 index 000000000..0667e8dc8 --- /dev/null +++ b/mods/ENVIRONMENT/lightning/locale/lightning.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: lightning +@1 was struck by lightning.=@1 被閃電擊斃。 +Let lightning strike at the specified position or yourself=讓閃電擊中指定位置或自己 +No position specified and unknown player=未指定位置且玩家未知 diff --git a/mods/ENVIRONMENT/lightning/locale/template.txt b/mods/ENVIRONMENT/lightning/locale/template.txt index 2c07393f6..2e7e5878a 100644 --- a/mods/ENVIRONMENT/lightning/locale/template.txt +++ b/mods/ENVIRONMENT/lightning/locale/template.txt @@ -1,4 +1,3 @@ # textdomain: lightning -@1 was struck by lightning.= -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/lightning/mod.conf b/mods/ENVIRONMENT/lightning/mod.conf index 948a40751..346a4a0b9 100644 --- a/mods/ENVIRONMENT/lightning/mod.conf +++ b/mods/ENVIRONMENT/lightning/mod.conf @@ -1 +1,5 @@ name = lightning +author = sofar +description = A mod that adds thunder and lightning effects. +depends = mcl_fire + diff --git a/mods/ENVIRONMENT/lightning/screenshot.png b/mods/ENVIRONMENT/lightning/screenshot.png deleted file mode 100644 index 8d3a047ca..000000000 Binary files a/mods/ENVIRONMENT/lightning/screenshot.png and /dev/null differ diff --git a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_1.png b/mods/ENVIRONMENT/lightning/textures/lightning_lightning_1.png deleted file mode 100644 index 37af59e04..000000000 Binary files a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_1.png and /dev/null differ diff --git a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_2.png b/mods/ENVIRONMENT/lightning/textures/lightning_lightning_2.png deleted file mode 100644 index 7bab36b74..000000000 Binary files a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_2.png and /dev/null differ diff --git a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_3.png b/mods/ENVIRONMENT/lightning/textures/lightning_lightning_3.png deleted file mode 100644 index f090529ec..000000000 Binary files a/mods/ENVIRONMENT/lightning/textures/lightning_lightning_3.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_moon/init.lua b/mods/ENVIRONMENT/mcl_moon/init.lua index 4ee2623a6..200c6ca41 100644 --- a/mods/ENVIRONMENT/mcl_moon/init.lua +++ b/mods/ENVIRONMENT/mcl_moon/init.lua @@ -4,18 +4,16 @@ local SHEET_W = 4 local SHEET_H = 2 -- Randomize initial moon phase, based on map seed -local phase_offset local mg_seed = minetest.get_mapgen_setting("seed") local rand = PseudoRandom(mg_seed) local phase_offset = rand:next(0, MOON_PHASES - 1) -rand = nil minetest.log("info", "[mcl_moon] Moon phase offset of this world: "..phase_offset) mcl_moon = {} mcl_moon.MOON_PHASES = MOON_PHASES -mcl_moon.get_moon_phase = function() +function mcl_moon.get_moon_phase() local after_midday = 0 -- Moon phase changes after midday local tod = minetest.get_timeofday() @@ -25,7 +23,7 @@ mcl_moon.get_moon_phase = function() return (minetest.get_day_count() + phase_offset + after_midday) % MOON_PHASES end -local get_moon_texture = function() +local function get_moon_texture() local phase = mcl_moon.get_moon_phase() local x = phase % MOON_PHASES_HALF local y diff --git a/mods/ENVIRONMENT/mcl_moon/mod.conf b/mods/ENVIRONMENT/mcl_moon/mod.conf index 9ff8c04ba..92541d72c 100644 --- a/mods/ENVIRONMENT/mcl_moon/mod.conf +++ b/mods/ENVIRONMENT/mcl_moon/mod.conf @@ -1,2 +1,3 @@ name = mcl_moon +author = Wuzzy description = Adds moon phases to the game diff --git a/mods/ENVIRONMENT/mcl_raids/init.lua b/mods/ENVIRONMENT/mcl_raids/init.lua new file mode 100644 index 000000000..8e7c644ae --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/init.lua @@ -0,0 +1,396 @@ +-- mcl_raids +mcl_raids = {} +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Define the amount of illagers to spawn each wave. +local waves = { + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 1, + }, + { + ["mobs_mc:pillager"] = 4, + ["mobs_mc:vindicator"] = 3, + }, + { + ["mobs_mc:pillager"] = 4, + ["mobs_mc:vindicator"] = 1, + ["mobs_mc:witch"] = 1, + --["mobs_mc:ravager"] = 1, + }, + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 2, + ["mobs_mc:witch"] = 3, + }, + { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 5, + ["mobs_mc:witch"] = 1, + ["mobs_mc:evoker"] = 1, + }, +} + +local extra_wave = { + ["mobs_mc:pillager"] = 5, + ["mobs_mc:vindicator"] = 5, + ["mobs_mc:witch"] = 1, + ["mobs_mc:evoker"] = 1, + --["mobs_mc:ravager"] = 2, +} + +local oban_layers = { + { + pattern = "rhombus", + color = "unicolor_cyan" + }, + { + color = "unicolor_grey", + pattern = "stripe_bottom" + }, + { + pattern = "stripe_center", + color = "unicolor_darkgrey" + }, + { + color = "unicolor_black", + pattern = "stripe_middle" + }, + { + pattern = "half_horizontal", + color = "unicolor_grey" + }, + { + color = "unicolor_grey", + pattern = "circle" + }, + { + pattern = "border", + color = "unicolor_black" + } +} + + +local oban_def = table.copy(minetest.registered_entities["mcl_banners:standing_banner"]) +oban_def.visual_size = { x=1, y=1 } +local old_step = oban_def.on_step +oban_def.on_step = function(self,dtime) + if not self.object:get_attach() then return self.object:remove() end + if old_step then return old_step(self.dtime) end +end + +minetest.register_entity(":mcl_raids:ominous_banner",oban_def) + +function mcl_raids.drop_obanner(pos) + local it = ItemStack("mcl_banners:banner_item_white") + it:get_meta():set_string("layers",minetest.serialize(oban_layers)) + it:get_meta():set_string("name",S("Ominous Banner")) + minetest.add_item(pos,it) +end + +function mcl_raids.promote_to_raidcaptain(c) -- object + if not c or not c:get_pos() then return end + local pos = c:get_pos() + local l = c:get_luaentity() + l._banner = minetest.add_entity(pos,"mcl_raids:ominous_banner") + l._banner:set_properties({textures = {mcl_banners.make_banner_texture("unicolor_white", oban_layers)}}) + l._banner:set_attach(c,"",vector.new(-1,5.5,0),vector.new(0,0,0),true) + l._raidcaptain = true + local old_ondie = l.on_die + l.on_die = function(self, pos, cmi_cause) + if l._banner then + l._banner:remove() + l._banner = nil + 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 + lv = math.max(5,lv + 1) + mcl_potions.bad_omen_func(cmi_cause.puncher,lv,6000) + end + end + if old_ondie then return old_ondie(self,pos,cmi_cause) end + end +end + +function mcl_raids.is_raidcaptain_near(pos) + for k,v in pairs(minetest.get_objects_inside_radius(pos,32)) do + local l = v:get_luaentity() + if l and l._raidcaptain then return true end + end +end + +function mcl_raids.register_possible_raidcaptain(mob) + local old_on_spawn = minetest.registered_entities[mob].on_spawn + local old_on_pick_up = minetest.registered_entities[mob].on_pick_up + if not minetest.registered_entities[mob].pick_up then minetest.registered_entities[mob].pick_up = {} end + table.insert(minetest.registered_entities[mob].pick_up,"mcl_banners:banner_item_white") + minetest.registered_entities[mob].on_pick_up = function(self,e) + local stack = ItemStack(e.itemstring) + if not self._raidcaptain and stack:get_meta():get_string("name"):find("Ominous Banner") then + stack:take_item(1) + mcl_raids.promote_to_raidcaptain(self.object) + return stack + end + if old_on_pick_up then return old_on_pick_up(self,e) end + end + minetest.registered_entities[mob].on_spawn = function(self) + if not mcl_raids.is_raidcaptain_near(self.object:get_pos()) then + mcl_raids.promote_to_raidcaptain(self.object) + end + if old_on_spawn then return old_on_spawn(self) end + end +end + +mcl_raids.register_possible_raidcaptain("mobs_mc:pillager") +mcl_raids.register_possible_raidcaptain("mobs_mc:vindicator") +mcl_raids.register_possible_raidcaptain("mobs_mc:evoker") + +function mcl_raids.spawn_raid(event) + local pos = event.pos + local wave = event.stage + local illager_count = 0 + local spawnable = false + local r = 32 + local n = 12 + local i = math.random(1, n) + local raid_pos = vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r * math.sin(((i-1)/n) * (2*math.pi))) + local sn = minetest.find_nodes_in_area_under_air(vector.offset(raid_pos,-5,-50,-5), vector.offset(raid_pos,5,50,5), {"group:grass_block", "group:grass_block_snow", "group:snow_cover", "group:sand", "mcl_core:ice"}) + mcl_bells.ring_once(pos) + if sn and #sn > 0 then + local spawn_pos = sn[math.random(#sn)] + if spawn_pos then + minetest.log("action", "[mcl_raids] Raid Spawn Position chosen at " .. minetest.pos_to_string(spawn_pos) .. ".") + event.health_max = 0 + local w + if event.stage <= #waves then + w= waves[event.stage] + else + w = extra_wave + end + for m,c in pairs(w) do + for i=1,c do + local p = vector.offset(spawn_pos,0,1,0) + local mob = mcl_mobs.spawn(p,m) + local l = mob:get_luaentity() + if l then + l.raidmob = true + event.health_max = event.health_max + l.health + table.insert(event.mobs,mob) + --minetest.log("action", "[mcl_raids] Here we go. Raid time") + l:gopath(pos) + end + end + end + if event.stage == 1 then + table.shuffle(event.mobs) + mcl_raids.promote_to_raidcaptain(event.mobs[1]) + end + minetest.log("action", "[mcl_raids] Raid Spawned. Illager Count: " .. #event.mobs .. ".") + return #event.mobs == 0 + else + minetest.log("action", "[mcl_raids] Raid Spawn Postion not chosen.") + end + elseif not sn then + minetest.log("action", "[mcl_raids] Raid Spawn Position error, no appropriate site found.") + end + return true +end + +function mcl_raids.find_villager(pos) + local obj = minetest.get_objects_inside_radius(pos, 8) + for _, objects in ipairs(obj) do + local object = objects:get_luaentity() + if object then + if object.name ~= "mobs_mc:villager" then + return + elseif object.name == "mobs_mc:villager" then + --minetest.log("action", "[mcl_raids] Villager Found.") + return true + else + --minetest.log("action", "[mcl_raids] No Villager Found.") + return false + end + end + end +end + +function mcl_raids.find_bed(pos) + return minetest.find_node_near(pos,32,{"mcl_beds:bed_red_bottom"}) +end + +function mcl_raids.find_village(pos) + local bed = mcl_raids.find_bed(pos) + if bed and mcl_raids.find_villager(bed) then + return bed + end +end + +local function get_point_on_circle(pos,r,n) + local rt = {} + for i=1, n do + table.insert(rt,vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r* math.sin(((i-1)/n) * (2*math.pi)) )) + end + table.shuffle(rt) + return rt[1] +end + +local function start_firework_rocket(pos) + local p = get_point_on_circle(pos,math.random(32,64),32) + local n = minetest.get_node(p) + local l = mcl_util.get_natural_light(pos,0.5) + if n.name ~= "air" or l <= minetest.LIGHT_MAX then return end + local o = minetest.add_entity(p,"mcl_bows:rocket_entity") + o:get_luaentity()._harmless = true + o:set_acceleration(vector.new(math.random(0,2),math.random(30,50),math.random(0,2))) +end + +local function make_firework(pos,stime) + if os.time() - stime > 60 then return end + for i=1,math.random(25) do + minetest.after(math.random(i),start_firework_rocket,pos) + end + minetest.after(10,make_firework,pos,stime) +end + +local function is_player_near(self) + for _,pl in pairs(minetest.get_connected_players()) do + if self.pos and vector.distance(pl:get_pos(),self.pos) < 64 then return true end + end +end + +local function check_mobs(self) + local m = {} + local h = 0 + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + if #m == 0 then --if no valid mobs in table search if there are any (reloaded ones) in the area + for k,o in pairs(minetest.get_objects_inside_radius(self.pos,64)) do + local l = o:get_luaentity() + if l and l.raidmob then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + end + self.mobs = m + return h +end + +mcl_events.register_event("raid",{ + readable_name = "Raid", + max_stage = 5, + health = 1, + health_max = 1, + exclusive_to_area = 128, + enable_bossbar = true, + cond_start = function(self) + --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 + local raid_pos = mcl_raids.find_village(p:get_pos()) + if raid_pos then + --minetest.log("We have a raid position. Start raid") + table.insert(r,{ player = p:get_player_name(), pos = raid_pos }) + end + end + end + if #r > 0 then return r end + end, + on_start = function(self) + 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 + end, + cond_progress = function(self) + if not is_player_near(self) then return false end + self.health = check_mobs(self) + self.percent = math.max(0,(self.health / self.health_max ) * 100) + if #self.mobs < 1 then + return true end + end, + on_stage_begin = mcl_raids.spawn_raid, + cond_complete = function(self) + if not is_player_near(self) then return false end + --let the event api handle cancel the event when no players are near + --without this check it would sort out the unloaded mob entities and + --think the raid is defeated. + check_mobs(self) + return self.stage >= self.max_stage and #self.mobs < 1 + 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") + make_firework(self.pos,os.time()) + end, +}) + +minetest.register_chatcommand("raidcap",{ + privs = {debug = true}, + func = function(pname,param) + local c = minetest.add_entity(minetest.get_player_by_name(pname):get_pos(),"mobs_mc:pillager") + mcl_raids.promote_to_raidcaptain(c) + end, +}) + +minetest.register_chatcommand("dump_banner_layers",{ + privs = {debug = true}, + func = function(pname,param) + local p = minetest.get_player_by_name(pname) + mcl_raids.drop_obanner(vector.offset(p:get_pos(),1,1,1)) + for k,v in pairs(minetest.get_objects_inside_radius(p:get_pos(),5)) do + local l = v:get_luaentity() + if l and l.name == "mcl_banners:standing_banner" then + minetest.log(dump(l._base_color)) + minetest.log(dump(l._layers)) + end + end + end +}) + +local function is_new_years() + local d = os.date("*t") + return d.month == 1 and d.day == 1 and d.hour < 1 +end + +mcl_events.register_event("new_years",{ + stage = 0, + max_stage = 1, + readable_name = "New Years", + pos = vector.new(0,0,0), + exclusive_to_area = 256, + cond_start = function(event) + if not is_new_years() then return false end + local r = {} + for _,p in pairs(minetest.get_connected_players()) do + table.insert(r,{ player = p:get_player_name(), pos = p:get_pos()}) + end + return r + end, + on_start = function(self) + minetest.chat_send_player(self.player," Happy new year <3") + end, + on_step = function(self,dtime) + if not self.timer or self.timer < 0 then + self.timer = math.random(1,5) + for i=1,math.random(8) do + minetest.after(math.random(i),start_firework_rocket,minetest.get_player_by_name(self.player):get_pos()) + end + end + self.timer = self.timer - dtime + end, + cond_complete = function(event) + return not is_new_years() + end, --return success +}) diff --git a/mods/ENVIRONMENT/mcl_raids/mod.conf b/mods/ENVIRONMENT/mcl_raids/mod.conf new file mode 100644 index 000000000..b4616e56b --- /dev/null +++ b/mods/ENVIRONMENT/mcl_raids/mod.conf @@ -0,0 +1,3 @@ +name = mcl_raids +author = PrairieWind +depends = mcl_events, mobs_mc, mcl_potions, mcl_bells, mcl_achievements diff --git a/mods/ENVIRONMENT/mcl_void_damage/depends.txt b/mods/ENVIRONMENT/mcl_void_damage/depends.txt deleted file mode 100644 index e134aeef6..000000000 --- a/mods/ENVIRONMENT/mcl_void_damage/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_worlds -mcl_death_messages diff --git a/mods/ENVIRONMENT/mcl_void_damage/description.txt b/mods/ENVIRONMENT/mcl_void_damage/description.txt deleted file mode 100644 index ac7e3d8c4..000000000 --- a/mods/ENVIRONMENT/mcl_void_damage/description.txt +++ /dev/null @@ -1 +0,0 @@ -Deal damage to entities stuck in the deep void diff --git a/mods/ENVIRONMENT/mcl_void_damage/init.lua b/mods/ENVIRONMENT/mcl_void_damage/init.lua index 205198a46..084028dd1 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/init.lua +++ b/mods/ENVIRONMENT/mcl_void_damage/init.lua @@ -1,5 +1,12 @@ -local S = minetest.get_translator("mcl_void_damage") -local enable_damage = minetest.settings:get_bool("enable_damage") +local S = minetest.get_translator(minetest.get_current_modname()) +--local enable_damage = minetest.settings:get_bool("enable_damage") + +local pos_to_dim = mcl_worlds.pos_to_dimension +local dim_change = mcl_worlds.dimension_change +local is_in_void = mcl_worlds.is_in_void +local get_spawn_pos = mcl_spawn.get_player_spawn_pos +local send_chat = minetest.chat_send_player +local get_connected = minetest.get_connected_players local voidtimer = 0 local VOID_DAMAGE_FREQ = 0.5 @@ -32,10 +39,9 @@ minetest.register_on_mods_loaded(function() end self._void_timer = 0 - local pos = obj:get_pos() - local void, void_deadly = mcl_worlds.is_in_void(pos) + local _, void_deadly = is_in_void(pos) if void_deadly then - local ent = obj:get_luaentity() + --local ent = obj:get_luaentity() obj:remove() return end @@ -51,11 +57,11 @@ minetest.register_globalstep(function(dtime) if voidtimer > VOID_DAMAGE_FREQ then voidtimer = 0 local enable_damage = minetest.settings:get_bool("enable_damage") - local players = minetest.get_connected_players() + local players = get_connected() for p=1, #players do local player = players[p] local pos = player:get_pos() - local void, void_deadly = mcl_worlds.is_in_void(pos) + local _, void_deadly = is_in_void(pos) if void_deadly then local immortal_val = player:get_armor_groups().immortal local is_immortal = false @@ -65,15 +71,14 @@ minetest.register_globalstep(function(dtime) if is_immortal or not enable_damage then -- If damage is disabled, we can't kill players. -- So we just teleport the player back to spawn. - local spawn = mcl_spawn.get_player_spawn_pos(player) + local spawn = get_spawn_pos(player) player:set_pos(spawn) - mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn)) - minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!")) + dim_change(player, pos_to_dim(spawn)) + send_chat(player:get_player_name(), S("The void is off-limits to you!")) elseif enable_damage and not is_immortal then -- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds) if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 fell into the endless void.", player:get_player_name())) - player:set_hp(player:get_hp() - VOID_DAMAGE) + mcl_util.deal_damage(player, VOID_DAMAGE, {type = "out_of_world"}) end end end diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.dk.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.dk.tr new file mode 100644 index 000000000..d22e61379 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.dk.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=Tomrummet er forbudt område for dig! +@1 fell into the endless void.=@1 faldt ned i det uendelige tomrum. diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr new file mode 100644 index 000000000..f29ff36de --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=奈落は立ち入り禁止! +@1 fell into the endless void.=@1は奈落の底に落ちていった。 diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pl.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pl.tr new file mode 100644 index 000000000..c943d3e67 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.pl.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=Otchłań jest poza twoim zasięgiem! +@1 fell into the endless void.=@1 spadła w bezkresną otchłań. diff --git a/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.zh_TW.tr b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.zh_TW.tr new file mode 100644 index 000000000..515e83fcc --- /dev/null +++ b/mods/ENVIRONMENT/mcl_void_damage/locale/mcl_void_damage.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_void_damage +The void is off-limits to you!=你不可以進入虛空! +@1 fell into the endless void.=@1 掉到世界外面了。 diff --git a/mods/ENVIRONMENT/mcl_void_damage/mod.conf b/mods/ENVIRONMENT/mcl_void_damage/mod.conf index 7e0ea4bac..1358e5217 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/mod.conf +++ b/mods/ENVIRONMENT/mcl_void_damage/mod.conf @@ -1 +1,4 @@ name = mcl_void_damage +author = Wuzzy +description = Deal damage to entities stuck in the deep void +depends = mcl_worlds diff --git a/mods/ENVIRONMENT/mcl_weather/depends.txt b/mods/ENVIRONMENT/mcl_weather/depends.txt deleted file mode 100644 index 0e5110c41..000000000 --- a/mods/ENVIRONMENT/mcl_weather/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_worlds -lightning? diff --git a/mods/ENVIRONMENT/mcl_weather/description.txt b/mods/ENVIRONMENT/mcl_weather/description.txt deleted file mode 100644 index 3f28b271e..000000000 --- a/mods/ENVIRONMENT/mcl_weather/description.txt +++ /dev/null @@ -1 +0,0 @@ -Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience diff --git a/mods/ENVIRONMENT/mcl_weather/init.lua b/mods/ENVIRONMENT/mcl_weather/init.lua index e4ebfb2dc..e13242996 100644 --- a/mods/ENVIRONMENT/mcl_weather/init.lua +++ b/mods/ENVIRONMENT/mcl_weather/init.lua @@ -1,4 +1,4 @@ -local modpath = minetest.get_modpath("mcl_weather") +local modpath = minetest.get_modpath(minetest.get_current_modname()) mcl_weather = {} @@ -12,6 +12,6 @@ dofile(modpath.."/snow.lua") dofile(modpath.."/rain.lua") dofile(modpath.."/nether_dust.lua") -if minetest.get_modpath("lightning") ~= nil then +if minetest.get_modpath("lightning") then dofile(modpath.."/thunder.lua") end diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.dk.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.dk.tr new file mode 100644 index 000000000..9aff5d717 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.dk.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=Gør en i stand til at styre vejret +Changes the weather to the specified parameter.=Ændrer vejret til det angivne. +Error: No weather specified.=Fejl: Intet vejr angivet. +Error: Invalid parameters.=Fejl: Ugyldige parametre. +Error: Duration can't be less than 1 second.=Fejl: Vargihed kan ikke være under 1 sekund. +Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Fejl: Ugyldigt vejr angivet. Brug "clear","rain","snow" eller "thunder". +Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Skifter mellem klart vejr og vejr med nedbør (tilfældigt enten regn, tordenstorm eller sne) diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr new file mode 100644 index 000000000..c4d666aa5 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=天候操作能力を付与 +Changes the weather to the specified parameter.=指定されたパラメータの天気を変更します。 +Error: No weather specified.=エラー:天候が指定されていません。 +Error: Invalid parameters.=エラー:パラメータが無効です。 +Error: Duration can't be less than 1 second.=エラー:持続時間は1秒以下にはできません。 +Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=エラー:指定した天候が無効です。「晴天」、「降雨」、「降雪」、「雷雨」のいずれかを使用してください。 +Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=晴天と荒天(ランダムに降雨・雷雨・降雪)を切替 diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pl.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pl.tr new file mode 100644 index 000000000..fc4c72a31 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=Daje możliwość kontrolowania pogody +Changes the weather to the specified parameter.=Zmienia pogodę na wskazany parametr +Error: No weather specified.=Błąd: nie wskazano pogody. +Error: Invalid parameters.=Błąd: nieprawidłowy parametr. +Error: Duration can't be less than 1 second.=Błąd: Czas trwania nie może być mniejszy niż 1 sekunda. +Error: Invalid weather specified. Use “clear”, “rain”, “snow” or “thunder”.=Błąd: wskazano nieprawidłową pogodę. Użyj "clear", "rain", "snow" lub "thunder". +Toggles between clear weather and weather with downfall (randomly rain, thunderstorm or snow)=Zmienia pomiędzy czystą pogodą i pogodą z opadami (losowo deszcz, burza lub śnieg) diff --git a/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.zh_TW.tr b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.zh_TW.tr new file mode 100644 index 000000000..42be7481b --- /dev/null +++ b/mods/ENVIRONMENT/mcl_weather/locale/mcl_weather.zh_TW.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_weather +Gives ability to control weather=賦予控制天氣的能力 +Changes the weather to the specified parameter.=將天氣改為指定的參數。 +Error: No weather specified.=錯誤:未指定天氣。 +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/mod.conf b/mods/ENVIRONMENT/mcl_weather/mod.conf index 4cc16984e..4f1102b7a 100644 --- a/mods/ENVIRONMENT/mcl_weather/mod.conf +++ b/mods/ENVIRONMENT/mcl_weather/mod.conf @@ -1 +1,5 @@ name = mcl_weather +author = xeranas +description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience +depends = mcl_init, mcl_worlds +optional_depends = lightning diff --git a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua index 735676454..023c8b20d 100644 --- a/mods/ENVIRONMENT/mcl_weather/nether_dust.lua +++ b/mods/ENVIRONMENT/mcl_weather/nether_dust.lua @@ -1,36 +1,68 @@ mcl_weather.nether_dust = {} -mcl_weather.nether_dust.particles_count = 99 +mcl_weather.nether_dust.particlespawners = {} --- calculates coordinates and draw particles for Nether dust -mcl_weather.nether_dust.add_dust_particles = function(player) - for i=mcl_weather.nether_dust.particles_count, 1,-1 do - local rpx, rpy, rpz = mcl_weather.get_random_pos_by_player_look_dir(player) - minetest.add_particle({ - pos = {x = rpx, y = rpy - math.random(6, 18), z = rpz}, - velocity = {x = math.random(-30,30)*0.01, y = math.random(-15,15)*0.01, z = math.random(-30,30)*0.01}, - acceleration = {x = math.random(-50,50)*0.02, y = math.random(-20,20)*0.02, z = math.random(-50,50)*0.02}, - expirationtime = 3, - size = math.random(6,20)*0.01, - collisiondetection = false, - object_collision = false, - vertical = false, - glow = math.random(0,minetest.LIGHT_MAX), - texture = "mcl_particles_nether_dust"..tostring(i%3+1)..".png", - playername = player:get_player_name() - }) +local PARTICLES_COUNT_NETHER_DUST = tonumber(minetest.settings:get("mcl_weather_dust_particles")) or 150 + +local psdef= { + amount = PARTICLES_COUNT_NETHER_DUST, + time = 0, + minpos = vector.new(-15,-15,-15), + maxpos =vector.new(15,15,15), + minvel = vector.new(-0.3,-0.15,-1), + maxvel = vector.new(0.3,0.15,0.3), + minacc = vector.new(-1,-0.4,-1), + maxacc = vector.new(1,0.4,1), + minexptime = 1, + maxexptime = 10, + minsize = 0.2, + maxsize = 0.7, + collisiondetection = false, + collision_removal = false, + object_collision = false, + vertical = false +} + +local function check_player(player) + local name=player:get_player_name() + if mcl_worlds.has_dust(player:get_pos()) and not mcl_weather.nether_dust.particlespawners[name] then + return true end end -local timer = 0 -minetest.register_globalstep(function(dtime) - timer = timer + dtime - if timer < 0.7 then return end - timer = 0 +mcl_weather.nether_dust.add_particlespawners = function(player) + local name=player:get_player_name() + mcl_weather.nether_dust.particlespawners[name]={} + psdef.playername = name + psdef.attached = player + psdef.glow = math.random(0,minetest.LIGHT_MAX) + for i=1,3 do + psdef.texture="mcl_particles_nether_dust"..i..".png" + mcl_weather.nether_dust.particlespawners[name][i]=minetest.add_particlespawner(psdef) + end +end - for _, player in ipairs(minetest.get_connected_players()) do - if not mcl_worlds.has_dust(player:get_pos()) then - return false +mcl_weather.nether_dust.delete_particlespawners = function(player) + local name=player:get_player_name() + if mcl_weather.nether_dust.particlespawners[name] then + for i=1,3 do + minetest.delete_particlespawner(mcl_weather.nether_dust.particlespawners[name][i]) end - mcl_weather.nether_dust.add_dust_particles(player) + mcl_weather.nether_dust.particlespawners[name]=nil + end +end + +mcl_worlds.register_on_dimension_change(function(player, dimension) + if check_player(player) then + return mcl_weather.nether_dust.add_particlespawners(player) + end + mcl_weather.nether_dust.delete_particlespawners(player) +end) + +minetest.register_on_joinplayer(function(player) + if check_player(player) then + mcl_weather.nether_dust.add_particlespawners(player) end end) +minetest.register_on_leaveplayer(function(player) + mcl_weather.nether_dust.delete_particlespawners(player) +end) diff --git a/mods/ENVIRONMENT/mcl_weather/rain.lua b/mods/ENVIRONMENT/mcl_weather/rain.lua index 9b4210060..00dc2f6eb 100644 --- a/mods/ENVIRONMENT/mcl_weather/rain.lua +++ b/mods/ENVIRONMENT/mcl_weather/rain.lua @@ -1,5 +1,8 @@ -local PARTICLES_COUNT_RAIN = 30 -local PARTICLES_COUNT_THUNDER = 45 +local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_particles")) or 500 +local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900 + +local get_connected_players = minetest.get_connected_players +local mgname = minetest.get_mapgen_setting("mg_name") mcl_weather.rain = { -- max rain particles created at time @@ -17,8 +20,37 @@ mcl_weather.rain = { init_done = false, } +local update_sound={} -mcl_weather.rain.sound_handler = function(player) +local psdef= { + amount = mcl_weather.rain.particles_count, + time=0, + minpos = vector.new(-15,20,-15), + maxpos = vector.new(15,25,15), + minvel = vector.new(0,-20,0), + maxvel = vector.new(0,-15,0), + minacc = vector.new(0,-0.8,0), + maxacc = vector.new(0,-0.8,0), + minexptime = 1, + maxexptime = 4, + minsize = 4, + maxsize= 8, + collisiondetection = true, + collision_removal = true, + vertical = true, +} + +local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png"} + +function mcl_weather.has_rain(pos) + if not mcl_worlds.has_weather(pos) then return false end + if mgname == "singlenode" or mgname == "v6" then return true end + local bd = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)] + if bd and bd._mcl_biome_type == "hot" then return false end + return true +end + +function mcl_weather.rain.sound_handler(player) return minetest.sound_play("weather_rain", { to_player = player:get_player_name(), loop = true, @@ -26,7 +58,7 @@ mcl_weather.rain.sound_handler = function(player) end -- set skybox based on time (uses skycolor api) -mcl_weather.rain.set_sky_box = function() +function mcl_weather.rain.set_sky_box() if mcl_weather.state == "rain" then mcl_weather.skycolor.add_layer( "weather-pack-rain-sky", @@ -36,95 +68,59 @@ mcl_weather.rain.set_sky_box = function() {r=85, g=86, b=98}, {r=0, g=0, b=0}}) mcl_weather.skycolor.active = true - for _, player in pairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do player:set_clouds({color="#5D5D5FE8"}) end end end --- creating manually parctiles instead of particles spawner because of easier to control --- spawn position. -mcl_weather.rain.add_rain_particles = function(player) - - mcl_weather.rain.last_rp_count = 0 - for i=mcl_weather.rain.particles_count, 1,-1 do - local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) - if mcl_weather.is_outdoor({x=random_pos_x, y=random_pos_y, z=random_pos_z}) then - mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1 - minetest.add_particle({ - pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z}, - velocity = {x=0, y=-10, z=0}, - acceleration = {x=0, y=-30, z=0}, - expirationtime = 1.0, - size = math.random(0.5, 3), - collisiondetection = true, - collision_removal = true, - vertical = true, - texture = mcl_weather.rain.get_texture(), - playername = player:get_player_name() - }) - end +-- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net. +function mcl_weather.rain.add_rain_particles(player) + mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count + local l = false + for k,v in pairs(textures) do + psdef.texture=v + l = l or mcl_weather.add_spawner_player(player,"rain"..k,psdef) end -end - --- Simple random texture getter -mcl_weather.rain.get_texture = function() - local texture_name - local random_number = math.random() - if random_number > 0.33 then - texture_name = "weather_pack_rain_raindrop_1.png" - elseif random_number > 0.66 then - texture_name = "weather_pack_rain_raindrop_2.png" - else - texture_name = "weather_pack_rain_raindrop_3.png" + if l then + update_sound[player:get_player_name()]=true end - return texture_name; end -- register player for rain weather. -- basically needs for origin sky reference and rain sound controls. -mcl_weather.rain.add_player = function(player) +function mcl_weather.rain.add_player(player) if mcl_weather.players[player:get_player_name()] == nil then local player_meta = {} - player_meta.origin_sky = {player:get_sky()} + player_meta.origin_sky = {player:get_sky(true)} mcl_weather.players[player:get_player_name()] = player_meta + update_sound[player:get_player_name()]=true end end -- remove player from player list effected by rain. -- be sure to remove sound before removing player otherwise soundhandler reference will be lost. -mcl_weather.rain.remove_player = function(player) +function mcl_weather.rain.remove_player(player) local player_meta = mcl_weather.players[player:get_player_name()] - if player_meta ~= nil and player_meta.origin_sky ~= nil then + if player_meta and player_meta.origin_sky then player:set_clouds({color="#FFF0F0E5"}) mcl_weather.players[player:get_player_name()] = nil + update_sound[player:get_player_name()]=true end end -mcl_worlds.register_on_dimension_change(function(player, dimension) - if dimension ~= "overworld" and dimension ~= "void" then - mcl_weather.rain.remove_sound(player) - mcl_weather.rain.remove_player(player) - elseif dimension == "overworld" then - mcl_weather.rain.update_sound(player) - if mcl_weather.rain.raining then - mcl_weather.rain.add_rain_particles(player) - mcl_weather.rain.add_player(player) - end - end -end) - -- adds and removes rain sound depending how much rain particles around player currently exist. -- have few seconds delay before each check to avoid on/off sound too often -- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance. -mcl_weather.rain.update_sound = function(player) +function mcl_weather.rain.update_sound(player) + if not update_sound[player:get_player_name()] then return end local player_meta = mcl_weather.players[player:get_player_name()] - if player_meta ~= nil then - if player_meta.sound_updated ~= nil and player_meta.sound_updated + 5 > minetest.get_gametime() then + if player_meta then + if player_meta.sound_updated and player_meta.sound_updated + 5 > minetest.get_gametime() then return false end - if player_meta.sound_handler ~= nil then + if player_meta.sound_handler then if mcl_weather.rain.last_rp_count == 0 then minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0) player_meta.sound_handler = nil @@ -135,12 +131,13 @@ mcl_weather.rain.update_sound = function(player) player_meta.sound_updated = minetest.get_gametime() end + update_sound[player:get_player_name()]=false end -- rain sound removed from player. -mcl_weather.rain.remove_sound = function(player) +function mcl_weather.rain.remove_sound(player) local player_meta = mcl_weather.players[player:get_player_name()] - if player_meta ~= nil and player_meta.sound_handler ~= nil then + if player_meta and player_meta.sound_handler then minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0) player_meta.sound_handler = nil player_meta.sound_updated = nil @@ -148,15 +145,16 @@ mcl_weather.rain.remove_sound = function(player) end -- callback function for removing rain -mcl_weather.rain.clear = function() +function mcl_weather.rain.clear() mcl_weather.rain.raining = false mcl_weather.rain.sky_last_update = -1 mcl_weather.rain.init_done = false mcl_weather.rain.set_particles_mode("rain") mcl_weather.skycolor.remove_layer("weather-pack-rain-sky") - for _, player in ipairs(minetest.get_connected_players()) do + for _, player in pairs(get_connected_players()) do mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_player(player) + mcl_weather.remove_spawners_player(player) end end @@ -164,11 +162,10 @@ minetest.register_globalstep(function(dtime) if mcl_weather.state ~= "rain" then return false end - mcl_weather.rain.make_weather() end) -mcl_weather.rain.make_weather = function() +function mcl_weather.rain.make_weather() if mcl_weather.rain.init_done == false then mcl_weather.rain.raining = true mcl_weather.rain.set_sky_box() @@ -176,22 +173,36 @@ mcl_weather.rain.make_weather = function() mcl_weather.rain.init_done = true end - for _, player in ipairs(minetest.get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then + for _, player in pairs(get_connected_players()) do + local pos=player:get_pos() + if mcl_weather.is_underwater(player) or not mcl_weather.has_rain(pos) then mcl_weather.rain.remove_sound(player) - return false + mcl_weather.remove_spawners_player(player) + if mcl_worlds.has_weather(pos) then + mcl_weather.set_sky_box_clear(player) + end + else + if mcl_weather.has_snow(pos) then + mcl_weather.rain.remove_sound(player) + mcl_weather.snow.add_player(player) + mcl_weather.snow.set_sky_box() + else + mcl_weather.rain.add_player(player) + mcl_weather.rain.add_rain_particles(player) + mcl_weather.rain.update_sound(player) + mcl_weather.rain.set_sky_box() + end end - mcl_weather.rain.add_player(player) - mcl_weather.rain.add_rain_particles(player) - mcl_weather.rain.update_sound(player) end end -- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops -mcl_weather.rain.set_particles_mode = function(mode) +function mcl_weather.rain.set_particles_mode(mode) if mode == "thunder" then + psdef.amount=PARTICLES_COUNT_THUNDER mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER else + psdef.amount=PARTICLES_COUNT_RAIN mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN end end @@ -215,7 +226,7 @@ if mcl_weather.allow_abm then } for a=1, #around do local apos = vector.add(pos, around[a]) - if mcl_weather.is_outdoor(apos) then + if mcl_weather.is_outdoor(apos) and mcl_weather.has_rain(apos) then minetest.remove_node(pos) minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 8, gain = 0.1}, true) return @@ -233,7 +244,7 @@ if mcl_weather.allow_abm then chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) -- Rain is equivalent to a water bottle - if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then + if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) and mcl_weather.has_rain(pos) then if node.name == "mcl_cauldrons:cauldron" then minetest.set_node(pos, {name="mcl_cauldrons:cauldron_1"}) elseif node.name == "mcl_cauldrons:cauldron_1" then @@ -247,7 +258,7 @@ if mcl_weather.allow_abm then end end end - }) + }) -- Wetten the soil minetest.register_abm({ @@ -256,13 +267,13 @@ if mcl_weather.allow_abm then interval = 22.0, chance = 3, action = function(pos, node, active_object_count, active_object_count_wider) - if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then + if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) and mcl_weather.has_rain(pos) then if node.name == "mcl_farming:soil" then minetest.set_node(pos, {name="mcl_farming:soil_wet"}) end end end - }) + }) end if mcl_weather.reg_weathers.rain == nil then diff --git a/mods/ENVIRONMENT/mcl_weather/screenshot.png b/mods/ENVIRONMENT/mcl_weather/screenshot.png deleted file mode 100644 index 1ee3ea059..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/screenshot.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/skycolor.lua b/mods/ENVIRONMENT/mcl_weather/skycolor.lua index 6cc94b5c1..aea469760 100644 --- a/mods/ENVIRONMENT/mcl_weather/skycolor.lua +++ b/mods/ENVIRONMENT/mcl_weather/skycolor.lua @@ -1,6 +1,70 @@ local mods_loaded = false local NIGHT_VISION_RATIO = 0.45 +local MINIMUM_LIGHT_LEVEL = 0.2 + +local water_color = "#3F76E4" + +local mg_name = minetest.get_mapgen_setting("mg_name") + +function mcl_weather.set_sky_box_clear(player, sky, fog) + local pos = player:get_pos() + if minetest.get_item_group(minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name, "water") ~= 0 then return end + local sc = { + day_sky = "#7BA4FF", + day_horizon = "#C0D8FF", + dawn_sky = "#7BA4FF", + dawn_horizon = "#C0D8FF", + night_sky = "#000000", + night_horizon = "#4A6790", + indoors = "#C0D8FF", + fog_sun_tint = "#ff5f33", + fog_moon_tint = nil, + fog_tint_type = "custom" + } + if sky then + sc.day_sky = sky + sc.dawn_sky = sky + end + if fog then + sc.day_horizon = fog + sc.dawn_horizon = fog + end + player:set_sky({ + type = "regular", + sky_color = sc, + clouds = true, + }) +end + +function mcl_weather.set_sky_color(player, def) + local pos = player:get_pos() + if minetest.get_item_group(minetest.get_node(vector.offset(pos, 0, 1.5, 0)).name, "water") ~= 0 then return end + player:set_sky({ + type = def.type, + sky_color = def.sky_color, + clouds = def.clouds, + }) +end + +-- Function to work out light modifier at different times +-- Noon is brightest, midnight is darkest, 0600 and 18000 is in the middle of this +local function get_light_modifier(time) + -- 0.1 = 0.2 + -- 0.4 = 0.8 + -- 0.5 = 1 + -- 0.6 = 0.8 + -- 0.9 = 0.2 + + local light_multiplier = time * 2 + if time > 0.5 then + light_multiplier = 2 * (1 - time) + else + light_multiplier = time / 0.5 + end + return light_multiplier +end + mcl_weather.skycolor = { -- Should be activated before do any effect. active = true, @@ -9,9 +73,9 @@ mcl_weather.skycolor = { force_update = true, -- Update interval. - update_interval = 15, + update_interval = 3, - -- Main sky colors: starts from midnight to midnight. + -- Main sky colors: starts from midnight to midnight. -- Please do not set directly. Use add_layer instead. colors = {}, @@ -43,7 +107,7 @@ mcl_weather.skycolor = { -- Remove layer from colors table remove_layer = function(layer_name) - for k, name in ipairs(mcl_weather.skycolor.layer_names) do + for k, name in pairs(mcl_weather.skycolor.layer_names) do if name == layer_name then table.remove(mcl_weather.skycolor.layer_names, k) mcl_weather.skycolor.force_update = true @@ -80,31 +144,79 @@ mcl_weather.skycolor = { for _, player in ipairs(players) do local pos = player:get_pos() local dim = mcl_worlds.pos_to_dimension(pos) + local has_weather = (mcl_worlds.has_weather(pos) and (mcl_weather.state == "snow" or mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_snow(pos)) or ((mcl_weather.state =="rain" or mcl_weather.state == "thunder") and mcl_weather.has_rain(pos)) + local checkname = minetest.get_node(vector.new(pos.x,pos.y+1.5,pos.z)).name + if minetest.get_item_group(checkname, "water") ~= 0 then + local biome_index = minetest.get_biome_data(player:get_pos()).biome + local biome_name = minetest.get_biome_name(biome_index) + local biome = minetest.registered_biomes[biome_name] + if biome then water_color = biome._mcl_waterfogcolor end + if not biome then water_color = "#3F76E4" end + if checkname == "mclx_core:river_water_source" or checkname == "mclx_core:river_water_flowing" then water_color = "#0084FF" end + player:set_sky({ type = "regular", + sky_color = { + day_sky = water_color, + day_horizon = water_color, + dawn_sky = water_color, + dawn_horizon = water_color, + night_sky = water_color, + night_horizon = water_color, + indoors = water_color, + fog_sun_tint = water_color, + fog_moon_tint = water_color, + fog_tint_type = "custom" + }, + clouds = false, + }) + end if dim == "overworld" then + local biomesky + local biomefog + if mg_name ~= "v6" and mg_name ~= "singlenode" then + local biome_index = minetest.get_biome_data(player:get_pos()).biome + local biome_name = minetest.get_biome_name(biome_index) + local biome = minetest.registered_biomes[biome_name] + if biome then + --minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name)) + biomesky = biome._mcl_skycolor + biomefog = biome._mcl_fogcolor + else + --minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name)) + end + end if (mcl_weather.state == "none") then -- Clear weather - player:set_sky({ - type = "regular", - sky_color = { - day_sky = "#92B9FF", - day_horizon = "#B4D0FF", - dawn_sky = "#B4BAFA", - dawn_horizon = "#BAC1F0", - night_sky = "#006AFF", - night_horizon = "#4090FF", - }, - clouds = true, - }) + mcl_weather.set_sky_box_clear(player,biomesky,biomefog) player:set_sun({visible = true, sunrise_visible = true}) player:set_moon({visible = true}) player:set_stars({visible = true}) mcl_weather.skycolor.override_day_night_ratio(player, nil) - else + elseif not has_weather then + local day_color = mcl_weather.skycolor.get_sky_layer_color(0.15) + local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.27) + local night_color = mcl_weather.skycolor.get_sky_layer_color(0.1) + mcl_weather.set_sky_color(player, { + type = "regular", + sky_color = { + day_sky = day_color, + day_horizon = day_color, + dawn_sky = dawn_color, + dawn_horizon = dawn_color, + night_sky = night_color, + night_horizon = night_color, + }, + clouds = true, + }) + player:set_sun({visible = false, sunrise_visible = false}) + player:set_moon({visible = false}) + player:set_stars({visible = false}) + elseif has_weather then -- Weather skies local day_color = mcl_weather.skycolor.get_sky_layer_color(0.5) local dawn_color = mcl_weather.skycolor.get_sky_layer_color(0.75) local night_color = mcl_weather.skycolor.get_sky_layer_color(0) - player:set_sky({ type = "regular", + mcl_weather.set_sky_color(player, { + type = "regular", sky_color = { day_sky = day_color, day_horizon = day_color, @@ -119,25 +231,36 @@ mcl_weather.skycolor = { player:set_moon({visible = false}) player:set_stars({visible = false}) - local lf = mcl_weather.get_current_light_factor() + local light_factor = mcl_weather.get_current_light_factor() if mcl_weather.skycolor.current_layer_name() == "lightning" then mcl_weather.skycolor.override_day_night_ratio(player, 1) - elseif lf then - local w = minetest.get_timeofday() - local light = (w * (lf*2)) - if light > 1 then - light = 1 - (light - 1) - end - light = (light * lf) + 0.15 - mcl_weather.skycolor.override_day_night_ratio(player, light) + elseif light_factor then + local time = minetest.get_timeofday() + local light_multiplier = get_light_modifier(time) + local new_light = math.max(light_factor * light_multiplier, MINIMUM_LIGHT_LEVEL) + mcl_weather.skycolor.override_day_night_ratio(player, new_light) else mcl_weather.skycolor.override_day_night_ratio(player, nil) end end elseif dim == "end" then + local biomesky = "#000000" + local biomefog = "#A080A0" + if mg_name ~= "v6" and mg_name ~= "singlenode" then + local biome_index = minetest.get_biome_data(player:get_pos()).biome + local biome_name = minetest.get_biome_name(biome_index) + local biome = minetest.registered_biomes[biome_name] + if biome then + --minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name)) + biomesky = biome._mcl_skycolor + biomefog = biome._mcl_fogcolor -- The End biomes seemingly don't use the fog colour, despite having this value according to the wiki. The sky colour is seemingly used for both sky and fog? + else + --minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name)) + end + end local t = "mcl_playerplus_end_sky.png" player:set_sky({ type = "skybox", - base_color = "#000000", + base_color = biomesky, textures = {t,t,t,t,t,t}, clouds = false, }) @@ -146,8 +269,34 @@ mcl_weather.skycolor = { player:set_stars({visible = false}) mcl_weather.skycolor.override_day_night_ratio(player, 0.5) elseif dim == "nether" then - player:set_sky({ type = "plain", - base_color = "#300808", + local biomesky = "#6EB1FF" + local biomefog = "#330808" + if mg_name ~= "v6" and mg_name ~= "singlenode" then + local biome_index = minetest.get_biome_data(player:get_pos()).biome + local biome_name = minetest.get_biome_name(biome_index) + local biome = minetest.registered_biomes[biome_name] + if biome then + --minetest.log("action", string.format("Biome found for number: %s in biome: %s", tostring(biome_index), biome_name)) + biomesky = biome._mcl_skycolor -- The Nether biomes seemingly don't use the sky colour, despite having this value according to the wiki. The fog colour is used for both sky and fog. + biomefog = biome._mcl_fogcolor + else + --minetest.log("action", string.format("No biome for number: %s in biome: %s", tostring(biome_index), biome_name)) + end + end + mcl_weather.set_sky_color(player, { + type = "regular", + sky_color = { + day_sky = biomefog, + day_horizon = biomefog, + dawn_sky = biomefog, + dawn_horizon = biomefog, + night_sky = biomefog, + night_horizon = biomefog, + indoors = biomefog, + fog_sun_tint = biomefog, + fog_moon_tint = biomefog, + fog_tint_type = "custom" + }, clouds = false, }) player:set_sun({visible = false , sunrise_visible = false}) @@ -205,8 +354,8 @@ mcl_weather.skycolor = { -- Returns first player sky color. I assume that all players are in same color layout. get_current_bg_color = function() local players = mcl_weather.skycolor.utils.get_players(nil) - for _, player in ipairs(players) do - return player:get_sky() + if players[1] then + return players[1]:get_sky(true).sky_color end return nil end @@ -235,13 +384,17 @@ minetest.register_globalstep(function(dtime) end) -local initsky = function(player) +local function initsky(player) + + if player.set_lighting then + player:set_lighting({ shadows = { intensity = tonumber(minetest.settings:get("mcl_default_shadow_intensity") or 0.33) } }) + end + if (mcl_weather.skycolor.active) then mcl_weather.skycolor.force_update = true end - -- MC-style clouds: Layer 127, thickness 4, fly to the “West” - player:set_clouds({height=mcl_worlds.layer_to_y(127), speed={x=-2, z=0}, thickness=4, color="#FFF0FEF"}) + player:set_clouds(mcl_worlds:get_cloud_parameters() or {height=mcl_worlds.layer_to_y(127), speed={x=-2, z=0}, thickness=4, color="#FFF0FEF"}) end minetest.register_on_joinplayer(initsky) diff --git a/mods/ENVIRONMENT/mcl_weather/snow.lua b/mods/ENVIRONMENT/mcl_weather/snow.lua index 986d38d43..9ff2605df 100644 --- a/mods/ENVIRONMENT/mcl_weather/snow.lua +++ b/mods/ENVIRONMENT/mcl_weather/snow.lua @@ -1,84 +1,107 @@ +local get_connected_players = minetest.get_connected_players + mcl_weather.snow = {} -mcl_weather.snow.particles_count = 15 +local PARTICLES_COUNT_SNOW = tonumber(minetest.settings:get("mcl_weather_snow_particles")) or 100 mcl_weather.snow.init_done = false +local mgname = minetest.get_mapgen_setting("mg_name") --- calculates coordinates and draw particles for snow weather -mcl_weather.snow.add_snow_particles = function(player) - mcl_weather.rain.last_rp_count = 0 - for i=mcl_weather.snow.particles_count, 1,-1 do - local random_pos_x, random_pos_y, random_pos_z = mcl_weather.get_random_pos_by_player_look_dir(player) - random_pos_y = math.random() + math.random(player:get_pos().y - 1, player:get_pos().y + 7) - if minetest.get_node_light({x=random_pos_x, y=random_pos_y, z=random_pos_z}, 0.5) == 15 then - mcl_weather.rain.last_rp_count = mcl_weather.rain.last_rp_count + 1 - minetest.add_particle({ - pos = {x=random_pos_x, y=random_pos_y, z=random_pos_z}, - velocity = {x = math.random(-100,100)*0.001, y = math.random(-300,-100)*0.004, z = math.random(-100,100)*0.001}, - acceleration = {x = 0, y=0, z = 0}, - expirationtime = 8.0, - size = 1, - collisiondetection = true, - collision_removal = true, - object_collision = false, - vertical = false, - texture = mcl_weather.snow.get_texture(), - playername = player:get_player_name() - }) - end - end +local snow_biomes = { + "ColdTaiga_underground", + "IcePlains_underground", + "IcePlainsSpikes_underground", + "MegaTaiga_underground", + "Taiga_underground", + "IcePlains_deep_ocean", + "MegaSpruceTaiga_deep_ocean", + "IcePlainsSpikes_ocean", + "StoneBeach_ocean", + "ColdTaiga_deep_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "MegaTaiga_deep_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "IcePlains_ocean", + "Taiga_ocean", + "Taiga_deep_ocean", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "ColdTaiga_beach", + "Taiga", + "ExtremeHills+_snowtop", + "MegaSpruceTaiga", + "MegaTaiga", + "ExtremeHills+", + "ColdTaiga", + "IcePlainsSpikes", + "IcePlains", +} + +local psdef= { + amount = PARTICLES_COUNT_SNOW, + time = 0, --stay on til we turn it off + minpos = vector.new(-25,20,-25), + maxpos =vector.new(25,25,25), + minvel = vector.new(-0.2,-1,-0.2), + maxvel = vector.new(0.2,-4,0.2), + minacc = vector.new(0,-1,0), + maxacc = vector.new(0,-4,0), + minexptime = 3, + maxexptime = 5, + minsize = 2, + maxsize = 5, + collisiondetection = true, + collision_removal = true, + object_collision = true, + vertical = true, + glow = 1 +} + +function mcl_weather.has_snow(pos) + if not mcl_worlds.has_weather(pos) then return false end + if mgname == "singlenode" or mgname == "v6" then return false end + local bn = minetest.get_biome_name(minetest.get_biome_data(pos).biome) + local bd = minetest.registered_biomes[bn] + if bd and bd._mcl_biome_type == "snowy" then return true end + if bd and bd._mcl_biome_type == "cold" then + if bn == "Taiga" and pos.y > 140 then return true end + if bn == "MegaSpruceTaiga" and pos.y > 100 then return true end + end + return false end -mcl_weather.snow.set_sky_box = function() - mcl_weather.skycolor.add_layer( - "weather-pack-snow-sky", - {{r=0, g=0, b=0}, - {r=85, g=86, b=86}, - {r=135, g=135, b=135}, - {r=85, g=86, b=86}, - {r=0, g=0, b=0}}) - mcl_weather.skycolor.active = true - for _, player in pairs(minetest.get_connected_players()) do - player:set_clouds({color="#ADADADE8"}) - end - mcl_weather.skycolor.active = true +function mcl_weather.snow.set_sky_box() + mcl_weather.skycolor.add_layer( + "weather-pack-snow-sky", + {{r=0, g=0, b=0}, + {r=85, g=86, b=86}, + {r=135, g=135, b=135}, + {r=85, g=86, b=86}, + {r=0, g=0, b=0}}) + mcl_weather.skycolor.active = true + for _, player in pairs(get_connected_players()) do + player:set_clouds({color="#ADADADE8"}) + end + mcl_weather.skycolor.active = true end -mcl_weather.snow.clear = function() - mcl_weather.skycolor.remove_layer("weather-pack-snow-sky") - mcl_weather.snow.init_done = false +function mcl_weather.snow.clear() + mcl_weather.skycolor.remove_layer("weather-pack-snow-sky") + mcl_weather.snow.init_done = false + mcl_weather.remove_all_spawners() end --- Simple random texture getter -mcl_weather.snow.get_texture = function() - return "weather_pack_snow_snowflake"..math.random(1,2)..".png" +function mcl_weather.snow.add_player(player) + for i=1,2 do + psdef.texture="weather_pack_snow_snowflake"..i..".png" + mcl_weather.add_spawner_player(player,"snow"..i,psdef) + end end -local timer = 0 -minetest.register_globalstep(function(dtime) - if mcl_weather.state ~= "snow" then - return false - end - - timer = timer + dtime; - if timer >= 0.5 then - timer = 0 - else - return - end - - if mcl_weather.snow.init_done == false then - mcl_weather.snow.set_sky_box() - mcl_weather.snow.init_done = true - end - - for _, player in ipairs(minetest.get_connected_players()) do - if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then - return false - end - mcl_weather.snow.add_snow_particles(player) - end -end) - -- register snow weather if mcl_weather.reg_weathers.snow == nil then mcl_weather.reg_weathers.snow = { @@ -94,3 +117,39 @@ if mcl_weather.reg_weathers.snow == nil then } } end + +minetest.register_abm({ + label = "Snow piles up", + nodenames = {"group:opaque","group:leaves","group:snow_cover"}, + neighbors = {"air"}, + interval = 27, + chance = 33, + min_y = mcl_vars.mg_overworld_min, + action = function(pos, node, active_object_count, active_object_count_wider) + if (mcl_weather.state ~= "rain" and mcl_weather.state ~= "thunder" and mcl_weather.state ~= "snow") + or not mcl_weather.has_snow(pos) + or node.name == "mcl_core:snowblock" then + return end + + local above = vector.offset(pos,0,1,0) + local above_node = minetest.get_node(above) + + if above_node.name == "air" and mcl_weather.is_outdoor(pos) then + local nn = nil + if node.name:find("snow") then + local l = node.name:sub(-1) + l = tonumber(l) + if node.name == "mcl_core:snow" then + nn={name = "mcl_core:snow_2"} + elseif l and l < 7 then + nn={name="mcl_core:snow_"..tostring(math.min(8,l + 1))} + elseif l and l >= 7 then + nn={name = "mcl_core:snowblock"} + end + if nn then minetest.set_node(pos,nn) end + else + minetest.set_node(above,{name = "mcl_core:snow"}) + end + end + end +}) diff --git a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_1.png b/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_1.png deleted file mode 100644 index ab18333b7..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_1.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_2.png b/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_2.png deleted file mode 100644 index fb37100a3..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_2.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_3.png b/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_3.png deleted file mode 100644 index 4432b355e..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_rain_raindrop_3.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake1.png b/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake1.png deleted file mode 100644 index 8604f5dce..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake1.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake2.png b/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake2.png deleted file mode 100644 index bea317ee8..000000000 Binary files a/mods/ENVIRONMENT/mcl_weather/textures/weather_pack_snow_snowflake2.png and /dev/null differ diff --git a/mods/ENVIRONMENT/mcl_weather/thunder.lua b/mods/ENVIRONMENT/mcl_weather/thunder.lua index b1837f023..f8e5a0371 100644 --- a/mods/ENVIRONMENT/mcl_weather/thunder.lua +++ b/mods/ENVIRONMENT/mcl_weather/thunder.lua @@ -1,61 +1,61 @@ +local get_connected_players = minetest.get_connected_players + -- turn off lightning mod 'auto mode' lightning.auto = false mcl_weather.thunder = { - next_strike = 0, - min_delay = 3, - max_delay = 12, - init_done = false, + next_strike = 0, + min_delay = 3, + max_delay = 12, + init_done = false, } minetest.register_globalstep(function(dtime) - if mcl_weather.get_weather() ~= "thunder" then - return false - end - - mcl_weather.rain.set_particles_mode("thunder") - mcl_weather.rain.make_weather() + if mcl_weather.get_weather() ~= "thunder" then + return false + end - if mcl_weather.thunder.init_done == false then - mcl_weather.skycolor.add_layer( - "weather-pack-thunder-sky", - {{r=0, g=0, b=0}, - {r=40, g=40, b=40}, - {r=85, g=86, b=86}, - {r=40, g=40, b=40}, - {r=0, g=0, b=0}}) - mcl_weather.skycolor.active = true - for _, player in pairs(minetest.get_connected_players()) do - player:set_clouds({color="#3D3D3FE8"}) - end - mcl_weather.thunder.init_done = true - end - - if (mcl_weather.thunder.next_strike <= minetest.get_gametime()) then - lightning.strike() - local delay = math.random(mcl_weather.thunder.min_delay, mcl_weather.thunder.max_delay) - mcl_weather.thunder.next_strike = minetest.get_gametime() + delay - end + mcl_weather.rain.set_particles_mode("thunder") + mcl_weather.rain.make_weather() + if mcl_weather.thunder.init_done == false then + mcl_weather.skycolor.add_layer("weather-pack-thunder-sky", { + {r=0, g=0, b=0}, + {r=40, g=40, b=40}, + {r=85, g=86, b=86}, + {r=40, g=40, b=40}, + {r=0, g=0, b=0}, + }) + mcl_weather.skycolor.active = true + for _, player in pairs(get_connected_players()) do + player:set_clouds({color="#3D3D3FE8"}) + end + mcl_weather.thunder.init_done = true + end + if (mcl_weather.thunder.next_strike <= minetest.get_gametime()) then + lightning.strike() + local delay = math.random(mcl_weather.thunder.min_delay, mcl_weather.thunder.max_delay) + mcl_weather.thunder.next_strike = minetest.get_gametime() + delay + end end) -mcl_weather.thunder.clear = function() - mcl_weather.rain.clear() - mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky") - mcl_weather.skycolor.remove_layer("lightning") - mcl_weather.thunder.init_done = false +function mcl_weather.thunder.clear() + mcl_weather.rain.clear() + mcl_weather.skycolor.remove_layer("weather-pack-thunder-sky") + mcl_weather.skycolor.remove_layer("lightning") + mcl_weather.thunder.init_done = false end -- register thunderstorm weather if mcl_weather.reg_weathers.thunder == nil then - mcl_weather.reg_weathers.thunder = { - clear = mcl_weather.thunder.clear, - light_factor = 0.33333, - -- 10min - 20min - min_duration = 600, - max_duration = 1200, - transitions = { - [100] = "rain", - } - } + mcl_weather.reg_weathers.thunder = { + clear = mcl_weather.thunder.clear, + light_factor = 0.33333, + -- 10min - 20min + min_duration = 600, + max_duration = 1200, + transitions = { + [100] = "rain", + }, + } end diff --git a/mods/ENVIRONMENT/mcl_weather/weather_core.lua b/mods/ENVIRONMENT/mcl_weather/weather_core.lua index 365f6e549..32d8db4df 100644 --- a/mods/ENVIRONMENT/mcl_weather/weather_core.lua +++ b/mods/ENVIRONMENT/mcl_weather/weather_core.lua @@ -1,27 +1,29 @@ -local S = minetest.get_translator("mcl_weather") +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math -- weather states, 'none' is default, other states depends from active mods mcl_weather.state = "none" - + -- player list for saving player meta info mcl_weather.players = {} - + -- default weather check interval for global step mcl_weather.check_interval = 5 - + -- weather min duration mcl_weather.min_duration = 600 - + -- weather max duration mcl_weather.max_duration = 9000 -- weather calculated end time mcl_weather.end_time = nil - + -- registered weathers mcl_weather.reg_weathers = {} --- global flag to disable/enable ABM logic. +-- global flag to disable/enable ABM logic. mcl_weather.allow_abm = true mcl_weather.reg_weathers["none"] = { @@ -37,24 +39,56 @@ mcl_weather.reg_weathers["none"] = { local storage = minetest.get_mod_storage() -- Save weather into mod storage, so it can be loaded after restarting the server -local save_weather = function() +local function save_weather() + if not mcl_weather.end_time then return end storage:set_string("mcl_weather_state", mcl_weather.state) storage:set_int("mcl_weather_end_time", mcl_weather.end_time) minetest.log("verbose", "[mcl_weather] Weather data saved: state="..mcl_weather.state.." end_time="..mcl_weather.end_time) end minetest.register_on_shutdown(save_weather) -mcl_weather.get_rand_end_time = function(min_duration, max_duration) +local particlespawners={} +function mcl_weather.add_spawner_player(pl,id,ps) + local name=pl:get_player_name() + if not particlespawners[name] then + particlespawners[name] = {} + end + if not particlespawners[name][id] then + mcl_weather.remove_spawners_player(pl) + particlespawners[name] = {} + ps.playername =name + ps.attached = pl + particlespawners[name][id]=minetest.add_particlespawner(ps) + return particlespawners[name][id] + end +end +function mcl_weather.remove_spawners_player(pl) + local name=pl:get_player_name() + if not particlespawners[name] then return end + for k,v in pairs(particlespawners[name]) do + minetest.delete_particlespawner(v) + end + particlespawners[name] = nil + return true +end + +function mcl_weather.remove_all_spawners() + for k,v in pairs(minetest.get_connected_players()) do + mcl_weather.remove_spawners_player(v) + end +end + +function mcl_weather.get_rand_end_time(min_duration, max_duration) local r - if min_duration ~= nil and max_duration ~= nil then + if min_duration and max_duration then r = math.random(min_duration, max_duration) else r = math.random(mcl_weather.min_duration, mcl_weather.max_duration) - end + end return minetest.get_gametime() + r end -mcl_weather.get_current_light_factor = function() +function mcl_weather.get_current_light_factor() if mcl_weather.state == "none" then return nil else @@ -65,7 +99,7 @@ end -- Returns true if pos is outdoor. -- Outdoor is defined as any node in the Overworld under open sky. -- FIXME: Nodes below glass also count as “outdoor”, this should not be the case. -mcl_weather.is_outdoor = function(pos) +function mcl_weather.is_outdoor(pos) local cpos = {x=pos.x, y=pos.y+1, z=pos.z} local dim = mcl_worlds.pos_to_dimension(cpos) if minetest.get_node_light(cpos, 0.5) == 15 and dim == "overworld" then @@ -76,11 +110,11 @@ end -- checks if player is undewater. This is needed in order to -- turn off weather particles generation. -mcl_weather.is_underwater = function(player) +function mcl_weather.is_underwater(player) local ppos = player:get_pos() local offset = player:get_eye_offset() - local player_eye_pos = {x = ppos.x + offset.x, - y = ppos.y + offset.y + 1.5, + local player_eye_pos = {x = ppos.x + offset.x, + y = ppos.y + offset.y + 1.5, z = ppos.z + offset.z} local node_level = minetest.get_node_level(player_eye_pos) if node_level == 8 or node_level == 7 then @@ -89,39 +123,8 @@ mcl_weather.is_underwater = function(player) return false end --- trying to locate position for particles by player look direction for performance reason. --- it is costly to generate many particles around player so goal is focus mainly on front view. -mcl_weather.get_random_pos_by_player_look_dir = function(player) - local look_dir = player:get_look_dir() - local player_pos = player:get_pos() - - local random_pos_x = 0 - local random_pos_y = 0 - local random_pos_z = 0 - - if look_dir.x > 0 then - if look_dir.z > 0 then - random_pos_x = math.random() + math.random(player_pos.x - 2.5, player_pos.x + 5) - random_pos_z = math.random() + math.random(player_pos.z - 2.5, player_pos.z + 5) - else - random_pos_x = math.random() + math.random(player_pos.x - 2.5, player_pos.x + 5) - random_pos_z = math.random() + math.random(player_pos.z - 5, player_pos.z + 2.5) - end - else - if look_dir.z > 0 then - random_pos_x = math.random() + math.random(player_pos.x - 5, player_pos.x + 2.5) - random_pos_z = math.random() + math.random(player_pos.z - 2.5, player_pos.z + 5) - else - random_pos_x = math.random() + math.random(player_pos.x - 5, player_pos.x + 2.5) - random_pos_z = math.random() + math.random(player_pos.z - 5, player_pos.z + 2.5) - end - end - - random_pos_y = math.random() + math.random(player_pos.y + 10, player_pos.y + 15) - return random_pos_x, random_pos_y, random_pos_z -end - local t, wci = 0, mcl_weather.check_interval + minetest.register_globalstep(function(dtime) t = t + dtime if t < wci then return end @@ -145,7 +148,7 @@ minetest.register_globalstep(function(dtime) end) -- Sets random weather (which could be 'none' (no weather)). -mcl_weather.set_random_weather = function(weather_name, weather_meta) +function mcl_weather.set_random_weather(weather_name, weather_meta) if weather_meta == nil then return end local transitions = weather_meta.transitions local random_roll = math.random(0,100) @@ -165,11 +168,11 @@ end -- * explicit_end_time is OPTIONAL. If specified, explicitly set the -- gametime (minetest.get_gametime) in which the weather ends. -- * changer is OPTIONAL, for logging purposes. -mcl_weather.change_weather = function(new_weather, explicit_end_time, changer_name) +function mcl_weather.change_weather(new_weather, explicit_end_time, changer_name) local changer_name = changer_name or debug.getinfo(2).name.."()" - if (mcl_weather.reg_weathers ~= nil and mcl_weather.reg_weathers[new_weather] ~= nil) then - if (mcl_weather.state ~= nil and mcl_weather.reg_weathers[mcl_weather.state] ~= nil) then + if (mcl_weather.reg_weathers and mcl_weather.reg_weathers[new_weather]) then + if (mcl_weather.state and mcl_weather.reg_weathers[mcl_weather.state]) then mcl_weather.reg_weathers[mcl_weather.state].clear() end @@ -198,7 +201,7 @@ mcl_weather.change_weather = function(new_weather, explicit_end_time, changer_na return false end -mcl_weather.get_weather = function() +function mcl_weather.get_weather() return mcl_weather.state end @@ -207,7 +210,7 @@ minetest.register_privilege("weather_manager", { give_to_singleplayer = false }) --- Weather command definition. Set +-- Weather command definition. Set minetest.register_chatcommand("weather", { params = "(clear | rain | snow | thunder) []", description = S("Changes the weather to the specified parameter."), @@ -267,12 +270,12 @@ minetest.register_chatcommand("toggledownfall", { -- Configuration setting which allows user to disable ABM for weathers (if they use it). -- Weather mods expected to be use this flag before registering ABM. local weather_allow_abm = minetest.settings:get_bool("weather_allow_abm") -if weather_allow_abm ~= nil and weather_allow_abm == false then +if weather_allow_abm == false then mcl_weather.allow_abm = false -end +end -local load_weather = function() +local function load_weather() local weather = storage:get_string("mcl_weather_state") if weather and weather ~= "" then mcl_weather.state = weather diff --git a/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua b/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua new file mode 100644 index 000000000..fefb17fa5 --- /dev/null +++ b/mods/ENVIRONMENT/mcl_zombie_sieges/init.lua @@ -0,0 +1,98 @@ +local zombie_siege_enabled = minetest.settings:get_bool("mcl_raids_zombie_siege", false) + +local function check_spawn_pos(pos) + return mcl_util.get_natural_light(pos) < 7 +end + +local function spawn_zombies(self) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(self.pos,-16,-16,-16),vector.offset(self.pos,16,16,16),{"group:solid"}) + table.shuffle(nn) + for i=1,20 do + local p = vector.offset(nn[i%#nn],0,1,0) + if check_spawn_pos(p) then + local m = mcl_mobs.spawn(p,"mobs_mc:zombie") + if m then + local l = m:get_luaentity() + l:gopath(self.pos) + table.insert(self.mobs, m) + self.health_max = self.health_max + l.health + else + --minetest.log("Failed to spawn zombie at location: " .. minetest.pos_to_string(p)) + end + end + end +end + +mcl_events.register_event("zombie_siege",{ + readable_name = "Zombie Siege", + max_stage = 1, + health = 1, + health_max = 1, + exclusive_to_area = 128, + enable_bossbar = false, + cond_start = function(self) + --minetest.log("Cond start zs") + local r = {} + + if not zombie_siege_enabled then + --minetest.log("action", "Zombie siege disabled") + return r + else + --minetest.log("action", "Zombie siege start check") + end + + local t = minetest.get_timeofday() + local pr = PseudoRandom(minetest.get_day_count()) + local rnd = pr:next(1,10) + + if t < 0.04 and rnd == 1 then + --minetest.log("Well, it's siege time") + for _,p in pairs(minetest.get_connected_players()) do + local village = mcl_raids.find_village(p:get_pos()) + if village then + minetest.log("action", "Zombie siege is starting") + table.insert(r,{ player = p:get_player_name(), pos = village}) + end + end + else + --minetest.log("Not night for a siege, or not success") + end + if #r > 0 then return r end + end, + on_start = function(self) + self.mobs = {} + self.health_max = 1 + self.health = 0 + end, + cond_progress = function(self) + local m = {} + local h = 0 + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + h = h + l.health + table.insert(m,o) + end + end + self.mobs = m + self.health = h + self.percent = math.max(0,(self.health / self.health_max ) * 100) + if #m < 1 then + return true end + end, + on_stage_begin = spawn_zombies, + cond_complete = function(self) + local m = {} + for k,o in pairs(self.mobs) do + if o and o:get_pos() then + local l = o:get_luaentity() + table.insert(m,o) + end + end + return self.stage >= self.max_stage and #m < 1 + end, + on_complete = function(self) + --minetest.log("SIEGE complete") + --awards.unlock(self.player,"mcl:hero_of_the_village") + end, +}) diff --git a/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf b/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf new file mode 100644 index 000000000..0263d367a --- /dev/null +++ b/mods/ENVIRONMENT/mcl_zombie_sieges/mod.conf @@ -0,0 +1,3 @@ +name = mcl_zombie_sieges +author = cora +depends = mcl_events, mcl_raids diff --git a/mods/HELP/doc/description.txt b/mods/HELP/doc/description.txt deleted file mode 100644 index 59a7a4c21..000000000 --- a/mods/HELP/doc/description.txt +++ /dev/null @@ -1 +0,0 @@ -Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/HELP/doc/doc/init.lua b/mods/HELP/doc/doc/init.lua index 360cc149c..304900753 100644 --- a/mods/HELP/doc/doc/init.lua +++ b/mods/HELP/doc/doc/init.lua @@ -1,13 +1,11 @@ -local S = minetest.get_translator("doc") +local S = minetest.get_translator(minetest.get_current_modname()) local F = function(f) return minetest.formspec_escape(S(f)) end --- Compability for 0.4.14 or earlier -local colorize -if minetest.colorize then - colorize = minetest.colorize -else - colorize = function(color, text) return text end -end +local mod_central_messages = minetest.get_modpath("central_message") +local mod_inventory_plus = minetest.get_modpath("inventory_plus") + +local math = math +local colorize = minetest.colorize doc = {} @@ -41,10 +39,10 @@ doc.FORMSPEC.ENTRY_HEIGHT = doc.FORMSPEC.ENTRY_END_Y - doc.FORMSPEC.ENTRY_START_ -- Internal helper variables local DOC_INTRO = S("This is the help.") -local COLOR_NOT_VIEWED = "#00FFFF" -- cyan -local COLOR_VIEWED = "#FFFFFF" -- white -local COLOR_HIDDEN = "#999999" -- gray -local COLOR_ERROR = "#FF0000" -- red +local COLOR_NOT_VIEWED = "#00FFFF" -- cyan +local COLOR_VIEWED = "#FFFFFF" -- white +local COLOR_HIDDEN = "#999999" -- gray +local COLOR_ERROR = "#FF0000" -- red local CATEGORYFIELDSIZE = { WIDTH = math.ceil(doc.FORMSPEC.WIDTH / 4), @@ -69,7 +67,7 @@ local set_category_order_was_called = false local function get_entry(category_id, entry_id) local category = doc.data.categories[category_id] local entry - if category ~= nil then + if category then entry = category.entries[entry_id] end if category == nil or entry == nil then @@ -99,7 +97,7 @@ end -- Add a new category function doc.add_category(id, def) - if doc.data.categories[id] == nil and id ~= nil then + if doc.data.categories[id] == nil and id then doc.data.categories[id] = {} doc.data.categories[id].entries = {} doc.data.categories[id].entry_count = 0 @@ -129,7 +127,7 @@ end -- Add a new entry function doc.add_entry(category_id, entry_id, def) local cat = doc.data.categories[category_id] - if cat ~= nil then + if cat then local hidden = def.hidden or (def.hidden == nil and cat.def.hide_entries_by_default) if hidden then cat.hidden_count = cat.hidden_count + 1 @@ -183,7 +181,7 @@ function doc.mark_entry_as_revealed(playername, category_id, entry_id) doc.data.players[playername].entry_textlist_needs_updating = true -- Notify player of entry revelation if doc.data.players[playername].stored_data.notify_on_reveal == true then - if minetest.get_modpath("central_message") ~= nil then + if mod_central_messages then local cat = doc.data.categories[category_id] cmsg.push_message_player(minetest.get_player_by_name(playername), S("New help entry unlocked: @1 > @2", cat.def.name, entry.name)) end @@ -230,7 +228,7 @@ function doc.mark_all_entries_as_revealed(playername) msg = S("All help entries are already revealed.") end -- Notify - if minetest.get_modpath("central_message") ~= nil then + if mod_central_messages then cmsg.push_message_player(minetest.get_player_by_name(playername), msg) else minetest.chat_send_player(playername, msg) @@ -239,7 +237,7 @@ end -- Returns true if the specified entry has been viewed by the player function doc.entry_viewed(playername, category_id, entry_id) - local entry, category_id, entry_id = get_entry(category_id, entry_id) + local _, category_id, entry_id = get_entry(category_id, entry_id) if doc.data.players[playername].stored_data.viewed[category_id] == nil then return false else @@ -249,7 +247,7 @@ end -- Returns true if the specified entry is hidden from the player function doc.entry_revealed(playername, category_id, entry_id) - local entry, category_id, entry_id = get_entry(category_id, entry_id) + local _, category_id, entry_id = get_entry(category_id, entry_id) local hidden = doc.data.categories[category_id].entries[entry_id].hidden if doc.data.players[playername].stored_data.revealed[category_id] == nil then return not hidden @@ -308,7 +306,7 @@ function doc.show_entry(playername, category_id, entry_id, ignore_hidden) minetest.show_formspec(playername, "doc:error_no_categories", doc.formspec_error_no_categories()) return end - local entry, category_id, entry_id = get_entry(category_id, entry_id) + local _, category_id, entry_id = get_entry(category_id, entry_id) if ignore_hidden or doc.entry_revealed(playername, category_id, entry_id) then local playerdata = doc.data.players[playername] playerdata.category = category_id @@ -433,7 +431,7 @@ end -- Returns the currently viewed entry and/or category of the player function doc.get_selection(playername) local playerdata = doc.data.players[playername] - if playerdata ~= nil then + if playerdata then local cat = playerdata.category if cat then local entry = playerdata.entry @@ -454,18 +452,18 @@ end doc.entry_builders = {} -- Scrollable freeform text -doc.entry_builders.text = function(data) +function doc.entry_builders.text(data) local formstring = doc.widgets.text(data, doc.FORMSPEC.ENTRY_START_X, doc.FORMSPEC.ENTRY_START_Y, doc.FORMSPEC.ENTRY_WIDTH - 0.4, doc.FORMSPEC.ENTRY_HEIGHT) return formstring end -- Scrollable freeform text with an optional standard gallery (3 rows, 3:2 aspect ratio) -doc.entry_builders.text_and_gallery = function(data, playername) +function doc.entry_builders.text_and_gallery(data, playername) -- How much height the image gallery “steals” from the text widget local stolen_height = 0 local formstring = "" -- Only add the gallery if images are in the data, otherwise, the text widget gets all of the space - if data.images ~= nil then + if data.images then local gallery gallery, stolen_height = doc.widgets.gallery(data.images, playername, nil, doc.FORMSPEC.ENTRY_END_Y + 0.2, nil, nil, nil, nil, false) formstring = formstring .. gallery @@ -482,7 +480,7 @@ end doc.widgets = {} -- Scrollable freeform text -doc.widgets.text = function(data, x, y, width, height) +function doc.widgets.text(data, x, y, width, height) if x == nil then x = doc.FORMSPEC.ENTRY_START_X end @@ -508,7 +506,7 @@ end -- Image gallery -- Currently, only one gallery per entry is supported. TODO: Add support for multiple galleries in an entry (low priority) -doc.widgets.gallery = function(imagedata, playername, x, y, aspect_ratio, width, rows, align_left, align_top) +function doc.widgets.gallery(imagedata, playername, x, y, aspect_ratio, width, rows, align_left, align_top) if playername == nil then return nil end -- emergency exit local formstring = "" @@ -593,13 +591,11 @@ doc.widgets.gallery = function(imagedata, playername, x, y, aspect_ratio, width, formstring = formstring .. "label["..nx..","..ny..";"..i.."]" pos = pos + 1 end - local bw, bh - return formstring, ih end -- Direct formspec -doc.entry_builders.formspec = function(data) +function doc.entry_builders.formspec(data) return data end @@ -613,7 +609,7 @@ do minetest.log("action", "[doc] doc.mt opened.") local string = file:read() io.close(file) - if(string ~= nil) then + if string then local savetable = minetest.deserialize(string) for name, players_stored_data in pairs(savetable.players_stored_data) do doc.data.players[name] = {} @@ -680,13 +676,13 @@ function doc.formspec_main(playername) local data = doc.data.categories[id] local bw = doc.FORMSPEC.WIDTH / math.floor(((doc.data.category_count-1) / CATEGORYFIELDSIZE.HEIGHT)+1) -- Skip categories which do not exist - if data ~= nil then + if data then -- Category buton local button = "button["..((x-1)*bw)..","..y..";"..bw..",1;doc_button_category_"..id..";"..minetest.formspec_escape(data.def.name).."]" local tooltip = "" -- Optional description - if data.def.description ~= nil then - tooltip = "tooltip[doc_button_category_"..id..";"..minetest.formspec_escape(data.def.description).."]" + if data.def.description then + tooltip = "tooltip[doc_button_category_"..id..";"..minetest.formspec_escape(data.def.description).."]" end formstring = formstring .. button .. tooltip y = y + 1 @@ -709,7 +705,7 @@ function doc.formspec_main(playername) end end local sel = doc.data.categories[doc.data.players[playername].category] - if sel ~= nil then + if sel then formstring = formstring .. ";" formstring = formstring .. doc.data.categories[doc.data.players[playername].category].order_position end @@ -719,7 +715,7 @@ function doc.formspec_main(playername) notify_checkbox_y = doc.FORMSPEC.HEIGHT-1 end local text - if minetest.get_modpath("central_message") then + if mod_central_messages then text = F("Notify me when new help is available") else text = F("Play notification sound when new help is available") @@ -810,7 +806,7 @@ function doc.get_sorted_entry_names(cid) local cat = doc.data.categories[cid] local used_eids = {} -- Helper function to extract the entry ID out of the output table - local extract = function(entry_table) + local function extract(entry_table) local eids = {} for k,v in pairs(entry_table) do local eid = v.eid @@ -952,7 +948,7 @@ function doc.process_form(player,formname,fields) local playername = player:get_player_name() --[[ process clicks on the tab header ]] if(formname == "doc:main" or formname == "doc:category" or formname == "doc:entry") then - if fields.doc_header ~= nil then + if fields.doc_header then local tab = tonumber(fields.doc_header) local formspec, subformname, contents local cid, eid @@ -967,7 +963,7 @@ function doc.process_form(player,formname,fields) elseif(tab==3) then doc.data.players[playername].galidx = 1 contents = doc.formspec_entry(cid, eid, playername) - if cid ~= nil and eid ~= nil then + if cid and eid then doc.mark_entry_as_viewed(playername, cid, eid) end subformname = "entry" @@ -992,7 +988,7 @@ function doc.process_form(player,formname,fields) if fields["doc_mainlist"] then local event = minetest.explode_textlist_event(fields["doc_mainlist"]) local cid = doc.data.category_order[event.index] - if cid ~= nil then + if cid then if event.type == "CHG" then doc.data.players[playername].catsel = nil doc.data.players[playername].category = cid @@ -1022,10 +1018,10 @@ function doc.process_form(player,formname,fields) elseif(formname == "doc:category") then if fields["doc_button_goto_entry"] then local cid = doc.data.players[playername].category - if cid ~= nil then + if cid then local eid = nil local eids, catsel = doc.data.players[playername].entry_ids, doc.data.players[playername].catsel - if eids ~= nil and catsel ~= nil then + if eids and catsel then eid = eids[catsel] end doc.data.players[playername].galidx = 1 @@ -1048,7 +1044,7 @@ function doc.process_form(player,formname,fields) local cid = doc.data.players[playername].category local eid = nil local eids, catsel = doc.data.players[playername].entry_ids, event.index - if eids ~= nil and catsel ~= nil then + if eids and catsel then eid = eids[catsel] end doc.mark_entry_as_viewed(playername, cid, eid) @@ -1109,7 +1105,7 @@ function doc.process_form(player,formname,fields) minetest.show_formspec(playername, "doc:entry", formspec) end else - if fields["doc_inventory_plus"] and minetest.get_modpath("inventory_plus") then + if fields["doc_inventory_plus"] and mod_inventory_plus then doc.show_doc(playername) return end @@ -1177,18 +1173,18 @@ minetest.register_on_joinplayer(function(player) end -- Add button for Inventory++ - if minetest.get_modpath("inventory_plus") ~= nil then + if mod_inventory_plus then inventory_plus.register_button(player, "doc_inventory_plus", S("Help")) end end) ---[[ Add buttons for inventory mods ]] -local button_action = function(player) +local function button_action(player) doc.show_doc(player:get_player_name()) end -- Unified Inventory -if minetest.get_modpath("unified_inventory") ~= nil then +if minetest.get_modpath("unified_inventory") then unified_inventory.register_button("doc", { type = "image", image = "doc_button_icon_hires.png", @@ -1198,7 +1194,7 @@ if minetest.get_modpath("unified_inventory") ~= nil then end -- sfinv_buttons -if minetest.get_modpath("sfinv_buttons") ~= nil then +if minetest.get_modpath("sfinv_buttons") then sfinv_buttons.register_button("doc", { image = "doc_button_icon_lores.png", tooltip = S("Collection of help texts"), diff --git a/mods/HELP/doc/doc/locale/doc.dk.tr b/mods/HELP/doc/doc/locale/doc.dk.tr new file mode 100644 index 000000000..49fb8ace3 --- /dev/null +++ b/mods/HELP/doc/doc/locale/doc.dk.tr @@ -0,0 +1,51 @@ +# textdomain:doc +<=< +>=> +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry.=Adgang til det forespurgte blev nægtet; det er hemmeligt. Du kan få adgang ved at nå længere i spillet. Find selv ud af, hvordan du får adgang. +All entries read.=Alle indtastninger læst. +All help entries revealed!=Alle hjælpeindtastninger afsløret! +All help entries are already revealed.=Alle hjælpeindtasterninger er allerede afsløret. +Allows you to reveal all hidden help entries with /help_reveal=Gør dig i stand til at afsløre alle skjulte hjælpeindtaster med /help_reveal +Category list=Kategoriliste +Currently all entries in this category are hidden from you.=Alle indtastninger i denne kategori er i øjeblikket skjult for dig. +Unlock new entries by progressing in the game.=Lås nye indtastninger op ved at nå længere i spillet. +Help=Hjælp +Entry=Indtastning +Entry list=Indtastningsliste +Error: Access denied.=Fejl: Adgang nægtet. +Error: No help available.=Fejl: Igen hjælp tilgængelig. +Go to category list=Gå til kategoriliste +Go to entry list=Gå til indtastningsliste +Help > @1=Hjælp > @1 +Help > @1 > @2= Hjælp > @1 > @2 +Help > @1 > (No Entry)=Hjælp > @1 > (Ingen indtasting) +Help > (No Category)=Hjælp > (Ingen kategori) +Hidden entries: @1=Skjult indtastning: @1 +Nameless entry (@1)=Unavngiven indtastning (@1) +New entries: @1=Nye indtastninger: @1 +New help entry unlocked: @1 > @2=Ny hjælpeindtastning låst op: @1 > @2 +No categories have been registered, but they are required to provide help.=Nye kategorier er blevet registreret, men de er påkrævede for at give hjælp. +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.= Dokumentationssystemet [doc] har ikke medfølgende hjælpeindhold, det behøver yderligere mods for at tilføje hjælpeindhold. +Number of entries: @1=Antal indtastninger: @1 +OK=OK +Open a window providing help entries about Minetest and more=Åbn et vindue med hjælpeindtastninger om Minetest og mere +Please select a category you wish to learn more about:=Vælg venlist en kategori som du ønsker at lære mere om: +Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia.=Anbefalede mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia. +Reveal all hidden help entries to you=Afslør alle gemte hjælpeindtastninger for dig. +Show entry=Vis indtastning +Show category=Vis kategori +Show next entry=Vis næste indtastning +Show previous entry=Vis forrige indtastning +This category does not have any entries.=Denne kategori har ingen indtastninger. +This category has the following entries:=Denne kategori har følgende indtastninger: +This category is empty.=Denne kategori er tom. +This is the help.=Dette er hjælpen. +You haven't chosen a category yet. Please choose one in the category list first.=Du har endnu ikke vagt en kategori. Vælg venligst én i kategoriliste før. +You haven't chosen an entry yet. Please choose one in the entry list first.=Du har ikke valgt en indtastning endnu. Vælg venligst en fra indtastningslisten først. +Collection of help texts=Samling at hjælpetekster. +Notify me when new help is available=Giv mig besked når ny hjælp er tilgængelig. +Play notification sound when new help is available=Afspil lyd når ny hjælp er tilgængeig. +Show previous image=Vis forrige billede +Show previous gallery page=Vis forrige galleriside +Show next image=Vis næste billede +Show next gallery page=Vis næste galleriside diff --git a/mods/HELP/doc/doc/locale/doc.fr.tr b/mods/HELP/doc/doc/locale/doc.fr.tr index f7f33b0f5..78c8bba76 100644 --- a/mods/HELP/doc/doc/locale/doc.fr.tr +++ b/mods/HELP/doc/doc/locale/doc.fr.tr @@ -24,7 +24,7 @@ Help > (No Category)=Aide > (Aucune catégorie) Hidden entries: @1=Pages cachées : @1 Nameless entry (@1)=Pages sans nom (@1) New entries: @1=Nouvelles pages : @1 -New help entry unlocked: @1 > @2=Nouvelles pages d'aide débloquées : @1 +New help entry unlocked: @1 > @2=Nouvelles pages d'aide débloquées : @1 > @2 No categories have been registered, but they are required to provide help.=Aucune catégorie n'a été enregistrée, mais elles sont nécessaires pour fournir l'aide. 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.=Le Système de Documentation [doc] n'est fourni avec aucun contenu d'aide, il a besoin d'autres mods pour ajouter le contenu de l'aide. Vérifiez que de tels mods sont activés pour ce monde, et réessayez. Number of entries: @1=Nombre de pages : @1 diff --git a/mods/HELP/doc/doc/locale/doc.ja.tr b/mods/HELP/doc/doc/locale/doc.ja.tr new file mode 100644 index 000000000..68cc90232 --- /dev/null +++ b/mods/HELP/doc/doc/locale/doc.ja.tr @@ -0,0 +1,51 @@ +# textdomain:doc +<=< +>=> +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry.=リクエストされたエントリーへのアクセスは拒否されました:このエントリーはシークレット要素です。ゲームを進行することでアクセスのロックを解除できるでしょう。このエントリーをアンロックする方法は、ご自身で見当をつけてみてください。 +All entries read.=すべてのエントリーを読みます。 +All help entries revealed!=ヘルプの全エントリーを公開! +All help entries are already revealed.=ヘルプのエントリーはすべて公開済みです。 +Allows you to reveal all hidden help entries with /help_reveal=/help_reveal で隠れているヘルプエントリーをすべて表示できるようにする +Category list=カテゴリーリスト +Currently all entries in this category are hidden from you.=現在、このカテゴリのエントリーはすべて非表示になっています。 +Unlock new entries by progressing in the game.=ゲームを進めることで、新たな項目をアンロックできます。 +Help=ヘルプ +Entry=エントリー +Entry list=エントリーリスト +Error: Access denied.=エラー:アクセスが拒否されました。 +Error: No help available.=エラー:利用可能なヘルプはありません。 +Go to category list=カテゴリーリストへ +Go to entry list=エントリーリストへ +Help > @1=ヘルプ > @1 +Help > @1 > @2=ヘルプ > @1 > @2 +Help > @1 > (No Entry)=ヘルプ > @1 > (エントリーなし) +Help > (No Category)=ヘルプ > (カテゴリーなし) +Hidden entries: @1=隠れているエントリー:@1 +Nameless entry (@1)=名無しのエントリー (@1) +New entries: @1=新しいエントリー:@1 +New help entry unlocked: @1 > @2=新しいヘルプエントリーがアンロックされた:@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]は、それ自体ではヘルプコンテンツを備えておらず、ヘルプコンテンツを追加するための追加MODが必要です。そのようなMODがこのワールドで有効になっていることを確認し、もう一度試してみてください。 +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.=推奨MOD:doc_basics、doc_items、doc_identifier、doc_encyclopedia +Reveal all hidden help entries to you=隠れているヘルプをすべて表示する +Show entry=エントリーを表示 +Show category=カテゴリーを表示 +Show next entry=次のエントリーを表示 +Show previous entry=前のエントリーを表示 +This category does not have any entries.=このカテゴリにはエントリーがありません。 +This category has the following entries:=このカテゴリには以下のエントリーがあります: +This category is empty.=このカテゴリは空っぽです。 +This is the help.=これはヘルプです。 +You haven't chosen a category yet. Please choose one in the category list first.=まだカテゴリーが選択されていません。まずはカテゴリーリストからひとつ選択してください。 +You haven't chosen an entry yet. Please choose one in the entry list first.=まだエントリーが選択されていません。まずはエントリーリストからひとつ選択してください。 +Collection of help texts=ヘルプテキスト集 +Notify me when new help is available=新しいヘルプが利用可能になったら通知する +Play notification sound when new help is available=新しいヘルプが利用可能になったときに通知音を再生する +Show previous image=前の画像を表示 +Show previous gallery page=前のギャラリーページを表示 +Show next image=次の画像を表示 +Show next gallery page=次のギャラリーページを表示 diff --git a/mods/HELP/doc/doc/locale/doc.pl.tr b/mods/HELP/doc/doc/locale/doc.pl.tr new file mode 100644 index 000000000..bd0f3dbaa --- /dev/null +++ b/mods/HELP/doc/doc/locale/doc.pl.tr @@ -0,0 +1,52 @@ +# textdomain:doc +<=< +>=> +Access to the requested entry has been denied; this entry is secret. You may unlock access by progressing in the game. Figure out on your own how to unlock this entry.=Brak dostępu do zażądanego wpisu; ten wpis jest tajemnicą. Możesz odblokować do niego dostęp przez robienie postępów w grze. Wymyśl jak go odblokować. +All entries read.=Wszystkie wpisy przeczytane. +All help entries revealed!=Wszystkie wpisy pomocnicze odkryte! +All help entries are already revealed.=Wszystkie wpisy pomocnicze są już odkryte. +Allows you to reveal all hidden help entries with /help_reveal=Pozwala odkryć wszystkie wpisy pomocnicze przy użyciu /help_reveal +Category list=Lista kategorii +Currently all entries in this category are hidden from you.=Aktualnie wszystkie wpisy w tej kategorii są przed tobą ukryte. +Unlock new entries by progressing in the game.=Odblokuj nowe wpisy przez robienie postępów w grze. +Help=Pomoc +Entry=Wpis +Entry list=Lista wpisów +Error: Access denied.=Błąd: Odmowa dostępu. +Error: No help available.=Błąd: Brak dostępnej pomocy. +Go to category list=Idź do listy kategorii +Go to entry list=Idź do listy wpisów +Help > @1=Pomoc > @1 +Help > @1 > @2=Pomoc > @1 > @2 +Help > @1 > (No Entry)=Pomoc > @1 > (Brak wpisu) +Help > (No Category)=Pomoc > (Brak kategorii) +Hidden entries: @1=Ukryte wpisy: @1 +Nameless entry (@1)=Nienazwany wpis (@1) +New entries: @1=Nowe wpisy: @1 +New help entry unlocked: @1 > @2=Nowy wpis pomocniczy odblokowany: @1 > @2 +No categories have been registered, but they are required to provide help.=Nie zarejestrowano żadnych kategorii, ale są one wymagane do uzyskania pomocy. +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.=System dokumentacji [doc] nie ma sam z siebie żadnej zawartości, potrzebuje dodatkowych modów, które dodadzą zawartość. +Number of entries: @1=Liczba wpisów: @1 +OK=OK +Open a window providing help entries about Minetest and more=Otwórz okno aby zobaczyć wpisy pomocnicze na temat Minetest i innych rzeczy +Please select a category you wish to learn more about:=Wybierz kategorię o której chciałbyś się więcej dowiedzieć: +Recommended mods: doc_basics, doc_items, doc_identifier, doc_encyclopedia.=Rekomendowane mody: doc_basics, doc_items, doc_identifier, doc_encyclopedia. +Reveal all hidden help entries to you=Odkryj wszystkie ukryte wpisy pomocnicze +Show entry=Pokaż wpis +Show category=Pokaż kategorię +Show next entry=Pokaż następny wpis +Show previous entry=Pokaż poprzedni wpis +This category does not have any entries.=W tej kategorii nie ma żadnych wpisów. +This category has the following entries:=W tej kategorii są następujące wpisy: +This category is empty.=Ta kategoria jest pusta. +This is the help.=To jest pomoc. +You haven't chosen a category yet. Please choose one in the category list first.=Nie wybrano żadnej kategorii. Proszę wybrać jedną z listy kategorii. +You haven't chosen an entry yet. Please choose one in the entry list first.=Nie wybrano wpisu. Proszę wybrać jeden z listy wpisów. +Collection of help texts=Kolekcja tekstów pomocniczych. +Notify me when new help is available=Powiadom mnie gdy nowa pomoc jest dostępna. +Play notification sound when new help is available=Odegraj dźwięk powiadomienia gdy nowa pomoc jest dostępna +Show previous image=Pokaż poprzedni obrazek +Show previous gallery page=Pokaż poprzednią stronę galerii +Show next image=Pokaż następny obrazek +Show next gallery page=Pokaż następną stronę galerii + diff --git a/mods/HELP/doc/doc/mod.conf b/mods/HELP/doc/doc/mod.conf index 302fd83d1..0f65ddff7 100644 --- a/mods/HELP/doc/doc/mod.conf +++ b/mods/HELP/doc/doc/mod.conf @@ -1,3 +1,4 @@ name = doc -optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus +author = Wuzzy description = A simple in-game documentation system which enables mods to add help entries based on templates. +optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus diff --git a/mods/HELP/doc/doc/screenshot.png b/mods/HELP/doc/doc/screenshot.png deleted file mode 100644 index 90946a999..000000000 Binary files a/mods/HELP/doc/doc/screenshot.png and /dev/null differ diff --git a/mods/HELP/doc/doc/textures/doc_awards_icon_generic.png b/mods/HELP/doc/doc/textures/doc_awards_icon_generic.png deleted file mode 100644 index b33fa34ad..000000000 Binary files a/mods/HELP/doc/doc/textures/doc_awards_icon_generic.png and /dev/null differ diff --git a/mods/HELP/doc/doc/textures/doc_button_icon_hires.png b/mods/HELP/doc/doc/textures/doc_button_icon_hires.png deleted file mode 100644 index 25c9fe4e9..000000000 Binary files a/mods/HELP/doc/doc/textures/doc_button_icon_hires.png and /dev/null differ diff --git a/mods/HELP/doc/doc/textures/doc_button_icon_lores.png b/mods/HELP/doc/doc/textures/doc_button_icon_lores.png deleted file mode 100644 index 3df6195c7..000000000 Binary files a/mods/HELP/doc/doc/textures/doc_button_icon_lores.png and /dev/null differ diff --git a/mods/HELP/doc/doc/textures/inventory_plus_doc_inventory_plus.png b/mods/HELP/doc/doc/textures/inventory_plus_doc_inventory_plus.png deleted file mode 100644 index 3df6195c7..000000000 Binary files a/mods/HELP/doc/doc/textures/inventory_plus_doc_inventory_plus.png and /dev/null differ diff --git a/mods/HELP/doc/doc_identifier/init.lua b/mods/HELP/doc/doc_identifier/init.lua index 2e041ae2e..c1c2043d3 100644 --- a/mods/HELP/doc/doc_identifier/init.lua +++ b/mods/HELP/doc/doc_identifier/init.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator("doc_identifier") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_doc_basics = minetest.get_modpath("doc_basics") local doc_identifier = {} @@ -6,15 +8,16 @@ doc_identifier.registered_objects = {} -- API doc.sub.identifier = {} -doc.sub.identifier.register_object = function(object_name, category_id, entry_id) + +function doc.sub.identifier.register_object(object_name, category_id, entry_id) doc_identifier.registered_objects[object_name] = { category = category_id, entry = entry_id } end -- END OF API -doc_identifier.identify = function(itemstack, user, pointed_thing) +function doc_identifier.identify(itemstack, user, pointed_thing) local username = user:get_player_name() - local show_message = function(username, itype, param) + local function show_message(username, itype, param) local vsize = 2 local message if itype == "error_item" then @@ -24,9 +27,9 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) elseif itype == "error_unknown" then vsize = vsize + 2 local mod - if param ~= nil then + if param then local colon = string.find(param, ":") - if colon ~= nil and colon > 1 then + if colon and colon > 1 then mod = string.sub(param,1,colon-1) end end @@ -36,8 +39,8 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) S("• The author of the game or a mod has made a mistake") message = message .. "\n\n" - if mod ~= nil then - if minetest.get_modpath(mod) ~= nil then + if mod then + if minetest.get_modpath(mod) then message = message .. S("It appears to originate from the mod “@1”, which is enabled.", mod) message = message .. "\n" else @@ -45,7 +48,7 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) message = message .. "\n" end end - if param ~= nil then + if param then message = message .. S("Its identifier is “@1”.", param) end elseif itype == "error_ignore" then @@ -66,8 +69,8 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) if pointed_thing.type == "node" then local pos = pointed_thing.under local node = minetest.get_node(pos) - if minetest.registered_nodes[node.name] ~= nil then - local nodedef = minetest.registered_nodes[node.name] + if minetest.registered_nodes[node.name] then + --local nodedef = minetest.registered_nodes[node.name] if(node.name == "ignore") then show_message(username, "error_ignore") elseif doc.entry_exists("nodes", node.name) then @@ -82,14 +85,14 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) local object = pointed_thing.ref local le = object:get_luaentity() if object:is_player() then - if minetest.get_modpath("doc_basics") ~= nil and doc.entry_exists("basics", "players") then + if mod_doc_basics and doc.entry_exists("basics", "players") then doc.show_entry(username, "basics", "players", true) else -- Fallback message show_message(username, "player") end -- luaentity exists - elseif le ~= nil then + elseif le then local ro = doc_identifier.registered_objects[le.name] -- Dropped items if le.name == "__builtin:item" then @@ -112,7 +115,7 @@ doc_identifier.identify = function(itemstack, user, pointed_thing) doc.show_entry(username, "nodes", itemstring, true) end -- A known registered object - elseif ro ~= nil then + elseif ro then doc.show_entry(username, ro.category, ro.entry, true) -- Undefined object (error) elseif minetest.registered_entities[le.name] == nil then @@ -195,10 +198,10 @@ minetest.register_craft({ {"group:stick", ""} } }) -if minetest.get_modpath("mcl_core") ~= nil then +if minetest.get_modpath("mcl_core") then minetest.register_craft({ output = "doc_identifier:identifier_solid", - recipe = { { "mcl_core:glass" }, + recipe = { { "mcl_core:glass" }, { "group:stick" } } }) end diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.dk.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.dk.tr new file mode 100644 index 000000000..5840b4319 --- /dev/null +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.dk.tr @@ -0,0 +1,18 @@ +# textdomain:doc_identifier +Error: This node, item or object is undefined. This is always an error.=Fejl: Dette knudepunkt, genstand eller objekt er ikke defineret. +This can happen for the following reasons:=Dette kan ske af følgende grunde: +• The mod which is required for it is not enabled=• Det mod som er krævet er ikke aktiveret +• The author of the game or a mod has made a mistake=• Ophavsmanden til spillet eller moddet har lavet en fejltagelse +It appears to originate from the mod “@1”, which is enabled.=Det ser ud til at stamme fra moddet "@1" som er aktiveret. +It appears to originate from the mod “@1”, which is not enabled!=Det ser ud til at stamme fra moddet "01" som er deaktiveret! +Its identifier is “@1”.=Dets identificering er "@1". +Lookup Tool=Opslagsværktøj +No help entry for this block could be found.=Der kunne ikke findes nogen hjælpeindtastning til denne blok. +No help entry for this item could be found.=Der kunne ikke findes nogen hjælpeindtastning til denne genstand. +No help entry for this object could be found.=Der kunne ikke findes nogen hjælpeindtastning for stte objekt. +OK=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.=Slå en hvilkensomhelst blok, genstand eller andre ting som du ønsker at vide mere om. Dette vil åbne den relevante hjælpeindtastning. Værktøjet findes i to tilstande som skiftes ved brug. I flydende tilstand vil værktøjet også peje på væsker, mens dette ikke er tilfældet i fast tilstand. +This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds.=Denne blok kan ikke identificeres fordi verdenen ikke har materialiseret sig endnu. Forsøg igen om et par sekunder. +This is a player.=Dette er en spiller. +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.=Denne smarte lille hjælper kan bruges til hurtigt at lære mere om omgivelserne. Den identificerer og analyserer blokke, genstande og andre ting, og den viser udtømmende informationer om den ting den bliver brugt på. +Show help for pointed thing=Vis hjælp til tingen diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr new file mode 100644 index 000000000..2a545f742 --- /dev/null +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.ja.tr @@ -0,0 +1,18 @@ +# 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=・そのために必要なMODが有効になっていない +• The author of the game or a mod has made a mistake=・ゲームの作者やMODがミスをした場合 +It appears to originate from the mod “@1”, which is enabled.=有効になっているMOD“@1”から発生しているようです。 +It appears to originate from the mod “@1”, which is not enabled!=有効化されていないMOD“@1”から発生しているようです! +Its identifier is “@1”.=その識別子は“@1”です。. +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=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.=ブロックやアイテムなど、詳しく知りたいものをパンチしてください。すると適切なヘルプエントリーが表示されます。この道具には2つのモードがあり、使用することで変更されます。液体モードでは、この道具は液体もポイントしますが、固体モードではそのようなことはありません。 +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.=この便利な小さいヘルプ機能は、自分の身近な環境について手っ取り早く知るために使えます。ブロックやアイテムなどを識別して分析し、使用されているものに関する幅広い情報を表示します。 +Show help for pointed thing=ポイントしたものをヘルプで表示する diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.pl.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.pl.tr new file mode 100644 index 000000000..3af2c377d --- /dev/null +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.pl.tr @@ -0,0 +1,18 @@ +# textdomain:doc_identifier +Error: This node, item or object is undefined. This is always an error.=Błąd: Ten węzeł, przedmiot lub obiekt nie jest zdefiniowany. To zawsze jest błąd. +This can happen for the following reasons:=To może się zdarzyć z następujących powodów: +• The mod which is required for it is not enabled=• Mod który jest do tego potrzebny nie jest włączony +• The author of the game or a mod has made a mistake=• Autor gry lub moda popełnił błąd +It appears to originate from the mod “@1”, which is enabled.=Wygląda na to, że powodem jest mod "@1", który jest włączony. +It appears to originate from the mod “@1”, which is not enabled!=Wygląda na to, że powodem jest mod "@1", który nie jest włączony! +Its identifier is “@1”.=Identyfikator to "@1". +Lookup Tool=Narzędzie rozpoznające +No help entry for this block could be found.=Nie znaleziono wpisu pomocniczego dla tego bloku. +No help entry for this item could be found.=Nie znaleziono wpisu pomocniczego dla tego przedmiotu. +No help entry for this object could be found.=Nie znaleziono wpisu pomocniczego dla tego obiektu. +OK=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.=Uderz dowolny blok, przedmiot lub inną rzecz aby dowiedzieć się o niej czegoś. To otworzy odpowiedni wpis pomocniczy. Narzędzie jest dostępne w dwóch trybach które można zmienić przez kliknięcie Użyj. W trybie płynów narzędzie to wskazuje również na płyny, podczas gdy w trybie stałym tak nie jest. +This block cannot be identified because the world has not materialized at this point yet. Try again in a few seconds.=Ten blok nie może być zidentyfikowany, ponieważ świat jeszcze się nie zmaterializował. Spróbuj ponownie za kilka sekund. +This is a player.=To jest gracz. +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.=To jest małe pomocnicze narzędzie, które może być użyte by szybko dowiedzieć się więcej na temat bliskiego otoczenia. Identyfikuje ono oraz analizuje bloki, przedmioty i inne rzeczy oraz pokazuje dokładne informacje na temat tego na czym zostanie użyte. +Show help for pointed thing=Pokaż pomoc dla wskazywanej rzeczy diff --git a/mods/HELP/doc/doc_identifier/locale/doc_identifier.zh_TW.tr b/mods/HELP/doc/doc_identifier/locale/doc_identifier.zh_TW.tr new file mode 100644 index 000000000..727887db9 --- /dev/null +++ b/mods/HELP/doc/doc_identifier/locale/doc_identifier.zh_TW.tr @@ -0,0 +1,18 @@ +# 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=• 未啟用所需的MOD +• The author of the game or a mod has made a mistake=• 遊戲或mod的作者犯了一個錯誤 +It appears to originate from the mod “@1”, which is enabled.=它似乎來自以啟用的mod「@1」。 +It appears to originate from the mod “@1”, which is not enabled!=它似乎來自沒啟用的mod「@1」! +Its identifier is “@1”.=其標識符為「@1」。 +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=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.=這個有用的小幫手可以用來快速了解自己所處的近距離環境。它可以識別和分析區塊、物品和其他事物。當你對着一個方塊、物品或實體使用它時,可以顯示出那個事物的大量信息。 +Show help for pointed thing=顯示選中方塊的資訊 diff --git a/mods/HELP/doc/doc_identifier/mod.conf b/mods/HELP/doc/doc_identifier/mod.conf index 4a7626a4e..28a09d07e 100644 --- a/mods/HELP/doc/doc_identifier/mod.conf +++ b/mods/HELP/doc/doc_identifier/mod.conf @@ -1,4 +1,5 @@ name = doc_identifier +author = Wuzzy +description = Adds a tool which shows help entries about almost anything which it punches. depends = doc, doc_items optional_depends = doc_basics, mcl_core -description = Adds a tool which shows help entries about almost anything which it punches. diff --git a/mods/HELP/doc/doc_identifier/screenshot.png b/mods/HELP/doc/doc_identifier/screenshot.png deleted file mode 100644 index 13b2540df..000000000 Binary files a/mods/HELP/doc/doc_identifier/screenshot.png and /dev/null differ diff --git a/mods/HELP/doc/doc_identifier/textures/doc_identifier_identifier.png b/mods/HELP/doc/doc_identifier/textures/doc_identifier_identifier.png deleted file mode 100644 index 00b3147a0..000000000 Binary files a/mods/HELP/doc/doc_identifier/textures/doc_identifier_identifier.png and /dev/null differ diff --git a/mods/HELP/doc/doc_items/init.lua b/mods/HELP/doc/doc_items/init.lua index b0be3e12d..325ad9abb 100644 --- a/mods/HELP/doc/doc_items/init.lua +++ b/mods/HELP/doc/doc_items/init.lua @@ -1,6 +1,12 @@ -local S = minetest.get_translator("doc_items") +local S = minetest.get_translator(minetest.get_current_modname()) local N = function(s) return s end +local math = math +local string = string + +local tostring = tostring +local pairs = pairs + doc.sub.items = {} -- Template texts @@ -34,13 +40,17 @@ local suppressed = { local forbidden_core_factoids = {} -- Helper functions -local yesno = function(bool) - if bool==true then return S("Yes") - elseif bool==false then return S("No") - else return "N/A" end +local function yesno(bool) + if bool == true then + return S("Yes") + elseif bool == false then + return S("No") + else + return "N/A" + end end -local groups_to_string = function(grouptable, filter) +local function groups_to_string(grouptable, filter) local gstring = "" local groups_count = 0 for id, value in pairs(grouptable) do @@ -50,7 +60,7 @@ local groups_to_string = function(grouptable, filter) -- List seperator gstring = gstring .. S(", ") end - if groupdefs[id] ~= nil and doc.sub.items.settings.friendly_group_names == true then + if groupdefs[id] and doc.sub.items.settings.friendly_group_names == true then gstring = gstring .. groupdefs[id] else gstring = gstring .. id @@ -66,7 +76,7 @@ local groups_to_string = function(grouptable, filter) end -- Removes all text after the first newline (including the newline) -local scrub_newlines = function(text) +local function scrub_newlines(text) local spl = string.split(text, "\n") if spl and #spl > 0 then return spl[1] @@ -76,7 +86,7 @@ local scrub_newlines = function(text) end --[[ Append a newline to text, unless it already ends with a newline. ]] -local newline = function(text) +local function newline(text) if string.sub(text, #text, #text) == "\n" or text == "" then return text else @@ -85,7 +95,7 @@ local newline = function(text) end --[[ Make sure the text ends with two newlines by appending any missing newlines at the end, if neccessary. ]] -local newline2 = function(text) +local function newline2(text) if string.sub(text, #text-1, #text) == "\n\n" or text == "" then return text elseif string.sub(text, #text, #text) == "\n" then @@ -97,7 +107,7 @@ end -- Extract suitable item description for formspec -local description_for_formspec = function(itemstring) +local function description_for_formspec(itemstring) if minetest.registered_items[itemstring] == nil then -- Huh? The item doesn't exist for some reason. Better give a dummy string minetest.log("warning", "[doc] Unknown item detected: "..tostring(itemstring)) @@ -111,26 +121,26 @@ local description_for_formspec = function(itemstring) end end -local get_entry_name = function(itemstring) +local function get_entry_name(itemstring) local def = minetest.registered_items[itemstring] - if def._doc_items_entry_name ~= nil then + if def._doc_items_entry_name then return def._doc_items_entry_name - elseif item_name_overrides[itemstring] ~= nil then + elseif item_name_overrides[itemstring] then return item_name_overrides[itemstring] else return def.description end end -doc.sub.items.get_group_name = function(groupname) - if groupdefs[groupname] ~= nil and doc.sub.items.settings.friendly_group_names == true then +function doc.sub.items.get_group_name(groupname) + if groupdefs[groupname] and doc.sub.items.settings.friendly_group_names == true then return groupdefs[groupname] else return groupname end end -local burntime_to_text = function(burntime) +local function burntime_to_text(burntime) if burntime == nil then return S("unknown") elseif burntime == 1 then @@ -146,16 +156,16 @@ end * Full punch interval * Damage groups ]] -local factoid_toolcaps = function(tool_capabilities, check_uses) +local function factoid_toolcaps(tool_capabilities, check_uses) if forbidden_core_factoids.tool_capabilities then return "" end local formstring = "" if check_uses == nil then check_uses = false end - if tool_capabilities ~= nil and tool_capabilities ~= {} then + if tool_capabilities and tool_capabilities ~= {} then local groupcaps = tool_capabilities.groupcaps - if groupcaps ~= nil then + if groupcaps then local miningcapstr = "" local miningtimesstr = "" local miningusesstr = "" @@ -164,7 +174,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses) local useslines = 0 for k,v in pairs(groupcaps) do -- Mining capabilities - local minrating, maxrating + --[[local minrating, maxrating if v.times then for rating, time in pairs(v.times) do if minrating == nil then minrating = rating else @@ -177,7 +187,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses) else minrating = 1 maxrating = 1 - end + end]] local maxlevel = v.maxlevel if not maxlevel then -- Default from tool.h @@ -188,7 +198,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses) caplines = caplines + 1 for rating=3, 1, -1 do - if v.times ~= nil and v.times[rating] ~= nil then + if v.times and v.times[rating] then local maxtime = v.times[rating] local mintime local mintimestr, maxtimestr @@ -255,7 +265,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses) -- Weapon data local damage_groups = tool_capabilities.damage_groups - if damage_groups ~= nil then + if damage_groups then formstring = formstring .. S("This is a melee weapon which deals damage by punching.") .. "\n" -- Damage groups formstring = formstring .. S("Maximum damage per hit:") .. "\n" @@ -266,7 +276,7 @@ local factoid_toolcaps = function(tool_capabilities, check_uses) -- Full punch interval local punch = 1.0 - if tool_capabilities.full_punch_interval ~= nil then + if tool_capabilities.full_punch_interval then punch = tool_capabilities.full_punch_interval end formstring = formstring .. S("Full punch interval: @1 s", string.format("%.1f", punch)) @@ -282,7 +292,7 @@ end - Digging times/groups - level group ]] -local factoid_mining_node = function(data) +local function factoid_mining_node(data) if forbidden_core_factoids.node_mining then return "" end @@ -292,7 +302,7 @@ local factoid_mining_node = function(data) -- Check if there are no mining groups at all local nogroups = true for groupname,_ in pairs(mininggroups) do - if data.def.groups[groupname] ~= nil or groupname == "dig_immediate" then + if data.def.groups[groupname] or groupname == "dig_immediate" then nogroups = false break end @@ -324,7 +334,7 @@ local factoid_mining_node = function(data) local minegroupcount = 0 for group,_ in pairs(mininggroups) do local rating = data.def.groups[group] - if rating ~= nil then + if rating then mstring = mstring .. S("• @1: @2", doc.sub.items.get_group_name(group), rating).."\n" minegroupcount = minegroupcount + 1 end @@ -344,18 +354,18 @@ local factoid_mining_node = function(data) end -- Pointing range of itmes -local range_factoid = function(itemstring, def) +local function range_factoid(itemstring, def) local handrange = minetest.registered_items[""].range local itemrange = def.range if itemstring == "" then - if handrange ~= nil then + if handrange then return S("Range: @1", itemrange) else return S("Range: 4") end else if handrange == nil then handrange = 4 end - if itemrange ~= nil then + if itemrange then return S("Range: @1", itemrange) else return S("Range: @1 (@2)", get_entry_name(""), handrange) @@ -364,14 +374,14 @@ local range_factoid = function(itemstring, def) end -- Smelting fuel factoid -local factoid_fuel = function(itemstring, ctype) +local function factoid_fuel(itemstring, ctype) if forbidden_core_factoids.fuel then return "" end local formstring = "" local result, decremented = minetest.get_craft_result({method = "fuel", items = {itemstring}}) - if result ~= nil and result.time > 0 then + if result and result.time > 0 then local base local burntext = burntime_to_text(result.time) if ctype == "tools" then @@ -392,7 +402,7 @@ local factoid_fuel = function(itemstring, ctype) end -- Shows the itemstring of an item -local factoid_itemstring = function(itemstring, playername) +local function factoid_itemstring(itemstring, playername) if forbidden_core_factoids.itemstring then return "" end @@ -405,7 +415,7 @@ local factoid_itemstring = function(itemstring, playername) end end -local entry_image = function(data) +local function entry_image(data) local formstring = "" -- No image for air if data.itemstring ~= "air" then @@ -414,7 +424,7 @@ local entry_image = function(data) formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;".. minetest.registered_items[""].wield_image.."]" -- Other items - elseif data.image ~= nil then + elseif data.image then formstring = formstring .. "image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.image.."]" else formstring = formstring .. "item_image["..(doc.FORMSPEC.ENTRY_END_X-1)..","..doc.FORMSPEC.ENTRY_START_Y..";1,1;"..data.itemstring.."]" @@ -432,9 +442,9 @@ factoid_generators.craftitems = {} --[[ Returns a list of all registered factoids for the specified category and type * category_id: Identifier of the Documentation System category in which the factoid appears * factoid_type: If set, oly returns factoid with a matching factoid_type. - If nil, all factoids for this category will be generated + If nil, all factoids for this category will be generated * data: Entry data to parse ]] -local factoid_custom = function(category_id, factoid_type, data) +local function factoid_custom(category_id, factoid_type, data) local ftable = factoid_generators[category_id] local datastring = "" -- Custom factoids are inserted here @@ -450,17 +460,17 @@ local factoid_custom = function(category_id, factoid_type, data) end -- Shows core information shared by all items, to be inserted at the top -local factoids_header = function(data, ctype) +local function factoids_header(data, ctype) local datastring = "" if not forbidden_core_factoids.basics then local longdesc = data.longdesc local usagehelp = data.usagehelp - if longdesc ~= nil then + if longdesc then datastring = datastring .. S("Description: @1", longdesc) datastring = newline2(datastring) end - if usagehelp ~= nil then + if usagehelp then datastring = datastring .. S("Usage help: @1", usagehelp) datastring = newline2(datastring) end @@ -484,7 +494,7 @@ local factoids_header = function(data, ctype) datastring = datastring .. S("This item points to liquids.").."\n" end end - if data.def.on_use ~= nil then + if data.def.on_use then if ctype == "nodes" then datastring = datastring .. S("Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.").."\n" elseif ctype == "tools" then @@ -510,7 +520,7 @@ local factoids_header = function(data, ctype) end -- Shows less important information shared by all items, to be inserted at the bottom -local factoids_footer = function(data, playername, ctype) +local function factoids_footer(data, playername, ctype) local datastring = "" datastring = datastring .. factoid_custom(ctype, "groups", data) datastring = newline2(datastring) @@ -518,7 +528,7 @@ local factoids_footer = function(data, playername, ctype) -- Show other “exposable” groups if not forbidden_core_factoids.groups then local gstring, gcount = groups_to_string(data.def.groups, miscgroups) - if gstring ~= nil then + if gstring then if gcount == 1 then if ctype == "nodes" then datastring = datastring .. S("This block belongs to the @1 group.", gstring) .. "\n" @@ -577,11 +587,8 @@ doc.add_category("nodes", { description = S("Item reference of blocks and other things which are capable of occupying space"), build_formspec = function(data, playername) if data then - local formstring = "" - local datastring = "" - - formstring = entry_image(data) - datastring = factoids_header(data, "nodes") + local formstring = entry_image(data) + local datastring = factoids_header(data, "nodes") local liquid = data.def.liquidtype ~= "none" and minetest.get_item_group(data.itemstring, "fake_liquid") == 0 if not forbidden_core_factoids.basics then @@ -600,7 +607,7 @@ doc.add_category("nodes", { datastring = datastring .. S("This block is a liquid with these properties:") .. "\n" local range, renew, viscos if data.def.liquid_range then range = data.def.liquid_range else range = 8 end - if data.def.liquid_renewable ~= nil then renew = data.def.liquid_renewable else renew = true end + if data.def.liquid_renewable then renew = data.def.liquid_renewable else renew = true end if data.def.liquid_viscosity then viscos = data.def.liquid_viscosity else viscos = 0 end if renew then datastring = datastring .. S("• Renewable") .. "\n" @@ -620,7 +627,7 @@ doc.add_category("nodes", { --- Direct interaction with the player ---- Damage (very important) if not forbidden_core_factoids.node_damage then - if data.def.damage_per_second ~= nil and data.def.damage_per_second > 1 then + if data.def.damage_per_second and data.def.damage_per_second > 1 then datastring = datastring .. S("This block causes a damage of @1 hit points per second.", data.def.damage_per_second) .. "\n" elseif data.def.damage_per_second == 1 then datastring = datastring .. S("This block causes a damage of @1 hit point per second.", data.def.damage_per_second) .. "\n" @@ -633,7 +640,7 @@ doc.add_category("nodes", { end end local fdap = data.def.groups.fall_damage_add_percent - if fdap ~= nil and fdap ~= 0 then + if fdap and fdap ~= 0 then if fdap > 0 then datastring = datastring .. S("The fall damage on this block is increased by @1%.", fdap) .. "\n" elseif fdap <= -100 then @@ -655,11 +662,11 @@ doc.add_category("nodes", { datastring = datastring .. S("This block can be climbed.").."\n" end local bouncy = data.def.groups.bouncy - if bouncy ~= nil and bouncy ~= 0 then + if bouncy and bouncy ~= 0 then datastring = datastring .. S("This block will make you bounce off with an elasticity of @1%.", bouncy).."\n" end local slippery = data.def.groups.slippery - if slippery ~= nil and slippery ~= 0 then + if slippery and slippery ~= 0 then datastring = datastring .. S("This block is slippery.") .. "\n" end datastring = datastring .. factoid_custom("nodes", "movement", data) @@ -759,7 +766,7 @@ doc.add_category("nodes", { datastring = newline2(datastring) --- List nodes/groups to which this node connects to - if not forbidden_core_factoids.connects_to and data.def.connects_to ~= nil then + if not forbidden_core_factoids.connects_to and data.def.connects_to then local nodes = {} local groups = {} for c=1,#data.def.connects_to do @@ -774,7 +781,7 @@ doc.add_category("nodes", { local nstring = "" for n=1,#nodes do local name - if item_name_overrides[nodes[n]] ~= nil then + if item_name_overrides[nodes[n]] then name = item_name_overrides[nodes[n]] else name = description_for_formspec(nodes[n]) @@ -782,7 +789,7 @@ doc.add_category("nodes", { if n > 1 then nstring = nstring .. S(", ") end - if name ~= nil then + if name then nstring = nstring .. name else nstring = nstring .. S("Unknown Node") @@ -813,9 +820,9 @@ doc.add_category("nodes", { datastring = newline2(datastring) -- Non-default drops - if not forbidden_core_factoids.drops and data.def.drop ~= nil and data.def.drop ~= data.itemstring and data.itemstring ~= "air" then + if not forbidden_core_factoids.drops and data.def.drop and data.def.drop ~= data.itemstring and data.itemstring ~= "air" then -- TODO: Calculate drop probabilities of max > 1 like for max == 1 - local get_desc = function(stack) + local function get_desc(stack) return description_for_formspec(stack:get_name()) end if data.def.drop == "" then @@ -831,10 +838,10 @@ doc.add_category("nodes", { datastring = datastring .. S("This block will drop the following when mined: @1.", desc).."\n" end end - elseif type(data.def.drop) == "table" and data.def.drop.items ~= nil then + elseif type(data.def.drop) == "table" and data.def.drop.items then local max = data.def.drop.max_items local dropstring = "" - local dropstring_base = "" + local dropstring_base if max == nil then dropstring_base = N("This block will drop the following items when mined: @1.") elseif max == 1 then @@ -852,7 +859,7 @@ doc.add_category("nodes", { local rarity_history = {} for i=1,#data.def.drop.items do local local_rarity = data.def.drop.items[i].rarity - local chance = 1 + local chance local rarity = 1 if local_rarity == nil then local_rarity = 1 @@ -885,7 +892,7 @@ doc.add_category("nodes", { if chance > 0 then probtable = {} probtable.items = {} - for j=1,#data.def.drop.items[i].items do + for j = 1, #data.def.drop.items[i].items do local dropstack = ItemStack(data.def.drop.items[i].items[j]) local itemstring = dropstack:get_name() local desc = get_desc(dropstack) @@ -907,7 +914,7 @@ doc.add_category("nodes", { -- Do some cleanup of the probability table if max == 1 or max == nil then -- Sort by rarity - local comp = function(p1, p2) + local function comp(p1, p2) return p1.rarity < p2.rarity end table.sort(probtables, comp) @@ -937,7 +944,6 @@ doc.add_category("nodes", { end local rarity = probtable.rarity - local raritystring = "" -- No percentage if there's only one possible guaranteed drop if not(rarity == 1 and #data.def.drop.items == 1) then local chance = (1/rarity)*100 @@ -957,7 +963,7 @@ doc.add_category("nodes", { dropstring = dropstring .. dropstring_this pcount = pcount + 1 end - if max ~= nil and max > 1 then + if max and max > 1 then datastring = datastring .. S(dropstring_base, max, dropstring) else datastring = datastring .. S(dropstring_base, dropstring) @@ -992,15 +998,15 @@ doc.add_category("tools", { if entries[2].eid == "" then return false end local comp = {} - for e=1, 2 do + for e = 1, 2 do comp[e] = {} end -- No tool capabilities: Instant loser - if entries[1].data.def.tool_capabilities == nil and entries[2].data.def.tool_capabilities ~= nil then return false end - if entries[2].data.def.tool_capabilities == nil and entries[1].data.def.tool_capabilities ~= nil then return true end + if entries[1].data.def.tool_capabilities == nil and entries[2].data.def.tool_capabilities then return false end + if entries[2].data.def.tool_capabilities == nil and entries[1].data.def.tool_capabilities then return true end -- No tool capabilities for both: Compare by uses if entries[1].data.def.tool_capabilities == nil and entries[2].data.def.tool_capabilities == nil then - for e=1, 2 do + for e = 1, 2 do if type(entries[e].data.def._doc_items_durability) == "number" then comp[e].uses = entries[e].data.def._doc_items_durability else @@ -1055,7 +1061,7 @@ doc.add_category("tools", { comp[e].count = groupcount comp[e].group = group comp[e].mintime = mintime - if realuses ~= nil then + if realuses then comp[e].uses = realuses elseif type(entries[e].data.def._doc_items_durability) == "number" then comp[e].uses = entries[e].data.def._doc_items_durability @@ -1086,11 +1092,8 @@ doc.add_category("tools", { end, build_formspec = function(data, playername) if data then - local formstring = "" - local datastring = "" - - formstring = entry_image(data) - datastring = factoids_header(data, "tools") + local formstring = entry_image(data) + local datastring = factoids_header(data, "tools") -- Overwritten durability info if type(data.def._doc_items_durability) == "number" then @@ -1120,11 +1123,8 @@ doc.add_category("craftitems", { description = S("Item reference of items which are neither blocks, tools or weapons (esp. crafting items)"), build_formspec = function(data, playername) if data then - local formstring = "" - local datastring = "" - - formstring = entry_image(data) - datastring = factoids_header(data, "craftitems") + local formstring = entry_image(data) + local datastring = factoids_header(data, "craftitems") datastring = datastring .. factoids_footer(data, playername, "craftitems") formstring = formstring .. doc.widgets.text(datastring, nil, nil, doc.FORMSPEC.ENTRY_WIDTH - 1.2) @@ -1166,9 +1166,9 @@ local function gather_descs() -- 1st pass: Gather groups of interest for id, def in pairs(minetest.registered_items) do -- Gather all groups used for mining - if def.tool_capabilities ~= nil then + if def.tool_capabilities then local groupcaps = def.tool_capabilities.groupcaps - if groupcaps ~= nil then + if groupcaps then for k,v in pairs(groupcaps) do if mininggroups[k] ~= true then mininggroups[k] = true @@ -1179,7 +1179,7 @@ local function gather_descs() -- ... and gather all groups which appear in crafting recipes local crafts = minetest.get_all_craft_recipes(id) - if crafts ~= nil then + if crafts then for c=1,#crafts do for k,v in pairs(crafts[c].items) do if string.sub(v,1,6) == "group:" then @@ -1194,7 +1194,7 @@ local function gather_descs() end -- ... and gather all groups used in connects_to - if def.connects_to ~= nil then + if def.connects_to then for c=1, #def.connects_to do if string.sub(def.connects_to[c],1,6) == "group:" then local group = string.sub(def.connects_to[c],7,-1) @@ -1213,7 +1213,7 @@ local function gather_descs() else help.longdesc["air"] = S("A transparent block, basically empty space. It is usually left behind after digging something.") end - if minetest.registered_items["ignore"]._doc_items_create_entry ~= nil then + if minetest.registered_items["ignore"]._doc_items_create_entry then suppressed["ignore"] = minetest.registered_items["ignore"]._doc_items_create_entry == true end @@ -1242,23 +1242,23 @@ local function gather_descs() }) end - local add_entries = function(deftable, category_id) + local function add_entries(deftable, category_id) for id, def in pairs(deftable) do local name, ld, uh, im local forced = false - if def._doc_items_create_entry == true and def ~= nil then forced = true end + if def._doc_items_create_entry == true and def then forced = true end name = get_entry_name(id) if not (((def.description == nil or def.description == "") and def._doc_items_entry_name == nil) or (def._doc_items_create_entry == false) or (suppressed[id] == true)) or forced then if def._doc_items_longdesc then ld = def._doc_items_longdesc end - if help.longdesc[id] ~= nil then + if help.longdesc[id] then ld = help.longdesc[id] end if def._doc_items_usagehelp then uh = def._doc_items_usagehelp end - if help.usagehelp[id] ~= nil then + if help.usagehelp[id] then uh = help.usagehelp[id] end if def._doc_items_image then @@ -1269,7 +1269,6 @@ local function gather_descs() if type(def._doc_items_hidden) == "boolean" then hidden = def._doc_items_hidden end - local custom_image name = scrub_newlines(name) local infotable = { name = name, @@ -1308,13 +1307,13 @@ local function reveal_item(playername, itemstring) if itemstring == nil or itemstring == "" or playername == nil or playername == "" then return false end - if minetest.registered_nodes[itemstring] ~= nil then + if minetest.registered_nodes[itemstring] then category_id = "nodes" - elseif minetest.registered_tools[itemstring] ~= nil then + elseif minetest.registered_tools[itemstring] then category_id = "tools" - elseif minetest.registered_craftitems[itemstring] ~= nil then + elseif minetest.registered_craftitems[itemstring] then category_id = "craftitems" - elseif minetest.registered_items[itemstring] ~= nil then + elseif minetest.registered_items[itemstring] then category_id = "craftitems" else return false @@ -1334,7 +1333,7 @@ end minetest.register_on_dignode(function(pos, oldnode, digger) if digger == nil then return end local playername = digger:get_player_name() - if playername ~= nil and playername ~= "" and oldnode ~= nil then + if playername and playername ~= "" and oldnode then reveal_item(playername, oldnode.name) reveal_items_in_inventory(digger) end @@ -1343,7 +1342,7 @@ end) minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing) if puncher == nil then return end local playername = puncher:get_player_name() - if playername ~= nil and playername ~= "" and node ~= nil then + if playername and playername ~= "" and node then reveal_item(playername, node.name) end end) @@ -1351,7 +1350,7 @@ end) minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing) if placer == nil then return end local playername = placer:get_player_name() - if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + if playername and playername ~= "" and itemstack and not itemstack:is_empty() then reveal_item(playername, itemstack:get_name()) end end) @@ -1359,7 +1358,7 @@ end) minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) if player == nil then return end local playername = player:get_player_name() - if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + if playername and playername ~= "" and itemstack and not itemstack:is_empty() then reveal_item(playername, itemstack:get_name()) end end) @@ -1371,7 +1370,7 @@ minetest.register_on_player_inventory_action(function(player, action, inventory, if action == "take" or action == "put" then itemstack = inventory_info.stack end - if itemstack ~= nil and playername ~= nil and playername ~= "" and (not itemstack:is_empty()) then + if itemstack and playername and playername ~= "" and (not itemstack:is_empty()) then reveal_item(playername, itemstack:get_name()) end end) @@ -1379,9 +1378,9 @@ end) minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing) if user == nil then return end local playername = user:get_player_name() - if playername ~= nil and playername ~= "" and itemstack ~= nil and not itemstack:is_empty() then + if playername and playername ~= "" and itemstack and not itemstack:is_empty() then reveal_item(playername, itemstack:get_name()) - if replace_with_item ~= nil then + if replace_with_item then reveal_item(playername, replace_with_item) end end @@ -1391,10 +1390,12 @@ minetest.register_on_joinplayer(function(player) reveal_items_in_inventory(player) end) ---[[ Periodically check all items in player inventory and reveal them all. +--[[ +Periodically check all items in player inventory and reveal them all. TODO: Check whether there's a serious performance impact on servers with many players. -TODO: If possible, try to replace this functionality by updating the revealed items as - soon the player obtained a new item (probably needs new Minetest callbacks). ]] +TODO: If possible, try to replace this functionality by updating the revealed items as soon the player obtained a new item (probably needs new Minetest callbacks). +]] + local checktime = 8 local timer = 0 minetest.register_globalstep(function(dtime) 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 90747c38a..f14c99314 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.de.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.de.tr @@ -10,9 +10,9 @@ # Itemname (ca. 25%) @1 (ca. @2%)=@1 (ca. @2%) # List separator (e.g. “one, two, three”) -, =, +, =, # Final list separator (e.g. “One, two and three”) - and = und + and = und 1 second=1 Sekunde A transparent block, basically empty space. It is usually left behind after digging something.=Ein transparenter Block, praktisch leerer Raum. Er wird üblicherweise hinterlassen, nachdem man etwas ausgegraben hat. Air=Luft @@ -32,7 +32,7 @@ Item reference of items which are neither blocks, tools or weapons (esp. craftin Liquids can flow into this block and destroy it.=Flüssigkeiten können in diesen Block hereinfließen und ihn zerstören. Maximum stack size: @1=Maximale Stapelgröße: @1 Mining level: @1=Grabestufe: @1 -Mining ratings:=Grabewertungen: +Mining ratings:=Grabewertungen: • @1, rating @2: @3 s - @4 s=• @1, Wertung @2: @3 s - @4 s • @1, rating @2: @3 s=• @1, Wertung @2: @3 s Mining times:=Grabezeiten: @@ -76,9 +76,8 @@ This block connects to these blocks: @1.=Dieser Block verbindet sich mit den fol This block connects to this block: @1.=Dieser Block verbindet sich mit diesem Block: @1. This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Dieser Block reduziert Ihren Atem und verursacht beim Ertrinken einen Schaden von @1 Trefferpunkt alle 2 Sekunden. This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Dieser Block reduziert Ihren Atem und verursacht beim Ertrinken einen Schaden von @1 Trefferpunkten alle 2 Sekunden. -This block glows faintly. It is barely noticable.=Dieser Block leuchtet schwach. Es ist kaum merklich. This block is a light source with a light level of @1.=Dieser Block ist eine Lichtquelle mit einer Helligkeitsstufe von @1. -This block glows faintly with a light level of @1.=Dieser Block leuchtet schwach mit einer Helligkeitsstufe von @1. +This block glows faintly with a light level of @1.=Dieser Block leuchtet schwach mit einer Helligkeitsstufe von @1. This block is a building block for creating various buildings.=Dieser Block ist für den Bau diverser Gebäude vorgesehen. This block is a liquid with these properties:=Dieser Block ist eine Flüssigkeit mit folgenden Eigenschaften: This block is affected by gravity and can fall.=Dieser Block wird von der Schwerkraft beeinflusst und kann fallen. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.dk.tr b/mods/HELP/doc/doc_items/locale/doc_items.dk.tr new file mode 100644 index 000000000..1dd3eff8a --- /dev/null +++ b/mods/HELP/doc/doc_items/locale/doc_items.dk.tr @@ -0,0 +1,143 @@ +# textdomain:doc_items +Using it as fuel turns it into: @1.=At bruge det som brændstof laver det om til: @1. +@1 seconds=@1 sekunder +# Item count times item name +@1×@2=@1x@2 +# Itemname (25%) +@1 (@2%)=@1 (@2%) +# Itemname (<0.5%) +@1 (<0.5%)= @1 (<0.5%) +# Itemname (ca. 25%) +@1 (ca. @2%)=@1 (ca. @2%) +# List separator (e.g. “one, two, three”) +, = , +# Final list separator (e.g. “One, two and three”) + and = and +1 second=1 sekund +A transparent block, basically empty space. It is usually left behind after digging something.=En gennemsigtig blok, egentlig bare tom luft. Det efterlades typisk efter at have gravet. +Air=Luft +Blocks=Blokke +Building another block at this block will place it inside and replace it.=At sætte en ny blok ved denne blok vil placere den indeni og erstatte den. +Building this block is completely silent.=Det er helt lydløst at bygge denne blok. +Collidable: @1=Kan kollidere: @1 +Description: @1=Beskrivelse: @1 +Falling blocks can go through this block; they destroy it when doing so.=Faldende blokke kan gå igennem denne blok; de ødelægger den idet i går igennem den. +Full punch interval: @1 s=Tid mellem hele slag: @1 +Hand=Hånd +Hold it in your hand, then leftclick to eat it.=Hold det i din hånd, og venstre-klik for at spise det. +Hold it in your hand, then leftclick to eat it. But why would you want to do this?=Hold det i din hånd, og venstre-klik for at spise det. Men hvorfor i alverden ville du have lyst til dét? +Item reference of all wieldable tools and weapons=Genstandsreference til alt værktøj og alle våden man kan bære. +Item reference of blocks and other things which are capable of occupying space=Genstandsreference til blokke og andre ting som kan optage plads. +Item reference of items which are neither blocks, tools or weapons (esp. crafting items)=Genstandsreference til genstanse som hverken er blokke, værktøj eller våben (især håndværksmateriale) +Liquids can flow into this block and destroy it.=Væsker kan flyde ind i denne blok og ødelægge den. +Maximum stack size: @1=Største stakstørrelse: @1 +Mining level: @1=Udvindingsevneevne: @1 +Mining ratings:=Udvindelsesvurdering +• @1, rating @2: @3 s - @4 s=• @1, vurdering @2: @3 s -@4 s +• @1, rating @2: @3 s=• @1, vurdering @2: @3 s +Mining times:=Udvindingstider +Mining this block is completely silent.=Det er helt lydløst at udvinde denne blok. +Miscellaneous items=Diverse genstande +No=Nej +Pointable: No=Retningsbestemt: Nej +Pointable: Only by special items=Retningsbestemt: Kun af særlige genstande +Pointable: Yes=Retningsbestemt: Ja +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.=Slag med denne blok virker ikke som normalt; nærkamp og udvinding er enten umulig eller virker anderledes. +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.=Slag med dette objekt virker ikke som normalt; nærkamp og udvinding er enten umulig eller virker anderledes. +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.=Slag med dette værktøj virker ikke som normalt; nærkamp og udvinding er enten umulig eller virker anderledes. +Range: @1=Rækkevidde: @1 +# Range: () +Range: @1 (@2)=Rækkevidde: @1 (@2) +Range: 4=Rækkevidde: 4 +# Rating used for digging times +Rating @1=Vurdering: @1 +# @1 is minimal rating, @2 is maximum rating +Rating @1-@2=Vurdering @1-@2 +The fall damage on this block is increased by @1%.=Faldskade på denne blok er øget med @1%. +The fall damage on this block is reduced by @1%.=Faldskade på denne blok er reduceret med @1%. +This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.=Denne blok lader lys sprede sig med et lille tab af styrke, og sollys kan endda gå igennem uden tab. +This block allows light to propagate with a small loss of brightness.=Denne blok tillader lys at sprede med et lille tab af styrke. +This block allows sunlight to propagate without loss in brightness.=Denne blok tillader sollys at sprede sig uden tab af styrke. +This block belongs to the @1 group.=Denne blok tilhører @1gruppen +This block belongs to these groups: @1.=Denne blok hører til følgende grupper: @1. +This block can be climbed.=Man kan klatre på denne blok. +This block can be destroyed by any mining tool immediately.=Denne blok kan ødelægges straks med ethvert udvindingsværktøj. +This block can be destroyed by any mining tool in half a second.=Denne blok kan ødelægges på et halvt sekund med ethvert udvindingsværktøj. +This block can be mined by any mining tool immediately.=Denne blok kan udvindes straks med ethvert udvindingsværktøj. +This block can be mined by any mining tool in half a second.=Denne blok kan udvindes på et halvt sekund med ethvert udvindingsværktøj. +This block can be mined by mining tools which match any of the following mining ratings and its toughness level.=Denne blok kan udvindes med ethvert udvindingsværktøj som svarer til en hvilkensomhelst af følgende udvindingsvurderinger og hårdhedsgrad. +This block can not be destroyed by ordinary mining tools.=Denne blok kan ikke ødelægges af normalt udvindingsværktøj. +This block can not be mined by ordinary mining tools.=Denne blok kan ikke udvindes med normalt udvindingsværktøj. +This block can serve as a smelting fuel with a burning time of @1.=Denne blok virker som brændstof til at smelte og har en brændetid på @1. +This block causes a damage of @1 hit point per second.=Denne blok giver @1 skade per sekund. +This block causes a damage of @1 hit points per second.=Denne blok giver @1 skade per sekund. +This block connects to blocks of the @1 group.=Denne blok forbindes til blokke i @1gruppen. +This block connects to blocks of the following groups: @1.=Denne blok forbindes til blokke i følgende grupper: @1. +This block connects to these blocks: @1.=Denne blok forbindes til disse blokke: @1. +This block connects to this block: @1.=Denne blok forbindes til denne blok: @1. +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Denne blok nedsætter dit åndedræt og giver @1 drukningsskade hvert 2. sekund. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Denne blok nedsætter dit åndedræt og giver @1 drukneskade hvert 2. sekund. +This block is a light source with a light level of @1.=Denne blok er en lyskilde med lysniveau @1. +This block glows faintly with a light level of @1.=Denne blok gløder svagt med et lysniveau på @1. +This block is a building block for creating various buildings.=Denne blok er en byggesten til at bygge forskellige bygninger. +This block is a liquid with these properties:=Denne blok er en væske med følgende egenskaber: +This block is affected by gravity and can fall.=Denne blok påvirkes af tyngdekraften og kan falde ned. +This block is completely silent when mined or built.=Denne blok er helt lydløs når den udvindes eller bygges. +This block is completely silent when walked on, mined or built.=Denne blok er helt lydløs når den betrædes, udvindes eller bygges. +This block is destroyed when a falling block ends up inside it.=Denne blok ødelægges når en nedfaldende blok ender indeni den. +This block negates all fall damage.=Denne blok modvirker al faldskade. +This block points to liquids.=Denne blok orienteres mod væsker. +This block will drop as an item when a falling block ends up inside it.=Denne blok dropper som genstand når en faldende blok ender indeni den. +This block will drop as an item when it is not attached to a surrounding block.=Denne blok dropper som genstand når den ikke sidder fast på en tilstødende blok. +This block will drop as an item when no collidable block is below it.=Denne blok dropper som genstand når der ikke er en bæredygtig blok under den. +This block will drop the following items when mined: @1.=Denne blok dropper følgende genstande når den udvindes: @1. +This block will drop the following when mined: @1×@2.=Denne blok dropper følgende når den udvindes: @1x@2. +This block will drop the following when mined: @1.=Denne blok dropper følgende når den udvindes: @1. +This block will drop the following when mined: @1.=Denne blok dropper følgende når den udvindes: @1. +This block will make you bounce off with an elasticity of @1%.=Denne blok får dig til at hoppe af med en elasticitet på @1%. +This block will randomly drop one of the following when mined: @1.=Denne blok dropper en vilkårlig af følgende genstande når den udvindes: @1. +This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=Denne blok dropper et vilkårligt antal op til @1 af følgende mulige ting når den udvindes: @2. +This block won't drop anything when mined.=Denne blok dropper ikke noget når den udvindes. +This is a decorational block.=Dette er en pynteblok. +This is a melee weapon which deals damage by punching.=Dette er et nærkampsvåben som giver skade ved at slå. +Maximum damage per hit:=Højeste skade per slag: +This item belongs to the @1 group.=Denne genstand hører til @1gruppen. +This item belongs to these groups: @1.=Denne genstand hører til disse grupper: @1. +This item can serve as a smelting fuel with a burning time of @1.=Denne genstand virker som brændstof til at smelte og har en brændetid på @1. +This item is primarily used for crafting other items.=Denne genstand bruges mest til at lave andre genstande. +This item points to liquids.=Denne genstand orienterer sig mod væsker. +This tool belongs to the @1 group.=Dette værktøj hører til @1gruppen +This tool belongs to these groups: @1.=Dette værktøj hører til disse grupper: +This tool can serve as a smelting fuel with a burning time of @1.=Dette værktøj virker som brændstof til at smelte og har en brændetid på @1. +This tool is capable of mining.=Dette værktøj kan bruges til udvinding. +Maximum toughness levels:=Højeste hårdhedsgrad. +This tool points to liquids.=Dette værktøj orienterer sig mod væsker. +Tools and weapons=Værktøj og våben +Unknown Node=Ukendt knudepunkt +Usage help: @1=Hjælp til brug: @1 +Walking on this block is completely silent.=Det er helt lydløst at gå på denne blok. +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.=Når du ikke anvender en genstand, bruger du din hånd som fungerer som et værktøj med sine egne egenskaber. Når du anvender en genstand som ikke er et værktøj til udvinding eller våben virker det som om du bruger din hånd. +Yes=Ja +You can not jump while standing on this block.=Du kan ikke hoppe mens du står på dene blok. +any level=hvilketsomhelst level +level 0=level 0 +level 0-@1=level 0-@1 +unknown=ukendt +Unknown item (@1)=ukendt genstand (@1) +• @1: @2= +• @1: @2 HP=• @1: @2 HP +• @1: @2, @3=• @1: @2, @3 +• Flowing range: @1=• Flydende rækkevidde: @1 +• No flowing=• Ingen strøm +• Not renewable=• Kan ikke genopfriskes +• Renewable=• Kan genopfriskes +• Viscosity: @1=• Viskositet: @1 +Itemstring: "@1"=Genstandsstreng: "@1" +Durability: @1 uses=Holdbarhed: @1 anvendelser +Durability: @1=Holdbarhed: @1 +Mining durability:=Udvindingsholdbarhed: +• @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. +Toughness level: @1=Hårdhedsgrad: @1 +This block is slippery.=Denne blok er glat. 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 5d655404d..269c97480 100644 --- a/mods/HELP/doc/doc_items/locale/doc_items.fr.tr +++ b/mods/HELP/doc/doc_items/locale/doc_items.fr.tr @@ -2,7 +2,7 @@ Using it as fuel turns it into: @1.=L'utiliser comme combustible le transforme en : @1. @1 seconds=@1 secondes # Item count times item name -%@1×@2=%@1×@ +@1×@2=@1×@2 # Itemname (25%) @1 (@2%)=@1 (@2%) # Itemname (<0.5%) @@ -96,11 +96,11 @@ This block will drop the following when mined: @1.=Ce bloc donnera les objets su This block will drop the following when mined: @1.=Ce bloc donnera les objets suivant lorsque miné : @1. This block will make you bounce off with an elasticity of @1%.=Ce bloc vous fera rebondir avec une élasticité de @1%. This block will randomly drop one of the following when mined: @1.=Ce bloc laissera tomber de manière aléatoire un des éléments suivants lorsque miné : @1. -This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=Ce bloc laissera tomber de manière aléatoire jusqu'à @1 des éléments suivants lorque miné : +This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=Ce bloc laissera tomber de manière aléatoire jusqu'à @1 des éléments suivants lorque miné : @2. This block won't drop anything when mined.=Ce bloc ne donnera rien lorsque miné. This is a decorational block.=C'est un bloc de décoration. -This is a melee weapon which deals damage by punching.=C'est une arme de mêlée qui inflige des dommages en frappant. -Maximum damage per hit:=Dommages maximaux par frappe : +This is a melee weapon which deals damage by punching.=C'est une arme de mêlée qui inflige des dégâts en frappant. +Maximum damage per hit:=Dégâts maximaux par frappe : This item belongs to the @1 group.=Cet objet appartient au groupe @1. This item belongs to these groups: @1.=Cet objet appartient aux groupes suivants : @1 This item can serve as a smelting fuel with a burning time of @1.=Cet objet peut servir de combustible pendant @1. diff --git a/mods/HELP/doc/doc_items/locale/doc_items.ja.tr b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr new file mode 100644 index 000000000..a2e1107de --- /dev/null +++ b/mods/HELP/doc/doc_items/locale/doc_items.ja.tr @@ -0,0 +1,143 @@ +# textdomain:doc_items +Using it as fuel turns it into: @1.=燃料として使うと次のように変化します:@1. +@1 seconds=@1秒 +# Item count times item name +@1×@2=@1×@2 +# Itemname (25%) +@1 (@2%)=@1 (@2%) +# Itemname (<0.5%) +@1 (<0.5%)=@1 (<0.5%) +# Itemname (ca. 25%) +@1 (ca. @2%)=@1 (ca. @2%) +# List separator (e.g. “one, two, three”) +, =、 +# 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.=透明なブロックで、基本的には何もない空間です。たいていは何かを掘った後に残ります。 +Air=空気 +Blocks=ブロック +Building another block at this block will place it inside and replace it.=このブロックのところに別のブロックを構築すると、中に入って置き換わります。 +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?=手に持って、左クリックで食べます。しかし、なぜこんなことをしたいのでしょうか? +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)=ブロックでも道具でも武器でもないアイテム(特にクラフトアイテム)の、アイテム参照 +Liquids can flow into this block and destroy it.=このブロックに液体が流れ込み、破壊されることがあります。 +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.=このブロックの採掘は、完全に無音です。 +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.=この道具でのパンチは、普段通りには機能しません:近接戦闘と採掘は不可能か、動作が異なります。 +Range: @1=範囲:@1 +# Range: () +Range: @1 (@2)=範囲:@1 (@2) +Range: 4=範囲:4 +# Rating used for digging times +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%軽減する。 +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 destroyed by any mining tool immediately.=このブロックは、どの採掘道具でも即座に壊せます。 +This block can be destroyed by any mining tool in half a second.=このブロックは、どの採掘道具でもコンマ5秒で壊せます。 +This block can be mined by any mining tool immediately.=このブロックは、どの採掘道具でも即座に掘れます。 +This block can be mined by any mining tool in half a second.=このブロックは、どの採掘道具でもコンマ5秒で掘れます。 +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.=このブロックは、毎秒@1HPのダメージを生じます。 +This block causes a damage of @1 hit points per second.=このブロックは、毎秒@1HPのダメージを生じます。 +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.=このブロックは呼吸を減少させ, 2秒毎に@1HPの窒息ダメージを与えます. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=このブロックは呼吸を減少させ, 2秒毎に@1HPの窒息ダメージを与えます. +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 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 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 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 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 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 is capable of mining.=この道具は採掘が可能です。 +Maximum toughness levels:=最大タフネスレベル: +This tool points to liquids.=この道具は液体を指します。 +Tools and weapons=道具と武器 +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.=このブロックの上に立っている間は、ジャンプできません。 +any level=任意のレベル +level 0=レベル 0 +level 0-@1=レベル 0-@1 +unknown=不明 +Unknown item (@1)=不明なアイテム (@1) +• @1: @2=・@1:@2 +• @1: @2 HP=・@1:@2 HP +• @1: @2, @3=・@1:@2, @3 +• Flowing range: @1=・流動範囲:@1 +• No flowing=・流れない +• Not renewable=・再生不能 +• Renewable=・再生可能 +• Viscosity: @1=・粘度:@1 +Itemstring: "@1"=アイテム文字列:"@1" +Durability: @1 uses=耐久度:@1回 使用 +Durability: @1=耐久度:@1 +Mining 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 is slippery.=このブロックは滑りやすいです。 diff --git a/mods/HELP/doc/doc_items/locale/doc_items.pl.tr b/mods/HELP/doc/doc_items/locale/doc_items.pl.tr new file mode 100644 index 000000000..8ff945368 --- /dev/null +++ b/mods/HELP/doc/doc_items/locale/doc_items.pl.tr @@ -0,0 +1,144 @@ +# textdomain:doc_items +Using it as fuel turns it into: @1.=Używanie tego jako paliwa zamienia to w: @1. +@1 seconds=@1 sekund(y) +# Item count times item name +@1×@2=@1×@2 +# Itemname (25%) +@1 (@2%)=@1 (@2%) +# Itemname (<0.5%) +@1 (<0.5%)=@1 (<0.5%) +# Itemname (ca. 25%) +@1 (ca. @2%)=@1 (ca. @2%) +# List separator (e.g. “one, two, three”) +, =, +# Final list separator (e.g. “One, two and three”) + and = oraz +1 second=1 sekunda +A transparent block, basically empty space. It is usually left behind after digging something.=Przezroczysty blok, praktycznie puste miejsce. Jest zwykle pozostawiany po wykopaniu czegoś. +Air=Powietrze +Blocks=Bloki +Building another block at this block will place it inside and replace it.=Postawienie innego bloku w tym bloku postawi ich wewnątrz i zastąpi go. +Building this block is completely silent.=Budowanie tego bloku jest bezgłośne. +Collidable: @1=Zderzalne: @1 +Description: @1=Opis: @1 +Falling blocks can go through this block; they destroy it when doing so.=Spadające bloki mogą przelecieć przez ten blok; niszczą go gdy tak robią. +Full punch interval: @1 s=Pełny okres uderzenia: @1 s +Hand=Ręka +Hold it in your hand, then leftclick to eat it.=Weź to do ręki, następnie kliknij lewy przycisk by je zjeść. +Hold it in your hand, then leftclick to eat it. But why would you want to do this?=Weź to do ręki, następnie kliknij lewy przycisk by je zjeść. Ale dlaczego chciałabyś to zrobić? +Item reference of all wieldable tools and weapons=Informacje na temat wszystkich narzędzi i broni możliwych do trzymania. +Item reference of blocks and other things which are capable of occupying space=Informacje na temat wszystkich bloków i innych obiektów, które są w stanie zajmować miejsce +Item reference of items which are neither blocks, tools or weapons (esp. crafting items)=Informacje na temat wszystkich rzeczy, które nie są blokami, narzędziami i broniami (głównie materiały do wytwarzania) +Liquids can flow into this block and destroy it.=Płyny mogą wpłynąć na ten blok i go zniszczyć. +Maximum stack size: @1=Maksymalny rozmiar grupy: @1 +Mining level: @1=Poziom kopania: @1 +Mining ratings:=Klasyfikacja kopania +• @1, rating @2: @3 s - @4 s=• @1, klasyfikacja @2: @3 s - @4 s +• @1, rating @2: @3 s=• @1, klasyfikacja @2: @3 s +Mining times:=Czas wykopania: +Mining this block is completely silent.=Wykopanie tego bloku jet bezgłośne. +Miscellaneous items=Różne rzeczy +No=Nie +Pointable: No=Wskazywalne: Nie +Pointable: Only by special items=Wskazywalne: Tylko przez specjalne przedmioty +Pointable: Yes=Wskazywalne: Tak +Punches with this block don't work as usual; melee combat and mining are either not possible or work differently.=Uderzanie tym blokiem nie działa tak jak zwykle; walka wręcz i kopanie są niemożliwe lub działają inaczej. +Punches with this item don't work as usual; melee combat and mining are either not possible or work differently.=Uderzanie tym przedmiotem nie działa tak jak zwykle; walka wręcz i kopanie są niemożliwe lub działają inaczej. +Punches with this tool don't work as usual; melee combat and mining are either not possible or work differently.=Uderzanie tym narzędziem nie działa tak jak zwykle; walka wręcz i kopanie są niemożliwe lub działają inaczej. +Range: @1=Zasięg: @1 +# Range: () +Range: @1 (@2)=Zasięg @1 (@2) +Range: 4=Zasięg: 4 +# Rating used for digging times +Rating @1=Klasyfikacja @1 +# @1 is minimal rating, @2 is maximum rating +Rating @1-@2=Klasyfikacja od @1 do @2 +The fall damage on this block is increased by @1%.=Obrażenia od upadku na tym bloku są zwiększone o @1%. +The fall damage on this block is reduced by @1%.=Obrażenia od upadku na tym bloku są zmniejszone o @1%. +This block allows light to propagate with a small loss of brightness, and sunlight can even go through losslessly.=Ten blok przepuszcza światło z niewielką stratą jasności, a światło słoneczne przepuszcza bezstratnie. +This block allows light to propagate with a small loss of brightness.=Ten blok przepuszcza światło z niewielką stratą jasności. +This block allows sunlight to propagate without loss in brightness.=Ten blok przepuszcza światło słoneczne bez straty jasności. +This block belongs to the @1 group.=Ten blok należy do grupy @1. +This block belongs to these groups: @1.=Ten blok należy do tych grup: @1. +This block can be climbed.=Na ten blok można się wspiąć. +This block can be destroyed by any mining tool immediately.=Ten blok może być zniszczony przez dowolne narzędzie do kopania natychmiastowo. +This block can be destroyed by any mining tool in half a second.=Ten blok może być zniszczony przez dowolne narzędzie do kopania w pół sekundy. +This block can be mined by any mining tool immediately.=Ten blok może być wykopany przez dowolne narzędzie do kopania natychmiastowo. +This block can be mined by any mining tool in half a second.=Ten blok może być wykopany przez dowolne narzędzie do kopania w pół sekundy. +This block can be mined by mining tools which match any of the following mining ratings and its toughness level.=Ten blok może zostać wykopany przez narzędzia do kopania, które pasują do którychkolwiek klasyfikacji kopania i poziomu twardości. +This block can not be destroyed by ordinary mining tools.=Ten blok nie może być zniszczony przez typowe narzędzia do kopania. +This block can not be mined by ordinary mining tools.=Ten blok nie może być wykopany przez typowe narzędzia do kopania. +This block can serve as a smelting fuel with a burning time of @1.=Ten blok może być wykorzystany jako paliwo do przetapiania z czasem palenia @1. +This block causes a damage of @1 hit point per second.=Ten blok zadaje @1 obrażenie na sekundę. +This block causes a damage of @1 hit points per second.=Ten blok zadaje @1 obrażeń na sekundę. +This block connects to blocks of the @1 group.=Ten blok łączy się do bloków z grupy @1. +This block connects to blocks of the following groups: @1.=Ten blok łączy się z blokami z następujących grup: @1. +This block connects to these blocks: @1.=Ten blok łączy się z tymi blokami: @1. +This block connects to this block: @1.=Ten blok łączy się z tym blokiem: @1. +This block decreases your breath and causes a drowning damage of @1 hit point every 2 seconds.=Ten blok zmniejsza twój tlen i zadaje @1 obrażenie co 2 sekundy. +This block decreases your breath and causes a drowning damage of @1 hit points every 2 seconds.=Ten blok zmniejsza twój tlen i zadaje @1 obrażeń co 2 sekundy. +This block is a light source with a light level of @1.=Ten blok jest źródłem światła z poziomem oświetlenia @1. +This block glows faintly with a light level of @1.=Ten blok ma poświatę o poziomie oświetlenia @1. +This block is a building block for creating various buildings.=Ten blok jest blokiem budowlanym do tworzenia różnych budowli. +This block is a liquid with these properties:=Ten blok jest płynem z tymi własnościami: +This block is affected by gravity and can fall.=Na ten blok wpływa grawitacja i może upaść. +This block is completely silent when mined or built.=Ten blok jest bezgłośny przy kopaniu i budowaniu. +This block is completely silent when walked on, mined or built.=Ten blok jest bezgłośny gdy się po nim chodzi, kopie lub buduje. +This block is destroyed when a falling block ends up inside it.=Ten blok jest zniszczony gdy upadający blok upadnie w niego. +This block negates all fall damage.=Ten blok neguje wszystkie obrażenia od upadku. +This block points to liquids.=Ten blok wskazuje na płyny. +This block will drop as an item when a falling block ends up inside it.=Ten blok wypadnie jako przedmiot gdy blok upadnie na niego. +This block will drop as an item when it is not attached to a surrounding block.=Ten blok wypadnie jako przedmiot gdy nie jest połączony z sąsiadującym blokiem. +This block will drop as an item when no collidable block is below it.=Ten blok wypadnie jako przedmiot gdy nie będzie pod nim zderzalnego bloku. +This block will drop the following items when mined: @1.=Z tego bloku wypadną następujące przedmioty po wykopaniu: @1. +This block will drop the following when mined: @1×@2.=Z tego bloku wypadną następujące rzeczy po wykopaniu: @1×@2. +This block will drop the following when mined: @1.=Z tego bloku wypadną następujące rzeczy po wykopaniu: @1. +This block will drop the following when mined: @1.=Z tego bloku wypadną następujące rzeczy po wykopaniu: @1. +This block will make you bounce off with an elasticity of @1%.=Od tego bloku odbijesz się z elastycznością @1%. +This block will randomly drop one of the following when mined: @1.=Z tego bloku wypadnie losowo jedna z następujących rzeczy po wykopaniu: @1. +This block will randomly drop up to @1 drops of the following possible drops when mined: @2.=Z tego bloku losowo wypadnie maksymalnie @1 rzeczy spośród tego zbioru: @2. +This block won't drop anything when mined.=Z tego bloku nic nie wypadnie po wykopaniu. +This is a decorational block.=Ten blok jest dekoracyjny. +This is a melee weapon which deals damage by punching.=To jest broń do walki wręcz, która zadaje obrażenia przy uderzaniu. +Maximum damage per hit:=Maksymalne obrażenia przy uderzeniu: +This item belongs to the @1 group.=Ten przedmiot należy do grupy @1. +This item belongs to these groups: @1.=Ten przedmiot należy do tych grup: @1. +This item can serve as a smelting fuel with a burning time of @1.=Ten przedmiot może być wykorzystany jako paliwo do przetapiania z czasem palenia @1. +This item is primarily used for crafting other items.=Ten przedmiot jest głównie wykorzystywany do wytwarzania innych przedmiotów. +This item points to liquids.=Ten przedmiot wskazuje na płyny. +This tool belongs to the @1 group.=To narzędzie należy do grupy @1. +This tool belongs to these groups: @1.=To narzędzie należy do tych grup: @1. +This tool can serve as a smelting fuel with a burning time of @1.=To narzędzie może być wykorzystany jako paliwo do przetapiania z czasem palenia @1. +This tool is capable of mining.=Tym narzędziem można kopać. +Maximum toughness levels:=Maksymalna poziom twardości: +This tool points to liquids.=To narzędzie wskazuje na płyny. +Tools and weapons=Narzędzia i bronie +Unknown Node=Nieznany węzeł +Usage help: @1=Sposób użycia: @1 +Walking on this block is completely silent.=Chodzenie po tym bloku jest bezgłośne. +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.=Gdy nie trzymasz żadnego przedmiotu używasz swojej ręki która działa jak narzędzie ze swoimi własnościami. Gdy trzymasz przedmiot, który nie jest narzędziem do kopania lub bronią, będzie się ono zachowywało jakby było ręką. +Yes=Tak +You can not jump while standing on this block.=Nie możesz skakać gdy stoisz na tym bloku. +any level=dowolny poziom +level 0=poziom 0 +level 0-@1=poziom 0-@1 +unknown=nieznane +Unknown item (@1)=Nieznany przedmiot (@1) +• @1: @2=• @1: @2 +• @1: @2 HP=• @1: @2 HP +• @1: @2, @3=• @1: @2, @3 +• Flowing range: @1=• Zasięg płynięcia: @1 +• No flowing=• Brak płynięcia +• Not renewable=• Nieodnawialne +• Renewable=• Odnawialne +• Viscosity: @1=• Lepkość: @1 +Itemstring: "@1"=Id przedmiotu: "@1" +Durability: @1 uses=Wytrzymałość: @1 użyć +Durability: @1=Wytrzymałość: @1 +Mining durability:=Wytrzymałość kopania: +• @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. +Toughness level: @1=Poziom twardości: @1 +This block is slippery.=Ten blok jest śliski. + diff --git a/mods/HELP/doc/doc_items/locale/template.txt b/mods/HELP/doc/doc_items/locale/template.txt index 484e40ec1..77f107863 100644 --- a/mods/HELP/doc/doc_items/locale/template.txt +++ b/mods/HELP/doc/doc_items/locale/template.txt @@ -2,7 +2,7 @@ Using it as fuel turns it into: @1.= @1 seconds= # Item count times item name -%@1×@2= +@1×@2= # Itemname (25%) @1 (@2%)= # Itemname (<0.5%) diff --git a/mods/HELP/doc/doc_items/mod.conf b/mods/HELP/doc/doc_items/mod.conf index f1c0fbbc5..65d6e8366 100644 --- a/mods/HELP/doc/doc_items/mod.conf +++ b/mods/HELP/doc/doc_items/mod.conf @@ -1,3 +1,4 @@ name = doc_items -depends = doc +author = Wuzzy description = Adds automatically generated help texts for items. +depends = doc diff --git a/mods/HELP/doc/doc_items/screenshot.png b/mods/HELP/doc/doc_items/screenshot.png deleted file mode 100644 index 8e7f5656c..000000000 Binary files a/mods/HELP/doc/doc_items/screenshot.png and /dev/null differ diff --git a/mods/HELP/doc/modpack.conf b/mods/HELP/doc/modpack.conf index 5e2f43080..f1268957d 100644 --- a/mods/HELP/doc/modpack.conf +++ b/mods/HELP/doc/modpack.conf @@ -1 +1,2 @@ name = doc +description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage. diff --git a/mods/HELP/mcl_craftguide/depends.txt b/mods/HELP/mcl_craftguide/depends.txt deleted file mode 100644 index 5bff11578..000000000 --- a/mods/HELP/mcl_craftguide/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_compass -mcl_clock -doc -sfinv? -sfinv_buttons? diff --git a/mods/HELP/mcl_craftguide/description.txt b/mods/HELP/mcl_craftguide/description.txt deleted file mode 100644 index b5c05403c..000000000 --- a/mods/HELP/mcl_craftguide/description.txt +++ /dev/null @@ -1,2 +0,0 @@ -The most comprehensive Crafting Guide -on Minetest. diff --git a/mods/HELP/mcl_craftguide/init.lua b/mods/HELP/mcl_craftguide/init.lua index eb98bcce0..5e3686047 100644 --- a/mods/HELP/mcl_craftguide/init.lua +++ b/mods/HELP/mcl_craftguide/init.lua @@ -33,7 +33,6 @@ local fmt, find, gmatch, match, sub, split, lower = local min, max, floor, ceil = math.min, math.max, math.floor, math.ceil local pairs, next, unpack = pairs, next, unpack -local vec_add, vec_mul = vector.add, vector.multiply local DEFAULT_SIZE = 10 local MIN_LIMIT, MAX_LIMIT = 10, 12 @@ -156,7 +155,7 @@ end local custom_crafts, craft_types = {}, {} function mcl_craftguide.register_craft_type(name, def) - local func = "mcl_craftguide.register_craft_guide(): " + local func = "mcl_craftguide.register_craft_type(): " assert(name, func .. "'name' field missing") assert(def.description, func .. "'description' field missing") assert(def.icon, func .. "'icon' field missing") @@ -410,7 +409,7 @@ local function get_tooltip(item, groups, cooktime, burntime) local tooltip if groups then - local gcol = "#FFAAFF" + local gcol = mcl_colors.LIGHT_PURPLE if #groups == 1 then local g = group_names[groups[1]] local groupstr @@ -418,9 +417,9 @@ local function get_tooltip(item, groups, cooktime, burntime) -- and just print the normal item name without special formatting if groups[1] == "compass" or groups[1] == "clock" then groupstr = reg_items[item].description - elseif group_names[groups[1]] then + elseif g then -- Use the special group name string - groupstr = minetest.colorize(gcol, group_names[groups[1]]) + groupstr = minetest.colorize(gcol, g) else --[[ Fallback: Generic group explanation: This always works, but the internally used group name (which @@ -446,12 +445,12 @@ local function get_tooltip(item, groups, cooktime, burntime) if not groups and cooktime then tooltip = tooltip .. "\n" .. - S("Cooking time: @1", colorize("yellow", cooktime)) + S("Cooking time: @1", colorize(mcl_colors.YELLOW, cooktime)) end if not groups and burntime then tooltip = tooltip .. "\n" .. - S("Burning time: @1", colorize("yellow", burntime)) + S("Burning time: @1", colorize(mcl_colors.YELLOW, burntime)) end return fmt(FMT.tooltip, item, ESC(tooltip)) @@ -546,10 +545,10 @@ local function get_recipe_fs(data, iY) if custom_recipe or shapeless or recipe.type == "cooking" then local icon = custom_recipe and custom_recipe.icon or - shapeless and "shapeless" or "furnace" + shapeless and "shapeless" or "furnace" if recipe.type == "cooking" then - icon = "default_furnace_front_active.png" + icon = "craftguide_furnace.png" elseif not custom_recipe then icon = fmt("craftguide_%s.png", icon) end @@ -639,7 +638,7 @@ local function make_formspec(name) fs[#fs + 1] = "background9[1,1;1,1;mcl_base_textures_background9.png;true;7]" fs[#fs + 1] = fmt([[ tooltip[size_inc;%s] - tooltip[size_dec;%s] ]], + tooltip[size_dec;%s] ]], ESC(S("Increase window size")), ESC(S("Decrease window size"))) @@ -657,9 +656,9 @@ local function make_formspec(name) ]] fs[#fs + 1] = fmt([[ tooltip[search;%s] - tooltip[clear;%s] - tooltip[prev;%s] - tooltip[next;%s] ]], + tooltip[clear;%s] + tooltip[prev;%s] + tooltip[next;%s] ]], ESC(S("Search")), ESC(S("Reset")), ESC(S("Previous page")), @@ -727,7 +726,7 @@ local function make_formspec(name) return concat(fs) end -local show_fs = function(player, name) +local function show_fs(player, name) if sfinv_only then sfinv.set_player_inventory_formspec(player) else @@ -1001,7 +1000,7 @@ else end end) - local function on_use(user) + --[[local function on_use(user) local name = user:get_player_name() if next(recipe_filters) then @@ -1011,7 +1010,7 @@ else end show_formspec(name, "mcl_craftguide", make_formspec(name)) - end + end]] end @@ -1098,7 +1097,6 @@ if progressive_mode then local name = player:get_player_name() init_data(name) local meta = player:get_meta() - local name = player:get_player_name() local data = player_data[name] data.inv_items = deserialize(meta:get_string("inv_items")) or {} @@ -1144,7 +1142,7 @@ else end function mcl_craftguide.show(name) - local player = minetest.get_player_by_name(name) + local player = get_player_by_name(name) if next(recipe_filters) then local data = player_data[name] data.items_raw = get_filtered_items(player) diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.dk.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.dk.tr new file mode 100644 index 000000000..9fe6a6ac8 --- /dev/null +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.dk.tr @@ -0,0 +1,37 @@ +# textdomain: craftguide +Any shulker box=Hvilkensomhelst shulkerboks +Any wool=Hvilkensomhelst uld +Any wood planks=Hvilkensomhelst træplanker +Any wood=Hvilkensomhelst træ +Any sand=Hvilkensomhelst sand +Any normal sandstone=Hvilkensomhelst normal sandsten +Any red sandstone=Hvilkensomhelst rød sandsten +Any carpet=HVilketsomhelst tæppe +Any dye=Hvilkensomhelst farvestof +Any water bucket=Hvilkensomhelst vandpand +Any flower=Hvilkensomhelst blomst +Any mushroom=Hvilkensomhelst svamp +Any wooden slab=Hvilkensomhelst træplade +Any wooden stairs=Hvilkensomhelst trætrappe +Any coal=Hvilketsomhelst kul +Any kind of quartz block=Hvilkensomhelst quartzblok +Any kind of purpur block=Hvilkensomhelst pupurblok +Any stone bricks=Hvilkensomhelst mursten af sten +Any stick=Hvilkensomhelst pind +Any item belonging to the @1 group=Hvilkensomhelst genstant i @1gruppen +Any item belonging to the groups: @1=Hvilkensomhelst genstand som hører til grupperne: @1 +Search=Søg +Reset=Nulstil +Previous page=Forrige side +Next page=Næste side +Usage @1 of @2=Brug @1 af @2 +Recipe @1 of @2=Opskrift @1 af @2 +Burning time: @1=Brændetid: @1 +Cooking time: @1=Tilberedelsestid: @1 +Recipe is too big to be displayed (@1×@2)=Formen er for stor til at blive vist (@1x@2) +Shapeless=Uformelig +Cooking=Madlavning +Increase window size=Øg vinduesstørrelsen +Decrease window size=Mindsk vinduesstørrelsen +No item to show=Ingen genstande at vise +Collect items to reveal more recipes=Saml genstande for at afsløre flere opskrifter diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr new file mode 100644 index 000000000..213a68f61 --- /dev/null +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.ja.tr @@ -0,0 +1,37 @@ +# textdomain: craftguide +Any shulker box=シュルカーボックス +Any wool=羊毛 +Any wood planks=板材 +Any wood=木 +Any sand=砂 +Any normal sandstone=普通の砂岩 +Any red sandstone=赤い砂岩 +Any carpet=カーペット +Any dye=染料 +Any water bucket=水入りバケツ +Any flower=花 +Any mushroom=キノコ +Any wooden slab=木製のスラブ +Any wooden stairs=木製の階段 +Any coal=石炭 +Any kind of quartz block=クォーツブロック +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 +Search=検索 +Reset=リセット +Previous page=前ページ +Next page=次ページ +Usage @1 of @2=使用方法 @1/@2 +Recipe @1 of @2=レシピ @1/@2 +Burning time: @1=燃焼時間:@1 +Cooking time: @1=調理時間:@1 +Recipe is too big to be displayed (@1×@2)=レシピを表示するには大きすぎる (@1×@2) +Shapeless=不定形 +Cooking=調理 +Increase window size=ウィンドウサイズ拡大 +Decrease window size=ウィンドウサイズ縮小 +No item to show=表示するアイテムなし +Collect items to reveal more recipes=アイテムを集めて、より多くのレシピを明かす diff --git a/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pl.tr b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pl.tr new file mode 100644 index 000000000..064fd90d3 --- /dev/null +++ b/mods/HELP/mcl_craftguide/locale/mcl_craftguide.pl.tr @@ -0,0 +1,38 @@ +# textdomain: mcl_craftguide +Any shulker box=Dowolna skrzynia shulkerowa +Any wool=Dowolna wełna +Any wood planks=Dowolne deski +Any wood=Dowolne drewno +Any sand=Dowolny piasek +Any normal sandstone=Dowolny zwykły piaskowiec +Any red sandstone=Dowolny czerwony piaskowiec +Any carpet=Dowolny dywan +Any dye=Dowolna farba +Any water bucket=Dowolne wiadro wody +Any flower=Dowolny kwiat +Any mushroom=Dowolny grzyb +Any wooden slab=Dowolny drewniana płyta +Any wooden stairs=Dowolne drewniane schody +Any coal=Dowolny węgiel +Any kind of quartz block=Dowolny typ bloku kwarcu +Any kind of purpur block=Dowolny typ bloku purpury +Any stone bricks=Dowolne kamienne cegły +Any stick=Dowolny patyk +Any item belonging to the @1 group=Dowolny przedmiot z grupy @1 +Any item belonging to the groups: @1=Dowolny przedmiot należący do grup: @1 +Search=Wyszukaj +Reset=Zresetuj +Previous page=Poprzednia strona +Next page=Następna strona +Usage @1 of @2=Użycie @1 z @2 +Recipe @1 of @2=Receptura @1 z @2 +Burning time: @1=Czas wypalenia: @1 +Cooking time: @1=Czas pieczenia: @1 +Recipe is too big to be displayed (@1×@2)=Receptura jest zbyt długa do wyświetlenia (@1×@2) +Shapeless=Bezkształtne +Cooking=Pieczenie +Increase window size=Zwiększ rozmiar okna +Decrease window size=Zmniejsz rozmiar okna +No item to show=Brak przedmiotów do pokazania +Collect items to reveal more recipes=Zbierz przedmioty by odkryć więcej receptur + diff --git a/mods/HELP/mcl_craftguide/mod.conf b/mods/HELP/mcl_craftguide/mod.conf index d51c45413..ce99c0e32 100644 --- a/mods/HELP/mcl_craftguide/mod.conf +++ b/mods/HELP/mcl_craftguide/mod.conf @@ -1 +1,5 @@ name = mcl_craftguide +author = kilbith +description = The most comprehensive Crafting Guide on Minetest. +depends = mcl_core, mcl_compass, mcl_clock, doc, mcl_colors +optional_depends = sfinv, sfinv_buttons diff --git a/mods/HELP/mcl_craftguide/screenshot.png b/mods/HELP/mcl_craftguide/screenshot.png deleted file mode 100644 index ebb8e4d76..000000000 Binary files a/mods/HELP/mcl_craftguide/screenshot.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_arrow.png b/mods/HELP/mcl_craftguide/textures/craftguide_arrow.png deleted file mode 100644 index cde70b1ce..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_arrow.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_clear_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_clear_icon.png deleted file mode 100644 index 9244264ad..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_clear_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_next_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_next_icon.png deleted file mode 100644 index 82cf3d361..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_next_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_prev_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_prev_icon.png deleted file mode 100644 index b26cd157f..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_prev_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_search_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_search_icon.png deleted file mode 100644 index aace8044a..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_search_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_zoomin_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_zoomin_icon.png deleted file mode 100644 index 5b8ecc2cb..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_zoomin_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_zoomout_icon.png b/mods/HELP/mcl_craftguide/textures/craftguide_zoomout_icon.png deleted file mode 100644 index 7db747fda..000000000 Binary files a/mods/HELP/mcl_craftguide/textures/craftguide_zoomout_icon.png and /dev/null differ diff --git a/mods/HELP/mcl_doc/depends.txt b/mods/HELP/mcl_doc/depends.txt deleted file mode 100644 index 93440a299..000000000 --- a/mods/HELP/mcl_doc/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -doc -doc_items diff --git a/mods/HELP/mcl_doc/description.txt b/mods/HELP/mcl_doc/description.txt deleted file mode 100644 index 4ae29f507..000000000 --- a/mods/HELP/mcl_doc/description.txt +++ /dev/null @@ -1 +0,0 @@ -This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2. diff --git a/mods/HELP/mcl_doc/init.lua b/mods/HELP/mcl_doc/init.lua index 6948aed04..4ba387e12 100644 --- a/mods/HELP/mcl_doc/init.lua +++ b/mods/HELP/mcl_doc/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_doc") +local S = minetest.get_translator(minetest.get_current_modname()) -- Disable built-in factoids; it is planned to add custom ones as replacements doc.sub.items.disable_core_factoid("node_mining") @@ -31,6 +31,14 @@ doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) return "" end) +-- usable by shovels +doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) + if def.groups.path_creation_possible then + return S("This block can be turned into grass path with a shovel.") + end + return "" +end) + -- soil doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) local datastring = "" @@ -50,8 +58,8 @@ end) doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) local formstring = "" - if def.groups.leafdecay ~= nil then - if def.drop ~= "" and def.drop ~= nil and def.drop ~= itemstring then + if def.groups.leafdecay then + if def.drop ~= "" and def.drop and def.drop ~= itemstring then formstring = S("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.", def.groups.leafdecay) else formstring = S("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.", def.groups.leafdecay) @@ -62,7 +70,6 @@ end) -- nodes which have flower placement rules doc.sub.items.register_factoid("nodes", "groups", function(itemstring, def) - local datastring = "" if def.groups.place_flowerlike == 1 then return S("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.") elseif def.groups.place_flowerlike == 2 then @@ -130,7 +137,7 @@ end) -- Armor doc.sub.items.register_factoid(nil, "use", function(itemstring, def) - local def = minetest.registered_items[itemstring] + --local def = minetest.registered_items[itemstring] local s = "" local head = minetest.get_item_group(itemstring, "armor_head") local torso = minetest.get_item_group(itemstring, "armor_torso") @@ -155,7 +162,7 @@ doc.sub.items.register_factoid(nil, "use", function(itemstring, def) return s end) doc.sub.items.register_factoid(nil, "groups", function(itemstring, def) - local def = minetest.registered_items[itemstring] + --local def = minetest.registered_items[itemstring] local s = "" local use = minetest.get_item_group(itemstring, "mcl_armor_uses") local pts = minetest.get_item_group(itemstring, "mcl_armor_points") @@ -173,7 +180,6 @@ end) doc.sub.items.register_factoid(nil, "groups", function(itemstring, def) if def._repair_material then local mdef = minetest.registered_items[def._repair_material] - local desc if mdef and mdef.description and mdef.description ~= "" then return S("This item can be repaired at an anvil with: @1.", mdef.description) elseif def._repair_material == "group:wood" then @@ -291,7 +297,7 @@ doc.sub.items.register_factoid("nodes", "drops", function(itemstring, def) local itemname = item:get_name() local itemcount = item:get_count() local idef = minetest.registered_items[itemname] - local text = "" + local text if idef.description and idef.description ~= "" then text = idef.description else @@ -401,7 +407,7 @@ doc.sub.items.register_factoid("tools", "misc", function(itemstring, def) local formstring = "" -- Weapon data local damage_groups = tool_capabilities.damage_groups - if damage_groups ~= nil and damage_groups.fleshy ~= nil then + if damage_groups and damage_groups.fleshy then formstring = formstring .. S("This is a melee weapon which deals damage by punching.") .. "\n" -- Damage groups @@ -410,7 +416,7 @@ doc.sub.items.register_factoid("tools", "misc", function(itemstring, def) -- Full punch interval local punch = 1.0 - if tool_capabilities.full_punch_interval ~= nil then + if tool_capabilities.full_punch_interval then punch = tool_capabilities.full_punch_interval end formstring = formstring .. S("Full punch interval: @1 s", string.format("%.1f", punch)) diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr b/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr new file mode 100644 index 000000000..7dfc40fdf --- /dev/null +++ b/mods/HELP/mcl_doc/locale/mcl_doc.dk.tr @@ -0,0 +1,79 @@ +# textdomain: mcl_doc +Water can flow into this block and cause it to drop as an item.=Der kan flyde vandt i denne blok, hvilket får den til at droppe som en genstand. +This block can be turned into dirt with a hoe.=Denne blok kan omdannes til jord med en hakke. +This block can be turned into farmland with a hoe.=Denne blok kan omdannes til landbrugsjord med en hakke. +This block acts as a soil for all saplings.=Denne blok virker som jord for alle spirer. +This block acts as a soil for some saplings.=Denne blok virker som jord for nogle spirer. +Sugar canes will grow on this block.=Sukkerrør gror på denne blok. +Nether wart will grow on this block.=Nethervorder gror på denne blok. +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.=Denne blok forgår hurtigt når der ikke er træblokke af nogen art af træblokke indenfor en afstand af @1. Når den forgår, forsvinder den, og dropper måske et af sine normale drops. Blokken forgår ikke når den er blevet placeret af en spiller. +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.=Denne blok forgår hurtigt og forsvinder når der ikke er nogen art af træblokke indenfor en afstand af @1. Blokken forgår ikke når den er blevet placeret af en spiller. +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.=Denne plante kan kun gro på græsblokke eller jord. For at overleve, har den brug for direkte udsyn til himlen, eller et lysniveau på 8 eller derover. +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.=Denne plante kan gro på græsblokke, podsol, jord eller grov jord. For at overleve, har den brug for direkte udsyn til himlen, eller et lysniveau på 8 eller derover. +This block is flammable.=Denne blok er brændfarlig. +This block destroys any item it touches.=Denne blok ødelægger enhver genstand den berør. +To eat it, wield it, then rightclick.=For at spise det skal du bære det og højre-klikke. +You can eat this even when your hunger bar is full.=Du kan spise dette selvom din sultbjælke er fuld. +You cannot eat this when your hunger bar is full.=Du kan ikke spise dette når din sultbjælke er fuld. +To drink it, wield it, then rightclick.=For at drikke det skal du bære det og højre-klikke. +You cannot drink this when your hunger bar is full.=Du kan ikke drikke dette når din sultbjælke er fuld. +To consume it, wield it, then rightclick.=For at indtage det skal du bære det og højre-klikke. +You cannot consume this when your hunger bar is full.=Du kan ikke indtage dette når din sultbjælke er fuld. +You have to wait for about 2 seconds before you can eat or drink again.=Du er nødt til at vente omkring 2 sekunder før du kan drikke eller spise igen. +Hunger points restored: @1=Sultpoint genvundet: @1 +Saturation points restored: @1%.1f=Mæthedspoint genvundet: @1%.1f +This item can be repaired at an anvil with: @1.=Denne genstand kan repareres ved en ambolt med: @1. +This item can be repaired at an anvil with any wooden planks.=Denne genstand kan repareres ved en ambolt med hvilkensomhelst træplanke. +This item can be repaired at an anvil with any item in the “@1” group.=Denne genstand kan repareres ved en ambolt med hvilkensomhelst genstand i "@1"gruppen +This item cannot be renamed at an anvil.=Denne genstand kan ikke omdøbes ved en ambolt. +This block crushes any block it falls into.=Denn blok knuser enhver blok den falder ind i. +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.=Denne blok falder dybere end 1 blok, og giver skade til enhver spiller den rammer. Skaden givet er Bx2-2 ned B @= antal faldne blokke. +Diamond Pickaxe=Minehakke i diamant +Iron Pickaxe=Jernhakke +Stone Pickaxe=Stenhakke +Golden Pickaxe=Guldhakke +Wooden Pickaxe=Træhakke +Diamond Axe=Diamantøkse +Iron Axe=Jernøkse +Stone Axe=Stenøkse +Golden Axe=Guldøkse +Wooden Axe=Træøkse +Diamond Shovel=Diamantskovl +Iron Shovel=Jernskovl +Stone Shovel=Stenskovl +Golden Shovel=Guldskovl +Wooden Shovel=Træskovl +This block can be mined by any tool instantly.=Denne blok kan udvindes momentant med ethvert værktøj. +This block can be mined by:=Denne blok kan udvindes med: +Hardness: ∞= Hårdhed:∞ +Hardness: @1=Hårdhed @1 +This block will not be destroyed by TNT explosions.=Denne blok ødelægges ikke af TNT-eksplosioner. +This block drops itself when mined by shears.=Denne blok dropper sig selv når den udvindes med sakse. +@1×@2=@1x@2 +This blocks drops the following when mined by shears: @1=Denne blok dropper følgende når den udvindes med sakse: @1 +, =, +• Shears=• Sakse +• Sword=• Sværd +• Hand=• Hånd +This is a melee weapon which deals damage by punching.=Dette er et nærkampsvåben som giver skade ved at slå. +Maximum damage: @1 HP=Højeste skade: @1 +Full punch interval: @1 s=Helt interval mellem slag: @1 s +This tool is capable of mining.=Dette værktøj kan bruges til udvinding. +Mining speed: @1=Udvindingshastighed: @1 +Painfully slow=Pinagtig langsom +Very slow=Meget langsom +Slow=Langsom +Fast=Hurtig +Very fast=Meget hurtig +Extremely fast=Ekstremt hurtig +Instantaneous=Momentan +@1 uses=@1 anvendelser +Unlimited uses=Uendelige anvendelser +Block breaking strength: @1=Blokkens brudstyrke: @1 +Mining durability: @1=Udvindingsholdbarhed: @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. +It can be worn on the torso.=Den kan bæres på kroppen. +It can be worn on the legs.=De kan bæres på benene. +It can be worn on the feet.=De kan bæres på fødderne. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr b/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr index 90e0c9b0e..529615821 100644 --- a/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr +++ b/mods/HELP/mcl_doc/locale/mcl_doc.fr.tr @@ -2,6 +2,7 @@ Water can flow into this block and cause it to drop as an item.=L'eau peut s'écouler dans ce bloc et provoquer sa chute en tant qu'élément. This block can be turned into dirt with a hoe.=Ce bloc peut être transformé en terre avec une houe. This block can be turned into farmland with a hoe.=Ce bloc peut être transformé en terres agricoles avec une houe. +This block can be turned into grass path with a shovel.=Ce bloc peut être transformé en chemin d'herbe avec une pelle. 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. @@ -28,38 +29,38 @@ This item can be repaired at an anvil with any item in the “@1” group.=Cet a This item cannot be renamed at an anvil.=Cet objet ne peut pas être renommé sur une enclume. This block crushes any block it falls into.=Ce bloc écrase tout bloc dans lequel il tombe. 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.=Lorsque ce bloc tombe plus profondément que 1 bloc, il inflige des dégâts à tout joueur qu'il frappe. Les dégâts infligés sont B×2−2 points de vie avec B @= nombre de blocs tombés. Les dégâts ne peuvent jamais dépasser 40 PV. -Diamond Pickaxe=Pioche en Diamant -Iron Pickaxe=Pioche en Fer -Stone Pickaxe=Pioche en Pierre -Golden Pickaxe=Pioche en Or -Wooden Pickaxe=Pioche en Bois -Diamond Axe=Hache en Diamant -Iron Axe=Hache en Fer -Stone Axe=Hache en Pierre -Golden Axe=Hache en Or -Wooden Axe=Hache en Bois -Diamond Shovel=Pelle en Diamant -Iron Shovel=Pelle en Fer -Stone Shovel=Pelle en Pierre -Golden Shovel=Pelle en Or -Wooden Shovel=Pelle de Bois +Diamond Pickaxe=Pioche en diamant +Iron Pickaxe=Pioche en fer +Stone Pickaxe=Pioche en pierre +Golden Pickaxe=Pioche en or +Wooden Pickaxe=Pioche en bois +Diamond Axe=Hache en diamant +Iron Axe=Hache en fer +Stone Axe=Hache en pierre +Golden Axe=Hache en or +Wooden Axe=Hache en bois +Diamond Shovel=Pelle en diamant +Iron Shovel=Pelle en fer +Stone Shovel=Pelle en pierre +Golden Shovel=Pelle en or +Wooden Shovel=Pelle en bois This block can be mined by any tool instantly.=Ce bloc peut être miné par n'importe quel outil instantanément. This block can be mined by:=Ce bloc peut être miné par: -Hardness: ∞=Dureté: ∞ -Hardness: @1=Dureté: @1 +Hardness: ∞=Dureté : ∞ +Hardness: @1=Dureté : @1 This block will not be destroyed by TNT explosions.=Ce bloc ne sera pas détruit par les explosions de TNT. This block drops itself when mined by shears.=Ce bloc se laisse tomber lorsqu'il est exploité par cisaille. @1×@2=@1×@2 -This blocks drops the following when mined by shears: @1=Ce bloc laisse tomber les choses suivantes lorsqu'il est exploité par cisaille: +This blocks drops the following when mined by shears: @1=Ce bloc laisse tomber les choses suivantes lorsqu'il est exploité par cisaille : @1 , =, • Shears=• Cisailles • Sword=• Epées • Hand=• Mains This is a melee weapon which deals damage by punching.=Il s'agit d'une arme de mêlée qui inflige des dégâts en frappant. -Maximum damage: @1 HP=Dégâts maximum: @1 -Full punch interval: @1 s=Interval de coup: @1 s +Maximum damage: @1 HP=Dégâts maximum : @1 PV +Full punch interval: @1 s=Interval de coup : @1 s This tool is capable of mining.=Cet outil est capable d'exploiter. -Mining speed: @1=Vitesse de minage: @1 +Mining speed: @1=Vitesse de minage : @1 Painfully slow=Péniblement lent Very slow=Très lent Slow=Lent @@ -69,10 +70,10 @@ Extremely fast=Extrêmenent rapide 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 -Armor points: @1=Point d'armure: @1 -Armor durability: @1=Durabilité de l'armure: @1 +Block breaking strength: @1=Résistance de rupture de bloc : @1 +Mining durability: @1=Durabilité de minage : @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. It can be worn on the torso.=Il peut être porté au torse. It can be worn on the legs.=Il peut être porté aux jambes. diff --git a/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr new file mode 100644 index 000000000..0cef853c8 --- /dev/null +++ b/mods/HELP/mcl_doc/locale/mcl_doc.ja.tr @@ -0,0 +1,79 @@ +# 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 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の距離内にどの種の木材ブロックもないとき、たちまち腐敗します。 腐敗すると消滅し、通常のドロップを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.=飲むには、手に持ってから右クリックします。 +You cannot drink this when your hunger bar is full.=満腹ゲージが満タンなら、これは飲めません。 +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.1f +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 -2HP と B @=落ちたブロック数。ダメージは40HP以上になることはありません。 +Diamond Pickaxe=ダイヤモンドのツルハシ +Iron Pickaxe=鉄のツルハシ +Stone Pickaxe=石のツルハシ +Golden Pickaxe=金のツルハシ +Wooden Pickaxe=木製のツルハシ +Diamond Axe=ダイヤモンドの斧 +Iron Axe=鉄の斧 +Stone Axe=石の斧 +Golden Axe=金の斧 +Wooden Axe=木製の斧 +Diamond Shovel=ダイヤモンドのシャベル +Iron Shovel=鉄のシャベル +Stone Shovel=石のシャベル +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.=このブロックは、TNTの爆発では壊れません。 +This block drops itself when mined by shears.=このブロックはハサミで掘ると、それ自体をドロップします。 +@1×@2=@1×@2 +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秒 +This tool is capable of mining.=この道具は採掘が可能です。 +Mining speed: @1=採掘速度:@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 +It can be worn on the head.=頭に装着することもできます。 +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/mcl_doc.pl.tr b/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr new file mode 100644 index 000000000..c451c8c39 --- /dev/null +++ b/mods/HELP/mcl_doc/locale/mcl_doc.pl.tr @@ -0,0 +1,80 @@ +# textdomain: mcl_doc +Water can flow into this block and cause it to drop as an item.=Woda może wpłynąć na ten blok i sprawić, że on wypadnie. +This block can be turned into dirt with a hoe.=Ten blok może być zamieniony w ziemię za pomocą motyki. +This block can be turned into farmland with a hoe.=Ten blok może być zamieniony w ziemię uprawną za pomocą motyki. +This block acts as a soil for all saplings.=Ten blok może być glebą dla wszystkich sadzonek. +This block acts as a soil for some saplings.=Ten blok może być glebą dla niektórych sadzonek. +Sugar canes will grow on this block.=Trzcina cukrowa będzie rosnąć na tym bloku. +Nether wart will grow on this block.=Netherowa brodawka będzie rosnąć na tym bloku. +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.=Ten blok szybko zanika gdy w odległości @1 nie ma żadnego bloku drewna dowolnego rodzaju. Gdy zanika może wyrzucić z siebie jeden z przedmiotów typowo wyrzucanych. +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.=Ten blok szybko zanika gdy w odległości @1 nie ma żadnego bloku drewna dowolnego rodzaju. Ten blok nie zanika gdy został postawiony przez gracza. +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.=Ta roślina może rosnąć tylko na blokach trawy i ziemi. Aby przetrwać musi mieć nieblokowany dostęp do nieba powyżej lub być oświetlana światłem o poziomie 8 lub wyższym. +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.=Ta roślina może rosnąć na blokach trawy, bielicy, ziemi i twardej ziemi. Aby przetrwać musi mieć nieblokowany dostęp do nieba powyżej lub być oświetlana światłem o poziomie 8 lub wyższym. +This block is flammable.=Ten blok jest łatwopalny. +This block destroys any item it touches.=Ten blok niszczy się gdy dowolny przedmiot go dotyka. +To eat it, wield it, then rightclick.=Aby to zjeść, weź to, następnie kliknij prawy przycisk myszy. +You can eat this even when your hunger bar is full.=Możesz to zjeść nawet gdy twój pasek nasycenia jest pełny. +You cannot eat this when your hunger bar is full.=Nie możesz tego jeść gdy twój pasek nasycenia jest pełny. +To drink it, wield it, then rightclick.=Aby to wypić, weź to, następnie kliknij prawy przycisk myszy. +You cannot drink this when your hunger bar is full.=Nie możesz tego pić gdy twój pasek nasycenia jest pełny. +To consume it, wield it, then rightclick.=Aby to skonsumować, weź to, następnie kliknij prawy przycisk myszy. +You cannot consume this when your hunger bar is full.=Nie możesz tego skonsumować gdy twój pasek nasycenia jest pełny. +You have to wait for about 2 seconds before you can eat or drink again.=Musisz poczekać przez 2 sekundy zanim znów będziesz mogła jeść lub pić. +Hunger points restored: @1=Przywrócone punkty głodu: @1 +Saturation points restored: @1%.1f=Przywrócone punkty nasycenia: @1%.1f +This item can be repaired at an anvil with: @1.=Ten przedmiot może być naprawiony przy kowadle przy użyciu: @1. +This item can be repaired at an anvil with any wooden planks.=Ten przedmiot może być naprawiony przy kowadle przy użyciu desek. +This item can be repaired at an anvil with any item in the “@1” group.=Ten przedmiot może być naprawiony przy kowadle przy użyciu dowolnego przedmiotu z grupy "@1". +This item cannot be renamed at an anvil.=Ten przedmiot nie może być przemianowany przy kowadle. +This block crushes any block it falls into.=Ten blok rozbija dowolny blok na który spadnie. +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.=Gdy ten blok spada więcej niż o 1 blok, zadaje on obrażenia dowolnemu graczowi którego uderzy. Zadaje on B×2−2 punktów obrażeń, gdzie B @= liczba bloków o który spadł. +Diamond Pickaxe=Diamentowy kilof +Iron Pickaxe=Żelazny kilof +Stone Pickaxe=Kamienny kilof +Golden Pickaxe=Złoty kilof +Wooden Pickaxe=Drewniany kilof +Diamond Axe=Diamentowa siekiera +Iron Axe=Żelazna siekiera +Stone Axe=Kamienna siekiera +Golden Axe=Złota siekiera +Wooden Axe=Drewniana siekiera +Diamond Shovel=Diamentowa łopata +Iron Shovel=Żelazna łopata +Stone Shovel=Kamienna łopata +Golden Shovel=Złota łopata +Wooden Shovel=Drewniana łopata +This block can be mined by any tool instantly.=Ten blok może zostać wykopany dowolnym narzędziem natychmiastowo. +This block can be mined by:=Ten blok może być wykopany przy użyciu: +Hardness: ∞=Twardość: ∞ +Hardness: @1=Twardość: @1 +This block will not be destroyed by TNT explosions.=Ten blok nie będzie zniszczony przez eksplozję trotylu. +This block drops itself when mined by shears.=Ten blok wyrzuca siebie gdy wykopany nożycami. +@1×@2=@1×@2 +This blocks drops the following when mined by shears: @1=Ten blok wyrzuca siebie gdy wykopany nożycami. +, =, +• Shears=• Nożyce +• Sword=• Miecz +• Hand=• Ręka +This is a melee weapon which deals damage by punching.=To jest broń ręczna która zadaje obrażenia przy uderzenia. +Maximum damage: @1 HP=Maksymalne obrażenia: @1 HP +Full punch interval: @1 s=Pełny okres uderzenia: @1 s +This tool is capable of mining.=To narzędzie jest w stanie kopać. +Mining speed: @1=Szybkość kopania: @1 +Painfully slow=Boleśnie powolne +Very slow=Bardzo wolne +Slow=Wolne +Fast=Szybkie +Very fast=Bardzo szybkie +Extremely fast=Ekstremalnie szybkie +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 +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. +It can be worn on the torso.=Może być noszone na piersi. +It can be worn on the legs.=Może być noszony na nogach. +It can be worn on the feet.=Może być noszony na stopach. + diff --git a/mods/HELP/mcl_doc/locale/template.txt b/mods/HELP/mcl_doc/locale/template.txt index de652f05e..ec825644c 100644 --- a/mods/HELP/mcl_doc/locale/template.txt +++ b/mods/HELP/mcl_doc/locale/template.txt @@ -2,6 +2,7 @@ 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 farmland with a hoe.= +This block can be turned into grass path with a shovel.= This block acts as a soil for all saplings.= This block acts as a soil for some saplings.= Sugar canes will grow on this block.= diff --git a/mods/HELP/mcl_doc/mod.conf b/mods/HELP/mcl_doc/mod.conf index f5c27d080..d939761d5 100644 --- a/mods/HELP/mcl_doc/mod.conf +++ b/mods/HELP/mcl_doc/mod.conf @@ -1 +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. +depends = doc, doc_items diff --git a/mods/HELP/mcl_doc_basics/init.lua b/mods/HELP/mcl_doc_basics/init.lua index e700e82bd..45ce75877 100644 --- a/mods/HELP/mcl_doc_basics/init.lua +++ b/mods/HELP/mcl_doc_basics/init.lua @@ -2,7 +2,7 @@ Basic help for MCL2. Fork of doc_basics ]] -local S = minetest.get_translator("mcl_doc_basics") +local S = minetest.get_translator(minetest.get_current_modname()) doc.add_category("basics", { 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 d6edcfb64..6825e4191 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 @@ -18,7 +18,7 @@ Basic controls:=Contrôles de base: • [I] for the inventory=• [I] pour l'inventaire • First items in inventory appear in hotbar below=• Les premiers éléments de l'inventaire apparaissent dans la barre de raccourci ci-dessous • Lowest row in inventory appears in hotbar below=• La ligne la plus basse de l'inventaire apparaît dans la barre d'outils ci-dessous -• [Esc] to close this window=• [Esc] pour fermer cette fenêtre +• [Esc] to close this window=• [Échap] pour fermer cette fenêtre How to play:=Comment jouer: • Punch a tree trunk until it breaks and collect wood=• Frappez un tronc d'arbre jusqu'à ce qu'il se brise et ramassez du bois • Place the wood into the 2×2 grid (your “crafting grid”) in your inventory menu and craft 4 wood planks=• Placez le bois dans la grille 2×2 (votre "grille d'établi") dans votre menu d'inventaire et fabriquez 4 planches de bois @@ -39,75 +39,75 @@ Minetest is usually bundled with a simple default game, named “Minetest Game Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly.=Minetest ainsi que Minetest Game sont tous deux inachevés pour le moment, alors veuillez nous pardonner quand tout ne fonctionne pas parfaitement. Sneaking=Se faufiler Sneaking makes you walk slower and prevents you from falling off the edge of a block.=Se faufiler vous fait marcher plus lentement et vous empêche de tomber du bord d'un bloc. -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!=Pour vous faufiler, maintenez enfoncée la touche furtive (par défaut: [Shift]). Lorsque vous le relâchez, vous arrêtez de vous faufiler. Attention: lorsque vous relâchez la touche furtive sur un rebord, vous risquez de tomber! -• Sneak: [Shift]=• Se faufiler: [Shift] +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!=Pour vous faufiler, maintenez enfoncée la touche furtive (par défaut : [Shift]). Lorsque vous la relâchez, vous arrêtez de vous faufiler. Attention : lorsque vous relâchez la touche furtive sur un rebord, vous risquez de tomber ! +• Sneak: [Shift]=• Se faufiler : [Shift] Sneaking only works when you stand on solid ground, are not in a liquid and don't climb.=Se faufiler ne fonctionne que lorsque vous vous tenez sur un sol solide, pas dans un liquide et ne grimpez pas. If you jump while holding the sneak key, you also jump slightly higher than usual.=Si vous sautez tout en maintenant la touche furtive, vous sautez également légèrement plus haut que d'habitude. Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges.=Le faufilement peut être désactivé par les mods. Dans ce cas, vous marchez toujours plus lentement en vous faufilant, mais vous ne serez plus arrêté aux rebords. Controls=Les contrôles -These are the default controls:=Ce sont les contrôles par défaut: -Basic movement:=Mouvement de base: -• Moving the mouse around: Look around=• Déplacer la souris: regardez autour -• W: Move forwards=• W: Avancer -• A: Move to the left=• A: Déplacer vers la gauche -• D: Move to the right=• D: Déplacer vers la droite -• S: Move backwards=• S: Reculer -• E: Sprint=• E: Courrir -While standing on solid ground:=En position debout sur un sol solide: -• Space: Jump=• Espace: Sauter -• Shift: Sneak=• Shift: Faufiler +These are the default controls:=Ce sont les contrôles par défaut : +Basic movement:=Mouvement de base : +• Moving the mouse around: Look around=• Déplacer la souris : regarder autour +• W: Move forwards=• W : Avancer +• A: Move to the left=• A : Déplacer vers la gauche +• D: Move to the right=• D : Déplacer vers la droite +• S: Move backwards=• S : Reculer +• E: Sprint=• E : Courir +While standing on solid ground:=En position debout sur un sol solide : +• Space: Jump=• Espace : Sauter +• Shift: Sneak=• Shift : Faufiler While on a ladder, swimming in a liquid or fly mode is active=Sur une échelle, nager dans un liquide ou le mode voler est actif -• Space: Move up=• Espace: Monter -• Shift: Move down=• Shift: Descendre -Extended movement (requires privileges):=Déplacement étendu (nécessite des privilèges): -• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=• J: Basculer en mode rapide, vous permet de courir ou de voler rapidement (nécessite le privilège "fast") -• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=• K: Basculer en mode vol, vous permet de vous déplacer librement dans toutes les directions (nécessite le privilège "fly") -• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=• H: Bascule le mode noclip, vous fait passer à travers les murs en mode vol (nécessite le privilège "noclip") -• E: Move even faster when in fast mode=• E: Déplacez-vous encore plus rapidement en mode rapide -• E: Walk fast in fast mode=• E: Marchez vite en mode rapide -World interaction:=Interaction avec le monde: -• Left mouse button: Punch / mine blocks / take items=• Bouton gauche de la souris: Perforer / miner des blocs / prendre des objets -• Left mouse button: Punch / mine blocks=• Bouton gauche de la souris: Perforer / miner des blocs -• Right mouse button: Build or use pointed block=• Bouton droit de la souris: Créer ou utiliser un bloc pointu -• Shift+Right mouse button: Build=• Shift+Bouton droit de la souris: Construire -• Roll mouse wheel: Select next/previous item in hotbar=• Molette de la souris: Sélectionnez l'élément suivant / précédent dans la barre active -• Roll mouse wheel / B / N: Select next/previous item in hotbar=• Faites rouler la molette de la souris / B / N: Sélectionnez l'élément suivant / précédent dans la barre de raccourci -• 1-9: Select item in hotbar directly=• 1-9: sélectionnez directement l'élément dans la barre de raccourci -• Q: Drop item stack=• Q: Déposer la pile d'objets -• Shift+Q: Drop 1 item=• Shift+Q: Déposer 1 élément -• I: Show/hide inventory menu=• I: Afficher/masquer le menu d'inventaire +• Space: Move up=• Espace : Monter +• Shift: Move down=• Shift : Descendre +Extended movement (requires privileges):=Déplacement étendu (nécessite des privilèges) : +• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=• J : Basculer en mode rapide, vous permet de courir ou de voler rapidement (nécessite le privilège "fast") +• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=• K : Basculer en mode vol, vous permet de vous déplacer librement dans toutes les directions (nécessite le privilège "fly") +• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=• H : Bascule le mode noclip, vous fait passer à travers les murs en mode vol (nécessite le privilège "noclip") +• E: Move even faster when in fast mode=• E : Déplacez-vous encore plus rapidement en mode rapide +• E: Walk fast in fast mode=• E : Marchez vite en mode rapide +World interaction:=Interaction avec le monde : +• Left mouse button: Punch / mine blocks / take items=• Bouton gauche de la souris : Frapper / miner des blocs / prendre des objets +• Left mouse button: Punch / mine blocks=• Bouton gauche de la souris : Frapper / miner des blocs +• Right mouse button: Build or use pointed block=• Bouton droit de la souris : Créer ou utiliser un bloc pointu +• Shift+Right mouse button: Build=• Shift+Bouton droit de la souris : Construire +• Roll mouse wheel: Select next/previous item in hotbar=• Molette de la souris : Sélectionnez l'élément suivant / précédent dans la barre active +• Roll mouse wheel / B / N: Select next/previous item in hotbar=• Faites rouler la molette de la souris / B / N : Sélectionnez l'élément suivant / précédent dans la barre de raccourci +• 1-9: Select item in hotbar directly=• 1-9 : sélectionnez directement l'élément dans la barre de raccourci +• Q: Drop item stack=• Q : Déposer la pile d'objets +• Shift+Q: Drop 1 item=• Shift+Q : Déposer 1 élément +• I: Show/hide inventory menu=• I : Afficher/masquer le menu d'inventaire Inventory interaction:=Interaction d'inventaire: See the entry “Basics > Inventory”.=Voir l'entrée «Bases> Inventaire». -Camera:=Caméra: -• Z: Zoom=• Z: Zoom -• F7: Toggle camera mode=• F7: Bascule le mode caméra -• F8: Toggle cinematic mode=• F8: Basculer le mode cinématique -Interface:=Interface: -• Esc: Open menu window (pauses in single-player mode) or close window=• Esc: Ouvrir la fenêtre du menu (fait une pause en mode solo) ou fermer la fenêtre -• F1: Show/hide HUD=• F1: Afficher/masquer le HUD -• F2: Show/hide chat=• F2: Afficher/masquer le chat -• F9: Toggle minimap=• F9: Basculer la mini-carte -• Shift+F9: Toggle minimap rotation mode=• Shift+F9: Bascule le mode de rotation de la mini-carte -• F10: Open/close console/chat log=• F10: Ouvrir/fermer la console/journal de chat -• F12: Take a screenshot=• F12: Prendre une capture d'écran -Server interaction:=Interaction avec le serveur: -• T: Open chat window (chat requires the “shout” privilege)=• T: Ouvrir la fenêtre de discussion (la discussion nécessite le privilège "shout") -• /: Start issuing a server command=• /: Lancer l'émission d'une commande serveur -Technical:=Technique: -• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=• R: Basculer la vue éloignée (désactive tout le brouillard et permet une visualisation éloignée, peut rendre le jeu très lent) -• +: Increase minimal viewing distance=• +: Augmentez la distance de visionnement minimale -• -: Decrease minimal viewing distance=• -: Diminue la distance de visionnement minimale -• F3: Enable/disable fog=• F3: Activer/désactiver le brouillard -• F5: Enable/disable debug screen which also shows your coordinates=• F5: Activer / désactiver l'écran de débogage qui affiche également vos coordonnées -• F6: Only useful for developers. Enables/disables profiler=• F6: utile uniquement pour les développeurs. Active/désactive le profileur -• P: Only useful for developers. Writes current stack traces=• P: utile uniquement pour les développeurs. Écrit les traces de pile actuelles +Camera:=Caméra : +• Z: Zoom=• Z : Zoom +• F7: Toggle camera mode=• F7 : Bascule le mode caméra +• F8: Toggle cinematic mode=• F8 : Basculer le mode cinématique +Interface:=Interface : +• Esc: Open menu window (pauses in single-player mode) or close window=• Échap : Ouvrir la fenêtre du menu (fait une pause en mode solo) ou fermer la fenêtre +• F1: Show/hide HUD=• F1 : Afficher/masquer le HUD +• F2: Show/hide chat=• F2 : Afficher/masquer le chat +• F9: Toggle minimap=• F9 : Basculer la mini-carte +• Shift+F9: Toggle minimap rotation mode=• Shift+F9 : Bascule le mode de rotation de la mini-carte +• F10: Open/close console/chat log=• F10 : Ouvrir/fermer la console/journal de chat +• F12: Take a screenshot=• F12 : Prendre une capture d'écran +Server interaction:=Interaction avec le serveur : +• T: Open chat window (chat requires the “shout” privilege)=• T : Ouvrir la fenêtre de discussion (la discussion nécessite le privilège "shout") +• /: Start issuing a server command=• / : Lancer l'émission d'une commande serveur +Technical:=Technique : +• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=• R : Basculer la vue éloignée (désactive tout le brouillard et permet une visualisation éloignée, peut rendre le jeu très lent) +• +: Increase minimal viewing distance=• + : Augmente la distance de vision minimale +• -: Decrease minimal viewing distance=• - : Diminue la distance de vision minimale +• F3: Enable/disable fog=• F3 : Activer/désactiver le brouillard +• F5: Enable/disable debug screen which also shows your coordinates=• F5 : Activer / désactiver l'écran de débogage qui affiche également vos coordonnées +• F6: Only useful for developers. Enables/disables profiler=• F6 : utile uniquement pour les développeurs. Active/désactive le profileur +• P: Only useful for developers. Writes current stack traces=• P : utile uniquement pour les développeurs. Écrit les traces de pile actuelles Players=Joueurs -Players (actually: “player characters”) are the characters which users control.=Les joueurs (en fait: "personnages joueurs") sont les personnages que les utilisateurs contrôlent. +Players (actually: “player characters”) are the characters which users control.=Les joueurs (en fait : "personnages joueurs") sont les personnages que les utilisateurs contrôlent. Players are living beings. They start with a number of health points (HP) and a number of breath points (BP).=Les joueurs sont des êtres vivants. Ils commencent par un certain nombre de points de vie (PV) et un certain nombre de points de respiration (BP). Players are capable of walking, sneaking, jumping, climbing, swimming, diving, mining, building, fighting and using tools and blocks.=Les joueurs sont capables de marcher, se faufiler, sauter, grimper, nager, plonger, exploiter, construire, se battre et utiliser des outils et des blocs. Players can take damage for a variety of reasons, here are some:=Les joueurs peuvent subir des dégâts pour diverses raisons, en voici quelques-unes: • Taking fall damage=• Prendre des dégâts de chute -• Touching a block which causes direct damage=• Toucher un bloc qui cause des dommages directs +• Touching a block which causes direct damage=• Toucher un bloc qui cause des dégâts directs • Drowning=• Noyade • Being attacked by another player=• Être attaqué par un autre joueur • Being attacked by a computer enemy=• Être attaqué par un ennemi informatique @@ -120,9 +120,9 @@ Items=Objects 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.=Les objets sont des choses que vous pouvez emporter et stocker dans des inventaires. Ils peuvent être utilisés pour l'artisanat, la fusion, la construction, l'exploitation minière, etc. Les types d'objets comprennent des blocs, des outils, des armes et des objets uniquement utilisés pour l'artisanat. 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.=Une pile d'objets est une collection d'objets du même type qui tient dans un seul emplacement d'objet. Les piles d'objets peuvent être déposées au sol. Les objets qui tombent dans les mêmes coordonnées formeront une pile d'objets. Items have several properties, including the following:=Les éléments ont plusieurs propriétés, notamment les suivantes: -• Maximum stack size: Number of items which fit on 1 item stack=• Taille maximale de la pile: Nombre d'articles pouvant tenir sur une pile d'articles -• Pointing range: How close things must be to be pointed while wielding this item=• Plage de pointage: A quelle distance les choses doivent être pointées lorsque vous maniez cet objet -• Group memberships: See “Basics > Groups”=• Appartenance à un groupe: Voir "Général> Groupes" +• Maximum stack size: Number of items which fit on 1 item stack=• Taille maximale de la pile : Nombre d'articles pouvant tenir sur une pile d'articles +• Pointing range: How close things must be to be pointed while wielding this item=• Plage de pointage : A quelle distance les choses doivent être pointées lorsque vous maniez cet objet +• Group memberships: See “Basics > Groups”=• Appartenance à un groupe : Voir "Général> Groupes" • May be used for crafting or cooking=• Peut être utilisé pour l'artisanat ou la cuisine Dropped item stacks will be collected automatically when you stand close to them.=Les piles d'objets déposés seront collectées automatiquement lorsque vous vous tenez près d'eux. Tools=Outils @@ -131,45 +131,45 @@ When nothing is wielded, players use their hand which may act as tool and weapon 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.=Un sous-ensemble d'outils sont les outils de minage. Ceux-ci sont importants pour casser toutes sortes de blocs. Les armes sont une sorte d'outil. Il existe bien sûr de nombreux autres outils possibles. Les actions spéciales des outils sont généralement effectuées par un clic gauche ou un clic droit. 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.=Les outils miniers sont importants pour briser toutes sortes de blocs. Les armes sont un autre type d'outil. Il existe d'autres outils plus spécialisés. Les actions spéciales des outils sont généralement effectuées par un clic droit. 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.=Quand rien n'est manié, les joueurs utilisent leur main qui peut servir d'outil et d'arme. La main est capable de poinçonner et inflige un minimum de dégâts. -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”.=De nombreux outils s'usent lors de leur utilisation et peuvent éventuellement être détruits. Les dégâts sont affichés dans une barre de dégâts sous l'icône de l'outil. Si aucune barre de dommage n'est affichée, l'outil est en parfait état. Les outils peuvent être réparables par artisanat, voir «Bases> Artisanat». +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”.=De nombreux outils s'usent lors de leur utilisation et peuvent éventuellement être détruits. Les dégâts sont affichés dans une barre de dégâts sous l'icône de l'outil. Si aucune barre de dégâts n'est affichée, l'outil est en parfait état. Les outils peuvent être réparables par artisanat, voir «Bases> Artisanat». Weapons=Armes Some items are usable as a melee weapon when wielded. Weapons share most of the properties of tools.=Certains objets sont utilisables comme arme de mêlée lorsqu'ils sont utilisés. Les armes partagent la plupart des propriétés des outils. -Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:=Les armes de mêlée infligent des dégâts en frappant les joueurs et d'autres objets animés. Il y a deux façons d'attaquer: -• Single punch: Left-click once to deal a single punch=• Coup de poing unique: Cliquez une fois avec le bouton gauche pour traiter un coup de poing -• Quick punching: Hold down the left mouse button to deal quick repeated punches=• Poinçonnage rapide: Maintenez le bouton gauche de la souris enfoncé pour effectuer des coups de poing répétés rapidement -There are two core attributes of melee weapons:=Il y a deux attributs principaux des armes de mêlée: -• Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered=• Dégâts maximum: Dégâts qui sont infligés après un coup lorsque l'arme a été complètement récupérée -• Full punch interval: Time it takes for fully recovering from a punch=• Intervalle de poinçonnage complet: temps nécessaire pour récupérer complètement d'un poinçon -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.=Une arme n'inflige des dégâts complets que lorsqu'elle a complètement récupéré d'un coup de poing précédent. Sinon, l'arme n'infligera que des dégâts réduits. Cela signifie que le poinçonnage rapide est très rapide, mais inflige également des dégâts plutôt faibles. Notez que l'intervalle de punch complet ne limite pas la vitesse à laquelle vous pouvez attaquer. -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.=Il existe une règle qui rend parfois les attaques impossibles: les joueurs, les objets animés et les armes appartiennent à des groupes de dégâts. Une arme inflige uniquement des dégâts à ceux qui partagent au moins un groupe de dégâts avec elle. Donc, si vous utilisez la mauvaise arme, vous pourriez ne pas infliger de dégâts du tout. +Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:=Les armes de mêlée infligent des dégâts en frappant les joueurs et d'autres objets animés. Il y a deux façons d'attaquer : +• Single punch: Left-click once to deal a single punch=• Coup unique : Cliquez une fois avec le bouton gauche pour donner un coup +• Quick punching: Hold down the left mouse button to deal quick repeated punches=• Coup rapide : Maintenez le bouton gauche de la souris enfoncé pour effectuer des coups répétés rapidement +There are two core attributes of melee weapons:=Il y a deux attributs principaux des armes de mêlée : +• Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered=• Dégâts maximum : Dégâts qui sont infligés après un coup lorsque l'arme a complètement récupéré +• Full punch interval: Time it takes for fully recovering from a punch=• Intervalle de coup complet : temps nécessaire pour récupérer complètement d'un coup +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.=Une arme n'inflige des dégâts complets que lorsqu'elle a complètement récupéré d'un coup précédent. Sinon, l'arme n'infligera que des dégâts réduits. Cela signifie que le coup rapide est très rapide, mais inflige également des dégâts plutôt faibles. Notez que l'intervalle de coup complet ne limite pas la vitesse à laquelle vous pouvez attaquer. +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.=Il existe une règle qui rend parfois les attaques impossibles : les joueurs, les objets animés et les armes appartiennent à des groupes de dégâts. Une arme inflige uniquement des dégâts à ceux qui partagent au moins un groupe de dégâts avec elle. Donc, si vous utilisez la mauvaise arme, vous pourriez ne pas infliger de dégâts du tout. Pointing=Pointage -“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.="Pointage" signifie regarder quelque chose à portée avec le réticule. Le pointage est nécessaire pour l'interaction, comme l'extraction, le poinçonnage, l'utilisation, etc. +“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.="Pointage" signifie regarder quelque chose à portée avec le réticule. Le pointage est nécessaire pour l'interaction, comme l'extraction, la frappe, l'utilisation, etc. 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.=Pour pointer quelque chose, il doit se trouver dans la plage de pointage (également appelée simplement "plage") de votre objet brandi. Il y a une plage par défaut lorsque vous ne maniez rien. Une chose pointue sera soulignée ou mise en évidence (en fonction de vos paramètres). Le pointage n'est pas possible avec la caméra frontale à la 3ème personne. 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.=Certaines choses ne peuvent pas être signalées. La plupart des blocs sont pointables. Quelques blocs, comme l'air, ne peuvent jamais être pointés. D'autres blocs, comme les liquides, ne peuvent être pointés que par des objets spéciaux. Camera=Caméra -There are 3 different views which determine the way you see the world. The modes are:=Il y a 3 vues différentes qui déterminent la façon dont vous voyez le monde. Les modes sont: -• 1: First-person view (default)=• 1: Vue à la première personne (par défaut) -• 2: Third-person view from behind=• 2: Vue à la troisième personne par derrière -• 3: Third-person view from the front=• 3: Vue à la troisième personne de face +There are 3 different views which determine the way you see the world. The modes are:=Il y a 3 vues différentes qui déterminent la façon dont vous voyez le monde. Les modes sont : +• 1: First-person view (default)=• 1 : Vue à la première personne (par défaut) +• 2: Third-person view from behind=• 2 : Vue à la troisième personne par derrière +• 3: Third-person view from the front=• 3 : Vue à la troisième personne de face You can change the camera mode by pressing [F7].=Vous pouvez changer le mode de l'appareil photo en appuyant sur [F7]. You might be able to zoom with [Z] to zoom the view at the crosshair. This allows you to look further.=Vous pourrez peut-être zoomer avec [Z] pour zoomer la vue sur le réticule. Cela vous permet de regarder plus loin. 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.=Le zoom est une fonctionnalité de gameplay qui peut être activée ou désactivée par le jeu. Par défaut, le zoom est activé en mode créatif mais désactivé dans le cas contraire. 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.=Il y a aussi le mode cinématique qui peut être basculé avec [F8]. Lorsque le mode cinématique est activé, les mouvements de la caméra deviennent plus fluides. Certains joueurs ne l'aiment pas, c'est une question de goût. By holding down [Z], you can zoom the view at your crosshair. You need the “zoom” privilege to do this.=En maintenant [Z] enfoncé, vous pouvez agrandir la vue sur votre réticule. Vous avez besoin du privilège "zoom" pour ce faire. -• Switch camera mode: [F7]=• Changer le mode de l'appareil photo: [F7] -• Toggle Cinematic Mode: [F8]=• Basculer le mode cinématique: [F8] -• Zoom: [Z]=• Zoom: [Z] +• Switch camera mode: [F7]=• Changer le mode de l'appareil photo : [F7] +• 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 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 -• 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=• Pointable: les blocs pointables affichent un filaire ou une boîte de halo lorsqu'ils sont pointés. Mais vous pointerez simplement à travers des blocs non pointables. Les liquides sont généralement non pointables mais ils peuvent être pointés par certains outils spéciaux -• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=• Propriétés minières: par quels outils il peut être extrait, à quelle vitesse et combien il s'use -• 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=• Grimpable: Pendant que vous êtes sur un bloc grimpable, vous ne tomberez pas et vous pouvez vous déplacer de haut en bas avec les touches de saut et de furtivité -• Drowning damage: See the entry “Basics > Player”=• Dommages liés à la noyade: voir l'entrée "Bases> Joueur" -• Liquids: See the entry “Basics > Liquids”=• Liquides: voir l'entrée "Bases> Liquides" -• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=• Appartenances aux groupes: les appartenances aux groupes sont utilisées pour déterminer les propriétés minières, l'artisanat, les interactions entre les blocs, etc. +• 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 +• 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=• Pointable : les blocs pointables affichent un filaire ou une boîte de halo lorsqu'ils sont pointés. Mais vous pointerez simplement à travers des blocs non pointables. Les liquides sont généralement non pointables mais ils peuvent être pointés par certains outils spéciaux +• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=• Propriétés minières : par quels outils il peut être extrait, à quelle vitesse et combien il s'use +• 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=• Grimpable : Pendant que vous êtes sur un bloc grimpable, vous ne tomberez pas et vous pouvez vous déplacer de haut en bas avec les touches de saut et de furtivité +• Drowning damage: See the entry “Basics > Player”=• Dégâts liés à la noyade : voir l'entrée "Bases> Joueur" +• Liquids: See the entry “Basics > Liquids”=• Liquides : voir l'entrée "Bases> Liquides" +• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=• Appartenances aux groupes : les appartenances aux groupes sont utilisées pour déterminer les propriétés minières, l'artisanat, les interactions entre les blocs, etc. Mining=Exploitation minière 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.=L'exploitation minière (ou creuser) est le processus de rupture des blocs pour les retirer. Pour extraire un bloc, pointez-le et maintenez enfoncé le bouton gauche de la souris jusqu'à ce qu'il se casse. 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.=Les blocs nécessitent un outil de minage pour être minés. Différents blocs sont extraits par différents outils d'exploration de données, et certains blocs ne peuvent être extraits par aucun outil. Les blocs varient en dureté et les outils varient en résistance. Les outils miniers s'useront avec le temps. Le temps d'extraction et l'usure de l'outil dépendent du bloc et de l'outil d'extraction. Le moyen le plus rapide de découvrir l'efficacité de vos outils d'exploration est simplement de les essayer sur différents blocs. Tous les objets que vous récupérez par extraction tomberont au sol, prêts à être récupérés. @@ -182,28 +182,28 @@ Building=Construire Almost all blocks can be built (or placed). Building is very simple and has no delay.=Presque tous les blocs peuvent être construits (ou placés). La construction est très simple et n'a pas de retard. 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.=Pour construire votre bloc brandi, pointez sur un bloc dans le monde et faites un clic droit. Si cela n'est pas possible car le bloc pointé a une action spéciale de clic droit, maintenez la touche furtive avant de cliquer avec le bouton droit. 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.=Les blocs peuvent presque toujours être construits sur des blocs pointables. Une exception est les blocs attachés au sol; ceux-ci ne peuvent être construits que sur le sol. -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.=Normalement, les blocs sont construits devant le côté pointu du bloc pointu. Quelques blocs sont différents: lorsque vous essayez de les construire, ils sont remplacés. +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.=Normalement, les blocs sont construits devant le côté pointu du bloc pointu. Quelques blocs sont différents : lorsque vous essayez de les construire, ils sont remplacés. Liquids=Liquides Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.=Les liquides sont des blocs dynamiques spéciaux. Les liquides aiment se propager et s'écouler vers leurs blocs environnants. Les joueurs peuvent nager et se noyer en eux. -Liquids usually come in two forms: In source form (S) and in flowing form (F).=Les liquides se présentent généralement sous deux formes: sous forme source (S) et sous forme fluide (F). +Liquids usually come in two forms: In source form (S) and in flowing form (F).=Les liquides se présentent généralement sous deux formes : sous forme source (S) et sous forme fluide (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.=Les sources liquides ont la forme d'un cube plein. Une source de liquide génère de temps à autre des liquides qui coulent autour d'elle et, si le liquide est renouvelable, elle génère également des sources de liquide. Une source liquide peut se maintenir. Tant qu'elle est laissée seule, une source liquide gardera normalement sa place et ne s'écoulera pas. 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.=Les liquides qui coulent prennent une forme inclinée. Les liquides qui coulent se répandent dans le monde jusqu'à ce qu'ils s'écoulent. Un liquide qui coule ne peut pas subvenir à ses besoins et provient toujours d'une source de liquide, directement ou indirectement. Sans source de liquide, un liquide qui s'écoule finira par s'écouler et disparaître. All liquids share the following properties:=Tous les liquides partagent les propriétés suivantes: • All properties of blocks (including drowning damage)=• Toutes les propriétés des blocs (y compris les dégâts de noyade) -• Renewability: Renewable liquids can create new sources=• Renouvelabilité: les liquides renouvelables peuvent créer de nouvelles sources -• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2=• Plage d'écoulement: le nombre de liquides qui s'écoulent au maximum par source de liquide détermine la distance de propagation du liquide. Les plages possibles sont comprises entre 0 et 8. À 0, aucun liquide ne sera créé. L'image 5 montre un liquide de gamme fluide 2 -• Viscosity: How slow players move through it and how slow the liquid spreads=• Viscosité: la vitesse à laquelle les joueurs se déplacent et la vitesse de propagation du liquide +• Renewability: Renewable liquids can create new sources=• Renouvelabilité : les liquides renouvelables peuvent créer de nouvelles sources +• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2=• Plage d'écoulement : le nombre de liquides qui s'écoulent au maximum par source de liquide détermine la distance de propagation du liquide. Les plages possibles sont comprises entre 0 et 8. À 0, aucun liquide ne sera créé. L'image 5 montre un liquide de gamme fluide 2 +• Viscosity: How slow players move through it and how slow the liquid spreads=• Viscosité : la vitesse à laquelle les joueurs se déplacent et la vitesse de propagation du liquide Renewable liquids create new liquid sources at open spaces (image 2). A new liquid source is created when:=Les liquides renouvelables créent de nouvelles sources de liquide dans les espaces ouverts (image 2). Une nouvelle source de liquide est créée lorsque: • Two renewable liquid blocks of the same type touch each other diagonally=• Deux blocs liquides renouvelables du même type se touchent en diagonale • These blocks are also on the same height=• Ces blocs sont également à la même hauteur • One of the two “corners” is open space which allows liquids to flow in=• L'un des deux «coins» est un espace ouvert qui permet aux liquides de s'écouler When those criteria are met, the open space is filled with a new liquid source of the same type (image 3).=Lorsque ces critères sont remplis, l'espace ouvert est rempli d'une nouvelle source de liquide du même type (image 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.=Nager dans un liquide est assez simple: les touches de direction habituelles pour les mouvements de base, la touche de saut pour la montée et la touche furtive pour le naufrage. +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.=Nager dans un liquide est assez simple : les touches de direction habituelles pour les mouvements de base, la touche de saut pour la montée et la touche furtive pour le naufrage. The physics for swimming and diving in a liquid are:=La physique pour nager et plonger dans un liquide est: • The higher the viscosity, the slower you move=• Plus la viscosité est élevée, plus vous vous déplacez lentement • If you rest, you'll slowly sink=• Si vous vous reposez, vous coulerez lentement -• There is no fall damage for falling into a liquid as such=• Il n'y a aucun dommage de chute pour tomber dans un liquide en tant que tel -• 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=• Si vous tombez dans un liquide, vous serez ralenti à l'impact (mais ne vous arrêtez pas instantanément). Votre profondeur d'impact est déterminée par votre vitesse et la viscosité du liquide. Pour une chute élevée et sûre dans un liquide, assurez-vous qu'il y a suffisamment de liquide au-dessus du sol, sinon vous pourriez toucher le sol et subir des dommages de chute +• There is no fall damage for falling into a liquid as such=• Il n'y a aucun dégât de chute pour tomber dans un liquide en tant que tel +• 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=• Si vous tombez dans un liquide, vous serez ralenti à l'impact (mais ne vous arrêtez pas instantanément). Votre profondeur d'impact est déterminée par votre vitesse et la viscosité du liquide. Pour une chute élevée et sûre dans un liquide, assurez-vous qu'il y a suffisamment de liquide au-dessus du sol, sinon vous pourriez toucher le sol et subir des dégâts de chute Liquids are often not pointable. But some special items are able to point all liquids.=Les liquides sont souvent inutiles. Mais certains objets spéciaux sont capables de pointer tous les liquides. Crafting=Artisanat Crafting is the task of combining several items to form a new item.=L'artisanat consiste à combiner plusieurs éléments pour former un nouvel élément. @@ -212,10 +212,10 @@ To complete the craft, take the result item from the output slot, which will con 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).=Une description sur la façon de fabriquer un objet est appelée "recette d'artisanat". Vous avez besoin de ces connaissances pour créer. Il existe plusieurs façons d'apprendre des recettes d'artisanat. Une façon consiste à utiliser un guide d'artisanat, qui contient une liste des recettes d'artisanat disponibles. Certains jeux proposent des guides d'artisanat. Il existe également des mods que vous pouvez télécharger en ligne pour installer un guide d'artisanat. Une autre façon consiste à lire le manuel en ligne du jeu (s'il en existe un). 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.=Les recettes d'artisanat consistent en au moins un élément d'entrée et exactement une pile d'éléments de sortie. Lors de l'exécution d'un seul métier, il consommera exactement un objet de chaque pile de la grille de fabrication, à moins que la recette de fabrication ne définisse des remplacements. There are multiple types of crafting recipes:=Il existe plusieurs types de recettes d'artisanat: -• Shaped (image 2): Items need to be placed in a particular shape=• En forme (image 2): Les articles doivent être placés dans une forme particulière -• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=• Sans forme (images 3 et 4): Les éléments doivent être placés quelque part dans l'entrée (les deux images montrent la même recette) -• Cooking: Explained in “Basics > Cooking”=• Cuisine: expliquée dans "Bases> Cuisine" -• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=• Réparation (image 5): Placez deux outils endommagés dans la grille d'artisanat n'importe où pour obtenir un outil qui est réparé de 5% +• Shaped (image 2): Items need to be placed in a particular shape=• En forme (image 2) : Les articles doivent être placés dans une forme particulière +• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=• Sans forme (images 3 et 4) : Les éléments doivent être placés quelque part dans l'entrée (les deux images montrent la même recette) +• Cooking: Explained in “Basics > Cooking”=• Cuisine : expliquée dans "Bases> Cuisine" +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=• Réparation (image 5) : Placez deux outils endommagés dans la grille d'artisanat n'importe où pour obtenir un outil qui est réparé de 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.=Dans certaines recettes d'artisanat, certains éléments d'entrée n'ont pas besoin d'être un élément concret, ils doivent plutôt être membres d'un groupe (voir "Bases> Groupes"). Ces recettes offrent un peu plus de liberté dans les éléments d'entrée. Les images 6-8 montrent la même recette de groupe. Ici, 8 éléments du groupe "pierre" sont requis, ce qui est vrai pour tous les éléments affichés. 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.=Rarement, les recettes d'artisanat ont des remplacements. Cela signifie que chaque fois que vous effectuez un métier, certains objets de la grille de fabrication ne seront pas consommés, mais seront remplacés à la place par un autre objet. Cooking=Cuisine @@ -225,9 +225,9 @@ Each cookable item requires time to be cooked. This time is specific to the item Hotbar=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.=Au bas de l'écran, vous voyez des carrés. C'est ce qu'on appelle la "hotbar". La barre d'accès vous permet d'accéder rapidement aux premiers éléments de votre inventaire de joueur. You can change the selected item with the mouse wheel or the keyboard.=Vous pouvez modifier l'élément sélectionné avec la molette de la souris ou le clavier. -• Select previous item in hotbar: [Mouse wheel up] or [B]=• Sélectionnez l'élément précédent dans la hotbar: [Molette de la souris vers le haut] ou [B] -• Select next item in hotbar: [Mouse wheel down] or [N]=• Sélectionnez l'élément suivant dans la hotbar: [Molette de la souris vers le bas] ou [N] -• Select item in hotbar directly: [1]-[9]=• Sélectionnez l'élément dans la hotbar directement: [1]-[9] +• Select previous item in hotbar: [Mouse wheel up] or [B]=• Sélectionnez l'élément précédent dans la hotbar : [Molette de la souris vers le haut] ou [B] +• Select next item in hotbar: [Mouse wheel down] or [N]=• Sélectionnez l'élément suivant dans la hotbar : [Molette de la souris vers le bas] ou [N] +• Select item in hotbar directly: [1]-[9]=• Sélectionnez l'élément dans la hotbar directement : [1]-[9] The selected item is also your wielded item.=L'élément sélectionné est également votre élément brandi. Minimap=Mini-carte If you have a map item in any of your hotbar slots, you can use the minimap.=Si vous avez un élément de carte dans l'un de vos emplacements de hotbar vous pouvez utiliser la minicarte. @@ -237,173 +237,173 @@ Surface mode (image 1) is a top-down view of the world, roughly resembling the c 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.=Le mode radar (image 2) est plus compliqué. Il affiche la «densité» de la zone autour de vous et change avec votre taille. En gros, plus une zone est verte, moins elle est «dense». Les zones noires ont de nombreux blocs. Utilisez le radar pour trouver des cavernes, des zones cachées, des murs et plus encore. Les formes rectangulaires de l'image 2 révèlent clairement la position d'un donjon. 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.=Il existe également deux modes de rotation différents. En "mode carré", la rotation de la minicarte est fixe. Si vous appuyez sur [Shift] + [F9] pour passer en "mode cercle", la minicarte tournera à la place avec votre direction de recherche, donc "haut" est toujours votre direction de recherche. In some games, the minimap may be disabled.=Dans certains jeux, la minicarte peut être désactivée. -• Toggle minimap mode: [F9]=• Basculer le mode mini-carte: [F9] -• Toggle minimap rotation mode: [Shift]+[F9]=• Basculer le mode de rotation de la mini-carte: [Shift]+[F9] +• Toggle minimap mode: [F9]=• Basculer le mode mini-carte : [F9] +• Toggle minimap rotation mode: [Shift]+[F9]=• Basculer le mode de rotation de la mini-carte : [Shift]+[F9] Inventory=Inventaire 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.=Les stocks sont utilisés pour stocker des piles d'articles. Il existe d'autres utilisations, telles que l'artisanat. Un inventaire se compose d'une grille rectangulaire d'emplacements d'objets. Chaque emplacement d'objet peut être vide ou contenir une pile d'objets. Les piles d'objets peuvent être déplacées librement entre la plupart des emplacements. -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.=Vous avez votre propre inventaire qui s'appelle votre "inventaire de joueur", vous pouvez l'ouvrir avec la clé d'inventaire (par défaut: [I]). Les premiers emplacements d'inventaire sont également utilisés comme emplacements dans votre hotbar. +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.=Vous avez votre propre inventaire qui s'appelle votre "inventaire de joueur", vous pouvez l'ouvrir avec la touche d'inventaire (par défaut : [I]). Les premiers emplacements d'inventaire sont également utilisés comme emplacements dans votre hotbar. Blocks can also have their own inventory, e.g. chests and furnaces.=Les blocs peuvent également avoir leur propre inventaire, par exemple coffres et fours. Inventory controls:=Contrôles d'inventaire: -Taking: You can take items from an occupied slot if the cursor holds nothing.=Prendre: vous pouvez prendre des objets dans un emplacement occupé si le curseur ne contient rien. -• Left click: take entire item stack=• Clic gauche: Prendre toute la pile d'objets -• Right click: take half from the item stack (rounded up)=• Clic droit: Prendre la moitié de la pile d'objets (arrondi vers le haut) -• Middle click: take 10 items from the item stack=• Clic du milieu: Prenez 10 objets de la pile d'objets -• Mouse wheel down: take 1 item from the item stack=• Molette de la souris vers le bas: Prenez 1 objet de la pile d'objets -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.=Placer: Vous pouvez placer des objets dans un emplacement si le curseur contient un ou plusieurs objets et que l'emplacement est vide ou contient une pile d'objets du même type d'objet. -• Left click: put entire item stack=• Clic gauche: Mettre toute la pile d'objets -• Right click: put 1 item of the item stack=• Clic droit: Mettre 1 élément de la pile d'objets -• Right click or mouse wheel up: put 1 item of the item stack=• Clic droit ou roulette de la souris vers le haut: Placez 1 article dans la pile d'objets -• Middle click: put 10 items of the item stack=• Clic du milieu: Mettez 10 objets dans la pile d'objets -Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=Échange: vous pouvez échanger des objets si le curseur contient un ou plusieurs objets et que l'emplacement de destination est occupé par un type d'objet différent. -• Click: exchange item stacks=• Cliquez: Echangez les piles d'articles -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.=Jeter: Si vous maintenez une pile d'objets et cliquez avec elle quelque part en dehors du menu, la pile d'objets est jetée dans l'environnement. -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 +Taking: You can take items from an occupied slot if the cursor holds nothing.=Prendre : vous pouvez prendre des objets dans un emplacement occupé si le curseur ne contient rien. +• Left click: take entire item stack=• Clic gauche : Prendre toute la pile d'objets +• Right click: take half from the item stack (rounded up)=• Clic droit : Prendre la moitié de la pile d'objets (arrondi vers le haut) +• Middle click: take 10 items from the item stack=• Clic du milieu : Prenez 10 objets de la pile d'objets +• Mouse wheel down: take 1 item from the item stack=• Molette de la souris vers le bas : Prenez 1 objet de la pile d'objets +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.=Placer : Vous pouvez placer des objets dans un emplacement si le curseur contient un ou plusieurs objets et que l'emplacement est vide ou contient une pile d'objets du même type d'objet. +• Left click: put entire item stack=• Clic gauche : Mettre toute la pile d'objets +• Right click: put 1 item of the item stack=• Clic droit : Mettre 1 élément de la pile d'objets +• Right click or mouse wheel up: put 1 item of the item stack=• Clic droit ou roulette de la souris vers le haut : Placez 1 article dans la pile d'objets +• Middle click: put 10 items of the item stack=• Clic du milieu : Mettez 10 objets dans la pile d'objets +Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=Échange : vous pouvez échanger des objets si le curseur contient un ou plusieurs objets et que l'emplacement de destination est occupé par un type d'objet différent. +• Click: exchange item stacks=• Cliquez : Echangez les piles d'articles +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.=Jeter : Si vous maintenez une pile d'objets et cliquez avec elle quelque part en dehors du menu, la pile d'objets est jetée dans l'environnement. +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: +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. -Bug tracker: =Suivi des bogues: +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: +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.=L'endroit principal pour trouver la version la plus récente de Minetest. -Community wiki: =Wiki de la communauté: +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. -Minetest forums: =Forums de minetest: +Minetest forums: =Forums de 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.=Une plate-forme de discussion en ligne où vous pouvez discuter de tout ce qui concerne Minetest. C'est également un endroit où les mods et les jeux créés par les joueurs sont publiés et discutés. Les discussions se déroulent principalement en anglais, mais il existe également un espace de discussion dans d'autres langues. -Chat: =Chat: +Chat: =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.=Un canal de discussion générique pour tout ce qui concerne le Minetest où les gens peuvent se rencontrer pour discuter en temps réel. Si vous ne comprenez pas IRC, consultez le wiki de la communauté pour obtenir de l'aide. Groups=Groupes Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:=Les objets, les joueurs et les objets (animés et inanimés) peuvent être membres de plusieurs de groupes. Les groupes ont plusieurs objectifs: -• 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=• Recettes d'artisanat: Les emplacements d'une recette d'artisanat peuvent ne pas nécessiter un élément spécifique, mais plutôt un élément qui est membre d'un groupe particulier ou de plusieurs groupes. -• 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=• Temps de creusement: Les blocs pouvant être creusés appartiennent à des groupes qui sont utilisés pour déterminer les temps de creusement. Les outils miniers sont capables de creuser des blocs appartenant à certains groupes -• Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group=• Comportement des blocs: Les blocs peuvent présenter un comportement spécial et interagir avec d'autres blocs lorsqu'ils appartiennent à un groupe particulier -• Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weapons”=• Dommages et armures: Les objets et les joueurs ont des groupes d'armures, les armes ont des groupes de dégâts. Ces groupes déterminent les dommages. Voir aussi: "Bases> Armes" +• 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=• Recettes d'artisanat : Les emplacements d'une recette d'artisanat peuvent ne pas nécessiter un élément spécifique, mais plutôt un élément qui est membre d'un groupe particulier ou de plusieurs groupes. +• 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=• Temps de creusement : Les blocs pouvant être creusés appartiennent à des groupes qui sont utilisés pour déterminer les temps de creusement. Les outils miniers sont capables de creuser des blocs appartenant à certains groupes +• Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group=• Comportement des blocs : Les blocs peuvent présenter un comportement spécial et interagir avec d'autres blocs lorsqu'ils appartiennent à un groupe particulier +• Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weapons”=• Dégâts et armures : Les objets et les joueurs ont des groupes d'armures, les armes ont des groupes de dégâts. Ces groupes déterminent les dégâts. Voir aussi : "Bases> Armes" • Other uses=• Autres utilisations In the item help, many important groups are usually mentioned and explained.=Dans l'aide aux objets, de nombreux groupes importants sont généralement mentionnés et expliqués. Glossary=Glossaire This is a list of commonly used terms:=Voici une liste de termes couramment utilisés: Controls:=Les contrôles: -• Wielding: Holding an item in hand=• Maniement: Tenir un objet en main -• Pointing: Looking with the crosshair at something in range=• Pointage: Regarder avec le réticule quelque chose à portée -• Dropping: Throwing an item or item stack to the ground=• Lâcher: Jeter un objet ou une pile d'objets au sol -• Punching: Attacking with left-click, is also used on blocks=• Frapper: Attaque avec clic gauche, est également utilisé sur les blocs -• Sneaking: Walking slowly while (usually) avoiding to fall over edges=• Se faufiler: Marcher lentement tout en évitant (généralement) de tomber sur les bords -• Climbing: Moving up or down a climbable block=• Escalade: Monter ou descendre un bloc grimpable +• Wielding: Holding an item in hand=• Maniement : Tenir un objet en main +• Pointing: Looking with the crosshair at something in range=• Pointage : Regarder avec le réticule quelque chose à portée +• Dropping: Throwing an item or item stack to the ground=• Lâcher : Jeter un objet ou une pile d'objets au sol +• Punching: Attacking with left-click, is also used on blocks=• Frapper : Attaque avec clic gauche, est également utilisé sur les blocs +• Sneaking: Walking slowly while (usually) avoiding to fall over edges=• Se faufiler : Marcher lentement tout en évitant (généralement) de tomber sur les bords +• Climbing: Moving up or down a climbable block=• Escalade : Monter ou descendre un bloc grimpable Blocks:=Blocs: -• Block: Cubes that the worlds are made of=• Bloc: Cubes dont les mondes sont faits -• Mining/digging: Using a mining tool to break a block=• Exploration/minage: Utilisation d'un outil d'exploration pour casser un bloc -• Building/placing: Putting a block somewhere=• Construction/Placement: Placer un bloc quelque part -• Drop: Items you get after mining a block=• Drop: Les objets que vous obtenez après avoir extrait un bloc -• Using a block: Right-clicking a block to access its special function=• Utilisation d'un bloc: Clic droit sur un bloc pour accéder à sa fonction spéciale +• Block: Cubes that the worlds are made of=• Bloc : Cubes dont les mondes sont faits +• Mining/digging: Using a mining tool to break a block=• Exploration/minage : Utilisation d'un outil d'exploration pour casser un bloc +• Building/placing: Putting a block somewhere=• Construction/Placement : Placer un bloc quelque part +• Drop: Items you get after mining a block=• Drop : Les objets que vous obtenez après avoir extrait un bloc +• Using a block: Right-clicking a block to access its special function=• Utilisation d'un bloc : Clic droit sur un bloc pour accéder à sa fonction spéciale Items:=Objects: -• Item: A single thing that players can possess=• Objet: Une seule chose que les joueurs peuvent posséder -• Item stack: A collection of items of the same kind=• Pile d'objets: Une collection d'objets du même type -• Maximum stack size: Maximum amount of items in an item stack=• Taille maximale de la pile: Quantité maximale d'éléments dans une pile d'éléments -• Slot / inventory slot: Can hold one item stack=• Emplacement/Emplacement d'inventaire: Peut contenir une pile d'objets -• Inventory: Provides several inventory slots for storage=• Inventaire: Fournit plusieurs emplacements d'inventaire pour le stockage -• Player inventory: The main inventory of a player=• Inventaire des joueurs: L'inventaire principal d'un joueur -• Tool: An item which you can use to do special things with when wielding=• Outil: Un élément que vous pouvez utiliser pour faire des choses spéciales avec lors du soudage -• Range: How far away things can be to be pointed by an item=• Plage: A quelle distance les objets peuvent être pointés par un élément -• Mining tool: A tool which allows to break blocks=• Outil minier: Un outil qui permet de casser des blocs -• Craftitem: An item which is (primarily or only) used for crafting=• Composant: Un objet qui est (principalement ou uniquement) utilisé pour l'artisanat +• Item: A single thing that players can possess=• Objet : Une seule chose que les joueurs peuvent posséder +• Item stack: A collection of items of the same kind=• Pile d'objets : Une collection d'objets du même type +• Maximum stack size: Maximum amount of items in an item stack=• Taille maximale de la pile : Quantité maximale d'éléments dans une pile d'éléments +• Slot / inventory slot: Can hold one item stack=• Emplacement/Emplacement d'inventaire : Peut contenir une pile d'objets +• Inventory: Provides several inventory slots for storage=• Inventaire : Fournit plusieurs emplacements d'inventaire pour le stockage +• Player inventory: The main inventory of a player=• Inventaire des joueurs : L'inventaire principal d'un joueur +• Tool: An item which you can use to do special things with when wielding=• Outil : Un élément que vous pouvez utiliser pour faire des choses spéciales avec lors du soudage +• Range: How far away things can be to be pointed by an item=• Plage : A quelle distance les objets peuvent être pointés par un élément +• Mining tool: A tool which allows to break blocks=• Outil minier : Un outil qui permet de casser des blocs +• Craftitem: An item which is (primarily or only) used for crafting=• Composant : Un objet qui est (principalement ou uniquement) utilisé pour l'artisanat Gameplay:=Gameplay: -• “heart”: A single health symbol, indicates 2 HP=• "coeur": Un seul symbole de santé, indique 2 PV -• “bubble”: A single breath symbol, indicates 1 BP=• "bulle": Un symbole de respiration unique, indique 1 BP -• HP: Hit point (equals half 1 “heart”)=• VP: point de vie (équivaut à un demi-«coeur») -• BP: Breath point, indicates breath when diving=• BP: Point de respiration, indique la respiration lors de la plongée -• Mob: Computer-controlled enemy=• Mob: Ennemi contrôlé par ordinateur -• Crafting: Combining multiple items to create new ones=• Artisanat: Combiner plusieurs objets pour en créer de nouveaux -• Crafting guide: A helper which shows available crafting recipes=• Guide d'artisanat: Un assistant qui montre les recettes d'artisanat disponibles -• Spawning: Appearing in the world=• Reproduction: Apparaissant dans le monde -• Respawning: Appearing again in the world after death=• Réapparition: Réapparaître dans le monde après la mort -• Group: Puts similar things together, often affects gameplay=• Groupe: Rassemble des choses similaires, affecte souvent le gameplay -• noclip: Allows to fly through walls=• noclip: Permet de voler à travers les murs +• “heart”: A single health symbol, indicates 2 HP=• "cœur" : Un seul symbole de santé, indique 2 PV +• “bubble”: A single breath symbol, indicates 1 BP=• "bulle" : Un symbole de respiration unique, indique 1 BP +• HP: Hit point (equals half 1 “heart”)=• PV : point de vie (équivaut à un demi-«cœur») +• BP: Breath point, indicates breath when diving=• BP : Point de respiration, indique la respiration lors de la plongée +• Mob: Computer-controlled enemy=• Mob : Ennemi contrôlé par ordinateur +• Crafting: Combining multiple items to create new ones=• Artisanat : Combiner plusieurs objets pour en créer de nouveaux +• Crafting guide: A helper which shows available crafting recipes=• Guide d'artisanat : Un assistant qui montre les recettes d'artisanat disponibles +• Spawning: Appearing in the world=• Reproduction : Apparaissant dans le monde +• Respawning: Appearing again in the world after death=• Réapparition : Réapparaître dans le monde après la mort +• Group: Puts similar things together, often affects gameplay=• Groupe : Rassemble des choses similaires, affecte souvent le gameplay +• noclip: Allows to fly through walls=• noclip : Permet de voler à travers les murs Interface=Interface -• Hotbar: Inventory slots at the bottom=• Hotbar: Emplacements d'inventaire en bas -• Statbar: Indicator made out of half-symbols, used for health and breath=• Statbar: Indicateur composé de demi-symboles, utilisé pour la santé et la respiration -• Minimap: The map or radar at the top right=• Mini-carte: La carte ou le radar en haut à droite -• Crosshair: Seen in the middle, used to point at things=• Réticule: Vu au milieu, utilisé pour pointer les choses +• Hotbar: Inventory slots at the bottom=• Hotbar : Emplacements d'inventaire en bas +• Statbar: Indicator made out of half-symbols, used for health and breath=• Statbar : Indicateur composé de demi-symboles, utilisé pour la santé et la respiration +• Minimap: The map or radar at the top right=• Mini-carte : La carte ou le radar en haut à droite +• Crosshair: Seen in the middle, used to point at things=• Réticule : Vu au milieu, utilisé pour pointer les choses Online multiplayer:=Multijoueur en ligne: -• PvP: Player vs Player. If active, players can deal damage to each other=• PvP: Joueur contre Joueur. S'ils sont actifs, les joueurs peuvent s'infliger mutuellement des dégâts -• Griefing: Destroying the buildings of other players against their will=• Deuil: Détruire les bâtiments des autres joueurs contre leur gré -• 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 +• PvP: Player vs Player. If active, players can deal damage to each other=• PvP : Joueur contre Joueur. S'ils sont actifs, les joueurs peuvent s'infliger mutuellement des dégâts +• Griefing: Destroying the buildings of other players against their will=• Deuil : Détruire les bâtiments des autres joueurs contre leur gré +• 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 que 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 -• Privilege: Allows a player to do something=• Privilège: Permet à un joueur de faire quelque chose -• Node: Other word for “block”=• Noeud: Autre mot pour "bloc" +• 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 +• 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 +• Privilege: Allows a player to do something=• Privilège : Permet à un joueur de faire quelque chose +• Node: Other word for “block”=• Noeud : Autre mot pour "bloc" Settings=Réglages There is a large variety of settings to configure Minetest. Pretty much every aspect can be changed that way.=Il existe une grande variété de paramètres pour configurer Minetest. Presque tous les aspects peuvent être modifiés de cette façon. -These are a few of the most important gameplay settings:=Voici quelques-uns des paramètres de jeu les plus importants: -• Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal=• Dommage activé (enable_damage): Active les attributs de santé et de souffle pour tous les joueurs. Si désactivé, les joueurs sont immortels -• 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.=• Mode créatif (creative_mode): permet un gameplay de style sandbox en se concentrant sur la créativité plutôt que sur un gameplay difficile. Le sens dépend du jeu; les changements habituels sont: temps de fouille réduits, accès facile à presque tous les articles, les outils ne s'usent jamais, etc. -• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=• PvP (enable_pvp): Abréviation de «Player vs Player». Si activé, les joueurs peuvent s'infliger mutuellement des dégâts +These are a few of the most important gameplay settings:=Voici quelques-uns des paramètres de jeu les plus importants : +• Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal=• Dégât activé (enable_damage) : Active les attributs de santé et de souffle pour tous les joueurs. Si désactivé, les joueurs sont immortels +• 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.=• Mode créatif (creative_mode) : permet un gameplay de style sandbox en se concentrant sur la créativité plutôt que sur un gameplay difficile. Le sens dépend du jeu ; les changements habituels sont : temps de fouille réduits, accès facile à presque tous les articles, les outils ne s'usent jamais, etc. +• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=• PvP (enable_pvp) : Abréviation de «Player vs Player». Si activé, les joueurs peuvent s'infliger mutuellement des dégâts For a full list of all available settings, use the “All Settings” dialog in the main menu.=Pour une liste complète de tous les paramètres disponibles, utilisez la boîte de dialogue "Tous les Paramètres" dans le menu principal. Movement modes=Modes de mouvement You can enable some special movement modes that change how you move.=Vous pouvez activer certains modes de déplacement spéciaux qui modifient votre façon de vous déplacer. -Pitch movement mode:=Mode de mouvement de tangage: -• 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.=• Description: Si ce mode est activé, les touches de déplacement vous déplaceront par rapport à votre hauteur de vue actuelle (angle de vue vertical) lorsque vous êtes en mode liquide ou en mode vol. -• Default key: [L]=• Touche par défaut: [L] +Pitch movement mode:=Mode de mouvement de tangage : +• 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.=• Description : Si ce mode est activé, les touches de déplacement vous déplaceront par rapport à votre hauteur de vue actuelle (angle de vue vertical) lorsque vous êtes en mode liquide ou en mode vol. +• Default key: [L]=• Touche par défaut : [L] • No privilege required=• Aucun privilège requis Fast mode:=Mode Rapide: • 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.=• Description: vous permet de vous déplacer beaucoup plus rapidement. Maintenez la touche "Utiliser" [E] enfoncée pour vous déplacer plus rapidement. Dans la configuration du client, vous pouvez personnaliser davantage le mode rapide. -• Default key: [J]=• Touche par défaut: [J] -• Required privilege: fast=• Privilège requis: fast +• Default key: [J]=• Touche par défaut : [J] +• Required privilege: fast=• Privilège requis : fast Fly mode:=Mode Vol: • 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.=• Description: La gravité ne vous affecte pas et vous pouvez vous déplacer librement dans toutes les directions. Utilisez la touche de saut pour monter et la touche de sneak pour descendre. -• Default key: [K]=• Touche par défaut: [K] -• Required privilege: fly=• Privilège requis: fly +• Default key: [K]=• Touche par défaut : [K] +• Required privilege: fly=• Privilège requis : fly Noclip mode:=Mode Noclip: • Description: Allows you to move through walls. Only works when fly mode is enabled, too.=• Description: vous permet de vous déplacer à travers les murs. Fonctionne uniquement lorsque le mode avion est également activé. -• Default key: [H]=• Touche par défaut: [H] -• Required privilege: noclip=• Privilège requis: noclip +• Default key: [H]=• Touche par défaut : [H] +• Required privilege: noclip=• Privilège requis : noclip Console=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.=Avec [F10], vous pouvez ouvrir et fermer la console. L'utilisation principale de la console est d'afficher le journal de discussion et d'entrer des messages de discussion ou des commandes de serveur. Using the chat or server command key also opens the console, but it is smaller and will be closed after you sent a message.=L'utilisation de la touche de commande chat ou serveur ouvre également la console, mais elle est plus petite et sera fermée après l'envoi d'un message. Use the chat to communicate with other players. This requires you to have the “shout” privilege.=Utilisez le chat pour communiquer avec d'autres joueurs. Cela vous oblige à avoir le privilège "shout". Just type in the message and hit [Enter]. Public chat messages can not begin with “/”.=Tapez simplement le message et appuyez sur [Entrée]. Les messages de discussion publique ne peuvent pas commencer par "/". -You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=Vous pouvez envoyer des messages privés: Dites "/msg " dans le chat pour envoyer "" qui ne peut être vu que par . +You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=Vous pouvez envoyer des messages privés : Dites "/msg " dans le chat pour envoyer "" qui ne peut être vu que par . There are some special controls for the console:=Il existe des commandes spéciales pour la console: -• [F10] Open/close console=• [F10]: Ouvrir/fermer la console -• [Enter]: Send message or command=• [Entrée]: Envoyer un message ou une commande -• [Tab]: Try to auto-complete a partially-entered player name=• [Tab]: Essayez de compléter automatiquement un nom de joueur partiellement entré -• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=• [Ctrl]+[Gauche]: Déplacer le curseur au début du mot précédent -• [Ctrl]+[Right]: Move cursor to the beginning of the next word=• [Ctrl]+[Droite]: Déplacez le curseur au début du mot suivant -• [Ctrl]+[Backspace]: Delete previous word=• [Ctrl]+[Retour arrière]: Supprimer le mot précédent -• [Ctrl]+[Delete]: Delete next word=• [Ctrl]+[Supprimer]: Supprimer le mot suivant -• [Ctrl]+[U]: Delete all text before the cursor=• [Ctrl]+[U]: Supprimer tout le texte avant le curseur -• [Ctrl]+[K]: Delete all text after the cursor=• [Ctrl]+[K]: Supprimer tout le texte après le curseur -• [Page up]: Scroll up=• [Page précédente]: Faites défiler vers le haut -• [Page down]: Scroll down=• [Page suivante]: Faites défiler vers le bas +• [F10] Open/close console=• [F10] : Ouvrir/fermer la console +• [Enter]: Send message or command=• [Entrée] : Envoyer un message ou une commande +• [Tab]: Try to auto-complete a partially-entered player name=• [Tab] : Essayez de compléter automatiquement un nom de joueur partiellement entré +• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=• [Ctrl]+[Gauche] : Déplacer le curseur au début du mot précédent +• [Ctrl]+[Right]: Move cursor to the beginning of the next word=• [Ctrl]+[Droite] : Déplacez le curseur au début du mot suivant +• [Ctrl]+[Backspace]: Delete previous word=• [Ctrl]+[Retour arrière] : Supprimer le mot précédent +• [Ctrl]+[Delete]: Delete next word=• [Ctrl]+[Supprimer] : Supprimer le mot suivant +• [Ctrl]+[U]: Delete all text before the cursor=• [Ctrl]+[U] : Supprimer tout le texte avant le curseur +• [Ctrl]+[K]: Delete all text after the cursor=• [Ctrl]+[K] : Supprimer tout le texte après le curseur +• [Page up]: Scroll up=• [Page précédente] : Faites défiler vers le haut +• [Page down]: Scroll down=• [Page suivante] : Faites défiler vers le bas There is also an input history. Minetest saves your previous console inputs which you can quickly access later:=Il existe également un historique des entrées. Minetest enregistre vos entrées de console précédentes auxquelles vous pouvez accéder rapidement plus tard: -• [Up]: Go to previous entry in history=• [Haut]: Aller à l'entrée précédente de l'historique -• [Down]: Go to next entry in history=• [Bas]: Passer à la prochaine entrée de l'historique +• [Up]: Go to previous entry in history=• [Haut] : Aller à l'entrée précédente de l'historique +• [Down]: Go to next entry in history=• [Bas] : Passer à la prochaine entrée de l'historique Server commands=Commandes serveur 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.=Les commandes serveur (également appelées "commandes de chat") sont de petites aides pour les utilisateurs avancés. Vous n'avez pas besoin d'utiliser ces commandes lors du jeu. Mais elles pourraient être utiles pour effectuer des tâches plus techniques. Les commandes du serveur fonctionnent à la fois en mode multi-joueurs et solo. 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.=Les commandes du serveur peuvent être saisies par les joueurs utilisant le chat pour effectuer une action spéciale du serveur. Il y a quelques commandes qui peuvent être émises par tout le monde, mais certaines commandes ne fonctionnent que si vous avez certains privilèges accordés sur le serveur. Il y a un petit ensemble de commandes de base qui sont toujours disponibles, d'autres commandes peuvent être ajoutées par des 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.=Pour lancer une commande, tapez-la simplement comme un message de discussion ou appuyez sur la touche de commande de Minetest (par défaut: [/]). Toutes les commandes doivent commencer par "/", par exemple "/mods". La touche de commande Minetest fait la même chose que la touche de conversation, sauf que la barre oblique est déjà entrée. -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.=Les commandes peuvent ou non donner une réponse dans le journal de discussion, mais les erreurs seront généralement affichées dans la discussion. Essayez-le par vous-même: Fermez cette fenêtre et tapez la commande "/mods". Cela vous donnera la liste des mods disponibles sur ce serveur. -“/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" est une commande très importante: vous obtenez une liste de toutes les commandes disponibles sur le serveur, une brève explication et les paramètres autorisés. Cette commande est également importante car les commandes disponibles diffèrent souvent selon le serveur. +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.=Pour lancer une commande, tapez-la simplement comme un message de discussion ou appuyez sur la touche de commande de Minetest (par défaut : [/]). Toutes les commandes doivent commencer par "/", par exemple "/mods". La touche de commande Minetest fait la même chose que la touche de conversation, sauf que la barre oblique est déjà entrée. +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.=Les commandes peuvent ou non donner une réponse dans le journal de discussion, mais les erreurs seront généralement affichées dans la discussion. Essayez-le par vous-même : Fermez cette fenêtre et tapez la commande "/mods". Cela vous donnera la liste des mods disponibles sur ce serveur. +“/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" est une commande très importante : vous obtenez une liste de toutes les commandes disponibles sur le serveur, une brève explication et les paramètres autorisés. Cette commande est également importante car les commandes disponibles diffèrent souvent selon le serveur. Commands are followed by zero or more parameters.=Les commandes sont suivies de zéro ou plusieurs paramètres. In the command reference, you see some placeholders which you need to replace with an actual value. Here's an explanation:=Dans la référence de commande, vous voyez des espaces réservés que vous devez remplacer par une valeur réelle. Voici une explication: -• Text in greater-than and lower-than signs (e.g. “”): Placeholder for a parameter=• Texte en signes supérieur à et inférieur à (par exemple «»): Espace réservé pour un paramètre +• Text in greater-than and lower-than signs (e.g. “”): Placeholder for a parameter=• Texte en signes supérieur à et inférieur à (par exemple «») : Espace réservé pour un paramètre • Anything in square brackets (e.g. “[text]”) is optional and can be omitted=• Tout ce qui est entre crochets (par exemple «[texte]») est facultatif et peut être omis -• Pipe or slash (e.g. “text1 | text2 | text3”): Alternation. One of multiple texts must be used (e.g. “text2”)=• Tuyau ou barre oblique (par exemple, «texte1 | texte2 | texte3»): Alternance. L'un des multiples textes doit être utilisé (par exemple, "texte2") -• Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=• Parenthèses: (par exemple «(mot1 mot2) | mot3»): Regroupe plusieurs mots, utilisés pour les alternances +• Pipe or slash (e.g. “text1 | text2 | text3”): Alternation. One of multiple texts must be used (e.g. “text2”)=• Tuyau ou barre oblique (par exemple, «texte1 | texte2 | texte3») : Alternance. L'un des multiples textes doit être utilisé (par exemple, "texte2") +• Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=• Parenthèses : (par exemple «(mot1 mot2) | mot3») : Regroupe plusieurs mots, utilisés pour les alternances • Everything else is to be read as literal text=• Tout le reste doit être lu comme un texte littéral Here are some examples to illustrate the command syntax:=Voici quelques exemples pour illustrer la syntaxe de commande: -• /mods: No parameters. Just enter “/mods”=• /mods: aucun paramètre. Entrez simplement "/mods" +• /mods: No parameters. Just enter “/mods”=• /mods : aucun paramètre. Entrez simplement "/mods" • /me : 1 parameter. You have to enter “/me ” followed by any text, e.g. “/me orders pizza”=• /me : 1 paramètre. Vous devez saisir "/me" suivi de tout texte, par ex. "/me order pizza" -• /give : Two parameters. Example: “/give Player default:apple”=• /give : Deux paramètres. Exemple: "/give Player default: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 | ]: Les entrées valides sont "/help", "/help all", "/help privs" ou "/help" suivi d'un nom de commande, comme "/help time" -• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=• /spawnentity [,,]: Les entrées valides sont “/spawnentity boats:boat” et “/spawnentity boats:boat 0,0,0” +• /give : Two parameters. Example: “/give Player default:apple”=• /give : Deux paramètres. Exemple : "/give Player default: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 | ] : Les entrées valides sont "/help", "/help all", "/help privs" ou "/help" suivi d'un nom de commande, comme "/help time" +• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=• /spawnentity [,,] : Les entrées valides sont “/spawnentity boats:boat” et “/spawnentity boats:boat 0,0,0” Some final remarks:=Quelques remarques finales: • 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=• Pour /give et /giveme, vous avez besoin d'une chaîne d'objet. Il s'agit d'un identifiant d'élément unique utilisé en interne que vous pouvez trouver dans l'aide de l'élément si vous disposez du privilège "give" ou "debug". • For /spawnentity you need an entity name, which is another identifier=• Pour /spawnentity, vous avez besoin d'un nom d'entité, qui est un autre identifiant @@ -413,36 +413,36 @@ On a multiplayer server with the default configuration, new players start with t There is a small set of core privileges which you'll find on every server, other privileges might be added by mods.=Il existe un petit ensemble de privilèges de base que vous trouverez sur chaque serveur, d'autres privilèges peuvent être ajoutés par les mods. To view your own privileges, issue the server command “/privs”.=Pour afficher vos propres privilèges, exécutez la commande serveur "/privs". Here are a few basic privilege-related commands:=Voici quelques commandes de base liées aux privilèges: -• /privs: Lists your privileges=• /privs: Répertorie vos privilèges -• /privs : Lists the privileges of =• /privs : Répertorie les privilèges de -• /help privs: Shows a list and description about all privileges=• /help privs: Affiche une liste et une description de tous les privilèges +• /privs: Lists your privileges=• /privs : Répertorie vos privilèges +• /privs : Lists the privileges of =• /privs : Répertorie les privilèges de +• /help privs: Shows a list and description about all privileges=• /help privs : Affiche une liste et une description de tous les privilèges Players with the “privs” privilege can modify privileges at will:=Les joueurs avec le privilège "privs" peuvent modifier les privilèges à volonté: -• /grant : Grant to =• /grant : Accordez à -• /revoke : Revoke from =• /revoke : Révoquer de +• /grant : Grant to =• /grant : Accordez à +• /revoke : Revoke from =• /revoke : Révoquer de In single-player mode, you can use “/grantme all” to unlock all abilities.=En mode solo, vous pouvez utiliser "/grantme all" pour débloquer toutes les capacités. Light=Lumière 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).=Comme le monde est entièrement basé sur des blocs, la lumière du monde l'est également. Chaque bloc a sa propre luminosité. La luminosité d'un bloc s'exprime dans un "niveau de lumière" qui varie de 0 (obscurité totale) à 15 (aussi lumineux que le soleil). -There are two types of light: Sunlight and artificial light.=Il existe deux types de lumière: La lumière du soleil et la lumière artificielle. +There are two types of light: Sunlight and artificial light.=Il existe deux types de lumière : La lumière du soleil et la lumière artificielle. Artificial light is emitted by luminous blocks. Artificial light has a light level from 1-14.=La lumière artificielle est émise par des blocs lumineux. La lumière artificielle a un niveau de lumière de 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.=La lumière du soleil est la lumière la plus brillante et descend toujours parfaitement directement du ciel à chaque heure de la journée. La nuit, la lumière du soleil deviendra le clair de lune à la place, qui fournit toujours une petite quantité de lumière. Le niveau de lumière solaire est de 15. Blocks have 3 levels of transparency:=Les blocs ont 3 niveaux de transparence: -• Transparent: Sunlight goes through limitless, artificial light goes through with losses=• Transparent: La lumière du soleil passe sans limite, la lumière artificielle passe avec des pertes -• Semi-transparent: Sunlight and artificial light go through with losses=• Semi-transparent: La lumière du soleil et la lumière artificielle subissent des pertes -• Opaque: No light passes through=• Opaque: Aucune lumière ne passe +• Transparent: Sunlight goes through limitless, artificial light goes through with losses=• Transparent : La lumière du soleil passe sans limite, la lumière artificielle passe avec des pertes +• Semi-transparent: Sunlight and artificial light go through with losses=• Semi-transparent : La lumière du soleil et la lumière artificielle subissent des pertes +• Opaque: No light passes through=• Opaque : Aucune lumière ne passe Artificial light will lose one level of brightness for each transparent or semi-transparent block it passes through, until only darkness remains (image 1).=La lumière artificielle perdra un niveau de luminosité pour chaque bloc transparent ou semi-transparent qu'elle traverse, jusqu'à ce qu'il ne reste que l'obscurité (image 1). Sunlight will preserve its brightness as long it only passes fully transparent blocks. When it passes through a semi-transparent block, it turns to artificial light. Image 2 shows the difference.=La lumière du soleil conservera sa luminosité tant qu'elle ne passera que par des blocs entièrement transparents. Lorsqu'il passe à travers un bloc semi-transparent, il se transforme en lumière artificielle. L'image 2 montre la différence. Note that “transparency” here only means that the block is able to carry brightness from its neighboring blocks. It is possible for a block to be transparent to light but you can't see trough the other side.=Notez que la "transparence" ici signifie uniquement que le bloc est capable de transporter la luminosité de ses blocs voisins. Il est possible qu'un bloc soit transparent à la lumière mais vous ne pouvez pas voir à travers l'autre côté. Coordinates=Coordonnées The 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.=Le monde est un grand cube. Et pour cette raison, une position dans le monde peut être facilement exprimée avec des coordonnées cartésiennes. Autrement dit, pour chaque position dans le monde, il existe 3 valeurs X, Y et Z. -Like this: (5, 45, -12)=Comme ceci: (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.=Cela fait référence à la position où X@=5, Y@=45 et Z@=-12. Les 3 lettres sont appelées "axes": Y est pour la hauteur. X et Z sont pour la position horizontale. +Like this: (5, 45, -12)=Comme ceci : (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.=Cela fait référence à la position où X@=5, Y@=45 et Z@=-12. Les 3 lettres sont appelées “axes” : Y est pour la hauteur. X et Z sont pour la position horizontale. The values for X, Y and Z work like this:=Les valeurs pour X, Y et Z fonctionnent comme ceci: • If you go up, Y increases=• Si vous montez, Y augmente • If you go down, Y decreases=• Si vous descendez, Y diminue • If you follow the sun, X increases=• Si vous suivez le soleil, X augmente • If you go to the reverse direction, X decreases=• Si vous allez dans le sens inverse, X diminue -• Follow the sun, then go right: Z increases=• Suivez le soleil, puis allez à droite: Z augmente -• Follow the sun, then go left: Z decreases=• Suivez le soleil, puis allez à gauche: Z diminue +• Follow the sun, then go right: Z increases=• Suivez le soleil, puis allez à droite : Z augmente +• Follow the sun, then go left: Z decreases=• Suivez le soleil, puis allez à gauche : Z diminue • The side length of a full cube is 1=• La longueur latérale d'un cube complet est de 1 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]). @@ -458,7 +458,7 @@ Enabling Creative Mode in MineClone 2 applies the following changes:=L'activatio • Tools don't wear off=• Les outils ne s'usent pas • You can eat food whenever you want=• Vous pouvez manger de la nourriture quand vous le souhaitez • You can always use the minimap (including radar mode)=• Vous pouvez toujours utiliser la minicarte (y compris le mode radar) -Damage is not affected by Creative Mode, it needs to be disabled separately.=Les dommages ne sont pas affectés par le mode créatif, ils doivent être désactivés séparément. +Damage is not affected by Creative Mode, it needs to be disabled separately.=Les dégâts ne sont pas affectés par le mode créatif, ils doivent être désactivés séparément. Mobs=Mobs Mobs are the living beings in the world. This includes animals and monsters.=Les mobs sont les êtres vivants du monde. Cela inclut les animaux et les monstres. 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).=Les mobs apparaissent de manière aléatoire à travers le monde. C'est ce qu'on appelle l'"apparition". Chaque type de mob apparaît sur des types de blocs particuliers à un niveau de lumière donné. La hauteur joue également un rôle. Les mobs pacifiques ont tendance à apparaître à la lumière du jour tandis que les hostiles préfèrent l'obscurité. La plupart des mobs peuvent apparaître sur n'importe quel bloc solide, mais certains n'apparaissent que sur des blocs particuliers (comme les blocs d'herbe). @@ -469,12 +469,12 @@ Animals are peaceful beings which roam the world aimlessly. You can feed, tame a Feeding:=Alimentation: Each animal has its own taste for food and doesn't just accept any food. To feed, hold an item in your hand and rightclick the animal.=Chaque animal a son propre goût pour la nourriture et n'accepte pas n'importe quelle nourriture. Pour vous nourrir, tenez un objet dans votre main et faites un clic droit sur l'animal. Animals are attraced to the food they like and follow you as long you hold the food item in hand.=Les animaux sont attirés par la nourriture qu'ils aiment et vous suivent aussi longtemps que vous tenez l'aliment en main. -Feeding an animal has three uses: Taming, healing and breeding.=Nourrir un animal a trois usages: Apprivoiser, guérir et se reproduire. +Feeding an animal has three uses: Taming, healing and breeding.=Nourrir un animal a trois usages : Apprivoiser, guérir et se reproduire. Feeding heals animals instantly, depending on the quality of the food item.=Nourrir les animaux guérit instantanément, selon la qualité de l'aliment. Taming:=Apprivoisement: 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.=Quelques animaux peuvent être apprivoisés. Vous pouvez généralement faire plus de choses avec des animaux apprivoisés et utiliser d'autres objets dessus. Par exemple, les chevaux apprivoisés peuvent être sellés et les loups apprivoisés se battent à vos côtés. Breeding:=Reproduction: -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.=Lorsque vous avez nourri un animal à sa santé maximale, puis le nourrir à nouveau, vous activerez le "Mode Amour" et de nombreux coeurs apparaissent autour de l'animal. +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.=Lorsque vous avez nourri un animal à sa santé maximale, puis le nourrir à nouveau, vous activerez le "Mode Amour" et de nombreux cœurs apparaissent autour de l'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.=Deux animaux de la même espèce commenceront à se reproduire s'ils sont en mode Amour et proches l'un de l'autre. Bientôt, un bébé animal apparaîtra. Baby animals:=Bébés animaux: 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.=Les bébés animaux sont comme leurs homologues adultes, mais ils ne peuvent pas être apprivoisés ou élevés et ne laissent rien tomber lorsqu'ils meurent. Ils deviennent adultes après peu de temps. Une fois nourris, ils deviennent plus vite adultes. @@ -490,7 +490,7 @@ Core hunger rules:=Règles fondamentales de la faim: • At 0 hunger points, you lose 1 HP every 4 seconds (down to 1 HP)=• À 0 point de faim, vous perdez 1 PV toutes les 4 secondes (jusqu'à 1 PV) • Poisonous food decreases your health=• La nourriture toxique diminue votre santé Details:=Détails: -You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=Vous avez 0-20 points de faim, indiqués par 20 demi-icônes de pilon de Poulet au-dessus de la hotbar. Vous avez également un attribut invisible: La saturation. +You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=Vous avez 0-20 points de faim, indiqués par 20 demi-icônes de pilon de Poulet au-dessus de la hotbar. Vous avez également un attribut invisible : La saturation. Hunger points reflect how full you are while saturation points reflect how long it takes until you're hungry again.=Les points de faim reflètent à quel point vous êtes plein tandis que les points de saturation reflètent le temps qu'il vous faut avant d'avoir à nouveau faim. Each food item increases both your hunger level as well your saturation.=Chaque aliment augmente à la fois votre niveau de faim et votre saturation. Food with a high saturation boost has the advantage that it will take longer until you get hungry again.=Les aliments avec une augmentation de saturation élevée ont l'avantage de prendre plus de temps jusqu'à ce que vous ayez de nouveau faim. 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 new file mode 100644 index 000000000..bde6e2152 --- /dev/null +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.ja.tr @@ -0,0 +1,511 @@ +# textdomain: mcl_doc_basics +Basics=基礎編 +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:=基本的なゲームプレイの簡素な紹介: +Basic controls:=基本操作: +• 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=・[Space]でジャンプ / 上昇 +• [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=・インベントリ最後尾のアイテムが、下のホットバーに表示される +• [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枚クラフト +• 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=・石を掘れるようになるために、木製のツルハシをクラフト +• 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(マインテスト) +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のオリジナルは、Perttu Ahola (別名"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の中核を成すのは、組み込みのMOD(モディファイ)機能です。MODとは、既存のゲームプレイを改造するものです。装飾ブロックを追加するだけの簡単なものから、全く新しいゲームプレイコンセプトを導入したり、全く異なる種類の世界を生成したりする非常に複雑なものまで、多岐にわたります。 +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は、一人でプレイすることも、複数のプレイヤーと一緒にオンラインでプレイすることも可能です。サーバーが全てを提供するため、どんなMODでもオンラインプレイはそのまま動作し、追加のソフトウェアも要りません。 +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の公式フォーラム からダウンロードできます。 +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] +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.=スニーキングはMODによって無効化される場合があります。この場合、歩行の鈍化は残りますが、崖っぷちに留まる機能は無くなっています。 +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:走る +While standing on solid ground:=固い地面に立ちながら: +• Space: Jump=・Space:ジャンプ +• Shift: Sneak=・Shift:スニーク +While on a ladder, swimming in a liquid or fly mode is active=ハシゴに登上・液中で遊泳・飛行モードが有効などの間: +• Space: Move up=・Space:上昇 +• 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:高速モードで早歩き +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:アイテムを一個単位でドロップ +• I: Show/hide inventory menu=・I:インベントリメニューの表示/非表示 +Inventory interaction:=インベントリでの作用: +See the entry “Basics > Inventory”.=エントリー“Basics > Inventory”を参照の事。 +Camera:=カメラ: +• 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:スクリーンショットを撮る +Server interaction:=サーバーでの作用: +• 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:開発者のみに有用。現在のスタックトレースを書き込む +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 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=・直接ダメージを与えるブロックに触れる +• 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.=体力が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.=いくつかの溺れる効果のあるブロックに頭を入れている間は、2秒ごとにBP(ブレスポイント)が1ずつ減少します。息がなくなると、溺水ダメージを受けるようになります。そのほかのブロックではすぐに呼吸が回復します。 +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.=アイテムスタックとは、1つのアイテムスロットに入る、同一種アイテムのまとまりです。アイテムスタックは地面に落とせます。同じ座標にドロップしたアイテムは、アイテムスタックを形成します。 +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アイテムスタックに収まるアイテム数 +• Pointing range: How close things must be to be pointed while wielding this item=・ポイント範囲:このアイテムを手に持っている時、モノがどのくらい近くにあればポイントできるか +• Group memberships: See “Basics > Groups”=・グループのメンバーシップ:“Basics > Groups”参照 +• 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.=道具の中の分類で一般的なのは、採掘道具です。これらは、あらゆるブロックを壊すために重要です。武器も道具の一種です。もちろん、他にも多くの道具があります。道具の特殊な操作は、通常、左クリックか右クリックで行います。 +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”.=多くの道具は使っていると消耗していき、ついには壊れてしまうこともあります。ダメージは、道具のアイコンの下にあるダメージバーで表示されます。ダメージバーが表示されていない場合、その道具は新品同様です。道具はクラフトで修理できる場合があります。“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:=近接武器は、プレイヤーや他のMOBを叩くことでダメージを与えることができます。攻撃方法は次の2つ: +• Single punch: Left-click once to deal a single punch=・単発攻撃:左クリック1回で、単一の攻撃 +• Quick punching: Hold down the left mouse button to deal quick repeated punches=・連続攻撃:マウスの左ボタンを押したままで、攻撃を素早く繰り返す +There are two core attributes of melee weapons:=近接武器の核となる性質は次の2つ: +• 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.=時々、攻撃が不可能になるルール:プレイヤー、MOB、武器はダメージグループに属します。武器は、少なくとも1つのダメージグループを共有している相手にしか、ダメージを与えません。なので使う武器が悪いと、なんのダメージも与えられないことがあります。 +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人称視点のフロントカメラでは、ポイントする事はできません。 +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つの視点があります。モードは次のとおり: +• 1: First-person view (default)=・1:一人称視点(デフォルト) +• 2: Third-person view from behind=・:背後からの三人称視点 +• 3: Third-person view from the front=・:前面からの三人称視点 +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]を押すと十字線に沿った視界をズームできる、かもしれません。これによって、より遠くを望めます。 +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] +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.=ワールドは、すべてがブロック(正確にはボクセル)で構成されています。ブロックは、適切なツールで追加や削除ができます。 +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=・よじ登り可能:よじ登り可能なブロックにいる間は落下せず、ジャンプキーとスニークキーで上下に移動できる +• Drowning damage: See the entry “Basics > Player”=・溺水ダメージ:エントリー“Basics > Player”参照 +• Liquids: See the entry “Basics > Liquids”=・液体:エントリー“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:=採掘後、ブロックが「ドロップ」を残すことがあります。これは、採掘後に得られるアイテムの数々です。最も一般的なのは、そのブロックそのものを入手することです。その他にも、ブロックの種類によってドロップの可能性があります。考えられるドロップは次の通り: +• Always drops itself (the usual case)=・常にそれ自身をドロップ(大抵の場合) +• Always drops the same items=・常に同じアイテムをドロップ +• 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.=手に持ったブロックを構築するには、ワールド内のブロックをポイントして右クリックします。これができない場合は、ポイントしたブロックが特殊な右クリックアクションを持っているせいである為、スニークキーを押しながら右クリックしてください。 +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.=通常、ブロックはポイントした側を前にして構築されます。一部の違うブロック:そのブロックに向かって構築しようとすると、置き換えられます。 +Liquids=液体 +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).=液体が通常取りうる2つの形態:源泉型(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.=流動液体は、傾斜した形状をとります。それらは枯渇するまでワールド中に広がります。流動液体は自身を維持できず、常に直接的または間接的に液体源から生じます。液体源がなければ、流動液体はやがて流出しきって消えます。 +All liquids share the following properties:=すべての液体に共通するプロパティは次のとおり: +• All properties of blocks (including drowning damage)=・ブロックのプロパティ全般(溺水ダメージ含む) +• Renewability: Renewable liquids can create new sources=・再生可能性:再生可能な液体は、新たな源泉を生み出せる +• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2=・流動範囲:液体源1つにつき、最大でどれだけの流動液体を生むか、液体がどこまで広がるかの設定。可能な範囲は0から8まで。0の場合、流動液体は発生しない。画像5は、流動範囲2の液体 +• Viscosity: How slow players move through it and how slow the liquid spreads=・粘性:プレイヤーがその中を移動する際の遅さ、液体が広がる際の遅さ +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=・同じ種類の再生可能な液体ブロック2個が、斜めに接する +• These blocks are also on the same height=・これらのブロックも同じ高さにある +• One of the two “corners” is open space which allows liquids to flow in=・2つの「かど」のうち1つは、液体が流れ込む空きスペース +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=液中に落ちると衝撃で速度が落ちる(但し瞬時には止まらない)。衝撃の深さは、速度と液体の粘性によって決まる。液体へ安全に高飛び込みするには、地面より上に十分な液体があることを確認する。そうでなければ、地面に衝突して落下ダメージを受ける可能性がある +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.=何かをクラフトするには、1つ以上のアイテム、クラフトグリッド(C)、クラフトレシピが必要です。クラフトグリッドは通常のインベントリのようなもので、クラフトにも使えます。アイテムは、クラフトグリッドに一定のパターンで配置する必要があります。クラフトグリッドの隣には、アウトプットスロット(O)があります。ここにアイテムを正しく配置すると、結果が表示されます。これはあくまでプレビューであり、実際のアイテムではありません。クラフトグリッドの大きさはまちまちなため、クラフトできるレシピが制限されたりもします。 +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).=アイテムのクラフト方法を記したものを「クラフトレシピ」と呼びます。この知識は、クラフトをするのに必要です。クラフトレシピを覚えるには、複数の方法があります。1つは、クラフトレシピの使用可能なリストを含むクラフトガイドを使用する方法です。いくつかのゲームではクラフトガイドを提供しています。また、クラフトガイドをインストールするために、オンラインでダウンロードできるMODがいくつかあります。もう1つの方法は、ゲームのオンラインマニュアルを読むことです(利用可能な場合)。 +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.=クラフトレシピは、少なくとも1つの入力アイテムと、ちょうど1つの出力アイテムのスタックから成ります。1つのクラフトを実行するとき、クラフトレシピが置換を定義していない限り、クラフトグリッドの各スタックから正確に1つのアイテムを消費します。 +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):アイテムは入力のどこかしらに置く必要がある(両画像とも同じレシピを表示) +• Cooking: Explained in “Basics > Cooking”=・調理:“Basics > Cooking”に解説あり +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=修復(画像5):損傷した道具を2つ、任意のクラフトグリッドに置くと、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.=・クラフトレシピの中には、入力アイテムが具体的でなくてもよいものがあり、その代わりグループに属している必要があります(“Basics > Groups”参照)。これらのレシピでは、入力アイテムにいくらか自由度があります。画像6-8は、同じグループ基準のレシピを示したものです。ここでは"stone "グループのアイテムが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.=まれに、クラフトレシピには置換があります。これは、クラフトを実行するたびに、クラフトグリッド内の一部のアイテムが消費されず、代わりに別のアイテムに置き換わることを意味します。 +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.=各燃料には燃焼時間があります。これは、1つの燃料がかまどの燃焼を維持する時間です。 +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.=画面の下に、いくつか四角いものが見えます。これは「ホットバー」と呼ばれるものです。ホットバーを使うと、インベントリの初段のアイテムに素早くアクセスできます。 +You can change the selected item with the mouse wheel or the keyboard.=選択した項目は、マウスホイールやキーボードで変更できます。 +• Select previous item in hotbar: [Mouse wheel up] or [B]=・ホットバーの選択項目を前へ:[マウスホイール上] or [B] +• Select next item in hotbar: [Mouse wheel down] or [N]=・ホットバーの選択項目を次へ:[マウスホイール下] or [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.=ホットバーのいずれかのスロットにマップアイテムがある場合、ミニマップが使えます。 +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.=また、2種類の回転モードがあります。「正方形モード」では、ミニマップの回転は固定されています。[Shift] + [F9]を押して「円形モード」に切り替えると、ミニマップはあなたの視線方向に合わせて回転し、常に「上」があなたの視線方向となります。 +In some games, the minimap may be disabled.=ゲームによっては、ミニマップが無効になっている場合があります。 +• 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.=インベントリは、アイテムスタックを収納するために使います。他にもクラフトなどの用途があります。インベントリは、アイテムスロットの四角いグリッドで構成されています。各アイテムスロットは、空の状態か、1つのアイテムスタックを保持できます。アイテムのスタックは、ほとんどのスロット間で自由に移動できます。 +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=・スニークキー + 左クリック:アイテムスタックの自動転送 +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 の最新バージョンを確認し、意見を交換できます。 +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.=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 の資料も掲載されています。 +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 に関連するあらゆることを話し合える、Webベースの議論場です。また、プレイヤーが作成したMODやゲームを公開し、議論する場でもあります。議論は主に英語で行われますが、他言語で議論するスペースもあります。 +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.=Minetest に関連するあらゆることをリアルタイムで議論するために人々が集う、IRC(インターネット・リレー・チャット)の汎用チャンネルです。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=・掘削時間:掘削可能なブロックが属するグループで、掘削時間の設定に使われる。採掘道具は、所定のグループに属するブロックが掘れる。 +• 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”=ダメージと防具:オブジェクトとプレイヤーは防具グループ、武器はダメージグループを持つ。これらのグループによってダメージが定まる。次も参考に:“Basics > Weapons” +• Other uses=・その他の用途 +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=・手に持つ:アイテムを手に持っている状態。ホットバーで選択した状態と同義 +• 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=・構築/配置:ブロックをどこかに置くこと +• 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=・インベントリ:保管用に複数のスロットを提供するもの +• 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=・クラフトアイテム:クラフトに(主に、または唯一)使用されるアイテム +Gameplay:=ゲームプレイ: +• “heart”: A single health symbol, indicates 2 HP=・「ハート」:ヘルス。マーク1つ分で 2 HP を示す +• “bubble”: A single breath symbol, indicates 1 BP=・「泡」:呼吸。マーク1つ分で 1 BP を示す +• HP: Hit point (equals half 1 “heart”)=・HP:ヘルスポイント。「ハート」マーク半分で 1 HP を示す +• BP: Breath point, indicates breath when diving=・BP:ブレスポイント。潜水時の息(酸素量)を示す +• Mob: Computer-controlled enemy=・MOB:コンピュータが操作する敵 +• 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=・リスポーン:死後、再びワールドに現れること +• Group: Puts similar things together, often affects gameplay=・グループ:似たようなものを、同類として扱う。しばしばゲームプレイに影響を与える +• noclip: Allows to fly through walls=・壁抜け:壁を通過し飛行を可能にする +Interface=インターフェイス +• 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=・保護:ワールドの各エリアを所有する仕組み。エリア内部のブロックは、所有者のみが変更可能となる +Technical terms:=技術的な用語: +• Minetest: This game engine=・Minetest:マインテスト。本ゲームエンジン +• MineClone 2: What you play right now=・MineClone 2:マインクローン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つのサブシステム。ゲームの基本的な構成要素であり、ゲームをさらに強化または変更するために使用できる +• Privilege: Allows a player to do something=・権限:プレイヤーにかかる何らかの制限を解除するための許可 +• 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):“Player vs Player”の略。有効にすると、プレイヤー同士がダメージを与え合うことが可能になる +For a full list of all available settings, use the “All Settings” dialog in the main menu.=利用可能なすべての設定の一覧は、メインメニューの「すべての設定」ダイアログを使用してください。 +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] +• 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.=・説明:より高速な移動が可能になります。「使う」キー[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] +• Required privilege: fly=・必要な権限:fly +Noclip mode:=壁抜けモード: +• Description: Allows you to move through walls. Only works when fly mode is enabled, too.=・説明:壁を通過して移動できるようになります。飛行モードも有効な場合のみ機能します。 +• 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 ”と言うと、だけが見ることができる“”を送れます。 +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]:下にスクロール +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=・[Up]:履歴の、前のエントリに移動 +• [Down]: Go to next entry in history=・[Down]:履歴の、次のエントリに移動 +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 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.=サーバーコマンドは、プレイヤーがチャットを使って入力することで、特別なサーバーアクションを実行できます。いくつかのコマンドは誰でも出すことができますが、中にはサーバーに与えられた特定の権限を持っている場合にのみ動作するコマンドもあります。基本的なコマンドは常に利用可能で、その他のコマンドはMODによって追加できます。 +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”コマンドを入力してください。このサーバーで利用可能なMODのリストが表示されます。 +“/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=・大なりと小なり記号で挟まれたテキスト(例:“”):パラメータのプレースホルダー +• Anything in square brackets (e.g. “[text]”) is optional and can be omitted=・角括弧内のもの(例:“[text]”):任意であり、省略が可能 +• Pipe or slash (e.g. “text1 | text2 | text3”): Alternation. One of multiple texts must be used (e.g. “text2”)=・パイプまたはスラッシュ(例:“text1|text2|text3”):択一。 区切られたテキストのうちの1つを使用する必要あり(例:"text2") +• Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=・半角の括弧(例:“(word1 word2) | word3”):複数の単語をグループ化し、交互に使う +• 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”とだけ入力する +• /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 :2つのパラメータ。例“/give Player default: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 time”のように、“/help ”の後にコマンド名を続けたもの +• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=・/spawnentity [,,]:有効な入力は“/spawnentity boats:boat”および“/spawnentity 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 にはエンティティ名が必要で、これは別の識別子です +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”権限は、チャットを行うためのものです。 +There is a small set of core privileges which you'll find on every server, other privileges might be added by mods.=すべてのサーバーで見られる主要な権限の小セットがあり、その他の権限はModによって追加される場合があります。 +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 の権限の一覧 +• /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).=世界がすべてブロックベースである以上、世界の光もまた然りです。各ブロックはそれぞれの明るさを持ちます。ブロックの明るさは“light level”(=明るさ)で表され、0(真っ暗)から15(太陽と同じ明るさ)までの範囲で設定できます。 +There are two types of light: Sunlight and artificial light.=光には2つの種類があります:太陽光と人工光です。 +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です。 +Blocks have 3 levels of transparency:=ブロックは3段階の透明度を持ちます: +• Transparent: Sunlight goes through limitless, artificial light goes through with losses=・透明:太陽光は無限に通過し、人工光は損失を伴って通過する +• Semi-transparent: Sunlight and artificial light go through with losses=・半透明:太陽光と人工光は損失を伴って通過する +• Opaque: No light passes through=・不透明:光を通さない +Artificial light will lose one level of brightness for each transparent or semi-transparent block it passes through, until only darkness remains (image 1).=人工光は、透明または半透明のブロックを通過するたびに明るさが1段階下がり、やがて暗闇だけが残ります(画像1)。 +Sunlight will preserve its brightness as long it only passes fully transparent blocks. When it passes through a semi-transparent block, it turns to artificial light. Image 2 shows the difference.=太陽光は、完全に透明なブロックだけを通過する限り、その明るさを保てます。半透明のブロックを通過すると、人工光に変化します。画像2 はその違いを示しています。 +Note that “transparency” here only means that the block is able to carry brightness from its neighboring blocks. It is possible for a block to be transparent to light but you can't see trough the other side.=なお、ここでいう「透明度」とは、隣接するブロックの明るさを伝達できるという意味でしかありません。ブロックが光に対して透明でも、あなたは向こう側が見通せないということはあり得ます。 +Coordinates=座標 +The 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.=世界は大きな立方体です。そのため、世界における位置は直交座標で簡単に表せます。つまり、世界の各位置には、X、Y、Zの3つの値が存在します。 +Like this: (5, 45, -12)=こんな感じで:(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.=これは、X@=5、Y@=45、Z@=12 の位置を指します。この3文字を“軸”と呼びます:Yは高さ、XとZは水平方向の位置を表します。 +The values for X, Y and Z work like this:=X、Y、Zの値は次のように動きます: +• If you go up, Y increases=・上昇すると、Yが増加 +• If you go down, Y decreases=・下降すると、Yが減少 +• If you follow the sun, X increases=・太陽の進行方向にならうと、Xが増加 +• If you go to the reverse direction, X decreases=・逆方向へ行くと、Xは減少 +• Follow the sun, then go right: Z increases=・太陽に向かって、右に進む:Zが増加 +• Follow the sun, then go left: Z decreases=・太陽に向かって、左に進む:Zが減少 +• The side length of a full cube is 1=・完全な立方体の辺の長さは、1 +You can view your current position in the debug screen (open with [F5]).=デバッグ画面([F5]で開く)にて現在位置を確認できます。 + +# MCL2 extensions +Creative Mode=クリエイティブモード +Enabling Creative Mode in MineClone 2 applies the following changes:=MineClone 2 で Creative Mode を有効にすると、以下の変更が適用されます: +• You keep the things you've placed=・あなたが置いたものを保つ +• Creative inventory is available to obtain most items easily=・ほとんどのアイテムを簡単に入手できるクリエイティブインベントリが利用可能 +• Hand breaks all default blocks instantly=・すべてのデフォルトブロックを手で即座に壊せる +• Greatly increased hand pointing range=・手のポイント範囲の大幅な拡大 +• Mined blocks don't drop items=・採掘されたブロックがアイテムをドロップしない +• Items don't get used up=・アイテムを使い切ることがない +• Tools don't wear off=・道具が消耗しない +• You can eat food whenever you want=・食べたい時にいつでも食べられる +• You can always use the minimap (including radar mode)=・常にミニマップが使える(レーダーモード含む) +Damage is not affected by Creative Mode, it needs to be disabled separately.=ダメージはクリエイティブモードの影響を受けないので、別途無効化する必要があります。 +Mobs=MOB +Mobs are the living beings in the world. This includes animals and monsters.=MOBとは、世界に存在する生き物のことです。動物やモンスターも含まれます。 +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).=MOBは世界各地にランダムに出現します。これを「スポーンする」と言います。各MOBは特定のブロックに、特定の明るさにおいて出現します。また、高さも重要な要素です。平和的なMOBは昼間に出現し、敵対的なMOBは暗闇を好む傾向があります。ほとんどのMOBはどの固体ブロックにもスポーンできますが、特定のブロック(草原のような)にしかスポーンしないMOBもいます。 +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.=プレイヤーと同様に、MOBにもヒットポイントがあり、時にはアーマーポイントもあります(ということは、ダメージを与えるにはより良い武器が必要です)。また、プレイヤーと同様に、敵対するMOBは直接攻撃することも距離を取って攻撃することもできます。MOBは死んだ後、ランダムなアイテムをドロップすることがあります。 +Most animals roam the world aimlessly while most hostile mobs hunt players. Animals can be fed, tamed and bred.=ほとんどの動物があてもなく世界をさまよい、ほとんどの敵対的なMOBがプレイヤーを狩ります。動物には餌を与え、飼いならし、繁殖させることができます。 +Animals=動物 +Animals are peaceful beings which roam the world aimlessly. You can feed, tame and breed them.=動物たちは、世界をあてもなく歩き回る平和な存在です。餌をあげたり、飼いならしたり、繁殖させたりすることができます。 +Feeding:=餌やり: +Each animal has its own taste for food and doesn't just accept any food. To feed, hold an item in your hand and rightclick the animal.=動物にはそれぞれ食べ物の好みがあり、どんな食べ物でもいいというわけではありません。餌を与えるには、アイテムを手に持ち、動物を右クリックします。 +Animals are attraced to the food they like and follow you as long you hold the food item in hand.=動物は好きな食べ物に惹かれ、餌を手にしている間はついてきます。 +Feeding an animal has three uses: Taming, healing and breeding.=動物の給餌には3つの用途があります:飼いならす、癒す、繁殖させる +Feeding heals animals instantly, depending on the quality of the food item.=餌を与えると、餌の質にもよりますが、動物がすぐに回復します。 +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.=同じ種の2匹の動物は、ラブモード状態で近くにいると交配を始めます。すぐに動物の赤ちゃんが飛び出します。 +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:=満腹度の基礎: +• You start with 20/20 hunger points (more points @= less hungry)=・20/20 の満腹度でスタート(ポイントが多い @= 空腹に長く耐えられる) +• 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のとき、4秒ごとにHPが1回復. +• 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になると、4秒ごとにHPが1減少(HP1まで) +• 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個分の骨付き肉(アイコン半分で1個分)がそれを示しています。また、見えない属性も持っています:隠し満腹度 +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.=いくつかの食べ物で、偶然にも食中毒を誘発することがあります。食中毒にかかると、ヘルスと満腹ゲージが病的な緑色になります。食中毒になると毎秒1HPずつ消耗しますが、減るのは1HPまでで0にはなりません。また、食中毒は隠し満腹度も消耗します。食中毒はミルクを飲むか、しばらく経つと治ります。 +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=・HPが回復する +• Suffering food poisoning=・食中毒を起こす +• Sprint-jumping=・走りながらジャンプする +• Sprinting=・走る +• Attacking=・攻撃する +• Taking damage=・ダメージを受ける +• Swimming=・泳ぐ +• 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.=いずれかのホットバースロットにマップアイテムがあれば、ミニマップが使えます。 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 new file mode 100644 index 000000000..37fe955ca --- /dev/null +++ b/mods/HELP/mcl_doc_basics/locale/mcl_doc_basics.pl.tr @@ -0,0 +1,512 @@ +# textdomain: mcl_doc_basics +Basics=Podstawy +Everything you need to know to get started with playing=Wszystko co musisz wiedzieć by zacząć grać +Advanced usage=Zaawansowane użycie +Advanced information which may be nice to know, but is not crucial to gameplay=Zaawansowane informacje które mogą być przydatne, ale nie są niezbędne podczas grania +Quick start=Szybki start +This is a very brief introduction to the basic gameplay:=Jest to bardzo krótki wstęp do podstawowej rozgrywki: +Basic controls:=Podstawowe sterowanie: +• Move mouse to look=• Porusz myszą by się rozglądać +• [W], [A], [S] and [D] to move=• Użyj [W], [A], [S] i [D] aby się poruszać +• [E] to sprint=• Użyj [E] aby biegać +• [Space] to jump or move upwards=• Użyj [Spacja] aby skakać lub poruszać się w górę +• [Shift] to sneak or move downwards=• Użyj [Shift] aby się skradać lub poruszać w dół +• Mouse wheel or [1]-[9] to select item=• Użyj kółka myszy lub klawiszy [1]-[9] aby wybrać przedmiot +• Left-click to mine blocks or attack=• Kliknij lewym przyciskiem by kopać bloki lub atakować +• Recover from swings to deal full damage=• Poczekaj aż ochłoniesz po zamachu, aby zadać pełne obrażenia +• Right-click to build blocks and use things=• Kliknij prawym przyciskiem aby kłaść bloki lub używać rzeczy +• [I] for the inventory=• Użyj [I] aby otworzyć ekwipunek +• First items in inventory appear in hotbar below=• Pierwsze przedmioty w ekwipunku pojawią się w pasku szybkiego dostępu +• Lowest row in inventory appears in hotbar below=• Najniższy wiersz ekwipunku pojawi się w pasku szybkiego dostępu +• [Esc] to close this window=• Użyj [Esc] aby zamknąć okno +How to play:=Jak grać: +• Punch a tree trunk until it breaks and collect wood=• Uderzaj pień drzewa aż się zniszczy i zbierz drewno +• Place the wood into the 2×2 grid (your “crafting grid”) in your inventory menu and craft 4 wood planks=• Umieść drewno w siatce 2×2 (twojej "siatce do wytwarzania") w twoim ekwipunku i wytwórz 4 deski +• Place them in a 2×2 shape in the crafting grid to craft a crafting table=• Umieść je w kształt 2×2 w twojej siatce do wytwarzania i wytwórz stół rzemieślniczy +• Place the crafting table on the ground=• Umieść stół rzemieślniczy na ziemi +• Rightclick it for a 3×3 crafting grid=• Kliknij go prawym przyciskiem aby zyskać dostęp do siatki 3×3 +• Use the crafting guide (book icon) to learn all the possible crafting recipes=• Użyj przewodnika do wytwarzania (ikona książki) aby poznać wszystkie możliwe receptury do wytwarzania +• Craft a wooden pickaxe so you can dig stone=• Wytwórz drewniany kilof aby wykopać kamień +• Different tools break different kinds of blocks. Try them out!=• Różne narzędzia są w stanie zniszczyć różne typy bloków. Wypróbuj je! +• Read entries in this help to learn the rest=• Przeczytaj inne wpisy aby dowiedzieć się resztę +• Continue playing as you wish. There's no goal. Have fun!=• Graj tak jak chcesz. Nie ma żadnego celu. Miłej zabawy! +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 jest wolnym oprogramowaniem i silnikiem do gier opartych o rozgrywkę na voxelach, inspirowanym przez InfiniMinera, Minecrafta i podobnym. Minetest był oryginalnie stworzony przez Perttu Ahola (alias “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.=Gracz jest wrzucony do ogromnego świata stworzonego z sześcianów lub bloków. Te sześciany zwykle tworzą widoczny krajobraz i mogą być usuwane oraz stawiane niemal całkowicie dowolnie. Korzystając z zebranych przedmiotów nowe narzędzia i inne rzeczy mogą zostać utworzone. Gry w Minetest mogą jednak być dużo bardziej skomplikowane niż to. +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.=Główną cechą Minetesta jest wbudowana możliwość budowania. Mody modyfikują istniejącą rozgrywkę. Mogą być tak proste jak dodanie kilku bloków dekoracyjnych, lub bardzo skomplikowane np. wprowadzając zupełnie nowe sposoby rozgrywki, generując zupełnie inny rodzaj świata i wiele innych rzeczy. +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.=W Minetest można grać samotnie lub online z kilkoma graczami. Gra online będzie działać od razu z modami, bez potrzeby dodatkowych programów jako, że są one całkowicie dostarczane przez serwer. +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 jest zwykle dystrybuowany wraz z prostą domyślną grą, nazwaną "Gra Minetest" (pokazana na obrazka 1 i 2). Prawdopodobnie już ją masz. Inne gry dla Minetesta mogą być pobrane z oficjalnych forum Minetesta . +Minetest as well as Minetest Game are both unfinished at the moment, so please forgive us when not everything works out perfectly.=Zarówno Minetest jak i Gra Minetest są aktualnie niedokończone, więc prosimy o wybaczenie jeśli nie wszystkie rzeczy działają idealnie. +Sneaking=Skradanie +Sneaking makes you walk slower and prevents you from falling off the edge of a block.=Skradanie sprawia, że chodzisz wolniej i zapobiega spadaniu z bloków. +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!=Aby się skradać przytrzymaj przycisk skradania (domyślnie: [Shift]). Gdy go puścisz, przestaniesz się skradać. Ostrożnie: Jeśli puścisz przycisk skradania na krawędzi możesz spaść! +• Sneak: [Shift]=• Skradanie: [Shift] +Sneaking only works when you stand on solid ground, are not in a liquid and don't climb.=Skradanie działa tylko gdy stoisz na stałym gruncie, nie w wodzie oraz nie podczas wspinania. +If you jump while holding the sneak key, you also jump slightly higher than usual.=Jeśli skoczysz podczas skradania, skoczysz nieco wyżej niż zwykle. +Sneaking might be disabled by mods. In this case, you still walk slower by sneaking, but you will no longer be stopped at ledges.=Skradanie może być wyłączone przez mody. W takim przypadku wciąż będziesz chodziła wolniej przy skradaniu, ale wciąż będziesz mogła spaść z bloków. +Controls=Sterowanie +These are the default controls:=To jest domyślne sterowanie: +Basic movement:=Podstawy poruszania: +• Moving the mouse around: Look around=• Poruszanie myszką: Rozglądnij się +• W: Move forwards=• W: Idź naprzód +• A: Move to the left=• A: Idź w lewo +• D: Move to the right=• D: Idź w prawo +• S: Move backwards=• S: Idź w tył +• E: Sprint=• E: Biegnij +While standing on solid ground:=Podczas stania na stałym gruncie: +• Space: Jump=• Spacja: Skok +• Shift: Sneak=• Shift: Skradanie +While on a ladder, swimming in a liquid or fly mode is active=Podczas wspinania, pływania w płynie lub aktywnego trybu latania: +• Space: Move up=• Spacja: W górę +• Shift: Move down=• Shift: W dół +Extended movement (requires privileges):=Rozszerzone poruszanie: +• J: Toggle fast mode, makes you run or fly fast (requires “fast” privilege)=• J: Przełącz tryb szybki, co umożliwia szybkie bieganie i latanie (wymaga przywileju "fast") +• K: Toggle fly mode, makes you move freely in all directions (requires “fly” privilege)=• K: Przełącz tryb latania, co umożliwia swobodne poruszanie w dowolnym kierunku (wymaga przywileju "fly") +• H: Toggle noclip mode, makes you go through walls in fly mode (requires “noclip” privilege)=• H: Przełącz tryb noclip, co umożliwia przechodzenie przez ściany w trybie latania (wymaga przywileju "noclip") +• E: Move even faster when in fast mode=• E: Poruszaj się jeszcze szybciej w trybie szybkim +• E: Walk fast in fast mode=• Poruszaj się szybciej w trybie szybkim +World interaction:=Interakcja ze światem: +• Left mouse button: Punch / mine blocks / take items=• Lewy przycisk myszy: Uderz / kop bloki / weź przedmiot +• Left mouse button: Punch / mine blocks=• Lewy przycisk myszy: Uderz / kop bloki +• Right mouse button: Build or use pointed block=• Prawy przycisk myszy: Zbuduj lub użyj wskazywany blok +• Shift+Right mouse button: Build=• Shift+Prawy przycisk myszy: Zbuduj +• Roll mouse wheel: Select next/previous item in hotbar=• Kręć kółkiem myszy: Wybierz następny/poprzedni przedmiot w pasku szybkiego dostępu +• Roll mouse wheel / B / N: Select next/previous item in hotbar=• Kręć kółkiem myszy / B / N: Wybierz następny/poprzedni przedmiot w pasku szybkiego dostępu +• 1-9: Select item in hotbar directly=• 1-9: Wybierz przedmiot z pasku szybkiego dostępu +• Q: Drop item stack=• Q: Wyrzuć grupę przedmiotów +• Shift+Q: Drop 1 item=• Shift+Q: Wyrzuć jeden przedmiot +• I: Show/hide inventory menu=• I: Pokaż/schowaj menu ekwipunku +Inventory interaction:=Interakcja z ekwipunkiem: +See the entry “Basics > Inventory”.=Zobacz wpis "Podstawy > Ekwipunek". +Camera:=Kamera: +• Z: Zoom=• Z: Przybliż +• F7: Toggle camera mode=• F7: Zmień tryb kamery +• F8: Toggle cinematic mode=• F8: Zmień na tryb kinowy +Interface:=Interfejs: +• Esc: Open menu window (pauses in single-player mode) or close window=• Esc: Otwórz okno menu (zatrzymuje grę w trybie pojedynczego gracza) lub zamknij okno +• F1: Show/hide HUD=• F1: Pokaż/ukryj interfejs +• F2: Show/hide chat=• F2: Pokaż/ukryj czat +• F9: Toggle minimap=• F9: Przełącz minimapę +• Shift+F9: Toggle minimap rotation mode=• Shift+F9: Przełącz tryb rotacji minimapy +• F10: Open/close console/chat log=• F10: Otwórz/zamknij konsolę/okno czatu +• F12: Take a screenshot=• F12: Zrób zrzut ekranu +Server interaction:=Interakcja z serwerem: +• T: Open chat window (chat requires the “shout” privilege)=• T: Otwórz okno czatu (chat wymaga przywileju "shout") +• /: Start issuing a server command=• /: Rozpocznij wpisywanie komendy serwera +Technical:=Techniczne: +• R: Toggle far view (disables all fog and allows viewing far away, can make game very slow)=• R: Przełącz tryb dalekiego widzenia (wyłącza mgłę i pozwala widzieć odległe obiekty, może znacząco spowolnić grę) +• +: Increase minimal viewing distance=• +: Zwiększ minimalny zasięg widzenia +• -: Decrease minimal viewing distance=• -: Zmniejsz minimalny zasięg widzenia +• F3: Enable/disable fog=• F3: Włącz/wyłącz mgłę +• F5: Enable/disable debug screen which also shows your coordinates=• F5: Włącz/wyłącz ekran debug'u, który pokazuje również twoje położenie +• F6: Only useful for developers. Enables/disables profiler=• F6: Przydatne tylko dla deweloperów. Włącza/wyłącza profiler +• P: Only useful for developers. Writes current stack traces=• P: Przydatne tylko dla deweloperów. Zapisuje aktualny zrzut stosu +Players=Gracze +Players (actually: “player characters”) are the characters which users control.=Gracze (właściwie "postacie graczy") są postaciami kontrolowanymi przez użytkowników. +Players are living beings. They start with a number of health points (HP) and a number of breath points (BP).=Gracze są żywymi stworzeniami. Zaczynają z pewną liczbą punktów życia (HP) oraz punktów oddechu (BP). +Players are capable of walking, sneaking, jumping, climbing, swimming, diving, mining, building, fighting and using tools and blocks.=Gracze są w stanie chodzić, skradać się, skakać, wspinać, pływać, nurkować, kopać, budować walczyć oraz korzystać z narzędzi i bloków. +Players can take damage for a variety of reasons, here are some:=Gracze mogą otrzymać obrażenia z wielu powodów, oto niektóre: +• Taking fall damage=• Obrażenia od upadku +• Touching a block which causes direct damage=• Dotknięcie bloku który zadaje obrażenia +• Drowning=• Tonięcie +• Being attacked by another player=• Zaatakowanie przez innego gracza +• Being attacked by a computer enemy=• Zaatakowanie przez przeciwnika sterowanego przez komputer +At a health of 0, the player dies. The player can just respawn in the world.=Gdy zdrowie osiągnie poziom 0, gracz umiera. Gracz może wtedy odrodzić się w świecie. +Other consequences of death depend on the game. The player could lose all items, or lose the round in a competitive game.=Inne konsekwencje śmierci zależą od gry. Gracz może stracić wszystkie przedmioty, lub stracić punkty w grze konkurencyjnej. +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.=Niektóre bloki zmniejszają oddech. Podczas przebywania w bloku powodującym topienie się, punkty oddechu są zmniejszane o 1 co 2 sekundy. Gdy punkty oddechu się skończą, gracz zacznie otrzymywać obrażenia od tonięcia. Oddech szybko odnawia się w dowolnym innym bloku. +Damage can be disabled on any world. Without damage, players are immortal and health and breath are unimportant.=Obrażenia mogą zostać wyłączone w dowolnym świecie. Bez obrażeń gracze są nieśmiertelni, a ich życie i oddech są nieistotne. +In multi-player mode, the name of other players is written above their head.=W trybie wieloosobowym imię innych graczy jest napisane powyżej ich głów. +Items=Przedmioty +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.=Przedmioty są rzeczami które możesz przenosić i przechowywać w ekwipunku. Mogą być wykorzystane do wytwarzania, przetapiania, budowania, kopania i w innych celach. Typy przedmiotów to m.in. bloki, narzędzia bronie oraz przedmioty użyteczne tylko w wytwarzaniu. +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.=Grupa przedmiotów jest zbiorem przedmiotów tego samego typu, która mieści się w jednym miejscu na przedmiot. Grupy przedmiotów mogą zostać upuszczone na ziemię. Przedmioty, które zostaną upuszczone na te same współrzędne utworzą grupę przedmiotów. +Dropped item stacks will be collected automatically when you stand close to them.=Upuszczone grupy przedmiotów zostaną podniesione automatycznie gdy staniesz w ich pobliżu. +Items have several properties, including the following:=Przedmioty mają wiele właściwości, między innymi: +• Maximum stack size: Number of items which fit on 1 item stack=• Maksymalny rozmiar grupy: Liczba przedmiotów które mieszczą się w jednej grupie +• Pointing range: How close things must be to be pointed while wielding this item=• Zasięg wskazywania: Jak blisko muszą być przedmioty aby można na nie wskazać za pomocą tego przedmiotu +• Group memberships: See “Basics > Groups”=• Przynależność do grupy: Zobacz "Podstawy > Grupy" +• May be used for crafting or cooking=• Mogą być używane do wytwarzania lub pieczenia +Tools=Narzędzia +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.=Niektóre przedmioty służą jako narzędzia gdy trzyma się je w rękach. Dowolny przedmiot, który ma specjalne użycia które mogą być bezpośrednio użyte przez jego posiadacza jest uznawany za narzędzie. +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.=Częstym podzbiorem narzędzi są narzędzia do kopania. Są one istotne przy niszczeniu różnych typów bloków. Bronie są innym rodzajem narzędzia. Jest oczywiście wiele innych możliwych narzędzi. Specjalne akcje narzędzi są zwykle aktywowane przy użyciu lewego lub prawego przycisku myszy. +When nothing is wielded, players use their hand which may act as tool and weapon.=Gdy nic nie jest trzymane, gracze używają swojej ręki, która może służyć jako narzędzie i broń. +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.=Narzędzia do kopania są istotne do niszczenia różnych bloków. Innym rodzajem narzędzi są bronie. Istnieją również inne, bardzie wyspecjalizowane narzędzia. Specjalne akcje narzędzi są zwykle wykonywane przy użyciu lewego oraz prawego przycisku myszy. +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.=Gdy nic nie jest trzymane gracze używają swojej dłoni, która może służyć za narzędzie i za broń. Ręką można uderzać co zadaje minimalne obrażenia. +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”.=Wiele narzędzi będzie się zużywać podczas używania, co w końcu sprawi, że zostaną zniszczone. Zużycie jest wyświetlane jako pasek poniżej ikony narzędzia. Jeśli pasek nie jest pokazywany, narzędzie jest w idealnym stanie. Narzędzia mogą być naprawiane przez wytwarzania, zobacz "Podstawy > Wytwarzanie". +Weapons=Bronie +Some items are usable as a melee weapon when wielded. Weapons share most of the properties of tools.=Niektóre przedmioty są przydatne jako bronie wręcz gdy trzymane. Bronie mają wiele podobnych własności co narzędzia. +Melee weapons deal damage by punching players and other animate objects. There are two ways to attack:=Bronie wręcz zadają obrażenia przy uderzaniu graczy i innych obiektów. +• Single punch: Left-click once to deal a single punch=• Pojedyncze uderzenie: Kliknij lewy przycisk myszy aby wykonać jedno uderzenie +• Quick punching: Hold down the left mouse button to deal quick repeated punches=• Szybkie uderzenia: Przytrzymaj lewy przycisk myszy aby zadać szybkie, powtarzające się uderzenia +There are two core attributes of melee weapons:=Dwie istotne cechy każdej broni wręcz: +• Maximum damage: Damage which is dealt after a hit when the weapon was fully recovered=• Maksymalne obrażenia: Obrażenia zadawane gdy broń przy uderzeniu gdy broń jest całkowicie ochłonięta +• Full punch interval: Time it takes for fully recovering from a punch=• Pełny okres uderzenia: Czas który jest potrzebny do ochłonięcia broni po uderzeniu +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.=Broń zadaje pełne obrażenia tylko gdy jest w pełni ochłonięta z poprzedniego uderzenia. W przeciwnym wypadku zadane obrażenia będą zmniejszone. To oznacza, że szybkie uderzanie jest bardzo szybkie, ale zadaje niskie obrażenia. Zauważ, że pełny okres uderzenia nie jest limitem na to jak szybko możesz atakować. +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.=Istnieje reguła która sprawia, że ataki są czasem niemożliwe: Gracze, ruchome obiekty i bronie należą do grup obrażeń. Broń zadaje obrażenia tylko tym, którzy należą do przynajmniej jednej z jej grup obrażeń. +Pointing=Wskazywanie +“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.="Wskazywanie" oznacza patrzenia na coś w zasięgu celownikiem. Wskazywanie jest wymagane podczas interakcji takich jak kopanie, uderzanie, używanie itp. Wskazywalne obiekty to między innymi bloki, gracze, przeciwnicy komputerowi i obiekty. +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.=Aby na coś wskazać musi być to w zasięgu wskazywania (zwykle nazywanym po prostu "zasięgiem") trzymanego przez ciebie przedmiotu. Gdy nic nie jest trzymane jest to zasięg domyślny. Wskazywany przedmiot będzie obrysowany lub podświetlony (w zależności od twoich ustawień). Wskazywanie nie jest możliwe gdy włączona jest przednia kamera trzecioosobowa. +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.=Na niektóre rzeczy nie można wskazywać. Większość bloków jest wskazywalna. Na niektóre bloki, np. powietrze, nie można wskazać. Inne bloki, takie jak płyny, mogą być wskazane tylko przy użyciu specjalnych przedmiotów. +Camera=Kamera +There are 3 different views which determine the way you see the world. The modes are:=Istnieją 3 różne widoki, które definiują w jaki sposób będziesz obserwował świat. Te widoki to: +• 1: First-person view (default)=• 1: Widok pierwszoosobowy (domyślny) +• 2: Third-person view from behind=• 2: Widok trzecioosobowy od tyłu +• 3: Third-person view from the front=• 3: Widok trzecioosobowy od przodu +You can change the camera mode by pressing [F7].=Możesz zmienić widok kamery naciskając [F7]. +You might be able to zoom with [Z] to zoom the view at the crosshair. This allows you to look further.=Możesz być w stanie przybliżać widok naciskając [Z]. To pozawala spojrzeć dalej w kierunku celownika. +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.=Przybliżanie jako cecha rozgrywki może być włączone lub wyłączone przez grę. Domyślnie przybliżanie jest włączone w trybie Kreatywny i wyłączone w przeciwnym przypadku. +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.=Istnieje również tryb kinowy, który może być włączony naciskając [F8]. Gdy jest on włączony ruchy kamery są bardziej wygładzone. Niektórzy gracze go nie lubią, jest to kwestia gustu. +By holding down [Z], you can zoom the view at your crosshair. You need the “zoom” privilege to do this.=Przytrzymując [Z] możesz przybliżyć widok na swoim celowniku. Potrzebujesz przywileju "zoom" aby to zrobić. +• Switch camera mode: [F7]=• Zmień widok kamery: [F7] +• 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 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ć. +• 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=• Wskazywalne: Te bloki pokażą obwód lub poświatę gdy zostaną wskazane. Ale przez niewskazywalne bloki będziesz wskazywała bloki znajdujące się za nimi. Płyny są zwykła niewskazywalne, ale można na nie wskazać przy użyciu specjalnych narzędzi. +• Mining properties: By which tools it can be mined, how fast and how much it wears off tools=• Własności kopania: Przez jakie narzędzia mogą być wykopane, jak szybko oraz jak bardzo zużyje to narzędzie +• 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=• Wspinaczkowe: Gdy jesteś obok bloków wspinaczkowych nie spadniesz, oraz możesz poruszać się w górę i w dół korzystając z przycisków do skakania i skradania. +• Drowning damage: See the entry “Basics > Player”=• Obrażenia tonięcia: Zobacz wpis "Podstawy > Gracz" +• Liquids: See the entry “Basics > Liquids”=• Płyny: Zobacz wpis "Podstawy > Płyny" +• Group memberships: Group memberships are used to determine mining properties, crafting, interactions between blocks and more=• Przynależność do grup: Przynależności do grup definiują własności kopania, wytwarzania, interakcje między blokami i wiele więcej +Mining=Kopanie +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.=Kopanie (lub wydobywanie) jest procesem niszczenia i usuwania bloków. Aby wykopać blok, wskaż na niego i przytrzymaj lewy przycisk myszy aż się zniszczy. +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.=Bloki wymagają narzędzi do kopania aby je wykopać. Różne bloki są wykopywane przez różne narzędzia, a niektóre nie mogą być wykopane przez żadne narzędzie. Najszybszym sposobem testowania jak efektowne są twoje narzędzia do kopania jest po prostu wypróbowanie ich na różnych blokach. Wszystkie przedmioty które wykopiesz zostaną upuszczone na ziemię, gotowe do podniesienia. +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:=Po wykopaniu, blok może upuścić "zrzut". Jest to kilka przedmiotów zdobytych przez kopanie. Najczęściej będzie to wykopany blok. Możliwe są inne zrzuty zależne od typu bloku. Następujące zrzuty są możliwe: +• Always drops itself (the usual case)=• Zawsze wyrzuca siebie (typowy przypadek) +• Always drops the same items=• Zawsze wyrzuca te same przedmioty +• Drops items based on probability=• Wyrzuca przedmioty z pewnym prawdopodobieństwem +• Drops nothing=• Nie wyrzuca niczego +Building=Budowanie +Almost all blocks can be built (or placed). Building is very simple and has no delay.=Prawie wszystkie bloki mogą być zbudowane (lub postawione). Stawianie jest bardzo proste i natychmiastowe. +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.=Aby postawić trzymany blok, wskaż na blok w świecie i kliknij prawy przycisk. Jeśli jest to niemożliwe, ponieważ wskazany blok ma specjalną akcję aktywowaną prawym przyciskiem myszy, przytrzymaj przycisk skradania przed kliknięciem prawego przycisku. +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.=Bloki prawie zawsze mogą być zbudowane na wskazywalnych blokach. Jednym z wyjątków są bloki przyczepione do podłogi; takie mogą być zbudowane tylko na podłodze. +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.=Zwykle, bloki są zbudowane przed wskazaną stroną wskazanego bloki. Niektóre bloki są inne: Gdy próbujesz na nich coś postawić są one tym zastępowane. +Liquids=Płyny +Liquids are special dynamic blocks. Liquids like to spread and flow to their surrounding blocks. Players can swim and drown in them.=Płyny są specjalnymi dynamicznymi blokami. Płyny lubią się rozprzestrzeniać i wpływać na otaczające bloki. Gracze mogą w nich pływać i tonąć. +Liquids usually come in two forms: In source form (S) and in flowing form (F).=Płyny zwykle pojawiają się w dwóch formach: W formie źródła (S) oraz w formie bieżącej (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.=Źródła płynów są w kształcie pełnej kostki. Źródło płynu od czasu do czasu wygeneruje bieżący formę płynu w swoim otoczeniu oraz jeśli płyn jest odnawialny, utworzy również źródła płynu. Źródło płynu podtrzymuje siebie. Tak długo jak nie jest ruszane, źródło wody zostanie w miejscu i nie kończy się. +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.=Bieżące płyny przyjmują formę ściętą. Rozprzestrzeniają się one po świecie dopóki się nie wyczerpią. Bieżący płyn nie podtrzymuje sam siebie i zawsze powstaje ze źródła płynu, bezpośrednio lub pośrednio. Bez źródła płynu, płyn bieżący prędzej czy później wyczerpie się i zniknie. +All liquids share the following properties:=Wszystkie płyny mają następujące własności: +• All properties of blocks (including drowning damage)=• Wszystkie własności bloków (włączając w to obrażenia od tonięcia) +• Renewability: Renewable liquids can create new sources=• Odnawialność: Odnawialne płyny mogą tworzyć nowe źródła +• Flowing range: How many flowing liquids are created at maximum per liquid source, it determines how far the liquid will spread. Possible are ranges from 0 to 8. At 0, no flowing liquids will be created. Image 5 shows a liquid of flowing range 2=• Zasięg płynięcia: Ile maksymalnie płynów bieżących jest utworzonych przez źródło płynu. Definiuje to jak daleko płyn może się rozprzestrzenić. Możliwe wartości są od 0 do 8. Przy 0, żadne płyny bieżące nie będą utworzone. Obrazek 5 pokazuje płyn z zasięgiem płynięcia 2 +• Viscosity: How slow players move through it and how slow the liquid spreads=• Lepkość: Jak wolno gracze poruszają się przez niego i jak wolno płyn się rozprzestrzenia +Renewable liquids create new liquid sources at open spaces (image 2). A new liquid source is created when:=Odnawialne płyny mogą tworzyć nowe źródła płynów w wolnej przestrzeni (obrazek 2). Nowe źródło płynu jest tworzone gdy: +• Two renewable liquid blocks of the same type touch each other diagonally=• Dwa odnawialne źródła płynów tego samego typu stykają się po przekątnej +• These blocks are also on the same height=• Bloki te są na tej samej wysokości +• One of the two “corners” is open space which allows liquids to flow in=• Jeden z dwóch "rogów" jest wolną przestrzenią gdzie może wpłynąć płyn +When those criteria are met, the open space is filled with a new liquid source of the same type (image 3).=Gdy te kryteria są spełnione, wolna przestrzeń jest zapełniona źródłem płynu tego samego typu (obrazek 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.=Pływanie w płynie jest całkiem proste: Klawisze chodzenia powodują ruch w danym kierunku, przycisk skakania powoduje wznoszenia, a skradania opadanie. +The physics for swimming and diving in a liquid are:=Fizyka pływania i nurkowania w płynach jest następująca: +• The higher the viscosity, the slower you move=• Im wyższa lepkość, tym wolniej się poruszasz +• If you rest, you'll slowly sink=• Jeśli się nie ruszasz, będziesz powoli opadała +• There is no fall damage for falling into a liquid as such=• Nie ma obrażeń od upadku gdy wpadniesz do płynu +• 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=• Gdy wpadasz do płynu będziesz spowolniona przy zetknięciu (ale nie natychmiast). Zanurzenie po upadku jest ustalane na podstawie twojej szybkości oraz lepkości płynu. Żeby bezpiecznie skoczyć do płynu, upewnij się, że jest go wystarczająco dużo nad ziemię. W przeciwnym wypadku możesz uderzyć w ziemię i otrzymać obrażenia od upadku. +Liquids are often not pointable. But some special items are able to point all liquids.=Płyny są zwykle niewskazywalne, ale niektóre specjalne przedmioty mogą wskazywać na płyny. +Crafting=Wytwarzanie +Crafting is the task of combining several items to form a new item.=Wytwarzanie jest procesem łączenia i przetwarzania przedmiotów aby utworzyć nowy przedmiot. +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.=Aby coś wytworzyć potrzebujesz jednego lub więcej przedmiotów, siatki do wytwarzania oraz receptury. Siatka do wytwarzania jest jak zwykły ekwipunek, który może być użyty do wytwarzania. Przedmioty muszą być ułożone w konkretny wzór w siatce do wytwarzania. Obok siatki wytwarzania jest miejsce wyjściowe (O). Tutaj pojawi się rezultat gdy poprawnie umieścisz przedmioty. Jest to tylko podgląd, a nie faktyczny przedmiot. Siatki do wytwarzania mogą mieć różne rozmiary, co ogranicza liczbę receptur które możesz wytworzyć. +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.=Aby zakończyć wytwarzanie zabierze wynikowy przedmiot z miejsca wyjściowego. Skonsumuje to przedmioty z siatki do wytwarzania i utworzy nowy przedmiot. Nie da się umieszczać przedmiotów w miejscu wyjściowym. +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).=Opis w jaki sposób uzyskać dany przedmiot nazywa się "recepturą wytwarzania". Potrzebujesz tej wiedzy do wytwarzania. Jest kilka sposobów by je poznać. Jednym z nich jest korzystanie z przewodnika do wytwarzania, który zawiera listę dostępnych receptur do wytwarzania. Niektóre gry dostarczają takie przewodniki. Istnieją także mody, które możesz pobrać z internetu dodające przewodniki. Innym sposobem jest przeczytanie instrukcji gry w internecie (jeśli taka jest dostępna). +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.=Receptury do wytwarzania składają się z przynajmniej jednego przedmiotu na wejściu i dokładnie jednej grupy przedmiotów wyjściowych. Podczas dokonywania pojedynczego wytwarzania skonsumowany zostanie dokładnie jeden przedmiot z każdej grupy w siatce wytwarzania, chyba, że receptura definiuje zamienniki. +There are multiple types of crafting recipes:=Istnieje kilka typów receptur: +• Shaped (image 2): Items need to be placed in a particular shape=• Kształtne (obrazek 2): Przedmioty muszą być ułożone w konkretny kształt +• Shapeless (images 3 and 4): Items need to be placed somewhere in input (both images show the same recipe)=• Bezkształtne (obrazki 3 i 4): Przedmioty muszą być ułożone gdzieś w wejściu (oba obrazki pokazują tę samą recepturę) +• Cooking: Explained in “Basics > Cooking”=• Pieczenie: Wyjaśnione w "Podstawy > Pieczenie" +• Repairing (image 5): Place two damaged tools into the crafting grid anywhere to get a tool which is repaired by 5%=• Naprawianie (obrazek 5): Postaw dwa uszkodzone narzędzia w siatce do wytwarzania w dowolnym miejscu aby uzyskać narzędzie naprawione o 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.=W niektórych recepturach, niektóre przedmioty wejściowe nie muszą być konkretnymi przedmiotami, tylko przynależeć do pewnej grupy (zobacz "Podstawy > Grupy"). Te receptury są nieco mniej restrykcyjne jeśli chodzi o wejściowe przedmioty. Obrazki 6-8 pokazują tę samą recepturę opartą o grupy. W tym przypadku 8 przedmiotów z grupy "kamień" są potrzebne, a wszystkie pokazane przedmioty do niej należą. +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.=Czasami, receptury mają zamienniki. To oznacza, że po wykonaniu przetwarzania, niektóre przedmioty w siatce nie będą skonsumowane, a jedynie zamienione w inny przedmiot. +Cooking=Pieczenie +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.=Pieczenie (lub przetapianie) jest formą wytwarzania, która nie wymaga siatki do wytwarzania. Pieczenie jest wykonywane przy użyciu specjalnego bloku (np. pieca), przedmiotu który można upiec, paliwa oraz czasu potrzebnego na uzyskanie nowego przedmiotu. +Each fuel item has a burning time. This is the time a single item of the fuel keeps a furnace burning.=Każdy przedmiot będący paliwem ma czas wypalania. Jest to czas przez jaki pojedynczy przedmiot tego paliwa utrzymuje piec zapalony. +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.=Każdy przedmiot możliwy do upieczenia potrzebuje czasu by zostać upieczony. Czas ten jest przypisany do typu przedmiotu i każdy przedmiot musi być "na ogniu" przez cały ten czas by uzyskać przedmiot wynikowy. +Hotbar=Pasek szybkiego dostępu +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.=Na dole swojego ekwipunku możesz zobaczyć kwadraty. To nazywa się "pasek szybkiego dostępu". Pozwala on na szybki dostęp do pierwszych przedmiotów z twojego ekwipunku. +You can change the selected item with the mouse wheel or the keyboard.=Możesz zmieniać wybrany przedmiot przy użyciu kółka myszy lub klawiatury. +• Select previous item in hotbar: [Mouse wheel up] or [B]=• Wybierz poprzedni przedmiot w pasku: [Kółko myszy w górę] lub [B] +• Select next item in hotbar: [Mouse wheel down] or [N]=• Wybierz następny przedmiot w pasku: [Kółko myszy w dół] lub [N] +• Select item in hotbar directly: [1]-[9]=• Wybierz bezpośrednio przedmiot w pasku: [1]-[9] +The selected item is also your wielded item.=Wybrany przedmiot jest również przedmiotem, który trzymasz. +Minimap=Minimapa +If you have a map item in any of your hotbar slots, you can use the minimap.=Jeśli masz przedmiot mapy w którymś z twoich miejsc na pasku szybkiego dostępu, możesz korzystać z minimapy. +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.=Naciśnij [F9] aby minimapa pojawiła się w prawym górnym rogu. Minimapa pomoże ci odnaleźć się w świecie. Naciśnij [F9] ponownie aby wybrać inny tryb minimapy i stopień przybliżenia. Minimapa pokazuje również pozycję innych graczy. +There are 2 minimap modes and 3 zoom levels.=Są 2 tryby minimapy oraz 3 stopnie przybliżenia. +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.=Tryb powierzchni (obrazek 1) jest widokiem z lotu ptaka na świat, mniej więcej odzwierciedlającym kolory bloków z których stworzony jest świat. Pokazuje tylko najwyżej położone bloki, wszystko poniżej jest ukryte, podobnie jak zdjęcie satelitarne. Tryb ten jest przydatny gdy się zgubisz. +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.=Tryb radaru (obrazek 2) jest bardziej skomplikowany. Pokazuje "gęstość" obszaru wokół ciebie i zmienia się z wysokością. Z grubsza, im bardziej zielony jest obszar, ty mniej "gęsty" jest. Czarne obszary mają wiele bloków. Użyj tego trybu by znaleźć jaskinie, ukryte obszary, ściany i więcej. Prostokątne kształty w obrazku 2 wyraźnie ujawniają pozycję lochów. +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.=Istnieją również dwa różne tryby rotacji. W "trybie kwadratowym" rotacja minimapy jest ustalona. Jeśli naciśniesz [Shift]+[F9] aby zmienić na "tryb okręgu", minimapy będzie natomiast obracać się wraz z twoim kierunkiem patrzenia. +In some games, the minimap may be disabled.=W niektórych grach minimapa może być wyłączona. +• Toggle minimap mode: [F9]=• Przełącz tryb minimapy: [F9] +• Toggle minimap rotation mode: [Shift]+[F9]=• Przełącz tryb rotacji minimapy: [Shift]+[F9] +Inventory=Ekwipunek +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.=Ekwipunki są wykorzystywane do przechowywania grup przedmiotów. Mogą być również wykorzystywane w innych celach, np. wytwarzanie. Ekwipunek składa się z prostokątnej siatki miejsc na przedmioty. Każde miejsce na przedmioty może być puste lub zapełnione jedną grupą przedmiotów. Grupy przedmiotów można dowolnie przenosić pomiędzy miejscami. +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.=Posiadasz swój własny ekwipunek nazywany "ekwipunkiem gracza", możesz go otworzyć klikając przycisk inwentarza (domyślnie: [I]). Pierwsze miejsca ekwipunku są również wykorzystywane jako miejsca na pasku szybkiego dostępu. +Blocks can also have their own inventory, e.g. chests and furnaces.=Bloki mogą mieć swój własny ekwipunek, np. skrzynie lub piece. +Inventory controls:=Sterowanie w ekwipunku +Taking: You can take items from an occupied slot if the cursor holds nothing.=Zabieranie: Możesz zabierać przedmioty z zajętego miejsca jeśli na kursorze niczego nie ma. +• Left click: take entire item stack=• Lewy przycisk: weź całą grupę przedmiotów +• Right click: take half from the item stack (rounded up)=• Prawy przycisk: weź połowę przedmiotów z grupy (zaokrąglone w górę) +• Middle click: take 10 items from the item stack=• Środkowy przycisk: weź 10 przedmiotów z grupy +• Mouse wheel down: take 1 item from the item stack=• Kółko myszy w dół: Weź 1 przedmiot z grupy +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.=Wstawianie: Możesz wstawić przedmioty w miejsce jeśli na kursorze jest przynajmniej 1 przedmiot, a wskazane miejsce jest puste lub zawiera grupę przedmiotów tego samego typu. +• Left click: put entire item stack=• Lewy przycisk: Wstaw całą grupę przedmiotów +• Right click: put 1 item of the item stack=• Prawy przycisk: Wstaw 1 przedmiot z grupy +• Right click or mouse wheel up: put 1 item of the item stack=• Prawy przycisk lub kółko myszy w górę: Wstaw 1 przedmiot z grupy +• Middle click: put 10 items of the item stack=• Środkowy przycisk: wstaw 10 przedmiotów z grupy +Exchanging: You can exchange items if the cursor holds 1 or more items and the destination slot is occupied by a different item type.=Wymienianie: Możesz wymieniać przedmioty jeśli na kursorze jest przynajmniej jeden przedmiot, a we wskazanym miejscu znajduje się grupa innych przedmiotów. +• Click: exchange item stacks=• Kliknij: wymień grupy przedmiotów +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.=Wyrzucanie: Jeśli trzymasz grupę przedmiotów i klikniesz poza menu ekwipunku, grupa przedmiotów zostanie wyrzucona w świat. +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 +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.=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. +Minetest forums: =Forum 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.=Platforma dyskusyjna, gdzie możesz porozmawiać na wszystkie tematy związane z Minetestem. Jest to również miejsce gdzie stworzone przez graczy mody i gry są publikowane i omawiane. Rozmowy są prowadzone głównie po angielsku ale jest również miejsce na rozmowy w innych językach. +Chat: =Czat: +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.=Ogólne kanał IRC na dowolny temat związany z Minetest, gdzie ludzie mogą się spotkać i rozmawiać w czasie rzeczywistym. Jeśli nie rozumiesz IRC, zobacz na Wiki społeczności by znaleźć pomoc. +Groups=Grupy +Items, players and objects (animate and inanimate) can be members of any number of groups. Groups serve multiple purposes:=Przedmioty, gracze i obiekty (ruchome i nieruchome) mogą przynależeć do dowolnej liczby grup. Grupy pełnią kilka funkcji: +• 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=• Receptury wytwarzania: Miejsca w recepturze mogą nie wymagać konkretnego przedmiotu, lecz przedmiotu, który przynależy do konkretnej grupy, lub kilku grup +• 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=• Czas kopania: Bloki które można wykopać należą do grupy, które definiują czas ich kopania. Narzędzia do kopania są w stanie kopać przedmioty należące do pewnych grup +• Block behavior: Blocks may show a special behaviour and interact with other blocks when they belong to a particular group=• Zachowanie bloku: Bloki mogą wykazywać się pewnym zachowaniem i wchodzić w interakcję z innymi blokami gdy należą do pewnych grup +• Damage and armor: Objects and players have armor groups, weapons have damage groups. These groups determine damage. See also: “Basics > Weapons”=• Obrażenia i zbroja: Obiekty i gracze mają grupy zbroi, bronie mają grupy obrażeń. Te grupy definiują obrażenia. Zobacz również: "Podstawy > Bronie" +• Other uses=• Inne użycia +In the item help, many important groups are usually mentioned and explained.=We wpisach o przedmiotach wiele istotnych grup jest zwykle wymienionych i opisanych. +Glossary=Słowniczek +This is a list of commonly used terms:=Jest to lita często używanych terminów: +Controls:=Sterowanie: +• Wielding: Holding an item in hand=• Trzymanie: Posiadanie przedmiotu w ręce +• Pointing: Looking with the crosshair at something in range=• Wskazywanie: Patrzenie na coś w zasięgu celownikiem +• Dropping: Throwing an item or item stack to the ground=• Upuszczanie: Wyrzucenie przedmiotu lub grupy przedmiotów na ziemię +• Punching: Attacking with left-click, is also used on blocks=• Uderzanie: Atakowanie lewym przyciskiem myszy, używane również na blokach +• Sneaking: Walking slowly while (usually) avoiding to fall over edges=• Skradanie: Powolne chodzenie i (zwykle) unikanie spadania z bloków +• Climbing: Moving up or down a climbable block=• Wspinanie: Wchodzenie w górę lub schodzenie w dół po wspinaczkowych blokach +Blocks:=Bloki: +• Block: Cubes that the worlds are made of=• Blok: Kostki z którego stworzony jest świat +• Mining/digging: Using a mining tool to break a block=• Kopanie/Wydobywanie: Używanie przedmiotów do kopania do niszczenia bloków +• Building/placing: Putting a block somewhere=• Budowanie/Umieszczanie: Wstawianie gdzieś bloku +• Drop: Items you get after mining a block=• Zrzut: Przedmioty uzyskane po wykopaniu bloku +• Using a block: Right-clicking a block to access its special function=• Używanie bloku: Kliknięcie prawym przyciskiem na blok aby uruchomić jego specjalną funkcję +Items:=Przedmioty: +• Item: A single thing that players can possess=• Przedmiot: Pojedyncza rzecz, którą gracz może posiadać +• Item stack: A collection of items of the same kind=• Grupa przedmiotów: Zbiór przedmiotów tego samego typu +• Maximum stack size: Maximum amount of items in an item stack=• Maksymalny rozmiar grupy: Maksymalna liczba przedmiotów w grupie przedmiotów +• Slot / inventory slot: Can hold one item stack=• Miejsce / miejsce w ekwipunku: Może przechowywać jedną grupę przedmiotów +• Inventory: Provides several inventory slots for storage=• Ekwipunek: Dostarcza kilka miejsc w ekwipunku do przechowywania +• Player inventory: The main inventory of a player=• Ekwipunek gracza: Główny ekwipunek gracza +• Tool: An item which you can use to do special things with when wielding=• Narzędzie: Przedmiot, który można wykorzystać w specjalny sposób podczas trzymania +• Range: How far away things can be to be pointed by an item=• Zasięg: Jak dalekie rzeczy mogą być wskazane przedmiotem +• Mining tool: A tool which allows to break blocks=• Narzędzie do kopania: Narzędzie pozwalające niszczyć bloki +• Craftitem: An item which is (primarily or only) used for crafting=• Przedmiot do wytwarzania: Przedmiot który jest (głównie lub tylko) wykorzystywany do wytwarzania. +Gameplay:=Rozgrywka +• “heart”: A single health symbol, indicates 2 HP=• "serce": Pojedynczy symbol zdrowia, reprezentujący 2 HP +• “bubble”: A single breath symbol, indicates 1 BP=• "bąbel": Pojedynczy symbol oddechu, reprezentujący 1 BP +• HP: Hit point (equals half 1 “heart”)=• HP: Punkt zdrowia (równy połowie serca) +• BP: Breath point, indicates breath when diving=• BP: Punkt oddechu reprezentujący ilość powietrza podczas nurkowania +• Mob: Computer-controlled enemy=• Mob: Przeciwnik sterowany przez komputer +• Crafting: Combining multiple items to create new ones=• Wytwarzanie: Łączenie kilku przedmiotów w celu uzyskania innych +• Crafting guide: A helper which shows available crafting recipes=• Przewodnik wytwarzania: Pomocniczy spis dostępnych receptur wytwarzania +• Spawning: Appearing in the world=• Spawnowanie: Pojawienie się w świecie +• Respawning: Appearing again in the world after death=• Odradzanie: Ponownie pojawienie się w świecie po śmierci +• Group: Puts similar things together, often affects gameplay=• Grupa: Łączy podobne rzeczy razem, często wpływa na rozgrywkę +• noclip: Allows to fly through walls=• noclip: Pozwala przelatywać przez ściany +Interface=Interfejs: +• Hotbar: Inventory slots at the bottom=• Pasek szybkiego dostępu: Miejsca ekwipunku na dole ekranu +• Statbar: Indicator made out of half-symbols, used for health and breath=• Pasek statusu: Wskaźniki składające się z symboli używane dla oznaczania życia oraz oddechu +• Minimap: The map or radar at the top right=• Minimapa: Mapa lub radar w prawym górnym rogu ekranu +• Crosshair: Seen in the middle, used to point at things=• Celownik: Widoczny na środku ekranu, używany do wskazywania na rzeczy +Online multiplayer:=Gra wieloosobowa w internecie: +• PvP: Player vs Player. If active, players can deal damage to each other=• PvP: Gracz kontra Gracz. Jeśli ten tryb jest aktywny, gracze mogą zadawać sobie obrażenia +• Griefing: Destroying the buildings of other players against their will=• Griefowanie: Celowe niszczenie budynków innych graczy wbrew ich woli +• 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 +• 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 +• Privilege: Allows a player to do something=• Przywilej: Pozwala graczowi coś zrobić +• Node: Other word for “block”=• Węzeł: Inna nazwa na "blok" +Settings=Ustawienia +There is a large variety of settings to configure Minetest. Pretty much every aspect can be changed that way.=Jest wiele różnych ustawień pozwalających zmodyfikować działanie Minetesta. Niemal każdy aspekt może być w ten sposób zmieniony. +These are a few of the most important gameplay settings:=Oto kilka najważniejszych ustawień dotyczących rozgrywki: +• Damage enabled (enable_damage): Enables the health and breath attributes for all players. If disabled, players are immortal=• Włączone obrażenia (enable_damage): Włącza paski zdrowia i oddechu. Jeśli wyłączone, gracze są nieśmiertelni +• 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.=• Tryb kreatywny (creative_mode): Włącza rozgrywkę w stylu piaskownicy, skupiająca się na kreatywności a nie wyzwaniach. Dokładne znaczenie zależy od gry; najczęstsze zmiany to: Zmniejszony czas kopania, łatwy dostęp do niemal wszystkich przedmiotów, narzędzie się nie wykorzystują itp. +• PvP (enable_pvp): Short for “Player vs Player”. If enabled, players can deal damage to each other=• PvP (enable_pvp): Skrót od "Player vs Player" (gracz kontra gracz). Jeśli włączone, gracze mogą zadawać sobie obrażenia +For a full list of all available settings, use the “All Settings” dialog in the main menu.=Aby zobaczyć pełną listę dostępnych ustawień, użyj przycisku "Wszystkie ustawienia" w menu głównym. +Movement modes=Tryby poruszania +You can enable some special movement modes that change how you move.=Możesz uruchomić specjalne tryby poruszania, które zmieniają sposób w jaki się przemieszczasz. +Pitch movement mode:=Alternatywny tryb poruszania bez-ważkiego: +• 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.=• Opis: Jeśli ten tryb jest włączony, klawisze ruchu będą poruszać cię prostopadle do kierunku patrzenia, gdy jesteś w płynach lub w trybie latania. +• Default key: [L]=• Domyślny przycisk: [L] +• No privilege required=• Nie potrzeba żadnego przywileju +Fast mode:=Tryb szybki: +• 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.=• Opis: Pozwala poruszać się znacznie szybciej. Przytrzymaj swój przycisk "Używania" [E] aby poruszać się szybciej. W konfiguracji klienta możesz dokładniej skonfigurować tryb szybki. +• Default key: [J]=• Domyślny przycisk: [J] +• Required privilege: fast=• Potrzebny przywilej: fast +Fly mode:=Tryb latania: +• 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.=• Opis: Grawitacja przestaje na ciebie wpływać i możesz swobodnie poruszać się w dowolnym kierunku. Użyj przycisku skoku aby się wznosić, a przycisku skradania aby opadać. +• Default key: [K]=• Domyślny przycisk: [K] +• Required privilege: fly=• Potrzebny przywilej: fly +Noclip mode:=Tryb noclip: +• Description: Allows you to move through walls. Only works when fly mode is enabled, too.=• Opis: Pozwala przechodzić przez ściany. Działa tylko gdy uruchomiony jest tryb latania. +• Default key: [H]=• Domyślny przycisk: [H] +• Required privilege: noclip=• Potrzebny przywilej: noclip +Console=Konsola +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.=Naciskając [F10] możesz otworzyć i zamknąć konsolę. Głównym zastosowaniem konsoli jest wyświetlenie czatu oraz wysyłanie wiadomości lub wpisywanie komend serwera. +Using the chat or server command key also opens the console, but it is smaller and will be closed after you sent a message.=Korzystanie z przycisku czatu lub komand serwera również otwiera konsolę, będzie ona jednak mniejsza i zostanie zamknięta po wysłaniu wiadomości. +Use the chat to communicate with other players. This requires you to have the “shout” privilege.=Użyj czatu by komunikować się z innymi graczami. Wymaga to przywileju "shout". +Just type in the message and hit [Enter]. Public chat messages can not begin with “/”.=Aby to zrobić wpisz wiadomość i naciśnij [Enter]. Publiczne wiadomości nie mogą rozpoczynać się od znaku "/". +You can send private messages: Say “/msg ” in chat to send “” which can only be seen by .=Możesz wysyłać prywatne wiadomości: Napisz "/msg " w czacie aby wysłać "" widoczną tylko przez . +There are some special controls for the console:=W konsoli obowiązuje kilka specjalnych metod sterowania: +• [F10] Open/close console=• [F10] Otwórz/zamknij konsolę +• [Enter]: Send message or command=• [Enter]: Wyślij wiadomość lub komendę +• [Tab]: Try to auto-complete a partially-entered player name=• [Tab]: Spróbuj dokończyć częściowo wprowadzone imię gracza +• [Ctrl]+[Left]: Move cursor to the beginning of the previous word=• [Ctrl]+[Lewo]: Przenieś kursor na początek poprzedniego słowa +• [Ctrl]+[Right]: Move cursor to the beginning of the next word=• [Ctrl]+[Prawo]: Przenieś kursor na początek następnego słowa +• [Ctrl]+[Backspace]: Delete previous word=• [Ctrl]+[Backspace]: Usuń poprzednie słowo +• [Ctrl]+[Delete]: Delete next word=• [Ctrl]+[Delete]: Usuń następne słowo +• [Ctrl]+[U]: Delete all text before the cursor=• [Ctrl]+[U]: Usuń cały tekst przed kursorem +• [Ctrl]+[K]: Delete all text after the cursor=• [Ctrl]+[K]: Usuń cały tekst po kursorze +• [Page up]: Scroll up=• [Page up]: Przewiń do góry +• [Page down]: Scroll down=• [Page down]: Przewiń w dół +There is also an input history. Minetest saves your previous console inputs which you can quickly access later:=Istnieje również historia wprowadzania. Minetest zapisuje wprowadzone komendy, do szybkiego dostępu później: +• [Up]: Go to previous entry in history=• [Góra]: Idź do poprzedniej komendy w historii +• [Down]: Go to next entry in history=• [Dół]: Idź do następnej komendy w historii +Server commands=Komendy serwera +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.=Komendy serwera (zwane również "komendy czatu") są drobnymi pomocnymi komendami dla zaawansowanych użytkowników. Nie musisz korzystać z tych komend podczas grania, ale mogą okazać się przydatne przy wykonywaniu technicznych zadań. Działają one zarówno w grze wieloosobowej i jednoosobowej. +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.=Komendy serwera mogą być wprowadzane przy użyciu czatu, aby wykonać akcje na serwerze. Niektóre komendy mogą być wywołane przez każdego, ale niektóre działają tylko jeśli masz przyznane przywileje na serwerze. Mały zbiór podstawowych komend dostępny jest zawsze, inne komendy mogą być dodane przez mody. +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.=Aby wywołać komendę, po prostu wpisze ją jako wiadomość czatu lub kliknij przycisk komend Minetesta (domyślnie: [/]). Wszystkie komendy muszą zaczynać się od "/', np. "/mods". Przycisk komend Minetesta robi dokładnie to samo co przycisk czatu, ale "/" jest od razu wpisany. +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.=Komendy mogą, ale nie muszą wypisać odpowiedź w czacie, ale błędy będą zwykle pokazane w czacie. Sama spróbuj: Zamknij to okno i wpisz komendę "/mods". Ta komenda wypiszę listę dostępnych modów na tym serwerze. +“/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" jest bardzo ważną komendą: Zostanie ci pokazana lista wszystkich dostępnych komend na serwerze, krótkie wyjaśnienie oraz dozwolone parametry. Ta komenda jest również ważna, ponieważ dostępne komendy będą inne w zależności od serwera. +Commands are followed by zero or more parameters.=Po komendach mogą wystąpić parametry. +In the command reference, you see some placeholders which you need to replace with an actual value. Here's an explanation:=W opisie komend możesz zobaczyć tekst zastępczy, który musisz zamienić na faktyczną wartość. Oto krótkie wyjaśnienie: +• Text in greater-than and lower-than signs (e.g. “”): Placeholder for a parameter=• Teks pomiędzy symbolami większe niż oraz mniejsze niż (np. ""): Tekst zastępczy dla parametru +• Anything in square brackets (e.g. “[text]”) is optional and can be omitted=• Cokolwiek w nawiasach kwadratowych (np. "[tekst]") jest opcjonalne i może być pominięte +• Pipe or slash (e.g. “text1 | text2 | text3”): Alternation. One of multiple texts must be used (e.g. “text2”)=• Pionowa kreska lub slesz (np. "tekst1 | tekst2 | tekst3"): Alternatywa. Jeden z wymienionych tekstów musi być użyty (np. "tekst2") +• Parenthesis: (e.g. “(word1 word2) | word3”): Groups multiple words together, used for alternations=• Nawiasy (np. "((słowo1 słowo2) | słowo3)"): Grupuje wiele słów razem, używane przy alternatywach +• Everything else is to be read as literal text=• Wszystko inne powinno być czytane jako dosłowny tekst +Here are some examples to illustrate the command syntax:=Oto kilka przykładów ilustrujących składnię komend: +• /mods: No parameters. Just enter “/mods”=• /mods: Brak parametrów. Po prostu wpisz "/mods" +• /me : 1 parameter. You have to enter “/me ” followed by any text, e.g. “/me orders pizza”=• /ja : 1 parametr. Musisz wpisać "/ja ", a następnie dowolny tekst, np. "/ja zamawiam pizzę" +• /give : Two parameters. Example: “/give Player default:apple”=• /give : Dwa parametry. Przykładowo: "/give gracz default: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|]: Poprawne użycia tej komendy to "/help", "/help all", "/help privs" lub "/help ", po którym następują nazwa komendy, np. "/help mods" +• /spawnentity [,,]: Valid inputs include “/spawnentity boats:boat” and “/spawnentity boats:boat 0,0,0”=• /spawnentity [,,]: Poprawne użycia tej komendy to np. "/spawnentity boats:boat" oraz "/spawnentity boats:boat 0,0,0" +Some final remarks:=Kilka uwag na koniec: +• 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=• Aby użyć komend /give oraz /giveme, potrzebujesz nazwy przedmiotu. Jest to używany wewnętrznie unikalny identyfikator, który możesz znaleźć w pomocy jeśli masz przywileje "give" lub "debug" +• For /spawnentity you need an entity name, which is another identifier=• Aby użyć /spawnentity musisz znać nazwę obiektu, która podobnie jest identyfikatorem +Privileges=Przywileje +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”.=Każdy gracz ma zbiór przywilejów, które są różne w zależności od serwera. Twoje przywileje definiują co możesz, a czego nie możesz robić. Przywileje mogą być nadane i odebrane przez dowolnego gracza, który ma przywilej "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.=Na serwerze z domyślną konfiguracją nowi gracze zaczynają z przywilejami "interact" oraz "shout". Przywilej "interact" pozwala na podstawowe akcje gry takie jak budowanie, kopanie, używanie itp. Przywilej "shout" pozwala na używanie czatu. +There is a small set of core privileges which you'll find on every server, other privileges might be added by mods.=Mały zbiór bazowych przywilejów znajdziesz na każdym serwerze, inne przywileje mogą zostać dodane przez mody. +To view your own privileges, issue the server command “/privs”.=Aby zobaczyć swoje przywileje, użyj komendy serwera "/privs". +Here are a few basic privilege-related commands:=Oto kilka podstawowych komend związanych z przywilejami: +• /privs: Lists your privileges=• /privs: Pokazuje twoje przywileje +• /privs : Lists the privileges of =• /privs : Pokazuje przywileje +• /help privs: Shows a list and description about all privileges=• /help privs: Pokazuje listę i opis wszystkich przywilejów +Players with the “privs” privilege can modify privileges at will:=Gracze z przywilejem "privs" mogą zmieniać przywileje jak chcą: +• /grant : Grant to =• /grant : Nadal +• /revoke : Revoke from =• /revoke : Odbierz +In single-player mode, you can use “/grantme all” to unlock all abilities.=W trybie jednoosobowym możesz użyć "/grantme all" aby odblokować wszystkie umiejętności. +Light=Światło +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).=Jako, że świat jest całkowicie oparty na blokach, jest tak również w przypadku światła. Każdy blok ma swoją własną jasność. Jasność bloku jest wyrażona w "poziomie oświetlenia", który przyjmuje wartości od 0 (zupełnie ciemny) do 15 (jasny jak słońce). +There are two types of light: Sunlight and artificial light.=Są dwa typy światła: słoneczne oraz sztuczne. +Artificial light is emitted by luminous blocks. Artificial light has a light level from 1-14.=Światło sztuczne jest emitowane przez oświetlające bloki. Sztuczne światło ma poziom oświetlenia od 1 do 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.=Światło słoneczne jest najjaśniejszym światłem i zawsze świeci bezpośrednio w dół w trakcie dnia. W nocy światło to zamieni się w księżycowe, które wciąż daje niewielką ilość światła. Poziom oświetlenia słonecznego jest równy 15. +Blocks have 3 levels of transparency:=Bloki mają 3 poziomy przeźroczystości: +• Transparent: Sunlight goes through limitless, artificial light goes through with losses=• Przeźroczysty: Światło słoneczne przenika bez strat, sztuczne przenika ze spadkiem +• Semi-transparent: Sunlight and artificial light go through with losses=• Półprzeźroczysty: Światło słoneczne i sztuczne przenika ze stratą jasności +• Opaque: No light passes through=• Nieprzeźroczysty: Światło nie przenika +Artificial light will lose one level of brightness for each transparent or semi-transparent block it passes through, until only darkness remains (image 1).=Światło sztuczne będzie traciło jeden poziom jasności z każdym przeźroczystym lub nieprzeźroczystym blokiem przez który przenika, dopóki nie pozostanie tylko ciemność (obrazek 1). +Sunlight will preserve its brightness as long it only passes fully transparent blocks. When it passes through a semi-transparent block, it turns to artificial light. Image 2 shows the difference.=Światło słoneczne zachowuje swoją jasność tak długo jak przenika tylko przez w pełni przeźroczyste bloki. Gdy przenika przez półprzeźroczyste bloki, zamienia się w światło sztuczne. Obrazek 2 pokazuje różnicy. +Note that “transparency” here only means that the block is able to carry brightness from its neighboring blocks. It is possible for a block to be transparent to light but you can't see trough the other side.=Zwróć uwagę, że "przeźroczystość" odnosi się tutaj tylko do możliwości przenoszenia poziomu oświetlenia z sąsiednich bloków. Jest możliwe by blok był przeźroczysty dla światła, ale nie będziesz w stanie przez niego zobaczyć. +Coordinates=Współrzędne +The 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.=Świat jest wielką kostką. I z tego powodu pozycja w świecie może być łatwo wyrażona we współrzędnych kartezjańskich. To oznacza, że dla każdej pozycji na świecie są 3 wartości X, Y oraz Z. +Like this: (5, 45, -12)=Na przykład: (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.=To opisuje pozycje w której X@=5, Y@=45 i Z@=-12. Te 3 litery nazywamy "osiami": Y jest wysokością, X i Z są dla pozycji poziomej. +The values for X, Y and Z work like this:=Wartości dla X, Y i Z działają następująco: +• If you go up, Y increases=• Jeśli pójdziesz w górę, Y się zwiększy +• If you go down, Y decreases=• Jeśli pójdziesz w dół, Y się zmniejszy +• If you follow the sun, X increases=• Jeśli podążysz za słońcem, X się zwiększy +• If you go to the reverse direction, X decreases=• Jeśli pójdziesz w przeciwnym kierunku, X się zmniejszy +• Follow the sun, then go right: Z increases=• Podążaj za słońcem następnie, w prawo: Z się zwiększy +• Follow the sun, then go left: Z decreases=• Podążaj za słońcem następnie, w lewo: Z się zmniejszy +• The side length of a full cube is 1=• Długość boku jednego sześcianu wynosi 1 +You can view your current position in the debug screen (open with [F5]).=Możesz zobaczyć swoją aktualną pozycję na ekranie debug (otwórz go naciskając [F5]). + +# 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: +• 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 +• Greatly increased hand pointing range=• Znacząco zwiększony zasięg reki +• Mined blocks don't drop items=• Wykopane bloki nie wyrzucają zrzutu +• Items don't get used up=• Przedmioty nie zużywają się +• Tools don't wear off=• Narzędzie nie niszczą się +• You can eat food whenever you want=• Możesz jeść jedzenie kiedy tylko chcesz +• You can always use the minimap (including radar mode)=• Zawsze możesz korzystać z minimapy (włączając w to tryb radaru) +Damage is not affected by Creative Mode, it needs to be disabled separately.=Tryb kreatywny nie ma wpływu na obrażenia, muszą być wyłączone osobno. +Mobs=Moby +Mobs are the living beings in the world. This includes animals and monsters.=Moby są żyjącymi stworzeniami w świecie. To między innymi zwierzęta i potwory. +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).=Moby pojawiają się losowo w świecie. Nazywamy to "spawnowaniem". Każdy mob pojawia się na pewnym typie bloku przy pewnym poziomie oświetlenia. Wysokość również ma znaczenie. Spokojne moby najczęściej spawnują się w świetle, podczas gdy wrogie preferują ciemność. Większość mobów spawnuje się na dowolnym stałym bloku, ale niektóre moby spawnują się tylko na konkretnych blokach (np. blokach trawy). +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.=Podobnie jak gracze, moby mają punkty życia, a czasami również zbroi (co oznacza, że będziesz potrzebował lepszych broni by zadać im obrażenia). Również podobnie jak gracze wrogie moby mogą atakować bezpośrednio lub z dystansu. Moby mogą wyrzucać losowe przedmioty przy śmierci. +Most animals roam the world aimlessly while most hostile mobs hunt players. Animals can be fed, tamed and bred.=Większość zwierząt przemieszcza się po świecie bez celu, a większość wrogich mobów poluje na gracza. Zwierzęta mogą być karmione, oswajane i rozmnażane. +Animals=Zwierzęta +Animals are peaceful beings which roam the world aimlessly. You can feed, tame and breed them.=Zwierzęta są spokojnymi mobami, które przemierzają świat bez celu. Mogą być karmione, oswajane i rozmnażane. +Feeding:=Karmienie: +Each animal has its own taste for food and doesn't just accept any food. To feed, hold an item in your hand and rightclick the animal.=Każde zwierzę ma swój własny gust w jedzeniu i nie przyjmuje byle czego. Aby nakarmić, weź przedmiot do swojej ręki i kliknij prawym przyciskiem na zwierzę. +Animals are attraced to the food they like and follow you as long you hold the food item in hand.=Zwierzęta są przyciągane do jedzenia które lubią i będą za tobą podążać tak długo jak będziesz je trzymała w dłoni. +Feeding an animal has three uses: Taming, healing and breeding.=Karmienie zwierząt a trzy zastosowania: Oswajanie, uzdrawianie i rozmnażanie. +Feeding heals animals instantly, depending on the quality of the food item.=Karmienie natychmiast uzdrawia zwierzęta w zależności od jakości. +Taming:=Oswajanie +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.=Niektóre zwierzęta mogą być oswojony. Z oswojonymi zwierzętami możesz zwykle robić więcej rzeczy i używać na nich dodatkowych przedmiotów. Przykładowo oswojone konie mogą być osiodłane, a oswojone wilki walczą po twojej stronie. +Breeding:=Rozmnażanie +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.=Gdy nakarmisz zwierzę do pełnego zdrowia, a następnie nakarmisz je jeszcze raz, aktywujesz "tryb miłości" i wiele serc pojawi się wokół zwierzęcia. +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.=Dwa zwierzęta tego samego gatunku będą się rozmnażać jeśli są blisko siebie i w trybie miłości. Wkrótce potem pojawi się dziecko zwierzątko. +Baby animals:=Dzieci zwierzątka +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.=Dzieci zwierzątka są takie jak ich dorosłe odpowiedniki, jednak nie mogą być oswojone i rozmnażane oraz nie wyrzucają niczego gdy umierają. Po pewnym czasie wyrastają w dorosłe zwierze. Gdy są karmione wyrastają szybciej. +Hunger=Głód +Hunger affects your health and your ability to sprint. Hunger is not in effect when damage is disabled.=Głód wpływa na twoje zdrowie i możliwość biegania. Głód jest wyłączony gdy obrażenia są wyłączone. +Core hunger rules:=Główne zasady głodu: +• You start with 20/20 hunger points (more points @= less hungry)=• Zaczynasz z 20/20 punktami głodu (więcej punktów @= mniej głodna) +• Actions like combat, jumping, sprinting, etc. decrease hunger points=• Akcje takie jak walka, skakanie, bieganie itp. zmniejszają liczbę punktów głodu +• Food restores hunger points=• Jedzenie przywraca punkty głodu +• If your hunger bar decreases, you're hungry=• Jeśli twój pasek głodu zmniejsza się, staniesz się głodna +• At 18-20 hunger points, you regenerate 1 HP every 4 seconds=• Przy 18-20 punktach głodu, będziesz regenerował 1 HP co 4 sekundy +• At 6 hunger points or less, you can't sprint=• Przy 6 punktach głodu i mniej, nie możesz biegać +• At 0 hunger points, you lose 1 HP every 4 seconds (down to 1 HP)=• Przy 0 punktach głodu i mniej, tracisz 1 HP co 4 sekundy +• Poisonous food decreases your health=• Trujące jedzenie zmniejsza twoje zdrowie +Details:=Szczegóły: +You have 0-20 hunger points, indicated by 20 drumstick half-icons above the hotbar. You also have an invisible attribute: Saturation.=Masz 0-20 punktów głodu, oznaczanych przez 20 pałek pół-ikon nad paskiem szybkiego dostępu. Posiadasz również niewidzialną własność: Nasycenie. +Hunger points reflect how full you are while saturation points reflect how long it takes until you're hungry again.=Punkty głodu pokazują jak pełna jesteś, podczas gdy punkty nasycenia mówią jak długo zajmie zanim znów będziesz głodna. +Each food item increases both your hunger level as well your saturation.=Każde jedzenie zwiększa zarówno twój poziom głodu jak i nasycenia. +Food with a high saturation boost has the advantage that it will take longer until you get hungry again.=Jedzenie z większym wzrostem nasycenia ma tę przewagę, że sprawi, że dłużej zajmie zanim znów będziesz głodna. +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.=Niektóre jedzenia mogą losowo wywołać zatrucie pokarmowe. Gdy jesteś otruta symbole życia i głodu zmienią kolor na zgniło-zielony. Zatrucie pokarmowe zmniejsza twoje życie o 1 HP na sekundę aż do 1 hp. Zmniejsza ono również twoje nasycenie. Zatrucie pokarmowe przechodzi po chwili lub gdy wypijesz mleko. +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.=Zaczynasz z 5 punktami nasycenia. Maksymalne nasycenie jest równe twojemu aktualnemu poziomowi głodu. Więc z 20 punktami głodu, twój maksymalny poziom nasycenia to 20. To oznacza, że jedzenie które zwiększa nasycenie jest bardziej efektywne im więcej punktów głodu masz. Jest tak ponieważ na niskich poziomach głodu spora część zwiększenia nasycenia zostanie stracona przez niski poziom maksymalny. +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.=Gdy twój poziom nasycenia spadnie do 0 stajesz się głodna i zaczynasz tracić punkty głodu. Gdy widzisz, że twój pasek głodu zmniejsza się, to jest to dobry moment na jedzenie. +Saturation decreases by doing things which exhaust you (highest exhaustion first):=Nasycenie zmniejsza się gdy robisz rzeczy, które cię męczą (w kolejności od najbardziej męczącego): +• Regenerating 1 HP=• Odnowienie 1 HP +• Suffering food poisoning=• Zatrucie pokarmowe +• Sprint-jumping=• Skakanie podczas biegu +• Sprinting=• Bieganie +• Attacking=• Atakowanie +• Taking damage=• Otrzymywanie obrażeń +• Swimming=• Pływanie +• Jumping=• Skakanie +• Mining a block=• Kopanie bloku +Other actions, like walking, do not exaust you.=Inne akcje takie jak chodzenie nie męczą cię. +If you have a map item in any of your hotbar slots, you can use the minimap.=Jeśli masz przedmiot mapy w swoim pasku szybkiego dostępu możesz korzystać z minimapy. + diff --git a/mods/HELP/mcl_doc_basics/mcl_extension.lua b/mods/HELP/mcl_doc_basics/mcl_extension.lua index c6f9f0aa9..a0f31a2c8 100644 --- a/mods/HELP/mcl_doc_basics/mcl_extension.lua +++ b/mods/HELP/mcl_doc_basics/mcl_extension.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_doc_basics") +local S = minetest.get_translator(minetest.get_current_modname()) doc.add_entry("advanced", "creative", { name = S("Creative Mode"), diff --git a/mods/HELP/mcl_doc_basics/mod.conf b/mods/HELP/mcl_doc_basics/mod.conf index 525619045..c23a0ad55 100644 --- a/mods/HELP/mcl_doc_basics/mod.conf +++ b/mods/HELP/mcl_doc_basics/mod.conf @@ -1,3 +1,4 @@ name = mcl_doc_basics -depends = doc +author = Wuzzy description = Adds some help texts explaining how to use MineClone 2. +depends = doc diff --git a/mods/HELP/mcl_doc_basics/screenshot.png b/mods/HELP/mcl_doc_basics/screenshot.png deleted file mode 100644 index f0be2d7ec..000000000 Binary files a/mods/HELP/mcl_doc_basics/screenshot.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_build.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_build.png deleted file mode 100644 index 3f89001f1..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_build.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_behind.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_behind.png deleted file mode 100644 index 2f17e4759..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_behind.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_ego.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_ego.png deleted file mode 100644 index 98b533d2d..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_ego.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_front.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_front.png deleted file mode 100644 index 71adb89fd..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_camera_front.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_grid.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_grid.png deleted file mode 100644 index bff1f91b1..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_grid.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_1.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_1.png deleted file mode 100644 index 878bc681b..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_1.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_2.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_2.png deleted file mode 100644 index eb23f5e0d..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_2.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_3.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_3.png deleted file mode 100644 index 149dc61d8..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_groups_3.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_repair.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_repair.png deleted file mode 100644 index fa21ddf93..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_repair.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shaped.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shaped.png deleted file mode 100644 index a5e2f8e70..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shaped.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_1.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_1.png deleted file mode 100644 index 68fb58114..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_1.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_2.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_2.png deleted file mode 100644 index 77a456914..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_craft_shapeless_2.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_carbone_ng.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_carbone_ng.png deleted file mode 100644 index 7ac6178f9..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_carbone_ng.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_hades.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_hades.png deleted file mode 100644 index debc08f8d..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_hades.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_lott.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_lott.png deleted file mode 100644 index db27d0acc..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_lott.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_moontest.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_moontest.png deleted file mode 100644 index 47ea2192d..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_moontest.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_1.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_1.png deleted file mode 100644 index d85d1cce7..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_1.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_2.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_2.png deleted file mode 100644 index 1ab57ba32..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_mtg_2.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_outback.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_outback.png deleted file mode 100644 index 540f4bbed..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_outback.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_pixture.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_pixture.png deleted file mode 100644 index ead1a160b..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_pixture.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png deleted file mode 100644 index 7b1957505..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_gameplay_xtraores_xtension.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar.png deleted file mode 100644 index 406f94db8..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar_relations.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar_relations.png deleted file mode 100644 index 4286d2744..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_hotbar_relations.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory.png deleted file mode 100644 index d23632f9f..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory_detail.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory_detail.png deleted file mode 100644 index 631daa6ea..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_inventory_detail.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_items_dropped.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_items_dropped.png deleted file mode 100644 index 4cbe82db2..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_items_dropped.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_light_test.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_light_test.png deleted file mode 100644 index 49f150365..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_light_test.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_light_torch.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_light_torch.png deleted file mode 100644 index d64fdedd2..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_light_torch.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_nonrenewable.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_nonrenewable.png deleted file mode 100644 index a0d238acb..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_nonrenewable.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_range.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_range.png deleted file mode 100644 index 622e98de3..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_range.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_1.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_1.png deleted file mode 100644 index ffb23fd14..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_1.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_2.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_2.png deleted file mode 100644 index 0eb44c54f..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_renewable_2.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_types.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_types.png deleted file mode 100644 index ac72b0cfa..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_liquids_types.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_map.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_map.png deleted file mode 100644 index b574f8b08..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_map.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_radar.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_radar.png deleted file mode 100644 index a743d6d9d..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_radar.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_round.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_round.png deleted file mode 100644 index 083903d36..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_minimap_round.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_nodes.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_nodes.png deleted file mode 100644 index 9f436ca37..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_nodes.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_flat.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_players_flat.png deleted file mode 100644 index 868cdb642..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_flat.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_lott.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_players_lott.png deleted file mode 100644 index 7427f2a7c..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_lott.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_sam.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_players_sam.png deleted file mode 100644 index afcd3111a..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_players_sam.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_pointing.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_pointing.png deleted file mode 100644 index 23b0dff16..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_pointing.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_sneak.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_sneak.png deleted file mode 100644 index 00325a2a9..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_sneak.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_tools.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_tools.png deleted file mode 100644 index 9bd639342..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_tools.png and /dev/null differ diff --git a/mods/HELP/mcl_doc_basics/textures/doc_basics_tools_mining.png b/mods/HELP/mcl_doc_basics/textures/doc_basics_tools_mining.png deleted file mode 100644 index 8655c5e2a..000000000 Binary files a/mods/HELP/mcl_doc_basics/textures/doc_basics_tools_mining.png and /dev/null differ diff --git a/mods/HELP/mcl_item_id/API.md b/mods/HELP/mcl_item_id/API.md new file mode 100644 index 000000000..a2f244e0c --- /dev/null +++ b/mods/HELP/mcl_item_id/API.md @@ -0,0 +1,24 @@ +# 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. + +## mcl_item_id.set_mod_namespace(modname, namespace) +Set a name space for all items in a mod. + +* param1: the modname +* param2: (optional) string of the desired name space, if nil, it is the name of the mod + +## mcl_item_id.get_mod_namespace(modname) +Get the name space of a mod registered with mcl_item_id.set_mod_namespace(modname, namespace). + +* param1: the modname + +### Examples: + +The name of the mod is "mod" which registered an item called "mod:itemname". + +* mcl_item_id.set_mod_namespace("mod", "mymod") will show "mymod:itemname" in the description of "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") diff --git a/mods/HELP/mcl_item_id/init.lua b/mods/HELP/mcl_item_id/init.lua new file mode 100644 index 000000000..0e029932b --- /dev/null +++ b/mods/HELP/mcl_item_id/init.lua @@ -0,0 +1,62 @@ +mcl_item_id = { + mod_namespaces = {}, +} + +local game = "mineclone" + +function mcl_item_id.set_mod_namespace(modname, namespace) + local namespace = namespace or modname + mcl_item_id.mod_namespaces[modname] = namespace +end + +function mcl_item_id.get_mod_namespace(modname) + local namespace = mcl_item_id.mod_namespaces[modname] + if namespace then + return namespace + else + return game + end +end + +local same_id = { + enchanting = { "table" }, + experience = { "bottle" }, + heads = { "skeleton", "zombie", "creeper", "wither_skeleton" }, + mobitems = { "rabbit", "chicken" }, + walls = { + "andesite", "brick", "cobble", "diorite", "endbricks", + "granite", "mossycobble", "netherbrick", "prismarine", + "rednetherbrick", "redsandstone", "sandstone", + "stonebrick", "stonebrickmossy", + }, + wool = { + "black", "blue", "brown", "cyan", "green", + "grey", "light_blue", "lime", "magenta", "orange", + "pink", "purple", "red", "silver", "white", "yellow", + }, +} + +tt.register_snippet(function(itemstring) + local def = minetest.registered_items[itemstring] + local item_split = itemstring:find(":") + local id_string = itemstring:sub(item_split) + local id_modname = itemstring:sub(1, item_split - 1) + local new_id = game .. 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", "") + end + end + end + if mod_namespace ~= game then + new_id = mod_namespace .. id_string + end + if mod_namespace ~= id_modname then + minetest.register_alias_force(new_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 diff --git a/mods/HELP/mcl_item_id/mod.conf b/mods/HELP/mcl_item_id/mod.conf new file mode 100644 index 000000000..c45e17fd3 --- /dev/null +++ b/mods/HELP/mcl_item_id/mod.conf @@ -0,0 +1,3 @@ +name = mcl_item_id +author = NO11 +depends = tt \ No newline at end of file diff --git a/mods/HELP/mcl_tt/depends.txt b/mods/HELP/mcl_tt/depends.txt deleted file mode 100644 index 12e5a198d..000000000 --- a/mods/HELP/mcl_tt/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -tt -mcl_enchanting diff --git a/mods/HELP/mcl_tt/init.lua b/mods/HELP/mcl_tt/init.lua index 9d0113040..3451e76da 100644 --- a/mods/HELP/mcl_tt/init.lua +++ b/mods/HELP/mcl_tt/init.lua @@ -1,2 +1,4 @@ -dofile(minetest.get_modpath("mcl_tt").."/snippets_base.lua") -dofile(minetest.get_modpath("mcl_tt").."/snippets_mcl.lua") +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath.."/snippets_base.lua") +dofile(modpath.."/snippets_mcl.lua") \ No newline at end of file diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr index 8f878afc7..54c376c3b 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.de.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.de.tr @@ -45,3 +45,4 @@ Mining durability: @1=Grabehaltbarkeit: @1 Block breaking strength: @1=Blockbruchstärke: @1 @1 uses=@1 Verwendungen Unlimited uses=Unbegrenzte Verwendungen +Durability: @1=Haltbarkeit: @1 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr index a66311448..77e9a35b0 100644 --- a/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr +++ b/mods/HELP/mcl_tt/locale/mcl_tt.fr.tr @@ -3,45 +3,46 @@ Head armor=Armure de tête Torso armor=Armure de torse Legs armor=Armure de jambes Feet armor=Armure de pieds -Armor points: @1=Points d'armure: @1 -Armor durability: @1=Durabilité d'armure: @1 -Protection: @1%=Protection: @1% -Hunger points: +@1=Points de faim: +@1 -Saturation points: +@1=Points de saturation: +@1 +Armor points: @1=Points d'armure : @1 +Armor durability: @1=Durabilité d'armure : @1 +Protection: @1%=Protection : @1% +Hunger points: +@1=Points de faim : +@1 +Saturation points: +@1=Points de saturation : +@1 Deals damage when falling=Inflige des dégâts en tombant Grows on grass blocks or dirt=Pousse sur des blocs d'herbe ou de terre Grows on grass blocks, podzol, dirt or coarse dirt=Pousse sur les blocs de gazon, le podzol, la terre ou la terre grossière 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% -Damage: @1=Dégâts: @1 -Damage (@1): @2=Dégâts (@1): @2 -Healing: @1=Guérison: @1 -Healing (@1): @2=Guérison (@1): @2 -Full punch interval: @1s=Intervalle de coup: @1s -Contact damage: @1 per second=Dégâts de contact: @1 par seconde -Contact healing: @1 per second=Guérison de contact: @1 par seconde -Drowning damage: @1=Dégâts de noyade: @1 +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% +Damage: @1=Dégâts : @1 +Damage (@1): @2=Dégâts (@1) : @2 +Healing: @1=Guérison : @1 +Healing (@1): @2=Guérison (@1) : @2 +Full punch interval: @1s=Intervalle de coup : @1s +Contact damage: @1 per second=Dégâts de contact : @1 par seconde +Contact healing: @1 per second=Guérison de contact : @1 par seconde +Drowning damage: @1=Dégâts de noyade : @1 Bouncy (@1%)=Rebondissant (@1%) -Luminance: @1=Luminance: @1 +Luminance: @1=Luminance : @1 Slippery=Glissant Climbable=Grimpable Climbable (only downwards)=Grimpable (uniquement vers le bas) No jumping=Ne pas sauter No swimming upwards=Ne pas nager vers le haut No rising=Pas de montée -Fall damage: @1%=Dégâts de chute: @1% -Fall damage: +@1%=Dégâts de chute: +@1% +Fall damage: @1%=Dégâts de chute : @1% +Fall damage: +@1%=Dégâts de chute : +@1% No fall damage=Pas de dégâts de chute -Mining speed: @1=Vitesse de minage: @1 +Mining speed: @1=Vitesse de minage : @1 Very fast=Très rapide Extremely fast=Extremement rapide 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 +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 +Durability: @1=Durabilité : @1 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr new file mode 100644 index 000000000..5e5cd5e7a --- /dev/null +++ b/mods/HELP/mcl_tt/locale/mcl_tt.ja.tr @@ -0,0 +1,48 @@ +# textdomain: mcl_tt +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 +Deals damage when falling=落下時にダメージ発生 +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% +Damage: @1=ダメージ:@1 +Damage (@1): @2=ダメージ (@1):@2 +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%) +Luminance: @1=発光:@1 +Slippery=滑りやすい +Climbable=よじ登れる +Climbable (only downwards)=よじ登れる(下方のみ) +No jumping=ジャンプ不可 +No swimming upwards=上方への水泳不可 +No rising=上昇不可 +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 使用 +Unlimited uses=無限に使用可能 +Durability: @1=耐久度:@1 diff --git a/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr b/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr new file mode 100644 index 000000000..aecc15d1e --- /dev/null +++ b/mods/HELP/mcl_tt/locale/mcl_tt.pl.tr @@ -0,0 +1,48 @@ +# textdomain: mcl_tt +Head armor=Zbroja na głowę +Torso armor=Zbroja na pierś +Legs armor=Zbroja na nogi +Feet armor=Zbroja na stopy +Armor points: @1=Punkty zbroi +Armor durability: @1=Wytrzymałość zbroi: @1 +Protection: @1%=Ochrona: @1% +Hunger points: +@1=Punkty głodu: +@1 +Saturation points: +@1=Punkty nasycenia: +@1 +Deals damage when falling=Zadaje obrażenia gdy spada +Grows on grass blocks or dirt=Rośnie na blokach trawy i ziemi +Grows on grass blocks, podzol, dirt or coarse dirt=Rośnie na blokach trawy, bielicy, ziemi oraz twardej ziemi +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% +Damage: @1=Obrażenia: @1 +Damage (@1): @2=Obrażenia (@1): @2 +Healing: @1=Leczenie: @1 +Healing (@1): @2=Leczenie (@1): @2 +Full punch interval: @1s=Pełny okres uderzenia: @1s +Contact damage: @1 per second=Obrażenia kontaktowe: @1 na sekundę +Contact healing: @1 per second=Leczenie kontaktowe: @1 na sekundę +Drowning damage: @1=Obrażenia od topienia: @1 +Bouncy (@1%)=Sprężystość (@1%) +Luminance: @1=Luminancja: @1 +Slippery=Śliskość +Climbable=Wspinaczkowe +Climbable (only downwards)=Wspinaczkowe (tylko w dół) +No jumping=Nie można skakać +No swimming upwards=Nie można płynąć pod górę +No rising=Nie wolno wstawać +Fall damage: @1%=Obrażenia od upadku @1% +Fall damage: +@1%=Obrażenia od upadku +@1% +No fall damage=Brak obrażeń od upadku +Mining speed: @1=Szybkość kopania: @1 +Very fast=Bardzo szybkie +Extremely fast=Ekstremalnie szybkie +Fast=Szybkie +Slow=Wolne +Very slow=Bardzo wolne +Painfully slow=Boleśnie wolne +Mining durability: @1=Wytrzymałość kopania: @1 +Block breaking strength: @1=Siła niszczenia bloku: @1 +@1 uses=@1 użyć +Unlimited uses=Nielimitowane użycia + diff --git a/mods/HELP/mcl_tt/locale/template.txt b/mods/HELP/mcl_tt/locale/template.txt index 1259216c7..6fb735b13 100644 --- a/mods/HELP/mcl_tt/locale/template.txt +++ b/mods/HELP/mcl_tt/locale/template.txt @@ -45,3 +45,4 @@ Mining durability: @1= Block breaking strength: @1= @1 uses= Unlimited uses= +Durability: @1= diff --git a/mods/HELP/mcl_tt/mod.conf b/mods/HELP/mcl_tt/mod.conf new file mode 100644 index 000000000..e442e1320 --- /dev/null +++ b/mods/HELP/mcl_tt/mod.conf @@ -0,0 +1,4 @@ +name = mcl_tt +author = Wuzzy +description = Add MCL2 tooltips +depends = tt, mcl_enchanting, mcl_colors diff --git a/mods/HELP/mcl_tt/snippets_base.lua b/mods/HELP/mcl_tt/snippets_base.lua index 8242f2c19..4e200d539 100644 --- a/mods/HELP/mcl_tt/snippets_base.lua +++ b/mods/HELP/mcl_tt/snippets_base.lua @@ -1,6 +1,6 @@ -local S = minetest.get_translator("mcl_tt") +local S = minetest.get_translator(minetest.get_current_modname()) -local function get_min_digtime(caps) +--[[local function get_min_digtime(caps) local mintime local unique = true local maxlevel = caps.maxlevel @@ -25,7 +25,7 @@ local function get_min_digtime(caps) end end return mintime, unique -end +end]] local function newline(str) if str ~= "" then @@ -47,7 +47,7 @@ tt.register_snippet(function(itemstring, toolcaps) local minestring = "" local capstr = "" local caplines = 0 - for k,v in pairs(groupcaps) do + for _,v in pairs(groupcaps) do local speedstr = "" local miningusesstr = "" -- Mining capabilities @@ -153,9 +153,9 @@ tt.register_snippet(function(itemstring, toolcaps) end) -- Weapon stats -tt.register_snippet(function(itemstring) +--[[tt.register_snippet(function(itemstring) local def = minetest.registered_items[itemstring] -end) +end)]] -- Food tt.register_snippet(function(itemstring) diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index 6e2803502..825776f5f 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -1,8 +1,8 @@ -local S = minetest.get_translator("mcl_tt") +local S = minetest.get_translator(minetest.get_current_modname()) -- Armor tt.register_snippet(function(itemstring) - local def = minetest.registered_items[itemstring] + --local def = minetest.registered_items[itemstring] local s = "" local head = minetest.get_item_group(itemstring, "armor_head") local torso = minetest.get_item_group(itemstring, "armor_torso") @@ -26,7 +26,7 @@ tt.register_snippet(function(itemstring) return s end) tt.register_snippet(function(itemstring, _, itemstack) - local def = minetest.registered_items[itemstring] + --local def = minetest.registered_items[itemstring] local s = "" local use = minetest.get_item_group(itemstring, "mcl_armor_uses") local pts = minetest.get_item_group(itemstring, "mcl_armor_points") @@ -75,9 +75,9 @@ tt.register_snippet(function(itemstring) end) tt.register_snippet(function(itemstring) - local def = minetest.registered_items[itemstring] + --local def = minetest.registered_items[itemstring] if minetest.get_item_group(itemstring, "crush_after_fall") == 1 then - return S("Deals damage when falling"), "#FFFF00" + return S("Deals damage when falling"), mcl_colors.YELLOW end end) @@ -107,3 +107,8 @@ tt.register_snippet(function(itemstring) 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)))) + end +end) diff --git a/mods/HELP/tt/init.lua b/mods/HELP/tt/init.lua index f23778b6c..f2b83b612 100644 --- a/mods/HELP/tt/init.lua +++ b/mods/HELP/tt/init.lua @@ -1,15 +1,20 @@ tt = {} -tt.COLOR_DEFAULT = "#d0ffd0" -tt.COLOR_DANGER = "#ffff00" -tt.COLOR_GOOD = "#00ff00" +tt.COLOR_DEFAULT = mcl_colors.GREEN +tt.COLOR_DANGER = mcl_colors.YELLOW +tt.COLOR_GOOD = mcl_colors.GREEN +tt.NAME_COLOR = mcl_colors.YELLOW -- API tt.registered_snippets = {} -tt.register_snippet = function(func) +function tt.register_snippet(func) table.insert(tt.registered_snippets, func) end +function tt.register_priority_snippet(func) + table.insert(tt.registered_snippets, 1, func) +end + dofile(minetest.get_modpath(minetest.get_current_modname()).."/snippets.lua") -- Apply item description updates @@ -21,8 +26,6 @@ local function apply_snippets(desc, itemstring, toolcaps, itemstack) local str, snippet_color = tt.registered_snippets[s](itemstring, toolcaps, itemstack) if snippet_color == nil then snippet_color = tt.COLOR_DEFAULT - elseif snippet_color == false then - snippet_color = false end if str then if first then @@ -40,7 +43,7 @@ local function apply_snippets(desc, itemstring, toolcaps, itemstack) end local function should_change(itemstring, def) - return itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def ~= nil and def.description ~= nil and def.description ~= "" and def._tt_ignore ~= true + return itemstring ~= "" and itemstring ~= "air" and itemstring ~= "ignore" and itemstring ~= "unknown" and def and def.description and def.description ~= "" and def._tt_ignore ~= true end local function append_snippets() @@ -57,21 +60,22 @@ end minetest.register_on_mods_loaded(append_snippets) -tt.reload_itemstack_description = function(itemstack) +function tt.reload_itemstack_description(itemstack) local itemstring = itemstack:get_name() local def = itemstack:get_definition() local meta = itemstack:get_meta() if def and def._mcl_generate_description then def._mcl_generate_description(itemstack) - elseif should_change(itemstring, def) and meta:get_string("name") == "" then + elseif should_change(itemstring, def) then local toolcaps if def.tool_capabilities then toolcaps = itemstack:get_tool_capabilities() end local orig_desc = def._tt_original_description or def.description - local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack) - if desc ~= orig_desc then - meta:set_string("description", desc) + if meta:get_string("name") ~= "" then + orig_desc = minetest.colorize(tt.NAME_COLOR, meta:get_string("name")) end + local desc = apply_snippets(orig_desc, itemstring, toolcaps or def.tool_capabilities, itemstack) + meta:set_string("description", desc) end end diff --git a/mods/HELP/tt/mod.conf b/mods/HELP/tt/mod.conf index d5c8c2eb1..2a260772d 100644 --- a/mods/HELP/tt/mod.conf +++ b/mods/HELP/tt/mod.conf @@ -1,2 +1,4 @@ name = tt +author = Wuzzy description = Support for custom tooltip extensions for items +depends = mcl_colors diff --git a/mods/HUD/awards/api.lua b/mods/HUD/awards/api.lua index 325c35165..6333272bd 100644 --- a/mods/HUD/awards/api.lua +++ b/mods/HUD/awards/api.lua @@ -14,11 +14,16 @@ -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + -- The global award namespace awards = { - show_mode = "hud" + show_mode = "hud", } -dofile(minetest.get_modpath("awards").."/api_helpers.lua") + +dofile(modpath.."/api_helpers.lua") -- Table Save Load Functions function awards.save() @@ -29,8 +34,6 @@ function awards.save() end end -local S = minetest.get_translator("awards") - function awards.init() awards.players = awards.load() awards.def = {} @@ -53,7 +56,7 @@ end function awards.register_trigger(name, func) awards.trigger_types[name] = func awards.on[name] = {} - awards['register_on_'..name] = function(func) + awards["register_on_"..name] = function(func) table.insert(awards.on[name], func) end end @@ -213,7 +216,8 @@ function awards.unlock(name, award) end -- Get award - minetest.log("action", name.." has gotten award "..name) + 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) .. "]"))) data.unlocked[award] = award awards.save() @@ -253,9 +257,13 @@ function awards.unlock(name, award) local custom_announce = awdef.custom_announce if not custom_announce then if awdef.secret then - custom_announce = S("Secret achievement gotten:") + custom_announce = S("Secret Advancement Made:") + elseif awdef.type == "Goal" then + custom_announce = S("Goal Completed:") + elseif awdef.type == "Challenge" then + custom_announce = S("Challenge Completed:") else - custom_announce = S("Achievement gotten:") + custom_announce = S("Advancement Made:") end end @@ -279,9 +287,13 @@ function awards.unlock(name, award) elseif awards.show_mode == "chat" then local chat_announce if awdef.secret == true then - chat_announce = S("Secret achievement gotten: @1") + chat_announce = S("Secret Advancement Made: @1") + elseif awdef.type == "Goal" then + chat_announce = S("Goal Completed: @1") + elseif awdef.type == "Challenge" then + chat_announce = S("Challenge Completed: @1") else - chat_announce = S("Achievement gotten: @1") + chat_announce = S("Advancement Made: @1") end -- use the chat console to send it minetest.chat_send_player(name, string.format(chat_announce, title)) @@ -293,7 +305,7 @@ function awards.unlock(name, award) local one = player:hud_add({ hud_elem_type = "image", name = "award_bg", - scale = {x = 1, y = 1}, + scale = {x = 1.25, y = 1}, text = background, position = {x = 0.5, y = 0}, offset = {x = 0, y = 138}, @@ -302,9 +314,13 @@ function awards.unlock(name, award) }) local hud_announce if awdef.secret == true then - hud_announce = S("Secret achievement gotten!") + hud_announce = S("Secret Advancement Made!") + elseif awdef.type == "Goal" then + hud_announce = S("Goal Completed!") + elseif awdef.type == "Challenge" then + hud_announce = S("Challenge Completed!") else - hud_announce = S("Achievement gotten!") + hud_announce = S("Advancement Made!") end local two = player:hud_add({ hud_elem_type = "text", @@ -313,7 +329,7 @@ function awards.unlock(name, award) scale = {x = 100, y = 20}, text = hud_announce, position = {x = 0.5, y = 0}, - offset = {x = 0, y = 40}, + offset = {x = 30, y = 40}, alignment = {x = 0, y = -1}, z_index = 102, }) @@ -324,7 +340,7 @@ function awards.unlock(name, award) scale = {x = 100, y = 20}, text = title, position = {x = 0.5, y = 0}, - offset = {x = 30, y = 100}, + offset = {x = 35, y = 100}, alignment = {x = 0, y = -1}, z_index = 102, }) @@ -339,7 +355,7 @@ function awards.unlock(name, award) number = 2, text = icon, position = {x = 0.5, y = 0}, - offset = {x = -110, y = 62}, + offset = {x = -138, y = 62}, alignment = {x = 0, y = 0}, direction = 0, z_index = 102, @@ -385,10 +401,10 @@ function awards.getFormspec(name, to, sid) local def = awards.def[item.name] if def and def.secret and not item.got then - formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret achievement)")).."]".. + formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret Advancement)")).."]".. "image[1,0;3,3;awards_unknown.png]" if def and def.description then - formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Get this achievement to find out what it is."))..";]" + formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Make this advancement to find out what it is."))..";]" end else local title = item.name @@ -446,7 +462,7 @@ function awards.getFormspec(name, to, sid) first = false if def.secret and not award.got then - formspec = formspec .. "#707070"..minetest.formspec_escape(S("(Secret Award)")) + formspec = formspec .. "#707070" .. minetest.formspec_escape(S("(Secret Advancement)")) else local title = award.name if def and def.title then @@ -455,7 +471,7 @@ function awards.getFormspec(name, to, sid) if award.got then formspec = formspec .. minetest.formspec_escape(title) else - formspec = formspec .. "#ACACAC".. minetest.formspec_escape(title) + formspec = formspec .. "#ACACAC" .. minetest.formspec_escape(title) end end end @@ -468,7 +484,7 @@ function awards.show_to(name, to, sid, text) name = to end if name == to and awards.player(to).disabled then - minetest.chat_send_player(S("You've disabled awards. Type /awards enable to reenable.")) + minetest.chat_send_player(name,S("You've disabled awards. Type /awards enable to reenable.")) return end if text then diff --git a/mods/HUD/awards/chat_commands.lua b/mods/HUD/awards/chat_commands.lua index 88e799dfe..04371139f 100644 --- a/mods/HUD/awards/chat_commands.lua +++ b/mods/HUD/awards/chat_commands.lua @@ -14,40 +14,46 @@ -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- -local S = minetest.get_translator("awards") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_chatcommand("awards", { params = S("[c|clear|disable|enable]"), - description = S("Show, clear, disable or enable your achievements"), + description = S("Show, clear, disable or enable your advancements."), func = function(name, param) + if param == "enable" then + awards.enable(name) + minetest.chat_send_player(name, S("You have enabled your advancements.")) + return + end + + if awards.player(name).disabled then + minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!")) + return + end + if param == "clear" then awards.clear_player(name) minetest.chat_send_player(name, S("All your awards and statistics have been cleared. You can now start again.")) elseif param == "disable" then awards.disable(name) - minetest.chat_send_player(name, S("You have disabled your achievements.")) - elseif param == "enable" then - awards.enable(name) - minetest.chat_send_player(name, S("You have enabled your achievements.")) - elseif param == "c" then - awards.show_to(name, name, nil, true) + minetest.chat_send_player(name, S("You have disabled your advancements.")) else awards.show_to(name, name, nil, false) end end }) -minetest.register_privilege("achievements", { - description = S("Can give achievements to any player"), +minetest.register_privilege("advancements", { + description = S("Can give advancements to any player"), give_to_singleplayer = false, give_to_admin = false, }) -minetest.register_chatcommand("achievement", { - params = S("(grant ( | all)) | list"), - privs = { achievements = true }, - description = S("Give achievement to player or list all achievements"), +minetest.register_chatcommand("advancement", { + params = S("(grant ( | all)) | list"), + privs = { advancements = true }, + description = S("Give advancement to player or list all advancements"), func = function(name, param) if param == "list" then local list = {} @@ -80,7 +86,7 @@ minetest.register_chatcommand("achievement", { awards.unlock(playername, achievement) return true, S("Done.") else - return false, S("Achievement “@1” does not exist.", achievement) + return false, S("Advancement “@1” does not exist.", achievement) end end }) diff --git a/mods/HUD/awards/depends.txt b/mods/HUD/awards/depends.txt deleted file mode 100644 index 80a448a44..000000000 --- a/mods/HUD/awards/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -sfinv? -unified_inventory? diff --git a/mods/HUD/awards/description.txt b/mods/HUD/awards/description.txt deleted file mode 100644 index f2b9944c7..000000000 --- a/mods/HUD/awards/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds achievements to Minetest, and an API to register new ones. diff --git a/mods/HUD/awards/init.lua b/mods/HUD/awards/init.lua index 63c9303c1..9b46fd066 100644 --- a/mods/HUD/awards/init.lua +++ b/mods/HUD/awards/init.lua @@ -14,9 +14,11 @@ -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- -dofile(minetest.get_modpath("awards").."/api.lua") -dofile(minetest.get_modpath("awards").."/chat_commands.lua") -dofile(minetest.get_modpath("awards").."/sfinv.lua") -dofile(minetest.get_modpath("awards").."/unified_inventory.lua") -dofile(minetest.get_modpath("awards").."/triggers.lua") +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath.."/api.lua") +dofile(modpath.."/chat_commands.lua") +dofile(modpath.."/sfinv.lua") +dofile(modpath.."/unified_inventory.lua") +dofile(modpath.."/triggers.lua") diff --git a/mods/HUD/awards/locale/awards.de.tr b/mods/HUD/awards/locale/awards.de.tr index 2fb04c4ca..19db5e0be 100644 --- a/mods/HUD/awards/locale/awards.de.tr +++ b/mods/HUD/awards/locale/awards.de.tr @@ -1,7 +1,7 @@ # textdomain:awards @1: @2=@1: @2 @1 (got)=@1 (erhalten) -@1’s awards:=Auszeichnungen von @1: +@1’s awards:=Auszeichnungen von @: (Secret Award)=(Geheime Auszeichnung) Achievement gotten!=Auszeichnung erhalten! Achievement gotten:=Auszeichnung erhalten: @@ -27,7 +27,6 @@ Awards=Auszeichnungen @1/@2 deaths=@1/@2 Tode @1/@2 dug=@1/@2 abgebaut @1/@2 game joins=@1/@2 Spielen beigetreten -@1/@2 lines of chat=@1/@2 Chatzeilen @1/@2 placed=@1/@2 platziert Die @1 times.=Sterben Sie @1 mal. Die.=Sterben Sie. @@ -58,3 +57,8 @@ Invalid action.=Ungültige Aktion. Player is not online.=Spieler ist nicht online. Done.=Fertig. Achievement “@1” does not exist.=Auszeichnung »@1« existiert nicht. +@1 has made the achievement @2=@1 hat die Auszeichnung @2 erhalten +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 diff --git a/mods/HUD/awards/locale/awards.fr.tr b/mods/HUD/awards/locale/awards.fr.tr index 0c2925db7..767848a69 100644 --- a/mods/HUD/awards/locale/awards.fr.tr +++ b/mods/HUD/awards/locale/awards.fr.tr @@ -1,45 +1,44 @@ # textdomain:awards @1/@2 chat messages=@1/@2 chat messages -@1/@2 crafted=@1/@2 fabrication -@1/@2 deaths=@1/@2 Mort +@1/@2 crafted=@1/@2 fabriqués +@1/@2 deaths=@1/@2 morts @1/@2 dug=@1/@2 creusé @1/@2 game joins=@1/@2 sessions -@1/@2 placed=@1/@2 mis +@1/@2 placed=@1/@2 placé @1 (got)=@1 (obtenu) -@1: @1=@1: @1 +@1: @2=@1 : @2 @1’s awards:=Récompenses de @1: -(Secret Award)=(Récompense Secrètte) -= +(Secret Award)=(Récompense secrète) += = -A Cat in a Pop-Tart?!=A Cat in a Pop-Tart?! -Achievement gotten!=Succès obtenue! -Achievement gotten:=Succès obtenue: -Achievement gotten: @1=Succès obtenue: @1 -Achievement not found.=Succès inconnu +Advancement Made!=Progrès réalisé ! +Advancement Made:=Progrès réalisé : +Advancement: @1=Progrès : @1 +Achievement not found.=Progrès inconnu All your awards and statistics have been cleared. You can now start again.=Toutes vos récompenses et statistiques ont été effacées. Vous pouvez maintenant recommencer. Awards=Récompenses -Craft: @1×@2=Frabrication: @1×@2 -Craft: @1=Frabrication: @1 +Craft: @1×@2=Fabrication: @1×@2 +Craft: @1=Fabrication: @1 Die @1 times.=Mort @1 fois. Die.=Mort. -Get the achievements statistics for the given player or yourself=Obtenez les statistiques de succès pour le joueur donné ou vous-même +Get the achievements statistics for the given player or yourself=Obtenez les statistiques de progrès pour le joueur donné ou vous-même Join the game @1 times.=Rejoignez le jeu @1 fois. Join the game.=Rejoignez le jeu. List awards in chat (deprecated)=Liste des récompenses dans le chat (obsolète) Place a block: @1=Placer un bloc: @1 Place blocks: @1×@2=Placer des blocs: @1×@2 -Secret Achievement gotten!=Succès secret obtenu! -Secret Achievement gotten:=Succès secret obtenu: -Secret Achievement gotten: @1=Succès secret obtenu: @1 -Show details of an achievement=Afficher les détails d'un succès -Show, clear, disable or enable your achievements=Affichez, effacez, désactivez ou activez vos succès -Get this achievement to find out what it is.=Obtenez ce succès pour découvrir de quoi il s'agit. +Secret Advancement Made!=Progrès secret réalisé ! +Secret Advancement Made:=Progrès secret réalisé : +Secret Advancement Made: @1=Progrès secret réalisé : @1 +Show details of an achievement=Afficher les détails d'un progrès +Show, clear, disable or enable your advancements.=Affichez, effacez, désactivez ou activez vos progrès. +Make this advancement to find out what it is.=Réalisez ce progrès pour découvrir de quoi il s'agit. Write @1 chat messages.=Écrivez @1 messages de chat. Write something in chat.=Écrivez quelque chose dans le chat. -You have disabled your achievements.=Vous avez désactivé vos succès. -You have enabled your achievements.=Vous avez activé vos succès. -You have not gotten any awards.=Vous n'avez reçu aucun prix. -You've disabled awards. Type /awards enable to reenable.=Vous avez désactivé les récompenses. Type /awards enable pour les activer. +You have disabled your advancements.=Vous avez désactivé vos progrès. +You have enabled your advancements.=Vous avez activé vos progrès. +You have not gotten any awards.=Vous n'avez reçu aucune récompense. +You've disabled awards. Type /awards enable to reenable.=Vous avez désactivé les récompenses. Tapez "/awards enable" pour les réactiver. [c|clear|disable|enable]=[c|clear|disable|enable] OK=OK Error: No awards available.=Erreur: aucune récompense disponible. @@ -50,12 +49,16 @@ Place @1 block(s).=Placer @1 bloc(s). Dig @1 block(s).=Creuser @1 bloc(s). Eat @1 item(s).=Manger @1 aliment(s). Craft @1 item(s).=Fabriquer @1 objet(s). -Can give achievements to any player=Peut donner des succès à n'importe quel joueur -(grant ( | all)) | list=(grant ( | all)) | list -Give achievement to player or list all achievements=Donner un succès a un joueur ou répertorier toutes les succès +Can give advancements to any player=Peut donner des progrès à n'importe quel joueur +(grant ( | all)) | list=(grant ( | all)) | list +Give advancement to player or list all advancements=Donner un progrès à un joueur ou répertorier tous les progrès @1 (@2)=@1 (@2) Invalid syntax.=Syntaxe invalide. Invalid action.=Action invalide. Player is not online.=Le joueur n'est pas en ligne. Done.=Terminé. -Achievement “@1” does not exist.=La réalisation «@1» n'existe pas. +Advancement “@1” does not exist.=Le progrès «@1» n'existe pas. +@1 has made the advancement @2=@1 a obtenu le progrès @2 +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 ! diff --git a/mods/HUD/awards/locale/awards.ja.tr b/mods/HUD/awards/locale/awards.ja.tr new file mode 100644 index 000000000..5a3b73174 --- /dev/null +++ b/mods/HUD/awards/locale/awards.ja.tr @@ -0,0 +1,70 @@ +# textdomain:awards +@1/@2 chat messages=@1/@2 チャットメッセージ +@1/@2 crafted=@1/@2 クラフトした +@1/@2 deaths=@1/@2 死亡した +@1/@2 dug=@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)=(シークレットアワード) +=<実績 ID> +=<名前> +Advancement Made!=進捗 更新! +Advancement Made:=進捗 更新: +Advancement: @1=進捗:@1 +Achievement not found.=実績 未検出 +All your awards and statistics have been cleared. You can now start again.=すべてのアワードと統計がクリアされました。これで再スタートが可能です。 +Awards=アワード +Craft: @1×@2=クラフト: @1×@2 +Craft: @1=クラフト: @1 +Die @1 times.=@1回死にました。 +Die.=死にました。 +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 +Show details of an achievement=実績の詳細を表示 +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|クリア|無効化|有効化] +OK=OK +Error: No awards available.=エラー:アワードに該当するものはありません。 +Eat: @1×@2=食す:@1×@2 +Eat: @1=食す:@1×@2 +@1/@2 eaten=@1/@2 食した +Place @1 block(s).=ブロックを@1個 配置します。 +Dig @1 block(s).=ブロックを@1個 掘ります。 +Eat @1 item(s).=アイテムを@1個 食べます。 +Craft @1 item(s).=アイテムを@1個 クラフトします。 +Can give advancements to any player=任意のプレイヤーに進捗を供与可能 +(grant ( | all)) | list=(供与 <プレイヤー> (<進捗> | 全て)) | リスト +Give advancement to player or list all advancements=プレイヤーに進捗を与えるか、すべての進捗をリストアップ +@1 (@2)=@1 (@2) +Invalid syntax.=無効な構文です。 +Invalid action.=無効な動作です。 +Player is not online.=プレーヤーがオンラインになってません。 +Done.=完了です。 +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 +Awards are disabled, enable them first by using /awards enable!=アワードは無効になってます、まず /awards enable を使用して有効にしてください! +Goal Completed:=目標達成: +Goal Completed!=目標達成! +Goal Completed: @1=目標達成:@1 +Challenge Completed:=チャレンジ達成: +Challenge Completed!=チャレンジ達成! +Challenge Completed: @1=チャレンジ達成:@1 diff --git a/mods/HUD/awards/locale/awards.pl.tr b/mods/HUD/awards/locale/awards.pl.tr new file mode 100644 index 000000000..76d5b9161 --- /dev/null +++ b/mods/HUD/awards/locale/awards.pl.tr @@ -0,0 +1,63 @@ +# textdomain:awards +@1/@2 chat messages=@1/@2 wiadomości na czacie +@1/@2 crafted=Wytworzono @1/@2 +@1/@2 deaths=@1/@2 śmierci +@1/@2 dug=Wykopano @1/@2 +@1/@2 game joins=Dołączono do @1/@2 gier +@1/@2 placed=Postawiono @1/@2 +@1 (got)=@1 (zdobyto) +@1: @2=@1: @2 +@1’s awards:=Nagrody @1: +(Secret Award)=(Sekretna nagroda) += += +Achievement gotten!=Zdobyto osiągnięcie! +Achievement gotten:=Zdobyto osiągnięcie: +Achievement gotten: @1=Zdobyto osiągnięcie: @1 +Achievement not found.=Nie znaleziono osiągnięcia. +All your awards and statistics have been cleared. You can now start again.=Wszystkie twoje nagrody i statystyki zostały usunięte. Możesz zacząć ponownie. +Awards=Nagrody. +Craft: @1×@2=Wytwórz: @1×@2 +Craft: @1=Wytwórz: @1 +Die @1 times.=Zgiń @1 razy. +Die.=Zgiń. +Get the achievements statistics for the given player or yourself=Zobacz statystyki osiągnięć danego gracza lub siebie +Join the game @1 times.=Dołącz do gry @1 razy. +Join the game.=Dołącz do gry. +List awards in chat (deprecated)=Wypisz nagrody w czacie (przestarzałe) +Place a block: @1=Postaw blok: @1 +Place blocks: @1×@2=Postaw bloki: @1×@2 +Secret achievement gotten!=Zdobyto sekretne osiągnięcie! +Secret achievement gotten:=Zdobyto sekretne osiągnięcie: +Secret achievement gotten: @1=Zdobyto sekretne osiągnięcie: @1 +Show details of an achievement=Pokaż szczegóły osiągnięcia +Show, clear, disable or enable your achievements=Pokaż, wyczyść, wyłącz lub włącz swoje osiągnięcia +Get this achievement to find out what it is.=Zdobądź to osiągnięcie aby dowiedzieć się jakie ono jest. +Write @1 chat messages.=Napisz @1 wiadomości na czacie. +Write something in chat.=Napisz coś na czacie. +You have disabled your achievements.=Twoje osiągnięcia zostały wyłączone. +You have enabled your achievements.=Twoje osiągnięcia zostały włączone. +You have not gotten any awards.=Nie zdobyto żadnych osiągnięć. +You've disabled awards. Type /awards enable to reenable.=Wyłączono osiągnięcia. Napisz /awards by je włączyć. +[c|clear|disable|enable]=[c|clear|disable|enable] +OK=OK +Error: No awards available.=Błąd: Brak dostępnych nagród. +Eat: @1×@2=Zjedz: @1×@2 +Eat: @1=Zjedz: @1 +@1/@2 eaten=Zjedzono @1/@2 +Place @1 block(s).=Postaw bloki: @1. +Dig @1 block(s).=Wykop bloki: @1. +Eat @1 item(s).=Zjedz przedmioty: @1. +Craft @1 item(s).=Wytwórz przedmioty: @1. +Can give achievements to any player=Może przyznawać osiągnięcia dowolnemu graczowi. +(grant ( | all)) | list=(grant ( | all)) | list +Give achievement to player or list all achievements=Daj osiągnięcie graczowi lub wypisz wszystkie osiągnięcia +@1 (@2)=@1 (@2) +Invalid syntax.=Niepoprawna składnia. +Invalid action.=Niepoprawna czynność. +Player is not online.=Gracz nie jest online. +Done.=Gotowe. +Achievement “@1” does not exist.=Osiągnięcie "@1" nie istnieje. +@1 has made the achievement @2=@2 zostało zdobyte przez @1. +Mine a block: @1=Wykop blok: @1 +Mine blocks: @1×@2=Wykop blok: @1×@2 diff --git a/mods/HUD/awards/locale/awards.ru.tr b/mods/HUD/awards/locale/awards.ru.tr index 19623f391..6f7a6d1bf 100644 --- a/mods/HUD/awards/locale/awards.ru.tr +++ b/mods/HUD/awards/locale/awards.ru.tr @@ -1,25 +1,24 @@ # textdomain:awards @1/@2 chat messages=@1/@2 сообщений чата -@1/@2 crafted=@1/@2 скрафчено +@1/@2 crafted=@1/@2 создано @1/@2 deaths=@1/@2 смертей @1/@2 dug=@1/@2 выкопано @1/@2 game joins=@1/@2 присоединений к игре -@1/@2 placed=@1/@2 помещено +@1/@2 placed=@1/@2 размещено @1 (got)=@1 (получено) -@1: @1=@1: @1 +@1: @2=@1: @2 @1’s awards:=Награды @1: -(Secret Award)=(Секретная награда) +(Secret Award)=(Тайная награда) =<идентификатор достижения> =<имя> -A Cat in a Pop-Tart?!=Кот в печеньке?! -Achievement gotten!=Получено достижение! -Achievement gotten:=Получено достижение: -Achievement gotten: @1=Получено достижение: @1 +Advancement Made!=Получено достижение! +Advancement Made:=Получено достижение: +Advancement: @1=Достижение: @1 Achievement not found.=Достижение не найдено. All your awards and statistics have been cleared. You can now start again.=Ваши награды удалены вместе со всей статистикой. Теперь можно начать всё сначала. Awards=Награды -Craft: @1×@2=Скрафчено: @1×@2 -Craft: @1=Скрафчено: @1 +Craft: @1×@2=Создано: @1×@2 +Craft: @1=Создано: @1 Die @1 times.=Умер(ла) @1 раз(а). Die.=Умер(ла). Get the achievements statistics for the given player or yourself=Получение статистики достижений для заданного игрока или для себя @@ -28,34 +27,44 @@ Join the game.=Присоединился(ась) к игре. List awards in chat (deprecated)=Вывести список наград в чат (устарело). Place a block: @1=Разметил(а) блок: @1 Place blocks: @1×@2=Разместил(а) блоки: @1×@2 -Secret Achievement gotten!=Секретное достижение получено! -Secret Achievement gotten:=Секретное достижение получено: -Secret Achievement gotten: @1=Секретное достижение получено: @1 +Secret Advancement Made!=Тайное достижение получено! +Secret Advancement Made:=Тайное достижение получено: +Secret Advancement Made: @1=Тайное достижение получено: @1 Show details of an achievement=Показать подробности достижения -Show, clear, disable or enable your achievements=Отобразить, очистить, запретить или разрешить ваши достижения -Get this achievement to find out what it is.=Получите это достижение, чтобы узнать, что это. -Write @1 chat messages.=Написано @1 сообщений(е,я) в чате. -Write something in chat.=Написал(а) что-то в чате. -You have disabled your achievements.=Вы запретили ваши достижения. -You have enabled your achievements.=Вы разрешили ваши достижения. +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.=Ошибка: Награды недоступны +[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 съедено -Place @1 block(s).=Поместил(а) @1 блок(а,ов). +Place @1 block(s).=Разместил(а) @1 блок(а,ов). Dig @1 block(s).=Выкопал(а) @1 блок(а,ов). Eat @1 item(s).=Съел(а) @1 предмет(а,ов). -Craft @1 item(s).=Скрафтил(а) @1 предмет(а,ов). -Can give achievements to any player=Может выдавать достижения любому игроку -(grant ( | all)) | list=(grant <игрок> (<достижение> | all - всем)) | список -Give achievement to player or list all achievements=Выдать достижение игроку или отобразить все достижения +Craft @1 item(s).=Сделал(а) @1 предмет(а,ов). +Can give advancements to any player=Может выдавать достижения любому игроку +(grant ( | all)) | list=(grant <игрок> (<достижение> | all — всем)) | список +Give advancement to player or list all advancements=Выдать достижение игроку или отобразить все достижения @1 (@2)=@1 (@2) -Invalid syntax.=Неверный синтаксис. +Invalid syntax.=Неверное составление. Invalid action.=Непредусмотренное действие. Player is not online.=Игрок не подключён. -Done.=Сделано. -Achievement “@1” does not exist.=Достижения “@1” не существует. +Done.=Готово. +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 +Awards are disabled, enable them first by using /awards enable!=Награды отключены, сначала включите их с помощью /awards enable! +Goal Completed:=Цель выполнена: +Goal Completed!=Цель выполнена! +Goal Completed: @1=Цель выполнена: @1 +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 529d524c0..5312c2ba7 100644 --- a/mods/HUD/awards/locale/template.txt +++ b/mods/HUD/awards/locale/template.txt @@ -6,15 +6,14 @@ @1/@2 game joins= @1/@2 placed= @1 (got)= -@1: @1= +@1: @2= @1’s awards:= (Secret Award)= = = -A Cat in a Pop-Tart?!= -Achievement gotten!= -Achievement gotten:= -Achievement gotten: @1= +Advancement Made!= +Advancement Made:= +Advancement: @1= Achievement not found.= All your awards and statistics have been cleared. You can now start again.= Awards= @@ -28,16 +27,16 @@ Join the game.= List awards in chat (deprecated)= Place a block: @1= Place blocks: @1×@2= -Secret Achievement gotten!= -Secret Achievement gotten:= -Secret Achievement gotten: @1= +Secret Advancement Made!= +Secret Advancement Made:= +Secret Advancement Made: @1= Show details of an achievement= -Show, clear, disable or enable your achievements= -Get this achievement 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.= Write something in chat.= -You have disabled your achievements.= -You have enabled your achievements.= +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.= [c|clear|disable|enable]= @@ -50,12 +49,22 @@ Place @1 block(s).= Dig @1 block(s).= Eat @1 item(s).= Craft @1 item(s).= -Can give achievements to any player= -(grant ( | all)) | list= -Give achievement to player or list all achievements= +Can give advancements to any player= +(grant ( | all)) | list= +Give advancement to player or list all advancements= @1 (@2)= Invalid syntax.= Invalid action.= Player is not online.= Done.= -Achievement “@1” does not exist.= +Advancement “@1” does not exist.= +@1 has made the advancement @2= +Mine a block: @1= +Mine blocks: @1×@2= +Awards are disabled, enable them first by using /awards enable!= +Goal Completed:= +Goal Completed!= +Goal Completed: @1= +Challenge Completed:= +Challenge Completed!= +Challenge Completed: @1= diff --git a/mods/HUD/awards/mod.conf b/mods/HUD/awards/mod.conf index 24042f267..1657323e2 100644 --- a/mods/HUD/awards/mod.conf +++ b/mods/HUD/awards/mod.conf @@ -5,3 +5,5 @@ description = Adds achievements to Minetest, and an API to register new ones. license = LGPL 2.1 or later forum = https://forum.minetest.net/viewtopic.php?t=4870 version = 2.3.0 +optional_depends = sfinv, unified_inventory +depends = mcl_colors diff --git a/mods/HUD/awards/screenshot.png b/mods/HUD/awards/screenshot.png deleted file mode 100644 index ab9e19e56..000000000 Binary files a/mods/HUD/awards/screenshot.png and /dev/null differ diff --git a/mods/HUD/awards/sfinv.lua b/mods/HUD/awards/sfinv.lua index 5d02cbb58..3b41d29ab 100644 --- a/mods/HUD/awards/sfinv.lua +++ b/mods/HUD/awards/sfinv.lua @@ -1,5 +1,5 @@ if minetest.get_modpath("sfinv") then - local S = minetest.get_translator("awards") + local S = minetest.get_translator(minetest.get_current_modname()) sfinv.register_page("awards:awards", { title = S("Awards"), diff --git a/mods/HUD/awards/textures/awards_bg_default.png b/mods/HUD/awards/textures/awards_bg_default.png deleted file mode 100644 index 86130d01f..000000000 Binary files a/mods/HUD/awards/textures/awards_bg_default.png and /dev/null differ diff --git a/mods/HUD/awards/textures/awards_bg_mining.png b/mods/HUD/awards/textures/awards_bg_mining.png deleted file mode 100644 index a6987794f..000000000 Binary files a/mods/HUD/awards/textures/awards_bg_mining.png and /dev/null differ diff --git a/mods/HUD/awards/textures/awards_template.png b/mods/HUD/awards/textures/awards_template.png deleted file mode 100644 index b29045480..000000000 Binary files a/mods/HUD/awards/textures/awards_template.png and /dev/null differ diff --git a/mods/HUD/awards/textures/awards_ui_icon.png b/mods/HUD/awards/textures/awards_ui_icon.png deleted file mode 100644 index 239ad71ec..000000000 Binary files a/mods/HUD/awards/textures/awards_ui_icon.png and /dev/null differ diff --git a/mods/HUD/awards/textures/awards_unknown.png b/mods/HUD/awards/textures/awards_unknown.png deleted file mode 100644 index b29045480..000000000 Binary files a/mods/HUD/awards/textures/awards_unknown.png and /dev/null differ diff --git a/mods/HUD/awards/triggers.lua b/mods/HUD/awards/triggers.lua index 318a4b281..c7194d2c9 100644 --- a/mods/HUD/awards/triggers.lua +++ b/mods/HUD/awards/triggers.lua @@ -14,7 +14,7 @@ -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -- -local S = minetest.get_translator("awards") +local S = minetest.get_translator(minetest.get_current_modname()) awards.register_trigger("dig", function(def) local tmp = { @@ -250,9 +250,7 @@ minetest.register_on_dignode(function(pos, oldnode, digger) local tnodedug = string.split(entry.node, ":") local tmod = tnodedug[1] local titem = tnodedug[2] - if not tmod or not titem or not data.count[tmod] or not data.count[tmod][titem] then - -- table running failed! - elseif data.count[tmod][titem] > entry.target-1 then + if tmod and titem and data.count[tmod] and data.count[tmod][titem] and data.count[tmod][titem] > entry.target-1 then return entry.award end elseif awards.get_total_item_count(data, "count") > entry.target-1 then @@ -277,9 +275,7 @@ minetest.register_on_placenode(function(pos, node, digger) local tnodedug = string.split(entry.node, ":") local tmod = tnodedug[1] local titem = tnodedug[2] - if not tmod or not titem or not data.place[tmod] or not data.place[tmod][titem] then - -- table running failed! - elseif data.place[tmod][titem] > entry.target-1 then + if tmod and titem and data.place[tmod] and data.place[tmod][titem] and data.place[tmod][titem] > entry.target-1 then return entry.award end elseif awards.get_total_item_count(data, "place") > entry.target-1 then @@ -303,9 +299,7 @@ minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, local titemstring = string.split(entry.item, ":") local tmod = titemstring[1] local titem = titemstring[2] - if not tmod or not titem or not data.eat[tmod] or not data.eat[tmod][titem] then - -- table running failed! - elseif data.eat[tmod][titem] > entry.target-1 then + if tmod and titem and data.eat[tmod] and data.eat[tmod][titem] and data.eat[tmod][titem] > entry.target-1 then return entry.award end elseif awards.get_total_item_count(data, "eat") > entry.target-1 then @@ -331,9 +325,7 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv local titemcrafted = string.split(entry.item, ":") local tmod = titemcrafted[1] local titem = titemcrafted[2] - if not tmod or not titem or not data.craft[tmod] or not data.craft[tmod][titem] then - -- table running failed! - elseif data.craft[tmod][titem] > entry.target-1 then + if tmod and titem and data.craft[tmod] and data.craft[tmod][titem] and data.craft[tmod][titem] > entry.target-1 then return entry.award end elseif awards.get_total_item_count(data, "craft") > entry.target-1 then @@ -390,7 +382,7 @@ end) minetest.register_on_chat_message(function(name, message) -- Run checks local idx = string.find(message,"/") - if not name or (idx ~= nil and idx <= 1) then + if not name or (idx and idx <= 1) then return end diff --git a/mods/HUD/awards/unified_inventory.lua b/mods/HUD/awards/unified_inventory.lua index be5ca5f94..3dc238e1a 100644 --- a/mods/HUD/awards/unified_inventory.lua +++ b/mods/HUD/awards/unified_inventory.lua @@ -1,6 +1,5 @@ -if minetest.get_modpath("unified_inventory") ~= nil then - local S = minetest.get_translator("awards") - +if minetest.get_modpath("unified_inventory") then + local S = minetest.get_translator(minetest.get_current_modname()) unified_inventory.register_button("awards", { type = "image", image = "awards_ui_icon.png", diff --git a/mods/HUD/hudbars/API.md b/mods/HUD/hudbars/API.md index ca6144ad1..ee112eceb 100644 --- a/mods/HUD/hudbars/API.md +++ b/mods/HUD/hudbars/API.md @@ -17,7 +17,7 @@ To give you a *very* brief overview over this API, here is the basic workflow on In order to use this API, you should be aware of a few basic rules in order to understand it: * A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%. -* The current value must always be equal to or smaller then the maximum +* The current value must always be equal to or smaller then the maximum * Both current value and maximum must not be smaller than 0 * Both current value and maximum must be real numbers. So no NaN, infinity, etc. * The HUD bar will be hidden if the maximum equals 0. This is intentional. @@ -45,7 +45,7 @@ a vertical gradient. ### Icon A 16×16 image shown left of the HUD bar. This is optional. -### `hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` +### `hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)` This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden and unhidden on a per-player basis. Note this does not yet display the HUD bar. @@ -63,6 +63,7 @@ for more information. * `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section). * `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used. * `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode. +* `direction`: Either left to right(0), or right to left(1). * `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value * `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value * `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it. diff --git a/mods/HUD/hudbars/default_settings.lua b/mods/HUD/hudbars/default_settings.lua index 0bd267d0e..865a7cb6a 100644 --- a/mods/HUD/hudbars/default_settings.lua +++ b/mods/HUD/hudbars/default_settings.lua @@ -20,9 +20,9 @@ if hb.settings.bar_type == "progress_bar" then hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86) else - hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -265) + hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -258) hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90) - hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 25) + hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 16) hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90) end -- Modified in MCL2! @@ -37,7 +37,7 @@ hb.settings.alignment_pattern = hb.load_setting("hudbars_alignment_pattern", "st hb.settings.autohide_breath = hb.load_setting("hudbars_autohide_breath", "bool", true) local sorting = minetest.settings:get("hudbars_sorting") -if sorting ~= nil then +if sorting then hb.settings.sorting = {} hb.settings.sorting_reverse = {} for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do diff --git a/mods/HUD/hudbars/init.lua b/mods/HUD/hudbars/init.lua index 44c826656..505ff403b 100644 --- a/mods/HUD/hudbars/init.lua +++ b/mods/HUD/hudbars/init.lua @@ -1,17 +1,22 @@ -local S = minetest.get_translator("hudbars") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local S = minetest.get_translator(modname) local N = function(s) return s end -hb = {} +local math = math +local table = table -hb.hudtables = {} - --- number of registered HUD bars -hb.hudbars_count = 0 - --- table which records which HUD bar slots have been “registered” so far; used for automatic positioning -hb.registered_slots = {} - -hb.settings = {} +hb = { + hudtables = {}, + -- number of registered HUD bars + hudbars_count = 0, + -- table which records which HUD bar slots have been “registered” so far; used for automatic positioning + registered_slots = {}, + settings = {}, + -- Table which contains all players with active default HUD bars (only for internal use) + players = {}, +} function hb.load_setting(sname, stype, defaultval, valid_values) local sval @@ -22,10 +27,10 @@ function hb.load_setting(sname, stype, defaultval, valid_values) elseif stype == "number" then sval = tonumber(minetest.settings:get(sname)) end - if sval ~= nil then - if valid_values ~= nil then + if sval then + if valid_values then local valid = false - for i=1,#valid_values do + for i = 1, #valid_values do if sval == valid_values[i] then valid = true end @@ -45,8 +50,9 @@ function hb.load_setting(sname, stype, defaultval, valid_values) end -- Load default settings -dofile(minetest.get_modpath("hudbars").."/default_settings.lua") -if minetest.get_modpath("mcl_experience") then +dofile(modpath.."/default_settings.lua") + +if minetest.get_modpath("mcl_experience") and not minetest.is_creative_enabled("") then -- reserve some space for experience bar: hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20 hb.settings.start_offset_right.y = hb.settings.start_offset_right.y - 20 @@ -85,9 +91,6 @@ local function make_label(format_string, format_string_config, label, start_valu return ret end --- Table which contains all players with active default HUD bars (only for internal use) -hb.players = {} - function hb.value_to_barlength(value, max) if max == 0 then return 0 @@ -111,7 +114,7 @@ function hb.get_hudtable(identifier) end function hb.get_hudbar_position_index(identifier) - if hb.settings.sorting[identifier] ~= nil then + if hb.settings.sorting[identifier] then return hb.settings.sorting[identifier] else local i = 0 @@ -124,7 +127,7 @@ function hb.get_hudbar_position_index(identifier) end end -function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) +function hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config) minetest.log("action", "hb.register_hudbar: "..tostring(identifier)) local hudtable = {} local pos, offset @@ -133,30 +136,33 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta if hb.settings.alignment_pattern == "stack_up" then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + x = direction == 0 and hb.settings.start_offset_left.x or -hb.settings.start_offset_right.x, y = hb.settings.start_offset_left.y - hb.settings.vmargin * index } elseif hb.settings.alignment_pattern == "stack_down" then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + x = direction == 0 and hb.settings.start_offset_right.x or -hb.settings.start_offset_left.x, y = hb.settings.start_offset_left.y + hb.settings.vmargin * index } - else + else -- zigzag if index % 2 == 0 then pos = hb.settings.pos_left offset = { - x = hb.settings.start_offset_left.x, + -- -(24+18) = -42. using linear eq, -42 = -258m - 24. + x = direction == 0 and hb.settings.start_offset_left.x or (-42+24)/(-258.0) * hb.settings.start_offset_left.x - 24, y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2) } else pos = hb.settings.pos_right offset = { - x = hb.settings.start_offset_right.x, + -- 24*10+30 - 24 = 234. using linear eq, 234 = 16m - 24. + x = direction == 0 and hb.settings.start_offset_right.x or (234+24)/(16) * hb.settings.start_offset_right.x - 24, y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2) } end end + if format_string == nil then format_string = N("@1: @2/@3") end @@ -173,7 +179,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta format_string_config.format_max_value = "%d" end - hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden) + function hudtable.add_all(player, hudtable, start_value, start_max, start_hidden) if start_value == nil then start_value = hudtable.default_start_value end if start_max == nil then start_max = hudtable.default_start_max end if start_hidden == nil then start_hidden = hudtable.default_start_hidden end @@ -181,6 +187,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta local state = {} local name = player:get_player_name() local bgscale, iconscale, text, barnumber, bgiconnumber + if start_max == 0 or start_hidden then bgscale = { x=0, y=0 } else @@ -197,6 +204,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta bgiconnumber = hb.settings.statbar_length text = make_label(format_string, format_string_config, label, start_value, start_max) end + if hb.settings.bar_type == "progress_bar" then ids.bg = player:hud_add({ hud_elem_type = "image", @@ -207,7 +215,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta offset = { x = offset.x - 1, y = offset.y - 1 }, z_index = 0, }) - if textures.icon ~= nil then + if textures.icon then ids.icon = player:hud_add({ hud_elem_type = "image", position = pos, @@ -219,6 +227,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta }) end end + local bar_image, bgicon, bar_size if hb.settings.bar_type == "progress_bar" then bar_image = textures.bar @@ -234,10 +243,12 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta bgicon = textures.bgicon bar_size = {x=24, y=24} end + local text2 if hb.settings.bar_type == "statbar_modern" then text2 = bgicon end + ids.bar = player:hud_add({ hud_elem_type = "statbar", position = pos, @@ -247,7 +258,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta item = bgiconnumber, alignment = {x=-1,y=-1}, offset = offset, - direction = 0, + direction = direction, size = bar_size, z_index = 1, }) @@ -258,7 +269,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta text = text, alignment = {x=1,y=1}, number = text_color, - direction = 0, + direction = direction, offset = { x = offset.x + 2, y = offset.y - 1}, z_index = 2, }) @@ -298,7 +309,7 @@ function hb.register_hudbar(identifier, text_color, label, textures, default_sta hudtable.default_start_max = default_start_max hb.hudbars_count= hb.hudbars_count + 1 - + hb.hudtables[identifier] = hudtable end @@ -324,7 +335,7 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon end local value_changed, max_changed = false, false - if new_value ~= nil then + if new_value then if new_value ~= hudtable.hudstate[name].value then hudtable.hudstate[name].value = new_value value_changed = true @@ -332,7 +343,7 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon else new_value = hudtable.hudstate[name].value end - if new_max_value ~= nil then + if new_max_value then if new_max_value ~= hudtable.hudstate[name].max then hudtable.hudstate[name].max = new_max_value max_changed = true @@ -342,28 +353,29 @@ function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon end if hb.settings.bar_type == "progress_bar" then - if new_icon ~= nil and hudtable.hudids[name].icon ~= nil then + if new_icon and hudtable.hudids[name].icon then player:hud_change(hudtable.hudids[name].icon, "text", new_icon) end - if new_bgicon ~= nil and hudtable.hudids[name].bgicon ~= nil then + if new_bgicon and hudtable.hudids[name].bgicon then player:hud_change(hudtable.hudids[name].bgicon, "text", new_bgicon) end - if new_bar ~= nil then + if new_bar then player:hud_change(hudtable.hudids[name].bar , "text", new_bar) end - if new_label ~= nil then + if new_label then hudtable.label = new_label local new_text = make_label(hudtable.format_string, hudtable.format_string_config, new_label, hudtable.hudstate[name].value, hudtable.hudstate[name].max) player:hud_change(hudtable.hudids[name].text, "text", new_text) end - if new_text_color ~= nil then + if new_text_color then player:hud_change(hudtable.hudids[name].text, "number", new_text_color) end + else - if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then + if new_icon and hudtable.hudids[name].bar then player:hud_change(hudtable.hudids[name].bar, "text", new_icon) end - if new_bgicon ~= nil and hudtable.hudids[name].bg ~= nil then + if new_bgicon and hudtable.hudids[name].bg then player:hud_change(hudtable.hudids[name].bg, "text", new_bgicon) end end @@ -413,8 +425,9 @@ function hb.hide_hudbar(player, identifier) local name = player:get_player_name() local hudtable = hb.get_hudtable(identifier) if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == true then return true end if hb.settings.bar_type == "progress_bar" then - if hudtable.hudids[name].icon ~= nil then + if hudtable.hudids[name].icon then player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0}) end player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0}) @@ -431,10 +444,11 @@ function hb.unhide_hudbar(player, identifier) local name = player:get_player_name() local hudtable = hb.get_hudtable(identifier) if hudtable == nil then return false end + if hudtable.hudstate[name].hidden == false then return true end local value = hudtable.hudstate[name].value local max = hudtable.hudstate[name].max if hb.settings.bar_type == "progress_bar" then - if hudtable.hudids[name].icon ~= nil then + if hudtable.hudids[name].icon then player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1}) end if hudtable.hudstate[name].max ~= 0 then @@ -474,8 +488,8 @@ end --register built-in HUD bars if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then - hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false) - hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true) + hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 0, 20, 20, false) + hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 1, 10, 10, true) end local function hide_builtin(player) @@ -511,16 +525,16 @@ local function update_health(player) end -- update built-in HUD bars -local function update_hud(player) +local function update_hud(player, has_damage) if not player_exists(player) then return end - if minetest.settings:get_bool("enable_damage") then + if has_damage then if hb.settings.forceload_default_hudbars then hb.unhide_hudbar(player, "health") end --air local breath_max = player:get_properties().breath_max local breath = player:get_breath() - + if breath >= breath_max and hb.settings.autohide_breath == true then hb.hide_hudbar(player, "breath") else @@ -536,7 +550,7 @@ local function update_hud(player) end minetest.register_on_player_hpchange(function(player) - if hb.players[player:get_player_name()] ~= nil then + if hb.players[player:get_player_name()] then update_health(player) end end) @@ -564,10 +578,11 @@ minetest.register_globalstep(function(dtime) if main_timer > hb.settings.tick or timer > 4 then if main_timer > hb.settings.tick then main_timer = 0 end -- only proceed if damage is enabled - if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then + local has_dmg = minetest.settings:get_bool("enable_damage") + if has_dmg or hb.settings.forceload_default_hudbars then for _, player in pairs(hb.players) do -- update all hud elements - update_hud(player) + update_hud(player, has_dmg) end end end diff --git a/mods/HUD/hudbars/locale/hudbars.fr.tr b/mods/HUD/hudbars/locale/hudbars.fr.tr index b31b7b0c1..586caa718 100644 --- a/mods/HUD/hudbars/locale/hudbars.fr.tr +++ b/mods/HUD/hudbars/locale/hudbars.fr.tr @@ -1,6 +1,6 @@ # textdomain: hudbars Health=Santé -Breath=Breath +Breath=Respiration # Default format string for progress bar-style HUD bars, e.g. “Health 5/20” -@1: @2/@3=@1: @2/@3 +@1: @2/@3=@1 : @2/@3 diff --git a/mods/HUD/hudbars/locale/hudbars.ja.tr b/mods/HUD/hudbars/locale/hudbars.ja.tr new file mode 100644 index 000000000..712c915cb --- /dev/null +++ b/mods/HUD/hudbars/locale/hudbars.ja.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=ヘルス +Breath=呼吸 + +# 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.pl.tr b/mods/HUD/hudbars/locale/hudbars.pl.tr new file mode 100644 index 000000000..be06b3579 --- /dev/null +++ b/mods/HUD/hudbars/locale/hudbars.pl.tr @@ -0,0 +1,7 @@ +# textdomain: hudbars +Health=Życie +Breath=Tlen + +# 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.zh_TW.tr b/mods/HUD/hudbars/locale/hudbars.zh_TW.tr new file mode 100644 index 000000000..2163c659e --- /dev/null +++ b/mods/HUD/hudbars/locale/hudbars.zh_TW.tr @@ -0,0 +1,6 @@ +# textdomain: hudbars +Health=生命 +Breath=氧氣 + +# Default format string for progress bar-style HUD bars, e.g. “Health 5/20” +@1: @2/@3= diff --git a/mods/HUD/hudbars/mod.conf b/mods/HUD/hudbars/mod.conf index 5fa238a83..9d49f65ec 100644 --- a/mods/HUD/hudbars/mod.conf +++ b/mods/HUD/hudbars/mod.conf @@ -1,2 +1,3 @@ name = hudbars +author = Wuzzy description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats. diff --git a/mods/HUD/hudbars/screenshot.png b/mods/HUD/hudbars/screenshot.png deleted file mode 100644 index 88ee3238d..000000000 Binary files a/mods/HUD/hudbars/screenshot.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_bar_background.png b/mods/HUD/hudbars/textures/hudbars_bar_background.png deleted file mode 100644 index cbc6c3f51..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_bar_background.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_bar_breath.png b/mods/HUD/hudbars/textures/hudbars_bar_breath.png deleted file mode 100644 index 7d19a5752..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_bar_breath.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_bar_health.png b/mods/HUD/hudbars/textures/hudbars_bar_health.png deleted file mode 100644 index 9043e1191..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_bar_health.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_bgicon_breath.png b/mods/HUD/hudbars/textures/hudbars_bgicon_breath.png deleted file mode 100644 index 51cb79aa7..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_bgicon_breath.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_bgicon_health.png b/mods/HUD/hudbars/textures/hudbars_bgicon_health.png deleted file mode 100644 index aa4a6123c..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_bgicon_health.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_icon_breath.png b/mods/HUD/hudbars/textures/hudbars_icon_breath.png deleted file mode 100644 index f1d714fec..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_icon_breath.png and /dev/null differ diff --git a/mods/HUD/hudbars/textures/hudbars_icon_health.png b/mods/HUD/hudbars/textures/hudbars_icon_health.png deleted file mode 100644 index d0e304100..000000000 Binary files a/mods/HUD/hudbars/textures/hudbars_icon_health.png and /dev/null differ diff --git a/mods/HUD/mcl_achievements/depends.txt b/mods/HUD/mcl_achievements/depends.txt deleted file mode 100644 index 203a4c0ab..000000000 --- a/mods/HUD/mcl_achievements/depends.txt +++ /dev/null @@ -1 +0,0 @@ -awards diff --git a/mods/HUD/mcl_achievements/init.lua b/mods/HUD/mcl_achievements/init.lua index 7473568d2..4d272fe86 100644 --- a/mods/HUD/mcl_achievements/init.lua +++ b/mods/HUD/mcl_achievements/init.lua @@ -3,7 +3,7 @@ -- If true, activates achievements from other Minecraft editions (XBox, PS, etc.) local non_pc_achievements = false -local S = minetest.get_translator("mcl_achievements") +local S = minetest.get_translator(minetest.get_current_modname()) -- Achievements from PC Edition @@ -15,7 +15,9 @@ awards.register_achievement("mcl_buildWorkBench", { type = "craft", item = "mcl_crafting_table:crafting_table", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildPickaxe", { title = S("Time to Mine!"), @@ -25,7 +27,9 @@ awards.register_achievement("mcl:buildPickaxe", { type = "craft", item = "mcl_tools:pick_wood", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildFurnace", { title = S("Hot Topic"), @@ -35,7 +39,9 @@ awards.register_achievement("mcl:buildFurnace", { type = "craft", item = "mcl_furnaces:furnace", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildHoe", { title = S("Time to Farm!"), @@ -45,7 +51,9 @@ awards.register_achievement("mcl:buildHoe", { type = "craft", item = "mcl_farming:hoe_wood", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:makeBread", { title = S("Bake Bread"), @@ -55,7 +63,9 @@ awards.register_achievement("mcl:makeBread", { type = "craft", item = "mcl_farming:bread", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:bakeCake", { @@ -66,7 +76,9 @@ awards.register_achievement("mcl:bakeCake", { type = "craft", item = "mcl_cake:cake", target = 1 - } + }, + type = "Advancement", + group = "Husbandry", }) awards.register_achievement("mcl:buildBetterPickaxe", { title = S("Getting an Upgrade"), @@ -77,7 +89,9 @@ awards.register_achievement("mcl:buildBetterPickaxe", { type = "craft", item = "mcl_tools:pick_stone", target = 1 - } + }, + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:buildSword", { title = S("Time to Strike!"), @@ -87,7 +101,9 @@ awards.register_achievement("mcl:buildSword", { type = "craft", item = "mcl_tools:sword_wood", target = 1 - } + }, + type = "Advancement", + group = "Adventure", }) awards.register_achievement("mcl:bookcase", { @@ -98,7 +114,22 @@ awards.register_achievement("mcl:bookcase", { type = "craft", item = "mcl_books:bookshelf", target = 1 - } + }, + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:buildIronPickaxe", { + title = S("Isn't It Iron Pick"), + description = S("Craft a iron pickaxe using sticks and iron."), + icon = "default_tool_steelpick.png", + trigger = { + type = "craft", + item = "mcl_tools:pick_iron", + target = 1 + }, + type = "Advancement", + group = "Overworld", }) -- Item pickup achievements: These are awarded when picking up a certain item. @@ -107,35 +138,78 @@ awards.register_achievement("mcl:diamonds", { title = S("DIAMONDS!"), description = S("Pick up a diamond from the floor."), icon = "mcl_core_diamond_ore.png", + type = "Advancement", }) awards.register_achievement("mcl:blazeRod", { title = S("Into Fire"), description = S("Pick up a blaze rod from the floor."), icon = "mcl_mobitems_blaze_rod.png", + type = "Advancement", + group = "Nether", }) awards.register_achievement("mcl:killCow", { title = S("Cow Tipper"), description = S("Pick up leather from the floor.\nHint: Cows and some other animals have a chance to drop leather, when killed."), icon = "mcl_mobitems_leather.png", + type = "Advancement", + group = "Adventure", }) awards.register_achievement("mcl:mineWood", { title = S("Getting Wood"), description = S("Pick up a wood item from the ground.\nHint: Punch a tree trunk until it pops out as an item."), icon = "default_tree.png", + type = "Advancement", + group = "Overworld", }) +awards.register_achievement("mcl:whosCuttingOnions", { + title = S("Who is Cutting Onions?"), + description = S("Pick up a crying obsidian from the floor."), + icon = "default_obsidian.png^mcl_core_crying_obsidian.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:hiddenInTheDepths", { + title = S("Hidden in the Depths"), + description = S("Pick up an Ancient Debris from the floor."), + icon = "mcl_nether_ancient_debris_side.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:PickUpDragonEgg", { + title = S("The Next Generation"), + description = S("Hold the Dragon Egg.\nHint: Pick up the egg from the ground and have it in your inventory."), + icon = "mcl_end_dragon_egg.png", + type = "Goal", + group = "End", +}) + +awards.register_achievement("mcl:skysTheLimit", { + title = S("Sky's the Limit"), + description = S("Find the elytra and prepare to fly above and beyond!"), + icon = "mcl_armor_inv_elytra.png", + type = "Goal", + group = "End", +}) -- TODO: Make also unlock when moved to inventory, not just picking up from ground + -- Smelting achivements: These are awarded when picking up an item from a furnace -- output. They are given in mcl_furnaces. awards.register_achievement("mcl:acquireIron", { - title = S("Aquire Hardware"), + title = S("Acquire Hardware"), description = S("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."), icon = "default_steel_ingot.png", + type = "Advancement", + group = "Overworld", }) awards.register_achievement("mcl:cookFish", { title = S("Delicious Fish"), description = S("Take a cooked fish from a furnace.\nHint: Use a fishing rod to catch a fish and cook it in a furnace."), icon = "mcl_fishing_fish_cooked.png", + type = "Advancement", + group = "Husbandry", }) -- Other achievements triggered outside of mcl_achievements @@ -145,6 +219,8 @@ awards.register_achievement("mcl:onARail", { title = S("On A Rail"), description = S("Travel by minecart for at least 1000 meters from your starting point in a single ride."), icon = "default_rail.png", + type = "Challenge", + group = "Adventure", }) -- Triggered in mcl_bows @@ -154,13 +230,205 @@ awards.register_achievement("mcl:snipeSkeleton", { -- TODO: The range should be 50, not 20. Nerfed because of reduced bow range description = S("Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters."), icon = "mcl_bows_bow.png", + type = "Challenge", + group = "Adventure", }) -- Triggered in mcl_portals awards.register_achievement("mcl:buildNetherPortal", { - title = S("Into the Nether"), + title = S("We Need to Go Deeper"), description = S("Use obsidian and a fire starter to construct a Nether portal."), - icon = "default_obsidian.png", + icon = "mcl_fire_flint_and_steel.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:enterEndPortal", { + title = S("The End?"), + description = S("Or the beginning?\nHint: Enter an end portal."), + icon = "mcl_end_end_stone.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:theNether", { + title = S("The Nether"), + description = S("Bring summer clothes.\nHint: Enter the Nether."), + icon = "mcl_nether_netherrack.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_totems +awards.register_achievement("mcl:postMortal", { + title = S("Postmortal"), + description = S("Use a Totem of Undying to cheat death."), + icon = "mcl_totems_totem.png", + type = "Goal", + group = "Adventure", +}) + +-- Triggered in mcl_beds +awards.register_achievement("mcl:sweetDreams", { + title = S("Sweet Dreams"), + description = S("Sleep in a bed to change your respawn point."), + icon = "mcl_beds_bed_red_inv.png", + type = "Advancement", + group = "Adventure", +}) + +awards.register_achievement("mcl:notQuiteNineLives", { + title = S('Not Quite "Nine" Lives'), + description = S("Charge a Respawn Anchor to the maximum."), + icon = "respawn_anchor_side4.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mobs_mc +awards.register_achievement("mcl:whatAdeal", { + title = S("What A Deal!"), + description = S("Successfully trade with a Villager."), + icon = "mcl_core_emerald.png", + type = "Advancement", + group = "Adventure", +}) + +awards.register_achievement("mcl:tacticalFishing", { + title = S("Tactical Fishing"), + description = S("Catch a fish... without a fishing rod!"), + icon = "mcl_buckets_pufferfish_bucket.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:cutestPredator", { + title = S("The Cutest Predator"), + description = S("Catch an Axolotl with a bucket!"), + icon = "mcl_buckets_axolotl_bucket.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:witheringHeights", { + title = S("Withering Heights"), + description = S("Summon the wither from the dead."), + icon = "mcl_mobitems_nether_star.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:freeTheEnd", { + title = S("Free the End"), + description = S("Kill the ender dragon. Good Luck!"), + icon = "(spawn_egg.png^[multiply:#252525)^(spawn_egg_overlay.png^[multiply:#b313c9)", -- TODO: Dragon Head Icon + type = "Advancement", + group = "End", +}) + +-- Triggered in mcl_fishing +awards.register_achievement("mcl:fishyBusiness", { + title = S("Fishy Business"), + description = S("Catch a fish.\nHint: Catch a fish, salmon, clownfish, or pufferfish."), + icon = "mcl_fishing_fishing_rod.png", + type = "Advancement", + group = "Husbandry", +}) + +-- Triggered in mcl_compass +awards.register_achievement("mcl:countryLode", { + title = S("Country Lode, Take Me Home"), + description = S("Use a compass on a Lodestone."), + icon = "lodestone_side4.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_smithing_table +awards.register_achievement("mcl:seriousDedication", { + title = S("Serious Dedication"), + description = S("Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices."), + icon = "farming_tool_netheritehoe.png", + type = "Challenge", + group = "Husbandry", +}) + +-- Triggered in mcl_brewing +awards.register_achievement("mcl:localBrewery", { + title = S("Local Brewery"), + description = S("Brew a Potion.\nHint: Take a potion or glass bottle out of the brewing stand."), + icon = "mcl_potions_potion_overlay.png^[colorize:#F82423:"..tostring(127).."^mcl_potions_potion_bottle.png", + type = "Advancement", + group = "Nether", +}) + +-- Triggered in mcl_enchanting +awards.register_achievement("mcl:enchanter", { + title = S("Enchanter"), + description = S("Enchant an item using an Enchantment Table."), + icon = "mcl_enchanting_book_enchanted.png", + type = "Advancement", + group = "Overworld", +}) + +--Triggered in mcl_beacons +awards.register_achievement("mcl:beacon", { + title = S("Bring Home the Beacon"), + description = S("Use a beacon."), + icon = "beacon_achievement_icon.png", + type = "Advancement", + group = "Nether", +}) + +awards.register_achievement("mcl:maxed_beacon", { + title = S("Beaconator"), + description = S("Use a fully powered beacon."), + icon = "beacon_achievement_icon.png", + type = "Goal", + group = "Nether", +}) + +-- Triggered in mcl_end +awards.register_achievement("mcl:theEndAgain", { + title = S("The End... Again..."), + description = S("Respawn the Ender Dragon."), + icon = "mcl_end_crystal_item.png", + type = "Goal", + group = "End", +}) + +-- Triggered in mcl_beehives +awards.register_achievement("mcl:bee_our_guest", { + title = S("Bee Our Guest"), + description = S("Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside."), + icon = "mcl_honey_honey_bottle.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:total_beelocation", { + title = S("Total Beelocation"), + description = S("Move a bee nest, with 3 bees inside, using a silk touch enchanted tool."), + icon = "mcl_beehives_bee_nest_front_honey.png", + type = "Advancement", + group = "Husbandry", +}) + +-- Triggered in mcl_copper +awards.register_achievement("mcl:wax_on", { + title = S("Wax On"), + description = S("Apply honeycomb to a copper block to protect it from the elements."), + icon = "mcl_honey_honeycomb.png", + type = "Advancement", + group = "Husbandry", +}) + +awards.register_achievement("mcl:wax_off", { + title = S("Wax Off"), + description = S("Scrape wax off of a copper block."), + icon = "default_tool_stoneaxe.png", + type = "Advancement", + group = "Husbandry", }) -- NON-PC ACHIEVEMENTS (XBox, Pocket Edition, etc.) @@ -238,3 +506,44 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) awards.show_to(name, name, nil, false) end end) + + +awards.register_achievement("mcl:stoneAge", { + title = S("Stone Age"), + description = S("Mine a stone with new pickaxe."), + icon = "default_cobble.png", + type = "Advancement", + group = "Overworld", +}) +awards.register_achievement("mcl:hotStuff", { + title = S("Hot Stuff"), + description = S("Put lava in a bucket."), + icon = "mcl_buckets_lava_bucket.png", + type = "Advancement", + group = "Overworld", +}) +awards.register_achievement("mcl:obsidian", { + title = S("Ice Bucket Challenge"), + description = S("Obtain an obsidian block."), + icon = "default_obsidian.png", + type = "Advancement", + group = "Overworld", +}) + +awards.register_achievement("mcl:hero_of_the_village", { + title = S("Hero of the Village"), + description = S("Successfully defend a village from a raid"), + icon = "mcl_raids_hero_of_the_village_icon.png", + type = "Advancement", + group = "Adventure", + secret = true, +}) + +awards.register_achievement("mcl:voluntary_exile", { + title = S("Voluntary Exile"), + description = S("Kill a raid captain. Maybe consider staying away from the local villages for the time being..."), + icon = "mcl_potions_effect_bad_omen.png", + type = "Advancement", + group = "Adventure", + secret = true, +}) diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr index 49c486e48..1c6f668e5 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.de.tr @@ -1,5 +1,5 @@ # textdomain:mcl_achievements -Aquire Hardware=Schmied +Acquire Hardware=Schmied Bake Bread=Brot backen Benchmarking=Tischler Cow Tipper=Kuhschubser @@ -47,3 +47,7 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Benutz Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Benutzen Sie eine Werkbank, um eine Holzspitzhacke aus Holzplanken und Stöcken zu fertigen. Use obsidian and a fire starter to construct a Nether portal.=Benutzen Sie Obsidian und ein Feuerzeug, um ein Netherportal zu errichten. Use wheat to craft a bread.=Benutzen Sie Weizen, um ein Brot zu machen. +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. diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr index 2044e8261..6f00d76b7 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.es.tr @@ -1,5 +1,5 @@ # textdomain:mcl_achievements -Aquire Hardware=Obteniendo un lingote +Acquire Hardware=Obteniendo un lingote Bake Bread=Horneando pan Benchmarking=Crea tu mesa de trabajo Cow Tipper=Consiguiendo cuero @@ -47,3 +47,68 @@ Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Usa un Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Usa una mesa de trabajo para hacer un pico de madera con tablas de madera procesada y palos de madera. Use obsidian and a fire starter to construct a Nether portal.=Usa obsidiana y un iniciador de fuego para construir un portal abisal. Use wheat to craft a bread.=Usa trigo para elaborar pan. +Who is Cutting Onions?=¿Quién esta cortando cebollas? +Pick up a crying obsidian from the floor.=Recoge una obsidiana llorosa del suelo +Hidden in the Depths=Oculto en las profundidades +Pick up an Ancient Debris from the floor.=Recoge un Escombro Ancestral del suelo +The Nether=El Nether +Bring summer clothes.@nHint: Enter the Nether.=Tráete ropa de verano.@nSugerencia: Entra al Nether +Isn't It Iron Pick=¿No es hierrónico? +Craft a iron pickaxe using sticks and iron.=Crea un pico de hierro usando palos y hierro. +Postmortal=Post mortem +Use a Totem of Undying to cheat death.=Usa un tótem de inmortalidad para engañar a la muerte +Sweet Dreams=Dulces sueños +Sleep in a bed to change your respawn point.=Duerme en una cama para cambiar tu punto de reaparición. +Not Quite "Nine" Lives=No "siete" vidas exactamente +Charge a Respawn Anchor to the maximum.=Carga un nexo de reaparición al máximo. +What A Deal!=¡Qué buen trato! +Successfully trade with a Villager.=Comercia con un aldeano. +Withering Heights=Dr. Witherstein +Summon the wither from the dead.=Invoca al wither desde los muertos. +The Cutest Predator=El depredador más lindo +Catch an Axolotl with a bucket!=Atrapa a un ajolote en un cubo +Fishy Business=Un asuno escamoso +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=Atrapa un pez.@nSugerencia: Atrapa un pez, salmón, pez payaso, o pez globo. +Country Lode, Take Me Home=Magnetita llévame a casita +Use a compass on a Lodestone.=Usa una brújula sobre una magnetita +Serious Dedication=Dedicación seria +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=Usa un lingote de netherita para mejorar una azada, y luego revalúa lo que estás haciendo con tu vida. +Local Brewery=Destilería local +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=Prepara una poción.@nSugerencia: Saca una poción o botella de vidrio de la destiladora +Enchanter=Aprendiz de mago +Enchant an item using an Enchantment Table.=Encanta un objeto usando la mesa de encantamientos +Bring Home the Beacon=Hágase la luz +Use a beacon.=Usa un faro. +Beaconator=Faroneitor +Use a fully powered beacon.=Utiliza un faro a máxima potencia. +The Next Generation=La nueva generación +Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.=Consigue el huevo de dragón.@nSugerencia: Recoge el huevo del suelo, y colócalo en tu inventario. +The End... Again...=El fin... de nuevo... +Respawn the Ender Dragon.=Vuelve a invocar al Enderdragón. +Sky's the Limit=El cielo es el límite +Find the elytra and prepare to fly above and beyond!=¿Encuentra los élitros y prepárate para volar al infinito y más allá! +Free the End=Libera el End +Kill the ender dragon. Good Luck!=Mata al Enderdragón. Buena suerte! +Bee Our Guest=Abelante, esta es tu casa +Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.=Usa una fogata y una botella para obtener miel de una colmena sin enojar a las abejas. +Total Beelocation=Abejémonos de aquí +Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.=Mueve una colmena que tenga 3 abejas usando una herramienta con toque de seda. +Wax On=Encerando ando +Apply honeycomb to a copper block to protect it from the elements.=Encera un bloque de cobre con un panal de abejas para protegerlo de los elementos. +Wax Off=Pulir cera +Scrape wax off of a copper block.=Quita la cera de un bloque de cobre +The End?=¿El End? +Or the beginning?@nHint: Enter an end portal.=¿O el principio?@nSugerencia: Entra al portal del End +Stone Age=La edad de piedra +Mine a stone with new pickaxe.=Mina piedra con tu nuevo pico. +Ice Bucket Challenge=Mente fría +Obtain an obsidian block.=Consigue un bloque de obsidiana. +Hot Stuff=¡La cosa está que arde! +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... +Tactical Fishing=Pesca táctica +Catch a fish... without a fishing rod!=Atrapa a un pez... ¡sin una caña de pescar! diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr index ae4941d2e..95800d5e9 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.fr.tr @@ -1,49 +1,113 @@ # textdomain:mcl_achievements -Aquire Hardware=Acquérir du matériel +Acquire Hardware=Acquérir du matériel Bake Bread=Faire du pain Benchmarking=Fabriquer Cow Tipper=Chevaucher une vache -Craft a bookshelf.=Fabriquez une Bibliothèque. +Craft a bookshelf.=Fabriquez une bibliothèque. Craft a cake using wheat, sugar, milk and an egg.=Fabriquez un gâteau avec du blé, du sucre, du lait et un œuf. Craft a crafting table from 4 wooden planks.=Fabriquez un établi à partir de 4 planches de bois. Craft a stone pickaxe using sticks and cobblestone.=Fabriquez une pioche en pierre à l'aide de bâtons et de pierre. Craft a wooden sword using wooden planks and sticks on a crafting table.=Fabriquez une épée en bois à l'aide de planches et de bâtons en bois sur un établi. -DIAMONDS!=DIAMANTS! -Delicious Fish=Délicieux Poisson +DIAMONDS!=DIAMANTS ! +Delicious Fish=Délicieux poisson Dispense With This=Dispenser de ça 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 augmentaton de niveau +Getting an Upgrade=Obtenir une augmentation de niveau 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 -Into the Nether=Dans le Nether +We Need to Go Deeper=Aller au fond des choses Iron Belly=Ventre de fer Librarian=Bibliothécaire -Mine emerald ore.=Mine de minerai d'émeraude. +Mine emerald ore.=Minez du minerai d'émeraude. On A Rail=Sur un rail Pick up a blaze rod from the floor.=Ramassez une tige de feu sur le sol. Pick up a diamond from the floor.=Ramassez un diamant sur le sol. -Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=Ramassez un objet en bois du sol.@nConseil: Frappez un tronc d'arbre jusqu'à ce qu'il ressorte comme un objet. -Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=Ramassez le cuir du sol.@nConseil: Les vaches et certains autres animaux ont une chance de laisser tomber le cuir lorsqu'ils sont tués. +Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=Ramassez un objet en bois au sol.@nAstuce : Frappez un tronc d'arbre jusqu'à ce qu'il ressorte comme un objet. +Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=Ramassez du cuir au sol.@nAstuce : Les vaches et certains autres animaux ont une chance de laisser tomber le cuir lorsqu'ils sont tués. Place a dispenser.=Placez un distributeur. Place a flower pot.=Placez un pot de fleurs. Pork Chop=Côtelette de porc Pot Planter=Jardinière en pot Rabbit Season=Saison du lapin Sniper Duel=Duel de sniper -Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=Prenez un poisson cuit d'un four.@nConseil: Utilisez une canne à pêche pour attraper un poisson et faites-le cuire dans un four. -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.=Prenez un lingot de fer dans la fente de sortie d'un four.@nConseil: Pour faire fondre un lingot de fer, mettez du combustible (comme du charbon) et du minerai de fer dans un four. +Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=Prenez un poisson cuit d'un four.@nAstuce : Utilisez une canne à pêche pour attraper un poisson et faites-le cuire dans un four. +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.=Prenez un lingot de fer dans la fente de sortie d'un four.@nAstuce : Pour faire fondre un lingot de fer, mettez du combustible (comme du charbon) et du minerai de fer dans un four. The Haggler=Le marchand The Lie=Le mensonge -Time to Farm!=C'est l'heure du fermier! -Time to Mine!=C'est l'heure de miner! -Time to Strike!=C'est l'heure de combattre! -Travel by minecart for at least 1000 meters from your starting point in a single ride.=Voyagez en wagonnet sur au moins 1000 mètres de votre point de départ en une seule fois. -Use 8 cobblestones to craft a furnace.=Utilise 8 pierres pour fabriquer un four. +Time to Farm!=C'est l'heure de cultiver ! +Time to Mine!=C'est l'heure de miner ! +Time to Strike!=C'est l'heure de combattre ! +Travel by minecart for at least 1000 meters from your starting point in a single ride.=Voyagez en wagonnet à au moins 1000 mètres de votre point de départ en une seule fois. +Use 8 cobblestones to craft a furnace.=Utilisez 8 pierres pour fabriquer un four. Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Utilisez un établi pour fabriquer une houe en bois à partir de planches et de bâtons en bois. Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Utilisez un établi pour fabriquer une pioche en bois à partir de planches et de bâtons en bois. Use obsidian and a fire starter to construct a Nether portal.=Utilisez de l'obsidienne et un briquet pour construire un portail du Nether. Use wheat to craft a bread.=Utilisez du blé pour fabriquer un pain. +Who is Cutting Onions?=Qui épluche des oignons ? +Pick up a crying obsidian from the floor.=Ramassez une obsidienne pleureuse sur le sol. +Hidden in the Depths=Caché dans les profondeurs +Pick up an Ancient Debris from the floor.=Ramassez un Ancien Débris par terre. +The Nether=Le Nether +Bring summer clothes.@nHint: Enter the Nether.=Apportez des vêtements d'été.@nAstuce : Entrez dans le Nether +Isn't It Iron Pick=Bonne Pioche ! +Craft a iron pickaxe using sticks and iron.=Fabriquez une pioche de fer avec des bâtons et du fer. +Postmortal=Aux frontières de la mort +Use a Totem of Undying to cheat death.=Utilisez un Totem d’immortalité pour tromper la mort. +Sweet Dreams=Bonne nuit les petits +Sleep in a bed to change your respawn point.=Dormez dans un lit pour changer votre point de réapparition. +Not Quite "Nine" Lives=Presque "neuf" vies +Charge a Respawn Anchor to the maximum.=Chargez une Ancre de Réapparition au maximum. +What A Deal!=Adjugé, Vendu ! +Successfully trade with a Villager.=Commercez avec succès avec un villageois. +Withering Heights=Les Witherables +Summon the wither from the dead.=Invoquez le Wither d'entre les morts. +The Cutest Predator=Le plus mignon des prédateurs +Catch an Axolotl with a bucket!=Attrapez un Axolotl avec un seau ! +Fishy Business=Merci pour le poisson +Catch a fish.@nHint: Catch a fish, salmon, clownfish, or pufferfish.=Attrapez un poisson.@nAstuce : attrapez un poisson, saumon, poisson-clown, ou poisson-globe. +Country Lode, Take Me Home=Petit Poucet +Use a compass on a Lodestone.=Utilisez une boussole sur une magnétite. +Serious Dedication=Sérieux dévouement +Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices.=Utilisez un lingot de Netherite pour améliorer une houe, puis réévaluez complètement vos choix de vie. +Local Brewery=Apprenti chimiste +Brew a Potion.@nHint: Take a potion or glass bottle out of the brewing stand.=Concoctez une potion.@nAstuce : Retirez une potion ou une bouteille d'eau d'un alambic. +Enchanter=Enchanté ! +Enchant an item using an Enchantment Table.=Enchantez un objet avec la table d'enchantement. +Bring Home the Beacon=Fais ta balise +Use a beacon.=Utilisez une balise. +Beaconator=Phare allumé +Use a fully powered beacon.=Utilisez une balise à pleine puissance. +The Next Generation=La nouvelle génération +Hold the Dragon Egg.@nHint: Pick up the egg from the ground and have it in your inventory.=Tenez l'oeuf de dragon.@nAstuce: Ramassez l’œuf sur le sol pour l'avoir dans votre inventaire. +The End... Again...=Un air de déjà vu... +Respawn the Ender Dragon.=Faites réapparaître l'Ender Dragon. +Sky's the Limit=Vers l'infini et au-delà +Find the elytra and prepare to fly above and beyond!=Trouvez des élytres et préparez vous à vous envoler ! +Free the End=Libérez l'End +Kill the ender dragon. Good Luck!=Tuez l'Ender Dragon. Bonne chance ! +Bee Our Guest=J'irai butinez chez vous +Use a campfire to collect a bottle of honey from a beehive without aggrivating the bees inside.=Utilisez un feu de camp pour remplir une bouteille de miel sans provoquez les abeilles. +Total Beelocation=Dé-miel-nagement +Move a bee nest, with 3 bees inside, using a silk touch enchanted tool.=Déplacez une ruche, avec 3 abeilles à l'intérieur en utilisant un outil enchanté avec toucher de soie. +Wax On=Lustrer +Apply honeycomb to a copper block to protect it from the elements.=Étalez de la cire sur un bloc de cuivre pour le protéger des éléments. +Wax Off=Frotter +Scrape wax off of a copper block.=Retirer la cire d'un bloc de cuivre. +The End?=Fin ? +Or the beginning?@nHint: Enter an end portal.=Ou le commencement ?@nAstuce : Entrer dans un portail de l'End. +Stone Age=L'âge de pierre +Mine a stone with new pickaxe.=Minez de la roche avec votre pioche. +Ice Bucket Challenge=Ice Bucket Challenge +Obtain an obsidian block.=Obtenez un bloc d'obsidienne. +Hot Stuff=Chaud devant ! +Put lava in a bucket.=Remplir un seau de lave. +Hero of the Village=Héros du village +Successfully defend a village from a raid=Protégez le village d'un raid +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 ! diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr new file mode 100644 index 000000000..bd86186e7 --- /dev/null +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.ja.tr @@ -0,0 +1,99 @@ +# 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.=作業台で木製の剣を作ろう。 材料:木の棒、木材 +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.=20m以上の距離から弓矢を当てよう。 対象:スケルトン、ウィザースケルトン、ストレイ等 +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.=植木鉢を置こう。 +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.=一回のトロッコ乗車で、1000m以上を走り抜けよう。 +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.=銅ブロックから錆止めを削り落とそう。 diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.pl.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.pl.tr new file mode 100644 index 000000000..ccb21a06f --- /dev/null +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.pl.tr @@ -0,0 +1,50 @@ +# textdomain:mcl_achievements +Acquire Hardware=Zdobądź narzędzie +Bake Bread=Upiecz chleb +Benchmarking=Rzemieślnictwo +Cow Tipper=Raz krowie śmierć +Craft a bookshelf.=Wytwórz półkę z książkami. +Craft a cake using wheat, sugar, milk and an egg.=Wytwórz ciasto z pszenicy, cukru, mleka i jajka. +Craft a crafting table from 4 wooden planks.=Wytwórz stół rzemieślniczy z 4 desek. +Craft a stone pickaxe using sticks and cobblestone.=Wytwórz kamienny kilof korzystając z patyków i brukowca. +Craft a wooden sword using wooden planks and sticks on a crafting table.=Wytwórz drewniany miecz korzystając z desek i patyków na stole rzemieślniczym. +DIAMONDS!=DIAMENTY! +Delicious Fish=Pyszna ryba +Dispense With This=Dozuj to +Eat a cooked porkchop.=Zjedz upieczony kotlet. +Eat a cooked rabbit.=Zjedz pieczonego królika. +Get really desperate and eat rotten flesh.=Bądź zdesperowany i zjedz zgniłe mięso. +Getting Wood=Zbieranie drewna +Getting an Upgrade=Ulepszenie +Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.=Traf szkieleta, witherowego szkieleta lub tułacza strzałą z łuku z odległości co najmniej 20 metrów. +Hot Topic=Gorący temat +Into Fire=W ogień +Into the Nether=W Nether +Iron Belly=Żelazny żołądek +Librarian=Bibliotekarz +Mine emerald ore.=Wykop rudę szmaragdu. +On A Rail=Na torach +Pick up a blaze rod from the floor.=Podnieś płomienną różdżkę z podłogi. +Pick up a diamond from the floor.=Ponieś diament z podłogi. +Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out as an item.=Podnieś drewniany przedmiot z ziemi.@nPodpowiedź: Uderzaj pień drzewa dopóki nie wyleci jako przedmiot. +Pick up leather from the floor.@nHint: Cows and some other animals have a chance to drop leather, when killed.=Podnieś skórkę z ziemi.@nPodpowiedź: Krowy i inne zwierzęta mają szansę upuścić skórę gdy zostaną zabite. +Place a dispenser.=Postaw dozownik. +Place a flower pot.=Postaw doniczkę. +Pork Chop=Kotlet +Pot Planter=Ogrodnik +Rabbit Season=Sezon na króliki +Sniper Duel=Pojedynek snajperów +Take a cooked fish from a furnace.@nHint: Use a fishing rod to catch a fish and cook it in a furnace.=Weź upieczoną rybę z pieca.@nPodpowiedź: Użyj wędki aby złapać rybę i upiecz ją w piecu. +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.=Weź sztabkę żelaza z wyjściowego miejsca pieca.@nPodpowiedź: Aby wytopić sztabkę żelaza, umieść paliwo (np. węgiel) w piecu. +The Haggler=Handlarz +The Lie=Kłamstwo +Time to Farm!=Czas na rolnictwo! +Time to Mine!=Czas na kopanie! +Time to Strike!=Czas na atak! +Travel by minecart for at least 1000 meters from your starting point in a single ride.=Przejedź przez przynajmniej 1000 metrów od punktu startowego pojedynczą przejażdżką. +Use 8 cobblestones to craft a furnace.=Użyj 8 brukowców by wytworzyć piec. +Use a crafting table to craft a wooden hoe from wooden planks and sticks.=Użyj stołu rzemieślniczego aby wytworzyć drewnianą motykę z desek i patyków. +Use a crafting table to craft a wooden pickaxe from wooden planks and sticks.=Użyj stołu rzemieślniczego aby wytworzyć drewniany kilof z desek i patyków. +Use obsidian and a fire starter to construct a Nether portal.=Użyj obsydianu i źródła ognia aby skonstruować portal do Netheru. +Use wheat to craft a bread.=Użyj pszenicy by wytworzyć chleb. + diff --git a/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr b/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr index 0db2ae99d..9a180d89b 100644 --- a/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr +++ b/mods/HUD/mcl_achievements/locale/mcl_achievements.ru.tr @@ -1,9 +1,9 @@ # textdomain:mcl_achievements -Aquire Hardware=Куй Железо +Acquire Hardware=Куй Железо Bake Bread=Хлеб всему голова Benchmarking=Верстак Cow Tipper=Кожа да кости -Craft a bookshelf.=Создание книжной полки +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.=Создание каменного топора из палок и булыжников. @@ -15,12 +15,12 @@ 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=В Огне -Into the Nether=В Аду -Iron Belly=Железный Живот +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=На Рельсах @@ -30,20 +30,84 @@ Pick up a wood item from the ground.@nHint: Punch a tree trunk until it pops out 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=Снайперская Дуэль +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 Haggler=Торговец The Lie=Тортик -Time to Farm!=Время фермерства! +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 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 diff --git a/mods/HUD/mcl_achievements/locale/template.txt b/mods/HUD/mcl_achievements/locale/template.txt index ecdba2672..d865b1668 100644 --- a/mods/HUD/mcl_achievements/locale/template.txt +++ b/mods/HUD/mcl_achievements/locale/template.txt @@ -1,5 +1,5 @@ # textdomain:mcl_achievements -Aquire Hardware= +Acquire Hardware= Bake Bread= Benchmarking= Cow Tipper= @@ -19,7 +19,7 @@ Getting an Upgrade= Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters.= Hot Topic= Into Fire= -Into the Nether= +We Need to Go Deeper= Iron Belly= Librarian= Mine emerald ore.= @@ -47,3 +47,67 @@ 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.= +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!= diff --git a/mods/HUD/mcl_achievements/mod.conf b/mods/HUD/mcl_achievements/mod.conf index b9d5af185..ed11618d7 100644 --- a/mods/HUD/mcl_achievements/mod.conf +++ b/mods/HUD/mcl_achievements/mod.conf @@ -1 +1,4 @@ name = mcl_achievements +author = Wuzzy +description = Adds MCL2 Archivements +depends = awards diff --git a/mods/HUD/mcl_achievements/textures/mcl_achievements_button.png b/mods/HUD/mcl_achievements/textures/mcl_achievements_button.png deleted file mode 100644 index cef7e59cc..000000000 Binary files a/mods/HUD/mcl_achievements/textures/mcl_achievements_button.png and /dev/null differ diff --git a/mods/HUD/mcl_base_textures/description.txt b/mods/HUD/mcl_base_textures/description.txt deleted file mode 100644 index bfd0d06bb..000000000 --- a/mods/HUD/mcl_base_textures/description.txt +++ /dev/null @@ -1 +0,0 @@ -Provides core textures needed by Minetest. diff --git a/mods/HUD/mcl_base_textures/mod.conf b/mods/HUD/mcl_base_textures/mod.conf index 492aeca87..b36dccfe4 100644 --- a/mods/HUD/mcl_base_textures/mod.conf +++ b/mods/HUD/mcl_base_textures/mod.conf @@ -1 +1,3 @@ name = mcl_base_textures +author = Wuzzy +description = Provides core textures needed by Minetest. diff --git a/mods/HUD/mcl_base_textures/textures/bubble.png b/mods/HUD/mcl_base_textures/textures/bubble.png deleted file mode 100644 index f1d714fec..000000000 Binary files a/mods/HUD/mcl_base_textures/textures/bubble.png and /dev/null differ diff --git a/mods/HUD/mcl_base_textures/textures/crack_anylength.png b/mods/HUD/mcl_base_textures/textures/crack_anylength.png deleted file mode 100644 index 7fe8721d9..000000000 Binary files a/mods/HUD/mcl_base_textures/textures/crack_anylength.png and /dev/null differ diff --git a/mods/HUD/mcl_base_textures/textures/crosshair.png b/mods/HUD/mcl_base_textures/textures/crosshair.png deleted file mode 100644 index 8e94dcc6b..000000000 Binary files a/mods/HUD/mcl_base_textures/textures/crosshair.png and /dev/null differ diff --git a/mods/HUD/mcl_base_textures/textures/heart.png b/mods/HUD/mcl_base_textures/textures/heart.png deleted file mode 100644 index d0e304100..000000000 Binary files a/mods/HUD/mcl_base_textures/textures/heart.png and /dev/null differ diff --git a/mods/HUD/mcl_base_textures/textures/object_crosshair.png b/mods/HUD/mcl_base_textures/textures/object_crosshair.png deleted file mode 100644 index e5a400e95..000000000 Binary files a/mods/HUD/mcl_base_textures/textures/object_crosshair.png and /dev/null differ diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua new file mode 100644 index 000000000..1ff981456 --- /dev/null +++ b/mods/HUD/mcl_bossbars/init.lua @@ -0,0 +1,199 @@ +mcl_bossbars = { + bars = {}, + huds = {}, + static = {}, + colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"}, + max_bars = tonumber(minetest.settings:get("max_bossbars")) or 4 +} + +function mcl_bossbars.recalculate_colors() + local sorted = {} + local colors = mcl_bossbars.colors + local color_count = #colors + local frame_count = color_count * 2 + for i, color in ipairs(colors) do + local idx = i * 2 - 1 + local image = "(mcl_bossbars.png" + .. "^[transformR270" + .. "^[verticalframe:" .. frame_count .. ":" .. (idx - 1) + .. "^(mcl_bossbars_empty.png" + .. "^[lowpart:%d:mcl_bossbars.png" + .. "^[transformR270" + .. "^[verticalframe:" .. frame_count .. ":" .. idx .. "))^[resize:1456x40" + local _, hex = mcl_util.get_color(color) + sorted[color] = { + image = image, + hex = hex, + } + end + mcl_bossbars.colors_sorted = sorted +end + +local function get_color_info(color, percentage) + local cdef = mcl_bossbars.colors_sorted[color] + return cdef.hex, string.format(cdef.image, percentage) +end + +local last_id = 0 + +function mcl_bossbars.add_bar(player, def, dynamic, priority) + local name = player:get_player_name() + local bars = mcl_bossbars.bars[name] + local bar = {text = def.text, priority = priority or 0, timeout = def.timeout} + bar.color, bar.image = get_color_info(def.color, def.percentage) + if dynamic then + for _, other in pairs(bars) do + if not other.id and other.color == bar.color and (other.original_text or other.text) == bar.text and other.image == bar.image then + if not other.count then + other.count = 1 + other.original_text = other.text + end + other.count = other.count + 1 + other.text = other.original_text .. " x" .. other.count + return + end + end + end + table.insert(bars, bar) + if not dynamic then + bar.raw_color = def.color + bar.id = last_id + 1 + last_id = bar.id + mcl_bossbars.static[bar.id] = bar + return bar.id + end +end + +function mcl_bossbars.remove_bar(id) + mcl_bossbars.static[id].id = nil + mcl_bossbars.static[id] = nil +end + +function mcl_bossbars.update_bar(id, def, priority) + local old = mcl_bossbars.static[id] + old.color = get_color_info(def.color or old.raw_color, def.percentage or old.percentage) + old.text = def.text or old.text + old.priority = priority or old.priority +end + +function mcl_bossbars.update_boss(object, name, color) + local props = object:get_luaentity() + if not props or not props.is_mob then + props = object:get_properties() + props.health = object:get_hp() + end + + local bardef = { + color = color, + text = props.nametag, + percentage = math.floor(props.health / props.hp_max * 100), + } + + if not bardef.text or bardef.text == "" then + bardef.text = name + end + + local pos = 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 +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + mcl_bossbars.huds[name] = {} + mcl_bossbars.bars[name] = {} +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + mcl_bossbars.huds[name] = nil + for _, bar in pairs(mcl_bossbars.bars[name]) do + if bar.id then + mcl_bossbars.static[bar.id] = nil + end + end + mcl_bossbars.bars[name] = nil +end) + +minetest.register_globalstep(function(dtime) + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local bars = mcl_bossbars.bars[name] + local huds = mcl_bossbars.huds[name] + table.sort(bars, function(a, b) return a.priority < b.priority end) + local huds_new = {} + local bars_new = {} + local i = 0 + + while #huds > 0 or #bars > 0 do + local bar = table.remove(bars, 1) + local hud = table.remove(huds, 1) + + if bar and bar.id then + if bar.timeout then + bar.timeout = bar.timeout - dtime + end + if not bar.timeout or bar.timeout > 0 then + table.insert(bars_new, bar) + end + end + + if bar and not hud then + if i < mcl_bossbars.max_bars then + hud = { + color = bar.color, + image = bar.image, + text = bar.text, + text_id = player:hud_add({ + hud_elem_type = "text", + text = bar.text, + number = bar.color, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40}, + }), + image_id = player:hud_add({ + hud_elem_type = "image", + text = bar.image, + position = {x = 0.5, y = 0}, + alignment = {x = 0, y = 1}, + offset = {x = 0, y = i * 40 + 25}, + scale = {x = 0.375, y = 0.375}, + }), + } + end + elseif hud and not bar then + player:hud_remove(hud.text_id) + player:hud_remove(hud.image_id) + hud = nil + else + if bar.text ~= hud.text then + player:hud_change(hud.text_id, "text", bar.text) + hud.text = bar.text + end + + if bar.color ~= hud.color then + player:hud_change(hud.text_id, "number", bar.color) + hud.color = bar.color + end + + if bar.image ~= hud.image then + player:hud_change(hud.image_id, "text", bar.image) + hud.image = bar.image + end + end + + table.insert(huds_new, hud) + i = i + 1 + end + + mcl_bossbars.huds[name] = huds_new + mcl_bossbars.bars[name] = bars_new + end +end) + +mcl_bossbars.recalculate_colors() diff --git a/mods/HUD/mcl_bossbars/mod.conf b/mods/HUD/mcl_bossbars/mod.conf new file mode 100644 index 000000000..64cbd4c9f --- /dev/null +++ b/mods/HUD/mcl_bossbars/mod.conf @@ -0,0 +1,4 @@ +name = mcl_bossbars +author = Fleckenstein +description = Show enderdragon & wither boss bars. Also allows custom bars. +depends = mcl_util, mcl_colors diff --git a/mods/HUD/mcl_credits/init.lua b/mods/HUD/mcl_credits/init.lua new file mode 100644 index 000000000..db3ac8436 --- /dev/null +++ b/mods/HUD/mcl_credits/init.lua @@ -0,0 +1,149 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +mcl_credits = { + players = {}, + description = S("A faithful Open Source clone of Minecraft"), + people = dofile(minetest.get_modpath(modname) .. "/people.lua"), +} + +local function add_hud_element(def, huds, y) + def.alignment = {x = 0, y = 0} + def.position = {x = 0.5, y = 0} + def.offset = {x = 0, y = y} + def.z_index = 1001 + local id = huds.player:hud_add(def) + table.insert(huds.ids, id) + huds.moving[id] = y + return id +end + +function mcl_credits.show(player) + local name = player:get_player_name() + if mcl_credits.players[name] then + return + end + local huds = { + new = true, -- workaround for MT < 5.5 (sending hud_add and hud_remove in the same tick) + player = player, + moving = {}, + ids = { + player:hud_add({ + hud_elem_type = "image", + text = "credits_bg.png", + position = {x = 0, y = 0}, + alignment = {x = 1, y = 1}, + scale = {x = -100, y = -100}, + z_index = 1000, + }), + player:hud_add({ + hud_elem_type = "text", + text = S("Sneak to skip"), + position = {x = 1, y = 1}, + alignment = {x = -1, y = -1}, + offset = {x = -5, y = -5}, + z_index = 1001, + number = 0xFFFFFF, + }), + player:hud_add({ + hud_elem_type = "text", + text = " "..S("Jump to speed up (additionally sprint)"), + position = {x = 0, y = 1}, + alignment = {x = 1, y = -1}, + offset = {x = -5, y = -5}, + z_index = 1002, + number = 0xFFFFFF, + }), + }, + } + add_hud_element({ + hud_elem_type = "image", + text = "mineclone2_logo.png", + scale = {x = 1, y = 1}, + }, huds, 300, 0) + add_hud_element({ + hud_elem_type = "text", + text = mcl_credits.description, + number = 0x757575, + scale = {x = 5, y = 5}, + }, huds, 350, 0) + local y = 450 + for _, group in ipairs(mcl_credits.people) do + add_hud_element({ + hud_elem_type = "text", + text = group[1], + number = group[2], + scale = {x = 3, y = 3}, + }, huds, y, 0) + y = y + 25 + for _, name in ipairs(group[3]) do + y = y + 25 + add_hud_element({ + hud_elem_type = "text", + text = name, + number = 0xFFFFFF, + scale = {x = 1, y = 1}, + }, huds, y, 0) + end + y = y + 200 + end + huds.icon = add_hud_element({ + hud_elem_type = "image", + text = "mineclone2_icon.png", + scale = {x = 1, y = 1}, + }, huds, y) + mcl_credits.players[name] = huds +end + +function mcl_credits.hide(player) + local name = player:get_player_name() + local huds = mcl_credits.players[name] + if huds then + for _, id in pairs(huds.ids) do + player:hud_remove(id) + end + end + mcl_credits.players[name] = nil +end + +minetest.register_on_leaveplayer(function(player) + mcl_credits.players[player:get_player_name()] = nil +end) + +minetest.register_globalstep(function(dtime) + for _, huds in pairs(mcl_credits.players) do + local player = huds.player + local control = player:get_player_control() + if not huds.new and control.sneak then + mcl_credits.hide(player) + else + local moving = {} + local any + for id, y in pairs(huds.moving) do + y = y - 1 + + if control.jump then + y = y - 2 + if control.aux1 then + y = y - 5 + end + end + + if y > -100 then + if id == huds.icon then + y = math.max(400, y) + else + any = true + end + player:hud_change(id, "offset", {x = 0, y = y}) + moving[id] = y + end + end + if not any then + mcl_credits.hide(player) + end + huds.moving = moving + end + huds.new = false + end +end) diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.de.tr b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr new file mode 100644 index 000000000..fa26f5bc4 --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.de.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models=3D Modelle +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 +Developers=Entwickler +Jump to speed up (additionally sprint)=Springen, um zu beschleunigen (zusätzlich sprinten) +Maintainers=Betreuer +MineClone5=MineClone5 +Original Mod Authors=Original-Mod-Autoren +Sneak to skip=Schleichen zum Überspringen +Textures=Texturen +Translations=Übersetzungen diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.es.tr b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.es.tr @@ -0,0 +1,14 @@ +# 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 diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr new file mode 100644 index 000000000..b34249eff --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.fr.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models=Modèles 3D +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 +Developers=Développeurs +Jump to speed up (additionally sprint)=Saut pour accélérer (peut être combiné avec sprint) +Maintainers=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 diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr new file mode 100644 index 000000000..e7bbbbfc2 --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_credits +3D Models=3Dモデル +A faithful Open Source clone of Minecraft=オープンソースによるマインクラフトの忠実なクローン +Contributors=投稿者 +Creator of MineClone=MineClone の創始者 +Creator of MineClone2=MineClone2 の創始者 +Developers=開発者 +Jump to speed up (additionally sprint)=ジャンプでスピードアップ(追加で疾走) +Maintainers=メンテナンス +MineClone5=MineClone5 +Original Mod Authors=オリジナルMODの作者 +Sneak to skip=スニークでスキップ +Textures=テクスチャ +Translations=翻訳 diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.pl.tr @@ -0,0 +1,14 @@ +# 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 diff --git a/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr new file mode 100644 index 000000000..a8886286e --- /dev/null +++ b/mods/HUD/mcl_credits/locale/mcl_credits.ru.tr @@ -0,0 +1,14 @@ +# 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 diff --git a/mods/HUD/mcl_credits/locale/template.txt b/mods/HUD/mcl_credits/locale/template.txt new file mode 100644 index 000000000..3ee9fa56c --- /dev/null +++ b/mods/HUD/mcl_credits/locale/template.txt @@ -0,0 +1,14 @@ +# 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= diff --git a/mods/HUD/mcl_credits/mod.conf b/mods/HUD/mcl_credits/mod.conf new file mode 100644 index 000000000..3df6370af --- /dev/null +++ b/mods/HUD/mcl_credits/mod.conf @@ -0,0 +1,3 @@ +name = mcl_credits +author = Fleckenstein +description = Show a HUD containing the credits diff --git a/mods/HUD/mcl_credits/people.lua b/mods/HUD/mcl_credits/people.lua new file mode 100644 index 000000000..a1aca670a --- /dev/null +++ b/mods/HUD/mcl_credits/people.lua @@ -0,0 +1,214 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +return { + {S("Creator of MineClone"), 0x0A9400, { + "davedevils", + }}, + {S("Creator of MineClone2"), 0xFBF837, { + "Wuzzy", + }}, + {S("Maintainers"), 0xFF51D5, { + "AncientMariner", + "Nicu", + }}, + {S("Previous Maintainers"), 0xFFFFFF, { + "Fleckenstein", + "cora", + }}, + {S("Developers"), 0xF84355, { + "AFCMS", + "epCode", + "chmodsayshello", + "PrairieWind", + "MrRar", + "FossFanatic ", + "SmokeyDope", + }}, + {S("Past Developers"), 0xF84355, { + "jordan4ibanez", + "iliekprogrammar", + "kabou", + "Faerraven / Michieal", + "MysticTempest", + "NO11", + "SumianVoice", + }}, + {S("Contributors"), 0x52FF00, { + "RandomLegoBrick", + "rudzik8", + "Code-Sploit", + "aligator", + "Rootyjr", + "ryvnf", + "bzoss", + "talamh", + "Laurent Rocher", + "HimbeerserverDE", + "TechDudie", + "Alexander Minges", + "ArTee3", + "ZeDique la Ruleta", + "pitchum", + "wuniversales", + "Bu-Gee", + "David McMackins II", + "Nicholas Niro", + "Wouters Dorian", + "Blue Blancmange", + "Jared Moody", + "Li0n", + "Midgard", + "Saku Laesvuori", + "Yukitty", + "ZedekThePD", + "aldum", + "dBeans", + "nickolas360", + "yutyo", + "Tianyang Zhang", + "j45", + "Marcin Serwin", + "erlehmann", + "E", + "n_to", + "kay27", + "debiankaios", + "Gustavo6046 / wallabra", + "CableGuy67", + "Benjamin Schötz", + "Doloment", + "Sydney Gems", + "Emily2255", + "Emojigit", + "FinishedFragment", + "sfan5", + "Blue Blancmange", + "Jared Moody", + "SmallJoker", + "Sven792", + "aldum", + "Dieter44", + "Pepebotella", + "Lazerbeak12345", + "mrminer", + "Thunder1035", + "opfromthestart", + "snowyu", + "FaceDeer", + "Herbert West", + "GuyLiner", + "3raven", + "anarquimico", + "TheOnlyJoeEnderman", + "Ranko Saotome", + "Gregor Parzefall", + "Wbjitscool", + "b3nderman", + "CyberMango", + "gldrk", + "atomdmac", + "emptyshore", + "FlamingRCCars", + "uqers", + "Niterux", + "appgurueu", + }}, + {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)", + "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, { + "Wuzzy", + "Fleckenstein", + "BlockMen", + "TenPlus1", + "PilzAdam", + "ryvnf", + "stujones11", + "Arcelmi", + "celeron55", + "maikerumine", + "GunshipPenguin", + "Qwertymine3", + "Rochambeau", + "rubenwardy", + "stu", + "4aiman", + "Kahrl", + "Krock", + "UgnilJoZ", + "lordfingle", + "22i", + "bzoss", + "kilbith", + "xeranas", + "kddekadenz", + "sofar", + "4Evergreen4", + "jordan4ibanez", + "paramat", + "debian044 / debian44", + "chmodsayshello", + "cora", + "Faerraven / Michieal", + "PrairieWind", + }}, + {S("3D Models"), 0x0019FF, { + "22i", + "tobyplowy", + "epCode", + "Faerraven / Michieal", + "SumianVoice", + }}, + {S("Textures"), 0xFF9705, { + "XSSheep", + "Wuzzy", + "kingoscargames", + "leorockway", + "xMrVizzy", + "yutyo", + "NO11", + "kay27", + "MysticTempest", + "RandomLegoBrick", + "cora", + "Faerraven / Michieal", + "Nicu", + "Exhale", + "Wbjitscool", + "SmokeyDope", + }}, + {S("Translations"), 0x00FF60, { + "Wuzzy", + "Rocher Laurent", + "wuniversales", + "kay27", + "pitchum", + "todoporlalibertad", + "Marcin Serwin", + "Pepebotella", + "Emojigit", + "snowyu", + "3raven", + "SakuraRiu", + "anarquimico", + "syl", + "Temak", + "megustanlosfrijoles", + "kbundg", + }}, + {S("Funders"), 0xF7FF00, { + "40W", + "bauknecht", + "Cora", + }}, + {S("Special thanks"), 0x00E9FF, { + "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", + }}, +} diff --git a/mods/HUD/mcl_death_messages/description.txt b/mods/HUD/mcl_death_messages/description.txt deleted file mode 100644 index 7c322f644..000000000 --- a/mods/HUD/mcl_death_messages/description.txt +++ /dev/null @@ -1 +0,0 @@ -Shows messages in chat when a player dies. diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index dfc5191a6..6c2040545 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,281 +1,252 @@ -local S = minetest.get_translator("mcl_death_messages") -local N = function(s) return s end - -mcl_death_messages = {} - --- Death messages -local msgs = { - ["arrow"] = { - N("@1 was fatally hit by an arrow."), - N("@1 has been killed by an arrow."), - }, - ["arrow_name"] = { - N("@1 was shot by an arrow from @2."), - }, - ["arrow_skeleton"] = { - N("@1 was shot by an arrow from a skeleton."), - }, - ["arrow_stray"] = { - N("@1 was shot by an arrow from a stray."), - }, - ["arrow_illusioner"] = { - N("@1 was shot by an arrow from an illusioner."), - }, - ["arrow_mob"] = { - N("@1 was shot by an arrow."), - }, - ["drown"] = { - N("@1 forgot to breathe."), - N("@1 drowned."), - N("@1 ran out of oxygen."), - }, - ["murder"] = { - N("@1 was killed by @2."), - }, - ["murder_any"] = { - N("@1 was killed."), - }, - ["mob_kill"] = { - N("@1 was killed by a mob."), - }, - ["blaze_fireball"] = { - N("@1 was burned to death by a blaze's fireball."), - N("@1 was killed by a fireball from a blaze."), - }, - ["fire_charge"] = { - N("@1 was burned by a fire charge."), - }, - ["ghast_fireball"] = { - N("A ghast scared @1 to death."), - N("@1 has been fireballed by a ghast."), - }, - ["fall"] = { - N("@1 fell from a high cliff."), - N("@1 took fatal fall damage."), - N("@1 fell victim to gravity."), - }, - ["other"] = { - N("@1 died."), - } -} - -local mobkills = { - ["mobs_mc:zombie"] = N("@1 was killed by a zombie."), - ["mobs_mc:baby_zombie"] = N("@1 was killed by a baby zombie."), - ["mobs_mc:blaze"] = N("@1 was killed by a blaze."), - ["mobs_mc:slime"] = N("@1 was killed by a slime."), - ["mobs_mc:witch"] = N("@1 was killed by a witch."), - ["mobs_mc:magma_cube_tiny"] = N("@1 was killed by a magma cube."), - ["mobs_mc:magma_cube_small"] = N("@1 was killed by a magma cube."), - ["mobs_mc:magma_cube_big"] = N("@1 was killed by a magma cube."), - ["mobs_mc:wolf"] = N("@1 was killed by a wolf."), - ["mobs_mc:cat"] = N("@1 was killed by a cat."), - ["mobs_mc:ocelot"] = N("@1 was killed by an ocelot."), - ["mobs_mc:enderdragon"] = N("@1 was killed by an ender dragon."), - ["mobs_mc:wither"] = N("@1 was killed by a wither."), - ["mobs_mc:enderman"] = N("@1 was killed by an enderman."), - ["mobs_mc:endermite"] = N("@1 was killed by an endermite."), - ["mobs_mc:ghast"] = N("@1 was killed by a ghast."), - ["mobs_mc:guardian_elder"] = N("@1 was killed by an elder guardian."), - ["mobs_mc:guardian"] = N("@1 was killed by a guardian."), - ["mobs_mc:iron_golem"] = N("@1 was killed by an iron golem."), - ["mobs_mc:polar_bear"] = N("@1 was killed by a polar_bear."), - ["mobs_mc:killer_bunny"] = N("@1 was killed by a killer bunny."), - ["mobs_mc:shulker"] = N("@1 was killed by a shulker."), - ["mobs_mc:silverfish"] = N("@1 was killed by a silverfish."), - ["mobs_mc:skeleton"] = N("@1 was killed by a skeleton."), - ["mobs_mc:stray"] = N("@1 was killed by a stray."), - ["mobs_mc:slime_tiny"] = N("@1 was killed by a slime."), - ["mobs_mc:slime_small"] = N("@1 was killed by a slime."), - ["mobs_mc:slime_big"] = N("@1 was killed by a slime."), - ["mobs_mc:spider"] = N("@1 was killed by a spider."), - ["mobs_mc:cave_spider"] = N("@1 was killed by a cave spider."), - ["mobs_mc:vex"] = N("@1 was killed by a vex."), - ["mobs_mc:evoker"] = N("@1 was killed by an evoker."), - ["mobs_mc:illusioner"] = N("@1 was killed by an illusioner."), - ["mobs_mc:vindicator"] = N("@1 was killed by a vindicator."), - ["mobs_mc:villager_zombie"] = N("@1 was killed by a zombie villager."), - ["mobs_mc:husk"] = N("@1 was killed by a husk."), - ["mobs_mc:baby_husk"] = N("@1 was killed by a baby husk."), - ["mobs_mc:pigman"] = N("@1 was killed by a zombie pigman."), - ["mobs_mc:baby_pigman"] = N("@1 was killed by a baby zombie pigman."), -} - --- Select death message -local dmsg = function(mtype, ...) - local r = math.random(1, #msgs[mtype]) - return S(msgs[mtype][r], ...) -end - --- Select death message for death by mob -local mmsg = function(mtype, ...) - if mobkills[mtype] then - return S(mobkills[mtype], ...) - else - return dmsg("mob_kill", ...) - end -end - -local last_damages = { } - -minetest.register_on_dieplayer(function(player, reason) - -- Death message - local message = minetest.settings:get_bool("mcl_showDeathMessages") - if message == nil then - message = true - end - if message then - local name = player:get_player_name() - if not name then - return - end - local msg - if last_damages[name] then - -- custom message - msg = last_damages[name].message - elseif reason.type == "node_damage" then - local pos = player:get_pos() - -- Check multiple nodes because players occupy multiple nodes - -- (we add one additional node because the check may fail if the player was - -- just barely touching the node with the head) - local posses = { pos, {x=pos.x,y=pos.y+1,z=pos.z}, {x=pos.x,y=pos.y+2,z=pos.z}} - local highest_damage = 0 - local highest_damage_def = nil - -- Show message for node that dealt the most damage - for p=1, #posses do - local def = minetest.registered_nodes[minetest.get_node(posses[p]).name] - local dmg = def.damage_per_second - if dmg and dmg > highest_damage then - highest_damage = dmg - highest_damage_def = def - end - end - if highest_damage_def and highest_damage_def._mcl_node_death_message then - local field = highest_damage_def._mcl_node_death_message - local field_msg - if type(field) == "table" then - field_msg = field[math.random(1, #field)] - else - field_msg = field - end - local textdomain - if highest_damage_def.mod_origin then - textdomain = highest_damage_def.mod_origin - else - textdomain = "mcl_death_messages" - end - -- We assume the textdomain of the death message in the node definition - -- equals the modname. - msg = minetest.translate(textdomain, field_msg, name) - end - elseif reason.type == "drown" then - msg = dmsg("drown", name) - elseif reason.type == "punch" then - -- Punches - local hitter = reason.object - local hittername, hittertype, hittersubtype, shooter - -- Custom message - if last_damages[name] then - msg = last_damages[name].message - -- Unknown hitter - elseif hitter == nil then - msg = dmsg("murder_any", name) - -- Player - elseif hitter:is_player() then - hittername = hitter:get_player_name() - if hittername ~= nil then - msg = dmsg("murder", name, hittername) - else - msg = dmsg("murder_any", name) - end - -- Mob (according to Common Mob Interface) - elseif hitter:get_luaentity()._cmi_is_mob then - if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then - hittername = hitter:get_luaentity().nametag - end - hittersubtype = hitter:get_luaentity().name - if hittername then - msg = dmsg("murder", name, hittername) - elseif hittersubtype ~= nil and hittersubtype ~= "" then - msg = mmsg(hittersubtype, name) - else - msg = dmsg("murder_any", name) - end - -- Arrow - elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" then - local shooter - if hitter:get_luaentity()._shooter then - shooter = hitter:get_luaentity()._shooter - end - local is_mob = false - local s_ent = shooter and shooter:get_luaentity() - if shooter == nil then - msg = dmsg("arrow", name) - elseif shooter:is_player() then - msg = dmsg("arrow_name", name, shooter:get_player_name()) - elseif s_ent and s_ent._cmi_is_mob then - if s_ent.nametag ~= "" then - msg = dmsg("arrow_name", name, shooter:get_player_name()) - elseif s_ent.name == "mobs_mc:skeleton" then - msg = dmsg("arrow_skeleton", name) - elseif s_ent.name == "mobs_mc:stray" then - msg = dmsg("arrow_stray", name) - elseif s_ent.name == "mobs_mc:illusioner" then - msg = dmsg("arrow_illusioner", name) - else - msg = dmsg("arrow_mob", name) - end - else - msg = dmsg("arrow", name) - end - -- Blaze fireball - elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then - if hitter:get_luaentity()._shot_from_dispenser then - msg = dmsg("fire_charge", name) - else - msg = dmsg("blaze_fireball", name) - end - -- Ghast fireball - elseif hitter:get_luaentity().name == "mobs_monster:fireball" then - msg = dmsg("ghast_fireball", name) - end - -- Falling - elseif reason.type == "fall" then - msg = dmsg("fall", name) - -- Other - elseif reason.type == "set_hp" then - if last_damages[name] then - msg = last_damages[name].message - end - end - if not msg then - msg = dmsg("other", name) - end - minetest.chat_send_all(msg) - last_damages[name] = nil - end -end) - --- dmg_sequence_number is used to discard old damage events -local dmg_sequence_number = 0 -local start_damage_reset_countdown = function (player, sequence_number) - minetest.after(1, function(playername, sequence_number) - if last_damages[playername] and last_damages[playername].sequence_number == sequence_number then - last_damages[playername] = nil - end - end, player:get_player_name(), sequence_number) -end - --- Send a custom death mesage when damaging a player via set_hp or punch. --- To be called directly BEFORE damaging a player via set_hp or punch. --- The next time the player dies due to a set_hp, the message will be shown. --- The player must die via set_hp within 0.1 seconds, otherwise the message will be discarded. -function mcl_death_messages.player_damage(player, message) - last_damages[player:get_player_name()] = { message = message, sequence_number = dmg_sequence_number } - start_damage_reset_countdown(player, dmg_sequence_number) - dmg_sequence_number = dmg_sequence_number + 1 - if dmg_sequence_number >= 65535 then - dmg_sequence_number = 0 - end -end - +local S = minetest.get_translator(minetest.get_current_modname()) + +local ASSIST_TIMEOUT_SEC = 5 + +mcl_death_messages = { + assist = {}, + messages = { + in_fire = { + _translator = S, + plain = "@1 went up in flames", + assist = "@1 walked into fire whilst fighting @2", + }, + lightning_bolt = { + _translator = S, + plain = "@1 was struck by lightning", + assist = "@1 was struck by lightning whilst fighting @2", + }, + on_fire = { + _translator = S, + plain = "@1 burned to death", + assist = "@1 was burnt to a crisp whilst fighting @2", + }, + lava = { + _translator = S, + plain = "@1 tried to swim in lava", + assist = "@1 tried to swim in lava to escape @2" + }, + hot_floor = { + _translator = S, + plain = "@1 discovered the floor was lava", + assist = "@1 walked into danger zone due to @2", + }, + in_wall = { + _translator = S, + plain = "@1 suffocated in a wall", + assist = "@1 suffocated in a wall whilst fighting @2", + }, + drown = { + _translator = S, + plain = "@1 drowned", + assist = "@1 drowned whilst trying to escape @2", + }, + starve = { + _translator = S, + plain = "@1 starved to death", + assist = "@1 starved to death whilst fighting @2", + }, + cactus = { + _translator = S, + plain = "@1 was pricked to death", + assist = "@1 walked into a cactus whilst trying to escape @2", + }, + fall = { + _translator = S, + plain = "@1 hit the ground too hard", + assist = "@1 hit the ground too hard whilst trying to escape @2", + -- "@1 fell from a high place" -- for fall distance > 5 blocks + -- "@1 fell while climbing" + -- "@1 fell off some twisting vines" + -- "@1 fell off some weeping vines" + -- "@1 fell off some vines" + -- "@1 fell off scaffolding" + -- "@1 fell off a ladder" + }, + fly_into_wall = { + _translator = S, + plain = "@1 experienced kinetic energy", + assist = "@1 experienced kinetic energy whilst trying to escape @2", + }, + out_of_world = { + _translator = S, + plain = "@1 fell out of the world", + assist = "@1 didn't want to live in the same world as @2", + }, + generic = { + _translator = S, + plain = "@1 died", + assist = "@1 died because of @2", + }, + magic = { + _translator = S, + plain = "@1 was killed by magic", + assist = "@1 was killed by magic whilst trying to escape @2", + killer = "@1 was killed by @2 using magic", + item = "@1 was killed by @2 using @3", + }, + dragon_breath = { + _translator = S, + plain = "@1 was roasted in dragon breath", + killer = "@1 was roasted in dragon breath by @2", + }, + wither = { + _translator = S, + plain = "@1 withered away", + escape = "@1 withered away whilst fighting @2", + }, + wither_skull = { + _translator = S, + plain = "@1 was killed by magic", + killer = "@1 was shot by a skull from @2", + }, + anvil = { + _translator = S, + plain = "@1 was squashed by a falling anvil", + escape = "@1 was squashed by a falling anvil whilst fighting @2", + }, + falling_node = { + _translator = S, + plain = "@1 was squashed by a falling block", + assist = "@1 was squashed by a falling block whilst fighting @2", + }, + mob = { + _translator = S, + killer = "@1 was slain by @2", + item = "@1 was slain by @2 using @3", + }, + player = { + _translator = S, + killer = "@1 was slain by @2", + item = "@1 was slain by @2 using @3" + }, + arrow = { + _translator = S, + killer = "@1 was shot by @2", + item = "@1 was shot by @2 using @3", + }, + fireball = { + _translator = S, + killer = "@1 was fireballed by @2", + item = "@1 was fireballed by @2 using @3", + }, + thorns = { + _translator = S, + killer = "@1 was killed trying to hurt @2", + item = "@1 tried to hurt @2 and died by @3", + }, + explosion = { + _translator = S, + plain = "@1 blew up", + killer = "@1 was blown up by @2", + item = "@1 was blown up by @2 using @3", + -- "@1 was killed by [Intentional Game Design]" -- for exploding bed in nether or end + }, + cramming = { + _translator = S, + plain = "@1 was squished too much", + assist = "@1 was squashed by @2", -- surprisingly "escape" is actually the correct subtype + }, + fireworks = { + _translator = S, + plain = "@1 went off with a bang", + item = "@1 went off with a bang due to a firework fired by @2 from @3", + }, + sweet_berry = { + _translator = S, + 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. + }, +} + +local function get_item_killer_message(obj, messages, reason) + if messages.item then + local wielded = mcl_util.get_wielded_item(reason.source) + local itemname = wielded:get_meta():get_string("name") + if itemname ~= "" then + itemname = "[" .. itemname .. "]" + if mcl_enchanting.is_enchanted(wielded:get_name()) then + itemname = minetest.colorize(mcl_colors.AQUA, itemname) + end + return messages._translator(messages.item, mcl_util.get_object_name(obj), mcl_util.get_object_name(reason.source), itemname) + end + end +end + +local function get_plain_killer_message(obj, messages, reason) + return messages.killer and messages._translator(messages.killer, mcl_util.get_object_name(obj), mcl_util.get_object_name(reason.source)) +end + +local function get_killer_message(obj, messages, reason) + return reason.source and (get_item_killer_message(obj, messages, reason) or get_plain_killer_message(obj, messages, reason)) +end + +local function get_assist_message(obj, messages, reason) + -- Avoid a timing issue if the assist passes its timeout. + local assist_details = mcl_death_messages.assist[obj] + if messages.assist and assist_details then + return messages._translator(messages.assist, mcl_util.get_object_name(obj), assist_details.name) + end +end + +local function get_plain_message(obj, messages, reason) + if messages.plain then + return messages._translator(messages.plain, mcl_util.get_object_name(obj)) + end +end + +local function get_fallback_message(obj, messages, reason) + return "mcl_death_messages.messages." .. reason.type .. " " .. mcl_util.get_object_name(obj) +end + +local function fallback_translator(s) + return s +end + +mcl_damage.register_on_death(function(obj, reason) + if not minetest.settings:get_bool("mcl_showDeathMessages", true) then + return + end + + local send_to + + if obj:is_player() then + send_to = true + end + + -- ToDo: add mob death messages for owned mobs, only send to owner (sent_to = "player name") + + if send_to then + local messages = mcl_death_messages.messages[reason.type] or {} + messages._translator = messages._translator or fallback_translator + + local message = + get_killer_message(obj, messages, reason) or + get_assist_message(obj, messages, reason) or + get_plain_message(obj, messages, reason) or + get_fallback_message(obj, messages, reason) + + if send_to == true then + minetest.chat_send_all(message) + else + minetest.chat_send_player(send_to, message) + end + end +end) + +mcl_damage.register_on_damage(function(obj, damage, reason) + if (obj:get_hp() - damage > 0) and reason.source and + (reason.source:is_player() or obj:get_luaentity()) then + -- To avoid timing issues we cancel the previous job before adding a new one. + if mcl_death_messages.assist[obj] then + mcl_death_messages.assist[obj].job:cancel() + end + + -- Add a new assist object with a timeout job. + local new_job = minetest.after(ASSIST_TIMEOUT_SEC, function() + mcl_death_messages.assist[obj] = nil + end) + mcl_death_messages.assist[obj] = {name = mcl_util.get_object_name(reason.source), job = new_job} + end +end) diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr index b9ef6680d..1e5003071 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr @@ -1,58 +1,58 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.=@1 wurde tödlich von einem Pfeil getroffen. -@1 has been killed by an arrow.=@1 wurde von einem Pfeil getötet. -@1 was shot by an arrow from @2.=@1 wurde mit einem Pfeil von @2 abgeschossen. -@1 was shot by an arrow from a skeleton.=@1 wurde von einem Skelett mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow from a stray.=@1 wurde von einem Eiswanderer mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow from an illusioner.=@1 wurde von einem Illusionisten mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow.=@1 wurde mit einem Pfeil abgeschossen. -@1 forgot to breathe.=@1 vergaß, zu atmen. -@1 drowned.=@1 ertrank. -@1 ran out of oxygen.=@1 ging die Luft aus. -@1 was killed by @2.=@1 wurde von @2 getötet. -@1 was killed.=@1 wurde getötet. -@1 was killed by a mob.=@1 wurde von einem Mob getötet. -@1 was burned to death by a blaze's fireball.=@1 wurde von einem Feuerball einer Lohe zu Tode verbrannt. -@1 was killed by a fireball from a blaze.=@1 wurde von einem Feuerball einer Lohe getötet. -@1 was burned by a fire charge.=@1 wurde von einer Feuerkugel verbrannt. -A ghast scared @1 to death.=Ein Ghast hat @1 zu Tode erschrocken. -@1 has been fireballed by a ghast.=@1 wurde von einem Ghast mit einer Feuerkugel abgeschossen. -@1 fell from a high cliff.=@1 stürzte von einer hohen Klippe. -@1 took fatal fall damage.=@1 nahm tödlichen Fallschaden. -@1 fell victim to gravity.=@1 fiel der Schwerkraft zum Opfer. -@1 died.=@1 starb. -@1 was killed by a zombie.=@1 wurde von einem Zombie getötet. -@1 was killed by a baby zombie.=@1 wurde von einem Zombiebaby getötet. -@1 was killed by a blaze.=@1 wurde von einer Lohe getötet. -@1 was killed by a slime.=@1 wurde von einem Schleim getötet. -@1 was killed by a witch.=@1 wurde von einer Hexe getötet. -@1 was killed by a magma cube.=@1 wurde von einem Magmakubus getötet. -@1 was killed by a wolf.=@1 wurde von einem Wolf getötet. -@1 was killed by a cat.=@1 wurde von einer Katze getötet. -@1 was killed by an ocelot.=@1 wurde von einem Ozelot getötet. -@1 was killed by an ender dragon.=@1 wurde von einem Enderdrachen getötet. -@1 was killed by a wither.=@1 wurde von einem Wither getötet. -@1 was killed by an enderman.=@1 wurde von einem Enderman getötet. -@1 was killed by an endermite.=@1 wurde von einer Endermilbe getötet. -@1 was killed by a ghast.=@1 wurde von einem Ghast getötet. -@1 was killed by an elder guardian.=@1 wurde von einem Großen Wächter getötet. -@1 was killed by a guardian.=@1 wurde von einem Wächter getötet. -@1 was killed by an iron golem.=@1 wurde von einem Eisengolem getötet. -@1 was killed by a polar_bear.=@1 wurde von einem Eisbären getötet. -@1 was killed by a killer bunny.=@1 wurde von einem Killerkaninchen getötet. -@1 was killed by a shulker.=@1 wurde von einem Schulker getötet. -@1 was killed by a silverfish.=@1 wurde von einem Silberfischchen getötet. -@1 was killed by a skeleton.=@1 wurde von einem Skelett getötet. -@1 was killed by a stray.=@1 wurde von einem Eiswanderer getötet. -@1 was killed by a slime.=@1 wurde von einem Schleim getötet. -@1 was killed by a spider.=@1 wurde von einer Spinne getötet. -@1 was killed by a cave spider.=@1 wurde von einer Höhlenspinne getötet. -@1 was killed by a vex.=@1 wurde von einem Plagegeist getötet. -@1 was killed by an evoker.=@1 wurde von einem Magier getötet. -@1 was killed by an illusioner.=@1 wurde von einem Illusionisten getötet. -@1 was killed by a vindicator.=@1 wurde von einem Diener getötet. -@1 was killed by a zombie villager.=@1 wurde von einem Dorfbewohnerzombie getötet. -@1 was killed by a husk.=@1 wurde von einem Wüstenzombie getötet. -@1 was killed by a baby husk.=@1 wurde von einem Wüstenzombiebaby getötet. -@1 was killed by a zombie pigman.=@1 wurde von einem Schweinezombie getötet. -@1 was killed by a baby zombie pigman.=@1 wurde von einem Schweinezombiebaby getötet. +@1 went up in flames=@1 ging in Flammen auf +@1 walked into fire whilst fighting @2=@1 ist während eines Kampfes mit @2 in ein Feuer gelaufen +@1 was struck by lightning=@1 wurde von einem Blitz erschlagen +@1 was struck by lightning whilst fighting @2=@1 wurde während eines Kampfes mit @2 von einem Blitz erschlagen +@1 burned to death=@1 ist verbrannt +@1 was burnt to a crisp whilst fighting @2=@1 ist während eines Kampfes mit @2 verbrannt +@1 tried to swim in lava=@1 hat versucht, in Lava zu schwimmen +@1 tried to swim in lava to escape @2=@1 hat versucht, in Lava zu schwimmen, um @2 zu entkommen +@1 discovered the floor was lava=@1 hat festgestellt, dass der Boden Lava ist +@1 walked into danger zone due to @2=@1 ist wegen @2 in eine Gefahrenzone gelaufen +@1 suffocated in a wall=@1 ist in einer Mauer erstickt +@1 suffocated in a wall whilst fighting @2=@1 ist während eines Kampfes mit @2 in einer Mauer erstickt +@1 drowned=@1 ist ertrunken +@1 drowned whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, ertrunken +@1 starved to death=@1 ist verhungert +@1 starved to death whilst fighting @2=@1 ist während eines Kampfes mit @2 verhungert +@1 was pricked to death=@1 wurde zu Tode gestochen +@1 walked into a cactus whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, in einen Kaktus gelaufen +@1 hit the ground too hard=@1 ist zu hart auf dem Boden aufgetroffen +@1 hit the ground too hard whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, zu hart auf dem Boden aufgetroffen +@1 experienced kinetic energy=@1 hat kinetische Energie erfahren +@1 experienced kinetic energy whilst trying to escape @2=@1 hat während dem Versuch, @2 zu entkommen, kinetische Energie erfahren +@1 fell out of the world=@1 ist aus der Welt gefallen +@1 didn't want to live in the same world as @2=@1 wollte nicht in der gleichen Welt wie @2 leben +@1 died=@1 ist gestorben +@1 died because of @2=@1 ist wegen @2 gestorben +@1 was killed by magic=@1 wurde von Magie getötet +@1 was killed by magic whilst trying to escape @2=@1 wurde während dem Versuch, @2 zu entkommen, von Magie getötet +@1 was killed by @2 using magic=@1 wurde von @2 mit Magie getötet +@1 was killed by @2 using @3=@1 wurde von @2 mit @3 getötet +@1 was roasted in dragon breath=@1 wurde in Drachenatem geröstet +@1 was roasted in dragon breath by @2=@1 wurde in Drachenatem von @2 geröstet +@1 withered away=@1 ist davon gewithert +@1 withered away whilst fighting @2=@1 ist während einem Kampf mit @2 davon gewithert +@1 was killed by magic=@1 wurde von Magie getötet +@1 was shot by a skull from @2=@1 wurde von einem Schädel von @2 erschossen +@1 was squashed by a falling anvil=@1 wurde von einem fallenden Amboss erquetscht +@1 was squashed by a falling anvil whilst fighting @2=@1 wurde während einem Kampf mit @2 von einem fallenden Amboss erquetscht +@1 was squashed by a falling block=@1 wurde von einem fallenden Block erquetscht +@1 was squashed by a falling block whilst fighting @2=@1 wurde während einem Kampf mit @2 von einem fallenden Block erquetscht +@1 was slain by @2=@1 wurde von @2 erschlagen +@1 was slain by @2 using @3=@1 wurde von @2 mit @3 erschlagen +@1 was slain by @2=@1 wurde von @2 erschlagen +@1 was slain by @2 using @3=@1 wurde von @2 mit @3 erschlagen +@1 was shot by @2=@1 wurde von @2 erschossen +@1 was shot by @2 using @3=@1 wurde von @2 mit @3 erschossen +@1 was fireballed by @2=@1 wurde von @2 gefeuerballt +@1 was fireballed by @2 using @3=@1 wurde von @2 mit @3 gefeuerballt +@1 was killed trying to hurt @2=@1 ist bei dem Versuch, @2 zu verletzten gestorben +@1 tried to hurt @2 and died by @3=@1 versuchte @2 zu verletzen und starb von @3 +@1 blew up=@1 ist gesprengt worden +@1 was blown up by @2=@1 wurde von @2 gesprengt +@1 was blown up by @2 using @3=@1 wurde von @2 mit @3 gesprengt +@1 was squished too much=@1 war zu gequetscht +@1 was squashed by @2=@1 wurde von @2 erquetscht +@1 went off with a bang=@1 ging mit einem Knall ab +@1 went off with a bang due to a firework fired by @2 from @3=@1 ging mit einem Knall los aufgrund eines Feuerwerks, das von @2 von @3 abgefeuert wurde diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr index 6ed106db8..8c56ebe9e 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.es.tr @@ -20,6 +20,9 @@ A ghast scared @1 to death.=Se ha asustado @1 hasta morir. @1 took fatal fall damage.=@1 se hizo daño crítico por una caída. @1 fell victim to gravity.=@1 cayó víctima de la gravedad. @1 died.=@1 murió. +@1 was slain by @2.= +@1 tried to hurt @2 and died by @3=@1 trató de lastimar a @2 y murió por @3 +@1 went off with a bang due to a firework fired by @2 from @3=@1 se disparó con fuerza debido a un fuego artificial disparado por @2 desde @3 @1 was killed by a zombie.=@1 fue asesinado por un zombie. @1 was killed by a baby zombie.=@1 fue asesinado por un bebé zombie. @1 was killed by a blaze.=@1 fue asesinado por una llamarada. @@ -53,5 +56,5 @@ A ghast scared @1 to death.=Se ha asustado @1 hasta morir. @1 was killed by a zombie villager.=@1 fue asesinado por un aldeano zombie. @1 was killed by a husk.=@1 fue asesinado por un husk. @1 was killed by a baby husk.=@1 fue asesinado por un bebé husk. -@1 was killed by a zombie pigman.=@1 fue asesinado por un cerdo zombie. -@1 was killed by a baby zombie pigman.=@1 fue asesinado por un bebé cerdo zombie. +@1 was killed by a zombie piglin.=@1 fue asesinado por un cerdo zombie. +@1 was killed by a baby zombie piglin.=@1 fue asesinado por un bebé cerdo zombie. \ No newline at end of file diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr index 6d0a5115c..6859d56d3 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.fr.tr @@ -1,58 +1,55 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.=@1 a été mortellement touché par une flèche. -@1 has been killed with an arrow.=@1 a été tué avec une flèche. -@1 was shot by an arrow from @2.=@1 a été abattu par une flèche de @2. -@1 was shot by an arrow from a skeleton.=@1 a été abattu par une flèche d'un squelette. -@1 was shot by an arrow from a stray.=@1 a été abattu par une flèche d'un vagabond. -@1 was shot by an arrow from an illusioner.=@1 a été abattu par une flèche d'un illusionniste. -@1 was shot by an arrow.=@1 a été abattu par une flèche. -@1 forgot to breathe.=@1 a oublié de respirer. -@1 drowned.=@1 s'est noyé. -@1 ran out of oxygen.=@1 a manqué d'oxygène. -@1 was killed by @2.=@1 a été tué par @2. -@1 was killed.=@1 a été tué. -@1 was killed by a mob.=@1 a été tué par un mob. -@1 was burned to death by a blaze's fireball.=@1 a été brûlé vif par la boule de feu d'un blaze. -@1 was killed by a fireball from a blaze.=@1 a été tué par une boule de feu lors d'un blaze. -@1 was burned by a fire charge.=@1 a été brûlé par un incendie. -A ghast scared @1 to death.=Un ghast a éffrayé @1 à mort. -@1 has been fireballed by a ghast.=@1 a été pétrifié par un ghast. -@1 fell from a high cliff.=@1 est tombé d'une haute falaise. -@1 took fatal fall damage.=@1 a succombé à un chute mortelle. -@1 fell victim to gravity.=@1 a été victime de la gravité. -@1 died.=@1 est mort. -@1 was killed by a zombie.=@1 a été tué par un zombie. -@1 was killed by a baby zombie.=@1 a été tué par un bébé zombie. -@1 was killed by a blaze.=@1 a été tué par un blaze. -@1 was killed by a slime.=@1 a été tué par un slime. -@1 was killed by a witch.=@1 a été tué par un sorcier. -@1 was killed by a magma cube.=@1 a été tué par un cube de magma. -@1 was killed by a wolf.=@1 a été tué par un loup. -@1 was killed by a cat.=@1 a été tué par un chat. -@1 was killed by an ocelot.=@1 a été tué par un ocelot. -@1 was killed by an ender dragon.=@1 a été tué par un ender dragon. -@1 was killed by a wither.=@1 a été tué par un wither. -@1 was killed by an enderman.=@1 a été tué par un enderman. -@1 was killed by an endermite.=@1 a été tué par un endermite. -@1 was killed by a ghast.=@1 a été tué par un ghast. -@1 was killed by an elder guardian.=@1 a été tué par un grand gardien. -@1 was killed by a guardian.=@1 a été tué par un gardien. -@1 was killed by an iron golem.=@1 a été tué par un golem de fer. -@1 was killed by a polar_bear.=@1 a été tué par un ours blanc. -@1 was killed by a killer bunny.=@1 a été tué par un lapin tueur. -@1 was killed by a shulker.=@1 a été tué par un shulker. -@1 was killed by a silverfish.=@1 a été tué par un poisson d'argent. -@1 was killed by a skeleton.=@1 a été tué par un squelette. -@1 was killed by a stray.=@1 a été tué par un vagabond. -@1 was killed by a slime.=@1 a été tué par un slime. -@1 was killed by a spider.=@1 a été tué par une araignée. -@1 was killed by a cave spider.=@1 a été tué par une araignée venimeuse. -@1 was killed by a vex.=@1 a été tué par un vex. -@1 was killed by an evoker.=@1 a été tué par un invocateur. -@1 was killed by an illusioner.=@1 a été tué par un illusionniste. -@1 was killed by a vindicator.=@1 a été tué par un vindicateur. -@1 was killed by a zombie villager.=@1 a été tué par un villageois zombie. -@1 was killed by a husk.=@1 a été tué par un zombie momie. -@1 was killed by a baby husk.=@1 a été tué par un bébé zombie momie. -@1 was killed by a zombie pigman.=@1 a été tué par un zombie-couchon. -@1 was killed by a baby zombie pigman.=@1 a été tué par un bébé zombie-couchon +@1 went up in flames=@1 est parti(e) en fumée +@1 walked into fire whilst fighting @2=@1 a marché dans le feu en combattant @2 +@1 was struck by lightning=@1 a été frappé(e) par la foudre +@1 was struck by lightning whilst fighting @2=@1 a été frappé(e) par la foudre en combattant @2 +@1 burned to death=@1 est mort(e) brûlé vif(ve) +@1 was burnt to a crisp whilst fighting @2=@1 a été grillé comme une saucisse en combattant @2 +@1 tried to swim in lava=@1 a essayé de nager dans la lave +@1 tried to swim in lava to escape @2=@1 a essayé de nager dans la lave pour échapper à @2 +@1 discovered the floor was lava=@1 a découvert que le sol était en lave +@1 walked into danger zone due to @2=@1 a marché dans une zone de danger à cause de @2 +@1 suffocated in a wall=@1 a étouffé dans un mur +@1 suffocated in a wall whilst fighting @2=@1 a étouffé dans un mur en combattant @2 +@1 drowned=@1 s'est noyé(e) +@1 drowned whilst trying to escape @2=@1 s'est noyé(e) en tentant d'échapper à @2 +@1 starved to death=@1 est mort(e) de faim +@1 starved to death whilst fighting @2=@1 est mort(e) de faim en combattant @2 +@1 was pricked to death=@1 a été piqué(e) à mort +@1 walked into a cactus whilst trying to escape @2=@1 est rentré(e) dans un cactus en tentant d'échapper @2 +@1 hit the ground too hard=@1 a heurté le sol trop fort +@1 hit the ground too hard whilst trying to escape @2=@1 a heurté le sol trop fort en tentant d'échapper à @2 +@1 experienced kinetic energy=@1 a fait l'expérience de l'énergie cinétique +@1 experienced kinetic energy whilst trying to escape @2=@1 a fait l'expérience de l'énergie cinétique en tentant d'échapper à @2 +@1 fell out of the world=@1 est tombé(e) hors du monde +@1 didn't want to live in the same world as @2=@1 ne voulait pas vivre dans le même monde que @2 +@1 died=@1 est mort. +@1 died because of @2=@1 est mort à cause de @2 +@1 was killed by magic=@1 a été tué(e) par magie +@1 was killed by magic whilst trying to escape @2=@1 a été tué(e) par magie en tentant d'échapper à @2 +@1 was killed by @2 using magic=@1 a été tué(e) par @2 en utilisant la magie +@1 was killed by @2 using @3=@1 a été tué(e) par @2 en utilisant @3 +@1 was roasted in dragon breath=@1 a été rôti(e) dans le souffle du dragon +@1 was roasted in dragon breath by @2=@1 a été rôti(e) dans le souffle du dragon par @2 +@1 withered away=@1 s'est flétri(e) +@1 withered away whilst fighting @2=@1 s'est flétri(e) en combattant @2 +@1 was shot by a skull from @2=@1 a été abattu(e) par un crâne lancé par @2 +@1 was squashed by a falling anvil=@1 a été écrasé(e) par la chute d'une enclume +@1 was squashed by a falling anvil whilst fighting @2=@1 a été écrasé(e) par la chute d'une enclume en combattant @2 +@1 was squashed by a falling block=@1 a été écrasé(e) par la chute d'un bloc +@1 was squashed by a falling block whilst fighting @2=@1 a été écrasé(e) par la chute d'un bloc en combattant @2 +@1 was slain by @2=@1 a été occis par @2 +@1 was slain by @2 using @3=@1 a été occis par @2 en utilisant @3 +@1 was shot by @2=@1 a été abattu(e) par @2 +@1 was shot by @2 using @3=@1 a été abattu(e) par @2 en utilisant @3 +@1 was fireballed by @2=@1 a reçu une balle de feu lancée par @2 +@1 was fireballed by @2 using @3=@1 a reçu une balle de feu lancée par @2 en utilisant @3 +@1 was killed trying to hurt @2=@1 a été tué(e) en essayant de blesser @2 +@1 tried to hurt @2 and died by @3=@1 a essayé de blesser @2 et est mort par @3 +@1 blew up=@1 a explosé +@1 was blown up by @2=@2 a fait exploser @1 +@1 was blown up by @2 using @3=@2 a fait exploser @1 en utilisant @3 +@1 was squished too much=@1 a été pressé(e) un peu trop +@1 was squashed by @2=@1 a été écrasé(e) par @2 +@1 went off with a bang=@1 est parti(e) avec un bang +@1 went off with a bang due to a firework fired by @2 from @3=@1 a explosé à cause d'un feu d'artifice tiré par @2 depuis @3 diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr new file mode 100644 index 000000000..0daae9c21 --- /dev/null +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.ja.tr @@ -0,0 +1,55 @@ +# textdomain: mcl_death_messages +@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=@1は@2の使った@3で殺害された +@1 was shot by @2=@1は@2に撃たれた +@1 was shot by @2 using @3=@1は@2の使った@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は@2を傷めつけようとした@3に殺された +@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は@2が@3から発射した花火により爆散した diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pl.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pl.tr new file mode 100644 index 000000000..c979e7dd6 --- /dev/null +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.pl.tr @@ -0,0 +1,59 @@ +# textdomain: mcl_death_messages +@1 went up in flames=@1 stanęła w płomieniach +@1 walked into fire whilst fighting @2=@1 weszła w płomienie podczas walki z @2 +@1 was struck by lightning=@1 została trafiona piorunem +@1 was struck by lightning whilst fighting @2=@1 została trafiona piorunem z @2 +@1 burned to death=@1 została spalona żywcem +@1 was burnt to a crisp whilst fighting @2=@1 została usmażona podczas walki z @2 +@1 tried to swim in lava=@1 próbowała pływać w lawie +@1 tried to swim in lava to escape @2=@1 próbowała pływać w lawie by uciec od @20 +@1 discovered the floor was lava=@1 odkryła, że podłoga to lawa +@1 walked into danger zone due to @2=@1 weszła do niebezpiecznej strony przez @2 +@1 suffocated in a wall=@1 udusiła się w ścianie +@1 suffocated in a wall whilst fighting @2=@1 udusiła się w ścianie podczas walki z @2 +@1 drowned=@1 utopiła się +@1 drowned whilst trying to escape @2=@1 utopiła się podczas ucieczki przed @2 +@1 starved to death=@1 zagłodziła się na śmierć +@1 starved to death whilst fighting @2=@1 zagłodziła się na śmierć podczas walki z @2 +@1 was pricked to death=@1 została zakłuta na śmierć +@1 walked into a cactus whilst trying to escape @2=@1 weszła w kaktus podczas ucieczki przed @2 +@1 hit the ground too hard=@1 zbyt twardo wylądowała +@1 hit the ground too hard whilst trying to escape @2=@1 zby twardo wylądowała podczas walki z @2 +@1 experienced kinetic energy=@1 doświadczyła energii kinetycznej +@1 experienced kinetic energy whilst trying to escape @2=@1 doświadczyła energii kinetycznej podczas ucieczki przed @2 +@1 fell out of the world=@1 wyleciała poza świat +@1 didn't want to live in the same world as @2=@1 nie chciała żyć w tym samym świecie co @2 +@1 died=@1 umarła +@1 died because of @2=@1 umarła przez @2 +@1 was killed by magic=@1 została zabita magią +@1 was killed by magic whilst trying to escape @2=@1 została zabita magią podczas ucieczki przed @2 +@1 was killed by @2 using magic=@1 została zabita przez @2 korzystając z magii +@1 was killed by @2 using @3=@1 została zabita przez @2 korzystając z @3 +@1 was roasted in dragon breath=@1 została usmażona przez oddech smoka +@1 was roasted in dragon breath by @2=@1 została usmażona przez oddech smoka od @2 +@1 withered away=@1 odeszła na wieki +@1 withered away whilst fighting @2=@1 odeszła na wieki podczas walki z @2 +@1 was killed by magic=@1 została zabita magią +@1 was shot by a skull from @2=@1 została zastrzelona czaszką przez @2 +@1 was squashed by a falling anvil=@1 została zmiażdżona spadającym kowadłem +@1 was squashed by a falling anvil whilst fighting @2=@1 została zmiażdżona spadającym kowadłem podczas walki z @2 +@1 was squashed by a falling block=@1 została zmiażdżona spadającym blokiem +@1 was squashed by a falling block whilst fighting @2=@1 została zmiażdżona spadającym blokiem podczas walki z @2 +@1 was slain by @2=@1 została zabita przez @2 +@1 was slain by @2 using @3=@1 została zabita przez @2 przy użyciu @3 +@1 was slain by @2=@1 została zabita przez @2 +@1 was slain by @2 using @3=@1 została zabita przez @2 przy użyciu @3 +@1 was shot by @2=@1 została zastrzelona przez @2 +@1 was shot by @2 using @3=@1 została zastrzelona przez @2 przy użyciu @3 +@1 was fireballed by @2=@1 została zabita kulą ognia przez @2 +@1 was fireballed by @2 using @3=@1 została zabita kulą ognia przez @2 przy użyciu @3 +@1 was killed trying to hurt @2=@1 została zabita gdy próbowała skrzywdzić @2 +@1 tried to hurt @2 and died by @3=@1 próbował skrzywdzić @2 i zginął przed @3 +@1 blew up=@1 wybuchła +@1 was blown up by @2=@1 została wysadzona przez @2 +@1 was blown up by @2 using @3=@1 została wysadzona przez @2 przy użyciu @3 +@1 was squished too much=@1 została zbyt mocno ściśnięta +@1 was squashed by @2=@1 została ściśnięta przez @2 +@1 went off with a bang=@1 odeszła z hukiem +@1 went off with a bang due to a firework fired by @2 from @3=@1 wybuchł z hukiem z powodu fajerwerków wystrzelonych przez @2 z @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 f9f164dd3..816546e5e 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 @@ -21,6 +21,9 @@ A ghast scared @1 to death.=Гаст напугал @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 был(а) убит(а) ифритом. @@ -54,5 +57,5 @@ A ghast scared @1 to death.=Гаст напугал @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 pigman.=@1 был(а) убит(а) зомби-свиночеловеком. -@1 was killed by a baby zombie pigman.=@1 был(а) убит(а) малышом-зомби-свиночеловеком. +@1 was killed by a zombie piglin.=@1 был(а) убит(а) зомби-свиночеловеком. +@1 was killed by a baby zombie piglin.=@1 был(а) убит(а) малышом-зомби-свиночеловеком. diff --git a/mods/HUD/mcl_death_messages/locale/template.txt b/mods/HUD/mcl_death_messages/locale/template.txt index db074f756..f94607603 100644 --- a/mods/HUD/mcl_death_messages/locale/template.txt +++ b/mods/HUD/mcl_death_messages/locale/template.txt @@ -1,58 +1,55 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.= -@1 has been killed with an arrow.= -@1 was shot by an arrow from @2.= -@1 was shot by an arrow from a skeleton.= -@1 was shot by an arrow from a stray.= -@1 was shot by an arrow from an illusioner.= -@1 was shot by an arrow.= -@1 forgot to breathe.= -@1 drowned.= -@1 ran out of oxygen.= -@1 was killed by @2.= -@1 was killed.= -@1 was killed by a mob.= -@1 was burned to death by a blaze's fireball.= -@1 was killed by a fireball from a blaze.= -@1 was burned by a fire charge.= -A ghast scared @1 to death.= -@1 has been fireballed by a ghast.= -@1 fell from a high cliff.= -@1 took fatal fall damage.= -@1 fell victim to gravity.= -@1 died.= -@1 was killed by a zombie.= -@1 was killed by a baby zombie.= -@1 was killed by a blaze.= -@1 was killed by a slime.= -@1 was killed by a witch.= -@1 was killed by a magma cube.= -@1 was killed by a wolf.= -@1 was killed by a cat.= -@1 was killed by an ocelot.= -@1 was killed by an ender dragon.= -@1 was killed by a wither.= -@1 was killed by an enderman.= -@1 was killed by an endermite.= -@1 was killed by a ghast.= -@1 was killed by an elder guardian.= -@1 was killed by a guardian.= -@1 was killed by an iron golem.= -@1 was killed by a polar_bear.= -@1 was killed by a killer bunny.= -@1 was killed by a shulker.= -@1 was killed by a silverfish.= -@1 was killed by a skeleton.= -@1 was killed by a stray.= -@1 was killed by a slime.= -@1 was killed by a spider.= -@1 was killed by a cave spider.= -@1 was killed by a vex.= -@1 was killed by an evoker.= -@1 was killed by an illusioner.= -@1 was killed by a vindicator.= -@1 was killed by a zombie villager.= -@1 was killed by a husk.= -@1 was killed by a baby husk.= -@1 was killed by a zombie pigman.= -@1 was killed by a baby zombie pigman.= +@1 went up in flames= +@1 walked into fire whilst fighting @2= +@1 was struck by lightning= +@1 was struck by lightning whilst fighting @2= +@1 burned to death= +@1 was burnt to a crisp whilst fighting @2= +@1 tried to swim in lava= +@1 tried to swim in lava to escape @2= +@1 discovered the floor was lava= +@1 walked into danger zone due to @2= +@1 suffocated in a wall= +@1 suffocated in a wall whilst fighting @2= +@1 drowned= +@1 drowned whilst trying to escape @2= +@1 starved to death= +@1 starved to death whilst fighting @2= +@1 was pricked to death= +@1 walked into a cactus whilst trying to escape @2= +@1 hit the ground too hard= +@1 hit the ground too hard whilst trying to escape @2= +@1 experienced kinetic energy= +@1 experienced kinetic energy whilst trying to escape @2= +@1 fell out of the world= +@1 didn't want to live in the same world as @2= +@1 died= +@1 died because of @2= +@1 was killed by magic= +@1 was killed by magic whilst trying to escape @2= +@1 was killed by @2 using magic= +@1 was killed by @2 using @3= +@1 was roasted in dragon breath= +@1 was roasted in dragon breath by @2= +@1 withered away= +@1 withered away whilst fighting @2= +@1 was shot by a skull from @2= +@1 was squashed by a falling anvil= +@1 was squashed by a falling anvil whilst fighting @2= +@1 was squashed by a falling block= +@1 was squashed by a falling block whilst fighting @2= +@1 was slain by @2= +@1 was slain by @2 using @3= +@1 was shot by @2= +@1 was shot by @2 using @3= +@1 was fireballed by @2= +@1 was fireballed by @2 using @3= +@1 was killed trying to hurt @2= +@1 tried to hurt @2 and died by @3= +@1 blew up= +@1 was blown up by @2= +@1 was blown up by @2 using @3= +@1 was squished too much= +@1 was squashed by @2= +@1 went off with a bang= +@1 went off with a bang due to a firework fired by @2 from @3= diff --git a/mods/HUD/mcl_death_messages/mod.conf b/mods/HUD/mcl_death_messages/mod.conf index 4e4396074..a634e16de 100644 --- a/mods/HUD/mcl_death_messages/mod.conf +++ b/mods/HUD/mcl_death_messages/mod.conf @@ -1 +1,4 @@ name = mcl_death_messages +author = 4Evergreen4 +description = Shows messages in chat when a player dies. +depends = mcl_colors diff --git a/mods/HUD/mcl_experience/bottle.lua b/mods/HUD/mcl_experience/bottle.lua new file mode 100644 index 000000000..62a3fb9ca --- /dev/null +++ b/mods/HUD/mcl_experience/bottle.lua @@ -0,0 +1,68 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_target = minetest.get_modpath("mcl_target") + +minetest.register_entity("mcl_experience:bottle",{ + textures = {"mcl_experience_bottle.png"}, + hp_max = 1, + visual_size = {x = 0.35, y = 0.35}, + collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, + pointable = false, + on_step = function(self, dtime) + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + 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)) + minetest.add_particlespawner({ + amount = 50, + time = 0.1, + minpos = vector.add(pos, vector.new(-0.1, 0.5, -0.1)), + maxpos = vector.add(pos, vector.new( 0.1, 0.6, 0.1)), + minvel = vector.new(-2, 0, -2), + maxvel = vector.new( 2, 2, 2), + minacc = vector.new(0, 0, 0), + maxacc = vector.new(0, 0, 0), + minexptime = 0.5, + maxexptime = 1.25, + minsize = 1, + maxsize = 2, + collisiondetection = true, + vertical = false, + texture = "mcl_particles_effect.png^[colorize:blue:127", + }) + if mod_target and n == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + end + self.object:remove() + end + end, +}) + +local function throw_xp_bottle(pos, dir, velocity) + 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) +end + +minetest.register_craftitem("mcl_experience:bottle", { + description = S("Bottle o' Enchanting"), + inventory_image = "mcl_experience_bottle.png", + 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) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + return itemstack + end, + _on_dispense = function(_, pos, _, _, dir) + throw_xp_bottle(vector.add(pos, vector.multiply(dir, 0.51)), dir, 10) + end +}) + diff --git a/mods/HUD/mcl_experience/command.lua b/mods/HUD/mcl_experience/command.lua new file mode 100644 index 000000000..040031b5a --- /dev/null +++ b/mods/HUD/mcl_experience/command.lua @@ -0,0 +1,39 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("xp", { + params = S("[[] ]"), + description = S("Gives a player some XP"), + privs = {server=true}, + func = function(name, params) + local player, xp = nil, 1000 + local P, i = {}, 0 + for str in string.gmatch(params, "([^ ]+)") do + i = i + 1 + P[i] = str + end + if i > 2 then + return false, S("Error: Too many parameters!") + end + if i > 0 then + xp = tonumber(P[i]) + end + if i < 2 then + player = minetest.get_player_by_name(name) + end + if i == 2 then + player = minetest.get_player_by_name(P[1]) + end + + if not xp then + return false, S("Error: Incorrect value of XP") + end + + if not player then + return false, S("Error: Player not found") + end + + mcl_experience.add_xp(player, xp) + + return true, S("Added @1 XP to @2, total: @3, experience level: @4", tostring(xp), player:get_player_name(), tostring(mcl_experience.get_xp(player)), tostring(mcl_experience.get_level(player))) + end, +}) diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index ff5647616..359e68918 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -1,653 +1,249 @@ -local S = minetest.get_translator("mcl_experience") -mcl_experience = {} -local pool = {} -local registered_nodes -local max_xp = 2^31-1 -local max_orb_age = 300 -- seconds - -local gravity = {x = 0, y = -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), z = 0} -local size_min, size_max = 20, 59 -- percents -local delta_size = size_max - size_min -local size_to_xp = { - {-32768, 2}, -- 1 - { 3, 6}, -- 2 - { 7, 16}, -- 3 - { 17, 36}, -- 4 - { 37, 72}, -- 5 - { 73, 148}, -- 6 - { 149, 306}, -- 7 - { 307, 616}, -- 8 - { 617, 1236}, -- 9 - { 1237, 2476}, --10 - { 2477, 32767} --11 +mcl_experience = { + on_add_xp = {}, } -local function xp_to_size(xp) - local i, l = 1, #size_to_xp - while (xp > size_to_xp[i][1]) and (i < l) do - i = i + 1 - end - return ((i-1) / (l-1) * delta_size + size_min)/100 -end +local modpath = minetest.get_modpath(minetest.get_current_modname()) -minetest.register_on_mods_loaded(function() - registered_nodes = minetest.registered_nodes -end) +dofile(modpath .. "/command.lua") +dofile(modpath .. "/orb.lua") +dofile(modpath .. "/bottle.lua") -local load_data = function(player) - local name = player:get_player_name() - pool[name] = {} - local temp_pool = pool[name] - local meta = player:get_meta() - temp_pool.xp = meta:get_int("xp") or 0 - temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) - temp_pool.last_time= minetest.get_us_time()/1000000 -end +-- local storage --- saves data to be utilized on next login -local save_data = function(player) - local name = player:get_player_name() - local temp_pool = pool[name] - local meta = player:get_meta() - meta:set_int("xp", temp_pool.xp) - pool[name] = nil -end +local hud_bars = {} +local hud_levels = {} +local caches = {} -local player_huds = {} -- the list of players hud lists (3d array) -hud_manager = {} -- hud manager class +-- helpers --- terminate the player's list on leave -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - player_huds[name] = nil -end) - --- create instance of new hud -hud_manager.add_hud = function(player,hud_name,def) - local name = player:get_player_name() - local local_hud = player:hud_add({ - hud_elem_type = def.hud_elem_type, - position = def.position, - text = def.text, - text2 = def.text2, - number = def.number, - item = def.item, - direction = def.direction, - size = def.size, - offset = def.offset, - z_index = def.z_index, - alignment = def.alignment, - scale = def.scale, - }) - -- create new 3d array here - -- depends.txt is not needed - -- with it here - if not player_huds[name] then - player_huds[name] = {} - end - - player_huds[name][hud_name] = local_hud -end - --- delete instance of hud -hud_manager.remove_hud = function(player,hud_name) - local name = player:get_player_name() - if player_huds[name] and player_huds[name][hud_name] then - player:hud_remove(player_huds[name][hud_name]) - player_huds[name][hud_name] = nil - end -end - --- change element of hud -hud_manager.change_hud = function(data) - local name = data.player:get_player_name() - if player_huds[name] and player_huds[name][data.hud_name] then - data.player:hud_change(player_huds[name][data.hud_name], data.element, data.data) - end -end - --- gets if hud exists -hud_manager.hud_exists = function(player,hud_name) - local name = player:get_player_name() - if player_huds[name] and player_huds[name][hud_name] then - return(true) - else - return(false) - end -end -------------------- - --- saves specific users data for when they relog -minetest.register_on_leaveplayer(function(player) - save_data(player) -end) - --- is used for shutdowns to save all data -local save_all = function() - for name,_ in pairs(pool) do - local player = minetest.get_player_by_name(name) - if player then - save_data(player) - end - end -end - --- save all data to mod storage on shutdown -minetest.register_on_shutdown(function() - save_all() -end) - - -function mcl_experience.get_player_xp_level(player) - local name = player:get_player_name() - return(pool[name].level) -end - -function mcl_experience.set_player_xp_level(player,level) - local name = player:get_player_name() - if level == pool[name].level then - return - end - pool[name].level = level - pool[name].xp, pool[name].bar_step, pool[name].xp_next_level = mcl_experience.bar_to_xp(pool[name].bar, level) - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(level)}) - -- we may don't update the bar -end - -local name -local temp_pool -minetest.register_on_joinplayer(function(player) - - load_data(player) - - name = player:get_player_name() - temp_pool = pool[name] - - hud_manager.add_hud(player,"experience_bar", - { - hud_elem_type = "image", - name = "experience bar", - text = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270", - position = {x=0.5, y=1}, - offset = {x = (-9 * 28) - 3, y = -(48 + 24 + 16 - 5)}, - scale = {x = 2.8, y = 3.0}, - alignment = { x = 1, y = 1 }, - z_index = 11, - }) - - hud_manager.add_hud(player,"xp_level", - { - hud_elem_type = "text", position = {x=0.5, y=1}, - name = "xp_level", text = tostring(temp_pool.level), - number = 0x80FF20, - offset = {x = 0, y = -(48 + 24 + 24)}, - z_index = 12, - }) -end) - -function mcl_experience.xp_to_level(xp) +local function xp_to_level(xp) local xp = xp or 0 local a, b, c, D + if xp > 1507 then - a, b, c = 4.5, -162.5, 2220-xp + a, b, c = 4.5, -162.5, 2220 - xp elseif xp > 352 then - a, b, c = 2.5, -40.5, 360-xp + a, b, c = 2.5, -40.5, 360 - xp else a, b, c = 1, 6, -xp end - D = b*b-4*a*c + + D = b * b - 4 * a * c + if D == 0 then - return math.floor(-b/2/a) - elseif D > 0 then - local v1, v2 = -b/2/a, math.sqrt(D)/2/a - return math.floor((math.max(v1-v2, v1+v2))) + return math.floor(-b / 2 / a) + elseif D > 0 then + local v1, v2 = -b / 2 / a, math.sqrt(D) / 2 / a + return math.floor(math.max(v1 - v2, v1 + v2)) end + return 0 end -function mcl_experience.level_to_xp(level) - if (level >= 1 and level <= 16) then +local function level_to_xp(level) + if level >= 1 and level <= 16 then return math.floor(math.pow(level, 2) + 6 * level) - elseif (level >= 17 and level <= 31) then + elseif level >= 17 and level <= 31 then return math.floor(2.5 * math.pow(level, 2) - 40.5 * level + 360) elseif level >= 32 then - return math.floor(4.5 * math.pow(level, 2) - 162.5 * level + 2220); + return math.floor(4.5 * math.pow(level, 2) - 162.5 * level + 2220) end + return 0 end -function mcl_experience.xp_to_bar(xp, level) - local level = level or mcl_experience.xp_to_level(xp) - local xp_this_level = mcl_experience.level_to_xp(level) - local xp_next_level = mcl_experience.level_to_xp(level+1) - local bar_step = 36 / (xp_next_level-xp_this_level) - local bar = (xp-xp_this_level) * bar_step - return bar, bar_step, xp_next_level +local function calculate_bounds(level) + return level_to_xp(level), level_to_xp(level + 1) end -function mcl_experience.bar_to_xp(bar, level) - local xp_this_level = mcl_experience.level_to_xp(level) - local xp_next_level = mcl_experience.level_to_xp(level+1) - local bar_step = 36 / (xp_next_level-xp_this_level) - local xp = xp_this_level + math.floor(bar/36*(xp_next_level-xp_this_level)) - return xp, bar_step, xp_next_level +local function xp_to_bar(xp, level) + local xp_min, xp_max = calculate_bounds(level) + + return (xp - xp_min) / (xp_max - xp_min) end -function mcl_experience.add_experience(player, experience) - local name = player:get_player_name() - local temp_pool = pool[name] +local function bar_to_xp(bar, level) + local xp_min, xp_max = calculate_bounds(level) - local old_bar, old_xp, old_level = temp_pool.bar, temp_pool.xp, temp_pool.level - temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp) + return xp_min + bar * (xp_max - xp_min) +end - if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then - temp_pool.bar = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) - else - temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp) - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) - end +local function get_time() + return minetest.get_us_time() / 1000000 +end - if old_bar ~= temp_pool.bar then - hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "text", data = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270",}) - end +-- api - if experience > 0 and minetest.get_us_time()/1000000 - temp_pool.last_time > 0.01 then - if old_level ~= temp_pool.level then - minetest.sound_play("level_up",{gain=0.2,to_player = name}) - temp_pool.last_time = minetest.get_us_time()/1000000 + 0.2 - else - minetest.sound_play("experience",{gain=0.1,to_player = name,pitch=math.random(75,99)/100}) - temp_pool.last_time = minetest.get_us_time()/1000000 - end - end +function mcl_experience.get_level(player) + return caches[player].level +end - if old_level ~= temp_pool.level then - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)}) +function mcl_experience.set_level(player, level) + local cache = caches[player] + + if level ~= cache.level then + mcl_experience.set_xp(player, math.floor(bar_to_xp(xp_to_bar(mcl_experience.get_xp(player), cache.level), level))) end end ---reset player level -local name -local temp_pool -local xp_amount -minetest.register_on_dieplayer(function(player) - if minetest.settings:get_bool("mcl_keepInventory", false) then - return - end +function mcl_experience.get_xp(player) + return player:get_meta():get_int("xp") +end - name = player:get_player_name() - temp_pool = pool[name] - xp_amount = temp_pool.xp +function mcl_experience.set_xp(player, xp) + player:get_meta():set_int("xp", xp) - temp_pool.xp = 0 - temp_pool.level = 0 - temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level) + mcl_experience.update(player) +end - hud_manager.change_hud({player = player, hud_name = "xp_level", element = "text", data = tostring(temp_pool.level)}) - hud_manager.change_hud({player = player, hud_name = "experience_bar", element = "text", data = "experience_bar_background.png^[lowpart:" .. math.floor(temp_pool.bar / 36 * 100) .. ":experience_bar.png^[transformR270",}) +function mcl_experience.add_xp(player, xp) + for _, cb in ipairs(mcl_experience.on_add_xp) do + xp = cb.func(player, xp) or xp - mcl_experience.throw_experience(player:get_pos(), xp_amount) -end) - - -local name -local collector, pos, pos2 -local direction, distance, player_velocity, goal -local currentvel, acceleration, multiplier, velocity -local node, vel, def -local is_moving, is_slippery, slippery, slip_factor -local size, data -local function xp_step(self, dtime) - --if item set to be collected then only execute go to player - if self.collected == true then - if not self.collector then - self.collected = false - return - end - collector = minetest.get_player_by_name(self.collector) - if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then - self.object:set_acceleration(vector.new(0,0,0)) - self.disable_physics(self) - --get the variables - pos = self.object:get_pos() - pos2 = collector:get_pos() - - player_velocity = collector:get_velocity() or collector:get_player_velocity() - - pos2.y = pos2.y + 0.8 - - direction = vector.direction(pos,pos2) - distance = vector.distance(pos2,pos) - multiplier = distance - if multiplier < 1 then - multiplier = 1 - end - goal = vector.multiply(direction,multiplier) - currentvel = self.object:get_velocity() - - if distance > 1 then - multiplier = 20 - distance - velocity = vector.multiply(direction,multiplier) - goal = velocity - acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) - self.object:add_velocity(vector.add(acceleration,player_velocity)) - elseif distance < 0.8 then - local xp = self._xp - local inv = collector:get_inventory() - local candidates = { - {list = "main", index = collector:get_wield_index()}, - {list = "armor", index = 2}, - {list = "armor", index = 3}, - {list = "armor", index = 4}, - {list = "armor", index = 5}, - } - local final_candidates = {} - for _, can in ipairs(candidates) do - local stack = inv:get_stack(can.list, can.index) - local wear = stack:get_wear() - if mcl_enchanting.has_enchantment(stack, "mending") and wear > 0 then - can.stack = stack - can.wear = wear - table.insert(final_candidates, can) - end - end - if #final_candidates > 0 then - local can = final_candidates[math.random(#final_candidates)] - local stack, list, index, wear = can.stack, can.list, can.index, can.wear - local unbreaking_level = mcl_enchanting.get_enchantment(stack, "unbreaking") - local uses - local armor_uses = minetest.get_item_group(stack:get_name(), "mcl_armor_uses") - if armor_uses > 0 then - uses = armor_uses - if unbreaking_level > 0 then - uses = uses / (0.6 + 0.4 / (unbreaking_level + 1)) - end - else - local def = stack:get_definition() - if def then - local fixed_uses = def._mcl_uses - if fixed_uses then - uses = fixed_uses - if unbreaking_level > 0 then - uses = uses * (unbreaking_level + 1) - end - end - end - if not uses then - local toolcaps = stack:get_tool_capabilities() - local groupcaps = toolcaps.groupcaps - for _, v in pairs(groupcaps) do - uses = v.uses - break - end - end - end - uses = uses or 0 - local multiplier = 2 * 65535 / uses - local repair = xp * multiplier - local new_wear = wear - repair - if new_wear < 0 then - xp = math.floor(-new_wear / multiplier + 0.5) - new_wear = 0 - else - xp = 0 - end - stack:set_wear(math.floor(new_wear)) - inv:set_stack(list, index, stack) - if can.list == "armor" then - local armor_inv = minetest.get_inventory({type = "detached", name = collector:get_player_name() .. "_armor"}) - armor_inv:set_stack(list, index, stack) - end - end - if xp > 0 then - mcl_experience.add_experience(collector, xp) - else - minetest.sound_play("experience",{gain=0.1,to_player = name,pitch=math.random(75,99)/100}) - end - self.object:remove() - end - return - else - self.collector = nil - self.enable_physics(self) + if xp == 0 then + break end end + local cache = caches[player] + local old_level = cache.level - self.age = self.age + dtime - if self.age > max_orb_age then - self.object:remove() - return - end + mcl_experience.set_xp(player, mcl_experience.get_xp(player) + xp) - pos = self.object:get_pos() + local current_time = get_time() - if pos then - node = minetest.get_node_or_nil({ - x = pos.x, - y = pos.y -0.25, - z = pos.z - }) - else - return - end + if current_time - cache.last_time > 0.01 then + local name = player:get_player_name() - -- Remove nodes in 'ignore' - if node and node.name == "ignore" then - self.object:remove() - return - end - - if not self.physical_state then - return -- Don't do anything - end - - -- Slide on slippery nodes - vel = self.object:get_velocity() - def = node and registered_nodes[node.name] - is_moving = (def and not def.walkable) or - vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 - is_slippery = false - - if def and def.walkable then - slippery = minetest.get_item_group(node.name, "slippery") - is_slippery = slippery ~= 0 - if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then - -- Horizontal deceleration - slip_factor = 4.0 / (slippery + 4) - self.object:set_acceleration({ - x = -vel.x * slip_factor, - y = 0, - z = -vel.z * slip_factor + if old_level == cache.level then + minetest.sound_play("mcl_experience", { + to_player = name, + gain = 0.1, + pitch = math.random(75, 99) / 100, }) - elseif vel.y == 0 then - is_moving = false + + cache.last_time = current_time + else + minetest.sound_play("mcl_experience_level_up", { + to_player = name, + gain = 0.2, + }) + + cache.last_time = current_time + 0.2 end end - - if self.moving_state == is_moving and self.slippery_state == is_slippery then - -- Do not update anything until the moving state changes - return - end - - self.moving_state = is_moving - self.slippery_state = is_slippery - - if is_moving then - self.object:set_acceleration(gravity) - else - self.object:set_acceleration({x = 0, y = 0, z = 0}) - self.object:set_velocity({x = 0, y = 0, z = 0}) - end end -minetest.register_entity("mcl_experience:orb", { - initial_properties = { - hp_max = 1, - physical = true, - collide_with_objects = false, - 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="experience_orb.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}}, - spritediv = {x = 1, y = 14}, - initial_sprite_basepos = {x = 0, y = 0}, - is_visible = true, - pointable = false, - static_save = false, - }, - moving_state = true, - slippery_state = false, - physical_state = true, - -- Item expiry - age = 0, - -- Pushing item out of solid nodes - force_out = nil, - force_out_start = nil, - --Collection Variables - collectable = false, - try_timer = 0, - collected = false, - delete_timer = 0, - radius = 4, - - - on_activate = function(self, staticdata, dtime_s) - self.object:set_velocity(vector.new( - math.random(-2,2)*math.random(), - math.random(2,5), - math.random(-2,2)*math.random() - )) - 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) - self._xp = xp - size = xp_to_size(xp) - self.object:set_properties({ - visual_size = {x = size, y = size}, - glow = 14, - }) - self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) - end, - - enable_physics = function(self) - if not self.physical_state then - self.physical_state = true - self.object:set_properties({physical = true}) - self.object:set_velocity({x=0, y=0, z=0}) - self.object:set_acceleration(gravity) - end - end, - - disable_physics = function(self) - if self.physical_state then - self.physical_state = false - self.object:set_properties({physical = false}) - self.object:set_velocity({x=0, y=0, z=0}) - self.object:set_acceleration({x=0, y=0, z=0}) - end - end, - on_step = function(self, dtime) - xp_step(self, dtime) - end, -}) - -minetest.register_chatcommand("xp", { - params = S("[[] ]"), - description = S("Gives a player some XP"), - privs = {server=true}, - func = function(name, params) - local player, xp = nil, 1000 - local P, i = {}, 0 - for str in string.gmatch(params, "([^ ]+)") do - i = i + 1 - P[i] = str - end - if i > 2 then - return false, S("Error: Too many parameters!") - end - if i > 0 then - xp = tonumber(P[i]) - end - if i < 2 then - player = minetest.get_player_by_name(name) - end - if i == 2 then - player = minetest.get_player_by_name(P[1]) - end - if not xp then - return false, S("Error: Incorrect value of XP") - end - if not player then - return false, S("Error: Player not found") - end - mcl_experience.add_experience(player, xp) - local playername = player:get_player_name() - minetest.chat_send_player(name, S("Added @1 XP to @2, total: @3, experience level: @4", tostring(xp), playername, tostring(pool[playername].xp), tostring(pool[playername].level))) - end, -}) - -function mcl_experience.throw_experience(pos, amount) +function mcl_experience.throw_xp(pos, total_xp) local i, j = 0, 0 - local obj, xp - while i < amount and j < 100 do - xp = math.min(math.random(1, math.min(32767, amount-math.floor(i/2))), amount-i) - obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) + local obs = {} + while i < total_xp and j < 100 do + local xp = math.min(math.random(1, math.min(32767, total_xp - math.floor(i / 2))), total_xp - i) + local obj = minetest.add_entity(pos, "mcl_experience:orb", tostring(xp)) + if not obj then return false end - obj:set_velocity({ - x=math.random(-2,2)*math.random(), - y=math.random(2,5), - z=math.random(-2,2)*math.random() - }) + + obj:set_velocity(vector.new( + math.random(-2, 2) * math.random(), + math.random( 2, 5), + math.random(-2, 2) * math.random() + )) + i = i + xp j = j + 1 + table.insert(obs,obj) + end + return obs +end + +function mcl_experience.remove_hud(player) + if hud_bars[player] then + player:hud_remove(hud_bars[player]) + hud_bars[player] = nil + end + if hud_levels[player] then + player:hud_remove(hud_levels[player]) + hud_levels[player] = nil end end -minetest.register_entity("mcl_experience:bottle",{ - textures = {"mcl_experience_bottle.png"}, - hp_max = 1, - visual_size = {x = 0.35, y = 0.35}, - collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1}, - pointable = false, - on_step = function(self, dtime) - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local n = node.name - if n ~= "air" and n ~= "mcl_portals:portal" and n ~= "mcl_portals:portal_end" and minetest.get_node_group(n, "liquid") == 0 then - minetest.sound_play("mcl_potions_breaking_glass", {pos = pos, max_hear_distance = 16, gain = 1}) - mcl_experience.throw_experience(pos, math.random(3, 11)) - self.object:remove() - end - end, -}) +function mcl_experience.setup_hud(player) + if hud_bars[player] and hud_levels[player] then return end + mcl_experience.remove_hud(player) + caches[player] = { + last_time = get_time(), + } -local function throw_xp_bottle(pos, dir, velocity) - 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 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}, + z_index = 11, + }) + + hud_levels[player] = player:hud_add({ + hud_elem_type = "text", + position = {x = 0.5, y = 1}, + number = 0x80FF20, + offset = {x = 0, y = -(48 + 24 + 24)}, + z_index = 12, + }) + end end -minetest.register_craftitem("mcl_experience:bottle", { - description = "Bottle o' Enchanting", - inventory_image = "mcl_experience_bottle.png", - 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) - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() +function mcl_experience.update(player) + local xp = mcl_experience.get_xp(player) + local cache = caches[player] + + cache.level = xp_to_level(xp) + + if not minetest.is_creative_enabled(player:get_player_name()) then + if not hud_bars[player] then + mcl_experience.setup_hud(player) + end + + player:hud_change(hud_bars[player], "text", "(mcl_experience_bar_background.png^[lowpart:" + .. math.floor(math.floor(xp_to_bar(xp, cache.level) * 18) / 18 * 100) + .. ":mcl_experience_bar.png)^[resize:40x1456^[transformR270" + ) + + if cache.level == 0 then + player:hud_change(hud_levels[player], "text", "") + else + player:hud_change(hud_levels[player], "text", tostring(cache.level)) end - return itemstack - end, - _on_dispense = function(_, pos, _, _, dir) - throw_xp_bottle(vector.add(pos, vector.multiply(dir, 0.51)), dir, 10) end -}) +end + +function mcl_experience.register_on_add_xp(func, priority) + table.insert(mcl_experience.on_add_xp, {func = func, priority = priority or 0}) +end + +-- callbacks + +minetest.register_on_joinplayer(function(player) + mcl_experience.setup_hud(player) + mcl_experience.update(player) +end) + +minetest.register_on_leaveplayer(function(player) + hud_bars[player] = nil + hud_levels[player] = nil + caches[player] = nil +end) + +minetest.register_on_dieplayer(function(player) + if not minetest.settings:get_bool("mcl_keepInventory", false) then + mcl_experience.throw_xp(player:get_pos(), mcl_experience.get_xp(player)) + mcl_experience.set_xp(player, 0) + end +end) + +minetest.register_on_mods_loaded(function() + table.sort(mcl_experience.on_add_xp, function(a, b) return a.priority < b.priority end) +end) diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr b/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr new file mode 100644 index 000000000..07e4234d1 --- /dev/null +++ b/mods/HUD/mcl_experience/locale/mcl_experience.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_experience +[[] ]=[[<プレイヤー>] ] +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=@2に @1 XPを追加、合計:@3、 XPレベル:@4 diff --git a/mods/HUD/mcl_experience/locale/mcl_experience.pl.tr b/mods/HUD/mcl_experience/locale/mcl_experience.pl.tr new file mode 100644 index 000000000..5834bac14 --- /dev/null +++ b/mods/HUD/mcl_experience/locale/mcl_experience.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_experience +[[] ]=[[] ] ]=[[<玩家名字>] <經驗值>] +Gives a player some XP=給予玩家經驗值 +Error: Too many parameters!=錯誤:太多參數! +Error: Incorrect value of XP=錯誤:經驗值數值不當! +Error: Player not found=錯誤:找不到玩家! +Added @1 XP to @2, total: @3, experience level: @4=已給予 @2 @1 點經驗值,共有 @3 點,經驗等級:@4 diff --git a/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr b/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr index 0644e2596..faadca410 100644 --- a/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr +++ b/mods/HUD/mcl_experience/locale/mlc_experience.fr.tr @@ -5,3 +5,4 @@ Error: Too many parameters!=Erreur: Trop de paramètres! Error: Incorrect value of XP=Erreur: Valeur incorrecte de XP Error: Player not found=Erreur: Joueur introuvable Added @1 XP to @2, total: @3, experience level: @4=Ajout de @1 XP à @2, total: @3, niveau d'expérience: @4 +Bottle o' Enchanting=Fiole d'expérience diff --git a/mods/HUD/mcl_experience/locale/template.txt b/mods/HUD/mcl_experience/locale/template.txt index a355cbbac..b2a4c04d2 100644 --- a/mods/HUD/mcl_experience/locale/template.txt +++ b/mods/HUD/mcl_experience/locale/template.txt @@ -5,3 +5,4 @@ Error: Too many parameters!= Error: Incorrect value of XP= Error: Player not found= Added @1 XP to @2, total: @3, experience level: @4= +Bottle o' Enchanting= diff --git a/mods/HUD/mcl_experience/mod.conf b/mods/HUD/mcl_experience/mod.conf new file mode 100644 index 000000000..211249b30 --- /dev/null +++ b/mods/HUD/mcl_experience/mod.conf @@ -0,0 +1,3 @@ +name = mcl_experience +author = oilboi +description = eXPerience mod diff --git a/mods/HUD/mcl_experience/orb.lua b/mods/HUD/mcl_experience/orb.lua new file mode 100644 index 000000000..9aecce00d --- /dev/null +++ b/mods/HUD/mcl_experience/orb.lua @@ -0,0 +1,220 @@ +local size_min, size_max = 20, 59 +local delta_size = size_max - size_min + +local size_to_xp = { + {-32768, 2}, -- 1 + { 3, 6}, -- 2 + { 7, 16}, -- 3 + { 17, 36}, -- 4 + { 37, 72}, -- 5 + { 73, 148}, -- 6 + { 149, 306}, -- 7 + { 307, 616}, -- 8 + { 617, 1236}, -- 9 + { 1237, 2476}, -- 10 + { 2477, 32767} -- 11 +} + +local function xp_to_size(xp) + local i, l = 1, #size_to_xp + + while xp > size_to_xp[i][1] and i < l do + i = i + 1 + end + + return ((i - 1) / (l - 1) * delta_size + size_min) / 100 +end + +local max_orb_age = 300 -- seconds +local gravity = vector.new(0, -((tonumber(minetest.settings:get("movement_gravity"))) or 9.81), 0) + +local collector, pos, pos2 +local direction, distance, player_velocity, goal +local currentvel, acceleration, multiplier, velocity +local node, vel, def +local is_moving, is_slippery, slippery, slip_factor +local size +local function xp_step(self, dtime) + --if item set to be collected then only execute go to player + if self.collected == true then + if not self.collector then + self.collected = false + return + end + collector = minetest.get_player_by_name(self.collector) + if collector and collector:get_hp() > 0 and vector.distance(self.object:get_pos(),collector:get_pos()) < 7.25 then + self.object:set_acceleration(vector.new(0,0,0)) + self.disable_physics(self) + --get the variables + pos = self.object:get_pos() + pos2 = collector:get_pos() + + player_velocity = collector:get_velocity() or collector:get_player_velocity() + + pos2.y = pos2.y + 0.8 + + direction = vector.direction(pos,pos2) + distance = vector.distance(pos2,pos) + multiplier = distance + if multiplier < 1 then + multiplier = 1 + end + goal = vector.multiply(direction,multiplier) + currentvel = self.object:get_velocity() + + if distance > 1 then + multiplier = 20 - distance + velocity = vector.multiply(direction,multiplier) + goal = velocity + acceleration = vector.new(goal.x-currentvel.x,goal.y-currentvel.y,goal.z-currentvel.z) + self.object:add_velocity(vector.add(acceleration,player_velocity)) + elseif distance < 0.8 then + mcl_experience.add_xp(collector, self._xp) + self.object:remove() + end + return + else + self.collector = nil + self.enable_physics(self) + end + end + + + self.age = self.age + dtime + if self.age > max_orb_age then + self.object:remove() + return + end + + pos = self.object:get_pos() + + if pos then + node = minetest.get_node_or_nil({ + x = pos.x, + y = pos.y -0.25, + z = pos.z + }) + else + return + end + + -- Remove nodes in 'ignore' + if node and node.name == "ignore" then + self.object:remove() + return + end + + if not self.physical_state then + return -- Don't do anything + end + + -- Slide on slippery nodes + vel = self.object:get_velocity() + def = node and minetest.registered_nodes[node.name] + is_moving = (def and not def.walkable) or + vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0 + is_slippery = false + + if def and def.walkable then + slippery = minetest.get_item_group(node.name, "slippery") + is_slippery = slippery ~= 0 + if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then + -- Horizontal deceleration + slip_factor = 4.0 / (slippery + 4) + self.object:set_acceleration({ + x = -vel.x * slip_factor, + y = 0, + z = -vel.z * slip_factor + }) + elseif vel.y == 0 then + is_moving = false + end + end + + if self.moving_state == is_moving and self.slippery_state == is_slippery then + -- Do not update anything until the moving state changes + return + end + + self.moving_state = is_moving + self.slippery_state = is_slippery + + if is_moving then + self.object:set_acceleration(gravity) + else + self.object:set_acceleration({x = 0, y = 0, z = 0}) + self.object:set_velocity({x = 0, y = 0, z = 0}) + end +end + +minetest.register_entity("mcl_experience:orb", { + initial_properties = { + hp_max = 1, + physical = true, + collide_with_objects = false, + 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}}, + spritediv = {x = 1, y = 14}, + initial_sprite_basepos = {x = 0, y = 0}, + is_visible = true, + pointable = false, + static_save = false, + }, + moving_state = true, + slippery_state = false, + physical_state = true, + -- Item expiry + age = 0, + -- Pushing item out of solid nodes + force_out = nil, + force_out_start = nil, + --Collection Variables + collectable = false, + try_timer = 0, + collected = false, + delete_timer = 0, + radius = 4, + + + on_activate = function(self, staticdata, dtime_s) + self.object:set_velocity(vector.new( + math.random(-2,2)*math.random(), + math.random(2,5), + math.random(-2,2)*math.random() + )) + 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) + self._xp = xp + size = xp_to_size(xp) + self.object:set_properties({ + visual_size = {x = size, y = size}, + glow = 14, + }) + self.object:set_sprite({x=1,y=math.random(1,14)}, 14, 0.05, false) + end, + + enable_physics = function(self) + if not self.physical_state then + self.physical_state = true + self.object:set_properties({physical = true}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration(gravity) + end + end, + + disable_physics = function(self) + if self.physical_state then + self.physical_state = false + self.object:set_properties({physical = false}) + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + end + end, + on_step = function(self, dtime) + xp_step(self, dtime) + end, +}) diff --git a/mods/HUD/mcl_experience/sounds/experience.ogg b/mods/HUD/mcl_experience/sounds/mcl_experience.ogg similarity index 100% rename from mods/HUD/mcl_experience/sounds/experience.ogg rename to mods/HUD/mcl_experience/sounds/mcl_experience.ogg diff --git a/mods/HUD/mcl_experience/sounds/level_up.ogg b/mods/HUD/mcl_experience/sounds/mcl_experience_level_up.ogg similarity index 100% rename from mods/HUD/mcl_experience/sounds/level_up.ogg rename to mods/HUD/mcl_experience/sounds/mcl_experience_level_up.ogg diff --git a/mods/HUD/mcl_experience/textures/attributes.txt b/mods/HUD/mcl_experience/textures/attributes.txt deleted file mode 100644 index 892455baa..000000000 --- a/mods/HUD/mcl_experience/textures/attributes.txt +++ /dev/null @@ -1 +0,0 @@ -experience_orb - https://github.com/Gerold55/Experience-Mod/blob/master/textures/orb.png \ No newline at end of file diff --git a/mods/HUD/mcl_experience/textures/experience_bar.png b/mods/HUD/mcl_experience/textures/experience_bar.png deleted file mode 100644 index 19a2c029d..000000000 Binary files a/mods/HUD/mcl_experience/textures/experience_bar.png and /dev/null differ diff --git a/mods/HUD/mcl_experience/textures/experience_bar_background.png b/mods/HUD/mcl_experience/textures/experience_bar_background.png deleted file mode 100644 index f28a0e0dd..000000000 Binary files a/mods/HUD/mcl_experience/textures/experience_bar_background.png and /dev/null differ diff --git a/mods/HUD/mcl_experience/textures/experience_orb.png b/mods/HUD/mcl_experience/textures/experience_orb.png deleted file mode 100644 index 4d553833c..000000000 Binary files a/mods/HUD/mcl_experience/textures/experience_orb.png and /dev/null differ diff --git a/mods/HUD/mcl_experience/textures/mcl_experience_bottle.png b/mods/HUD/mcl_experience/textures/mcl_experience_bottle.png deleted file mode 100644 index 51b6e3406..000000000 Binary files a/mods/HUD/mcl_experience/textures/mcl_experience_bottle.png and /dev/null differ diff --git a/mods/HUD/mcl_formspec/mod.conf b/mods/HUD/mcl_formspec/mod.conf index 9d614403f..8bc1ca7c3 100644 --- a/mods/HUD/mcl_formspec/mod.conf +++ b/mods/HUD/mcl_formspec/mod.conf @@ -1 +1,3 @@ +name = mcl_formspec +author = Wuzzy description = Helper mod to simplify creation of formspecs a little bit diff --git a/mods/HUD/mcl_formspec/textures/mcl_formspec_itemslot.png b/mods/HUD/mcl_formspec/textures/mcl_formspec_itemslot.png deleted file mode 100644 index 84958ecd4..000000000 Binary files a/mods/HUD/mcl_formspec/textures/mcl_formspec_itemslot.png and /dev/null differ diff --git a/mods/HUD/mcl_formspec_prepend/depends.txt b/mods/HUD/mcl_formspec_prepend/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/HUD/mcl_formspec_prepend/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/HUD/mcl_formspec_prepend/mod.conf b/mods/HUD/mcl_formspec_prepend/mod.conf index c576d4493..544ab4ec7 100644 --- a/mods/HUD/mcl_formspec_prepend/mod.conf +++ b/mods/HUD/mcl_formspec_prepend/mod.conf @@ -1 +1,4 @@ name = mcl_formspec_prepend +author = Wuzzy +description = Formspec prepend for MCL2 +depends = mcl_init diff --git a/mods/HUD/mcl_hbarmor/description.txt b/mods/HUD/mcl_hbarmor/description.txt deleted file mode 100644 index 02a8a34f9..000000000 --- a/mods/HUD/mcl_hbarmor/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a HUD bar displaying the current damage of the player's armor. diff --git a/mods/HUD/mcl_hbarmor/init.lua b/mods/HUD/mcl_hbarmor/init.lua index 57978359c..34ac205ac 100644 --- a/mods/HUD/mcl_hbarmor/init.lua +++ b/mods/HUD/mcl_hbarmor/init.lua @@ -1,35 +1,34 @@ -local S = minetest.get_translator("mcl_hbarmor") +local S = minetest.get_translator(minetest.get_current_modname()) -if (not armor) or (not armor.def) then - minetest.log("error", "[mcl_hbarmor] Outdated mcl_armor version. Please update your version of mcl_armor!") -end +local math = math +local tonumber = tonumber -local mcl_hbarmor = {} +local get_connected_players = minetest.get_connected_players --- HUD statbar values -mcl_hbarmor.armor = {} +local mcl_hbarmor = { + -- HUD statbar values + armor = {}, + -- Stores if player's HUD bar has been initialized so far. + player_active = {}, + -- Time difference in seconds between updates to the HUD armor bar. + -- Increase this number for slow servers. + tick = 0.1, + -- If true, the armor bar is hidden when the player does not wear any armor + autohide = true, +} --- Stores if player's HUD bar has been initialized so far. -mcl_hbarmor.player_active = {} +local tick_config = minetest.settings:get("mcl_hbarmor_tick") --- Time difference in seconds between updates to the HUD armor bar. --- Increase this number for slow servers. -mcl_hbarmor.tick = 0.1 - --- If true, the armor bar is hidden when the player does not wear any armor -mcl_hbarmor.autohide = true - -set = minetest.settings:get("mcl_hbarmor_tick") -if tonumber(set) ~= nil then - mcl_hbarmor.tick = tonumber(set) +if tonumber(tick_config) then + mcl_hbarmor.tick = tonumber(tick_config) end -local must_hide = function(playername, arm) +local function must_hide(playername, arm) return arm == 0 end -local arm_printable = function(arm) +local function arm_printable(arm) return math.ceil(math.floor(arm+0.5)) end @@ -57,14 +56,11 @@ local function custom_hud(player) end --register and define armor HUD bar -hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 20, mcl_hbarmor.autohide) +hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide) function mcl_hbarmor.get_armor(player) - if not player or not armor.def then - return false - end local name = player:get_player_name() - local pts = armor:get_armor_points(player) + local pts = player:get_meta():get_int("mcl_armor:armor_points") if not pts then return false else @@ -113,12 +109,13 @@ end) local main_timer = 0 local timer = 0 minetest.register_globalstep(function(dtime) + --TODO: replace this by playerglobalstep API then implemented main_timer = main_timer + dtime timer = timer + dtime if main_timer > mcl_hbarmor.tick or timer > 4 then if minetest.settings:get_bool("enable_damage") then if main_timer > mcl_hbarmor.tick then main_timer = 0 end - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(get_connected_players()) do local name = player:get_player_name() if mcl_hbarmor.player_active[name] == true then local ret = mcl_hbarmor.get_armor(player) diff --git a/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr b/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr new file mode 100644 index 000000000..2d32381ae --- /dev/null +++ b/mods/HUD/mcl_hbarmor/locale/hbarmor.ja.tr @@ -0,0 +1,2 @@ +# textdomain:hbarmor +Armor=防具 diff --git a/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pl.tr b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pl.tr new file mode 100644 index 000000000..ff43d7e81 --- /dev/null +++ b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.pl.tr @@ -0,0 +1,3 @@ +# textdomain:hbarmor +Armor=Zbroja + diff --git a/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.zh_TW.tr b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.zh_TW.tr new file mode 100644 index 000000000..a0dc8174e --- /dev/null +++ b/mods/HUD/mcl_hbarmor/locale/mcl_hbarmor.zh_TW.tr @@ -0,0 +1,2 @@ +# textdomain:hbarmor +Armor=防禦點數 diff --git a/mods/HUD/mcl_hbarmor/mod.conf b/mods/HUD/mcl_hbarmor/mod.conf index de5a2f20a..258395875 100644 --- a/mods/HUD/mcl_hbarmor/mod.conf +++ b/mods/HUD/mcl_hbarmor/mod.conf @@ -1,2 +1,4 @@ name = mcl_hbarmor +author = BlockMen +description = Adds a HUD bar displaying the current damage of the player's armor. depends = hudbars, mcl_armor diff --git a/mods/HUD/mcl_hbarmor/textures/hbarmor_bar.png b/mods/HUD/mcl_hbarmor/textures/hbarmor_bar.png deleted file mode 100644 index ce0aa78ec..000000000 Binary files a/mods/HUD/mcl_hbarmor/textures/hbarmor_bar.png and /dev/null differ diff --git a/mods/HUD/mcl_hbarmor/textures/hbarmor_bgicon.png b/mods/HUD/mcl_hbarmor/textures/hbarmor_bgicon.png deleted file mode 100644 index 86e68e403..000000000 Binary files a/mods/HUD/mcl_hbarmor/textures/hbarmor_bgicon.png and /dev/null differ diff --git a/mods/HUD/mcl_hbarmor/textures/hbarmor_icon.png b/mods/HUD/mcl_hbarmor/textures/hbarmor_icon.png deleted file mode 100644 index e0066a387..000000000 Binary files a/mods/HUD/mcl_hbarmor/textures/hbarmor_icon.png and /dev/null differ diff --git a/mods/HUD/mcl_info/API.md b/mods/HUD/mcl_info/API.md new file mode 100644 index 000000000..18c901162 --- /dev/null +++ b/mods/HUD/mcl_info/API.md @@ -0,0 +1,18 @@ +## mcl_info +An api to make custom entries in the mcl2 debug hud. + +### mcl_info.register_debug_field(name,defintion) +Debug field defintion example: +{ + level = 3, + --show with debug level 3 and upwards + + func = function(player,pos) return minetest.pos_to_string(pos) end, + -- Function that is run for at each debug + -- sample (default: every .63 seconds) + -- It should output a string and determines + -- the content of the debug field. +} + +### mcl_info.registered_debug_fields +Table the debug definitions are stored in. Do not modify this directly. If you need to overwrite a field just set it again with mcl_info.register_debug_field(). diff --git a/mods/HUD/mcl_info/init.lua b/mods/HUD/mcl_info/init.lua new file mode 100644 index 000000000..b6f69255c --- /dev/null +++ b/mods/HUD/mcl_info/init.lua @@ -0,0 +1,204 @@ +mcl_info = {} +local format, pairs,ipairs,table,vector,minetest,mcl_info,tonumber,tostring = string.format,pairs,ipairs,table,vector,minetest,mcl_info,tonumber,tostring + +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local storage = minetest.get_mod_storage() +local player_dbg = {} + +local refresh_interval = .63 +local huds = {} +local default_debug = 0 + +local function check_setting(s) + return s +end + +--return player setting, set it to 2nd argument if supplied +local function player_setting(p,s) + local name = p:get_player_name() + if check_setting(s) then + p:get_meta():set_string("mcl_info_show",s) + player_dbg[name] = tonumber(s) + end + if not player_dbg[name] then + local r = p:get_meta():get_string("mcl_info_show") + if r == nil or r == "" then r = 0 end + player_dbg[name] = tonumber(r) + end + return player_dbg[name] +end + +mcl_info.registered_debug_fields = {} +local fields_keyset = {} +function mcl_info.register_debug_field(name,def) + table.insert(fields_keyset,name) + mcl_info.registered_debug_fields[name]=def +end + +local function nodeinfo(pos) + local n = minetest.get_node_or_nil(pos) + if not n then return "" end + local l = minetest.get_node_light(pos) + local ld = minetest.get_node_light(pos,0.5) + local r = n.name .. " p1:"..n.param1.." p2:"..n.param2 + if l and ld then + r = r .. " Light: "..l.."/"..ld + end + return r +end + +local function get_text(player, bits) + local pos = vector.offset(player:get_pos(),0,0.5,0) + local bits = bits + if bits == -1 then return "" end + + local r = "" + for _,key in ipairs(fields_keyset) do + local def = mcl_info.registered_debug_fields[key] + if def then + if def.level == nil or def.level <= bits then + r = r ..key..": "..tostring(def.func(player,pos)).."\n" + end + else + r = r ..key..": \n" + end + end + return r +end + +local function info() + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local s = player_setting(player) + local pos = player:get_pos() + local text = get_text(player, s) + local hud = huds[name] + if s and not hud then + local def = { + hud_elem_type = "text", + alignment = {x = 1, y = -1}, + scale = {x = 100, y = 100}, + position = {x = 0.0073, y = 0.889}, + text = text, + style = 5, + ["number"] = 0xcccac0, + z_index = 0, + } + local def_bg = table.copy(def) + def_bg.offset = {x = 2, y = 1} + def_bg["number"] = 0 + def_bg.z_index = -1 + huds[name] = { + player:hud_add(def), + player:hud_add(def_bg), + text, + } + elseif text ~= hud[3] then + hud[3] = text + player:hud_change(huds[name][1], "text", text) + player:hud_change(huds[name][2], "text", text) + end + end + minetest.after(refresh_interval, info) +end +minetest.after(0,info) + +minetest.register_on_leaveplayer(function(p) + local name = p:get_player_name() + huds[name] = nil + player_dbg[name] = nil +end) + +minetest.register_chatcommand("debug",{ + description = S("Set debug bit mask: 0 = disable, 1 = player coords, 2 = coordinates, 3 = biome name, 4 = all"), + params = S(""), + privs = { debug = true }, + func = function(name, params) + local player = minetest.get_player_by_name(name) + if params == "" then return true, "Debug bitmask is "..player_setting(player) end + local dbg = math.floor(tonumber(params) or default_debug) + if dbg < -1 or dbg > 4 then + minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", -1, 4)) + return false,"Current bitmask: "..player_setting(player) + end + return true, "Debug bit mask set to "..player_setting(player,dbg) + end +}) + +-- register normal user access to debug levels 1 and 0. +minetest.register_chatcommand("whereami", { + description = S("Set location bit mask: 0 = disable, 1 = coordinates"), + params = S(""), + -- privs = { }, + func = function(name, params) + local player = minetest.get_player_by_name(name) + if params == "" then + return true, "Location bitmask is " .. player_setting(player) + end + local loc_lev = math.floor(tonumber(params) or default_debug) + if loc_lev < 0 or loc_lev > 4 then + minetest.chat_send_player(name, S("Error! Possible values are integer numbers from @1 to @2", 0, 1)) + return false, "Current bitmask: " .. player_setting(player) + end + return true, "Location bit mask set to " .. player_setting(player, loc_lev) + end +}) + +mcl_info.register_debug_field("Node feet",{ + level = 4, + func = function(pl,pos) + return nodeinfo(pos) + end +}) +mcl_info.register_debug_field("Node below",{ + level = 4, + func = function(pl,pos) + return nodeinfo(vector.offset(pos,0,-1,0)) + end +}) +mcl_info.register_debug_field("Biome",{ + level = 3, + func = function(pl,pos) + local biome_data = minetest.get_biome_data(pos) + local biome = biome_data and minetest.get_biome_name(biome_data.biome) or "No biome" + if biome_data then + return format("%s (%s), Humidity: %.1f, Temperature: %.1f",biome, biome_data.biome, biome_data.humidity, biome_data.heat) + end + return "No biome" + end +}) + +mcl_info.register_debug_field("Coords", { + level = 2, + func = function(pl, pos) + return format("x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + end +}) + +mcl_info.register_debug_field("Location", { + level = 1, + func = function(pl, pos) + local report_y = 0 + -- overworld + if (pos.y >= mcl_vars.mg_overworld_min) and (pos.y <= mcl_vars.mg_overworld_max) then + return format("Overworld: x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + end + + -- nether + if (pos.y >= mcl_vars.mg_nether_min) and (pos.y <= mcl_vars.mg_nether_max) then + report_y = pos.y - mcl_vars.mg_nether_min + return format("Nether: x:%.1f y:%.1f z:%.1f", pos.x, report_y, pos.z) + end + + -- end + if (pos.y >= mcl_vars.mg_end_min) and (pos.y <= mcl_vars.mg_end_max) then + report_y = pos.y - mcl_vars.mg_end_min + return format("End: x:%.1f y:%.1f z:%.1f", pos.x, report_y, pos.z) + end + + -- outside of scoped bounds. + return format("Void: x:%.1f y:%.1f z:%.1f", pos.x, pos.y, pos.z) + + end +}) diff --git a/mods/HUD/mcl_info/locale/mcl_info.fr.tr b/mods/HUD/mcl_info/locale/mcl_info.fr.tr new file mode 100644 index 000000000..96fb2622e --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.fr.tr @@ -0,0 +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= +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.ja.tr b/mods/HUD/mcl_info/locale/mcl_info.ja.tr new file mode 100644 index 000000000..3b2f3966b --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=デバッグビットマスク設定:0 @= 無効, 1 @= バイオーム名, 2 @= 座標, 3 @= 全て +Error! Possible values are integer numbers from @1 to @2=エラー! 指定できる値は@1〜@2の整数値です。 +Debug bit mask set to @1=デバッグビットマスクを@1に設定 diff --git a/mods/HUD/mcl_info/locale/mcl_info.ru.tr b/mods/HUD/mcl_info/locale/mcl_info.ru.tr new file mode 100644 index 000000000..7f5b79fe1 --- /dev/null +++ b/mods/HUD/mcl_info/locale/mcl_info.ru.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all=Установка отладочной битовой маски: 0 @= отключить, 1 @= биом, 2 @= координаты, 3 @= всё +Error! Possible values are integer numbers from @1 to @2=Ошибка! Допустимые значения - целые числа от @1 до @2 +Debug bit mask set to @1=Отладочной битовой маске присвоено значение @1 diff --git a/mods/HUD/mcl_info/locale/template.txt b/mods/HUD/mcl_info/locale/template.txt new file mode 100644 index 000000000..1a0b70ebc --- /dev/null +++ b/mods/HUD/mcl_info/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_info +Set debug bit mask: 0 @= disable, 1 @= biome name, 2 @= coordinates, 3 @= all= +Error! Possible values are integer numbers from @1 to @2= +Debug bit mask set to @1= diff --git a/mods/HUD/mcl_info/mod.conf b/mods/HUD/mcl_info/mod.conf new file mode 100644 index 000000000..41fdfb0b5 --- /dev/null +++ b/mods/HUD/mcl_info/mod.conf @@ -0,0 +1,3 @@ +name = mcl_info +description = Prints biome name and player position +depends = mcl_init diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index f762b9d66..32bb226f0 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -1,687 +1,637 @@ -local S = minetest.get_translator("mcl_inventory") -local F = minetest.formspec_escape - --- Prepare player info table -local players = {} - --- Containing all the items for each Creative Mode tab -local inventory_lists = {} - -local show_armor = minetest.get_modpath("mcl_armor") ~= nil -local mod_player = minetest.get_modpath("mcl_player") ~= nil - --- Create tables -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 - -local function replace_enchanted_books(tbl) - for k, item in ipairs(tbl) do - if item:find("mcl_enchanting:book_enchanted") == 1 then - local _, enchantment, level = item:match("(%a+) ([_%w]+) (%d+)") - level = level and tonumber(level) - if enchantment and level then - tbl[k] = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), enchantment, level) - end - end - end -end - ---[[ Populate all the item tables. We only do this once. Note this mod must be -loaded after _mcl_autogroup for this to work, because it required certain -groups to be set. ]] -do - 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 - local is_redstone = function(def) - return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off - end - local is_tool = function(def) - return def.groups.tool or (def.tool_capabilities ~= nil and def.tool_capabilities.damage_groups == nil) - end - local is_weapon_or_armor = function(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) - end - -- Is set to true if it was added in any category besides misc - local nonmisc = false - if def.groups.building_block then - table.insert(inventory_lists["blocks"], name) - nonmisc = true - end - if def.groups.deco_block then - table.insert(inventory_lists["deco"], name) - nonmisc = true - end - if is_redstone(def) then - table.insert(inventory_lists["redstone"], name) - nonmisc = true - end - if def.groups.transport then - table.insert(inventory_lists["rail"], name) - nonmisc = true - end - if (def.groups.food and not def.groups.brewitem) or def.groups.eatable then - table.insert(inventory_lists["food"], name) - nonmisc = true - end - if is_tool(def) then - table.insert(inventory_lists["tools"], name) - nonmisc = true - end - if is_weapon_or_armor(def) then - table.insert(inventory_lists["combat"], name) - nonmisc = true - end - if def.groups.spawn_egg == 1 then - table.insert(inventory_lists["mobs"], name) - nonmisc = true - end - if def.groups.brewitem then - table.insert(inventory_lists["brew"], name) - nonmisc = true - end - if def.groups.craftitem then - table.insert(inventory_lists["matr"], name) - nonmisc = true - end - -- Misc. category is for everything which is not in any other category - if not nonmisc then - table.insert(inventory_lists["misc"], name) - end - - table.insert(inventory_lists["all"], name) - 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 - table.insert(inventory_lists["tools"], str) - end - if def.inv_combat_tab then - table.insert(inventory_lists["combat"], str) - end - table.insert(inventory_lists["all"], str) - end - - for _, to_sort in pairs(inventory_lists) do - table.sort(to_sort) - replace_enchanted_books(to_sort) - end -end - -local function filter_item(name, description, lang, filter) - local desc - if not lang then - desc = string.lower(description) - else - desc = string.lower(minetest.get_translated_string(lang, description)) - end - return string.find(name, filter) or string.find(desc, filter) -end - -local function set_inv_search(filter, player) - local playername = player:get_player_name() - 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 - if filter_item(string.lower(def.name), def.description, lang, filter) then - table.insert(creative_list, name) - end - end - end - for ench, def in pairs(mcl_enchanting.enchantments) do - for i = 1, def.max_level do - local stack = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), ench, i) - if filter_item("mcl_enchanting:book_enchanted", minetest.strip_colors(stack:get_description()), lang, filter) then - table.insert(creative_list, "mcl_enchanting:book_enchanted " .. ench .. " " .. i) - end - end - end - table.sort(creative_list) - replace_enchanted_books(creative_list) - - inv:set_size("main", #creative_list) - inv:set_list("main", creative_list) -end - -local function set_inv_page(page, player) - local playername = player:get_player_name() - 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 - creative_list = inventory_lists[page] - end - inv:set_size("main", #creative_list) - inv:set_list("main", creative_list) -end - -local function init(player) - local playername = player:get_player_name() - local inv = 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 - return count - else - return 0 - end - end, - allow_put = function(inv, listname, index, stack, player) - return 0 - end, - allow_take = function(inv, listname, index, stack, player) - if minetest.is_creative_enabled(player:get_player_name()) then - return -1 - else - return 0 - end - end, - }, playername) - set_inv_page("all", player) -end - --- Create the trash field -local trash = minetest.create_detached_inventory("trash", { - allow_put = function(inv, listname, index, stack, player) - if minetest.is_creative_enabled(player:get_player_name()) then - return stack:get_count() - else - return 0 - end - end, - on_put = function(inv, listname, index, stack, player) - 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 = {} - -local noffset_x_start = -0.24 -local noffset_x = noffset_x_start -local noffset_y = -0.25 -local next_noffset = function(id, right) - if right then - noffset[id] = { 8.94, noffset_y } - else - noffset[id] = { noffset_x, noffset_y } - noffset_x = noffset_x + 1.25 - end -end - --- Upper row -next_noffset("blocks") -next_noffset("deco") -next_noffset("redstone") -next_noffset("rail") -next_noffset("brew") -next_noffset("misc") -next_noffset("nix", true) - -noffset_x = noffset_x_start -noffset_y = 8.12 - --- Lower row -next_noffset("food") -next_noffset("tools") -next_noffset("combat") -next_noffset("mobs") -next_noffset("matr") -next_noffset("inv", true) - -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) -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" - -filtername = {} -filtername["blocks"] = S("Building Blocks") -filtername["deco"] = S("Decoration Blocks") -filtername["redstone"] = S("Redstone") -filtername["rail"] = S("Transportation") -filtername["misc"] = S("Miscellaneous") -filtername["nix"] = S("Search Items") -filtername["food"] = S("Foodstuffs") -filtername["tools"] = S("Tools") -filtername["combat"] = S("Combat") -filtername["mobs"] = S("Mobs") -filtername["brew"] = S("Brewing") -filtername["matr"] = S("Materials") -filtername["inv"] = S("Survival Inventory") - -local dark_bg = "crafting_creative_bg_dark.png" - -local function reset_menu_item_bg() - bg["blocks"] = dark_bg - bg["deco"] = dark_bg - bg["redstone"] = dark_bg - bg["rail"] = dark_bg - bg["misc"] = dark_bg - bg["nix"] = dark_bg - bg["food"] = dark_bg - bg["tools"] = dark_bg - bg["combat"] = dark_bg - bg["mobs"] = dark_bg - bg["brew"] = dark_bg - bg["matr"] = dark_bg - bg["inv"] = dark_bg - bg["default"] = dark_bg -end - - -mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_size, show, page, filter) - reset_menu_item_bg() - pagenum = math.floor(pagenum) or 1 - - local playername = player:get_player_name() - - 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 ~= nil 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 formspec = "" - local main_list - local listrings = "listring[detached:creative_"..playername..";main]".. - "listring[current_player;main]".. - "listring[detached:trash;main]" - - if page ~= nil then - name = page - if players[playername] then - players[playername].page = page - end - end - bg[name] = "crafting_creative_bg.png" - - local inv_bg = "crafting_inventory_creative.png" - if name == "inv" then - inv_bg = "crafting_inventory_creative_survival.png" - - -- Show armor and player image - local img, img_player - if mod_player then - img_player = mcl_player.player_get_preview(player) - else - img_player = "player.png" - end - img = img_player - local player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]" - if show_armor and armor.textures[playername] and armor.textures[playername].preview then - img = armor.textures[playername].preview - local s1 = img:find("character_preview") - if s1 ~= nil then - s1 = img:sub(s1+21) - img = img_player..s1 - end - player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]" - end - - -- 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]" - 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]" - 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]" - 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]" - end - - -- 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).. - -- armor - "list[detached:"..playername.."_armor;armor;2.5,1.3;1,1;1]".. - "list[detached:"..playername.."_armor;armor;2.5,2.75;1,1;2]".. - "list[detached:"..playername.."_armor;armor;5.5,1.3;1,1;3]".. - "list[detached:"..playername.."_armor;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).. - armor_slot_imgs.. - -- player preview - player_preview.. - -- crafting guide button - "image_button[9,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")).."]".. - -- skins button - "image_button[9,3;1,1;mcl_skins_button.png;__mcl_skins;]".. - "tooltip[__mcl_skins;"..F(S("Select player skin")).."]".. - -- achievements button - "image_button[9,4;1,1;mcl_achievements_button.png;__mcl_achievements;]".. - --"style_type[image_button;border=;bgimg=;bgimg_pressed=]".. - "tooltip[__mcl_achievements;"..F(S("Achievements")).."]" - - -- For shortcuts - listrings = listrings .. - "listring[detached:"..playername.."_armor;armor]".. - "listring[current_player;main]" - else - -- 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;]" - 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", - } - 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" - else - bg_img = "crafting_creative_inactive"..hoch[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 .. "]" .. - "image[" .. boffset[this_tab] .. ";1,1;crafting_creative_marker.png]" - end - local caption = "" - if name ~= "inv" and filtername[name] then - caption = "label[0,1.2;"..F(minetest.colorize("#313131", filtername[name])).."]" - end - - 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.."]".. - tab(name, "blocks") .. - "tooltip[blocks;"..F(filtername["blocks"]).."]".. - tab(name, "deco") .. - "tooltip[deco;"..F(filtername["deco"]).."]".. - tab(name, "redstone") .. - "tooltip[redstone;"..F(filtername["redstone"]).."]".. - tab(name, "rail") .. - "tooltip[rail;"..F(filtername["rail"]).."]".. - tab(name, "misc") .. - "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") .. - "tooltip[tools;"..F(filtername["tools"]).."]".. - tab(name, "combat") .. - "tooltip[combat;"..F(filtername["combat"]).."]".. - tab(name, "mobs") .. - "tooltip[mobs;"..F(filtername["mobs"]).."]".. - tab(name, "brew") .. - "tooltip[brew;"..F(filtername["brew"]).."]".. - 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 - - if name == "nix" then - if filter == nil then - filter = "" - end - formspec = formspec .. "field[5.3,1.34;4,0.75;suche;;"..minetest.formspec_escape(filter).."]" - formspec = formspec .. "field_close_on_enter[suche;false]" - end - if pagenum ~= nil then formspec = formspec .. "p"..tostring(pagenum) end - - - player:set_inventory_formspec(formspec) -end - -minetest.register_on_player_receive_fields(function(player, formname, fields) - local page = nil - - if not minetest.is_creative_enabled(player:get_player_name()) then - return - end - if formname ~= "" or fields.quit == "true" then - -- No-op if formspec closed or not player inventory (formname == "") - return - end - - local name = player:get_player_name() - - if fields.blocks then - if players[name].page == "blocks" then return end - set_inv_page("blocks",player) - page = "blocks" - elseif fields.deco then - if players[name].page == "deco" then return end - set_inv_page("deco",player) - page = "deco" - elseif fields.redstone then - if players[name].page == "redstone" then return end - set_inv_page("redstone",player) - page = "redstone" - elseif fields.rail then - if players[name].page == "rail" then return end - set_inv_page("rail",player) - page = "rail" - elseif fields.misc then - if players[name].page == "misc" then return end - set_inv_page("misc",player) - page = "misc" - elseif fields.nix then - set_inv_page("all",player) - page = "nix" - elseif fields.food then - if players[name].page == "food" then return end - set_inv_page("food",player) - page = "food" - elseif fields.tools then - if players[name].page == "tools" then return end - set_inv_page("tools",player) - page = "tools" - elseif fields.combat then - if players[name].page == "combat" then return end - set_inv_page("combat",player) - page = "combat" - elseif fields.mobs then - if players[name].page == "mobs" then return end - set_inv_page("mobs",player) - page = "mobs" - elseif fields.brew then - if players[name].page == "brew" then return end - set_inv_page("brew",player) - page = "brew" - elseif fields.matr then - if players[name].page == "matr" then return end - set_inv_page("matr",player) - page = "matr" - elseif fields.inv then - if players[name].page == "inv" then return end - page = "inv" - elseif fields.suche == "" and not fields.creative_next and not fields.creative_prev then - set_inv_page("all", player) - page = "nix" - elseif fields.suche ~= nil and not fields.creative_next and not fields.creative_prev then - set_inv_search(string.lower(fields.suche),player) - page = "nix" - end - - if page then - players[name].page = page - end - if players[name].page then - page = players[name].page - end - - -- Figure out current scroll bar from formspec - local formspec = player:get_inventory_formspec() - - local start_i = players[name].start_i - - if fields.creative_prev then - start_i = start_i - 9*5 - elseif fields.creative_next then - 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 - end - - local inv_size - if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) - inv_size = inv:get_size("main") - elseif page ~= nil and page ~= "inv" then - inv_size = #(inventory_lists[page]) - else - inv_size = 0 - end - - if start_i >= inv_size then - start_i = start_i - 9*5 - end - if start_i < 0 or start_i >= inv_size then - start_i = 0 - end - players[name].start_i = start_i - - local filter = "" - if not fields.nix and fields.suche ~= nil and fields.suche ~= "" then - filter = fields.suche - players[name].filter = filter - end - - mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) -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 - end - 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 - - mcl_inventory.update_inventory_formspec = function(player) - local page = nil - - local name = player:get_player_name() - - if players[name].page then - page = players[name].page - else - page = "nix" - end - - -- Figure out current scroll bar from formspec - local formspec = player:get_inventory_formspec() - local start_i = players[name].start_i - - local inv_size - if page == "nix" then - local inv = minetest.get_inventory({type="detached", name="creative_"..name}) - inv_size = inv:get_size("main") - elseif page ~= nil and page ~= "inv" then - inv_size = #(inventory_lists[page]) - else - inv_size = 0 - end - - local filter = players[name].filter - if filter == nil then - filter = "" - end - - mcl_inventory.set_creative_formspec(player, start_i, start_i / (9*5) + 1, inv_size, false, page, filter) - end -end - -minetest.register_on_joinplayer(function(player) - -- Initialize variables and inventory - local name = player:get_player_name() - if not players[name] then - players[name] = {} - players[name].page = "nix" - players[name].filter = "" - players[name].start_i = 0 - end - init(player) - mcl_inventory.set_creative_formspec(player, 0, 1, nil, false, "nix", "") -end) +local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize + +-- Prepare player info table +local players = {} + +-- Containing all the items for each Creative Mode tab +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"} +for _, f in pairs(builtin_filter_ids) do + inventory_lists[f] = {} +end + +local function replace_enchanted_books(tbl) + for k, item in ipairs(tbl) do + if item:find("mcl_enchanting:book_enchanted") == 1 then + local _, enchantment, level = item:match("(%a+) ([_%w]+) (%d+)") + level = level and tonumber(level) + if enchantment and level then + tbl[k] = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), enchantment, level) + end + end + 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. ]] +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 + local function is_redstone(def) + return def.mesecons or def.groups.mesecon or def.groups.mesecon_conductor_craftable or def.groups.mesecon_effecor_off + end + local function is_tool(def) + return def.groups.tool or (def.tool_capabilities and def.tool_capabilities.damage_groups == nil) + end + 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) + end + -- Is set to true if it was added in any category besides misc + local nonmisc = false + if def.groups.building_block then + table.insert(inventory_lists["blocks"], name) + nonmisc = true + end + if def.groups.deco_block then + table.insert(inventory_lists["deco"], name) + nonmisc = true + end + if is_redstone(def) then + table.insert(inventory_lists["redstone"], name) + nonmisc = true + end + if def.groups.transport then + table.insert(inventory_lists["rail"], name) + nonmisc = true + end + if (def.groups.food and not def.groups.brewitem) or def.groups.eatable then + table.insert(inventory_lists["food"], name) + nonmisc = true + end + if is_tool(def) then + table.insert(inventory_lists["tools"], name) + nonmisc = true + end + if is_weapon_or_armor(def) then + table.insert(inventory_lists["combat"], name) + nonmisc = true + end + if def.groups.spawn_egg == 1 then + table.insert(inventory_lists["mobs"], name) + nonmisc = true + end + if def.groups.brewitem then + table.insert(inventory_lists["brew"], name) + nonmisc = true + end + if def.groups.craftitem then + table.insert(inventory_lists["matr"], name) + nonmisc = true + end + -- Misc. category is for everything which is not in any other category + if not nonmisc then + table.insert(inventory_lists["misc"], name) + end + + table.insert(inventory_lists["all"], name) + 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 + table.insert(inventory_lists["tools"], str) + end + if def.inv_combat_tab then + table.insert(inventory_lists["combat"], str) + end + table.insert(inventory_lists["all"], str) + end + + for _, to_sort in pairs(inventory_lists) do + table.sort(to_sort) + replace_enchanted_books(to_sort) + end +end) + +local function filter_item(name, description, lang, filter) + local desc + if not lang then + desc = string.lower(description) + else + desc = string.lower(minetest.get_translated_string(lang, description)) + end + return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true) +end + +local function set_inv_search(filter, player) + local playername = player:get_player_name() + 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 + if filter_item(string.lower(def.name), def.description, lang, filter) then + table.insert(creative_list, name) + end + end + end + for ench, def in pairs(mcl_enchanting.enchantments) do + for i = 1, def.max_level do + local stack = mcl_enchanting.enchant(ItemStack("mcl_enchanting:book_enchanted"), ench, i) + if filter_item("mcl_enchanting:book_enchanted", minetest.strip_colors(stack:get_description()), lang, filter) then + table.insert(creative_list, "mcl_enchanting:book_enchanted " .. ench .. " " .. i) + end + end + end + table.sort(creative_list) + replace_enchanted_books(creative_list) + + inv:set_size("main", #creative_list) + inv:set_list("main", creative_list) +end + +local function set_inv_page(page, player) + local playername = player:get_player_name() + 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 + creative_list = inventory_lists[page] + end + inv:set_size("main", #creative_list) + players[playername].inv_size = #creative_list + inv:set_list("main", creative_list) +end + +local function init(player) + local playername = player:get_player_name() + 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 + return count + else + return 0 + end + end, + allow_put = function(inv, listname, index, stack, player) + return 0 + end, + allow_take = function(inv, listname, index, stack, player) + if minetest.is_creative_enabled(player:get_player_name()) then + return -1 + else + return 0 + end + end, + }, playername) + set_inv_page("all", player) +end + +-- Create the trash field +local trash = minetest.create_detached_inventory("trash", { + allow_put = function(inv, listname, index, stack, player) + if minetest.is_creative_enabled(player:get_player_name()) then + return stack:get_count() + else + return 0 + end + end, + on_put = function(inv, listname, index, stack, player) + 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 = {} + +local noffset_x_start = -0.24 +local noffset_x = noffset_x_start +local noffset_y = -0.25 +local function next_noffset(id, right) + if right then + noffset[id] = { 8.94, noffset_y } + else + noffset[id] = { noffset_x, noffset_y } + noffset_x = noffset_x + 1.25 + end +end + +-- Upper row +next_noffset("blocks") +next_noffset("deco") +next_noffset("redstone") +next_noffset("rail") +next_noffset("brew") +next_noffset("misc") +next_noffset("nix", true) + +noffset_x = noffset_x_start +noffset_y = 8.12 + +-- Lower row +next_noffset("food") +next_noffset("tools") +next_noffset("combat") +next_noffset("mobs") +next_noffset("matr") +next_noffset("inv", true) + +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) +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" + +filtername["blocks"] = S("Building Blocks") +filtername["deco"] = S("Decoration Blocks") +filtername["redstone"] = S("Redstone") +filtername["rail"] = S("Transportation") +filtername["misc"] = S("Miscellaneous") +filtername["nix"] = S("Search Items") +filtername["food"] = S("Foodstuffs") +filtername["tools"] = S("Tools") +filtername["combat"] = S("Combat") +filtername["mobs"] = S("Mobs") +filtername["brew"] = S("Brewing") +filtername["matr"] = S("Materials") +filtername["inv"] = S("Survival Inventory") + +--local dark_bg = "crafting_creative_bg_dark.png" + +--[[local function reset_menu_item_bg() + bg["blocks"] = dark_bg + bg["deco"] = dark_bg + bg["redstone"] = dark_bg + bg["rail"] = dark_bg + bg["misc"] = dark_bg + bg["nix"] = dark_bg + bg["food"] = dark_bg + bg["tools"] = dark_bg + bg["combat"] = dark_bg + bg["mobs"] = dark_bg + bg["brew"] = dark_bg + bg["matr"] = dark_bg + bg["inv"] = dark_bg + bg["default"] = dark_bg +end]] + +local function get_stack_size(player) + return player:get_meta():get_int("mcl_inventory:switch_stack") +end + +local function set_stack_size(player, n) + player:get_meta():set_int("mcl_inventory:switch_stack", n) +end + +minetest.register_on_joinplayer(function (player) + if get_stack_size(player) == 0 then + set_stack_size(player, 64) + end +end) + +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 inv_size = players[playername].inv_size + local filter = players[playername].filter + local pagemax = math.max(1, math.floor((inv_size-1) / (9*5) + 1)) + local main_list + local listrings = "listring[detached:creative_"..playername..";main]".. + "listring[current_player;main]".. + "listring[detached:trash;main]" + + 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]" + 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]" + 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]" + 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]" + 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]" + 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) .. + + -- 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 .. + + -- Player preview + mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") .. + + -- Crafting guide button + "image_button[9,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")) .. "]" .. + + -- 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 + + -- For shortcuts + listrings = listrings .. + "listring[detached:"..playername.."_armor;armor]".. + "listring[current_player;main]" + else + -- 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;]" + 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", + } + 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" + else + bg_img = "crafting_creative_inactive"..hoch[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])).."]" + 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.."]".. + tab(name, "blocks") .. + "tooltip[blocks;"..F(filtername["blocks"]).."]".. + tab(name, "deco") .. + "tooltip[deco;"..F(filtername["deco"]).."]".. + tab(name, "redstone") .. + "tooltip[redstone;"..F(filtername["redstone"]).."]".. + tab(name, "rail") .. + "tooltip[rail;"..F(filtername["rail"]).."]".. + tab(name, "misc") .. + "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") .. + "tooltip[tools;"..F(filtername["tools"]).."]".. + tab(name, "combat") .. + "tooltip[combat;"..F(filtername["combat"]).."]".. + tab(name, "mobs") .. + "tooltip[mobs;"..F(filtername["mobs"]).."]".. + tab(name, "brew") .. + "tooltip[brew;"..F(filtername["brew"]).."]".. + 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 + + 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]" + end + if pagenum then formspec = formspec .. "p"..tostring(pagenum) end + player:set_inventory_formspec(formspec) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local page = nil + + if not minetest.is_creative_enabled(player:get_player_name()) then + return + end + if formname ~= "" or fields.quit == "true" then + -- No-op if formspec closed or not player inventory (formname == "") + return + end + + local name = player:get_player_name() + + if fields.blocks then + if players[name].page == "blocks" then return end + set_inv_page("blocks",player) + page = "blocks" + elseif fields.deco then + if players[name].page == "deco" then return end + set_inv_page("deco",player) + page = "deco" + elseif fields.redstone then + if players[name].page == "redstone" then return end + set_inv_page("redstone",player) + page = "redstone" + elseif fields.rail then + if players[name].page == "rail" then return end + set_inv_page("rail",player) + page = "rail" + elseif fields.misc then + if players[name].page == "misc" then return end + set_inv_page("misc",player) + page = "misc" + elseif fields.nix then + set_inv_page("all",player) + page = "nix" + elseif fields.food then + if players[name].page == "food" then return end + set_inv_page("food",player) + page = "food" + elseif fields.tools then + if players[name].page == "tools" then return end + set_inv_page("tools",player) + page = "tools" + elseif fields.combat then + if players[name].page == "combat" then return end + set_inv_page("combat",player) + page = "combat" + elseif fields.mobs then + if players[name].page == "mobs" then return end + set_inv_page("mobs",player) + page = "mobs" + elseif fields.brew then + if players[name].page == "brew" then return end + set_inv_page("brew",player) + page = "brew" + elseif fields.matr then + if players[name].page == "matr" then return end + set_inv_page("matr",player) + page = "matr" + elseif fields.inv then + if players[name].page == "inv" then return end + page = "inv" + elseif fields.search == "" and not fields.creative_next and not fields.creative_prev then + 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) + page = "nix" + elseif fields.__switch_stack then + local switch = 1 + if get_stack_size(player) == 1 then + switch = 64 + end + set_stack_size(player, switch) + end + + if page then + players[name].page = page + else + page = players[name].page + end + + local start_i = players[name].start_i + if fields.creative_prev then + start_i = start_i - 9*5 + elseif fields.creative_next then + 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 + end + + local inv_size + if page == "nix" then + 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]) + else + inv_size = 0 + end + players[name].inv_size = inv_size + + if start_i >= inv_size then + start_i = start_i - 9*5 + end + if start_i < 0 or start_i >= inv_size then + start_i = 0 + end + players[name].start_i = start_i + + if not fields.nix and fields.search then + players[name].filter = fields.search + else + players[name].filter = "" + end + + 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) + +minetest.register_on_joinplayer(function(player) + -- Initialize variables and inventory + local name = player:get_player_name() + if not players[name] then + players[name] = {} + players[name].page = "nix" + players[name].filter = "" + players[name].start_i = 0 + end + init(player) + -- Setup initial creative inventory to the "nix" page. + mcl_inventory.set_creative_formspec(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 + local stack = inventory_info.stack + stack:set_count(stack:get_stack_max()) + player:get_inventory():set_stack("main", inventory_info.index, stack) + end +end) diff --git a/mods/HUD/mcl_inventory/depends.txt b/mods/HUD/mcl_inventory/depends.txt deleted file mode 100644 index 27231e5df..000000000 --- a/mods/HUD/mcl_inventory/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_formspec -mcl_player? -_mcl_autogroup? -mcl_armor? -mcl_brewing? -mcl_potions? -mcl_enchanting diff --git a/mods/HUD/mcl_inventory/description.txt b/mods/HUD/mcl_inventory/description.txt deleted file mode 100644 index 207a3fa5e..000000000 --- a/mods/HUD/mcl_inventory/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds the player inventory and creative inventory. diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index c6f97185d..4ca0f2a73 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -1,205 +1,246 @@ -local S = minetest.get_translator("mcl_inventory") -local F = minetest.formspec_escape - -mcl_inventory = {} - -local show_armor = minetest.get_modpath("mcl_armor") ~= nil -local mod_player = minetest.get_modpath("mcl_player") ~= nil -local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil - --- 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) - end - return itemstack -end - --- Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left -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, armor_change_only) - if minetest.is_creative_enabled(player:get_player_name()) then - 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 player_name = player:get_player_name() - - -- Show armor and player image - local img, img_player - if mod_player then - img_player = mcl_player.player_get_preview(player) - else - img_player = "player.png" - end - img = img_player - local player_preview = "image[0.6,0.2;2,4;"..img.."]" - if show_armor and armor.textures[player_name] and armor.textures[player_name].preview then - img = armor.textures[player_name].preview - local s1 = img:find("character_preview") - if s1 ~= nil then - s1 = img:sub(s1+21) - img = img_player..s1 - end - player_preview = "image[1.1,0.2;2,4;"..img.."]" - end - - 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 - - local form = "size[9,8.75]".. - "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]".. - player_preview.. - --armor - "list[detached:"..player_name.."_armor;armor;0,0;1,1;1]".. - "list[detached:"..player_name.."_armor;armor;0,1;1,1;2]".. - "list[detached:"..player_name.."_armor;armor;0,2;1,1;3]".. - "list[detached:"..player_name.."_armor;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).. - 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 - "image_button[3,3;1,1;mcl_skins_button.png;__mcl_skins;]".. - "tooltip[__mcl_skins;"..F(S("Select player skin")).."]".. - -- achievements button - "image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]".. - "tooltip[__mcl_achievements;"..F(S("Achievements")).."]".. - -- for shortcuts - "listring[current_player;main]".. - "listring[current_player;craft]".. - "listring[current_player;main]".. - "listring[detached:"..player_name.."_armor;armor]" - - player:set_inventory_formspec(form) -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") - if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then - set_inventory(player) - end - end -end) - -if not minetest.is_creative_enabled("") then - mcl_inventory.update_inventory_formspec = function(player) - set_inventory(player) - end -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") -end) - -minetest.register_on_joinplayer(function(player) - --init inventory - player:get_inventory():set_width("main", 9) - player:get_inventory():set_size("main", 36) - - --set hotbar size - player:hud_set_hotbar_itemcount(9) - --add hotbar images - player:hud_set_hotbar_image("mcl_inventory_hotbar.png") - player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png") - - if show_armor then - local set_player_armor_original = armor.set_player_armor - local update_inventory_original = armor.update_inventory - armor.set_player_armor = function(self, player) - set_player_armor_original(self, player) - end - armor.update_inventory = function(self, player) - update_inventory_original(self, player) - set_inventory(player, true) - end - armor:set_player_armor(player) - armor:update_inventory(player) - end - - -- In Creative Mode, the initial inventory setup is handled in creative.lua - if not minetest.is_creative_enabled(player:get_player_name()) then - set_inventory(player) - end - - --[[ Make sure the crafting grid is empty. Why? Because the player might have - 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") -end) - -if minetest.is_creative_enabled("") then - dofile(minetest.get_modpath("mcl_inventory").."/creative.lua") -end - +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") + +-- 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) + end + return itemstack +end + +-- Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left +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) + if minetest.is_creative_enabled(player:get_player_name()) then + mcl_inventory.set_creative_formspec(player) + 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) +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") + 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 + +-- 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") +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) + + --set hotbar size + player:hud_set_hotbar_itemcount(9) + --add hotbar images + player:hud_set_hotbar_image("mcl_inventory_hotbar.png") + player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png") + + -- In Creative Mode, the initial inventory setup is handled in creative.lua + if not minetest.is_creative_enabled(player:get_player_name()) then + set_inventory(player) + end + + --[[ Make sure the crafting grid is empty. Why? Because the player might have + 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") +end) + +dofile(minetest.get_modpath(minetest.get_current_modname()).."/creative.lua") + +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.fr.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.fr.tr index edb15a77b..986636f03 100644 --- a/mods/HUD/mcl_inventory/locale/mcl_inventory.fr.tr +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.fr.tr @@ -2,12 +2,12 @@ Recipe book=Livre de recettes Help=Aide Select player skin=Sélectionnez l'apparence du joueur -Achievements=Accomplissements -Building Blocks=Blocs de Construction -Decoration Blocks=Blocs de Décoration +Advancements=Progrès +Building Blocks=Blocs de construction +Decoration Blocks=Blocs de décoration Redstone=Redstone Transportation=Transport -Brewing= +Brewing=Potion Miscellaneous=Divers Search Items=Rechercher des objets Foodstuffs=Denrées alimentaires @@ -19,3 +19,4 @@ Survival Inventory=Inventaire de survie Crafting=Artisanat Inventory=Inventaire @1/@2=@1/@2 +Switch stack size=Changer la quantité maximale par pile diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr new file mode 100644 index 000000000..77c8fe686 --- /dev/null +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.ja.tr @@ -0,0 +1,21 @@ +# textdomain: mcl_inventory +Recipe book=レシピ本 +Help=ヘルプ +Select player skin=プレイヤースキン選択 +Advancements=進捗 +Building Blocks=建築ブロック +Decoration Blocks=装飾ブロック +Redstone=レッドストーン +Transportation=運送 +Brewing=醸造 +Miscellaneous=その他 +Search Items=アイテム検索 +Foodstuffs=食物 +Tools=道具 +Combat=戦闘 +Mobs=Mob +Materials=素材 +Survival Inventory=サバイバル インベントリ +Crafting=クラフト +Inventory=インベントリ +@1/@2=@1/@2 diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.pl.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.pl.tr new file mode 100644 index 000000000..3817d88a1 --- /dev/null +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.pl.tr @@ -0,0 +1,22 @@ +# textdomain: mcl_inventory +Recipe book=Książka z recepturami +Help=Pomoc +Select player skin=Wybierz skin gracza +Achievements=Osiągnięcia +Building Blocks=Bloki budowlane +Decoration Blocks=Bloki dekoracyjne +Redstone=Czerwienit +Transportation=Transport +Brewing=Warzenie +Miscellaneous=Różne +Search Items=Wyszukaj przedmioty +Foodstuffs=Jedzenie +Tools=Narzędzia +Combat=Walka +Mobs=Moby +Materials=Materiały +Survival Inventory=Ekwipunek przetrwania +Crafting=Wytwarzanie +Inventory=Ekwipunek +@1/@2=@1/@2 + diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr index d378e168b..a5c52bc1d 100644 --- a/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.ru.tr @@ -1,21 +1,21 @@ # textdomain: mcl_inventory Recipe book=Книга рецептов -Help=Помощь -Select player skin=Выбор скина +Help=Справка +Select player skin=Выбор внешности Achievements=Достижения Building Blocks=Строительные блоки -Decoration Blocks=Декоративные блоки -Redstone=Редстоун (красный камень) +Decoration Blocks=Отделочные блоки +Redstone=Красный камень Transportation=Транспорт Brewing=Зелья Miscellaneous=Прочее -Search Items=Искать предметы +Search Items=Поиск предметов Foodstuffs=Продовольствие Tools=Инструменты Combat=Битва -Mobs=Мобы +Mobs=Сущности Materials=Материалы Survival Inventory=Инвентарь выживания -Crafting=Крафтинг (изготовление) +Crafting=Создание Inventory=Инвентарь @1/@2=@1/@2 diff --git a/mods/HUD/mcl_inventory/locale/mcl_inventory.zh_TW.tr b/mods/HUD/mcl_inventory/locale/mcl_inventory.zh_TW.tr new file mode 100644 index 000000000..880d224f2 --- /dev/null +++ b/mods/HUD/mcl_inventory/locale/mcl_inventory.zh_TW.tr @@ -0,0 +1,21 @@ +# textdomain: mcl_inventory +Recipe book=合成教學 +Help=幫助 +Select player skin=選擇玩家皮膚 +Achievements=成就 +Building Blocks=建築方塊 +Decoration Blocks=裝飾性方塊 +Redstone=紅石 +Transportation=交通 +Brewing=釀造 +Miscellaneous=雜項 +Search Items=搜尋 +Foodstuffs=食物 +Tools=工具 +Combat=戰鬥 +Mobs=生物 +Materials=材料 +Survival Inventory=生存模式物品欄 +Crafting=合成 +Inventory=物品欄 +@1/@2= diff --git a/mods/HUD/mcl_inventory/locale/template.txt b/mods/HUD/mcl_inventory/locale/template.txt index 7f1c9769d..9cc687e3f 100644 --- a/mods/HUD/mcl_inventory/locale/template.txt +++ b/mods/HUD/mcl_inventory/locale/template.txt @@ -2,7 +2,7 @@ Recipe book= Help= Select player skin= -Achievements= +Advancements= Building Blocks= Decoration Blocks= Redstone= @@ -19,3 +19,4 @@ Survival Inventory= Crafting= Inventory= @1/@2= +Switch stack size= diff --git a/mods/HUD/mcl_inventory/mod.conf b/mods/HUD/mcl_inventory/mod.conf index 2900f85c5..e42213d4f 100644 --- a/mods/HUD/mcl_inventory/mod.conf +++ b/mods/HUD/mcl_inventory/mod.conf @@ -1 +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 diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_next.png b/mods/HUD/mcl_inventory/textures/crafting_creative_next.png deleted file mode 100644 index 65586775c..000000000 Binary files a/mods/HUD/mcl_inventory/textures/crafting_creative_next.png and /dev/null differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_prev.png b/mods/HUD/mcl_inventory/textures/crafting_creative_prev.png deleted file mode 100644 index 30e4bc311..000000000 Binary files a/mods/HUD/mcl_inventory/textures/crafting_creative_prev.png and /dev/null differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_formspec_bg.png b/mods/HUD/mcl_inventory/textures/crafting_formspec_bg.png deleted file mode 100644 index 5fd888dec..000000000 Binary files a/mods/HUD/mcl_inventory/textures/crafting_formspec_bg.png and /dev/null differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_inventory_creative.png b/mods/HUD/mcl_inventory/textures/crafting_inventory_creative.png deleted file mode 100644 index b0348629e..000000000 Binary files a/mods/HUD/mcl_inventory/textures/crafting_inventory_creative.png and /dev/null differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_inventory_creative_survival.png b/mods/HUD/mcl_inventory/textures/crafting_inventory_creative_survival.png deleted file mode 100644 index 828404ea2..000000000 Binary files a/mods/HUD/mcl_inventory/textures/crafting_inventory_creative_survival.png and /dev/null differ diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_hotbar.png b/mods/HUD/mcl_inventory/textures/mcl_inventory_hotbar.png deleted file mode 100644 index d3dd364d6..000000000 Binary files a/mods/HUD/mcl_inventory/textures/mcl_inventory_hotbar.png and /dev/null differ diff --git a/mods/HUD/mcl_offhand/init.lua b/mods/HUD/mcl_offhand/init.lua new file mode 100644 index 000000000..98954b4f5 --- /dev/null +++ b/mods/HUD/mcl_offhand/init.lua @@ -0,0 +1,172 @@ +local minetest, math = minetest, math +mcl_offhand = {} + +local max_offhand_px = 128 +-- only supports up to 128px textures + +function mcl_offhand.get_offhand(player) + return player:get_inventory():get_stack("offhand", 1) +end + +local function offhand_get_wear(player) + return mcl_offhand.get_offhand(player):get_wear() +end + +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] = { + hud = {}, + last_wear = offhand_get_wear(player), + last_count = offhand_get_count(player), + } +end) + +local function remove_hud(player, hud) + local offhand_hud = mcl_offhand[player].hud[hud] + if offhand_hud then + player:hud_remove(offhand_hud) + mcl_offhand[player].hud[hud] = nil + end +end + +function rgb_to_hex(r, g, b) + return string.format("%02x%02x%02x", r, g, b) +end + +local function update_wear_bar(player, itemstack) + local wear_bar_percent = (65535 - offhand_get_wear(player)) / 65535 + + local color = {255, 255, 255} + local wear = itemstack:get_wear() / 65535; + local wear_i = math.min(math.floor(wear * 600), 511); + wear_i = math.min(wear_i + 10, 511); + if wear_i <= 255 then + color = {wear_i, 255, 0} + else + color = {255, 511 - wear_i, 0} + end + local wear_bar = mcl_offhand[player].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}) +end + +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 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 + local position = {x = 0.5, y = 1} + local offset = {x = -320, y = -32} + + if not offhand_hud.slot then + offhand_hud.slot = player:hud_add({ + hud_elem_type = "image", + position = position, + offset = offset, + scale = {x = 0.46875, y = 0.46875}, + text = "mcl_offhand_slot.png" .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px, + z_index = 0, + }) + end + if not offhand_hud.item then + offhand_hud.item = player:hud_add({ + hud_elem_type = "image", + position = position, + offset = offset, + scale = {x = 0.375, y = 0.375}, + text = item_texture, + z_index = 1, + }) + else + player:hud_change(offhand_hud.item, "text", item_texture) + end + if not offhand_hud.wear_bar_bg and minetest.registered_tools[offhand_item] then + if offhand_get_wear(player) > 0 then + local texture = "mcl_wear_bar.png^[colorize:#000000" + offhand_hud.wear_bar_bg = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 1}, + offset = {x = -320, y = -13}, + scale = {x = 40, y = 3}, + text = texture, + z_index = 2, + }) + offhand_hud.wear_bar = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 1}, + offset = {x = -320, y = -13}, + scale = {x = 10, y = 3}, + text = texture, + z_index = 3, + }) + update_wear_bar(player, itemstack) + end + end + + if not offhand_hud.item_count and offhand_get_count(player) > 1 then + offhand_hud.item_count = player:hud_add({ + hud_elem_type = "text", + position = {x = 0.5, y = 1}, + offset = {x = -298, y = -18}, + scale = {x = 1, y = 1}, + alignment = {x = -1, y = 0}, + text = offhand_get_count(player), + z_index = 4, + number = 0xFFFFFF, + }) + end + + if offhand_hud.wear_bar then + if offhand_hud.last_wear ~= offhand_get_wear(player) then + update_wear_bar(player, itemstack) + offhand_hud.last_wear = offhand_get_wear(player) + end + if offhand_get_wear(player) <= 0 or not minetest.registered_tools[offhand_item] then + remove_hud(player, "wear_bar_bg") + remove_hud(player, "wear_bar") + end + end + + if offhand_hud.item_count then + if offhand_hud.last_count ~= offhand_get_count(player) then + player:hud_change(offhand_hud.item_count, "text", offhand_get_count(player)) + offhand_hud.last_count = offhand_get_count(player) + end + if offhand_get_count(player) <= 1 then + remove_hud(player, "item_count") + end + end + + elseif offhand_hud.slot then + for index, _ in pairs(mcl_offhand[player].hud) do + remove_hud(player, index) + end + end + end +end) + +minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info) + if action == "move" and inventory_info.to_list == "offhand" then + local itemstack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index) + if not (minetest.get_item_group(itemstack:get_name(), "offhand_item") > 0) then + return 0 + else + return itemstack:get_stack_max() + end + end +end) + +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + local from_offhand = inventory_info.from_list == "offhand" + local to_offhand = inventory_info.to_list == "offhand" + if action == "move" and from_offhand or to_offhand then + mcl_inventory.update_inventory_formspec(player) + end +end) diff --git a/mods/HUD/mcl_offhand/mod.conf b/mods/HUD/mcl_offhand/mod.conf new file mode 100644 index 000000000..f0260f35c --- /dev/null +++ b/mods/HUD/mcl_offhand/mod.conf @@ -0,0 +1,3 @@ +name = mcl_offhand +author = NO11 +depends = mcl_inventory diff --git a/mods/HUD/mcl_title/API.md b/mods/HUD/mcl_title/API.md new file mode 100644 index 000000000..37f1c279f --- /dev/null +++ b/mods/HUD/mcl_title/API.md @@ -0,0 +1,50 @@ +# mcl_title + +Allow mods to show messages in the hud of players. + +## mcl_title.set(player, type, data) + +Show a hud message of `type` to player `player` with `data` as params. + +The element will stay for the per-player param `stay` or `data.stay` (in gametick which is 1/20 second). + +Here is a usage exemple: + +```lua +--show a title in the HUD with minecraft color "gold" +mcl_title.set(player, "title", {text="dummy text", color="gold"}) + +--show a subtitle in the HUD with hex color "#612D2D" +mcl_title.set(player, "subtitle", {text="dummy subtitle", color="#612D2D"}) + +--show an actionbar in the HUD (above the hotbar) with minecraft color "red" +mcl_title.set(player, "subtitle", {text="dummy actionbar", color="red"}) + +--show a title in the HUD with minecraft color "gold" staying for 3 seconds (override stay setting) +mcl_title.set(player, "title", {text="dummy text", color="gold", stay=60}) +``` + +## mcl_title.remove(player, type) + +Hide HUD element of type `type` for player `player`. + +## mcl_title.clear(player) + +Remove every title/subtitle/actionbar from a player. +Basicaly run `mcl_title.remove(player, type)` for every type. + +## mcl_title.params_set(player, params) + +Allow mods to set `stay` and upcomming `fadeIn`/`fadeOut` params. + +```lua +mcl_title.params_set(player, {stay = 600}) --elements with no 'data.stay' field will stay during 30s (600/20) +``` + +## mcl_title.params_get(player) + +Get `stay` and upcomming `fadeIn` and `fadeOut` params of a player as a table. + +```lua +mcl_title.params_get(player) +``` \ No newline at end of file diff --git a/mods/HUD/mcl_title/init.lua b/mods/HUD/mcl_title/init.lua new file mode 100644 index 000000000..2e8397fc1 --- /dev/null +++ b/mods/HUD/mcl_title/init.lua @@ -0,0 +1,307 @@ +--Based on: +--https://www.digminecraft.com/game_commands/title_command.php +--https://youtu.be/oVrtQRO2hpY + +--TODO: use SSCSM to reduce lag and network trafic (just send modchannel messages) +--TODO: fadeIn and fadeOut animation (needs engine change: SSCSM or native support) +--TODO: allow obfuscating text (needs engine change: SSCSM or native support) +--TODO: allow colorizing and styling of part of the text (NEEDS ENGINE CHANGE!!!) +--TODO: exactly mc like layout + +--Note that the table storing timeouts use playername as index insteed of player objects (faster) +--This is intended in order to speedup the process of removing HUD elements the the timeout is up + +---@type table> +local huds_idx = {} + +---@type table> +local hud_hide_timeouts = {} + +hud_hide_timeouts.title = {} +hud_hide_timeouts.subtitle = {} +hud_hide_timeouts.actionbar = {} + +huds_idx.title = {} +huds_idx.subtitle = {} +huds_idx.actionbar = {} + +mcl_title = {} +mcl_title.defaults = { fadein = 10, stay = 70, fadeout = 20 } +mcl_title.layout = {} +mcl_title.layout.title = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = -1.3 }, size = 7 } +mcl_title.layout.subtitle = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = 1.7 }, size = 4 } +mcl_title.layout.actionbar = { position = { x = 0.5, y = 1 }, alignment = { x = 0, y = 0 }, size = 1 } + +local get_color = mcl_util.get_color + +--local string = string +local pairs = pairs + +---@param gametick integer +---@return number? +local function gametick_to_secondes(gametick) + if gametick then + return gametick / 20 + else + return nil + end +end + +--https://github.com/minetest/minetest/blob/b3b075ea02034306256b486dd45410aa765f035a/doc/lua_api.txt#L8477 + +---@param bold? boolean +---@param italic? boolean +---@return integer +local function style_to_bits(bold, italic) + if bold then + if italic then + return 3 + else + return 1 + end + else + if italic then + return 2 + else + return 0 + end + end +end + +local no_style = style_to_bits(false, false) + +---PARAMS SYSTEM +---@type table +local player_params = {} + +minetest.register_on_joinplayer(function(player) + --local playername = player:get_player_name() + player_params[player] = { + stay = mcl_title.defaults.stay, + --fadeIn = mcl_title.defaults.fadein, + --fadeOut = mcl_title.defaults.fadeout, + } + local _, hex_color = get_color("white") + huds_idx.title[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.title.position, + alignment = mcl_title.layout.title.alignment, + text = "", + style = no_style, + size = { x = mcl_title.layout.title.size }, + number = hex_color, + z_index = 100, + }) + huds_idx.subtitle[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.subtitle.position, + alignment = mcl_title.layout.subtitle.alignment, + text = "", + style = no_style, + size = { x = mcl_title.layout.subtitle.size }, + number = hex_color, + z_index = 100, + }) + huds_idx.actionbar[player] = player:hud_add({ + hud_elem_type = "text", + position = mcl_title.layout.actionbar.position, + offset = { x = 0, y = -210 }, + alignment = mcl_title.layout.actionbar.alignment, + style = no_style, + text = "", + size = { x = mcl_title.layout.actionbar.size }, + number = hex_color, + z_index = 100, + }) +end) + +minetest.register_on_leaveplayer(function(player) + local playername = player:get_player_name() + + --remove player params from the list + player_params[player] = nil + + --remove HUD idx from the list (HUD elements are removed by the engine) + huds_idx.title[player] = nil + huds_idx.subtitle[player] = nil + huds_idx.actionbar[player] = nil + + --remove timers from list + hud_hide_timeouts.title[playername] = nil + hud_hide_timeouts.subtitle[playername] = nil + hud_hide_timeouts.actionbar[playername] = nil +end) + +---@param player ObjectRef +---@param data {stay: integer} +function mcl_title.params_set(player, data) + player_params[player] = { + stay = data.stay or mcl_title.defaults.stay, + --fadeIn = data.fadeIn or mcl_title.defaults.fadein, + --fadeOut = data.fadeOut or mcl_title.defaults.fadeout, + } +end + +---@param player ObjectRef +---@return {stay: integer} +function mcl_title.params_get(player) + return player_params[player] +end + +--API FUNCTIONS + +---@param player ObjectRef +---@param type '"title"'|'"subtitle"'|'"actionbar"' +---@param data {text: string, color: string, stay: integer, bold: boolean, italic: boolean} +---@return boolean +function mcl_title.set(player, type, data) + if not data.color then + data.color = "white" + end + local _, hex_color = get_color(data.color) + if not hex_color then + return false + end + + player:hud_change(huds_idx[type][player], "text", data.text) + player:hud_change(huds_idx[type][player], "number", hex_color) + + -- Apply bold and italic + player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic)) + + hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or + gametick_to_secondes(mcl_title.params_get(player).stay) + + return true +end + +---@param player ObjectRef? +---@param type '"title"'|'"subtitle"'|'"actionbar"' +function mcl_title.remove(player, type) + if player then + player:hud_change(huds_idx[type][player], "text", "") + player:hud_change(huds_idx[type][player], "style", no_style) + end +end + +---@param player ObjectRef +function mcl_title.clear(player) + mcl_title.remove(player, "title") + mcl_title.remove(player, "subtitle") + mcl_title.remove(player, "actionbar") +end + +minetest.register_on_dieplayer(function(player) + mcl_title.clear(player) +end) + +minetest.register_globalstep(function(dtime) + local new_timeouts = { + title = {}, + subtitle = {}, + actionbar = {}, + } + + for element, content in pairs(hud_hide_timeouts) do + for name, timeout in pairs(content) do + timeout = timeout - dtime + if timeout <= 0 then + local player = minetest.get_player_by_name(name) + mcl_title.remove(player, element) + else + new_timeouts[element][name] = timeout + end + end + end + + hud_hide_timeouts = new_timeouts +end) + + +--DEBUG STUFF!! +--TODO:Proper /title command that can send the title to other players. +--These commands are just for debugging right now. +local dbg_msg = "Note that these are just debug commands right now. e.g. the title is only sent to he player issuing the command. Proper /title commands will be added in the future." +minetest.register_chatcommand("title", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.set(player, "title", { text = param, color = "gold", bold = true, italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("subtitle", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.set(player, "subtitle", { text = param, color = "gold" }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("actionbar", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.set(player, "actionbar", { text = param, color = "gold", bold = true, italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("title_timeout", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.params_set(player, { stay = 600 }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("title_all", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.params_set(player, { stay = 600 }) + mcl_title.set(player, "title", { text = param, color = "gold" }) + mcl_title.set(player, "subtitle", { text = param, color = "gold" }) + mcl_title.set(player, "actionbar", { text = param, color = "gold" }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) + +minetest.register_chatcommand("title_all_styles", { + privs = { debug = true }, + func = function(name, param) + local player = minetest.get_player_by_name(name) + if player then + mcl_title.params_set(player, { stay = 600 }) + mcl_title.set(player, "title", { text = param, color = "gold" }) + mcl_title.set(player, "subtitle", { text = param, color = "gold", bold = true }) + mcl_title.set(player, "actionbar", { text = param, color = "gold", italic = true }) + return true, dbg_msg + else + return false, dbg_msg + end + end, +}) diff --git a/mods/HUD/mcl_title/mod.conf b/mods/HUD/mcl_title/mod.conf new file mode 100644 index 000000000..0f29a8118 --- /dev/null +++ b/mods/HUD/mcl_title/mod.conf @@ -0,0 +1,4 @@ +name = mcl_title +description = Add an API to add in HUD title +depends = mcl_colors +author = AFCMS \ No newline at end of file diff --git a/mods/HUD/mcl_tmp_message/init.lua b/mods/HUD/mcl_tmp_message/init.lua deleted file mode 100644 index 1456cd592..000000000 --- a/mods/HUD/mcl_tmp_message/init.lua +++ /dev/null @@ -1,44 +0,0 @@ -mcl_tmp_message = {} - -local huds = {} -local hud_hide_timeouts = {} - -function mcl_tmp_message.message(player, message) - local name = player:get_player_name() - player:hud_change(huds[name], "text", message) - hud_hide_timeouts[name] = 3 -end - -minetest.register_on_joinplayer(function(player) - huds[player:get_player_name()] = player:hud_add({ - hud_elem_type = "text", - position = {x=0.5, y=1}, - offset = {x = 0, y = -210}, - alignment = {x=0, y=0}, - number = 0xFFFFFF , - text = "", - z_index = 100, - }) -end) - -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - huds[name] = nil - hud_hide_timeouts[name] = nil -end) - -minetest.register_globalstep(function(dtime) - local new_timeouts = {} - for name, timeout in pairs(hud_hide_timeouts) do - timeout = timeout - dtime - if timeout <= 0 then - local player = minetest.get_player_by_name(name) - if player then - player:hud_change(huds[name], "text", "") - end - else - new_timeouts[name] = timeout - end - end - hud_hide_timeouts = new_timeouts -end) diff --git a/mods/HUD/mcl_ver_info/init.lua b/mods/HUD/mcl_ver_info/init.lua new file mode 100644 index 000000000..632847275 --- /dev/null +++ b/mods/HUD/mcl_ver_info/init.lua @@ -0,0 +1,65 @@ +--- +--- Generated by EmmyLua +--- Created by Michieal. +--- DateTime: 11/28/22 4:38 PM +--- +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +local function xpcall_ver (error) + minetest.log("info", "mcl_ver_info:: Gamepath not supported in this version of Minetest.") +end + +local function get_game_info () + local game_info + + if xpcall(minetest.get_game_info, xpcall_ver) then + game_info = minetest.get_game_info() + else + minetest.log( S("Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.")) + return false + end + + return game_info +end + +-- register normal user access to debug levels 1 and 0. +minetest.register_chatcommand("ver", { + description = S("Display Mineclone 2 game version."), + func = function(name, params) + --[[ get_game_info's table data: + { + id = string, + title = string, + author = string, + -- The root directory of the game + path = string, + } + --]] + local game_info = get_game_info () + + if game_info == false then + return true + end + + local conf = Settings(game_info.path .. "/game.conf") + local version = conf:get("version") + + if game_info.title == nil or game_info.title == "" then + game_info.title = "Mineclone 2" + 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. + if version == nil or version == "" then -- workaround for id = not being implemented yet. + if game_info.id == nil or game_info.id == "" then + game_info.id = " Please upgrade your version to the newest version for the /ver command to work." + end + else + game_info.id = version + end + + minetest.chat_send_player(name, string.format("Version: %s - %s", game_info.title, game_info.id)) + return true + end +}) + 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 new file mode 100644 index 000000000..3e6c9af6d --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.fr.tr @@ -0,0 +1,2 @@ +# 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. diff --git a/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr new file mode 100644 index 000000000..e306d9373 --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/mcl_ver_info.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_ver_info +Sorry, but your version of Minetest doesn't support the latest API. Please upgrade your minetest.=すみませんが、お使いの Minetest のバージョンは、最新のAPIをサポートしていません。minetest を更新してみて下さい。 \ No newline at end of file diff --git a/mods/HUD/mcl_ver_info/locale/template.txt b/mods/HUD/mcl_ver_info/locale/template.txt new file mode 100644 index 000000000..75febe815 --- /dev/null +++ b/mods/HUD/mcl_ver_info/locale/template.txt @@ -0,0 +1,2 @@ +# 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 diff --git a/mods/HUD/mcl_ver_info/mod.conf b/mods/HUD/mcl_ver_info/mod.conf new file mode 100644 index 000000000..b6f6dca98 --- /dev/null +++ b/mods/HUD/mcl_ver_info/mod.conf @@ -0,0 +1,4 @@ +name = mcl_ver_info +description = Prints game version information; /ver command. +depends = mcl_init +author = Michieal diff --git a/mods/HUD/show_wielded_item/depends.txt b/mods/HUD/show_wielded_item/depends.txt deleted file mode 100644 index 3e1d5c201..000000000 --- a/mods/HUD/show_wielded_item/depends.txt +++ /dev/null @@ -1 +0,0 @@ -hudbars? diff --git a/mods/HUD/show_wielded_item/description.txt b/mods/HUD/show_wielded_item/description.txt deleted file mode 100644 index 361cab6ce..000000000 --- a/mods/HUD/show_wielded_item/description.txt +++ /dev/null @@ -1 +0,0 @@ -Displays the name of the wielded item. diff --git a/mods/HUD/show_wielded_item/init.lua b/mods/HUD/show_wielded_item/init.lua index bc06bee43..dfa87a85c 100644 --- a/mods/HUD/show_wielded_item/init.lua +++ b/mods/HUD/show_wielded_item/init.lua @@ -6,12 +6,16 @@ local huds = {} local dtimes = {} local dlimit = 3 -- HUD element will be hidden after this many seconds +local math = math +local string = string +local tonumber = tonumber + local hudbars_mod = minetest.get_modpath("hudbars") local xp_mod = minetest.get_modpath("mcl_experience") local function set_hud(player) if not player:is_player() then return end - local player_name = player:get_player_name() + local player_name = player:get_player_name() -- Fixed offset in config file local fixed = tonumber(minetest.settings:get("show_wielded_item_y_offset")) local off @@ -74,7 +78,7 @@ minetest.register_globalstep(function(dtime) if dtimes[player_name] and dtimes[player_name] < dlimit then dtimes[player_name] = dtimes[player_name] + dtime if dtimes[player_name] > dlimit and huds[player_name] then - player:hud_change(huds[player_name], 'text', "") + player:hud_change(huds[player_name], "text", "") end end @@ -84,7 +88,7 @@ minetest.register_globalstep(function(dtime) wield[player_name] = wname dtimes[player_name] = 0 - if huds[player_name] then + if huds[player_name] then local def = minetest.registered_items[wname] local meta = wstack:get_meta() @@ -105,7 +109,7 @@ minetest.register_globalstep(function(dtime) if firstnewline then desc = string.sub(desc, 1, firstnewline-1) end - player:hud_change(huds[player_name], 'text', desc) + player:hud_change(huds[player_name], "text", desc) end end end diff --git a/mods/HUD/show_wielded_item/mod.conf b/mods/HUD/show_wielded_item/mod.conf index fdedae0f7..50648dc6a 100644 --- a/mods/HUD/show_wielded_item/mod.conf +++ b/mods/HUD/show_wielded_item/mod.conf @@ -1 +1,4 @@ name = show_wielded_item +author = 4aiman +description = Displays the name of the wielded item. +optional_depends = hudbars diff --git a/mods/HUD/show_wielded_item/screenshot.png b/mods/HUD/show_wielded_item/screenshot.png deleted file mode 100644 index 50c2c6260..000000000 Binary files a/mods/HUD/show_wielded_item/screenshot.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt b/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt deleted file mode 100644 index 2cc05ce78..000000000 --- a/mods/ITEMS/REDSTONE/mcl_comparators/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mesecons -mcl_sounds -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua index 48bd18bfe..01b42c340 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_comparators/init.lua @@ -1,8 +1,8 @@ -local S = minetest.get_translator("mcl_comparators") +local S = minetest.get_translator(minetest.get_current_modname()) -- Functions that get the input/output rules of the comparator -local comparator_get_output_rules = function(node) +local function comparator_get_output_rules(node) local rules = {{x = -1, y = 0, z = 0, spread=true}} for i = 0, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -11,7 +11,7 @@ local comparator_get_output_rules = function(node) end -local comparator_get_input_rules = function(node) +local function comparator_get_input_rules(node) local rules = { -- we rely on this order in update_self below {x = 1, y = 0, z = 0}, -- back @@ -27,13 +27,13 @@ end -- Functions that are called after the delay time -local comparator_turnon = function(params) +local function comparator_turnon(params) local rules = comparator_get_output_rules(params.node) mesecon.receptor_on(params.pos, rules) end -local comparator_turnoff = function(params) +local function comparator_turnoff(params) local rules = comparator_get_output_rules(params.node) mesecon.receptor_off(params.pos, rules) end @@ -41,22 +41,28 @@ end -- Functions that set the correct node type an schedule a turnon/off -local comparator_activate = function(pos, node) +local function comparator_activate(pos, node) local def = minetest.registered_nodes[node.name] - minetest.swap_node(pos, { name = def.comparator_onstate, param2 = node.param2 }) + local onstate = def.comparator_onstate + if onstate then + minetest.swap_node(pos, { name = onstate, param2 = node.param2 }) + end minetest.after(0.1, comparator_turnon , {pos = pos, node = node}) end -local comparator_deactivate = function(pos, node) +local function comparator_deactivate(pos, node) local def = minetest.registered_nodes[node.name] - minetest.swap_node(pos, { name = def.comparator_offstate, param2 = node.param2 }) + local offstate = def.comparator_offstate + if offstate then + minetest.swap_node(pos, { name = offstate, param2 = node.param2 }) + end minetest.after(0.1, comparator_turnoff, {pos = pos, node = node}) end -- weather pos has an inventory that contains at least one item -local container_inventory_nonempty = function(pos) +local function container_inventory_nonempty(pos) local invnode = minetest.get_node(pos) local invnodedef = minetest.registered_nodes[invnode.name] -- Ignore stale nodes @@ -78,14 +84,14 @@ local container_inventory_nonempty = function(pos) end -- weather pos has an constant signal output for the comparator -local static_signal_output = function(pos) +local function static_signal_output(pos) local node = minetest.get_node(pos) local g = minetest.get_item_group(node.name, "comparator_signal") return g > 0 end -- whether the comparator should be on according to its inputs -local comparator_desired_on = function(pos, node) +local function comparator_desired_on(pos, node) local my_input_rules = comparator_get_input_rules(node); local back_rule = my_input_rules[1] local state @@ -116,7 +122,7 @@ end -- update comparator state, if needed -local update_self = function(pos, node) +local function update_self(pos, node) node = node or minetest.get_node(pos) local old_state = mesecon.is_receptor_on(node.name) local new_state = comparator_desired_on(pos, node) @@ -131,7 +137,7 @@ end -- compute tile depending on state and mode -local get_tiles = function(state, mode) +local function get_tiles(state, mode) local top = "mcl_comparators_"..state..".png^".. "mcl_comparators_"..mode..".png" local sides = "mcl_comparators_sides_"..state..".png^".. @@ -146,13 +152,13 @@ local get_tiles = function(state, mode) end -- Given one mode, get the other mode -local flipmode = function(mode) +local function flipmode(mode) if mode == "comp" then return "sub" elseif mode == "sub" then return "comp" end end -local make_rightclick_handler = function(state, mode) +local function make_rightclick_handler(state, mode) local newnodename = "mcl_comparators:comparator_"..state.."_"..flipmode(mode) return function (pos, node, clicker) @@ -217,92 +223,94 @@ if minetest.get_modpath("screwdriver") then end for _, mode in pairs{"comp", "sub"} do -for _, state in pairs{mesecon.state.on, mesecon.state.off} do - local state_str = state_strs[state] - local nodename = - "mcl_comparators:comparator_"..state_strs[state].."_"..mode + for _, state in pairs{mesecon.state.on, mesecon.state.off} do + local state_str = state_strs[state] + local nodename = + "mcl_comparators:comparator_"..state_str.."_"..mode - -- Help - local longdesc, usagehelp, use_help - if state_strs[state] == "off" and mode == "comp" then - longdesc = S("Redstone comparators are multi-purpose redstone components.").."\n".. - S("They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.") + -- Help + local longdesc, usagehelp, use_help + if state_str == "off" and mode == "comp" then + longdesc = S("Redstone comparators are multi-purpose redstone components.").."\n".. + S("They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.") - usagehelp = S("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.").."\n".. - S("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.").."\n".. - S("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.").."\n\n".. - S("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".. - S("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.") - else - use_help = false - end + usagehelp = S("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.").."\n".. + S("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.").."\n".. + S("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.").."\n\n".. + S("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".. + S("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.") + else + use_help = false + end - local nodedef = { - description = S("Redstone Comparator"), - inventory_image = icon, - wield_image = icon, - _doc_items_create_entry = use_help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - drawtype = "nodebox", - tiles = get_tiles(state_strs[state], mode), - wield_image = "mcl_comparators_off.png", - walkable = true, - selection_box = collision_box, - collision_box = collision_box, - node_box = { - type = "fixed", - fixed = node_boxes[mode], - }, - groups = groups, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = false, - is_ground_content = false, - drop = 'mcl_comparators:comparator_off_comp', - on_construct = update_self, - on_rightclick = - make_rightclick_handler(state_strs[state], mode), - comparator_mode = mode, - comparator_onstate = "mcl_comparators:comparator_on_"..mode, - comparator_offstate = "mcl_comparators:comparator_off_"..mode, - sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = { - receptor = { - state = state, - rules = comparator_get_output_rules, + local nodedef = { + description = S("Redstone Comparator"), + inventory_image = icon, + wield_image = icon, + _doc_items_create_entry = use_help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + drawtype = "nodebox", + tiles = get_tiles(state_str, mode), + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + --wield_image = "mcl_comparators_off.png", + walkable = true, + selection_box = collision_box, + collision_box = collision_box, + node_box = { + type = "fixed", + fixed = node_boxes[mode], }, - effector = { - rules = comparator_get_input_rules, - action_change = update_self, - } - }, - on_rotate = on_rotate, - } + groups = groups, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = false, + is_ground_content = false, + drop = "mcl_comparators:comparator_off_comp", + on_construct = update_self, + on_rightclick = + make_rightclick_handler(state_str, mode), + comparator_mode = mode, + comparator_onstate = "mcl_comparators:comparator_on_"..mode, + comparator_offstate = "mcl_comparators:comparator_off_"..mode, + sounds = mcl_sounds.node_sound_stone_defaults(), + mesecons = { + receptor = { + state = state, + rules = comparator_get_output_rules, + }, + effector = { + rules = comparator_get_input_rules, + action_change = update_self, + } + }, + on_rotate = on_rotate, + } - if mode == "comp" and state == mesecon.state.off then - -- This is the prototype - nodedef._doc_items_create_entry = true - else - nodedef.groups = table.copy(nodedef.groups) - nodedef.groups.not_in_creative_inventory = 1 - local extra_desc = {} - if mode == "sub" or state == mesecon.state.on then - nodedef.inventory_image = nil + if mode == "comp" and state == mesecon.state.off then + -- This is the prototype + nodedef._doc_items_create_entry = true + else + nodedef.groups = table.copy(nodedef.groups) + nodedef.groups.not_in_creative_inventory = 1 + --local extra_desc = {} + if mode == "sub" or state == mesecon.state.on then + nodedef.inventory_image = nil + end + local desc = nodedef.description + if mode ~= "sub" and state == mesecon.state.on then + desc = S("Redstone Comparator (Powered)") + elseif mode == "sub" and state ~= mesecon.state.on then + desc = S("Redstone Comparator (Subtract)") + elseif mode == "sub" and state == mesecon.state.on then + desc = S("Redstone Comparator (Subtract, Powered)") + end + nodedef.description = desc end - local desc = nodedef.description - if mode ~= "sub" and state == mesecon.state.on then - desc = S("Redstone Comparator (Powered)") - elseif mode == "sub" and state ~= mesecon.state.on then - desc = S("Redstone Comparator (Subtract)") - elseif mode == "sub" and state == mesecon.state.on then - desc = S("Redstone Comparator (Subtract, Powered)") - end - nodedef.description = desc + + minetest.register_node(nodename, nodedef) + mcl_wip.register_wip_item(nodename) end - - minetest.register_node(nodename, nodedef) -end end -- Register recipies @@ -349,9 +357,9 @@ minetest.register_abm({ -- Add entry aliases for the Help if minetest.get_modpath("doc") then doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", - "nodes", "mcl_comparators:comparator_off_sub") + "nodes", "mcl_comparators:comparator_off_sub") doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", - "nodes", "mcl_comparators:comparator_on_comp") + "nodes", "mcl_comparators:comparator_on_comp") doc.add_entry_alias("nodes", "mcl_comparators:comparator_off_comp", - "nodes", "mcl_comparators:comparator_on_sub") + "nodes", "mcl_comparators:comparator_on_sub") end diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr new file mode 100644 index 000000000..f836d8239 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.ja.tr @@ -0,0 +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.=レッドストーン信号の送信、ブロックにアイテムが含まれているかどうかの検出、複数の信号の比較などが可能です。 +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つ目は、コンテナ(チェストのようなもの)が前に置かれ、そのコンテナに少なくとも1つのアイテムが入っている場合にのみ、動力が得られます。 +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.=サイド入力には、通常のレッドストーン動力のみが供給されます。レッドストーンコンパレータは、2つのモードで動作できます。送信モードと減算モードです。送信モードで起動し、ブロックによりモードを変更できます。 +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前面のトーチは非点灯で降りています。出力が動力を供給するのは、メイン入力に動力が来ている場合のみです。2つのサイド入力は無視されます。 +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)=レッドストーンコンパレータ(減算・稼動) diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pl.tr b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pl.tr new file mode 100644 index 000000000..e20d253c8 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_comparators/locale/mcl_comparators.pl.tr @@ -0,0 +1,13 @@ +# textdomain: mcl_comparators +Redstone comparators are multi-purpose redstone components.=Komparatory są wielofunkcyjnymi mechanizmami czerwienitowymi. +They can transmit a redstone signal, detect whether a block contains any items and compare multiple signals.=Mogą one przesyłać sygnał czerwienitowy, wykrywać czy blok zawiera przedmioty i porównywać wiele sygnałów. +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.=Komparator ma jedno główne wejście, 2 wejścia poboczne i jedno wyjście. Wyjście jest wskazywane przez strzałkę, wejście jest na przeciwko. Pozostałe dwa wejścia są poboczne. +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.=Główny wejście można zasilać na 2 sposoby: Może być zasilany bezpośrednio energią czerwienitową jak każdy inny komponent, lub gdy przed nim postawiony jest kontener zawierający przynajmniej jeden przedmiot. +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.=Wejścia poboczne są aktywowane przez zwykłą energię czerwienitową. Komparator może działać w dwóch trybach: tryb przekazywania oraz tryb odejmowania. Początkowo jest w trybie przekazywania, a tryb może być zmienione przez użycie go. +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.=Tryb przekazywania:@nPrzednia pochodnia jest niezaświecona i obniżona. Wyjście jest zasilane wtedy i tylko wtedy gdy wejście główne jest zasilane. Wejścia boczne są ignorowane. +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.=Tryb odejmowania:@nPrzednia pochodnia jest zaświecona. Wyjście jest zasilane wtedy i tylko gdy zasilane jest główne wejście, a wejścia boczne nie są. +Redstone Comparator=Komparator +Redstone Comparator (Subtract)=Komparator (odejmowanie) +Redstone Comparator (Powered)=Komparator (zasilony) +Redstone Comparator (Subtract, Powered)=Komparator (odejmowanie, zasilony) + diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf index e0a6a9bbb..100e42814 100644 --- a/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf +++ b/mods/ITEMS/REDSTONE/mcl_comparators/mod.conf @@ -1 +1,3 @@ name = mcl_comparators +depends = mcl_wip, mesecons, mcl_sounds +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_off.png b/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_off.png deleted file mode 100644 index b7affc2ea..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_off.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_on.png b/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_on.png deleted file mode 100644 index c2e250d50..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_on.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_sub.png b/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_sub.png deleted file mode 100644 index 76d9187d3..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_sub.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt b/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt deleted file mode 100644 index 7b51f67cc..000000000 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/depends.txt +++ /dev/null @@ -1,12 +0,0 @@ -mcl_init -mcl_formspec -mesecons -mcl_sounds -mcl_tnt -mcl_worlds -mcl_core -mcl_nether -mcl_armor_stand -mcl_armor -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index b6d0d2ef6..17d9385a2 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -7,10 +7,10 @@ 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("mcl_dispensers") +local S = minetest.get_translator(minetest.get_current_modname()) -- For after_place_node -local setup_dispenser = function(pos) +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"))).."]".. @@ -19,9 +19,9 @@ local setup_dispenser = function(pos) "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[current_name;main;3,0.5;3,3;]".. + "list[context;main;3,0.5;3,3;]".. mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[current_name;main]".. + "listring[context;main]".. "listring[current_player;main]" local meta = minetest.get_meta(pos) meta:set_string("formspec", form) @@ -29,7 +29,7 @@ local setup_dispenser = function(pos) inv:set_size("main", 9) end -local orientate_dispenser = function(pos, placer) +local function orientate_dispenser(pos, placer) -- Not placed by player if not placer then return end @@ -82,7 +82,7 @@ local dispenserdef = { end, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1, inv:get_size("main") do @@ -92,191 +92,206 @@ local dispenserdef = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, _mcl_blast_resistance = 3.5, _mcl_hardness = 3.5, - mesecons = {effector = { - -- Dispense random item when triggered - action_on = function (pos, node) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local droppos, dropdir - if node.name == "mcl_dispensers:dispenser" then - 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} - 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} - end - local dropnode = minetest.get_node(droppos) - local dropnodedef = minetest.registered_nodes[dropnode.name] - local stacks = {} - 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}) + mesecons = { + effector = { + -- Dispense random item when triggered + action_on = function(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local droppos, dropdir + if node.name == "mcl_dispensers:dispenser" then + 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} + 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} end - end - if #stacks >= 1 then - local r = math.random(1, #stacks) - local stack = stacks[r].stack - local dropitem = ItemStack(stack) - dropitem:set_count(1) - local stack_id = stacks[r].stackpos - local stackdef = stack:get_definition() - local iname = stack:get_name() - local igroups = minetest.registered_items[iname].groups + local dropnode = minetest.get_node(droppos) + local dropnodedef = minetest.registered_nodes[dropnode.name] + local stacks = {} + 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}) + end + end + if #stacks >= 1 then + local r = math.random(1, #stacks) + local stack = stacks[r].stack + local dropitem = ItemStack(stack) + dropitem:set_count(1) + local stack_id = stacks[r].stackpos + local stackdef = stack:get_definition() - --[===[ Dispense item ]===] - - -- Hardcoded dispensions -- - - -- Armor, mob heads and pumpkins - if igroups.armor_head or igroups.armor_torso or igroups.armor_legs or igroups.armor_feet then - local armor_type, armor_slot - local armor_dispensed = false - if igroups.armor_head then - armor_type = "armor_head" - armor_slot = 2 - elseif igroups.armor_torso then - armor_type = "armor_torso" - armor_slot = 3 - elseif igroups.armor_legs then - armor_type = "armor_legs" - armor_slot = 4 - elseif igroups.armor_feet then - armor_type = "armor_feet" - armor_slot = 5 + if not stackdef then + return end - local droppos_below = {x=droppos.x, y=droppos.y-1, z=droppos.z} - local dropnode_below = minetest.get_node(droppos_below) - -- Put armor on player or armor stand - local standpos - if dropnode.name == "mcl_armor_stand:armor_stand" then - standpos = droppos - elseif dropnode_below.name == "mcl_armor_stand:armor_stand" then - standpos = droppos_below - end - if standpos then - local dropmeta = minetest.get_meta(standpos) - local dropinv = dropmeta:get_inventory() - if dropinv:room_for_item(armor_type, dropitem) then - dropinv:add_item(armor_type, dropitem) - minetest.registered_nodes["mcl_armor_stand:armor_stand"].on_metadata_inventory_put(standpos) - stack:take_item() - inv:set_stack("main", stack_id, stack) - armor:play_equip_sound(dropitem, nil, standpos) - armor_dispensed = true - end - else - -- Put armor on nearby player - -- First search for player in front of dispenser (check 2 nodes) - local objs1 = minetest.get_objects_inside_radius(droppos, 1) - local objs2 = minetest.get_objects_inside_radius(droppos_below, 1) - local objs_table = {objs1, objs2} - local player - for oi=1, #objs_table do - local objs_inner = objs_table[oi] - for o=1, #objs_inner do - --[[ First player in list is the lucky one. The other player get nothing :-( - If multiple players are close to the dispenser, it can be a bit - -- unpredictable on who gets the armor. ]] - if objs_inner[o]:is_player() then - player = objs_inner[o] + local iname = stack:get_name() + local igroups = stackdef.groups + + --[===[ Dispense item ]===] + + -- Hardcoded dispensions -- + + -- Armor, mob heads and pumpkins + if igroups.armor then + local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z} + + 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 break end end - if player then + if stack:is_empty() then break end end - -- If player found, add armor - if player then - local ainv = minetest.get_inventory({type="detached", name=player:get_player_name().."_armor"}) - local pinv = player:get_inventory() - if ainv:get_stack("armor", armor_slot):is_empty() and pinv:get_stack("armor", armor_slot):is_empty() then - ainv:set_stack("armor", armor_slot, dropitem) - pinv:set_stack("armor", armor_slot, dropitem) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(dropitem, player) - stack:take_item() - inv:set_stack("main", stack_id, stack) - armor_dispensed = true - end - end - - -- Place head or pumpkin as node, if equipping it as armor has failed - if not armor_dispensed then + -- 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}) stack:take_item() - inv:set_stack("main", stack_id, stack) end end end - end - -- Spawn Egg - elseif igroups.spawn_egg then - -- Spawn mob - if not dropnodedef.walkable then - pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } } - minetest.add_entity(droppos, stack:get_name()) - - stack:take_item() inv:set_stack("main", stack_id, stack) - end - -- Generalized dispension - elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then - --[[ _on_dispense(stack, pos, droppos, dropnode, dropdir) - * stack: Itemstack which is dispense - * pos: Position of dispenser - * droppos: Position to which to dispense item - * dropnode: Node of droppos - * dropdir: Drop direction - - _dispense_into_walkable: If true, can dispense into walkable nodes - ]] - if stackdef._on_dispense then - -- Item-specific dispension (if defined) - local od_ret = stackdef._on_dispense(dropitem, pos, droppos, dropnode, dropdir) - if od_ret then - local newcount = stack:get_count() - 1 - stack:set_count(newcount) - inv:set_stack("main", stack_id, stack) - if newcount == 0 then - inv:set_stack("main", stack_id, od_ret) - elseif inv:room_for_item("main", od_ret) then - inv:add_item("main", od_ret) - else - minetest.add_item(droppos, dropitem) + -- 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() + if entity and not entity.child and not entity.gotten then + local entname = entity.name + local pos = obj:get_pos() + local used, texture = false + if entname == "mobs_mc:sheep" then + if entity.drops[2] then + minetest.add_item(pos, entity.drops[2].name .. " " .. math.random(1, 3)) + end + if not entity.color then + entity.color = "unicolor_white" + end + entity.base_texture = { "blank.png", "mobs_mc_sheep.png" } + texture = entity.base_texture + entity.drops = { + { name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2 }, + } + used = true + elseif entname == "mobs_mc:snowman" then + texture = { + "mobs_mc_snowman.png", + "blank.png", "blank.png", + "blank.png", "blank.png", + "blank.png", "blank.png", + } + used = true + elseif entname == "mobs_mc:mooshroom" then + local droppos = vector.offset(pos, 0, 1.4, 0) + if entity.base_texture[1] == "mobs_mc_mooshroom_brown.png" then + minetest.add_item(droppos, "mcl_mushrooms:mushroom_brown 5") + else + minetest.add_item(droppos, "mcl_mushrooms:mushroom_red 5") + end + obj = mcl_util.replace_mob(obj, "mobs_mc:cow") + entity = obj:get_luaentity() + used = true + end + if used then + obj:set_properties({ textures = texture }) + entity.gotten = true + minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true) + stack:add_wear(65535 / stackdef._mcl_diggroups.shearsy.uses) + inv:set_stack("main", stack_id, stack) + break + end end - else + end + + -- Spawn Egg + elseif igroups.spawn_egg then + -- Spawn mob + if not dropnodedef.walkable then + --pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } } + minetest.add_entity(droppos, stack:get_name()) + + stack:take_item() + inv:set_stack("main", stack_id, stack) + end + + -- Generalized dispension + elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then + --[[ _on_dispense(stack, pos, droppos, dropnode, dropdir) + * stack: Itemstack which is dispense + * pos: Position of dispenser + * droppos: Position to which to dispense item + * dropnode: Node of droppos + * dropdir: Drop direction + + _dispense_into_walkable: If true, can dispense into walkable nodes + ]] + if stackdef._on_dispense then + -- Item-specific dispension (if defined) + local od_ret = stackdef._on_dispense(dropitem, pos, droppos, dropnode, dropdir) + if od_ret then + local newcount = stack:get_count() - 1 + stack:set_count(newcount) + inv:set_stack("main", stack_id, stack) + if newcount == 0 then + inv:set_stack("main", stack_id, od_ret) + elseif inv:room_for_item("main", od_ret) then + inv:add_item("main", od_ret) + else + 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)) + end + else + stack:take_item() + inv:set_stack("main", stack_id, stack) + end + else + -- Drop item otherwise + 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 - else - -- Drop item otherwise - minetest.add_item(droppos, dropitem) - stack:take_item() - inv:set_stack("main", stack_id, stack) end + + end - - - end - end, - rules = mesecon.rules.alldirs, - }}, + end, + rules = mesecon.rules.alldirs, + }, + }, on_rotate = on_rotate, } @@ -306,10 +321,11 @@ 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") -horizontal_def.after_place_node = function(pos, placer, itemstack, pointed_thing) +function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dispenser(pos) orientate_dispenser(pos, placer) end + horizontal_def.tiles = { "default_furnace_top.png", "default_furnace_bottom.png", "default_furnace_side.png", "default_furnace_side.png", @@ -347,7 +363,7 @@ minetest.register_node("mcl_dispensers:dispenser_up", up_def) minetest.register_craft({ - output = 'mcl_dispensers:dispenser', + output = "mcl_dispensers:dispenser", recipe = { {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, {"mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble",}, diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.fr.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.fr.tr index 622d0a70e..04ce1ca63 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.fr.tr +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.fr.tr @@ -1,5 +1,5 @@ # textdomain: mcl_dispensers -Dispenser=Dispenser +Dispenser=Distributeur 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 distributeur est un bloc qui agit comme un composant redstone qui, lorsqu'il est alimenté avec une puissance redstone, distribue un article. Il a un conteneur avec 9 emplacements d'inventaire. 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.=Placez le distributeur dans l'une des 6 directions possibles. Le "trou" est l'endroit où les articles sortiront du distributeur. Utilisez le distributeur pour accéder à son inventaire. Insérez les articles que vous souhaitez distribuer. Fournissez au distributeur de l'énergie de redstone une fois pour distribuer un objet aléatoire. The dispenser will do different things, depending on the dispensed item:=Le distributeur fera différentes choses, selon l'article distribué: diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr new file mode 100644 index 000000000..33d1caddf --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.ja.tr @@ -0,0 +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:=ディスペンサーは、放出されるアイテムによって振る舞いが異なる: +• Arrows: Are launched=矢:発射 +• Eggs and snowballs: Are thrown=卵、雪玉:投擲 +• Fire charges: Are fired in a straight line=発火弾:一直線に射撃 +• 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=骨粉:向き合っているブロックに適用 +• 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=頭、カボチャ:プレイヤーや防具立てに装備、またはブロックとして配置 +• Shulker boxes: Are placed as a block=シュルカーボックス:ブロックとして配置 +• TNT: Is placed and ignited=TNT:着火したTNTを設置 +• Flint and steel: Is used to ignite a fire in air and to ignite TNT=火打ち石と打ち金:空気とTNTに着火するために使用 +• Spawn eggs: Will summon the mob they contain=スポーンエッグ:各種mobを召喚 +• Other items: Are simply dropped=その他のアイテム:単純にドロップ +Downwards-Facing Dispenser=下向きディスペンサー +Upwards-Facing Dispenser=上向きディスペンサー +Inventory=インベントリ +9 inventory slots=9つのインベントリスロット +Launches item when powered by redstone power=レッドストーン動力が来ているとアイテムを発射 diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pl.tr b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pl.tr new file mode 100644 index 000000000..ee2b3cffe --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/locale/mcl_dispensers.pl.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_dispensers +Dispenser=Dozownik +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.=Dozownik jest mechanizmem czerwienitowym, który po zasileniu wystrzeli lub wyrzuci przedmiot. Jest on pojemnikiem z 9 miejscami. +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.=Postaw dozownik w jednym z 6 możliwych kierunków. "Dziura" wskazuje z której strony przedmioty będą dozowane. Użyj dozownika, aby zarządzać jego ekwipunkiem. Zasil dozownik czerwienitem aby wyrzucić losowy przedmiot. +The dispenser will do different things, depending on the dispensed item:=Dozownik będzie zachowywał się inaczej w zależności od przedmiotu: +• Arrows: Are launched=• Strzały: są wystrzelone +• Eggs and snowballs: Are thrown=• Jaja i śnieżki: są wyrzucane +• Fire charges: Are fired in a straight line=• Ładunki ogniowe: Są wystrzelone w linii prostej +• Armor: Will be equipped to players and armor stands=• Zbroja: będzie ekwipowana graczom, lub stojakom na zbroję +• Boats: Are placed on water or are dropped=• Łódki: Będą postawione na wodzie, lub wypuszczone +• Minecart: Are placed on rails or are dropped=• Wagoniki: będą postawione na torach, lub upuszczone +• Bone meal: Is applied on the block it is facing=• Mączka kostna: będzie zaaplikowana do bloku +• Empty buckets: Are used to collect a liquid source=• Puste wiadra: będą wykorzystane do zebrania źródła płynu +• Filled buckets: Are used to place a liquid source=• Pełne wiadra: będą wykorzystane do postawienia źródła płynu +• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Głowy, dynie: będą ekwipowane graczom i stojakom na zbroję, lub postawione jako bloki +• Shulker boxes: Are placed as a block=Shulkerowe skrzynie: są postawione jako blok +• TNT: Is placed and ignited=• Trotyl: będzie postawiony i zapalony +• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Krzesiwo: będzie wykorzystane do rozpalenia ognia w powietrzu i zapalenia trotylu +• Spawn eggs: Will summon the mob they contain=• Jaja przywołujące: przywołają moba, którego zawierają +• Other items: Are simply dropped=• Inne przedmioty: zostaną upuszczone +Downwards-Facing Dispenser=Dozownik skierowany w dół +Upwards-Facing Dispenser=Dozownik skierowany w górę +Inventory=Ekwipunek +9 inventory slots=9 miejsc ekwipunku +Launches item when powered by redstone power=Wystrzela przedmiot gdy zasilony czerwienitem diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf b/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf new file mode 100644 index 000000000..13cdb5f5a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/mod.conf @@ -0,0 +1,3 @@ +name = mcl_dispensers +depends = mcl_init, mcl_formspec, mesecons, mcl_sounds, mcl_tnt, mcl_worlds, mcl_core, mcl_nether, mcl_armor_stand, mcl_armor +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt b/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt deleted file mode 100644 index cfd9772fe..000000000 --- a/mods/ITEMS/REDSTONE/mcl_droppers/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_init -mcl_formspec -mesecons -mcl_util -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index 715a85f3d..5f8f94d84 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -8,10 +8,10 @@ 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("mcl_droppers") +local S = minetest.get_translator(minetest.get_current_modname()) -- For after_place_node -local setup_dropper = function(pos) +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"))).."]".. @@ -20,9 +20,9 @@ local setup_dropper = function(pos) "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[current_name;main;3,0.5;3,3;]".. + "list[context;main;3,0.5;3,3;]".. mcl_formspec.get_itemslot_bg(3,0.5,3,3).. - "listring[current_name;main]".. + "listring[context;main]".. "listring[current_player;main]" local meta = minetest.get_meta(pos) meta:set_string("formspec", form) @@ -30,7 +30,7 @@ local setup_dropper = function(pos) inv:set_size("main", 9) end -local orientate_dropper = function(pos, placer) +local function orientate_dropper(pos, placer) -- Not placed by player if not placer then return end @@ -55,7 +55,7 @@ local dropperdef = { sounds = mcl_sounds.node_sound_stone_defaults(), after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for i=1, inv:get_size("main") do @@ -65,7 +65,7 @@ local dropperdef = { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() @@ -98,7 +98,8 @@ local dropperdef = { _mcl_hardness = 3.5, mesecons = {effector = { -- Drop random item when triggered - action_on = function (pos, node) + action_on = function(pos, node) + if not pos then return end local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local droppos @@ -134,7 +135,16 @@ local dropperdef = { -- No container? if not dropped and not dropnodedef.groups.container then -- Drop item normally - minetest.add_item(droppos, dropitem) + 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 @@ -152,7 +162,7 @@ horizontal_def.description = S("Dropper") 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.") -horizontal_def.after_place_node = function(pos, placer, itemstack, pointed_thing) +function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing) setup_dropper(pos) orientate_dropper(pos, placer) end @@ -195,7 +205,7 @@ minetest.register_node("mcl_droppers:dropper_up", up_def) -- Ladies and gentlemen, I present to you: the crafting recipe! minetest.register_craft({ - output = 'mcl_droppers:dropper', + output = "mcl_droppers:dropper", recipe = { {"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",}, {"mcl_core:cobble", "", "mcl_core:cobble",}, diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua deleted file mode 100644 index 1bf968a82..000000000 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init_new.lua +++ /dev/null @@ -1,218 +0,0 @@ ---[[ This mod registers 3 nodes: -- One node for the horizontal-facing dropper (mcl_droppers:dropper) -- One node for the upwards-facing droppers (mcl_droppers:dropper_up) -- One node for the downwards-facing droppers (mcl_droppers:dropper_down) - -3 node definitions are needed because of the way the textures are defined. -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("mcl_droppers") - --- For after_place_node -local setup_dropper = function(pos) - -- Set formspec and inventory - local form = "size[9,8.75]".. - "background[-0.19,-0.25;9.41,9.49;crafting_inventory_9_slots.png]".. - "label[0,4.0;"..minetest.formspec_escape(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[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dropper"))).."]".. - "list[current_name;main;3,0.5;3,3;]".. - "listring[current_name;main]".. - "listring[current_player;main]" - local meta = minetest.get_meta(pos) - meta:set_string("formspec", form) - local inv = meta:get_inventory() - inv:set_size("main", 9) -end - -local orientate_dropper = function(pos, placer) - -- Not placed by player - if not placer then return end - - -- Pitch in degrees - local pitch = placer:get_look_vertical() * (180 / math.pi) - - if pitch > 55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_up"}) - elseif pitch < -55 then - minetest.swap_node(pos, {name="mcl_droppers:dropper_down"}) - end -end - -local on_rotate -if minetest.get_modpath("screwdriver") then - on_rotate = screwdriver.rotate_simple -end - --- Shared core definition table -local dropperdef = { - is_ground_content = false, - sounds = mcl_sounds.node_sound_stone_defaults(), - after_dig_node = function(pos, oldnode, oldmetadata, digger) - local meta = minetest.get_meta(pos) - local meta2 = meta - meta:from_table(oldmetadata) - local inv = meta:get_inventory() - 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) - end - end - meta:from_table(meta2:to_table()) - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return count - end - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - _mcl_blast_resistance = 3.5, - _mcl_hardness = 3.5, - mesecons = {effector = { - -- Drop random item when triggered - action_on = function (pos, node) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local droppos - if node.name == "mcl_droppers:dropper" then - 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} - elseif node.name == "mcl_droppers:dropper_down" then - droppos = {x=pos.x, y=pos.y-1, z=pos.z} - 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 - return - end - local stacks = {} - 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}) - end - end - if #stacks >= 1 then - local r = math.random(1, #stacks) - local stack = stacks[r].stack - 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 - minetest.add_item(droppos, dropitem) - stack:take_item() - inv:set_stack("main", stack_id, stack) - end - end - end, - rules = mesecon.rules.alldirs, - }}, - on_rotate = on_rotate, -} - --- Horizontal dropper - -local horizontal_def = table.copy(dropperdef) -horizontal_def.description = S("Dropper") -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.") -horizontal_def.after_place_node = function(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} - -minetest.register_node("mcl_droppers:dropper", horizontal_def) - --- Down dropper -local down_def = table.copy(dropperdef) -down_def.description = S("Downwards-Facing Dropper") -down_def.after_place_node = setup_dropper -down_def.tiles = { - "default_furnace_top.png", "mcl_droppers_dropper_front_vertical.png", - "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._doc_items_create_entry = false -down_def.drop = "mcl_droppers:dropper" -minetest.register_node("mcl_droppers:dropper_down", down_def) - --- Up dropper --- The up dropper is almost identical to the down dropper, it only differs in textures -local up_def = table.copy(down_def) -up_def.description = S("Upwards-Facing Dropper") -up_def.tiles = { - "mcl_droppers_dropper_front_vertical.png", "default_furnace_bottom.png", - "default_furnace_side.png", "default_furnace_side.png", - "default_furnace_side.png", "default_furnace_side.png" -} -minetest.register_node("mcl_droppers:dropper_up", up_def) - - - --- Ladies and gentlemen, I present to you: the crafting recipe! -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",}, - } -}) - --- Add entry aliases for the Help -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_droppers:dropper", "nodes", "mcl_droppers:dropper_down") - doc.add_entry_alias("nodes", "mcl_droppers:dropper", "nodes", "mcl_droppers:dropper_up") -end - -minetest.register_lbm({ - label = "Update dropper formspecs (0.51.0)", - name = "mcl_droppers:update_formspecs_0_51_0", - nodenames = { "mcl_droppers:dropper", "mcl_droppers:dropper_down", "mcl_droppers:dropper_up" }, - action = function(pos, node) - minetest.registered_nodes[node.name].on_construct(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.ja.tr b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ja.tr new file mode 100644 index 000000000..53f800ba4 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.ja.tr @@ -0,0 +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方向に設置することができ、穴からアイテムをドロップしようとします。ドロッパーを使用し、そのインベントリにアクセスします。ドロッパーにレッドストーンエネルギーを供給すると、ランダムなアイテムがドロップまたは転送されます。 +Downwards-Facing Dropper=下向きドロッパー +Upwards-Facing Dropper=上向きドロッパー +Inventory=インベントリ +9 inventory slots=9つのインベントリスロット +Drops item when powered by redstone power=レッドストーン動力が来るとアイテムをドロップ diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pl.tr b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pl.tr new file mode 100644 index 000000000..7b0fd3c0d --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/locale/mcl_droppers.pl.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_droppers +Dropper=Podajnik +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.=Podajnik jest urządzeniem czerwienitowym i pojemnikiem z 9 miejscami, który po dostarczeniu energii czerwienitowej wyrzuca przedmiot lub umieszcza go w pojemniku przed nim. +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.=Podajniki mogą być skierowane w 6 możliwych kierunkach, przedmioty będą wyrzucane z dziury. Użyj podajnika aby zyskać dostęp do jego ekwipunku. Dostarcz do niego energii czerwienitowej aby sprawić by wyrzucił lub przeniósł losowy przedmiot. +Downwards-Facing Dropper=Podajnik skierowany w dół +Upwards-Facing Dropper=Podajnik skierowany w górę +Inventory=Ekwipunek +9 inventory slots=9 miejsc ekwipunku +Drops item when powered by redstone power=Wyrzuca przedmiot gdy zasilony czerwienitem diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf b/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf new file mode 100644 index 000000000..bbb1c19f2 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_droppers/mod.conf @@ -0,0 +1,3 @@ +name = mcl_droppers +depends = mcl_init, mcl_formspec, mesecons, mcl_util +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_horizontal.png b/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_horizontal.png deleted file mode 100644 index e247e92c8..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_horizontal.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_vertical.png b/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_vertical.png deleted file mode 100644 index 37bc9fa20..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_droppers/textures/mcl_droppers_dropper_front_vertical.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_observers/depends.txt b/mods/ITEMS/REDSTONE/mcl_observers/depends.txt deleted file mode 100644 index 95222145e..000000000 --- a/mods/ITEMS/REDSTONE/mcl_observers/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -mcl_util diff --git a/mods/ITEMS/REDSTONE/mcl_observers/init.lua b/mods/ITEMS/REDSTONE/mcl_observers/init.lua index 932f4f643..6045b5677 100644 --- a/mods/ITEMS/REDSTONE/mcl_observers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_observers/init.lua @@ -1,7 +1,11 @@ -local S = minetest.get_translator("mcl_observers") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_observers = {} +local string = string + +local get_node = minetest.get_node + -- Warning! TODO: Remove this message. -- 'realtime' is experimental feature! It can slow down the everything! -- Please set it to false and restart the game if something's wrong: @@ -11,7 +15,7 @@ local realtime = true local rules_flat = { { x = 0, y = 0, z = -1, spread = true }, } -local get_rules_flat = function(node) +local function get_rules_flat(node) local rules = rules_flat for i=1, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -24,7 +28,7 @@ local rules_up = {{ x = 0, y = -1, z = 0, spread = true }} function mcl_observers.observer_activate(pos) minetest.after(mcl_vars.redstone_tick, function(pos) - local node = minetest.get_node(pos) + local node = get_node(pos) if not node then return end @@ -46,8 +50,8 @@ end -- and update the observer state if needed. -- TODO: Also scan metadata changes. -- TODO: Ignore some node changes. -local observer_scan = function(pos, initialize) - local node = minetest.get_node(pos) +local function observer_scan(pos, initialize) + local node = get_node(pos) local front if node.name == "mcl_observers:observer_up_off" or node.name == "mcl_observers:observer_up_on" then front = vector.add(pos, {x=0, y=1, z=0}) @@ -56,7 +60,7 @@ local observer_scan = function(pos, initialize) else front = vector.add(pos, minetest.facedir_to_dir(node.param2)) end - local frontnode = minetest.get_node(front) + local frontnode = get_node(front) local meta = minetest.get_meta(pos) local oldnode = meta:get_string("node_name") local oldparam2 = meta:get_string("node_param2") @@ -87,14 +91,14 @@ local observer_scan = function(pos, initialize) end -- Vertical orientation (CURRENTLY DISABLED) -local observer_orientate = function(pos, placer) +local function observer_orientate(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 node = get_node(pos) if pitch > 55 then -- player looking upwards -- Observer looking downwards minetest.set_node(pos, {name="mcl_observers:observer_down_off"}) @@ -104,162 +108,167 @@ local observer_orientate = function(pos, placer) end end -mesecon.register_node("mcl_observers:observer", -{ - is_ground_content = false, - sounds = mcl_sounds.node_sound_stone_defaults(), - paramtype2 = "facedir", - on_rotate = false, - _mcl_blast_resistance = 3.5, - _mcl_hardness = 3.5, -}, -{ - description = S("Observer"), - _tt_help = S("Emits redstone pulse when block in front changes"), - _doc_items_longdesc = S("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."), - _doc_items_usagehelp = S("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."), +mesecon.register_node("mcl_observers:observer", { + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + paramtype2 = "facedir", + on_rotate = false, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + }, { + description = S("Observer"), + _tt_help = S("Emits redstone pulse when block in front changes"), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("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."), - groups = {pickaxey=1, material_stone=1, not_opaque=1, }, - tiles = { - "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", - "mcl_observers_observer_side.png", "mcl_observers_observer_side.png", - "mcl_observers_observer_front.png", "mcl_observers_observer_back.png", - }, - mesecons = { receptor = { - state = mesecon.state.off, - rules = get_rules_flat, - }}, - on_construct = function(pos) - if not realtime then - observer_scan(pos, true) - end - end, - after_place_node = observer_orientate, -}, -{ - _doc_items_create_entry = false, - groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, - tiles = { - "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", - "mcl_observers_observer_side.png", "mcl_observers_observer_side.png", - "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", - }, - mesecons = { receptor = { - state = mesecon.state.on, - rules = get_rules_flat, - }}, + groups = {pickaxey=1, material_stone=1, not_opaque=1, }, + tiles = { + "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", + "mcl_observers_observer_side.png", "mcl_observers_observer_side.png", + "mcl_observers_observer_front.png", "mcl_observers_observer_back.png", + }, + mesecons = { + receptor = { + state = mesecon.state.off, + rules = get_rules_flat, + }, + }, + on_construct = function(pos) + if not realtime then + observer_scan(pos, true) + end + end, + after_place_node = observer_orientate, + }, { + _doc_items_create_entry = false, + groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, + tiles = { + "mcl_observers_observer_top.png^[transformR180", "default_furnace_bottom.png", + "mcl_observers_observer_side.png", "mcl_observers_observer_side.png", + "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", + }, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = get_rules_flat, + } + }, - -- VERY quickly disable observer after construction - on_construct = function(pos) - local timer = minetest.get_node_timer(pos) - timer:start(mcl_vars.redstone_tick) - end, - on_timer = function(pos, elapsed) - local node = minetest.get_node(pos) - minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2}) - mesecon.receptor_off(pos, get_rules_flat(node)) - end, -} + -- VERY quickly disable observer after construction + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(mcl_vars.redstone_tick) + end, + on_timer = function(pos, elapsed) + local node = get_node(pos) + minetest.set_node(pos, {name = "mcl_observers:observer_off", param2 = node.param2}) + mesecon.receptor_off(pos, get_rules_flat(node)) + end, + } ) -mesecon.register_node("mcl_observers:observer_down", -{ - is_ground_content = false, - sounds = mcl_sounds.node_sound_stone_defaults(), - groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, - on_rotate = false, - _mcl_blast_resistance = 3.5, - _mcl_hardness = 3.5, - drop = "mcl_observers:observer_off", -}, -{ - tiles = { - "mcl_observers_observer_back.png", "mcl_observers_observer_front.png", - "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", - "mcl_observers_observer_top.png", "mcl_observers_observer_top.png", - }, - mesecons = { receptor = { - state = mesecon.state.off, - rules = rules_down, - }}, - on_construct = function(pos) - if not realtime then - observer_scan(pos, true) - end - end, -}, -{ - _doc_items_create_entry = false, - tiles = { - "mcl_observers_observer_back_lit.png", "mcl_observers_observer_front.png", - "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", - "mcl_observers_observer_top.png", "mcl_observers_observer_top.png", - }, - mesecons = { receptor = { - state = mesecon.state.on, - rules = rules_down, - }}, +mesecon.register_node("mcl_observers:observer_down", { + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, + on_rotate = false, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + drop = "mcl_observers:observer_off", + }, { + tiles = { + "mcl_observers_observer_back.png", "mcl_observers_observer_front.png", + "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", + "mcl_observers_observer_top.png", "mcl_observers_observer_top.png", + }, + mesecons = { + receptor = { + state = mesecon.state.off, + rules = rules_down, + }, + }, + on_construct = function(pos) + if not realtime then + observer_scan(pos, true) + end + end, + }, { + _doc_items_create_entry = false, + tiles = { + "mcl_observers_observer_back_lit.png", "mcl_observers_observer_front.png", + "mcl_observers_observer_side.png^[transformR90", "mcl_observers_observer_side.png^[transformR90", + "mcl_observers_observer_top.png", "mcl_observers_observer_top.png", + }, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = rules_down, + }, + }, - -- VERY quickly disable observer after construction - on_construct = function(pos) - local timer = minetest.get_node_timer(pos) - timer:start(mcl_vars.redstone_tick) - end, - on_timer = function(pos, elapsed) - local node = minetest.get_node(pos) - minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2}) - mesecon.receptor_off(pos, rules_down) - end, -}) + -- VERY quickly disable observer after construction + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(mcl_vars.redstone_tick) + end, + on_timer = function(pos, elapsed) + local node = get_node(pos) + minetest.set_node(pos, {name = "mcl_observers:observer_down_off", param2 = node.param2}) + mesecon.receptor_off(pos, rules_down) + end, + } +) -mesecon.register_node("mcl_observers:observer_up", -{ - is_ground_content = false, - sounds = mcl_sounds.node_sound_stone_defaults(), - groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, - on_rotate = false, - _mcl_blast_resistance = 3.5, - _mcl_hardness = 3.5, - drop = "mcl_observers:observer_off", -}, -{ - tiles = { - "mcl_observers_observer_front.png", "mcl_observers_observer_back.png", - "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", - "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", - }, - mesecons = { receptor = { - state = mesecon.state.off, - rules = rules_up, - }}, - on_construct = function(pos) - if not realtime then - observer_scan(pos, true) - end - end, -}, -{ - _doc_items_create_entry = false, - tiles = { - "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", - "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", - "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", - }, - mesecons = { receptor = { - state = mesecon.state.on, - rules = rules_up, - }}, +mesecon.register_node("mcl_observers:observer_up", { + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + groups = {pickaxey=1, material_stone=1, not_opaque=1, not_in_creative_inventory=1 }, + on_rotate = false, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + drop = "mcl_observers:observer_off", + }, { + tiles = { + "mcl_observers_observer_front.png", "mcl_observers_observer_back.png", + "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", + "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", + }, + mesecons = { + receptor = { + state = mesecon.state.off, + rules = rules_up, + }, + }, + on_construct = function(pos) + if not realtime then + observer_scan(pos, true) + end + end, + }, { + _doc_items_create_entry = false, + tiles = { + "mcl_observers_observer_front.png", "mcl_observers_observer_back_lit.png", + "mcl_observers_observer_side.png^[transformR270", "mcl_observers_observer_side.png^[transformR270", + "mcl_observers_observer_top.png^[transformR180", "mcl_observers_observer_top.png^[transformR180", + }, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = rules_up, + }, + }, - -- VERY quickly disable observer after construction - on_construct = function(pos) - local timer = minetest.get_node_timer(pos) - timer:start(mcl_vars.redstone_tick) - end, - on_timer = function(pos, elapsed) - minetest.set_node(pos, {name = "mcl_observers:observer_up_off"}) - mesecon.receptor_off(pos, rules_up) - end, -}) + -- VERY quickly disable observer after construction + on_construct = function(pos) + local timer = minetest.get_node_timer(pos) + timer:start(mcl_vars.redstone_tick) + end, + on_timer = function(pos, elapsed) + minetest.set_node(pos, {name = "mcl_observers:observer_up_off"}) + mesecon.receptor_off(pos, rules_up) + end, + } +) minetest.register_craft({ output = "mcl_observers:observer_off", @@ -267,7 +276,7 @@ minetest.register_craft({ { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mcl_nether:quartz", "mesecons:redstone", "mesecons:redstone" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, - } + }, }) minetest.register_craft({ output = "mcl_observers:observer_off", @@ -275,7 +284,7 @@ minetest.register_craft({ { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, { "mesecons:redstone", "mesecons:redstone", "mcl_nether:quartz" }, { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, - } + }, }) if realtime then @@ -286,138 +295,138 @@ if realtime then mcl_observers.remove_node = minetest.remove_node mcl_observers.bulk_set_node = minetest.bulk_set_node - minetest.add_node=function(pos,node) + function minetest.add_node(pos,node) mcl_observers.add_node(pos,node) - local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) + local n = get_node({x=pos.x+1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) + n = get_node({x=pos.x-1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z+1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z-1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1}) end - n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y-1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y+1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z}) end end - minetest.set_node=function(pos,node) + function minetest.set_node(pos,node) mcl_observers.set_node(pos,node) - local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) + local n = get_node({x=pos.x+1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) + n = get_node({x=pos.x-1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z+1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z-1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1}) end - n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y-1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y+1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z}) end end - minetest.swap_node=function(pos,node) + function minetest.swap_node(pos,node) mcl_observers.swap_node(pos,node) - local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) + local n = get_node({x=pos.x+1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) + n = get_node({x=pos.x-1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z+1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z-1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1}) end - n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y-1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y+1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z}) end end - minetest.remove_node=function(pos) + function minetest.remove_node(pos) mcl_observers.remove_node(pos) - local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) + local n = get_node({x=pos.x+1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) + n = get_node({x=pos.x-1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z+1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z-1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1}) end - n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y-1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y+1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z}) end end - minetest.bulk_set_node=function(lst, node) + function minetest.bulk_set_node(lst, node) mcl_observers.bulk_set_node(lst, node) for _, pos in pairs(lst) do - local n=minetest.get_node({x=pos.x+1,y=pos.y,z=pos.z}) + local n = get_node({x=pos.x+1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==-1 then mcl_observers.observer_activate({x=pos.x+1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x-1,y=pos.y,z=pos.z}) + n = get_node({x=pos.x-1,y=pos.y,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).x==1 then mcl_observers.observer_activate({x=pos.x-1,y=pos.y,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z+1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z+1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==-1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z+1}) end - n=minetest.get_node({x=pos.x,y=pos.y,z=pos.z-1}) + n = get_node({x=pos.x,y=pos.y,z=pos.z-1}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_o" and minetest.facedir_to_dir(n.param2).z==1 then mcl_observers.observer_activate({x=pos.x,y=pos.y,z=pos.z-1}) end - n=minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y-1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_u" then mcl_observers.observer_activate({x=pos.x,y=pos.y-1,z=pos.z}) end - n=minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + n = get_node({x=pos.x,y=pos.y+1,z=pos.z}) if n and n.name and string.sub(n.name,1,24)=="mcl_observers:observer_d" then mcl_observers.observer_activate({x=pos.x,y=pos.y+1,z=pos.z}) end @@ -454,7 +463,7 @@ minetest.register_lbm({ "mcl_observers:observer_down_on", "mcl_observers:observer_up_on", }, - run_at_every_load = true, + run_at_every_load = true, action = function(pos) minetest.after(1, mcl_observers.observer_activate, {x=pos.x, y=pos.y, z=pos.z}) end, diff --git a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr new file mode 100644 index 000000000..b8acdf1e6 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.ja.tr @@ -0,0 +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=前方のブロックが変更されると、レッドストーンパルスを送信 diff --git a/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pl.tr b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pl.tr new file mode 100644 index 000000000..9c789be00 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/locale/mcl_observers.pl.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_observers +Observer=Detektor +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.=Detektor jest mechanizmem czerwienitowym, który obserwuje blok przed sobą i wysyła krótki puls energii czerwienitowej gdy blok ten się zmienia. +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.=Postaw detektor przed blokiem, który chcesz obserwować z "twarzą" wskazującą na ten blok. Strzałka wskazuje na stronę z wyjściem, która jest po przeciwnej stronie do "twarzy". Możesz postawić tutaj czerwienit lub dowolny inny komponent. +Emits redstone pulse when block in front changes=Wysyła sygnał czerwienitowy gdy blok przed nim się zmienia + diff --git a/mods/ITEMS/REDSTONE/mcl_observers/mod.conf b/mods/ITEMS/REDSTONE/mcl_observers/mod.conf new file mode 100644 index 000000000..fce00191a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_observers/mod.conf @@ -0,0 +1,2 @@ +name = mcl_observers +depends = mesecons, mcl_util diff --git a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_side.png b/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_side.png deleted file mode 100644 index 84cd4065d..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_side.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_top.png b/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_top.png deleted file mode 100644 index 73dab21be..000000000 Binary files a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_top.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mcl_target/init.lua b/mods/ITEMS/REDSTONE/mcl_target/init.lua new file mode 100644 index 000000000..268c6ebe3 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/init.lua @@ -0,0 +1,70 @@ +local S = minetest.get_translator("mcl_target") + +local mod_farming = minetest.get_modpath("mcl_farming") + +mcl_target = {} + +function mcl_target.hit(pos, time) + minetest.set_node(pos, {name="mcl_target:target_on"}) + mesecon.receptor_on(pos, mesecon.rules.alldirs) + + local timer = minetest.get_node_timer(pos) + timer:start(time) +end + +minetest.register_node("mcl_target:target_off", { + description = S("Target"), + _doc_items_longdesc = S("A target is a block that provides a temporary redstone charge when hit by a projectile."), + _doc_items_usagehelp = S("Throw a projectile on the target to activate it."), + tiles = {"mcl_target_target_top.png", "mcl_target_target_top.png", "mcl_target_target_side.png"}, + groups = {hoey = 1}, + sounds = mcl_sounds.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.1}, + }), + mesecons = { + receptor = { + state = mesecon.state.off, + rules = mesecon.rules.alldirs, + }, + }, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, +}) + +minetest.register_node("mcl_target:target_on", { + description = S("Target"), + _doc_items_create_entry = false, + tiles = {"mcl_target_target_top.png", "mcl_target_target_top.png", "mcl_target_target_side.png"}, + groups = {hoey = 1, not_in_creative_inventory = 1}, + drop = "mcl_target:target_off", + sounds = mcl_sounds.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.1}, + }), + on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + if node.name == "mcl_target:target_on" then --has not been dug + minetest.set_node(pos, {name="mcl_target:target_off"}) + mesecon.receptor_off(pos, mesecon.rules.alldirs) + end + end, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = mesecon.rules.alldirs, + }, + }, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, +}) + + +if mod_farming then + minetest.register_craft({ + output = "mcl_target:target_off", + recipe = { + {"", "mesecons:redstone", ""}, + {"mesecons:redstone", "mcl_farming:hay_block", "mesecons:redstone"}, + {"", "mesecons:redstone", ""}, + }, + }) +end \ No newline at end of file diff --git a/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.fr.tr b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.fr.tr new file mode 100644 index 000000000..6c558683d --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_target +Target=Cible +A target is a block that provides a temporary redstone charge when hit by a projectile.=La cible est un bloc qui se comporte comme une source d'énergie temporaire quand elle est frappée par un projectile. +Throw a projectile on the target to activate it.=Lancer un projectile sur la cible pour l'activer. \ No newline at end of file diff --git a/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.tr b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.tr new file mode 100644 index 000000000..53109f675 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/mcl_target.ja.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/mcl_target/locale/template.txt b/mods/ITEMS/REDSTONE/mcl_target/locale/template.txt new file mode 100644 index 000000000..18bc7708c --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/locale/template.txt @@ -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/mcl_target/mod.conf b/mods/ITEMS/REDSTONE/mcl_target/mod.conf new file mode 100644 index 000000000..16f70ed12 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mcl_target/mod.conf @@ -0,0 +1,3 @@ +name = mcl_target +author = AFCMS +depends = mesecons, mcl_sounds \ No newline at end of file diff --git a/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua b/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua index f3479ce59..34202aecd 100644 --- a/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua +++ b/mods/ITEMS/REDSTONE/mesecons/actionqueue.lua @@ -1,3 +1,5 @@ +local table = table + mesecon.queue.actions={} -- contains all ActionQueue actions function mesecon.queue:add_function(name, func) @@ -22,7 +24,7 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior local toremove = nil -- Otherwise, add the action to the queue if overwritecheck then -- check if old action has to be overwritten / removed: - for i, ac in ipairs(mesecon.queue.actions) do + for i, ac in pairs(mesecon.queue.actions) do if(vector.equals(pos, ac.pos) and mesecon.cmpAny(overwritecheck, ac.owcheck)) then toremove = i @@ -31,7 +33,7 @@ function mesecon.queue:add_action(pos, func, params, time, overwritecheck, prior end end - if (toremove ~= nil) then + if toremove then table.remove(mesecon.queue.actions, toremove) end @@ -43,7 +45,7 @@ end -- this makes sure that resuming mesecons circuits when restarting minetest works fine -- However, even that does not work in some cases, that's why we delay the time the globalsteps -- start to be execute by 5 seconds -local get_highest_priority = function (actions) +local function get_highest_priority(actions) local highestp = -1 local highesti for i, ac in ipairs(actions) do @@ -87,6 +89,8 @@ minetest.register_globalstep(function (dtime) end) function mesecon.queue:execute(action) + if not action.pos then return end + -- ignore if action queue function name doesn't exist, -- (e.g. in case the action queue savegame was written by an old mesecons version) if mesecon.queue.funcs[action.func] then diff --git a/mods/ITEMS/REDSTONE/mesecons/depends.txt b/mods/ITEMS/REDSTONE/mesecons/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/REDSTONE/mesecons/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons/init.lua b/mods/ITEMS/REDSTONE/mesecons/init.lua index 93d299f06..18965287e 100644 --- a/mods/ITEMS/REDSTONE/mesecons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons/init.lua @@ -75,10 +75,10 @@ mesecon.queue:add_function("receptor_on", function (pos, rules) rules = rules or mesecon.rules.default -- Call turnon on all linking positions - for _, rule in ipairs(mesecon.flattenrules(rules)) do + for _, rule in pairs(mesecon.flattenrules(rules)) do local np = vector.add(pos, rule) local rulenames = mesecon.rules_link_rule_all(pos, rule) - for _, rulename in ipairs(rulenames) do + for _, rulename in pairs(rulenames) do mesecon.turnon(np, rulename) end end diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index 7986c2908..d7983d353 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -47,28 +47,34 @@ -- mesecon.rotate_rules_down(rules) -- These functions return rules that have been rotated in the specific direction +local equals = vector.equals +local get_node_force = mesecon.get_node_force +local invertRule = mesecon.invertRule +local copy, insert = table.copy, table.insert +local registered_nodes = minetest.registered_nodes + -- General function mesecon.get_effector(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.effector then - return minetest.registered_nodes[nodename].mesecons.effector + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.effector then + return registered_nodes[nodename].mesecons.effector end end function mesecon.get_receptor(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.receptor then - return minetest.registered_nodes[nodename].mesecons.receptor + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.receptor then + return registered_nodes[nodename].mesecons.receptor end end function mesecon.get_conductor(nodename) - if minetest.registered_nodes[nodename] - and minetest.registered_nodes[nodename].mesecons - and minetest.registered_nodes[nodename].mesecons.conductor then - return minetest.registered_nodes[nodename].mesecons.conductor + if registered_nodes[nodename] + and registered_nodes[nodename].mesecons + and registered_nodes[nodename].mesecons.conductor then + return registered_nodes[nodename].mesecons.conductor end end @@ -103,13 +109,14 @@ end -- Receptors -- Nodes that can power mesecons -function mesecon.is_receptor_on(nodename) +local function is_receptor_on(nodename) local receptor = mesecon.get_receptor(nodename) if receptor and receptor.state == mesecon.state.on then return true end return false end +mesecon.is_receptor_on = is_receptor_on function mesecon.is_receptor_off(nodename) local receptor = mesecon.get_receptor(nodename) @@ -127,11 +134,11 @@ function mesecon.is_receptor(nodename) return false end -function mesecon.receptor_get_rules(node) +local function receptor_get_rules(node) local receptor = mesecon.get_receptor(node.name) if receptor then local rules = receptor.rules - if type(rules) == 'function' then + if type(rules) == "function" then return rules(node) elseif rules then return rules @@ -140,6 +147,7 @@ function mesecon.receptor_get_rules(node) return mesecon.rules.default end +mesecon.receptor_get_rules = receptor_get_rules -- Effectors -- Nodes that can be powered by mesecons @@ -169,9 +177,9 @@ end function mesecon.effector_get_rules(node) local effector = mesecon.get_effector(node.name) - if effector then + if effector and effector.rules then local rules = effector.rules - if type(rules) == 'function' then + if type(rules) == "function" then return rules(node) elseif rules then return rules @@ -186,7 +194,7 @@ end -- Activation: mesecon.queue:add_function("activate", function (pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -198,7 +206,7 @@ end) function mesecon.activate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.activate(pos, node, rule, depth + 1) end return @@ -209,7 +217,7 @@ end -- Deactivation mesecon.queue:add_function("deactivate", function (pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -221,7 +229,7 @@ end) function mesecon.deactivate(pos, node, rulename, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.deactivate(pos, node, rule, depth + 1) end return @@ -232,7 +240,7 @@ end -- Change mesecon.queue:add_function("change", function (pos, rulename, changetype) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if not node then return end local effector = mesecon.get_effector(node.name) @@ -244,7 +252,7 @@ end) function mesecon.changesignal(pos, node, rulename, newstate, depth) if rulename == nil then - for _,rule in ipairs(mesecon.effector_get_rules(node)) do + for _,rule in pairs(mesecon.effector_get_rules(node)) do mesecon.changesignal(pos, node, rule, newstate, depth + 1) end return @@ -321,7 +329,7 @@ function mesecon.get_conductor_on(node_off, rulename) return conductor.states[tonumber(binstate,2)+1] end end - return offstate + return conductor.offstate end function mesecon.get_conductor_off(node_on, rulename) @@ -337,14 +345,14 @@ function mesecon.get_conductor_off(node_on, rulename) return conductor.states[tonumber(binstate,2)+1] end end - return onstate + return conductor.onstate end function mesecon.conductor_get_rules(node) local conductor = mesecon.get_conductor(node.name) if conductor then local rules = conductor.rules - if type(rules) == 'function' then + if type(rules) == "function" then return rules(node) elseif rules then return rules @@ -356,15 +364,15 @@ end -- some more general high-level stuff function mesecon.is_power_on(pos, rulename) - local node = mesecon.get_node_force(pos) - if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then + local node = get_node_force(pos) + if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then return true end return false end function mesecon.is_power_off(pos, rulename) - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then return true end @@ -381,18 +389,16 @@ function mesecon.turnon(pos, link) local depth = 1 while frontiers[1] do local f = table.remove(frontiers, 1) - local node = mesecon.get_node_force(f.pos) + local node = get_node_force(f.pos) - if not node then - -- Area does not exist; do nothing - elseif mesecon.is_conductor_off(node, f.link) then + if node and mesecon.is_conductor_off(node, f.link) then local rules = mesecon.conductor_get_rules(node) -- Call turnon on neighbors - for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + for _, r in pairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - table.insert(frontiers, {pos = np, link = l}) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + insert(frontiers, {pos = np, link = l}) end end @@ -406,12 +412,12 @@ function mesecon.turnon(pos, link) if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then -- Call turnon on neighbors -- Warning: A LOT of nodes need to be looked at for this to work - for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do + for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do local np = vector.add(f.pos, r) - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - local nlink = table.copy(l) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + local nlink = copy(l) nlink.spread = false - table.insert(frontiers, {pos = np, link = nlink}) + insert(frontiers, {pos = np, link = nlink}) end end end @@ -443,33 +449,31 @@ function mesecon.turnoff(pos, link) local depth = 1 while frontiers[1] do local f = table.remove(frontiers, 1) - local node = mesecon.get_node_force(f.pos) + local node = get_node_force(f.pos) - if not node then - -- No-op - elseif mesecon.is_conductor_on(node, f.link) then + if node and mesecon.is_conductor_on(node, f.link) then local rules = mesecon.conductor_get_rules(node) - for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do + for _, r in pairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) -- Check if an onstate receptor is connected. If that is the case, -- abort this turnoff process by returning false. `receptor_off` will -- discard all the changes that we made in the voxelmanip: - for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do - if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then + for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do + if is_receptor_on(get_node_force(np).name) then return false end end -- Call turnoff on neighbors - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - table.insert(frontiers, {pos = np, link = l}) + for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do + insert(frontiers, {pos = np, link = l}) end end mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link)) elseif mesecon.is_effector(node.name) then - table.insert(signals, { + insert(signals, { pos = f.pos, node = node, link = f.link, @@ -480,21 +484,22 @@ function mesecon.turnoff(pos, link) if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then -- Call turnoff on neighbors -- Warning: A LOT of nodes need to be looked at for this to work - for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do - local np = vector.add(f.pos, r) - local n = mesecon.get_node_force(np) - if mesecon.is_receptor_on(n.name) then - local receptorrules = mesecon.receptor_get_rules(n) + local fpos = f.pos + for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do + local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z} + local n = get_node_force(np) + if n and is_receptor_on(n.name) then + local receptorrules = receptor_get_rules(n) for _, rr in pairs(receptorrules) do - if rr.spread and vector.equals(mesecon.invertRule(rr), r) then + if rr.spread and equals(invertRule(rr), r) then return false end end end - for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do - local nlink = table.copy(l) + for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do + local nlink = copy(l) nlink.spread = false - table.insert(frontiers, {pos = np, link = nlink}) + insert(frontiers, {pos = np, link = nlink}) end end end @@ -502,7 +507,7 @@ function mesecon.turnoff(pos, link) depth = depth + 1 end - for _, sig in ipairs(signals) do + for _, sig in pairs(signals) do mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth) if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth) @@ -516,19 +521,20 @@ end -- outputnode (receptor or conductor) at position `output` and has an output in direction `rule` function mesecon.rules_link_rule_all(output, rule) local input = vector.add(output, rule) - local inputnode = mesecon.get_node_force(input) + if not input then return {} end + local inputnode = get_node_force(input) local inputrules = mesecon.get_any_inputrules(inputnode) if not inputrules then return {} end local rules = {} - for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do + for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do -- Check if input accepts from output - if vector.equals(vector.add(input, inputrule), output) then - local newrule = table.copy(inputrule) + if equals(vector.add(input, inputrule), output) then + local newrule = copy(inputrule) newrule.spread = rule.spread - table.insert(rules, newrule) + insert(rules, newrule) end end @@ -539,19 +545,19 @@ end -- inputnode (effector or conductor) at position `input` and has an input in direction `rule` function mesecon.rules_link_rule_all_inverted(input, rule) local output = vector.add(input, rule) - local outputnode = mesecon.get_node_force(output) + local outputnode = get_node_force(output) local outputrules = mesecon.get_any_outputrules(outputnode) if not outputrules then return {} end local rules = {} - for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do - if vector.equals(vector.add(output, outputrule), input) then - local newrule = table.copy(outputrule) - newrule = mesecon.invertRule(newrule) + for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do + if equals(vector.add(output, outputrule), input) then + local newrule = copy(outputrule) + newrule = invertRule(newrule) newrule.spread = rule.spread - table.insert(rules, newrule) + insert(rules, newrule) end end return rules @@ -562,7 +568,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) if depth > 1 then return false, false end - local node = mesecon.get_node_force(pos) + local node = get_node_force(pos) local rules = mesecon.get_any_inputrules(node) if not rules then return false, false @@ -578,23 +584,23 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) local spread = false - for _, rname in ipairs(rulenames) do + for _, rname in pairs(rulenames) do local np = vector.add(pos, rname) - local nn = mesecon.get_node_force(np) - if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) - or mesecon.is_receptor_on (nn.name)) then - if not vector.equals(home_pos, np) then + local nn = get_node_force(np) + if (mesecon.is_conductor_on (nn, invertRule(rname)) + or is_receptor_on (nn.name)) then + if not equals(home_pos, np) then local rulez = mesecon.get_any_outputrules(nn) local spread_tmp = false for r=1, #rulez do - if vector.equals(mesecon.invertRule(rname), rulez[r]) then + if equals(invertRule(rname), rulez[r]) then if rulez[r].spread then spread_tmp = true end end end if depth == 0 or spread_tmp then - table.insert(sourcepos, np) + insert(sourcepos, np) if spread_tmp then spread = true end @@ -612,7 +618,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos) local spread = false if not rule then - for _, rule in ipairs(mesecon.flattenrules(rules)) do + for _, rule in pairs(mesecon.flattenrules(rules)) do local spread_temp local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth) diff --git a/mods/ITEMS/REDSTONE/mesecons/mod.conf b/mods/ITEMS/REDSTONE/mesecons/mod.conf new file mode 100644 index 000000000..94be76509 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons/mod.conf @@ -0,0 +1,3 @@ +name = mesecons +depends = mcl_sounds, mcl_core +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons/presets.lua b/mods/ITEMS/REDSTONE/mesecons/presets.lua index f624c52fe..d9d8418d8 100644 --- a/mods/ITEMS/REDSTONE/mesecons/presets.lua +++ b/mods/ITEMS/REDSTONE/mesecons/presets.lua @@ -96,12 +96,12 @@ local function rules_from_dir(ruleset, dir) if dir.z == -1 then return ruleset.zn end end -mesecon.rules.buttonlike_get = function(node) +function mesecon.rules.buttonlike_get(node) local dir = minetest.facedir_to_dir(node.param2) return rules_from_dir(rules_buttonlike, dir) end -mesecon.rules.wallmounted_get = function(node) +function mesecon.rules.wallmounted_get(node) local dir = minetest.wallmounted_to_dir(node.param2) return rules_from_dir(rules_wallmounted, dir) end diff --git a/mods/ITEMS/REDSTONE/mesecons/services.lua b/mods/ITEMS/REDSTONE/mesecons/services.lua index 9addda8bd..7d1fce2d8 100644 --- a/mods/ITEMS/REDSTONE/mesecons/services.lua +++ b/mods/ITEMS/REDSTONE/mesecons/services.lua @@ -1,6 +1,6 @@ -- Dig and place services -mesecon.on_placenode = function(pos, node) +function mesecon.on_placenode(pos, node) mesecon.execute_autoconnect_hooks_now(pos, node) -- Receptors: Send on signal when active @@ -70,14 +70,14 @@ mesecon.on_placenode = function(pos, node) end end -mesecon.on_dignode = function(pos, node) +function mesecon.on_dignode(pos, node) if mesecon.is_conductor_on(node) then mesecon.receptor_off(pos, mesecon.conductor_get_rules(node)) elseif mesecon.is_receptor_on(node.name) then mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) end if minetest.get_item_group(node.name, "opaque") == 1 then - local sources = mesecon.is_powered(pos) + --local sources = mesecon.is_powered(pos) local neighbors = mesecon.mcl_get_neighbors(pos) for n=1, #neighbors do local npos = neighbors[n].pos @@ -95,7 +95,7 @@ mesecon.on_dignode = function(pos, node) mesecon.execute_autoconnect_hooks_queue(pos, node) end -mesecon.on_blastnode = function(pos, node) +function mesecon.on_blastnode(pos, node) local node = minetest.get_node(pos) minetest.remove_node(pos) mesecon.on_dignode(pos, node) diff --git a/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt b/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt deleted file mode 100644 index acaa92412..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_alias/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf b/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf new file mode 100644 index 000000000..533d54c80 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_alias/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_alias +depends = mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_button/depends.txt b/mods/ITEMS/REDSTONE/mesecons_button/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_button/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_button/init.lua b/mods/ITEMS/REDSTONE/mesecons_button/init.lua index 377a24c00..275cac2e2 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_button/init.lua @@ -1,7 +1,7 @@ -- WALL BUTTON -- A button that when pressed emits power for a short moment and then turns off again -local S = minetest.get_translator("mesecons_button") +local S = minetest.get_translator(minetest.get_current_modname()) local button_sounds = {} -- remember button push sounds @@ -21,7 +21,7 @@ local boxes_on = { } -- Push the button -mesecon.push_button = function(pos, node) +function mesecon.push_button(pos, node) -- No-op if button is already pushed if mesecon.is_receptor_on(node) then return @@ -37,7 +37,7 @@ mesecon.push_button = function(pos, node) timer:start(def._mcl_button_timer) end -local on_button_place = function(itemstack, placer, pointed_thing) +local function on_button_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" then -- no interaction possible with entities return itemstack @@ -86,12 +86,13 @@ end local buttonuse = S("Use the button to push it.") -mesecon.register_button = function(basename, description, texture, recipeitem, sounds, plusgroups, button_timer, push_by_arrow, longdesc, button_sound) +function mesecon.register_button(basename, description, texture, recipeitem, sounds, plusgroups, button_timer, push_by_arrow, longdesc, button_sound) local groups_off = table.copy(plusgroups) groups_off.attached_node=1 groups_off.dig_by_water=1 groups_off.destroy_by_lava_flow=1 groups_off.dig_by_piston=1 + groups_off.dig_immediate_piston=1 groups_off.button=1 -- button (off) local groups_on = table.copy(groups_off) @@ -103,6 +104,14 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s end button_sounds["mesecons_button:button_"..basename.."_off"] = button_sound + if not longdesc then + if groups_off.material_wood ~= 0 then + longdesc = S("A wooden button is a redstone component made out of wood which can be pushed to provide redstone power. When pushed, it powers adjacent redstone components for 1.5 seconds. Wooden buttons may also be pushed by arrows.") + 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) + end + end + if push_by_arrow then groups_off.button_push_by_arrow = 1 groups_on.button_push_by_arrow = 1 @@ -112,7 +121,7 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s if push_by_arrow then tt = tt .. "\n" .. S("Pushable by arrow") end - minetest.register_node("mesecons_button:button_"..basename.."_off", { + minetest.register_node(":mesecons_button:button_"..basename.."_off", { drawtype = "nodebox", tiles = {texture}, wield_image = "mesecons_button_wield_mask.png^"..texture.."^mesecons_button_wield_mask.png^[makealpha:255,126,126", @@ -132,7 +141,7 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s _doc_items_usagehelp = buttonuse, on_place = on_button_place, node_placement_prediction = "", - on_rightclick = function (pos, node) + on_rightclick = function(pos, node) mesecon.push_button(pos, node) end, sounds = sounds, @@ -147,7 +156,7 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s _mcl_hardness = 0.5, }) - minetest.register_node("mesecons_button:button_"..basename.."_on", { + minetest.register_node(":mesecons_button:button_"..basename.."_on", { drawtype = "nodebox", tiles = {texture}, wield_image = "mesecons_button_wield_mask.png^"..texture.."^mesecons_button_wield_mask.png^[makealpha:255,126,126", @@ -159,7 +168,7 @@ mesecon.register_button = function(basename, description, texture, recipeitem, s sunlight_propagates = true, node_box = boxes_on, groups = groups_on, - drop = 'mesecons_button:button_'..basename..'_off', + drop = "mesecons_button:button_"..basename.."_off", _doc_items_create_entry = false, node_placement_prediction = "", sounds = sounds, @@ -216,6 +225,18 @@ mesecon.register_button( S("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."), "mesecons_button_push") +mesecon.register_button( + "polished_blackstone", + S("Polished Blackstone Button"), + "mcl_blackstone_polished.png", + "mcl_blackstone:blackstone_polished", + mcl_sounds.node_sound_stone_defaults(), + {material_stone=1,handy=1,pickaxey=1}, + 1, + false, + S("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."), + "mesecons_button_push") + local woods = { { "wood", "mcl_core:wood", "default_wood.png", S("Oak Button") }, { "acaciawood", "mcl_core:acaciawood", "default_acacia_wood.png", S("Acacia Button") }, @@ -223,6 +244,10 @@ local woods = { { "darkwood", "mcl_core:darkwood", "mcl_core_planks_big_oak.png", S("Dark Oak Button") }, { "sprucewood", "mcl_core:sprucewood", "mcl_core_planks_spruce.png", S("Spruce Button") }, { "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Button") }, + + { "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Button") }, + { "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "mcl_crimson_crimson_hyphae_wood.png", S("Crimson Button") }, + { "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "mcl_crimson_warped_hyphae_wood.png", S("Warped Button") }, } for w=1, #woods do @@ -235,7 +260,7 @@ for w=1, #woods do {material_wood=1,handy=1,axey=1}, 1.5, true, - 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."), + nil, "mesecons_button_push_wood") minetest.register_craft({ 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 96f963b4b..1d844bd36 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.fr.tr @@ -2,13 +2,18 @@ Use the button to push it.=Utilisez le bouton pour le pousser. Stone Button=Bouton de pierre 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.=Un bouton en pierre est un composant Redstone en pierre qui peut être poussé pour fournir de la puissance Redstone. Lorsqu'il est poussé, il alimente les composants Redstone adjacents pendant 1 seconde. -Oak Button=Bouton en Chêne -Acacia Button=Bouton en Acacia -Birch Button=Bouton en Bouleau -Dark Oak Button=Bouton en Chêne Noir -Spruce Button=Bouton en Sapin -Jungle Button=Bouton en Acajou +Polished Blackstone Button=Bouton de pierre noire +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.=Un bouton en pierre noire est un composant Redstone en pierre noire qui peut être poussé pour fournir de la puissance Redstone. Lorsqu'il est poussé, il alimente les composants Redstone adjacents pendant 1 seconde. +Oak Button=Bouton en chêne +Acacia Button=Bouton en acacia +Birch Button=Bouton en bouleau +Dark Oak Button=Bouton en chêne noir +Spruce Button=Bouton en sapin +Jungle Button=Bouton en acajou +Mangrove Button=Bouton en palétuvier +Crimson Button=Bouton écarlate +Warped Button=Bouton tordu 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.=Un bouton en bois est un composant de redstone en bois qui peut être poussé pour fournir une puissance de redstone. Lorsqu'il est poussé, il alimente les composants Redstone adjacents pendant 1,5 seconde. Les boutons en bois peuvent également être poussés par des flèches. Provides redstone power when pushed=Fournit une puissance de redstone lorsqu'il est poussé -Push duration: @1s=Durée de poussée: @1s +Push duration: @1s=Durée de poussée : @1s Pushable by arrow=Poussable par une flèche diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr new file mode 100644 index 000000000..036568fad --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mesecons_button +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秒間 動作させます。 +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.=木製のボタンは木でできたレッドストーン部品で、押すことでレッドストーン動力を提供できます。押すと、隣接するレッドストーン部品を 1.5秒間 動作させます。木製のボタンは、矢でも押せます。 +Provides redstone power when pushed=押すとレッドストーン動力を提供 +Push duration: @1s=押下持続時間: @1秒 +Pushable by arrow=矢で押下可能 diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pl.tr b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pl.tr new file mode 100644 index 000000000..f6d895ad0 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/mesecons_button.pl.tr @@ -0,0 +1,14 @@ +# textdomain: mesecons_button +Use the button to push it.=Użyj przycisku by go wcisnąć. +Stone Button=Kamienny przycisk +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.=Kamienny przycisk jest mechanizmem czerwienitowym, który można nacisnąć by dostarczył on energię czerwienitową. Po naciśnięciu zasila on przyległy mechanizm czerwienitowy przez 1 sekundę. +Oak Button=Dębowy przycisk +Acacia Button=Akacjowy przycisk +Birch Button=Brzozowy przycisk +Dark Oak Button=Ciemno-dębowy przycisk +Spruce Button=Świerkowy przycisk +Jungle Button=Tropikalny przycisk +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.=Drewniany przycisk jest mechanizmem czerwienitowym wykonanym z drewna, który można nacisnąć by dostarczał energię czerwienitową. Po naciśnięciu zasila on przyległe mechanizmy czerwienitowe przez 1.5 sekundy. Drewniane przyciski mogą być również naciśnięte przez strzały. +Provides redstone power when pushed=Dostarcza energii czerwienitowej gdy naciśnięty +Push duration: @1s=Czas trwania naciśnięcia: @1s +Pushable by arrow=Można nacisnąć strzałą diff --git a/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt index 4c352b878..d42a03741 100644 --- a/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_button/locale/template.txt @@ -2,13 +2,19 @@ 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.= +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.= Oak Button= Acacia Button= Birch Button= Dark Oak Button= Spruce Button= 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.= 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.= diff --git a/mods/ITEMS/REDSTONE/mesecons_button/mod.conf b/mods/ITEMS/REDSTONE/mesecons_button/mod.conf new file mode 100644 index 000000000..be127362b --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_button/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_button +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_button/textures/mesecons_button_wield_mask.png b/mods/ITEMS/REDSTONE/mesecons_button/textures/mesecons_button_wield_mask.png deleted file mode 100644 index 211ac43fb..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_button/textures/mesecons_button_wield_mask.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt b/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt deleted file mode 100644 index 95ac10fe5..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -doc? -doc_items? diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua index c5c3b3dc8..3902c3c18 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/init.lua @@ -1,6 +1,13 @@ -local S = minetest.get_translator("mesecons_commandblock") +local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape +local tonumber = tonumber + +local color_red = mcl_colors.RED + +local command_blocks_activated = minetest.settings:get_bool("mcl_enable_commandblocks", true) +local msg_not_activated = S("Command blocks are not enabled on this server") + local function construct(pos) local meta = minetest.get_meta(pos) @@ -22,7 +29,7 @@ local function resolve_commands(commands, pos) local commander = meta:get_string("commander") -- A non-printable character used while replacing “@@”. - local SUBSTITUTE_CHARACTER = '\26' -- ASCII SUB + local SUBSTITUTE_CHARACTER = "\26" -- ASCII SUB -- No players online: remove all commands containing -- problematic placeholders. @@ -67,7 +74,7 @@ end local function check_commands(commands, player_name) for _, command in pairs(commands:split("\n")) do local pos = command:find(" ") - local cmd, param = command, "" + local cmd = command if pos then cmd = command:sub(1, pos - 1) end @@ -78,7 +85,7 @@ local function check_commands(commands, player_name) if string.sub(cmd, 1, 1) == "/" then msg = S("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.", cmd) end - return false, minetest.colorize("#FF0000", msg) + return false, minetest.colorize(color_red, msg) end if player_name then local player_privs = minetest.get_player_privs(player_name) @@ -86,7 +93,7 @@ local function check_commands(commands, player_name) for cmd_priv, _ in pairs(cmddef.privs) do if player_privs[cmd_priv] ~= true then local msg = S("Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.", cmd, cmd_priv) - return false, minetest.colorize("#FF0000", msg) + return false, minetest.colorize(color_red, msg) end end end @@ -99,9 +106,14 @@ local function commandblock_action_on(pos, node) return end - minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) - local meta = minetest.get_meta(pos) + local commander = meta:get_string("commander") + + if not command_blocks_activated then + --minetest.chat_send_player(commander, msg_not_activated) + return + end + minetest.swap_node(pos, {name = "mesecons_commandblock:commandblock_on"}) local commands = resolve_commands(meta:get_string("commands"), pos) for _, command in pairs(commands:split("\n")) do @@ -117,7 +129,6 @@ local function commandblock_action_on(pos, node) return end -- Execute command in the name of commander - local commander = meta:get_string("commander") cmddef.func(commander, param) end end @@ -128,7 +139,11 @@ local function commandblock_action_off(pos, node) end end -local on_rightclick = function(pos, node, player, itemstack, pointed_thing) +local function on_rightclick(pos, node, player, itemstack, pointed_thing) + if not command_blocks_activated then + minetest.chat_send_player(player:get_player_name(), msg_not_activated) + return + end local can_edit = true -- Only allow write access in Creative Mode if not minetest.is_creative_enabled(player:get_player_name()) then @@ -179,18 +194,18 @@ local on_rightclick = function(pos, node, player, itemstack, pointed_thing) minetest.show_formspec(pname, "commandblock_"..pos.x.."_"..pos.y.."_"..pos.z, formspec) end -local on_place = function(itemstack, placer, pointed_thing) +local function on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" then return itemstack 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 + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack + end + + --local node = minetest.get_node(pointed_thing.under) local privs = minetest.get_player_privs(placer:get_player_name()) if not privs.maphack then @@ -282,8 +297,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end local index, _, x, y, z = string.find(formname, "commandblock_(-?%d+)_(-?%d+)_(-?%d+)") - if index ~= nil and x ~= nil and y ~= nil and z ~= nil then - local pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)} + if index and x and y and z then + local pos = {x = tonumber(x), y = tonumber(y), z = tonumber(z)} local meta = minetest.get_meta(pos) if not minetest.is_creative_enabled(player:get_player_name()) then minetest.chat_send_player(player:get_player_name(), S("Editing the command block has failed! You can only change the command block in Creative Mode!")) diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr index 9c9b1df1d..a149feef9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.de.tr @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Zugr Editing the command block has failed! You can only change the command block in Creative Mode!=Bearbeitung des Befehlsblocks fehlgeschlagen! Sie können den Befehlsblock nur im Kreativmodus ändern! Editing the command block has failed! The command block is gone.=Bearbeiten des Befehlsblocks fehlgeschlagen! Der Befehlsblock ist verschwunden. Executes server commands when powered by redstone power=Führt Serverbefehle aus, wenn mit Redstoneenergie versorgt +Command blocks are not enabled on this server= 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 8826ab9a6..938c710b9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.es.tr @@ -28,3 +28,4 @@ Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=2. Access denied. You need the “maphack” privilege to edit command blocks.=Acceso denegado. Necesita el privilegio "maphack" para editar bloques de comandos. Editing the command block has failed! You can only change the command block in Creative Mode!=¡La edición del bloque de comando ha fallado! ¡Solo puede cambiar el bloque de comandos en modo creativo! Editing the command block has failed! The command block is gone.=¡La edición del bloque de comando ha fallado! El bloque de comando se ha ido. +Command blocks are not enabled on this server= diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr index 6d608f589..b397c979c 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.fr.tr @@ -13,8 +13,7 @@ Command Block=Bloc de Commande 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.=Les blocs de commande sont des composants redstone puissants qui sont capables de modifier la réalité elle-même. En d'autres termes, ils obligent le serveur à exécuter des commandes serveur lorsqu'ils sont alimentés en redstone. Everyone can activate a command block and look at its commands, but not everyone can edit and place them.=Tout le monde peut activer un bloc de commandes et consulter ses commandes, mais tout le monde ne peut pas les modifier et les placer. 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.=Pour afficher les commandes dans un bloc de commandes, utilisez-le. Pour activer le bloc de commande, il suffit de l'alimenter en redstone. Cela exécutera les commandes une fois. Pour exécuter à nouveau les commandes, éteignez puis rallumez le Redstone. -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.= -# ^ OLD TRANSLATION: Pour pouvoir placer un bloc de commande et modifier les commandes, vous devez être en mode créatif et avoir le privilège "maphack". Un nouveau bloc de commandes n'a aucune commande et ne fait rien. Utilisez le bloc de commande (en mode créatif!) Pour modifier ses commandes. Lisez l'entrée d'aide "Rubriques avancées> Commandes du serveur" pour comprendre le fonctionnement des commandes. Chaque ligne contient une seule commande. Vous les entrez comme vous le feriez dans la console, mais sans la barre oblique principale. Les commandes seront exécutées de haut en bas. +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.=Pour pouvoir placer un bloc de commande et modifier les commandes, vous devez être en mode créatif et avoir le privilège "maphack". Un nouveau bloc de commande n'a aucune commande et ne fait rien. Utilisez le bloc de commande (en mode créatif!) Pour modifier ses commandes. Lisez l'entrée d'aide "Utilisation avancée> Commandes du serveur" pour comprendre le fonctionnement des commandes. Chaque ligne contient une seule commande. Vous les entrez comme vous le feriez dans la console, mais sans la barre oblique principale. Les commandes seront exécutées de haut en bas. 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.=Toutes les commandes seront exécutées au nom du joueur qui a placé le bloc de commande, comme si le joueur avait tapé les commandes. Ce joueur est appelé le "commandant" du bloc. Command blocks support placeholders, insert one of these placeholders and they will be replaced by some other text:=Les blocs de commande prennent en charge les espaces réservés, insérez l'un de ces espaces réservés et ils seront remplacés par un autre texte: • “@@c”: commander of this command block=• “@@c”: commandant de ce bloc que commande @@ -28,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=Acc Editing the command block has failed! You can only change the command block in Creative Mode!=La modification du bloc de commandes a échoué! Vous ne pouvez modifier le bloc de commandes qu'en mode créatif! Editing the command block has failed! The command block is gone.=La modification du bloc de commandes a échoué! Le bloc de commande a disparu. Executes server commands when powered by redstone power=Exécute les commandes du serveur lorsqu'il est alimenté par l'alimentation Redstone +Command blocks are not enabled on this server=Les blocks de commandes ne sont pas activés sur ce serveur diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr new file mode 100644 index 000000000..1b46a6c7a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ja.tr @@ -0,0 +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: 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=提出 +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」権限が必要です。新しいコマンドブロックはコマンドを持たず、何もしません。コマンドブロックを使って(クリエイティブモードで!)そのコマンドを編集してください。コマンドの動作について知るには、ヘルプの "Advanced usage > Server Commands" をお読みください。各行は単一のコマンドを含んでいます。コンソールと同じように入力しますが、先頭のスラッシュを除きます。コマンドは上から順に実行されます。 +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:=コマンドブロックはプレースホルダーをサポートしており、いずれかのプレースホルダーを挿入すると、他のテキストに置き換わります: +• “@@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 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=このサーバーではコマンドブロックが有効になっていない diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.pl.tr b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.pl.tr new file mode 100644 index 000000000..6ee1afcad --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.pl.tr @@ -0,0 +1,31 @@ +# 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.=Błąd: Komenda "@1" nie istnieje; twój blok komend nie został zmieniony. Użyj komendy "help" aby zobaczyć listę dostępnych komend. +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.=Błąd: Komenda "@1" nie istnieje; twój blok komend nie został zmieniony. Użyj komendy "help" aby zobaczyć listę dostępnych komend. Wskazówka: Spróbuj usunąć poprzedzający slesz. +Error: You have insufficient privileges to use the command “@1” (missing privilege: @2)! The command block has not been changed.=Błąd: Masz niewystarczające uprawnienia by użyć komendy "@1" (brakujący przywilej: @2)! Blok komend nie został zmieniony. +Error: No commander! Block must be replaced.=Blok: Brak komendanta! Blok musi zostać zamieniony. +Commander: @1=Komendant: @1 +Submit=Zatwierdź +No commands.=Brak komend. +Commands:=Komendy: +Help=Pomoc +Placement denied. You need the “maphack” privilege to place command blocks.=Odmówiono postawienia. Potrzebujesz przywileju "maphack" aby stawiać bloki komend. +Command Block=Blok komend +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.=Bloki komend są potężnymi mechanizmami czerwienitowymi, które są w stanie zmieniać samą rzeczywistość. Innymi słowy powodują one, że serwer wykonuje komendy gdy dostarczy się im energię czerwienitową. +Everyone can activate a command block and look at its commands, but not everyone can edit and place them.=Każdy może aktywować blok komend i patrzeć na ich komendy, ale nie wszyscy mogą edytować i kłaść je. +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.=Aby zobaczyć komendy w bloku komend, kliknij użyj na nim. Aby aktywować blok komend zasil go energią czerwienitową. To wykona komendy raz. Aby wykonać je ponownie wyłącz, a następnie włącz energię. +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.=Aby być w stanie kłaść bloki komend i zmieniać ich komendy musisz być w trybie kreatywnym i posiadać przywilej "maphack". Nowy blok komend nie posiada żadnych komend i nie robi nic. Użyj bloku komend (w trybie kreatywnym!) aby zmienić jego komendy. Przeczytaj wpis w pomocy "Zaawansowane użycie > Komendy serwera" aby dowiedzieć się jak komendy działają. Każda linia zawiera pojedynczą komendę. Wprowadzasz je tak jak w konsoli, ale bez poprzedzającego slesza. Komendy będą wykonywane od góry do dołu. +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.=Wszystkie komendy będą formalnie wykonane przez gracza, który postawił blok komend, jakby to ten gracz wpisał komendę. Ten gracz nazywany jest komendantem bloku. +Command blocks support placeholders, insert one of these placeholders and they will be replaced by some other text:=Bloki komend wspierają zamienniki, wstaw jeden z nich a zostaną one zastąpione przez jakiś inny tekst: +• “@@c”: commander of this command block=• "@@c": komendant tego bloku komend +• “@@n” or “@@p”: nearest player from the command block=• "@@n" lub "@@p": gracz najbliżej tego bloku komend +• “@@f” farthest player from the command block=• "@@f": gracz najdalej od tego bloku komend +• “@@r”: random player currently in the world=• "@@r": losowy gracz znajdujący się w świecie +• “@@@@”: literal “@@” sign=• "@@@@": dosłowny znak "@@" +Example 1:@n time 12000@nSets the game clock to 12:00=Przykład 1:@n time 12000@nUstawia zegar gry na 12:00 +Example 2:@n give @@n mcl_core:apple 5@nGives the nearest player 5 apples=Przykład 2:@n give @@n mcl_core:apple 5@nDaje najbliższemu graczowi 5 jabłek +Access denied. You need the “maphack” privilege to edit command blocks.=Odmowa dostępu. Potrzebujesz przywileju "maphack" by zmieniać bloki komend. +Editing the command block has failed! You can only change the command block in Creative Mode!=Edycja bloku komend nieudana! Możesz zmieniać bloki komend tylko w trybie kreatywnym. +Editing the command block has failed! The command block is gone.=Edycja bloku komend nieudana! Bloku komend już nie ma. +Executes server commands when powered by redstone power=Wykonuje komendy serwera gdy jest zasilany energią czerwienitową +Command blocks are not enabled on this server=Bloki komend nie są włączone na tym serwerze + 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 8671099c7..85bed4b95 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/mesecons_commandblock.ru.tr @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.=До 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_commandblock/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt index 0e0c3caa5..49e98ef2b 100644 --- a/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/locale/template.txt @@ -27,3 +27,4 @@ Access denied. You need the “maphack” privilege to edit command blocks.= 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_commandblock/mod.conf b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf new file mode 100644 index 000000000..26059530a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_commandblock/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_commandblock +depends = mesecons, mcl_colors, mcl_util +optional_depends = doc, doc_items diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt b/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt deleted file mode 100644 index 14ced9309..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua index 80489814b..fc12c0a36 100644 --- a/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/init.lua @@ -1,10 +1,10 @@ -local S = minetest.get_translator("mesecons_delayer") +local S = minetest.get_translator(minetest.get_current_modname()) local DELAYS = { 0.1, 0.2, 0.3, 0.4 } local DEFAULT_DELAY = DELAYS[1] -- Function that get the input/output rules of the delayer -local delayer_get_output_rules = function(node) +local function delayer_get_output_rules(node) local rules = {{x = -1, y = 0, z = 0, spread=true}} for i = 0, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -12,7 +12,7 @@ local delayer_get_output_rules = function(node) return rules end -local delayer_get_input_rules = function(node) +local function delayer_get_input_rules(node) local rules = {{x = 1, y = 0, z = 0}} for i = 0, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -22,7 +22,7 @@ end -- Return the sides of a delayer. -- Those are used to toggle the lock state. -local delayer_get_sides = function(node) +local function delayer_get_sides(node) local rules = { {x = 0, y = 0, z = -1}, {x = 0, y = 0, z = 1}, @@ -35,7 +35,7 @@ end -- Make the repeater at pos try to lock any repeater it faces. -- Returns true if a repeater was locked. -local check_lock_repeater = function(pos, node) +local function check_lock_repeater(pos, node) -- Check the repeater at pos and look if it faces -- a repeater placed sideways. -- If yes, lock the second repeater. @@ -67,7 +67,7 @@ end -- Make the repeater at pos try to unlock any repeater it faces. -- Returns true if a repeater was unlocked. -local check_unlock_repeater = function(pos, node) +local function check_unlock_repeater(pos, node) -- Check the repeater at pos and look if it faces -- a repeater placed sideways. -- If yes, also check if the second repeater doesn't receive @@ -119,21 +119,19 @@ local check_unlock_repeater = function(pos, node) end -- Functions that are called after the delay time -local delayer_activate = function(pos, node) +local function delayer_activate(pos, node) local def = minetest.registered_nodes[node.name] local time = def.delayer_time minetest.set_node(pos, {name=def.delayer_onstate, param2=node.param2}) mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(node)}, time, nil) - check_lock_repeater(pos, node) end -local delayer_deactivate = function(pos, node) +local function delayer_deactivate(pos, node) local def = minetest.registered_nodes[node.name] local time = def.delayer_time minetest.set_node(pos, {name=def.delayer_offstate, param2=node.param2}) mesecon.queue:add_action(pos, "receptor_off", {delayer_get_output_rules(node)}, time, nil) - check_unlock_repeater(pos, node) end @@ -145,234 +143,230 @@ end -- Register the 2 (states) x 4 (delay times) delayers for i = 1, 4 do -local groups = {} -if i == 1 then - groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i} -else - groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i,not_in_creative_inventory=1} -end + local groups + if i == 1 then + groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i} + else + groups = {dig_immediate=3,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,attached_node=1,redstone_repeater=i,not_in_creative_inventory=1} + end -local delaytime = DELAYS[i] + local delaytime = DELAYS[i] -local boxes -if i == 1 then -boxes = { - { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab - { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch - { -1/16, -6/16, 0/16, 1/16, -1/16, 2/16}, -- moved torch -} -elseif i == 2 then -boxes = { - { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab - { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch - { -1/16, -6/16, -2/16, 1/16, -1/16, 0/16}, -- moved torch -} -elseif i == 3 then -boxes = { - { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab - { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch - { -1/16, -6/16, -4/16, 1/16, -1/16, -2/16}, -- moved torch -} -elseif i == 4 then -boxes = { - { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab - { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch - { -1/16, -6/16, -6/16, 1/16, -1/16, -4/16}, -- moved torch -} -end + local boxes + if i == 1 then + boxes = { + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab + { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch + { -1/16, -6/16, 0/16, 1/16, -1/16, 2/16}, -- moved torch + } + elseif i == 2 then + boxes = { + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab + { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch + { -1/16, -6/16, -2/16, 1/16, -1/16, 0/16}, -- moved torch + } + elseif i == 3 then + boxes = { + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab + { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch + { -1/16, -6/16, -4/16, 1/16, -1/16, -2/16}, -- moved torch + } + elseif i == 4 then + boxes = { + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, -- the main slab + { -1/16, -6/16, 6/16, 1/16, -1/16, 4/16}, -- still torch + { -1/16, -6/16, -6/16, 1/16, -1/16, -4/16}, -- moved torch + } + end -local help, tt, longdesc, usagehelp, icon, on_construct -if i == 1 then - help = true - tt = S("Transmits redstone power only in one direction").."\n".. - S("Delays signal").."\n".. - S("Output locks when getting active redstone repeater signal from the side") - longdesc = S("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.") - usagehelp = S("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.").."\n".. - S("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.") - icon = "mesecons_delayer_item.png" - - -- Check sides of constructed repeater and lock it, if required - on_construct = function(pos) - local node = minetest.get_node(pos) - local sides = delayer_get_sides(node) - for s=1, #sides do - local spos = vector.add(pos, sides[s]) - local snode = minetest.get_node(spos) - -- Is there a powered repeater at one of our sides? - local g = minetest.get_item_group(snode.name, "redstone_repeater") - if g ~= 0 and mesecon.is_receptor_on(snode.name) then - -- The other repeater must also face towards the constructed node - local sface = delayer_get_output_rules(snode)[1] - local sface_pos = vector.add(spos, sface) - if vector.equals(sface_pos, pos) then - -- Repeater is facing towards us! Now we just need to lock the costructed node - if mesecon.is_powered(pos, delayer_get_input_rules(node)[1]) ~= false then - local newnode = {name="mesecons_delayer:delayer_on_locked", param2 = node.param2} - minetest.set_node(pos, newnode) - mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(newnode)}, DEFAULT_DELAY, nil) - else - minetest.set_node(pos, {name="mesecons_delayer:delayer_off_locked", param2 = node.param2}) + local help, tt, longdesc, usagehelp, icon, on_construct + if i == 1 then + help = true + tt = S("Transmits redstone power only in one direction").."\n".. + S("Delays signal").."\n".. + S("Output locks when getting active redstone repeater signal from the side") + longdesc = S("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.") + usagehelp = S("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.").."\n".. + S("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.") + icon = "mesecons_delayer_item.png" + -- Check sides of constructed repeater and lock it, if required + on_construct = function(pos) + local node = minetest.get_node(pos) + local sides = delayer_get_sides(node) + for s=1, #sides do + local spos = vector.add(pos, sides[s]) + local snode = minetest.get_node(spos) + -- Is there a powered repeater at one of our sides? + local g = minetest.get_item_group(snode.name, "redstone_repeater") + if g ~= 0 and mesecon.is_receptor_on(snode.name) then + -- The other repeater must also face towards the constructed node + local sface = delayer_get_output_rules(snode)[1] + local sface_pos = vector.add(spos, sface) + if vector.equals(sface_pos, pos) then + -- Repeater is facing towards us! Now we just need to lock the costructed node + if mesecon.is_powered(pos, delayer_get_input_rules(node)[1]) ~= false then + local newnode = {name="mesecons_delayer:delayer_on_locked", param2 = node.param2} + minetest.set_node(pos, newnode) + mesecon.queue:add_action(pos, "receptor_on", {delayer_get_output_rules(newnode)}, DEFAULT_DELAY, nil) + else + minetest.set_node(pos, {name="mesecons_delayer:delayer_off_locked", param2 = node.param2}) + end + break end - break end end end + else + help = false end -else - help = false -end -local desc_off -if i == 1 then - desc_off = S("Redstone Repeater") -else - desc_off = S("Redstone Repeater (Delay @1)", i) -end + local desc_off + if i == 1 then + desc_off = S("Redstone Repeater") + else + desc_off = S("Redstone Repeater (Delay @1)", i) + end -minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), { - description = desc_off, - inventory_image = icon, - wield_image = icon, - _tt_help = tt, - _doc_items_create_entry = help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - drawtype = "nodebox", - tiles = { - "mesecons_delayer_off.png", - "mcl_stairs_stone_slab_top.png", - "mesecons_delayer_sides_off.png", - "mesecons_delayer_sides_off.png", - "mesecons_delayer_ends_off.png", - "mesecons_delayer_ends_off.png", + minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), { + description = desc_off, + inventory_image = icon, + wield_image = icon, + _tt_help = tt, + _doc_items_create_entry = help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + drawtype = "nodebox", + tiles = { + "mesecons_delayer_off.png", + "mcl_stairs_stone_slab_top.png", + "mesecons_delayer_sides_off.png", + "mesecons_delayer_sides_off.png", + "mesecons_delayer_ends_off.png", + "mesecons_delayer_ends_off.png", }, - wield_image = "mesecons_delayer_off.png", - walkable = true, - selection_box = { - type = "fixed", - fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, - }, - collision_box = { - type = "fixed", - fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, - }, - node_box = { - type = "fixed", - fixed = boxes - }, - groups = groups, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = false, - is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', - on_rightclick = function (pos, node, clicker) - local protname = clicker:get_player_name() - if minetest.is_protected(pos, protname) then - minetest.record_protection_violation(pos, protname) - return - end - if node.name=="mesecons_delayer:delayer_off_1" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_off_2" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_off_3" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_off_4" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2}) - end - end, - on_construct = on_construct, - delayer_time = delaytime, - delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i), - delayer_lockstate = "mesecons_delayer:delayer_off_locked", - sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = { - receptor = - { - state = mesecon.state.off, - rules = delayer_get_output_rules + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + --wield_image = "mesecons_delayer_off.png", + walkable = true, + selection_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, }, - effector = - { - rules = delayer_get_input_rules, - action_on = delayer_activate - } - }, - on_rotate = on_rotate, -}) - - -minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), { - description = S("Redstone Repeater (Delay @1, Powered)", i), - _doc_items_create_entry = false, - drawtype = "nodebox", - tiles = { - "mesecons_delayer_on.png", - "mcl_stairs_stone_slab_top.png", - "mesecons_delayer_sides_on.png", - "mesecons_delayer_sides_on.png", - "mesecons_delayer_ends_on.png", - "mesecons_delayer_ends_on.png", + collision_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, }, - walkable = true, - selection_box = { - type = "fixed", - fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, - }, - collision_box = { - type = "fixed", - fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, - }, - node_box = { - type = "fixed", - fixed = boxes - }, - groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=i, not_in_creative_inventory = 1}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = false, - is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', - on_rightclick = function (pos, node, clicker) - local protname = clicker:get_player_name() - if minetest.is_protected(pos, protname) then - minetest.record_protection_violation(pos, protname) - return - end - if node.name=="mesecons_delayer:delayer_on_1" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_on_2",param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_on_2" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_on_3",param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_on_3" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_on_4",param2=node.param2}) - elseif node.name=="mesecons_delayer:delayer_on_4" then - minetest.set_node(pos, {name="mesecons_delayer:delayer_on_1",param2=node.param2}) - end - end, - after_dig_node = function(pos, oldnode) - check_unlock_repeater(pos, oldnode) - end, - delayer_time = delaytime, - delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i), - delayer_lockstate = "mesecons_delayer:delayer_on_locked", - sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = { - receptor = - { - state = mesecon.state.on, - rules = delayer_get_output_rules + node_box = { + type = "fixed", + fixed = boxes }, - effector = - { - rules = delayer_get_input_rules, - action_off = delayer_deactivate - } - }, - on_rotate = on_rotate, -}) + groups = groups, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = false, + is_ground_content = false, + drop = "mesecons_delayer:delayer_off_1", + on_rightclick = function(pos, node, clicker) + local protname = clicker:get_player_name() + if minetest.is_protected(pos, protname) then + minetest.record_protection_violation(pos, protname) + return + end + if node.name=="mesecons_delayer:delayer_off_1" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_off_2", param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_off_2" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_off_3", param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_off_3" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_off_4", param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_off_4" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_off_1", param2=node.param2}) + end + end, + on_construct = on_construct, + delayer_time = delaytime, + delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i), + delayer_lockstate = "mesecons_delayer:delayer_off_locked", + sounds = mcl_sounds.node_sound_stone_defaults(), + mesecons = { + receptor = { + state = mesecon.state.off, + rules = delayer_get_output_rules, + }, + effector = { + rules = delayer_get_input_rules, + action_on = delayer_activate, + }, + }, + on_rotate = on_rotate, + }) + minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), { + description = S("Redstone Repeater (Delay @1, Powered)", i), + _doc_items_create_entry = false, + drawtype = "nodebox", + tiles = { + "mesecons_delayer_on.png", + "mcl_stairs_stone_slab_top.png", + "mesecons_delayer_sides_on.png", + "mesecons_delayer_sides_on.png", + "mesecons_delayer_ends_on.png", + "mesecons_delayer_ends_on.png", + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + walkable = true, + selection_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, + }, + collision_box = { + type = "fixed", + fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, + }, + node_box = { + type = "fixed", + fixed = boxes + }, + groups = {dig_immediate = 3, dig_by_water=1,destroy_by_lava_flow=1, dig_by_piston=1, attached_node=1, redstone_repeater=i, not_in_creative_inventory = 1}, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = false, + is_ground_content = false, + drop = "mesecons_delayer:delayer_off_1", + on_rightclick = function(pos, node, clicker) + local protname = clicker:get_player_name() + if minetest.is_protected(pos, protname) then + minetest.record_protection_violation(pos, protname) + return + end + --HACK! we already know the node name, so we should generate the function to avoid multiple checks + if node.name=="mesecons_delayer:delayer_on_1" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_on_2",param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_on_2" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_on_3",param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_on_3" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_on_4",param2=node.param2}) + elseif node.name=="mesecons_delayer:delayer_on_4" then + minetest.set_node(pos, {name="mesecons_delayer:delayer_on_1",param2=node.param2}) + end + end, + after_dig_node = function(pos, oldnode) + check_unlock_repeater(pos, oldnode) + end, + delayer_time = delaytime, + delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i), + delayer_lockstate = "mesecons_delayer:delayer_on_locked", + sounds = mcl_sounds.node_sound_stone_defaults(), + mesecons = { + receptor = { + state = mesecon.state.on, + rules = delayer_get_output_rules, + }, + effector = { + rules = delayer_get_input_rules, + action_off = delayer_deactivate, + }, + }, + on_rotate = on_rotate, + }) end @@ -391,7 +385,8 @@ minetest.register_node("mesecons_delayer:delayer_off_locked", { "mesecons_delayer_sides_locked_off.png", "mesecons_delayer_front_locked_off.png", "mesecons_delayer_end_locked_off.png", - }, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, wield_image = "mesecons_delayer_locked_off.png", walkable = true, selection_box = { @@ -415,7 +410,7 @@ minetest.register_node("mesecons_delayer:delayer_off_locked", { paramtype2 = "facedir", sunlight_propagates = false, is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', + drop = "mesecons_delayer:delayer_off_1", delayer_time = DEFAULT_DELAY, sounds = mcl_sounds.node_sound_stone_defaults(), mesecons = { @@ -443,7 +438,8 @@ minetest.register_node("mesecons_delayer:delayer_on_locked", { "mesecons_delayer_sides_locked_on.png", "mesecons_delayer_front_locked_on.png", "mesecons_delayer_end_locked_on.png", - }, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, walkable = true, selection_box = { type = "fixed", @@ -469,7 +465,7 @@ minetest.register_node("mesecons_delayer:delayer_on_locked", { paramtype2 = "facedir", sunlight_propagates = false, is_ground_content = false, - drop = 'mesecons_delayer:delayer_off_1', + drop = "mesecons_delayer:delayer_off_1", delayer_time = DEFAULT_DELAY, sounds = mcl_sounds.node_sound_stone_defaults(), mesecons = { diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.tr b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.tr new file mode 100644 index 000000000..74e8d644d --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.ja.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.=レッドストーンリピーターは多目的に使えるレッドストーン部品:1、信号は一方通行のみ。 2、信号が遅延する。 3、任意で,出力を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 (Delay @1)=レッドストーンリピーター(遅延 @1) +Redstone Repeater (Delay @1, Powered)=レッドストーンリピーター(遅延 @1・稼動) +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_delayer/locale/mesecons_delayer.pl.tr b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.pl.tr new file mode 100644 index 000000000..ed533e241 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/locale/mesecons_delayer.pl.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.=Przekaźniki są wszechstronnymi mechanizmami czerwienitowym z kilkoma funkcjami: 1. Pozwalają by sygnał podróżował tylko w jednym kierunku. 2. Opóźniają sygnał. 3. Opcjonalnie mogą zablokować swój output w jednym stanie. +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.=Aby zasilić przekaźnik dostarcz sygnał w kierunku "strzałki" (wejście). Sygnał wyjściowy pojawi się po przeciwnej stronie z opóźnieniem. Aby zmienić opóźnienie kliknij użyj na przekaźniku. Możliwe opóźnienia są pomiędzy 0.1 a 0.4 sekundy i może być zmieniony używając przekaźnik co zmienia go o 0.1 sekundy. Opóźnienie jest oznaczone przez pozycję przesuwającej się pochodni. +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.=Aby zablokować przekaźnik wyślij sygnał z przyległego przekaźnika w jeden z jego boków. Gdy jest zablokowany poruszająca się pochodnia znika, sygnał wyjściowy się nie zmienia, a sygnał wejściowy jest ignorowany. +Redstone Repeater=Przekaźnik czerwienitowy +Redstone Repeater (Powered)=Przekaźnik czerwienitowy (zasilony) +Redstone Repeater (Locked)=Przekaźnik czerwienitowy (zablokowany) +Redstone Repeater (Locked, Powered)=Przekaźnik czerwienitowy (zablokowany, zasilony) +Redstone Repeater (Delay @1)=Przekaźnik czerwienitowy (opóźnienie @1) +Redstone Repeater (Delay @1, Powered)=Przekaźnik czerwienitowy (opóźnienie @1, zasilony) +Transmits redstone power only in one direction=Przesyła energię czerwienitową w jednym kierunku +Delays signal=Opóźnia sygnał +Output locks when getting active redstone repeater signal from the side=Wyjście się blokuje przy otrzymywaniu zasilonego sygnału z przekaźnika z boku diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf b/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf new file mode 100644 index 000000000..3f8446239 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_delayer/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_delayer +depends = mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_off.png b/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_off.png deleted file mode 100644 index 326dbe63e..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_off.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_on.png b/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_on.png deleted file mode 100644 index bab909eb3..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_on.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt b/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua b/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua index c09bcf592..0e517e4dc 100644 --- a/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mesecons_lightstone") +local S = minetest.get_translator(minetest.get_current_modname()) local light = minetest.LIGHT_MAX @@ -11,7 +11,7 @@ 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) + action_on = function(pos, node) minetest.swap_node(pos, {name="mesecons_lightstone:lightstone_on", param2 = node.param2}) end, rules = mesecon.rules.alldirs, @@ -29,7 +29,7 @@ minetest.register_node("mesecons_lightstone:lightstone_on", { light_source = light, sounds = mcl_sounds.node_sound_glass_defaults(), mesecons = {effector = { - action_off = function (pos, node) + action_off = function(pos, node) minetest.swap_node(pos, {name="mesecons_lightstone:lightstone_off", param2 = node.param2}) end, rules = mesecon.rules.alldirs, @@ -41,9 +41,9 @@ minetest.register_node("mesecons_lightstone:lightstone_on", { minetest.register_craft({ output = "mesecons_lightstone:lightstone_off", recipe = { - {'',"mesecons:redstone",''}, - {"mesecons:redstone",'mcl_nether:glowstone',"mesecons:redstone"}, - {'','mesecons:redstone',''}, + {"","mesecons:redstone",""}, + {"mesecons:redstone","mcl_nether:glowstone","mesecons:redstone"}, + {"","mesecons:redstone",""}, } }) diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr new file mode 100644 index 000000000..d3224f581 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.ja.tr @@ -0,0 +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=レッドストーン動力が来ると点灯 diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr new file mode 100644 index 000000000..cd2f755c9 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/locale/mesecons_lightstone.pl.tr @@ -0,0 +1,4 @@ +# textdomain: mesecons_lightstone +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 diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf b/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf new file mode 100644 index 000000000..95811bd27 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_lightstone/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_lightstone +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/textures/jeija_lightstone_gray_off.png b/mods/ITEMS/REDSTONE/mesecons_lightstone/textures/jeija_lightstone_gray_off.png deleted file mode 100644 index 7f0c18b70..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_lightstone/textures/jeija_lightstone_gray_off.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt b/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt deleted file mode 100644 index acaa92412..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua index 669edbcbb..663d0f727 100644 --- a/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/init.lua @@ -1,3 +1,6 @@ +local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) +local table = table + --register stoppers for movestones/pistons mesecon.mvps_stoppers = {} @@ -6,8 +9,6 @@ mesecon.mvps_droppers = {} mesecon.on_mvps_move = {} mesecon.mvps_unmov = {} -local is_protected = minetest.is_protected - --- Objects (entities) that cannot be moved function mesecon.register_mvps_unmov(objectname) mesecon.mvps_unmov[objectname] = true; @@ -47,8 +48,6 @@ end -- For nodes which ignore sticky sides. -- They can't be pulled by sticky pistons and don't interact with slime blocks. --- TODO: This has NOT any actual effect so far. The actual functionality --- still needs to be implemented. function mesecon.register_mvps_unsticky(nodename, get_unsticky) if get_unsticky == nil then get_unsticky = true @@ -66,14 +65,12 @@ function mesecon.is_mvps_unsticky(node, pulldir, stack, stackid) if type(get_unsticky) == "function" then get_unsticky = get_unsticky(node, pulldir, stack, stackid) end - if get_unsticky == nil then - get_unsticky = false - end return get_unsticky end -- Functions to be called on mvps movement +-- See also the callback function mesecon.register_on_mvps_move(callback) mesecon.on_mvps_move[#mesecon.on_mvps_move+1] = callback end @@ -150,6 +147,7 @@ function mesecon.mvps_get_stack(pos, dir, maximum, piston_pos) -- 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) @@ -209,7 +207,15 @@ function mesecon.mvps_push(pos, dir, maximum, player_name, piston_pos) end function mesecon.mvps_pull_single(pos, dir, maximum, player_name, piston_pos) - return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, player_name, piston_pos) + local nodes = mesecon.mvps_get_stack(pos, dir, maximum, player_name, piston_pos) + + if not nodes then return end + -- ensure sticky pistons; even without slimeblocks attached adhere to the unpullable rule. + for id, n in ipairs(nodes) do + if not mesecon.is_mvps_unsticky(n.node, dir, nodes, id) then + return mesecon.mvps_push_or_pull(pos, vector.multiply(dir, -1), dir, maximum, player_name, piston_pos) + end + end end -- pos: pos of mvps; stackdir: direction of building the stack @@ -257,7 +263,7 @@ function mesecon.mvps_push_or_pull(pos, stackdir, movedir, maximum, player_name, n.meta = minetest.get_meta(n.pos):to_table() local is_dropper = mesecon.is_mvps_dropper(n.node, movedir, nodes, id) if is_dropper then - local drops = minetest.get_node_drops(n.node.name, "") + --local drops = minetest.get_node_drops(n.node.name, "") minetest.dig_node(n.pos) else minetest.remove_node(n.pos) @@ -323,17 +329,17 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) -- Move object at tip of stack, pushpos is position at tip of stack local pushpos = vector.add(pos, vector.multiply(dir, #nodestack)) - local objects = minetest.get_objects_inside_radius(pushpos, 1) + local objects = minetest.get_objects_inside_radius(pushpos, 1.15) for _, obj in ipairs(objects) do table.insert(objects_to_move, obj) end -- Move objects lying/standing on the stack (before it was pushed - oldstack) - if tonumber(minetest.settings:get("movement_gravity")) > 0 and dir.y == 0 then + if GRAVITY > 0 then -- If gravity positive and dir horizontal, push players standing on the stack for _, n in ipairs(nodestack) do local p_above = vector.add(n.pos, {x=0, y=1, z=0}) - local objects = minetest.get_objects_inside_radius(p_above, 1) + local objects = minetest.get_objects_inside_radius(p_above, 1.15) for _, obj in ipairs(objects) do table.insert(objects_to_move, obj) end @@ -342,7 +348,10 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) for _, obj in ipairs(objects_to_move) do local entity = obj:get_luaentity() - if not entity or not mesecon.is_mvps_unmov(entity.name) then + local player = obj:is_player() + + + if not entity or not player and not mesecon.is_mvps_unmov(entity.name) then local np = vector.add(obj:get_pos(), dir) --move only if destination is not solid @@ -350,18 +359,43 @@ function mesecon.mvps_move_objects(pos, dir, nodestack) if not ((not minetest.registered_nodes[nn.name]) or minetest.registered_nodes[nn.name].walkable) then obj:set_pos(np) + -- Launch Player, TNT & mobs like in Minecraft + -- Only doing so if slimeblock is attached. + for _, r in ipairs(mesecon.rules.alldirs) do + local adjpos = vector.add(np, r) + local adjnode = minetest.get_node(adjpos) + if minetest.registered_nodes[adjnode.name] and minetest.registered_nodes[adjnode.name].mvps_sticky and adjnode.name == "mcl_core:slimeblock" then + local np = vector.add(obj:get_pos(), dir) + + -- Reset acceleration of all objects before launching. + -- Fixes eggs, & snowballs thrown by dispensers + obj:set_acceleration({x=dir.x, y=-GRAVITY, z=dir.z}) + + --Need to set velocities differently for players, items & mobs/tnt, and falling anvils. + if player then + obj:add_velocity({x = dir.x * 10, y = dir.y * 13, z = dir.z * 10}) + elseif entity.name == "__builtin:item" then + obj:add_velocity({x = dir.x * 9, y = dir.y * 11, z = dir.z * 9}) + elseif entity.name == "__builtin:falling_node" then + obj:add_velocity({x = dir.x * 43, y = dir.y * 72, z = dir.z * 43}) + else + obj:add_velocity({x = dir.x * 6, y = dir.y * 9, z = dir.z * 6}) + end + end + end end end end end --- Unmovable by design +-- Unmovable by design: nodes mesecon.register_mvps_stopper("mcl_core:barrier") 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_chests:ender_chest") +mesecon.register_mvps_stopper("mcl_chests:ender_chest_small") mesecon.register_mvps_stopper("mcl_mobspawners:spawner") mesecon.register_mvps_stopper("mesecons_commandblock:commandblock_off") mesecon.register_mvps_stopper("mesecons_commandblock:commandblock_on") @@ -369,11 +403,25 @@ mesecon.register_mvps_stopper("mcl_portals:portal") mesecon.register_mvps_stopper("mcl_portals:portal_end") mesecon.register_mvps_stopper("mcl_portals:end_portal_frame") mesecon.register_mvps_stopper("mcl_portals:end_portal_frame_eye") +mesecon.register_mvps_stopper("mcl_enchanting:table") +mesecon.register_mvps_stopper("mcl_jukebox:jukebox") +mesecon.register_mvps_stopper("mesecons_solarpanel:solar_panel_on") +mesecon.register_mvps_stopper("mesecons_solarpanel:solar_panel_off") +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") -- Unmovable by technical restrictions. -- Open formspec would screw up if node is destroyed (minor problem) +-- Would screw up on/off state of trapped chest (big problem) +-- Would duplicate xp when moved mesecon.register_mvps_stopper("mcl_furnaces:furnace") mesecon.register_mvps_stopper("mcl_furnaces:furnace_active") +mesecon.register_mvps_stopper("mcl_blast_furnace:blast_furnace") +mesecon.register_mvps_stopper("mcl_blast_furnace:blast_furnace_active") +mesecon.register_mvps_stopper("mcl_smoker:smoker") +mesecon.register_mvps_stopper("mcl_smoker:smoker_active") mesecon.register_mvps_stopper("mcl_hoppers:hopper") mesecon.register_mvps_stopper("mcl_hoppers:hopper_side") mesecon.register_mvps_stopper("mcl_droppers:dropper") @@ -385,9 +433,39 @@ mesecon.register_mvps_stopper("mcl_dispensers:dispenser_down") mesecon.register_mvps_stopper("mcl_anvils:anvil") mesecon.register_mvps_stopper("mcl_anvils:anvil_damage_1") mesecon.register_mvps_stopper("mcl_anvils:anvil_damage_2") --- Would screw up on/off state of trapped chest (big problem) +mesecon.register_mvps_stopper("mcl_chests:chest") +mesecon.register_mvps_stopper("mcl_chests:chest_small") +mesecon.register_mvps_stopper("mcl_chests:chest_left") +mesecon.register_mvps_stopper("mcl_chests:chest_right") +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") --- Glazed terracotta: unpullable + +-- Unmovable by design: objects +mesecon.register_mvps_unmov("mcl_enchanting:book") +mesecon.register_mvps_unmov("mcl_chests:chest") +mesecon.register_mvps_unmov("mcl_banners:hanging_banner") +mesecon.register_mvps_unmov("mcl_banners:standing_banner") +mesecon.register_mvps_unmov("mcl_signs:text") +mesecon.register_mvps_unmov("mcl_mobspawners:doll") +mesecon.register_mvps_unmov("mcl_armor_stand:armor_entity") +mesecon.register_mvps_unmov("mcl_itemframes:item") +mesecon.register_mvps_unmov("mcl_itemframes:map") +mesecon.register_mvps_unmov("mcl_paintings:painting") +mesecon.register_mvps_unmov("mcl_end:crystal") + + +-- Unpullable by design: nodes +-- Glazed Terracotta mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_red") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_orange") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_yellow") @@ -404,18 +482,474 @@ mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_black") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_brown") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_light_blue") mesecon.register_mvps_unsticky("mcl_colorblocks:glazed_terracotta_pink") +-- Bamboo +mesecon.register_mvps_unsticky("mcl_bamboo:bamboo") +mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_endcap") +mesecon.register_mvps_unsticky("mcl_bamboo:bamboo_1") +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 +mesecon.register_mvps_unsticky("mcl_beds:bed_black_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_black_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_blue_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_blue_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_brown_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_brown_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_cyan_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_cyan_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_green_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_green_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_grey_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_grey_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_light_blue_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_light_blue_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_lime_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_lime_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_magenta_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_magenta_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_orange_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_orange_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_pink_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_pink_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_purple_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_purple_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_red_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_red_bottom") +mesecon.register_mvps_unsticky("mcl_beds:bed_silver_top") +mesecon.register_mvps_unsticky("mcl_beds:bed_silver_bottom") +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") +mesecon.register_mvps_unsticky("mcl_core:vine") +-- Cake +mesecon.register_mvps_unsticky("mcl_cake:cake_1") +mesecon.register_mvps_unsticky("mcl_cake:cake_2") +mesecon.register_mvps_unsticky("mcl_cake:cake_3") +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") +mesecon.register_mvps_unsticky("mcl_farming:pumpkin") +mesecon.register_mvps_unsticky("mcl_farming:melon") +-- Chorus Plant & Flower +mesecon.register_mvps_unsticky("mcl_end:chorus_plant") +mesecon.register_mvps_unsticky("mcl_end:chorus_flower") +-- Cobweb +mesecon.register_mvps_unsticky("mcl_core:cobweb") +-- Cocoa +mesecon.register_mvps_unsticky("mcl_cocoas:cocoa_1") +mesecon.register_mvps_unsticky("mcl_cocoas:cocoa_2") +mesecon.register_mvps_unsticky("mcl_cocoas:cocoa_3") +-- Doors +mesecon.register_mvps_unsticky("mcl_doors:wooden_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:wooden_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:wooden_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:wooden_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:iron_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:iron_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:iron_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:iron_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:acacia_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:acacia_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:acacia_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:acacia_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:birch_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:birch_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:birch_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:birch_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:dark_oak_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:dark_oak_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:dark_oak_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:dark_oak_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:spruce_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:spruce_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:spruce_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:spruce_door_b_2") +mesecon.register_mvps_unsticky("mcl_doors:jungle_door_t_1") +mesecon.register_mvps_unsticky("mcl_doors:jungle_door_b_1") +mesecon.register_mvps_unsticky("mcl_doors:jungle_door_t_2") +mesecon.register_mvps_unsticky("mcl_doors:jungle_door_b_2") +-- Dragon Egg +mesecon.register_mvps_unsticky("mcl_end:dragon_egg") +-- Fire +mesecon.register_mvps_unsticky("mcl_fire:fire") +mesecon.register_mvps_unsticky("mcl_fire:eternal_fire") +-- Flower Pots +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_allium") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_azure_bluet") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_blue_orchid") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_dandelion") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_fern") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_oxeye_daisy") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_poppy") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_tulip_orange") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_tulip_pink") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_tulip_red") +mesecon.register_mvps_unsticky("mcl_flowerpots:flower_pot_tulip_white") +-- Flowers, Lilypad & Dead Bush +mesecon.register_mvps_unsticky("mcl_core:deadbush") +mesecon.register_mvps_unsticky("mcl_flowers:allium") +mesecon.register_mvps_unsticky("mcl_flowers:azure_bluet") +mesecon.register_mvps_unsticky("mcl_flowers:blue_orchid") +mesecon.register_mvps_unsticky("mcl_flowers:dandelion") +mesecon.register_mvps_unsticky("mcl_flowers:double_fern") +mesecon.register_mvps_unsticky("mcl_flowers:double_fern_top") +mesecon.register_mvps_unsticky("mcl_flowers:fern") +mesecon.register_mvps_unsticky("mcl_flowers:lilac") +mesecon.register_mvps_unsticky("mcl_flowers:lilac_top") +mesecon.register_mvps_unsticky("mcl_flowers:oxeye_daisy") +mesecon.register_mvps_unsticky("mcl_flowers:peony") +mesecon.register_mvps_unsticky("mcl_flowers:peony_top") +mesecon.register_mvps_unsticky("mcl_flowers:poppy") +mesecon.register_mvps_unsticky("mcl_flowers:rose_bush") +mesecon.register_mvps_unsticky("mcl_flowers:rose_bush_top") +mesecon.register_mvps_unsticky("mcl_flowers:sunflower") +mesecon.register_mvps_unsticky("mcl_flowers:sunflower_top") +mesecon.register_mvps_unsticky("mcl_flowers:tallgrass") +mesecon.register_mvps_unsticky("mcl_flowers:double_grass") +mesecon.register_mvps_unsticky("mcl_flowers:double_grass_top") +mesecon.register_mvps_unsticky("mcl_flowers:tulip_orange") +mesecon.register_mvps_unsticky("mcl_flowers:tulip_pink") +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:skeleton") +mesecon.register_mvps_unsticky("mcl_heads:steve") +mesecon.register_mvps_unsticky("mcl_heads:wither_skeleton") +mesecon.register_mvps_unsticky("mcl_heads:zombie") +-- Item Frame +mesecon.register_mvps_unsticky("mcl_itemframes:item_frame") +-- Ladder +mesecon.register_mvps_unsticky("mcl_core:ladder") +-- Lava & Water +mesecon.register_mvps_unsticky("mcl_core:lava_source") +mesecon.register_mvps_unsticky("mcl_core:lava_flowing") +mesecon.register_mvps_unsticky("mcl_core:water_source") +mesecon.register_mvps_unsticky("mcl_core:water_flowing") +mesecon.register_mvps_unsticky("mclx_core:river_water_source") +mesecon.register_mvps_unsticky("mclx_core:river_water_flowing") +-- Leaves +mesecon.register_mvps_unsticky("mcl_core:leaves") +mesecon.register_mvps_unsticky("mcl_core:acacialeaves") +mesecon.register_mvps_unsticky("mcl_core:birchleaves") +mesecon.register_mvps_unsticky("mcl_core:darkleaves") +mesecon.register_mvps_unsticky("mcl_core:spruceleaves") +mesecon.register_mvps_unsticky("mcl_core:jungleleaves") +-- Lever +mesecon.register_mvps_unsticky("mesecons_walllever:wall_lever_off") +mesecon.register_mvps_unsticky("mesecons_walllever:wall_lever_on") +-- Mushrooms, Nether Wart & Amethyst +mesecon.register_mvps_unsticky("mcl_mushroom:mushroom_brown") +mesecon.register_mvps_unsticky("mcl_mushroom:mushroom_red") +mesecon.register_mvps_unsticky("mcl_nether:nether_wart_0") +mesecon.register_mvps_unsticky("mcl_nether:nether_wart_1") +mesecon.register_mvps_unsticky("mcl_nether:nether_wart_2") +mesecon.register_mvps_unsticky("mcl_nether:nether_wart") +mesecon.register_mvps_unsticky("mcl_amethyst:amethyst_cluster") +mesecon.register_mvps_unsticky("mcl_amethyst:budding_amethyst_block") +-- Pressure Plates +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_wood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_wood_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_stone_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_stone_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_acaciawood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_acaciawoood_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_birchwood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_birchwood_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_darkwood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_darkwood_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_sprucekwood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_sprucewood_off") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_junglewood_on") +mesecon.register_mvps_unsticky("mesecons_pressureplates:pressure_plate_junglewood_off") +-- Redstone Comparators +mesecon.register_mvps_unsticky("mcl_comparators:comparator_on_sub") +mesecon.register_mvps_unsticky("mcl_comparators:comparator_off_sub") +mesecon.register_mvps_unsticky("mcl_comparators:comparator_on_comp") +mesecon.register_mvps_unsticky("mcl_comparators:comparator_off_comp") +-- Redstone Dust +mesecon.register_mvps_unsticky("mesecons:wire_00000000_on") +mesecon.register_mvps_unsticky("mesecons:wire_00000000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10000000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10000000_off") +mesecon.register_mvps_unsticky("mesecons:wire_01000000_on") +mesecon.register_mvps_unsticky("mesecons:wire_01000000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11000000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11000000_off") +mesecon.register_mvps_unsticky("mesecons:wire_00100000_on") +mesecon.register_mvps_unsticky("mesecons:wire_00100000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10100000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10100000_off") +mesecon.register_mvps_unsticky("mesecons:wire_01100000_on") +mesecon.register_mvps_unsticky("mesecons:wire_01100000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11100000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11100000_off") +mesecon.register_mvps_unsticky("mesecons:wire_00010000_on") +mesecon.register_mvps_unsticky("mesecons:wire_00010000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10010000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10010000_off") +mesecon.register_mvps_unsticky("mesecons:wire_01010000_on") +mesecon.register_mvps_unsticky("mesecons:wire_01010000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11010000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11010000_off") +mesecon.register_mvps_unsticky("mesecons:wire_00110000_on") +mesecon.register_mvps_unsticky("mesecons:wire_00110000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10110000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10110000_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110000_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10001000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10001000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11001000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11001000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10101000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10101000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11101000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11101000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10011000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10011000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11011000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11011000_off") +mesecon.register_mvps_unsticky("mesecons:wire_10111000_on") +mesecon.register_mvps_unsticky("mesecons:wire_10111000_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111000_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111000_off") +mesecon.register_mvps_unsticky("mesecons:wire_01000100_on") +mesecon.register_mvps_unsticky("mesecons:wire_01000100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11000100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11000100_off") +mesecon.register_mvps_unsticky("mesecons:wire_01100100_on") +mesecon.register_mvps_unsticky("mesecons:wire_01100100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11100100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11100100_off") +mesecon.register_mvps_unsticky("mesecons:wire_01010100_on") +mesecon.register_mvps_unsticky("mesecons:wire_01010100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11010100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11010100_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110100_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11001100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11001100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11101100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11101100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11011100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11011100_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111100_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111100_off") +mesecon.register_mvps_unsticky("mesecons:wire_00100010_on") +mesecon.register_mvps_unsticky("mesecons:wire_00100010_off") +mesecon.register_mvps_unsticky("mesecons:wire_10100010_on") +mesecon.register_mvps_unsticky("mesecons:wire_10100010_off") +mesecon.register_mvps_unsticky("mesecons:wire_01100010_on") +mesecon.register_mvps_unsticky("mesecons:wire_01100010_off") +mesecon.register_mvps_unsticky("mesecons:wire_11100010_on") +mesecon.register_mvps_unsticky("mesecons:wire_11100010_off") +mesecon.register_mvps_unsticky("mesecons:wire_00110010_on") +mesecon.register_mvps_unsticky("mesecons:wire_00110010_off") +mesecon.register_mvps_unsticky("mesecons:wire_10110010_on") +mesecon.register_mvps_unsticky("mesecons:wire_10110010_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110010_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110010_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110010_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110010_off") +mesecon.register_mvps_unsticky("mesecons:wire_10101010_on") +mesecon.register_mvps_unsticky("mesecons:wire_10101010_off") +mesecon.register_mvps_unsticky("mesecons:wire_11101010_on") +mesecon.register_mvps_unsticky("mesecons:wire_11101010_off") +mesecon.register_mvps_unsticky("mesecons:wire_10111010_on") +mesecon.register_mvps_unsticky("mesecons:wire_10111010_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111010_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111010_off") +mesecon.register_mvps_unsticky("mesecons:wire_01100110_on") +mesecon.register_mvps_unsticky("mesecons:wire_01100110_off") +mesecon.register_mvps_unsticky("mesecons:wire_11100110_on") +mesecon.register_mvps_unsticky("mesecons:wire_11100110_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110110_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110110_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110110_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110110_off") +mesecon.register_mvps_unsticky("mesecons:wire_11101110_on") +mesecon.register_mvps_unsticky("mesecons:wire_11101110_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111110_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111110_off") +mesecon.register_mvps_unsticky("mesecons:wire_00010001_on") +mesecon.register_mvps_unsticky("mesecons:wire_00010001_off") +mesecon.register_mvps_unsticky("mesecons:wire_10010001_on") +mesecon.register_mvps_unsticky("mesecons:wire_10010001_off") +mesecon.register_mvps_unsticky("mesecons:wire_01010001_on") +mesecon.register_mvps_unsticky("mesecons:wire_01010001_off") +mesecon.register_mvps_unsticky("mesecons:wire_11010001_on") +mesecon.register_mvps_unsticky("mesecons:wire_11010001_off") +mesecon.register_mvps_unsticky("mesecons:wire_00110001_on") +mesecon.register_mvps_unsticky("mesecons:wire_00110001_off") +mesecon.register_mvps_unsticky("mesecons:wire_10110001_on") +mesecon.register_mvps_unsticky("mesecons:wire_10110001_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110001_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110001_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110001_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110001_off") +mesecon.register_mvps_unsticky("mesecons:wire_10011001_on") +mesecon.register_mvps_unsticky("mesecons:wire_10011001_off") +mesecon.register_mvps_unsticky("mesecons:wire_11011001_on") +mesecon.register_mvps_unsticky("mesecons:wire_11011001_off") +mesecon.register_mvps_unsticky("mesecons:wire_10111001_on") +mesecon.register_mvps_unsticky("mesecons:wire_10111001_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111001_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111001_off") +mesecon.register_mvps_unsticky("mesecons:wire_01010101_on") +mesecon.register_mvps_unsticky("mesecons:wire_01010101_off") +mesecon.register_mvps_unsticky("mesecons:wire_11010101_on") +mesecon.register_mvps_unsticky("mesecons:wire_11010101_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110101_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110101_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110101_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110101_off") +mesecon.register_mvps_unsticky("mesecons:wire_11011101_on") +mesecon.register_mvps_unsticky("mesecons:wire_11011101_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111101_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111101_off") +mesecon.register_mvps_unsticky("mesecons:wire_00110011_on") +mesecon.register_mvps_unsticky("mesecons:wire_00110011_off") +mesecon.register_mvps_unsticky("mesecons:wire_10110011_on") +mesecon.register_mvps_unsticky("mesecons:wire_10110011_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110011_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110011_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110011_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110011_off") +mesecon.register_mvps_unsticky("mesecons:wire_10111011_on") +mesecon.register_mvps_unsticky("mesecons:wire_10111011_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111011_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111011_off") +mesecon.register_mvps_unsticky("mesecons:wire_01110111_on") +mesecon.register_mvps_unsticky("mesecons:wire_01110111_off") +mesecon.register_mvps_unsticky("mesecons:wire_11110111_on") +mesecon.register_mvps_unsticky("mesecons:wire_11110111_off") +mesecon.register_mvps_unsticky("mesecons:wire_11111111_on") +mesecon.register_mvps_unsticky("mesecons:wire_11111111_off") +-- Redstone Repeater +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_off_1") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_off_2") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_off_3") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_off_4") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_on_1") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_on_2") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_on_3") +mesecon.register_mvps_unsticky("mesecons_delayer:delayer_on_4") +-- Redstone Torch +mesecon.register_mvps_unsticky("mesecons_torch:mesecon_torch_on") +mesecon.register_mvps_unsticky("mesecons_torch:mesecon_torch_off") +mesecon.register_mvps_unsticky("mesecons_torch:mesecon_torch_on_wall") +mesecon.register_mvps_unsticky("mesecons_torch:mesecon_torch_off_wall") +-- Sea Pickle +mesecon.register_mvps_unsticky("mcl_ocean:sea_pickle_1_dead_brain_coral_block") +mesecon.register_mvps_unsticky("mcl_ocean:sea_pickle_2_dead_brain_coral_block") +mesecon.register_mvps_unsticky("mcl_ocean:sea_pickle_3_dead_brain_coral_block") +mesecon.register_mvps_unsticky("mcl_ocean:sea_pickle_4_dead_brain_coral_block") +-- Shulker chests +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: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:red_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:silver_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:white_shulker_box_small") +mesecon.register_mvps_unsticky("mcl_chests:yellow_shulker_box_small") +-- Snow +mesecon.register_mvps_unsticky("mcl_core:snow") +mesecon.register_mvps_unsticky("mcl_core:snow_2") +mesecon.register_mvps_unsticky("mcl_core:snow_3") +mesecon.register_mvps_unsticky("mcl_core:snow_4") +mesecon.register_mvps_unsticky("mcl_core:snow_5") +mesecon.register_mvps_unsticky("mcl_core:snow_6") +mesecon.register_mvps_unsticky("mcl_core:snow_7") +mesecon.register_mvps_unsticky("mcl_core:snow_8") +-- Torch +mesecon.register_mvps_unsticky("mcl_torches:torch") +mesecon.register_mvps_unsticky("mcl_torches:torch_wall") +-- Wheat +mesecon.register_mvps_unsticky("mcl_farming:wheat") +mesecon.register_mvps_unsticky("mcl_farming:wheat_2") +mesecon.register_mvps_unsticky("mcl_farming:wheat_3") +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") + +-- Includes node heat when moving them mesecon.register_on_mvps_move(mesecon.move_hot_nodes) --- Check for falling after moving node mesecon.register_on_mvps_move(function(moved_nodes) for i = 1, #moved_nodes do local moved_node = moved_nodes[i] + -- Check for falling after moving node mesecon.on_placenode(moved_node.pos, moved_node.node) minetest.after(0, function() minetest.check_for_falling(moved_node.oldpos) minetest.check_for_falling(moved_node.pos) end) + + -- Callback for on_mvps_move stored in nodedef local node_def = minetest.registered_nodes[moved_node.node.name] if node_def and node_def.mesecon and node_def.mesecon.on_mvps_move then node_def.mesecon.on_mvps_move(moved_node.pos, moved_node.node, diff --git a/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf b/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf new file mode 100644 index 000000000..3e347879f --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_mvps/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_mvps +depends = mesecons diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt b/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt deleted file mode 100644 index 77b6f4da3..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -mcl_particles diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua b/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua index 279e98ba6..ac56d8bc5 100644 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/init.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator("mesecons_noteblock") +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math minetest.register_node("mesecons_noteblock:noteblock", { description = S("Note Block"), @@ -28,7 +30,7 @@ S("The note block will only play a note when it is below air, otherwise, it stay groups = {handy=1,axey=1, material_wood=1, flammable=-1}, is_ground_content = false, place_param2 = 0, - on_rightclick = function (pos, node, clicker) -- change sound when rightclicked + on_rightclick = function(pos, node, clicker) -- change sound when rightclicked local protname = clicker:get_player_name() if minetest.is_protected(pos, protname) then minetest.record_protection_violation(pos, protname) @@ -38,12 +40,12 @@ S("The note block will only play a note when it is below air, otherwise, it stay mesecon.noteblock_play(pos, node.param2) minetest.set_node(pos, node) end, - on_punch = function (pos, node) -- play current sound when punched + on_punch = function(pos, node) -- play current sound when punched mesecon.noteblock_play(pos, node.param2) end, sounds = mcl_sounds.node_sound_wood_defaults(), mesecons = {effector = { -- play sound when activated - action_on = function (pos, node) + action_on = function(pos, node) mesecon.noteblock_play(pos, node.param2) end, rules = mesecon.rules.alldirs, @@ -53,7 +55,7 @@ S("The note block will only play a note when it is below air, otherwise, it stay }) minetest.register_craft({ - output = '"mesecons_noteblock:noteblock" 1', + output = "mesecons_noteblock:noteblock", recipe = { {"group:wood", "group:wood", "group:wood"}, {"group:wood", "mesecons:redstone", "group:wood"}, @@ -124,7 +126,11 @@ local function param2_to_note_color(param2) return string.format("#%06X", color) end -mesecon.noteblock_play = function (pos, param2) +local function param2_to_pitch(param2) + return 2^((param2-12)/12) +end + +function mesecon.noteblock_play(pos, param2) local block_above_name = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name if block_above_name ~= "air" then -- Don't play sound if no air is above @@ -132,9 +138,6 @@ mesecon.noteblock_play = function (pos, param2) end local block_below_name = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name - local param2_to_pitch = function(param2) - return 2^((param2-12)/12) - end local pitched = false local soundname, pitch if block_below_name == "mcl_core:goldblock" then diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.fr.tr b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.fr.tr index f8d8e3d75..a3ddcb242 100644 --- a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.fr.tr @@ -2,21 +2,21 @@ Note Block=Bloc de notes 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.=Un bloc de notes est un bloc musical qui joue l'une des nombreuses notes de musique et différents instruments lorsqu'il est frappé ou alimenté en redstone. 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:=Utilisez le bloc de notes pour choisir la prochaine note de musique (il y a 25 demi-tons ou 2 octaves). L'instrument joué dépend du matériau du bloc situé sous le bloc de notes: -• Glass: Sticks=• Glass: Sticks -• Wood: Bass guitar=• Bois: Guitare Basse -• Stone: Bass drum=• Pierre: Grosse caisse -• Sand or gravel: Snare drum=• Sable ou gravier: Caisse claire -• Block of Gold: Bell=• Bloc d'OR: Cloche -• Clay: Flute=• Argile: Flûte -• Packed Ice: Chime=• Glace tassée: Carillon -• Wool: Guitar=• Laine: Guitare -• Bone Block: Xylophne=• Bloc osseux: Xylophne -• Block of Iron: Iron xylophne=• Bloc de fer: Xylophone en fer -• Soul Sand: Cow bell=• Soul Sand: Cloche de vache -• Pumpkin: Didgeridoo=• Citrouille: Didgeridoo -• Block of Emerald: Square wave=• Bloc d'émeraude: Onde carrée -• Hay Bale: Banjo=• Hay Bale: Banjo -• Glowstone: Electric piano=• Glowstone: Piano Electrique -• Anything else: Piano=• Autres: Piano +• Glass: Sticks=• Verre : Baguettes +• Wood: Bass guitar=• Bois : Guitare Basse +• Stone: Bass drum=• Pierre : Grosse caisse +• Sand or gravel: Snare drum=• Sable ou gravier : Caisse claire +• Block of Gold: Bell=• Bloc d'OR : Cloche +• Clay: Flute=• Argile : Flûte +• Packed Ice: Chime=• Glace tassée : Carillon +• Wool: Guitar=• Laine : Guitare +• Bone Block: Xylophne=• Bloc osseux : Xylophne +• Block of Iron: Iron xylophne=• Bloc de fer : Xylophone en fer +• Soul Sand: Cow bell=• Soul Sand : Cloche de vache +• Pumpkin: Didgeridoo=• Citrouille : Didgeridoo +• Block of Emerald: Square wave=• Bloc d'émeraude : Onde carrée +• Hay Bale: Banjo=• Hay Bale : Banjo +• Glowstone: Electric piano=• Glowstone : Piano Electrique +• Anything else: Piano=• Autres : Piano The note block will only play a note when it is below air, otherwise, it stays silent.=Le bloc de notes ne jouera une note que lorsqu'il est sous l'air, sinon il reste silencieux. Plays a musical note when powered by redstone power=Joue une note de musique lorsqu'il est alimenté par une puissance redstone diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr new file mode 100644 index 000000000..0591b6b92 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.ja.tr @@ -0,0 +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.=音符ブロックは、パンチしたりレッドストーン動力を供給することで、多くの音符やさまざまな楽器のうちの1つを演奏する音楽ブロックです。 +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=砂・砂利:スネアドラム +• Anything else: Piano=その他:ピアノ +• Block of Gold: Bell=金ブロック:ベル +• Clay: Flute=粘土:フルート +• Packed Ice: Chime=氷塊:チャイム +• Wool: Guitar=羊毛:ギター +• Bone Block: 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=レッドストーン動力が来ると音符を演奏 diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.pl.tr b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.pl.tr new file mode 100644 index 000000000..fbf31bc16 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/locale/mesecons_noteblock.pl.tr @@ -0,0 +1,22 @@ +# textdomain: mesecons_noteblock +Note Block=Blok nuty +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.=Blok nuty jest muzycznym blokiem, który gra jedną z wielu muzycznych nut różnych instrumentów gdy jest uderzony, lub zasilony czerwienitem. +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:=Użyj bloku nuty aby wybrać następną muzyczną nutę (możliwe jest 25 półtonów, lub 2 oktawy). Zagrany instrument zależy od materiału znajdującego się pod blokiem nuty: +• Glass: Sticks=• Szkło: patyki +• Wood: Bass guitar=• Drewno: gitara basowa +• Stone: Bass drum=• Kamień: bęben +• Sand or gravel: Snare drum=• Piasek lub żwir: bęben mały +• Anything else: Piano=• Cokolwiek innego: pianino +• Block of Gold: Bell=• Blok złota: dzwon +• Clay: Flute=• Glina: flet +• Packed Ice: Chime=• Zbity lud: cymbałki +• Wool: Guitar=• Wełna: gitara +• Bone Block: Xylophne=• Blok kości: ksylofon +• Block of Iron: Iron xylophne=• Blok żelaza: żelazny ksylofon +• Soul Sand: Cow bell=• Piasek dusz: krowi dzwonek +• Pumpkin: Didgeridoo=• Dynia: Didgeridoo +• Block of Emerald: Square wave=• Blok szmaragdu: fala kwadratowa +• Hay Bale: Banjo=• Bela siana: banjo +• Glowstone: Electric piano=• Jasnogłaz: elektryczne pianino +The note block will only play a note when it is below air, otherwise, it stays silent.=Blok nuty gra tylko gdy jest poniżej powietrza, w przeciwnym przypadku będzie cichy. +Plays a musical note when powered by redstone power=Gra muzyczną nutę gdy zasilana energię czerwienitową diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf b/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf new file mode 100644 index 000000000..c388e7a26 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_noteblock/mod.conf @@ -0,0 +1,2 @@ +name = mesecons_noteblock +depends = mesecons, mcl_particles diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt b/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt deleted file mode 100644 index c19acf4b9..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mesecons -mesecons_mvps -mcl_mobitems -doc? -screwdriver? diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua index 3230d9804..93b8df96d 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/init.lua @@ -1,30 +1,37 @@ -local S = minetest.get_translator("mesecons_pistons") +local S = minetest.get_translator(minetest.get_current_modname()) local PISTON_MAXIMUM_PUSH = 12 --- Get mesecon rules of pistons -local piston_rules = -{{x=0, y=0, z=1}, --everything apart from z- (pusher side) - {x=1, y=0, z=0}, - {x=-1, y=0, z=0}, - {x=0, y=1, z=0}, - {x=0, y=-1, z=0}} +--Get mesecon rules of pistons -local piston_up_rules = -{{x=0, y=0, z=-1}, --everything apart from y+ (pusher side) - {x=0, y=0, z=1}, - {x=-1, y=0, z=0}, - {x=1, y=0, z=0}, - {x=0, y=-1, z=0}} +--everything apart from z- (pusher side) +local piston_rules = { + {x=0, y=0, z=1}, + {x=1, y=0, z=0}, + {x=-1, y=0, z=0}, + {x=0, y=1, z=0}, + {x=0, y=-1, z=0}, +} -local piston_down_rules = -{{x=0, y=0, z=-1}, --everything apart from y- (pusher side) - {x=0, y=0, z=1}, - {x=-1, y=0, z=0}, - {x=1, y=0, z=0}, - {x=0, y=1, z=0}} +--everything apart from y+ (pusher side) +local piston_up_rules = { + {x=0, y=0, z=-1}, + {x=0, y=0, z=1}, + {x=-1, y=0, z=0}, + {x=1, y=0, z=0}, + {x=0, y=-1, z=0}, +} -local piston_get_rules = function (node) +--everything apart from y- (pusher side) +local piston_down_rules = { + {x=0, y=0, z=-1}, + {x=0, y=0, z=1}, + {x=-1, y=0, z=0}, + {x=1, y=0, z=0}, + {x=0, y=1, z=0}, +} + +local function piston_get_rules(node) local rules = piston_rules for i = 1, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -32,7 +39,7 @@ local piston_get_rules = function (node) return rules end -local piston_facedir_direction = function (node) +local function piston_facedir_direction(node) local rules = {{x = 0, y = 0, z = -1}} for i = 1, node.param2 do rules = mesecon.rotate_rules_left(rules) @@ -40,7 +47,7 @@ local piston_facedir_direction = function (node) return rules[1] end -local piston_get_direction = function (dir, node) +local function piston_get_direction(dir, node) if type(dir) == "function" then return dir(node) else @@ -50,7 +57,7 @@ end -- Remove pusher of piston. -- To be used when piston was destroyed or dug. -local piston_remove_pusher = function (pos, oldnode) +local function piston_remove_pusher(pos, oldnode) local pistonspec = minetest.registered_nodes[oldnode.name].mesecons_piston local dir = piston_get_direction(pistonspec.dir, oldnode) @@ -59,7 +66,7 @@ local piston_remove_pusher = function (pos, oldnode) if pushername == pistonspec.pusher then -- make sure there actually is a pusher minetest.remove_node(pusherpos) - core.check_for_falling(pusherpos) + minetest.check_for_falling(pusherpos) minetest.sound_play("piston_retract", { pos = pos, max_hear_distance = 31, @@ -70,7 +77,7 @@ end -- Remove base node of piston. -- To be used when pusher was destroyed. -local piston_remove_base = function (pos, oldnode) +local function piston_remove_base(pos, oldnode) local basenodename = minetest.registered_nodes[oldnode.name].corresponding_piston local pistonspec = minetest.registered_nodes[basenodename].mesecons_piston @@ -80,7 +87,7 @@ local piston_remove_base = function (pos, oldnode) if basename == pistonspec.onname then -- make sure there actually is a base node minetest.remove_node(basepos) - core.check_for_falling(basepos) + minetest.check_for_falling(basepos) minetest.sound_play("piston_retract", { pos = pos, max_hear_distance = 31, @@ -89,7 +96,7 @@ local piston_remove_base = function (pos, oldnode) end end -local piston_on = function (pos, node) +local function piston_on(pos, node) local pistonspec = minetest.registered_nodes[node.name].mesecons_piston local dir = piston_get_direction(pistonspec.dir, node) @@ -113,7 +120,7 @@ local piston_on = function (pos, node) end end -local piston_off = function (pos, node) +local function piston_off(pos, node) local pistonspec = minetest.registered_nodes[node.name].mesecons_piston minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.offname}) piston_remove_pusher (pos, node) @@ -124,13 +131,13 @@ local piston_off = function (pos, node) local dir = piston_get_direction(pistonspec.dir, node) local pullpos = vector.add(pos, vector.multiply(dir, 2)) local meta = minetest.get_meta(pos) - local success, stack, oldstack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos) + local success, stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos) if success then mesecon.mvps_process_stack(pos, dir, stack) end end -local piston_orientate = function (pos, placer) +local function piston_orientate(pos, placer) mesecon.mvps_set_owner(pos, placer) -- not placed by player @@ -158,14 +165,14 @@ local piston_pusher_box = { fixed = { {-2/16, -2/16, -.5 + pt, 2/16, 2/16, .5 + pt}, {-.5 , -.5 , -.5 , .5 , .5 , -.5 + pt}, - } + }, } local piston_on_box = { type = "fixed", fixed = { {-.5, -.5, -.5 + pt, .5, .5, .5} - } + }, } @@ -195,18 +202,20 @@ minetest.register_node("mesecons_pistons:piston_normal_off", { "mesecons_piston_bottom.png^[transformR270", "mesecons_piston_back.png", "mesecons_piston_pusher_front.png" - }, - groups = {handy = 1, piston=1}, + }, + groups = {handy=1, piston=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, after_place_node = piston_orientate, mesecons_piston = pistonspec_normal, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_on = piston_on, - rules = piston_get_rules - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_get_rules + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = function(pos, node, user, mode) @@ -227,8 +236,8 @@ minetest.register_node("mesecons_pistons:piston_normal_on", { "mesecons_piston_bottom.png^[transformR270", "mesecons_piston_back.png", "mesecons_piston_on_front.png" - }, - groups = {handy=1, piston=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -238,10 +247,12 @@ minetest.register_node("mesecons_pistons:piston_normal_on", { selection_box = piston_on_box, mesecons_piston = pistonspec_normal, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_get_rules - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_get_rules + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -257,10 +268,10 @@ minetest.register_node("mesecons_pistons:piston_pusher_normal", { "mesecons_piston_pusher_right.png", "mesecons_piston_pusher_back.png", "mesecons_piston_pusher_front.png" - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 1 }, + groups = {piston_pusher=1}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -299,7 +310,7 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", { "mesecons_piston_bottom.png^[transformR270", "mesecons_piston_back.png", "mesecons_piston_pusher_front_sticky.png" - }, + }, groups = {handy=1, piston=2}, paramtype = "light", paramtype2 = "facedir", @@ -307,10 +318,12 @@ minetest.register_node("mesecons_pistons:piston_sticky_off", { after_place_node = piston_orientate, mesecons_piston = pistonspec_sticky, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_on = piston_on, - rules = piston_get_rules - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_get_rules + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = function(pos, node, user, mode) @@ -331,8 +344,8 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", { "mesecons_piston_bottom.png^[transformR270", "mesecons_piston_back.png", "mesecons_piston_on_front.png" - }, - groups = {handy=1, piston=2, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=2, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -342,10 +355,12 @@ minetest.register_node("mesecons_pistons:piston_sticky_on", { selection_box = piston_on_box, mesecons_piston = pistonspec_sticky, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_get_rules - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_get_rules + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -361,10 +376,10 @@ minetest.register_node("mesecons_pistons:piston_pusher_sticky", { "mesecons_piston_pusher_right.png", "mesecons_piston_pusher_back.png", "mesecons_piston_pusher_front_sticky.png" - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 2 }, + groups = {piston_pusher=2}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -388,14 +403,14 @@ local piston_up_pusher_box = { fixed = { {-2/16, -.5 - pt, -2/16, 2/16, .5 - pt, 2/16}, {-.5 , .5 - pt, -.5 , .5 , .5 , .5}, - } + }, } local piston_up_on_box = { type = "fixed", fixed = { {-.5, -.5, -.5 , .5, .5-pt, .5} - } + }, } -- Normal @@ -404,7 +419,7 @@ local pistonspec_normal_up = { offname = "mesecons_pistons:piston_up_normal_off", onname = "mesecons_pistons:piston_up_normal_on", dir = {x = 0, y = 1, z = 0}, - pusher = "mesecons_pistons:piston_up_pusher_normal" + pusher = "mesecons_pistons:piston_up_pusher_normal", } -- offstate @@ -416,17 +431,19 @@ minetest.register_node("mesecons_pistons:piston_up_normal_off", { "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", - }, - groups = {handy=1, piston=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, drop = "mesecons_pistons:piston_normal_off", mesecons_piston = pistonspec_normal_up, - mesecons = {effector={ - action_on = piston_on, - rules = piston_up_rules, - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_up_rules, + }, + }, sounds = mcl_sounds.node_sound_stone_defaults({ footstep = mcl_sounds.node_sound_wood_defaults().footstep }), @@ -451,8 +468,8 @@ minetest.register_node("mesecons_pistons:piston_up_normal_on", { "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", - }, - groups = {handy=1, piston_=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston_=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -462,10 +479,12 @@ minetest.register_node("mesecons_pistons:piston_up_normal_on", { selection_box = piston_up_on_box, mesecons_piston = pistonspec_normal_up, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_up_rules, - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_up_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -481,10 +500,10 @@ minetest.register_node("mesecons_pistons:piston_up_pusher_normal", { "mesecons_piston_pusher_right.png^[transformR90", "mesecons_piston_pusher_bottom.png", "mesecons_piston_pusher_top.png^[transformR180", - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 1 }, + groups = {piston_pusher=1}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -507,7 +526,7 @@ local pistonspec_sticky_up = { onname = "mesecons_pistons:piston_up_sticky_on", dir = {x = 0, y = 1, z = 0}, pusher = "mesecons_pistons:piston_up_pusher_sticky", - sticky = true + sticky = true, } -- offstate @@ -519,8 +538,8 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_off", { "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", - }, - groups = {handy=1, piston=2, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=2, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -529,10 +548,12 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_off", { sounds = mcl_sounds.node_sound_stone_defaults({ footstep = mcl_sounds.node_sound_wood_defaults().footstep }), - mesecons = {effector={ - action_on = piston_on, - rules = piston_up_rules, - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_up_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = function(pos, node, user, mode) @@ -554,8 +575,8 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_on", { "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", "mesecons_piston_bottom.png", - }, - groups = {handy=1, piston=2, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=2, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -565,10 +586,12 @@ minetest.register_node("mesecons_pistons:piston_up_sticky_on", { selection_box = piston_up_on_box, mesecons_piston = pistonspec_sticky_up, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_up_rules, - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_up_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -584,10 +607,10 @@ minetest.register_node("mesecons_pistons:piston_up_pusher_sticky", { "mesecons_piston_pusher_right.png^[transformR90", "mesecons_piston_pusher_bottom.png", "mesecons_piston_pusher_top.png^[transformR180", - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 2 }, + groups = {piston_pusher=2}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -611,14 +634,14 @@ local piston_down_pusher_box = { fixed = { {-2/16, -.5 + pt, -2/16, 2/16, .5 + pt, 2/16}, {-.5 , -.5 , -.5 , .5 , -.5 + pt, .5}, - } + }, } local piston_down_on_box = { type = "fixed", fixed = { {-.5, -.5+pt, -.5 , .5, .5, .5} - } + }, } @@ -641,18 +664,20 @@ minetest.register_node("mesecons_pistons:piston_down_normal_off", { "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", - }, - groups = {handy=1, piston=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, drop = "mesecons_pistons:piston_normal_off", mesecons_piston = pistonspec_normal_down, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_on = piston_on, - rules = piston_down_rules, - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_down_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = function(pos, node, user, mode) @@ -674,8 +699,8 @@ minetest.register_node("mesecons_pistons:piston_down_normal_on", { "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", - }, - groups = {handy=1, piston=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -685,10 +710,12 @@ minetest.register_node("mesecons_pistons:piston_down_normal_on", { selection_box = piston_down_on_box, mesecons_piston = pistonspec_normal_down, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_down_rules, - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_down_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -704,10 +731,10 @@ minetest.register_node("mesecons_pistons:piston_down_pusher_normal", { "mesecons_piston_pusher_right.png^[transformR270", "mesecons_piston_pusher_bottom.png^[transformR180", "mesecons_piston_pusher_top.png", - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 1 }, + groups = {piston_pusher=1}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -727,7 +754,7 @@ local pistonspec_sticky_down = { offname = "mesecons_pistons:piston_down_sticky_off", dir = {x = 0, y = -1, z = 0}, pusher = "mesecons_pistons:piston_down_pusher_sticky", - sticky = true + sticky = true, } -- offstate @@ -739,7 +766,7 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_off", { "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", - }, + }, groups = {handy=1, piston=2, not_in_creative_inventory = 1}, paramtype = "light", paramtype2 = "facedir", @@ -747,10 +774,12 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_off", { drop = "mesecons_pistons:piston_sticky_off", mesecons_piston = pistonspec_sticky_down, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_on = piston_on, - rules = piston_down_rules, - }}, + mesecons = { + effector = { + action_on = piston_on, + rules = piston_down_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = function(pos, node, user, mode) @@ -772,8 +801,8 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_on", { "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", "mesecons_piston_bottom.png^[transformR180", - }, - groups = {handy=1, piston=1, not_in_creative_inventory = 1}, + }, + groups = {handy=1, piston=1, not_in_creative_inventory=1}, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, @@ -783,10 +812,12 @@ minetest.register_node("mesecons_pistons:piston_down_sticky_on", { selection_box = piston_down_on_box, mesecons_piston = pistonspec_sticky_down, sounds = mcl_sounds.node_sound_stone_defaults(), - mesecons = {effector={ - action_off = piston_off, - rules = piston_down_rules, - }}, + mesecons = { + effector = { + action_off = piston_off, + rules = piston_down_rules, + }, + }, _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, on_rotate = false, @@ -802,10 +833,10 @@ minetest.register_node("mesecons_pistons:piston_down_pusher_sticky", { "mesecons_piston_pusher_right.png^[transformR270", "mesecons_piston_pusher_bottom.png^[transformR180", "mesecons_piston_pusher_top.png", - }, + }, paramtype = "light", paramtype2 = "facedir", - groups = { piston_pusher = 2 }, + groups = {piston_pusher=2}, is_ground_content = false, after_destruct = piston_remove_base, diggable = false, @@ -834,12 +865,12 @@ mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on") --craft recipes minetest.register_craft({ - output = 'mesecons_pistons:piston_normal_off', + output = "mesecons_pistons:piston_normal_off", recipe = { {"group:wood", "group:wood", "group:wood"}, {"mcl_core:cobble", "mcl_core:iron_ingot", "mcl_core:cobble"}, {"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble"}, - } + }, }) minetest.register_craft({ @@ -847,7 +878,7 @@ minetest.register_craft({ recipe = { {"mcl_mobitems:slimeball"}, {"mesecons_pistons:piston_normal_off"}, - } + }, }) -- Add entry aliases for the Help diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr new file mode 100644 index 000000000..949de6805 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mesecons_pistons +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.=ピストンとは、押出機を備えたレッドストーン部品のことで、レッドストーン動力が供給されると、その前方の1つないしは複数のブロックを押します。ただし、すべてのブロックが押せるわけではありません。 +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.=粘着ピストンは、粘着付押出機が伸縮できるレッドストーン部品です。レッドストーン動力が供給されると伸びます。押出機が伸びると、その前方の1つないしは複数のブロックを押します。押出機が縮むと、手前にある1つのブロックを引き戻します。なお、すべてのブロックが伸縮できるわけではありません。 +Pushes block when powered by redstone power=レッドストーン動力が来るとブロックを押す +Pushes or pulls block when powered by redstone power=レッドストーン動力が来るとブロックを押すか引く diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.pl.tr b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.pl.tr new file mode 100644 index 000000000..8f7f45191 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/locale/mesecons_pistons.pl.tr @@ -0,0 +1,9 @@ +# textdomain: mesecons_pistons +This block can have one of 6 possible orientations.=Ten blok może mieć 6 możliwych orientacji. +Piston=Tłok +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.=Tłoki są mechanizmami czerwienitowymi które popycha blok lub bloki stojące przed nim gdy dostarczy się mu energię czerwienitową, jednak nie wszystkie bloki mogą zostać popchnięte. +Sticky Piston=Lepki tłok +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.=Lepki tłok jest mechanizmem czerwienitowym z lepkim wysięgnikiem, który można wysuwać i wsuwać. Wysuwa się gdy dostarczana jest energia czerwienitowa. Gdy się wysuwa popycha on blok lub bloki znajdujące się przed nim. Gdy się wsuwa przyciąga on pojedynczy blok przed nim. Nie wszystkie bloki mogą być przesuwane i przyciągane. +Pushes block when powered by redstone power=Popycha blok gdy jest zasilony czerwienitem +Pushes or pulls block when powered by redstone power=Popycha lub przyciąga blok gdy jest zasilany czerwienitem + diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf b/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf new file mode 100644 index 000000000..5a3f6c80f --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pistons/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_pistons +depends = mesecons, mesecons_mvps, mcl_mobitems +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_back.png b/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_back.png deleted file mode 100644 index 6ea941df5..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_back.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_bottom.png b/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_bottom.png deleted file mode 100644 index b3b44718e..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_bottom.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_on_front.png b/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_on_front.png deleted file mode 100644 index a718134ca..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_on_front.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt b/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua index 2e161ae4d..a4043fb5f 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/init.lua @@ -1,6 +1,6 @@ -local S = minetest.get_translator("mesecons_pressureplates") +local S = minetest.get_translator(minetest.get_current_modname()) -local PRESSURE_PLATE_INTERVAL = 0.04 +local PRESSURE_PLATE_INTERVAL = 0.25 local pp_box_off = { type = "fixed", @@ -12,6 +12,16 @@ local pp_box_on = { fixed = { -7/16, -8/16, -7/16, 7/16, -7.5/16, 7/16 }, } +local function pp_on_rightclick(pos, node) + local basename = minetest.registered_nodes[node.name].pressureplate_basename + if node.name == basename .. "_off" then + minetest.set_node(pos, { name = basename .. "_on" }) + mesecon.receptor_on(pos, mesecon.rules.pplate) + else + minetest.get_meta(pos):set_string("deact_time", "") + end +end + local function pp_on_timer(pos, elapsed) local node = minetest.get_node(pos) local basename = minetest.registered_nodes[node.name].pressureplate_basename @@ -28,7 +38,7 @@ local function pp_on_timer(pos, elapsed) local obj_does_activate = function(obj, activated_by) if activated_by.any then return true - elseif activated_by.mob and obj:get_luaentity() and obj:get_luaentity()._cmi_is_mob == true then + elseif activated_by.mob and obj:get_luaentity() and obj:get_luaentity().is_mob == true then return true elseif activated_by.player and obj:is_player() then return true @@ -37,34 +47,80 @@ local function pp_on_timer(pos, elapsed) end end - local objs = minetest.get_objects_inside_radius(pos, 1) + local function obj_touching_plate_pos(obj_ref, plate_pos) + local obj_pos = obj_ref:get_pos() + local props = obj_ref:get_properties() + local parent = obj_ref:get_attach() + if props and obj_pos and not parent then + local collisionbox = props.collisionbox + local physical = props.physical + local is_player = obj_ref:is_player() + local luaentity = obj_ref:get_luaentity() + local is_item = luaentity and luaentity.name == "__builtin:item" + if collisionbox and physical or is_player or is_item then + local plate_x_min = plate_pos.x - 7 / 16 + local plate_x_max = plate_pos.x + 7 / 16 + local plate_z_min = plate_pos.z - 7 / 16 + local plate_z_max = plate_pos.z + 7 / 16 + local plate_y_max = plate_pos.y - 7 / 16 - if node.name == basename .. "_on" then - local disable - if #objs == 0 then - disable = true - elseif not activated_by.any then - disable = true - for k, obj in pairs(objs) do - if obj_does_activate(obj, activated_by) then - disable = false - break + local obj_x_min = obj_pos.x + collisionbox[1] + local obj_x_max = obj_pos.x + collisionbox[4] + local obj_z_min = obj_pos.z + collisionbox[3] + local obj_z_max = obj_pos.z + collisionbox[6] + local obj_y_min = obj_pos.y + collisionbox[2] + + if + obj_y_min <= plate_y_max and + not (obj_x_min >= plate_x_max) and + not (obj_x_max <= plate_x_min) and + not (obj_z_min >= plate_z_max) and + not (obj_z_max <= plate_z_min) + then + return true end end end + return false + end + + local objs = minetest.get_objects_inside_radius(pos, 1) + + if node.name == basename .. "_on" then + local disable = true + for k, obj in pairs(objs) do + if + obj_does_activate(obj, activated_by) and + obj_touching_plate_pos(obj, pos) + then + disable = false + minetest.get_meta(pos):set_string("deact_time", "") + break + end + end if disable then - minetest.set_node(pos, {name = basename .. "_off"}) - mesecon.receptor_off(pos, mesecon.rules.pplate) + local meta = minetest.get_meta(pos) + local deact_time = meta:get_float("deact_time") + local current_time = minetest.get_us_time() + if deact_time == 0 then + deact_time = current_time + 1 * 1000 * 1000 + meta:set_float("deact_time", deact_time) + end + if deact_time <= current_time then + minetest.set_node(pos, { name = basename .. "_off" }) + mesecon.receptor_off(pos, mesecon.rules.pplate) + meta:set_string("deact_time", "") + end end elseif node.name == basename .. "_off" then for k, obj in pairs(objs) do - local objpos = obj:get_pos() - if obj_does_activate(obj, activated_by) then - if objpos.y > pos.y-1 and objpos.y < pos.y then - minetest.set_node(pos, {name = basename .. "_on"}) - mesecon.receptor_on(pos, mesecon.rules.pplate) - break - end + if + obj_does_activate(obj, activated_by) and + obj_touching_plate_pos(obj, pos) + then + minetest.set_node(pos, { name = basename .. "_on" }) + mesecon.receptor_on(pos, mesecon.rules.pplate) + break end end end @@ -97,7 +153,11 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te groups_on.not_in_creative_inventory = 1 groups_on.pressure_plate = 2 if not longdesc then - longdesc = S("A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.") + if groups_off.material_wood ~= 0 then + longdesc = S("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.") + else + longdesc = S("A pressure plate is a redstone component which supplies its surrounding blocks with redstone power while someone or something rests on top of it.") + end end local tt = S("Provides redstone power when pushed") if not activated_by then @@ -116,8 +176,9 @@ function mesecon.register_pressure_plate(basename, description, textures_off, te wield_image = image_w, paramtype = "light", walkable = false, - description = description, + description = description, on_timer = pp_on_timer, + on_rightclick = pp_on_rightclick, on_construct = function(pos) minetest.get_node_timer(pos):start(PRESSURE_PLATE_INTERVAL) end, @@ -164,6 +225,10 @@ local woods = { { "darkwood", "mcl_core:darkwood", "mcl_core_planks_big_oak.png", S("Dark Oak Pressure Plate" )}, { "sprucewood", "mcl_core:sprucewood", "mcl_core_planks_spruce.png", S("Spruce Pressure Plate") }, { "junglewood", "mcl_core:junglewood", "default_junglewood.png", S("Jungle Pressure Plate") }, + + { "mangrove_wood", "mcl_mangrove:mangrove_wood", "mcl_mangrove_planks.png", S("Mangrove Pressure Plate") }, + { "crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", "mcl_crimson_crimson_hyphae_wood.png", S("Crimson Pressure Plate") }, + { "warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", "mcl_crimson_warped_hyphae_wood.png", S("Warped Pressure Plate") }, } for w=1, #woods do @@ -177,8 +242,7 @@ for w=1, #woods do {{woods[w][2], woods[w][2]}}, mcl_sounds.node_sound_wood_defaults(), {axey=1, material_wood=1}, - nil, - S("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.")) + nil) minetest.register_craft({ type = "fuel", @@ -201,4 +265,17 @@ mesecon.register_pressure_plate( { player = true, mob = true }, S("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.")) +mesecon.register_pressure_plate( + "mesecons_pressureplates:pressure_plate_polished_blackstone", + S("Polished Blackstone Pressure Plate"), + {"mcl_blackstone_polished.png"}, + {"mcl_blackstone_polished.png"}, + "mcl_blackstone_polished.png", + nil, + {{"mcl_blackstone:blackstone_polished", "mcl_blackstone:blackstone_polished"}}, + mcl_sounds.node_sound_stone_defaults(), + {pickaxey=1, material_stone=1}, + { player = true, mob = true }, + S("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.")) + diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.fr.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.fr.tr index ef145de56..630ebdd48 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.fr.tr @@ -1,12 +1,17 @@ # 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.=Une plaque de pression est un composant de redstone qui alimente ses blocs environnants en puissance de redstone pendant que quelqu'un ou quelque chose repose dessus. -Oak Pressure Plate=Plaque de pression en Chêne -Acacia Pressure Plate=Plaque de pression en Acacia -Birch Pressure Plate=Plaque de pression en Bouleau -Dark Oak Pressure Plate=Plaque de pression en Chêne Noir -Spruce Pressure Plate=Plaque de pression en Sapin -Jungle Pressure Plate=Plaque de pression en Acajou +Oak Pressure Plate=Plaque de pression en chêne +Acacia Pressure Plate=Plaque de pression en acacia +Birch Pressure Plate=Plaque de pression en bouleau +Dark Oak Pressure Plate=Plaque de pression en chêne noir +Spruce Pressure Plate=Plaque de pression en sapin +Jungle Pressure Plate=Plaque de pression en acajou +Mangrove Pressure Plate=Plaque de pression en palétuvier +Crimson Pressure Plate=Plaque de pression écarlate +Warped Pressure Plate=Plaque de pression tordue 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 de redstone qui alimente ses blocs environnants en puissance de redstone tandis que tout objet mobile (y compris les objets lâchés, les joueurs et les mobs) repose dessus. +Polished Blackstone Pressure Plate=Plaque de pression en pierre noire +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.=Une plaque de pression en pierre noire est un composant de redstone qui alimente ses blocs environnants en puissance de redstone pendant qu'un joueur ou un mob se tient au-dessus. Il n'est déclenché par rien d'autre. Stone Pressure Plate=Plaque de pression en pierre 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.=Une plaque de pression en pierre est un composant de redstone qui alimente ses blocs environnants en puissance de redstone pendant qu'un joueur ou un mob se tient au-dessus. Il n'est déclenché par rien d'autre. Provides redstone power when pushed=Fournit une puissance de redstone lorsqu'il est poussé diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr new file mode 100644 index 000000000..f1e926e31 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.ja.tr @@ -0,0 +1,16 @@ +# 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=押せるのはプレイヤー、モブ、オブジェクト +Pushable by players and mobs=押せるのはプレイヤーかモブ +Pushable by players=押せるのはプレイヤー +Pushable by mobs=押せるのはモブ diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pl.tr b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pl.tr new file mode 100644 index 000000000..50cef3ba7 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/mesecons_pressureplates.pl.tr @@ -0,0 +1,16 @@ +# 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.=Płyta naciskowa jest mechanizmem czerwienitowym, który zasila otaczające bloki energią czerwienitową gdy ktoś lub coś na niej spoczywa. +Oak Pressure Plate=Dębowa płyta naciskowa +Acacia Pressure Plate=Akacjowa płyta naciskowa +Birch Pressure Plate=Brzozowa płyta naciskowa +Dark Oak Pressure Plate=Ciemno-dębowa płyta naciskowa +Spruce Pressure Plate=Świerkowa płyta naciskowa +Jungle Pressure Plate=Tropikalna płyta naciskowa +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.=Drewniana płyta naciskowa jest mechanizmem czerwienitowym, który zasila otaczające bloki energią czerwienitowym, gdy ruchomy obiekt (włączając w to upuszczone przedmioty, graczy, moby) spoczywa na niej. +Stone Pressure Plate=Kamienna płyta naciskowa +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.=Kamienna płyta naciskowa jest mechanizmem czerwienitowym, która zasila otaczające bloki energią czerwienitową gdy gracz lub mob na niej stoi. Nie jest aktywowana niczym innym. +Provides redstone power when pushed=Dostarcza energię czerwienitową gdy naciśnięta +Pushable by players, mobs and objects=Możliwa do naciśnięcia przez graczy, moby i obiekty +Pushable by players and mobs=Możliwa do naciśnięcia przez graczy i moby +Pushable by players=Możliwa do naciśnięcia przez graczy +Pushable by mobs=Możliwa do naciśnięcia przez moby diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/template.txt index 96eb3f922..061d82410 100644 --- a/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/locale/template.txt @@ -6,7 +6,12 @@ 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= diff --git a/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf b/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf new file mode 100644 index 000000000..0edd40e9a --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_pressureplates/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_pressureplates +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt b/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua index b256d87e2..f4e63b78a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/init.lua @@ -1,4 +1,9 @@ -local S = minetest.get_translator("mesecons_solarpanel") +local S = minetest.get_translator(minetest.get_current_modname()) + +local function sunlight_visible(position) + local light_level = mcl_util.get_natural_light(position) + return light_level ~= nil and light_level >= 12 +end local boxes = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 } @@ -81,11 +86,11 @@ minetest.register_node("mesecons_solarpanel:solar_panel_off", { }) minetest.register_craft({ - output = 'mesecons_solarpanel:solar_panel_off', + output = "mesecons_solarpanel:solar_panel_off", recipe = { - {'mcl_core:glass', 'mcl_core:glass', 'mcl_core:glass'}, - {'mcl_nether:quartz', 'mcl_nether:quartz', 'mcl_nether:quartz'}, - {'group:wood_slab', 'group:wood_slab', 'group:wood_slab'}, + {"mcl_core:glass", "mcl_core:glass", "mcl_core:glass"}, + {"mcl_nether:quartz", "mcl_nether:quartz", "mcl_nether:quartz"}, + {"group:wood_slab", "group:wood_slab", "group:wood_slab"}, } }) @@ -95,9 +100,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) - - if light >= 12 and minetest.get_timeofday() > 0.2 and minetest.get_timeofday() < 0.8 then + if sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -110,9 +113,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) - - if light < 12 then + if not sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end @@ -202,9 +203,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) - - if light < 12 then + if not sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_on", param2=node.param2}) mesecon.receptor_on(pos, mesecon.rules.pplate) end @@ -217,9 +216,7 @@ minetest.register_abm({ interval = 1, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local light = minetest.get_node_light(pos, nil) - - if light >= 12 and minetest.get_timeofday() > 0.8 and minetest.get_timeofday() < 0.2 then + if sunlight_visible(pos) then minetest.set_node(pos, {name="mesecons_solarpanel:solar_panel_inverted_off", param2=node.param2}) mesecon.receptor_off(pos, mesecon.rules.pplate) end diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr new file mode 100644 index 000000000..5ba7a13ec --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.ja.tr @@ -0,0 +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.=日照センサーを使用して、その状態を切り替えます。 +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=日光の下でレッドストーン動力を供給 +Can be inverted=反転可能 diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.pl.tr b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.pl.tr new file mode 100644 index 000000000..d7e3e19ca --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/locale/mesecons_solarpanel.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mesecons_solarpanel +Daylight Sensor=Czujnik światła dziennego +Daylight sensors are redstone components which provide redstone power when they are in sunlight and no power otherwise. They can also be inverted.=Czujniki światła dziennego są czerwienitowymi elementami, które wysyłają energie czerwienitową gdy są w świetle słonecznym i nie dostarczają energii w przeciwnym przypadku. +Use the daylight sensor to toggle its state.=Użyj czujnik światła dziennego by zmienić jego stan. +Inverted Daylight Sensor=Odwrotny czujnik światła dziennego +In inverted state, they provide redstone power when they are not in sunlight and no power otherwise.=W odwrotnym stanie, dostarczają energię czerwienitową gdy nie są w świetle słonecznym i nie dostarczają energii w przeciwnym przypadku. +Provides redstone power when in sunlight=Dostarcza energię czerwienitową gdy w oświetlony słońcem +Can be inverted=Może być odwrócony diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf b/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf new file mode 100644 index 000000000..9897b7488 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_solarpanel/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_solarpanel +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel_side.png b/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel_side.png deleted file mode 100644 index ca6c3d6a5..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel_side.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt b/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt deleted file mode 100644 index 9636f7bd5..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_torch/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mesecons -mcl_torches -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua index c7c4a4ca2..e49b843cc 100644 --- a/mods/ITEMS/REDSTONE/mesecons_torch/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_torch/init.lua @@ -1,10 +1,10 @@ -- REDSTONE TORCH AND BLOCK OF REDSTONE -local S = minetest.get_translator("mesecons_torch") +local S = minetest.get_translator(minetest.get_current_modname()) local TORCH_COOLOFF = 120 -- Number of seconds it takes for a burned-out torch to reactivate -local rotate_torch_rules = function (rules, param2) +local function rotate_torch_rules(rules, param2) if param2 == 1 then return rules elseif param2 == 5 then @@ -20,7 +20,7 @@ local rotate_torch_rules = function (rules, param2) end end -local torch_get_output_rules = function(node) +local function torch_get_output_rules(node) if node.param2 == 1 then return { { x = -1, y = 0, z = 0 }, @@ -41,7 +41,7 @@ local torch_get_output_rules = function(node) end end -local torch_get_input_rules = function(node) +local function torch_get_input_rules(node) if node.param2 == 1 then return {{x = 0, y = -1, z = 0 }} else @@ -49,7 +49,7 @@ local torch_get_input_rules = function(node) end end -local torch_overheated = function(pos) +local function torch_overheated(pos) minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.02, max_hear_distance = 6}, true) minetest.add_particle({ pos = {x=pos.x, y=pos.y+0.2, z=pos.z}, @@ -62,7 +62,7 @@ local torch_overheated = function(pos) timer:start(TORCH_COOLOFF) end -local torch_action_on = function(pos, node) +local function torch_action_on(pos, node) local overheat if node.name == "mesecons_torch:mesecon_torch_on" then overheat = mesecon.do_overheat(pos) @@ -86,7 +86,7 @@ local torch_action_on = function(pos, node) end end -local torch_action_off = function(pos, node) +local function torch_action_off(pos, node) local overheat if node.name == "mesecons_torch:mesecon_torch_off" or node.name == "mesecons_torch:mesecon_torch_overheated" then overheat = mesecon.do_overheat(pos) @@ -111,89 +111,96 @@ local torch_action_off = function(pos, node) end minetest.register_craft({ - output = 'mesecons_torch:mesecon_torch_on', + output = "mesecons_torch:mesecon_torch_on", recipe = { {"mesecons:redstone"}, {"mcl_core:stick"},} }) -mcl_torches.register_torch("mesecon_torch_off", S("Redstone Torch (off)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - mesecons = { - receptor = { - state = mesecon.state.off, - rules = torch_get_output_rules, - }, - effector = { - state = mesecon.state.on, - rules = torch_get_input_rules, - action_off = torch_action_off, - }, +local off_def = { + name = "mesecon_torch_off", + description = S("Redstone Torch (off)"), + doc_items_create_entry = false, + icon = "jeija_torches_off.png", + tiles = {"jeija_torches_off.png"}, + light = 0, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + drop = "mesecons_torch:mesecon_torch_on", +} + +mcl_torches.register_torch(off_def) + +local off_override = { + mesecons = { + receptor = { + state = mesecon.state.off, + rules = torch_get_output_rules, + }, + effector = { + state = mesecon.state.on, + rules = torch_get_input_rules, + action_off = torch_action_off, }, - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, } -) +} -mcl_torches.register_torch("mesecon_torch_overheated", S("Redstone Torch (overheated)"), - nil, - nil, - "jeija_torches_off.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_off.png"}, - 0, - {dig_immediate=3, dig_by_water=1, redstone_torch=2, mesecon_ignore_opaque_dig=1, not_in_creative_inventory=1}, - mcl_sounds.node_sound_wood_defaults(), - { - drop = "mesecons_torch:mesecon_torch_on", - _doc_items_create_entry = false, - on_timer = function(pos, elapsed) - if not mesecon.is_powered(pos) then - local node = minetest.get_node(pos) - torch_action_off(pos, node) - end - end, - } -) +minetest.override_item("mesecons_torch:mesecon_torch_off", off_override) +minetest.override_item("mesecons_torch:mesecon_torch_off_wall", off_override) +local overheated_def = table.copy(off_def) +overheated_def.name = "mesecon_torch_overheated" +overheated_def.description = S("Redstone Torch (overheated)") +mcl_torches.register_torch(overheated_def) -mcl_torches.register_torch("mesecon_torch_on", S("Redstone Torch"), - S("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."), - S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), - "jeija_torches_on.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {"jeija_torches_on.png"}, - 7, - {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, - mcl_sounds.node_sound_wood_defaults(), - { - on_destruct = function(pos, oldnode) +local overheated_override = { + on_timer = function(pos, elapsed) + if not mesecon.is_powered(pos) then local node = minetest.get_node(pos) - torch_action_on(pos, node) - end, - mesecons = { - receptor = { - state = mesecon.state.on, - rules = torch_get_output_rules - }, - effector = { - state = mesecon.state.off, - rules = torch_get_input_rules, - action_on = torch_action_on, - }, + torch_action_off(pos, node) + end + end +} + +minetest.override_item("mesecons_torch:mesecon_torch_overheated", overheated_override) +minetest.override_item("mesecons_torch:mesecon_torch_overheated_wall", overheated_override) + +local on_def = { + name = "mesecon_torch_on", + description = S("Redstone Torch"), + doc_items_longdesc = S("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."), + doc_items_usagehelp = S("Redstone torches can be placed at the side and on the top of full solid opaque blocks."), + icon = "jeija_torches_on.png", + tiles = {"jeija_torches_on.png"}, + light = 7, + groups = {dig_immediate=3, dig_by_water=1, redstone_torch=1, mesecon_ignore_opaque_dig=1}, + sounds = mcl_sounds.node_sound_wood_defaults(), +} + +mcl_torches.register_torch(on_def) + +local on_override = { + on_destruct = function(pos, oldnode) + local node = minetest.get_node(pos) + torch_action_on(pos, node) + end, + mesecons = { + receptor = { + state = mesecon.state.on, + rules = torch_get_output_rules }, - _tt_help = S("Provides redstone power when it's not powered itself"), - } -) + effector = { + state = mesecon.state.off, + rules = torch_get_input_rules, + action_on = torch_action_on, + }, + }, + _tt_help = S("Provides redstone power when it's not powered itself"), +} + +minetest.override_item("mesecons_torch:mesecon_torch_on", on_override) +minetest.override_item("mesecons_torch:mesecon_torch_on_wall", on_override) minetest.register_node("mesecons_torch:redstoneblock", { description = S("Block of Redstone"), @@ -215,16 +222,16 @@ minetest.register_node("mesecons_torch:redstoneblock", { minetest.register_craft({ output = "mesecons_torch:redstoneblock", recipe = { - {'mesecons:wire_00000000_off','mesecons:wire_00000000_off','mesecons:wire_00000000_off'}, - {'mesecons:wire_00000000_off','mesecons:wire_00000000_off','mesecons:wire_00000000_off'}, - {'mesecons:wire_00000000_off','mesecons:wire_00000000_off','mesecons:wire_00000000_off'}, + {"mesecons:wire_00000000_off","mesecons:wire_00000000_off","mesecons:wire_00000000_off"}, + {"mesecons:wire_00000000_off","mesecons:wire_00000000_off","mesecons:wire_00000000_off"}, + {"mesecons:wire_00000000_off","mesecons:wire_00000000_off","mesecons:wire_00000000_off"}, } }) minetest.register_craft({ - output = 'mesecons:wire_00000000_off 9', + output = "mesecons:wire_00000000_off 9", recipe = { - {'mesecons_torch:redstoneblock'}, + {"mesecons_torch:redstoneblock"}, } }) diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr new file mode 100644 index 000000000..05bfa2574 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.ja.tr @@ -0,0 +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.=レッドストーントーチは、全固体の不透明ブロックの側面と上部に配置できます。 +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=レッドストーン動力を提供 diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.pl.tr b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.pl.tr new file mode 100644 index 000000000..a791da3a7 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_torch/locale/mesecons_torch.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mesecons_torch +Redstone Torch=Pochodnia czerwienitowa +Redstone Torch (off)=Pochodnia czerwienitowa (wyłączona) +Redstone Torch (overheated)=Pochodnia czerwienitowa (przegrzana) +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.=Pochodnia czerwienitowa to mechanizm czerwienitowy, który można wykorzystać do odwrócenia czerwienitowego sygnału. Dostarcza otaczającym jej blokom energię czerwienitową, z wyjątkiem bloku do którego jest przyczepiona. Pochodnia czerwienitowa normalnie jest zapalona, jednak może zostać wyłączona przez zasilenie bloku do którego jest przyczepiona. Gdy jest wyłączona nie zasila ona niczego. +Redstone torches can be placed at the side and on the top of full solid opaque blocks.=Pochodnia czerwienitowa może być postawiona na boku i wierzchu pełnych, stałych, nieprzezroczystych bloków. +Block of Redstone=Blok czerwienitu +A block of redstone permanently supplies redstone power to its surrounding blocks.=Blok czerwienitu nieustannie dostarcza energię czerwienitową do otaczających go bloków. +Provides redstone power when it's not powered itself=Dostarcza energię czerwienitową gdy nie jest zasilona +Provides redstone power=Dostarcza energię czerwienitową diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf b/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf new file mode 100644 index 000000000..85586cad7 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_torch/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_torch +depends = mesecons, mcl_torches +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png deleted file mode 100644 index cecdaf8fa..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_off.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png b/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png deleted file mode 100644 index 24d0a94d9..000000000 Binary files a/mods/ITEMS/REDSTONE/mesecons_torch/textures/jeija_torches_on.png and /dev/null differ diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt b/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua b/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua index f73ee0387..c251587d5 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/init.lua @@ -1,8 +1,8 @@ -local S = minetest.get_translator("mesecons_wallever") +local S = minetest.get_translator(minetest.get_current_modname()) local lever_get_output_rules = mesecon.rules.buttonlike_get -local on_rotate = function(pos, node, user, mode) +local function on_rotate(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then if node.param2 == 10 then node.param2 = 13 @@ -32,11 +32,11 @@ minetest.register_node("mesecons_walllever:wall_lever_off", { tiles = { "jeija_wall_lever_lever_light_on.png", }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, inventory_image = "jeija_wall_lever.png", wield_image = "jeija_wall_lever.png", paramtype = "light", paramtype2 = "facedir", - drawtype = "mesh", mesh = "jeija_wall_lever_off.obj", sunlight_propagates = true, walkable = false, @@ -50,7 +50,7 @@ minetest.register_node("mesecons_walllever:wall_lever_off", { _tt_help = S("Provides redstone power while it's turned on"), _doc_items_longdesc = S("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."), _doc_items_usagehelp = S("Use the lever to flip it on or off."), - on_rightclick = function (pos, node) + on_rightclick = function(pos, node) minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_on", param2=node.param2}) mesecon.receptor_on(pos, lever_get_output_rules(node)) minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16}, true) @@ -136,6 +136,7 @@ minetest.register_node("mesecons_walllever:wall_lever_on", { tiles = { "jeija_wall_lever_lever_light_on.png", }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", mesh = "jeija_wall_lever_on.obj", @@ -147,9 +148,9 @@ minetest.register_node("mesecons_walllever:wall_lever_on", { }, groups = {handy=1, not_in_creative_inventory = 1, dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, attached_node_facedir=1}, is_ground_content = false, - drop = '"mesecons_walllever:wall_lever_off" 1', + drop = "mesecons_walllever:wall_lever_off", _doc_items_create_entry = false, - on_rightclick = function (pos, node) + on_rightclick = function(pos, node) minetest.swap_node(pos, {name="mesecons_walllever:wall_lever_off", param2=node.param2}) mesecon.receptor_off(pos, lever_get_output_rules(node)) minetest.sound_play("mesecons_button_push", {pos=pos, max_hear_distance=16, pitch=0.9}, true) @@ -165,10 +166,10 @@ minetest.register_node("mesecons_walllever:wall_lever_on", { }) minetest.register_craft({ - output = 'mesecons_walllever:wall_lever_off', + output = "mesecons_walllever:wall_lever_off", recipe = { - {'mcl_core:stick'}, - {'mcl_core:cobble'}, + {"mcl_core:stick"}, + {"mcl_core:cobble"}, } }) diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr index 27a3bb55f..880219396 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.de.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Hebel 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.=Ein Hebel ist eine Redstonekomponente, die ein- und ausgeschaltet werden kann. Er versorgt seine benachbarten Blöcke mit Redstoneenergie, solange er sich im eingeschalteten Zustand befindet. Use the lever to flip it on or off.=Benutzen Sie den Hebel, um ihn ein- oder auszuschalten. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr index e0e55298e..9b83bf6db 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.es.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Palanca 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.=EUna palanca es un componente de redstone que se puede activar y desactivar. Suministra energía redstone a bloques adyacentes mientras está en el estado "encendido". Use the lever to flip it on or off.=Use la palanca para encenderlo o apagarlo. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr index 3d5d23c81..c3dc63aa9 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.fr.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# textdomain: mesecons_walllever Lever=Levier 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.=Un levier est un composant de redstone qui peut être activé et désactivé. Il fournit de l'énergie redstone aux blocs adjacents pendant qu'il est à l'état "activé". Use the lever to flip it on or off.=Utilisez le levier pour l'activer ou le désactiver. diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr new file mode 100644 index 000000000..d751d9d15 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ja.tr @@ -0,0 +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.=レバーでON/OFFを切り替えます。 +Provides redstone power while it's turned on=電源オン時にレッドストーン動力を提供 diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr new file mode 100644 index 000000000..9bfed99db --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mesecons_walllever +Lever=Dźwignia +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.=Dźwignia jest czerwienitowym elementem, który można przełączać między stanem włączonym i wyłączonym. Wysyła ona czerwienitową energię gdy jest w stanie włączonym. +Use the lever to flip it on or off.=Użyj dźwigni by przełączyć ją między stanami. +Provides redstone power while it's turned on=Dostarcza energii czerwienitowej gdy jest włączona 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 6ed05b387..00a3e84f1 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/mesecons_walllever.ru.tr @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# 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.=[Используйте] рычаг, чтобы перещёлкнуть его во включённое или выключенное положение . diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt index 0187e6d28..198ad9f9a 100644 --- a/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/locale/template.txt @@ -1,4 +1,4 @@ -# textdomain: mesecons_wallever +# 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.= diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf b/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf new file mode 100644 index 000000000..8512e9d6b --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_walllever/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_walllever +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt b/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt deleted file mode 100644 index 4fdbda79f..000000000 --- a/mods/ITEMS/REDSTONE/mesecons_wires/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mesecons -doc? diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/init.lua b/mods/ITEMS/REDSTONE/mesecons_wires/init.lua index 75acd3ce0..0f2febc44 100644 --- a/mods/ITEMS/REDSTONE/mesecons_wires/init.lua +++ b/mods/ITEMS/REDSTONE/mesecons_wires/init.lua @@ -4,7 +4,7 @@ -- Where 0 means the wire has no visual connection to that direction and -- 1 means that the wire visually connects to that other node. -local S = minetest.get_translator("mesecons_wires") +local S = minetest.get_translator(minetest.get_current_modname()) -- ####################### -- ## Update wire looks ## @@ -28,12 +28,12 @@ local wire_rules = {x= 0, y=-1, z=-1}} -- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for -local wire_getconnect = function (from_pos, self_pos) +local function wire_getconnect(from_pos, self_pos) local node = minetest.get_node(self_pos) if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].mesecons then -- rules of node to possibly connect to - local rules = {} + local rules if (minetest.registered_nodes[node.name].mesecon_wire) then rules = wire_rules else @@ -50,7 +50,7 @@ local wire_getconnect = function (from_pos, self_pos) end -- Update this node -local wire_updateconnect = function (pos) +local function wire_updateconnect(pos) local connections = {} for _, r in ipairs(wire_rules) do @@ -83,7 +83,7 @@ local wire_updateconnect = function (pos) minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix}) end -local update_on_place_dig = function (pos, node) +local function update_on_place_dig(pos, node) -- Update placed node (get_node again as it may have been dug) local nn = minetest.get_node(pos) if (minetest.registered_nodes[nn.name]) @@ -139,8 +139,8 @@ local selectionbox = } -- go to the next nodeid (ex.: 01000011 --> 01000100) -local nid_inc = function() end -nid_inc = function (nid) +local function nid_inc() end +function nid_inc(nid) local i = 0 while nid[i-1] ~= 1 do nid[i] = (nid[i] ~= 1) and 1 or 0 @@ -214,8 +214,7 @@ local function register_wires() local dot_off = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_off local dot_on = "redstone_redstone_dust_dot.png^[colorize:#FF0000:"..ratio_on - local tiles_off = { crossing_off, crossing_off, straight0_off, straight1_off, straight0_off, straight1_off } - local tiles_on = { crossing_on, crossing_on, straight0_on, straight1_on, straight0_on, straight1_on } + local tiles_off, tiles_on local wirehelp, tt, longdesc, usagehelp, img, desc_off, desc_on if nodeid == "00000000" then @@ -238,8 +237,8 @@ S("Read the help entries on the other redstone components to learn how redstone else -- Connected redstone wire table.insert(nodebox, box_center) - tiles_off = { crossing_off, crossing_off, straight0_off, straight1_off, straight0_off, straight1_off, } - tiles_on = { crossing_on, crossing_on, straight0_on, straight1_on, straight0_on, straight1_on, } + tiles_off = { crossing_off, crossing_off, straight0_off, straight1_off, straight0_off, straight1_off } + tiles_on = { crossing_on, crossing_on, straight0_on, straight1_on, straight0_on, straight1_on } wirehelp = false desc_off = S("Redstone Trail (@1)", nodeid) desc_on = S("Powered Redstone Trail (@1)", nodeid) @@ -248,6 +247,7 @@ S("Read the help entries on the other redstone components to learn how redstone mesecon.register_node(":mesecons:wire_"..nodeid, { drawtype = "nodebox", paramtype = "light", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, sunlight_propagates = true, selection_box = selectionbox, node_box = nodebox, diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr new file mode 100644 index 000000000..33da44f9c --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.ja.tr @@ -0,0 +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.=レッドストーン導線は、稼動と非稼動の2つの状態がとれます。稼動中のレッドストーン導線は、隣接するレッドストーン部品に動力を与えます(つまり作動します)。 +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) +Redstone Trail (@1)=レッドストーン導線 (@1) +Powered Redstone Trail (@1)=稼動中のレッドストーン導線 (@1) +Transmits redstone power, powers mechanisms=レッドストーン動力の伝達、メカニズム類の起動 diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.pl.tr b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.pl.tr new file mode 100644 index 000000000..bdc717649 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_wires/locale/mesecons_wires.pl.tr @@ -0,0 +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.=Czerwienit jest wszechstronnym przewodzącym minerałem, który przewodzi energię czerwienitową. Może być położony na ziemi tworząc ścieżkę. +A redstone trail can be in two states: Powered or not powered. A powered redstone trail will power (and thus activate) adjacent redstone components.=Ścieżka czerwienitu może być w dwóch stanach: Zasilonym lub Nie zasilonym. Zasilona ścieżka będzie zasilać (a więc również aktywować) sąsiadujące mechanizmy czerwienitowe. +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.=Energia czerwienitowa może być uzyskana z różnych mechanizmów czerwienitowych, takich jak blok czerwienitu czy przycisk. Energia czerwienitowa może być wykorzystywana do aktywowania różnych mechanizmów takich jak czerwienitowe lampy lub tłoki. +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.=Połóż czerwienit na ziemi aby stworzyć ścieżkę czerwienitu. Ścieżki połączą się ze sobą automatycznie, nawet jeśli istnieje różnica wysokości. Łatwym sposobem na zasilenie ścieżki czerwienitu jest postawienie czerwienitowej pochodni. +Read the help entries on the other redstone components to learn how redstone components interact.=Przeczytaj wpisy na temat innych czerwienitowych mechanizmów, by dowiedzieć się jak wchodzą ze sobą w interakcję. +Redstone=Czerwienit +Powered Redstone Spot (@1)=Zasilony punkt czerwienitu (@1) +Redstone Trail (@1)=Ścieżka czerwienitu (@1) +Powered Redstone Trail (@1)=Zasilona ścieżka czerwienitu (@1) +Transmits redstone power, powers mechanisms=Przekazuje energię czerwienitową, zasila mechanizmy diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf b/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf new file mode 100644 index 000000000..15f2e0d32 --- /dev/null +++ b/mods/ITEMS/REDSTONE/mesecons_wires/mod.conf @@ -0,0 +1,3 @@ +name = mesecons_wires +depends = mesecons +optional_depends = doc diff --git a/mods/ITEMS/mcl_amethyst/grow.lua b/mods/ITEMS/mcl_amethyst/grow.lua new file mode 100644 index 000000000..9617c586d --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/grow.lua @@ -0,0 +1,54 @@ +local interval = 10 +local chance = 5 + +local function grow(pos, node) + local def = minetest.registered_nodes[node.name] + local next_gen = def._mcl_amethyst_next_grade + if not next_gen then return end + + local dir = minetest.wallmounted_to_dir(node.param2) + local ba_pos = vector.add(pos, dir) + local ba_node = minetest.get_node(ba_pos) + if ba_node.name ~= "mcl_amethyst:budding_amethyst_block" then return end + + local swap_result = table.copy(node) + swap_result.name = next_gen + minetest.swap_node(pos, swap_result) +end + +minetest.register_abm({ + label = "Amethyst Bud Growth", + nodenames = {"group:amethyst_buds"}, + neighbors = {"mcl_amethyst:budding_amethyst_block"}, + interval = interval, + chance = chance, + action = grow, +}) + +local all_directions = { + vector.new(1, 0, 0), + vector.new(0, 1, 0), + vector.new(0, 0, 1), + vector.new(-1, 0, 0), + vector.new(0, -1, 0), + vector.new(0, 0, -1), +} + +minetest.register_abm({ + label = "Spawn Amethyst Bud", + nodenames = { "mcl_amethyst:budding_amethyst_block" }, + neighbors = { "air", "group:water" }, + interval = 34.135, -- 34.135 is 1/2 of 68.27, which is the average time for one bud to grow 1 stage. + chance = 2, + action = function(pos) + local check_pos = vector.add(all_directions[math.random(1, #all_directions)], pos) + local check_node = minetest.get_node(check_pos) + local check_node_name = check_node.name + if check_node_name ~= "air" and minetest.get_item_group(check_node_name, "water") == 0 then + return + end + local param2 = minetest.dir_to_wallmounted(vector.subtract(pos, check_pos)) + local new_node = { name = "mcl_amethyst:small_amethyst_bud", param2 = param2 } + minetest.swap_node(check_pos, new_node) + end, +}) diff --git a/mods/ITEMS/mcl_amethyst/init.lua b/mods/ITEMS/mcl_amethyst/init.lua new file mode 100644 index 000000000..e43223a41 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/init.lua @@ -0,0 +1,218 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local sounds = mcl_sounds.node_sound_glass_defaults({ + footstep = {name = "mcl_amethyst_amethyst_walk", gain = 0.4}, + dug = {name = "mcl_amethyst_amethyst_break", gain = 0.44}, +}) + +-- Amethyst block +minetest.register_node("mcl_amethyst:amethyst_block",{ + description = S("Block of Amethyst"), + _doc_items_longdesc = S("The Block of Amethyst is a decoration block crafted from amethyst shards."), + tiles = {"mcl_amethyst_amethyst_block.png"}, + groups = {pickaxey = 1, building_block = 1}, + sounds = sounds, + is_ground_content = true, + _mcl_hardness = 1.5, + _mcl_blast_resistance = 1.5, +}) + +minetest.register_node("mcl_amethyst:budding_amethyst_block",{ + description = S("Budding Amethyst"), + _doc_items_longdesc = S("The Budding Amethyst can grow amethyst"), + tiles = {"mcl_amethyst_budding_amethyst.png"}, + drop = "", + groups = { + pickaxey = 1, + building_block = 1, + dig_by_piston = 1, + }, + sounds = sounds, + is_ground_content = true, + _mcl_hardness = 1.5, + _mcl_blast_resistance = 1.5, +}) + +mcl_wip.register_wip_item("mcl_amethyst:budding_amethyst_block") + +-- Amethyst Shard +minetest.register_craftitem("mcl_amethyst:amethyst_shard",{ + description = S("Amethyst Shard"), + _doc_items_longdesc = S("An amethyst shard is a crystalline mineral."), + inventory_image = "mcl_amethyst_amethyst_shard.png", + groups = {craftitem = 1}, +}) + +-- Calcite +minetest.register_node("mcl_amethyst:calcite",{ + description = S("Calcite"), + _doc_items_longdesc = S("Calcite can be found as part of amethyst geodes."), + tiles = {"mcl_amethyst_calcite_block.png"}, + groups = {pickaxey = 1, building_block = 1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = true, + _mcl_hardness = 0.75, + _mcl_blast_resistance = 0.75, +}) + +-- Tinied Glass +minetest.register_node("mcl_amethyst:tinted_glass",{ + description = S("Tinted Glass"), + _doc_items_longdesc = S("Tinted Glass is a type of glass which blocks lights while it is visually transparent."), + tiles = {"mcl_amethyst_tinted_glass.png"}, + _mcl_hardness = 0.3, + _mcl_blast_resistance = 0.3, + drawtype = "glasslike", + use_texture_alpha = "blend", + sunlight_propagates = false, + groups = {handy = 1, building_block = 1, deco_block = 1}, + sounds = mcl_sounds.node_sound_glass_defaults(), + is_ground_content = false, +}) + +-- Amethyst Cluster +local bud_def = { + { + size = "small", + description = S("Small Amethyst Bud"), + long_desc = S("Small Amethyst Bud is the first growth of amethyst bud."), + light_source = 3, + next_stage = "mcl_amethyst:medium_amethyst_bud", + selection_box = { -4/16, -7/16, -4/16, 4/16, -3/16, 4/16 }, + }, + { + size = "medium", + description = S("Medium Amethyst Bud"), + long_desc = S("Medium Amethyst Bud is the second growth of amethyst bud."), + light_source = 4, + next_stage = "mcl_amethyst:large_amethyst_bud", + selection_box = { -4.5/16, -8/16, -4.5/16, 4.5/16, -2/16, 4.5/16 }, + }, + { + size = "large", + description = S("Large Amethyst Bud"), + long_desc = S("Large Amethyst Bud is the third growth of amethyst bud."), + light_source = 5, + next_stage = "mcl_amethyst:amethyst_cluster", + selection_box = { -4.5/16, -8/16, -4.5/16, 4.5/16, -1/16, 4.5/16 }, + }, +} + +for _, def in pairs(bud_def) do + local size = def.size + local name = "mcl_amethyst:" .. size .. "_amethyst_bud" + local tile = "mcl_amethyst_amethyst_bud_" .. size .. ".png" + local inventory_image = "mcl_amethyst_amethyst_bud_" .. size .. ".png" + minetest.register_node(name, { + description = def.description, + _doc_items_longdesc = def.longdesc, + drop = "", + tiles = {tile}, + inventory_image = inventory_image, + paramtype1 = "light", + paramtype2 = "wallmounted", + drawtype = "plantlike", + use_texture_alpha = "clip", + sunlight_propagates = true, + walkable = false, + light_source = def.light_source, + groups = { + destroy_by_lava_flow = 1, + dig_by_piston = 1, + pickaxey = 1, + deco_block = 1, + amethyst_buds = 1, + attached_node = 1, + }, + sounds = sounds, + selection_box = { + type = "fixed", + fixed = def.selection_box + }, + _mcl_hardness = 1.5, + _mcl_blast_resistance = 1.5, + _mcl_silk_touch_drop = true, + _mcl_amethyst_next_grade = def.next_stage, + }) +end + +minetest.register_node("mcl_amethyst:amethyst_cluster",{ + description = S("Amethyst Cluster"), + _doc_items_longdesc = S("Amethyst Cluster is the final growth of amethyst bud."), + drop = { + max_items = 1, + items = { + { + tools = {"~mcl_tools:pick_"}, + items = {"mcl_amethyst:amethyst_shard 4"}, + }, + { + items = {"mcl_amethyst:amethyst_shard 2"}, + }, + } + }, + tiles = {"mcl_amethyst_amethyst_cluster.png",}, + inventory_image = "mcl_amethyst_amethyst_cluster.png", + paramtype2 = "wallmounted", + drawtype = "plantlike", + paramtype1 = "light", + use_texture_alpha = "clip", + sunlight_propagates = true, + walkable = false, + light_source = 7, + groups = { + destroy_by_lava_flow = 1, + dig_by_piston = 1, + pickaxey = 1, + deco_block = 1, + attached_node = 1, + }, + sounds = sounds, + selection_box = { + type = "fixed", + fixed = { -4.8/16, -8/16, -4.8/16, 4.8/16, 3.9/16, 4.8/16 }, + }, + _mcl_hardness = 1.5, + _mcl_blast_resistance = 1.5, + _mcl_silk_touch_drop = true, +}) + +-- Register Crafts +minetest.register_craft({ + output = "mcl_amethyst:amethyst_block", + recipe = { + {"mcl_amethyst:amethyst_shard", "mcl_amethyst:amethyst_shard"}, + {"mcl_amethyst:amethyst_shard", "mcl_amethyst:amethyst_shard"}, + }, +}) + +minetest.register_craft({ + output = "mcl_amethyst:tinted_glass 2", + recipe = { + {"", "mcl_amethyst:amethyst_shard", ""}, + {"mcl_amethyst:amethyst_shard", "mcl_core:glass", "mcl_amethyst:amethyst_shard",}, + {"", "mcl_amethyst:amethyst_shard", ""}, + }, +}) + +if minetest.get_modpath("mcl_spyglass") then + minetest.clear_craft({output = "mcl_spyglass:spyglass",}) + local function craft_spyglass(ingot) + minetest.register_craft({ + output = "mcl_spyglass:spyglass", + recipe = { + {"mcl_amethyst:amethyst_shard"}, + {ingot}, + {ingot}, + } + }) + end + if minetest.get_modpath("mcl_copper") then + craft_spyglass("mcl_copper:copper_ingot") + else + craft_spyglass("mcl_core:iron_ingot") + end +end + +-- Amethyst Growing +dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/grow.lua") diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.dk.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.dk.tr new file mode 100644 index 000000000..2a7d6307c --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.dk.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=Ametystklynge +Amethyst Cluster is the final growth of amethyst bud.=En ameystklynge er den sidste udvikling af en ametystspire. +Amethyst Shard=Ametystskår +An amethyst shard is a crystalline mineral.=Et ametystskår er et krystallisk mineral. +Block of Amethyst=Blok af ametyst +Budding Amethyst=Spirende ametyst +Calcite=Calcedon +Calcite can be found as part of amethyst geodes.=Calcedon kan findes som en del af krystalhuler med ametyst. +Large Amethyst Bud=Stor ametystknop +Large Amethyst Bud is the third growth of amethyst bud.=En stor ametystknop er den trejde udvikling af en ametystspire. +Medium Amethyst Bud=Mellem ametystknop +Medium Amethyst Bud is the second growth of amethyst bud.=En mellem ametystknop er den anden udvikling af en ametystspire. +Small Amethyst Bud=Lille ametystknop +Small Amethyst Bud is the first growth of amethyst bud.=En lille ametystknop er den første udvikling af en ametystspire. +The Block of Amethyst is a decoration block crafted from amethyst shards.=En blok af ametyst er en udsmykningsblok som kan laves ametystskår. +The Budding Amethyst can grow amethyst=Den spirende ametyst kan gro ametyst +Tinted Glass=Farvet glas +Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Farvet glas er en glastype som er gennemsigtig, men lukker lys ude. diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.fr.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.fr.tr new file mode 100644 index 000000000..bd0c83f85 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.fr.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=Agrégat d'améthyste +Amethyst Cluster is the final growth of amethyst bud.=L'agrégat d'améthyste est le stade final de la croissance du bourgeon d'améthyste. +Amethyst Shard=Éclat d'améthyste +An amethyst shard is a crystalline mineral.=Un éclat d'améthyste est un minéral cristallin. +Block of Amethyst=Bloc d'améthyste +Budding Amethyst=Améthyste bourgeonnante +Calcite=Calcite +Calcite can be found as part of amethyst geodes.=La calcite peut être trouvée dans les géodes d'améthyste. +Large Amethyst Bud=Grand bourgeon d'améthyste +Large Amethyst Bud is the third growth of amethyst bud.=Le grand bourgeon d'améthyste est le troisième stade de la croissance du bourgeon d'améthyste. +Medium Amethyst Bud=Bourgeon d'améthyste moyen +Medium Amethyst Bud is the second growth of amethyst bud.=Le bourgeon d'améthyste moyen est le deuxième stade de la croissance du bourgeon d'améthyste. +Small Amethyst Bud=Petit bourgeon d'améthyste +Small Amethyst Bud is the first growth of amethyst bud.=Le petit bourgeon d'améthyste est le premier stade de la croissance du bourgeon d'améthyste. +The Block of Amethyst is a decoration block crafted from amethyst shards.=Le bloc d'améthyste est un bloc décoratif fabriqué à partir d'éclats d'améthyste. +The Budding Amethyst can grow amethyst=L'améthyste bourgeonnante peut faire croître de l'améthyste. +Tinted Glass=Verre teinté +Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Le verre teinté est un type de verre qui bloque la lumière tout en étant visuellement transparent. diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr new file mode 100644 index 000000000..4535580e9 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ja.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=アメジストの集塊 +Amethyst Cluster is the final growth of amethyst bud.=アメジストの集塊は、アメジストの芽の成長最終段階です。 +Amethyst Shard=アメジストの欠片 +An amethyst shard is a crystalline mineral.=アメジストの欠片は、結晶性の鉱物です。 +Block of Amethyst=アメジストブロック +Budding Amethyst=芽生えたアメジスト +Calcite=方解石 +Calcite can be found as part of amethyst geodes.=方解石は、アメジストジオードの一部として見つけることができます。 +Large Amethyst Bud=大きなアメジストの芽 +Large Amethyst Bud is the third growth of amethyst bud.=大きなアメジストの芽は、アメジストの芽の成長三段階目です。 +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 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_amethyst/locale/mcl_amethyst.pt_BR.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.pt_BR.tr new file mode 100644 index 000000000..c5c440495 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.pt_BR.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=Aglomerado de Ametista +Amethyst Cluster is the final growth of amethyst bud.=O aglomerado de ametista é o final do crescimento do broto de ametista. +Amethyst Shard=Fragmento de Ametista +An amethyst shard is a crystalline mineral.=Um fragmento de ametista é um mineral cristalino. +Block of Amethyst=Bloco de Ametista +Budding Amethyst=Ametista Brotando +Calcite=Calcita +Calcite can be found as part of amethyst geodes.=Calcita pode ser encontrada como parte dos geodos de ametista. +Large Amethyst Bud=Broto de Ametista Grande +Large Amethyst Bud is the third growth of amethyst bud.=Broto de Ametista Grande é a terceira etapa de crescimento do broto de ametista. +Medium Amethyst Bud=Broto de Ametista Médio +Medium Amethyst Bud is the second growth of amethyst bud.=Broto de Ametista Médio é a segunda etapa de crescimento do broto de ametista. +Small Amethyst Bud=Broto de Ametista Pequeno +Small Amethyst Bud is the first growth of amethyst bud.=Broto de Ametista Pequeno é a primeira etapa de crescimento do broto de ametista. +The Block of Amethyst is a decoration block crafted from amethyst shards.=O bloco de ametista é um bloco decorativo feito a partir de fragmentos de ametista. +The Budding Amethyst can grow amethyst=A ametista brotando pode crescer ametista. +Tinted Glass=Vidro Tingido +Tinted Glass is a type of glass which blocks lights while it is visually transparent.=Vidro tingido é um tipo de vidro que bloqueia luzes enquanto é visualmente transparente. diff --git a/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr new file mode 100644 index 000000000..9f1d0f572 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/mcl_amethyst.ru.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster=Аметистовая друза +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=Кальцит +Calcite can be found as part of amethyst geodes.=Кальцит можно найти в составе аметистовых жеод. +Large Amethyst Bud=Большой росток аметиста +Large Amethyst Bud is the third growth of amethyst bud.=Большой росток - третья стадия роста аметиста. +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 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_amethyst/locale/template.txt b/mods/ITEMS/mcl_amethyst/locale/template.txt new file mode 100644 index 000000000..7f23e9965 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/locale/template.txt @@ -0,0 +1,19 @@ +# textdomain: mcl_amethyst +Amethyst Cluster= +Amethyst Cluster is the final growth of amethyst bud.= +Amethyst Shard= +An amethyst shard is a crystalline mineral.= +Block of Amethyst= +Budding Amethyst= +Calcite= +Calcite can be found as part of amethyst geodes.= +Large Amethyst Bud= +Large Amethyst Bud is the third growth of amethyst bud.= +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 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_amethyst/mod.conf b/mods/ITEMS/mcl_amethyst/mod.conf new file mode 100644 index 000000000..97ed6ae99 --- /dev/null +++ b/mods/ITEMS/mcl_amethyst/mod.conf @@ -0,0 +1,5 @@ +name = mcl_amethyst +author = Emojiminetest, kay27 +description = Amethyst related stuff +depends = mcl_init, mcl_core, mcl_wip +optional_depends = mcl_spyglass, mcl_copper diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.1.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.1.ogg new file mode 100644 index 000000000..a2208012c Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.1.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.2.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.2.ogg new file mode 100644 index 000000000..a3903550c Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.2.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.3.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.3.ogg new file mode 100644 index 000000000..9cc81e20f Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_break.3.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.1.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.1.ogg new file mode 100644 index 000000000..8165edd5f Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.1.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.2.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.2.ogg new file mode 100644 index 000000000..5bb5c4657 Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.2.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.3.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.3.ogg new file mode 100644 index 000000000..781668514 Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.3.ogg differ diff --git a/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.4.ogg b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.4.ogg new file mode 100644 index 000000000..14299f50c Binary files /dev/null and b/mods/ITEMS/mcl_amethyst/sounds/mcl_amethyst_amethyst_walk.4.ogg differ diff --git a/mods/ITEMS/mcl_anvils/depends.txt b/mods/ITEMS/mcl_anvils/depends.txt deleted file mode 100644 index 89b87aa2d..000000000 --- a/mods/ITEMS/mcl_anvils/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_formspec -mcl_sounds -mcl_core? -screwdriver? -tt -mcl_enchanting diff --git a/mods/ITEMS/mcl_anvils/init.lua b/mods/ITEMS/mcl_anvils/init.lua index bf912c7a0..a56299cd9 100644 --- a/mods/ITEMS/mcl_anvils/init.lua +++ b/mods/ITEMS/mcl_anvils/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_anvils") +local S = minetest.get_translator(minetest.get_current_modname()) local MAX_NAME_LENGTH = 35 local MAX_WEAR = 65535 @@ -9,7 +9,6 @@ local MATERIAL_TOOL_REPAIR_BOOST = { math.ceil(MAX_WEAR * 0.75), -- 75% MAX_WEAR, -- 100% } -local NAME_COLOR = "#FFFF4C" local function get_anvil_formspec(set_name) if not set_name then @@ -42,7 +41,7 @@ end -- needs to be used up to repair the tool. local function get_consumed_materials(tool, material) local wear = tool:get_wear() - local health = (MAX_WEAR - wear) + --local health = (MAX_WEAR - wear) local matsize = material:get_count() local materials_used = 0 for m=1, math.min(4, matsize) do @@ -54,6 +53,15 @@ 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. @@ -61,24 +69,42 @@ end local function distinguish_tool_and_material(input1, input2) local def1 = input1:get_definition() local def2 = input2:get_definition() - if def1.type == "tool" and def1._repair_material then + 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 return "tool", input1, input2 - elseif def2.type == "tool" and def2._repair_material then + elseif def2.type == "tool" and r2 and type(r2) == "table" and contains(r2, input1) then + return "material", input2, input1 + elseif def1.type == "tool" and r1 then + return "tool", input1, input2 + elseif def2.type == "tool" and r2 then return "material", input2, input1 else return nil end end +-- Helper function to make sure update_anvil_slots NEVER overstacks the output slot +local function fix_stack_size(stack) + if not stack or stack == "" then return "" end + local count = stack:get_count() + local max_count = stack:get_stack_max() + + if count > max_count then + stack:set_count(max_count) + count = max_count + end + return count +end + -- Update the inventory slots of an anvil node. -- meta: Metadata of anvil node local function update_anvil_slots(meta) local inv = meta:get_inventory() local new_name = meta:get_string("set_name") - local input1, input2, output - input1 = inv:get_stack("input", 1) - input2 = inv:get_stack("input", 2) - output = inv:get_stack("output", 1) + local input1 = inv:get_stack("input", 1) + local input2 = inv:get_stack("input", 2) + --local output = inv:get_stack("output", 1) local new_output, name_item local just_rename = false @@ -101,14 +127,14 @@ local function update_anvil_slots(meta) end local can_combine = mcl_enchanting.combine(input1, input2) - + if can_combine then -- Add tool health together plus a small bonus if def1.type == "tool" and def2.type == "tool" then local new_wear = calculate_repair(input1:get_wear(), input2:get_wear(), SAME_TOOL_REPAIR_BOOST) input1:set_wear(new_wear) end - + name_item = input1 new_output = name_item -- Tool + repair item @@ -123,11 +149,28 @@ local function update_anvil_slots(meta) local distinguished, tool, material = distinguish_tool_and_material(input1, input2) if distinguished then local tooldef = tool:get_definition() + local repair = tooldef._repair_material local has_correct_material = false - if string.sub(tooldef._repair_material, 1, 6) == "group:" then - has_correct_material = minetest.get_item_group(material:get_name(), string.sub(tooldef._repair_material, 7)) ~= 0 - elseif material:get_name() == tooldef._repair_material then - has_correct_material = true + local material_name = material:get_name() + if type(repair) == "string" then + if string.sub(repair, 1, 6) == "group:" then + has_correct_material = minetest.get_item_group(material_name, string.sub(repair, 7)) ~= 0 + elseif material_name == repair then + has_correct_material = true + end + else + if contains(repair, material_name) then + has_correct_material = true + else + for _, r in pairs(repair) do + if string.sub(r, 1, 6) == "group:" then + if minetest.get_item_group(material_name, string.sub(r, 7)) ~= 0 then + has_correct_material = true + end + + end + end + end end if has_correct_material and tool:get_wear() > 0 then local materials_used = get_consumed_materials(tool, material) @@ -172,14 +215,8 @@ local function update_anvil_slots(meta) if new_name ~= old_name then -- Save the raw name internally meta:set_string("name", new_name) - -- Rename item - if new_name == "" then - tt.reload_itemstack_description(name_item) - else - -- Custom name set. Colorize it! - -- This makes the name visually different from unnamed items - meta:set_string("description", minetest.colorize(NAME_COLOR, new_name)) - end + -- Rename item handled by tt + tt.reload_itemstack_description(name_item) new_output = name_item elseif just_rename then new_output = "" @@ -188,7 +225,8 @@ local function update_anvil_slots(meta) end -- Set the new output slot - if new_output ~= nil then + if new_output then + fix_stack_size(new_output) inv:set_stack("output", 1, new_output) end end @@ -250,7 +288,6 @@ end -- Returns true if anvil was destroyed. local function damage_anvil(pos) local node = minetest.get_node(pos) - local new if node.name == "mcl_anvils:anvil" then minetest.swap_node(pos, {name="mcl_anvils:anvil_damage_1", param2=node.param2}) damage_particles(pos, node) @@ -285,7 +322,6 @@ local function damage_anvil_by_using(pos) end local function damage_anvil_by_falling(pos, distance) - local chance local r = math.random(1, 100) if distance > 1 then if r <= (5*distance) then @@ -294,9 +330,16 @@ local function damage_anvil_by_falling(pos, distance) end end +local anvilbox = { + type = "fixed", + fixed = { + { -8 / 16, -8 / 16, -6 / 16, 8 / 16, 8 / 16, 6 / 16 }, + }, +} 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, _tt_help = S("Repair and rename items"), paramtype = "light", sunlight_propagates = true, @@ -306,22 +349,25 @@ local anvildef = { node_box = { type = "fixed", fixed = { - {-8/16, 2/16, -5/16, 8/16, 8/16, 5/16}, -- top - {-5/16, -4/16, -2/16, 5/16, 5/16, 2/16}, -- middle - {-8/16, -8/16, -5/16, 8/16, -4/16, 5/16}, -- base + { -6 / 16, -8 / 16, -6 / 16, 6 / 16, -4 / 16, 6 / 16 }, + { -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, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 1200, _mcl_hardness = 5, _mcl_after_falling = damage_anvil_by_falling, after_dig_node = function(pos, oldnode, oldmetadata, digger) - local meta = minetest.get_meta(pos) - local meta2 = meta + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() meta:from_table(oldmetadata) drop_anvil_items(pos, meta) - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_take = function(pos, listname, index, stack, player) local name = player:get_player_name() @@ -494,7 +540,6 @@ S("The anvil has limited durability and 3 damage levels: undamaged, slightly dam local anvildef1 = table.copy(anvildef) anvildef1.description = S("Slightly Damaged Anvil") anvildef1._doc_items_create_entry = false -anvildef1.groups.not_in_creative_inventory = 1 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"} @@ -502,7 +547,6 @@ anvildef1.tiles = {"mcl_anvils_anvil_top_damaged_1.png^[transformR90", "mcl_anvi local anvildef2 = table.copy(anvildef) anvildef2.description = S("Very Damaged Anvil") anvildef2._doc_items_create_entry = false -anvildef2.groups.not_in_creative_inventory = 1 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"} diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.dk.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.dk.tr new file mode 100644 index 000000000..8649aabc2 --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.dk.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +Set Name=Navngiv +Repair and Name=Reparér og navngiv +Inventory=Oppakning +Anvil=Ambolt +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!=Ambolten gør dig i stand til at reparere værktøj og rustninger, og til at navngive genstande. Den har dog begrænset holdbarhed. Lad den ikke falde ned i hovedet på dig, det kunne gøre meget ondt! +To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=For at bruge ambolten skal du højre-klikke på den. En ambolt har to indgangspladser (til venstre), og én udgangsplads. +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.=For at omdøbe en genstande skal du putte dem i den ene indgangsplads og lade den anden indgangsplads være tom. Skriv et navn, tryk på enter eller "Giv navn", og tag så den omdøbte genstand fra udgangspladsen. +There are two possibilities to repair tools (and armor):=Der er to muligheder for at reparere værktøj (og rustninger) +• 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.=• Værktøj + Værktøj: Placér to stykker værktøj af samme type i indgangspladserne. Holbarheden af det reparerede stykke værktøj er summen af holdbarheden på begge stykker værktøj plus 12% bonus. +• 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%.=• Værktøj + Materiale: Noget værktøj kan også repareres ved at kombinere dem med en genstand de er lavet af. For eksempel kan en jernhakke repareres med jernbarre. Dette reparerer værktøjet med 25%. +Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Rustninger tæller som værktøj. Det er muligt at reparere og omdøbe værktøj i ét enkelt trin. +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.=Ambolten har en begrænset holdbarhed og 3 skadeniveauer: Ubeskadiget, let beskadiget og meget beskadiget. Hver gang du reparerer eller omdøber noget er der en 12% chance for, at ambolten bliver beskadiget. Ambolte har også en risiko for at blive beskadiget når de falder mere end én blok ned. Hvis en beskadiget ambolt beskadiges igen bliver den ødelagt. +Slightly Damaged Anvil=Let beskadiget ambolt +Very Damaged Anvil=Meget beskadiget ambolt +Repair and rename items=Reparér og omdøb genstande diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.es.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.es.tr index 7212b92ba..218ff89cf 100644 --- a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.es.tr +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.es.tr @@ -13,3 +13,4 @@ Armor counts as a tool. It is possible to repair and rename a tool in a single 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.=El yunque tiene una durabilidad limitada y 3 niveles de daño: sin daños, ligeramente dañado y muy dañado. Cada vez que reparas o cambias el nombre de algo, hay un 12% de posibilidades de que el yunque se dañe. Los yunques también tienen la posibilidad de dañarse cuando caen en más de 1 bloque. Si un yunque muy dañado se daña nuevamente, se destruye. Slightly Damaged Anvil=Yunque dañado Very Damaged Anvil=Yunque muy dañado +Repair and rename items=Reparar y renombrar objetos diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.fr.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.fr.tr index 1f03de8e5..4bb909021 100644 --- a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.fr.tr +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.fr.tr @@ -1,16 +1,16 @@ # textdomain: mcl_anvils -Set Name=Définir le Nom -Repair and Name=Réparation et Nomme +Set Name=Définir le nom +Repair and Name=Réparer et nommer Inventory=Inventaire Anvil=Enclume -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!=L'enclume vous permet de réparer des outils et des armures, et de donner des noms à des objets. Il a cependant une durabilité limitée. Ne la laissez pas tomber sur la tête, cela pourrait être assez douloureux! +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!=L'enclume vous permet de réparer des outils et des armures, et de donner des noms à des objets. Elle a cependant une durabilité limitée. Ne la laissez pas tomber sur votre tête, cela pourrait être assez douloureux ! To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Pour utiliser une enclume, faites un clic droit dessus. Une enclume a 2 emplacements d'entrée (à gauche) et un emplacement de sortie. 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.=Pour renommer des objets, placez une pile d'objets dans l'un des emplacements d'objets tout en laissant l'autre emplacement d'entrée vide. Tapez un nom, appuyez sur Entrée ou sur «Définir le nom», puis prenez l'élément renommé dans l'emplacement de sortie. There are two possibilities to repair tools (and armor):=Il existe deux possibilités pour réparer les outils (et les armures): • 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.=• Outil + Outil: Placez deux outils du même type dans les emplacements d'entrée. La "santé" de l'outil réparé est la somme de la "santé" des deux outils d'entrée, plus un bonus de 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%.=• Outil + Matériel: Certains outils peuvent également être réparés en les combinant avec un élément dont il est fait. Par exemple, les pioches de fer peuvent être réparées avec des lingots de fer. Cela répare l'outil de 25%. Armor counts as a tool. It is possible to repair and rename a tool in a single step.=L'armure compte comme un outil. Il est possible de réparer et de renommer un outil en une seule étape. -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.=L'enclume a une durabilité limitée et 3 niveaux de dommages: en bon état, légèrement endommagé et très endommagé. Chaque fois que vous réparez ou renommez quelque chose, il y a 12% de chances que l'enclume soit endommagée. Les enclumes ont également une chance d'être endommagées lorsqu'elles tombent de plus d'un bloc. Si une enclume très endommagée est à nouveau endommagée, elle est détruite. -Slightly Damaged Anvil=Enclume Légèrement Endommagée -Very Damaged Anvil=Enclume Très Endommagée +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.=L'enclume a une durabilité limitée et 3 niveaux de dommages : en bon état, légèrement endommagée et très endommagée. Chaque fois que vous réparez ou renommez quelque chose, il y a 12% de chances que l'enclume soit endommagée. Les enclumes ont également une chance d'être endommagées lorsqu'elles tombent de plus d'un bloc. Si une enclume très endommagée est à nouveau endommagée, elle est détruite. +Slightly Damaged Anvil=Enclume légèrement endommagée +Very Damaged Anvil=Enclume très endommagée Repair and rename items=Réparer et renommer des objets diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr new file mode 100644 index 000000000..881ea5460 --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.ja.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +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.=金床を使用するには、右クリックです。金床には、2つの入力スロット(左側)と1つの出力スロットがあります。 +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.=アイテムを改名するには、入力スロットの片方にアイテムを入れ、もう一方は空のままにしておきます。名前を入力し、エンターキーか「名称を設定」を押したら、出力スロットから改名したアイテムを取り出します。 +There are two possibilities to repair tools (and armor):=道具(と防具)の修理方法には、可能性が次の2通りある: +• 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.=・ 道具 + 道具:同種の道具を2つ、入力スロットに置きます。修理された道具の「耐久度」は、入力した両方の道具の「耐久度」合計に、ボーナスで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=やや損傷した金床 +Very Damaged Anvil=かなり損傷した金床 +Repair and rename items=アイテムの修理と改名 diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pl.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pl.tr new file mode 100644 index 000000000..cf778e554 --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pl.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +Set Name=Ustaw nazwę +Repair and Name=Napraw i nazwij +Inventory=Ekwipunek +Anvil=Kowadło +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!=Kowadło pozwala naprawiać przedmioty i zbroje, a także nazywać przedmioty. Ma jednak ograniczoną wytrzymałość. Nie pozwól by spadło ci na głowę, bo będzie bardzo boleśnie! +To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Aby użyć kowadła, kliknij je prawym przyciskiem. Kowadło ma dwa miejsca wejściowe (po lewej) i jedno miejsce wyjściowe. +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.=Aby zmienić nazwę przedmiotów, włóż grupę przedmiotów w jedno z miejsc i zostaw drugie miejsce puste. Wpisz imię, kliknij "Ustaw imię", a następnie wyjmij przemianowane przedmioty z miejsca wyjściowego. +There are two possibilities to repair tools (and armor):=Są dwie możliwości naprawiania przedmiotów (i zbroi): +• 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.=Narzędzie + narzędzie: Wstaw dwa narzędzia tego samego typu w miejscach wejściowych. "Życie" naprawionego w ten sposób narzędzia jest sumą "żyć" obu narzędzi wejściowych plus 12% bonusu. +• 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%.=Narzędzie + materiał: Niektóre narzędzia mogą być naprawiane przez łączenie ich z przedmiotem z którego są wykonane. Przykładowo żelazne kilofy mogą być naprawione przy użyciu sztabek żelaza. To przywraca 25% "życia" narzędzia. +Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Zbroje liczą się tu jako narzędzia. Możliwe jest jednoczesna naprawa i przemianowanie przedmiotu. +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.=Kowadło ma ograniczoną wytrzymałość i trzy poziomu uszkodzenia: nieuszkodzone, lekko uszkodzone i bardzo uszkodzone. Za każdym razem gdy naprawiasz lub przemianowujesz coś jest 12% szans, że kowadło się uszkodzi. Kowadła mogą się również uszkodzić gdy spadają z wysokości większej niż jeden blok. Jeśli bardzo uszkodzone kowadło zostanie uszkodzone jeszcze raz, zostanie zniszczone. +Slightly Damaged Anvil=Lekko uszkodzone kowadło +Very Damaged Anvil=Bardzo uszkodzone kowadło +Repair and rename items=Napraw i przemianuj przedmioty diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pt_BR.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pt_BR.tr new file mode 100644 index 000000000..0d7fa486d --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.pt_BR.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +Set Name=Colocar nome +Repair and Name=Reparar e Nomear +Inventory=Inventário +Anvil=Bigorna +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!=A bigorna permite você reparar ferramentas e armaduras e nomear itens. No entanto, possui uma durabilidade limitada. Não a deixe cair sob sua cabeça, pode ser doloroso! +To use an anvil, rightclick it. An anvil has 2 input slots (on the left) and one output slot.=Para usar a bigorna, aperte-a com o botão direito. Uma bigorna possui 2 espaços de entrada (a esquerda) e um espaço de saída. +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.=Para renomear itens, coloque-o em um espaço de entrada enquanto mantém o outro vazio. Digite um nome e aperte enter ou "Colocar nome". Retire o item renomeado do espaço de saída. +There are two possibilities to repair tools (and armor):=Há duas possibilidades de reparar ferramentas (e armaduras): +• 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.= Ferramenta + Ferramenta: Coloque duas ferramentas do mesmo tipo nos espaços de entrada. A durabilidade da ferramenta reparada é a soma da durabilidade de ambas ferramentas utilizadas acrescido de um bônus de 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%.=Ferramenta + Material: Algumas ferramentas também podem ser reparadas combinando com o material da qual ela é feita. Por exemplo, picaretas de ferro podem ser reparadas com lingotes de ferro. Este repara a ferramenta por 25%. +Armor counts as a tool. It is possible to repair and rename a tool in a single step.=Armadura conta como uma ferramenta. É possível reparar e nomear uma ferramenta em uma única etapa. +Slightly Damaged Anvil=Bigorna danificada +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.=A bigorna tem durabilidade limitada e 3 níveis de dano: não danificada, danificada, muito danificada. Toda vez que você reparar ou nomear algo, há uma chance de 12% da bigorna ser danificada. Bigornas também possuem uma chance de serem danificadas quando cai por mais de 1 bloco. Se uma bigorna muito danificada sofre dano, ela é destruída. +Very Damaged Anvil=Bigorna muito danificada +Repair and rename items=Reparar e renomear itens diff --git a/mods/ITEMS/mcl_anvils/locale/mcl_anvils.zh_TW.tr b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.zh_TW.tr new file mode 100644 index 000000000..8ddf546a9 --- /dev/null +++ b/mods/ITEMS/mcl_anvils/locale/mcl_anvils.zh_TW.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_anvils +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.=要重新命名物品,在其中一個物品槽裡放一個物品,同時保持另一個輸入槽為空。鍵入名稱,點擊回車或「設置名稱」,然後從輸出槽中取出重命名後的物品。 +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=微損的鐵砧 +Very Damaged Anvil=耗損的鐵砧 +Repair and rename items=修復與命名物品 diff --git a/mods/ITEMS/mcl_anvils/mod.conf b/mods/ITEMS/mcl_anvils/mod.conf index 7712df190..cd4fa02a8 100644 --- a/mods/ITEMS/mcl_anvils/mod.conf +++ b/mods/ITEMS/mcl_anvils/mod.conf @@ -1 +1,5 @@ name = mcl_anvils +author = Wuzzy +description = Anvils mods for MCL2 +depends = mcl_init, mcl_formspec, mcl_sounds, tt, mcl_enchanting +optional_depends = mcl_core, screwdriver diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png deleted file mode 100644 index 84c64e915..000000000 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_0.png and /dev/null differ diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_1.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_1.png deleted file mode 100644 index 61c2ac6ab..000000000 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png deleted file mode 100644 index 5f5cfbffa..000000000 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_top_damaged_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_inventory.png b/mods/ITEMS/mcl_anvils/textures/mcl_anvils_inventory.png deleted file mode 100644 index fdbb706d1..000000000 Binary files a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_inventory.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/API.md b/mods/ITEMS/mcl_armor/API.md new file mode 100644 index 000000000..06292aab4 --- /dev/null +++ b/mods/ITEMS/mcl_armor/API.md @@ -0,0 +1,288 @@ +# mcl_armor + +This mod implements the ability of registering armors. + +## Registering an Armor Set + +The `mcl_armor.register_set()` function aims to simplify the process of registering a full set of armor. + +This function register four pieces of armor (head, torso, leggings, feets) based on a definition table: + +```lua +mcl_armor.register_set({ + --name of the armor material (used for generating itemstrings) + name = "dummy_armor", + + --description of the armor material + --do NOT translate this string, it will be concatenated will each piece of armor's description and result will be automatically fetched from your mod's translation files + description = "Dummy Armor", + + --overide description of each armor piece + --do NOT localize this string + descriptions = { + head = "Cap", --default: "Helmet" + torso = "Tunic", --default: "Chestplate" + legs = "Pants", --default: "Leggings" + feet = "Shoes", --default: "Boots" + }, + + --this is used to calculate each armor piece durability with the minecraft algorithm + --head durability = durability * 0.6857 + 1 + --torso durability = durability * 1.0 + 1 + --legs durability = durability * 0.9375 + 1 + --feet durability = durability * 0.8125 + 1 + durability = 80, + + --this is used then you need to specify the durability of each piece of armor + --this field have the priority over the durability one + --if the durability of some pieces of armor isn't specified in this field, the durability field will be used insteed + durabilities = { + head = 200, + torso = 500, + legs = 400, + feet = 300, + }, + + --this define how good enchants you will get then enchanting one piece of the armor in an enchanting table + --if set to zero or nil, the armor will not be enchantable + enchantability = 15, + + --this define how much each piece of armor protect the player + --these points will be shown in the HUD (chestplate bar above the health bar) + points = { + head = 1, + torso = 3, + legs = 2, + feet = 1, + }, + + --this attribute reduce strong damage even more + --See https://minecraft.fandom.com/wiki/Armor#Armor_toughness for more explanations + --default: 0 + toughness = 2, + + --this field is used to specify some items groups that will be added to each piece of armor + --please note that some groups do NOT need to be added by hand, because they are already handeled by the register function: + --(armor, combat_armor, armor_, combat_armor_, mcl_armor_points, mcl_armor_toughness, mcl_armor_uses, enchantability) + groups = {op_armor = 1}, + + --specify textures that will be overlayed on the entity wearing the armor + --these fields have default values and its recommanded to keep the code clean by just using the default name for your textures + textures = { + head = "dummy_texture.png", --default: "_helmet_.png" + torso = "dummy_texture.png", --default: "_chestplate_.png" + legs = "dummy_texture.png", --default: "_leggings_.png" + feet = "dummy_texture.png", --default: "_boots_.png" + }, + --you can also define these fields as functions, that will be called each time the API function mcl_armor.update(obj) is called (every time you equip/unequip some armor piece, take damage, and more) + --note that the enchanting overlay will not appear unless you implement it in the function + --this allow to make armors where the textures change whitout needing to register many other armors with different textures + textures = { + head = function(obj, itemstack) + if mcl_enchanting.is_enchanted(itemstack) then + return "dummy_texture.png^"..mcl_enchanting.overlay + else + return "dummy_texture.png" + end + end, + }, + + --inventory textures aren't definable using a table similar to textures or previews + --you are forced to use the default texture names which are: + --head: "_inv_helmet_.png + --torso: "_inv_chestplate_.png + --legs: "_inv_leggings_.png + --feet: "_inv_boots_.png + + --this callback table allow you to define functions that will be called each time an entity equip an armor piece or the mcl_armor.on_equip() function is called + --the functions accept two arguments: obj and itemstack + on_equip_callbacks = { + head = function(obj, itemstack) + --do stuff + end, + }, + + --this callback table allow you to define functions that will be called each time an entity unequip an armor piece or the mcl_armor.on_unequip() function is called + --the functions accept two arguments: obj and itemstack + on_unequip_callbacks = { + head = function(obj, itemstack) + --do stuff + end, + }, + + --this callback table allow you to define functions that will be called then an armor piece break + --the functions accept one arguments: obj + --the itemstack isn't sended due to how minetest handle items which have a zero durability + on_break_callbacks = { + head = function(obj) + --do stuff + end, + }, + + --this is used to generate automaticaly armor crafts based on each element type folowing the regular minecraft pattern + --if set to nil no craft will be added + craft_material = "mcl_mobitems:leather", + + --this is used to generate cooking crafts for each piece of armor + --if set to nil no craft will be added + cook_material = "mcl_core:gold_nugget", --cooking any piece of this armor will output a gold nugged + + --this is used for allowing each piece of the armor to be repaired by using an anvil with repair_material as aditionnal material + --it basicaly set the _repair_material item field of each piece of the armor + --if set to nil no repair material will be added + repair_material = "mcl_core:iron_ingot", +}) +``` + +## Creating an Armor Piece + +If you don't want to register a full set of armor, then you will need to manually register your own single item. + +```lua +minetest.register_tool("dummy_mod:random_armor", { + description = S("Random Armor"), + + --these two item fields are used for ingame documentation + --the mcl_armor.longdesc and mcl_armor.usage vars contains the basic usage and purpose of a piece of armor + --these vars may not be enough for that you want to do, so you may add some extra informations like that: + --_doc_items_longdesc = mcl_armor.longdesc.." "..S("Some extra informations.") + _doc_items_longdesc = mcl_armor.longdesc, + _doc_items_usagehelp = mcl_armor.usage, + + --this field is similar to any item definition in minetest + --it just set the image shown then the armor is dropped as an item or inside an inventory + inventory_image = "mcl_armor_inv_elytra.png", + + --this field is used by minetest internally and also by some helper functions + --in order for the tool to be shown is the right creative inventory tab, the right groups should be added + --"mcl_armor_uses" is required to give your armor a durability + --in that case, the armor can be worn by 10 points before breaking + --if you want the armor to be enchantable, you should also add the "enchantability" group, with the highest number the better enchants you can apply + groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10}, + + --this table is used by minetest for seraching item specific sounds + --the _mcl_armor_equip and _mcl_armor_unequip are used by the armor implementation to play sounds on equip and unequip + --note that you don't need to provide any file extention + sounds = { + _mcl_armor_equip = "mcl_armor_equip_leather", + _mcl_armor_unequip = "mcl_armor_unequip_leather", + }, + + --these fields should be initialised like that in most cases + --mcl_armor.equip_on_use is a function that try to equip the piece of armor you have in hand inside the right armor slot if the slot is empty + on_place = mcl_armor.equip_on_use, + on_secondary_use = mcl_armor.equip_on_use, + + --this field define that the tool is ACTUALLY an armor piece and in which armor slot you can put it + --it should be set to "head", "torso", "legs" or "feet" + _mcl_armor_element = "torso", + + + --this field is used to provide the texture that will be overlayed on the object (player or mob) skin + --this field can be a texture name or a function that will be called each time the mcl_armor.update(obj) function is called + --see the mcl_armor.register_set() documentation for more explanations + _mcl_armor_texture = "mcl_armor_elytra.png" + + --callbacks + --see the mcl_armor.register_set() documentation for more explanations + + _on_equip = function(obj, itemstack) + end, + _on_unequip = function(obj, itemstack) + end, + _on_break = function(obj) + end, +}) +``` + +## Interacting with Armor of an Entity + +Mods may want to interact with armor of an entity. + +Most global functions not described here may not be stable or may be for internal use only. + +You can equip a piece of armor on an entity inside a mod by using `mcl_armor.equip()`. + +```lua +--itemstack: an itemstack containing the armor piece to equip +--obj: the entity you want to equip the armor on +--swap: boolean, force equiping the armor piece, even if the entity already have one of the same type +mcl_armor.equip(itemstack, obj, swap) +``` + +You can update the entity apparence by using `mcl_armor.update()`. + +This function put the armor overlay on the object's base texture. +If the object is player it will update his displayed armor points count in HUD. + +This function will work both on players and mobs. + +```lua +--obj: the entity you want the apparence to be updated +mcl_armor.update(obj) +``` + +## Handling Enchantments + +Armors can be enchanted in most cases. + +The enchanting part of MineClone2 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. + +The `mcl_armor.register_protection_enchantment()` function aims to simplificate the creation of such enchants. + +```lua +mcl_armor.register_protection_enchantment({ + --this field is the id that will be used for registering enchanted book and store the enchant inside armor metadata. + --(his internal name) + id = "magic_protection", + + --visible name of the enchant + --this field is used as the name of registered enchanted book and inside armor tooltip + --translation should be added + name = S("Magic Protection"), + + --this field is used to know that the enchant currently do + --translation should be added + description = S("Reduces magic damage."), + + --how many levels can the enchant have + --ex: 4 => I, II, III, IV + --default: 4 + max_level = 4, + + --which enchants this enchant will not be compatible with + --each of these values is a enchant id + incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true}, + + --how much will the enchant consume from the enchantability group of the armor item + --default: 5 + weight = 5, + + --false => the enchant can be obtained in an enchanting table + --true => the enchant isn't obtainable in the enchanting table + --is true, you will probably need to implement some ways to obtain it + --even it the field is named "treasure", it will be no way to find it + --default: false + treasure = false, + + --how much will damage be reduced + --see Minecraft Wiki for more informations + --https://minecraft.gamepedia.com/Armor#Damage_protection + --https://minecraft.gamepedia.com/Armor#Enchantments + factor = 1, + + --restrict damage to one type + --allow the enchant to only protect of one type of damage + damage_type = "magic", + + --restrict damage to one category + --allow to protect from many type of damage at once + --this is much less specific than damage_type and also much more customisable + --the "is_magic" flag is used in the "magic", "dragon_breath", "wither_skull" and "thorns" damage types + --you can checkout the mcl_damage source code for a list of availlable damage types and associated flags + --but be warned that mods can register additionnal damage types + damage_flag = "is_magic", +}) +``` diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua new file mode 100644 index 000000000..1b9aa4f73 --- /dev/null +++ b/mods/ITEMS/mcl_armor/api.lua @@ -0,0 +1,259 @@ +function mcl_armor.play_equip_sound(stack, obj, pos, unequip) + local def = stack:get_definition() + local estr = "equip" + if unequip then + estr = "unequip" + end + local snd = def.sounds and def.sounds["_mcl_armor_" .. estr] + if not snd then + -- Fallback sound + snd = { name = "mcl_armor_" .. estr .. "_generic" } + end + if snd then + local dist = 8 + if pos then + dist = 16 + end + minetest.sound_play(snd, {object = obj, pos = pos, gain = 0.5, max_hear_distance = dist}, true) + end +end + +function mcl_armor.on_equip(itemstack, obj) + local def = itemstack:get_definition() + mcl_armor.play_equip_sound(itemstack, obj) + if def._on_equip then + def._on_equip(obj, itemstack) + end + mcl_armor.update(obj) +end + +function mcl_armor.on_unequip(itemstack, obj) + local def = itemstack:get_definition() + mcl_armor.play_equip_sound(itemstack, obj, nil, true) + if def._on_unequip then + def._on_unequip(obj, itemstack) + end + mcl_armor.update(obj) +end + +function mcl_armor.equip(itemstack, obj, swap) + local def = itemstack:get_definition() + + if not def then + return itemstack + end + + local inv = mcl_util.get_inventory(obj, true) + + if not inv or inv:get_size("armor") == 0 then + return itemstack + end + + local element = mcl_armor.elements[def._mcl_armor_element or ""] + + if element then + local old_stack = inv:get_stack("armor", element.index) + + if swap or old_stack:is_empty() then + local new_stack + + if swap then + new_stack = itemstack + itemstack = old_stack + else + new_stack = itemstack:take_item() + end + + inv:set_stack("armor", element.index, new_stack) + mcl_armor.on_equip(new_stack, obj) + end + end + + return itemstack +end + +function mcl_armor.equip_on_use(itemstack, player, pointed_thing) + if not player or not player:is_player() then + return itemstack + end + + local new_stack = mcl_util.call_on_rightclick(itemstack, player, pointed_thing) + if new_stack then + return new_stack + end + + return mcl_armor.equip(itemstack, player) +end + +function mcl_armor.register_set(def) + local modname = minetest.get_current_modname() + local S = minetest.get_translator(modname) + local descriptions = def.descriptions or {} + local groups = def.groups or {} + local on_equip_callbacks = def.on_equip_callbacks or {} + local on_unequip_callbacks = def.on_unequip_callbacks or {} + local on_break_callbacks = def.on_break_callbacks or {} + local textures = def.textures or {} + local durabilities = def.durabilities or {} + local element_groups = def.element_groups or {} + + for name, element in pairs(mcl_armor.elements) do + local itemname = element.name .. "_" .. def.name + local itemstring = modname .. ":" .. itemname + + local groups = table.copy(groups) + groups["armor_" .. name] = 1 + groups["combat_armor_" .. name] = 1 + groups.armor = 1 + groups.combat_armor = 1 + groups.mcl_armor_points = def.points[name] + groups.mcl_armor_toughness = def.toughness + groups.mcl_armor_uses = (durabilities[name] or math.floor(def.durability * element.durability)) + 1 + groups.enchantability = def.enchantability + + for k, v in pairs(element_groups) do + groups[k] = v + end + local upgrade_item = nil + if def._mcl_upgradable and def._mcl_upgrade_item_material then + upgrade_item = itemstring:gsub("_[%l%d]*$",def._mcl_upgrade_item_material) + end + + minetest.register_tool(itemstring, { + description = S(def.description .. " " .. (descriptions[name] or element.description)), + _doc_items_longdesc = mcl_armor.longdesc, + _doc_items_usagehelp = mcl_armor.usage, + inventory_image = modname .. "_inv_" .. itemname .. ".png", + _repair_material = def.repair_material or def.craft_material, + groups = groups, + sounds = { + _mcl_armor_equip = def.sound_equip or modname .. "_equip_" .. def.name, + _mcl_armor_unequip = def.sound_unequip or modname .. "_unequip_" .. def.name, + }, + on_place = mcl_armor.equip_on_use, + on_secondary_use = mcl_armor.equip_on_use, + _on_equip = on_equip_callbacks[name] or def.on_equip, + _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_upgradable = def._mcl_upgradable, + _mcl_upgrade_item = upgrade_item + }) + + if def.craft_material then + minetest.register_craft({ + output = itemstring, + recipe = element.craft(def.craft_material), + }) + end + + if def.cook_material then + minetest.register_craft({ + type = "cooking", + output = def.cook_material, + recipe = itemstring, + cooktime = 10, + }) + end + end +end + +mcl_armor.protection_enchantments = { + flags = {}, + types = {}, + wildcard = {}, +} + +function mcl_armor.register_protection_enchantment(def) + local prot_def = {id = def.id, factor = def.factor} + if def.damage_flag then + local tbl = mcl_armor.protection_enchantments.flags[def.damage_flag] or {} + table.insert(tbl, prot_def) + mcl_armor.protection_enchantments.flags = tbl + elseif def.damage_type then + local tbl = mcl_armor.protection_enchantments.types[def.damage_type] or {} + table.insert(tbl, prot_def) + mcl_armor.protection_enchantments.types = tbl + else + table.insert(mcl_armor.protection_enchantments.wildcard, prot_def) + end + mcl_enchanting.enchantments[def.id] = { + name = def.name, + max_level = def.max_level or 4, + primary = def.primary or {combat_armor = true}, + secondary = {}, + disallow = {}, + incompatible = def.incompatible or {}, + weight = def.weight or 5, + description = def.description, + curse = false, + on_enchant = function() end, + requires_tool = false, + treasure = def.treasure or false, + power_range_table = def.power_range_table, + inv_combat_tab = true, + inv_tool_tab = false, + } +end + +function mcl_armor.update(obj) + local info = {points = 0, view_range_factors = {}} + + local inv = mcl_util.get_inventory(obj) + + if inv then + for i = 2, 5 do + local itemstack = inv:get_stack("armor", i) + + local itemname = itemstack:get_name() + if minetest.registered_aliases[itemname] then + itemname = minetest.registered_aliases[itemname] + end + + if not itemstack:is_empty() then + local def = itemstack:get_definition() + + local texture = def._mcl_armor_texture + + if texture then + if type(texture) == "function" then + texture = texture(obj, itemstack) + end + if texture then + info.texture = "(" .. texture .. ")" .. (info.texture and "^" .. info.texture or "") + end + end + + info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points") + + local mob_range_mob = def._mcl_armor_mob_range_mob + + if mob_range_mob then + local factor = info.view_range_factors[mob_range_mob] + + if factor then + if factor > 0 then + info.view_range_factors[mob_range_mob] = factor * def._mcl_armor_mob_range_factor + end + else + info.view_range_factors[mob_range_mob] = def._mcl_armor_mob_range_factor + end + end + end + end + end + + info.texture = info.texture or "blank.png" + + if obj:is_player() then + mcl_armor.update_player(obj, info) + else + local luaentity = obj:get_luaentity() + + if luaentity.update_armor then + luaentity:update_armor(info) + end + end +end + diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua deleted file mode 100644 index 690b8b03c..000000000 --- a/mods/ITEMS/mcl_armor/armor.lua +++ /dev/null @@ -1,644 +0,0 @@ -local ARMOR_INIT_DELAY = 1 -local ARMOR_INIT_TIMES = 1 -local ARMOR_BONES_DELAY = 1 - -local skin_mod = nil - -local modpath = minetest.get_modpath(minetest.get_current_modname()) - -armor = { - timer = 0, - elements = {"head", "torso", "legs", "feet"}, - physics = {"jump","speed","gravity"}, - formspec = "size[8,8.5]image[2,0.75;2,4;armor_preview]" - .."list[current_player;main;0,4.5;8,4;]" - .."list[current_player;craft;4,1;3,3;]" - .."list[current_player;craftpreview;7,2;1,1;]" - .."listring[current_player;main]" - .."listring[current_player;craft]", - textures = {}, - default_skin = "character", - last_damage_types = {}, -} - -if minetest.get_modpath("mcl_skins") then - skin_mod = "mcl_skins" -elseif minetest.get_modpath("skins") then - skin_mod = "skins" -elseif minetest.get_modpath("simple_skins") then - skin_mod = "simple_skins" -elseif minetest.get_modpath("u_skins") then - skin_mod = "u_skins" -elseif minetest.get_modpath("wardrobe") then - skin_mod = "wardrobe" -end - -function armor.on_armor_use(itemstack, user, pointed_thing) - if not user or user:is_player() == false then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - if pointed_thing.type == "node" then - 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 - - local name, player_inv, armor_inv = armor:get_valid_player(user, "[on_armor_use]") - if not name then - return itemstack - end - - local def = itemstack:get_definition() - local slot - if def.groups and def.groups.armor_head then - slot = 2 - elseif def.groups and def.groups.armor_torso then - slot = 3 - elseif def.groups and def.groups.armor_legs then - slot = 4 - elseif def.groups and def.groups.armor_feet then - slot = 5 - end - - if slot then - local itemstack_single = ItemStack(itemstack) - itemstack_single:set_count(1) - local itemstack_slot = armor_inv:get_stack("armor", slot) - if itemstack_slot:is_empty() then - armor_inv:set_stack("armor", slot, itemstack_single) - player_inv:set_stack("armor", slot, itemstack_single) - armor:set_player_armor(user) - armor:update_inventory(user) - armor:play_equip_sound(itemstack_single, user) - itemstack:take_item() - elseif itemstack:get_count() <= 1 and not mcl_enchanting.has_enchantment(itemstack_slot, "curse_of_binding") then - armor_inv:set_stack("armor", slot, itemstack_single) - player_inv:set_stack("armor", slot, itemstack_single) - armor:set_player_armor(user) - armor:update_inventory(user) - armor:play_equip_sound(itemstack_single, user) - itemstack = ItemStack(itemstack_slot) - end - end - - return itemstack -end - -armor.def = { - count = 0, -} - -armor.update_player_visuals = function(self, player) - if not player then - return - end - - local player_holding = player:get_wielded_item():get_name() - if string.find(player_holding,"mcl_tools:") or player_holding == "mcl_mobitems:bone" or player_holding == "mcl_fishing:fishing_rod" then - player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) - elseif string.find(player_holding, "mcl_bows:bow") then - player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) - else - player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) - end - - local name = player:get_player_name() - if self.textures[name] then - mcl_player.player_set_textures(player, { - self.textures[name].skin, - self.textures[name].armor, - self.textures[name].wielditem, - }) - end -end - -armor.set_player_armor = function(self, player) - local name, player_inv = armor:get_valid_player(player, "[set_player_armor]") - if not name then - return - end - local armor_texture = "blank.png" - local armor_level = 0 - local mcl_armor_points = 0 - local items = 0 - local elements = {} - local textures = {} - local physics_o = {speed=1,gravity=1,jump=1} - local material = {type=nil, count=1} - local preview - for _,v in ipairs(self.elements) do - elements[v] = false - end - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - local item = stack:get_name() - if minetest.registered_aliases[item] then - item = minetest.registered_aliases[item] - end - if stack:get_count() == 1 then - local def = stack:get_definition() - for k, v in pairs(elements) do - if v == false then - local level = def.groups["armor_"..k] - if level then - local texture = def.texture or item:gsub("%:", "_") - local enchanted_addition = (mcl_enchanting.is_enchanted(item) and mcl_enchanting.overlay or "") - table.insert(textures, "("..texture..".png"..enchanted_addition..")") - preview = "(player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..")"..(preview and "^"..preview or "") - armor_level = armor_level + level - items = items + 1 - mcl_armor_points = mcl_armor_points + (def.groups["mcl_armor_points"] or 0) - for kk,vv in ipairs(self.physics) do - local o_value = def.groups["physics_"..vv] - if o_value then - physics_o[vv] = physics_o[vv] + o_value - end - end - local mat = string.match(item, "%:.+_(.+)$") - if material.type then - if material.type == mat then - material.count = material.count + 1 - end - else - material.type = mat - end - elements[k] = true - end - end - end - end - end - preview = (armor:get_preview(name) or "character_preview.png")..(preview and "^"..preview or "") - if minetest.get_modpath("shields") then - armor_level = armor_level * 0.9 - end - if material.type and material.count == #self.elements then - armor_level = armor_level * 1.1 - end - if #textures > 0 then - armor_texture = table.concat(textures, "^") - end - local armor_groups = player:get_armor_groups() - armor_groups.fleshy = 100 - armor_groups.level = nil - if armor_level > 0 then - armor_groups.level = math.floor(armor_level / 20) - armor_groups.fleshy = 100 - armor_level - end - player:set_armor_groups(armor_groups) - -- Physics override intentionally removed because of possible conflicts - self.textures[name].armor = armor_texture - self.textures[name].preview = preview - self.def[name].count = items - self.def[name].level = armor_level - self.def[name].heal = mcl_armor_points - self.def[name].jump = physics_o.jump - self.def[name].speed = physics_o.speed - self.def[name].gravity = physics_o.gravity - self:update_player_visuals(player) -end - -armor.update_armor = function(self, player) - -- Legacy support: Called when armor levels are changed - -- Other mods can hook on to this function, see hud mod for example -end - -armor.get_armor_points = function(self, player) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_armor_points]") - if not name then - return nil - end - local pts = 0 - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local p = minetest.get_item_group(stack:get_name(), "mcl_armor_points") - if p then - pts = pts + p - end - end - end - return pts -end - --- Returns a change factor for a mob's view_range for the given player --- or nil, if there's no change. Certain armors (like mob heads) can --- affect the view range of mobs. -armor.get_mob_view_range_factor = function(self, player, mob) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_mob_view_range_factor]") - if not name then - return - end - local factor - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local def = stack:get_definition() - if def._mcl_armor_mob_range_mob == mob then - if not factor then - factor = def._mcl_armor_mob_range_factor - elseif factor == 0 then - return 0 - else - factor = factor * def._mcl_armor_mob_range_factor - end - end - end - end - return factor -end - -armor.get_player_skin = function(self, name) - local skin = nil - if skin_mod == "mcl_skins" then - skin = mcl_skins.skins[name] - elseif skin_mod == "skins" or skin_mod == "simple_skins" then - skin = skins.skins[name] - elseif skin_mod == "u_skins" then - skin = u_skins.u_skins[name] - elseif skin_mod == "wardrobe" then - skin = string.gsub(wardrobe.playerSkins[name], "%.png$","") - end - return skin or armor.default_skin -end - -armor.get_preview = function(self, name) - if skin_mod == "skins" then - return armor:get_player_skin(name).."_preview.png" - end -end - -armor.get_armor_formspec = function(self, name) - if not armor.textures[name] then - minetest.log("error", "mcl_armor: Player texture["..name.."] is nil [get_armor_formspec]") - return "" - end - if not armor.def[name] then - minetest.log("error", "mcl_armor: Armor def["..name.."] is nil [get_armor_formspec]") - return "" - end - local formspec = armor.formspec.."list[detached:"..name.."_armor;armor;0,1;2,3;]" - formspec = formspec:gsub("armor_preview", armor.textures[name].preview) - formspec = formspec:gsub("armor_level", armor.def[name].level) - formspec = formspec:gsub("mcl_armor_points", armor.def[name].heal) - return formspec -end - -armor.update_inventory = function(self, player) -end - -armor.get_valid_player = function(self, player, msg) - msg = msg or "" - if not player then - minetest.log("error", "mcl_armor: Player reference is nil "..msg) - return - end - local name = player:get_player_name() - if not name then - minetest.log("error", "mcl_armor: Player name is nil "..msg) - return - end - local pos = player:get_pos() - local player_inv = player:get_inventory() - local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"}) - if not pos then - minetest.log("error", "mcl_armor: Player position is nil "..msg) - return - elseif not player_inv then - minetest.log("error", "mcl_armor: Player inventory is nil "..msg) - return - elseif not armor_inv then - minetest.log("error", "mcl_armor: Detached armor inventory is nil "..msg) - return - end - return name, player_inv, armor_inv, pos -end - -armor.play_equip_sound = function(self, stack, player, pos, unequip) - local def = stack:get_definition() - local estr = "equip" - if unequip then - estr = "unequip" - end - local snd = def.sounds and def.sounds["_mcl_armor_"..estr] - if not snd then - -- Fallback sound - snd = { name = "mcl_armor_"..estr.."_generic" } - end - if snd then - local dist = 8 - if pos then - dist = 16 - end - minetest.sound_play(snd, {object=player, pos=pos, gain=0.5, max_hear_distance=dist}, true) - end -end - --- Register Player Model - -mcl_player.player_register_model("mcl_armor_character.b3d", { - animation_speed = 30, - textures = { - armor.default_skin..".png", - "blank.png", - "blank.png", - }, - animations = { - stand = {x=0, y=79}, - lay = {x=162, y=166}, - walk = {x=168, y=187}, - mine = {x=189, y=198}, - walk_mine = {x=200, y=219}, - sit = {x=81, y=160}, - sneak_stand = {x=222, y=302}, - sneak_mine = {x=346, y=366}, - sneak_walk = {x=304, y=323}, - sneak_walk_mine = {x=325, y=344}, - swim_walk = {x=368, y=387}, - swim_walk_mine = {x=389, y=408}, - swim_stand = {x=434, y=434}, - swim_mine = {x=411, y=430}, - }, -}) - --- Register Callbacks - -minetest.register_on_player_receive_fields(function(player, formname, fields) - local name = armor:get_valid_player(player, "[on_player_receive_fields]") - if not name then - return - end - if fields.armor then - return - end - for field, _ in pairs(fields) do - if string.find(field, "skins_set") then - minetest.after(0, function(name) - local player = minetest.get_player_by_name(name) - if not player then - return - end - local skin = armor:get_player_skin(name) - armor.textures[name].skin = skin..".png" - armor:set_player_armor(player) - end, player:get_player_name()) - end - end -end) - -minetest.register_on_joinplayer(function(player) - mcl_player.player_set_model(player, "mcl_armor_character.b3d") - local name = player:get_player_name() - local player_inv = player:get_inventory() - local armor_inv = minetest.create_detached_inventory(name.."_armor", { - on_put = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, stack) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player) - end, - on_take = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player, nil, true) - end, - on_move = function(inv, from_list, from_index, to_list, to_index, count, player) - local plaver_inv = player:get_inventory() - local stack = inv:get_stack(to_list, to_index) - player_inv:set_stack(to_list, to_index, stack) - player_inv:set_stack(from_list, from_index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player) - end, - allow_put = function(inv, listname, index, stack, player) - local iname = stack:get_name() - local g - local groupcheck - if index == 2 then - g = minetest.get_item_group(iname, "armor_head") - elseif index == 3 then - g = minetest.get_item_group(iname, "armor_torso") - elseif index == 4 then - g = minetest.get_item_group(iname, "armor_legs") - elseif index == 5 then - g = minetest.get_item_group(iname, "armor_feet") - end - -- Minor FIXME: If player attempts to place stack into occupied slot, this is rejected. - -- It would be better if 1 item is placed in exchanged for the item in the slot. - if g ~= 0 and g ~= nil and (inv:get_stack(listname, index):is_empty() or (inv:get_stack(listname, index):get_name() ~= stack:get_name()) and stack:get_count() <= 1) then - return 1 - else - return 0 - end - end, - allow_take = function(inv, listname, index, stack, player) - if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.settings:get_bool("creative") then - return 0 - end - return stack:get_count() - end, - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - return 0 - end, - }, name) - armor_inv:set_size("armor", 6) - player_inv:set_size("armor", 6) - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - armor_inv:set_stack("armor", i, stack) - end - armor.def[name] = { - count = 0, - level = 0, - heal = 0, - jump = 1, - speed = 1, - gravity = 1, - } - armor.textures[name] = { - skin = armor.default_skin..".png", - armor = "blank.png", - wielditem = "blank.png", - preview = armor.default_skin.."_preview.png", - } - if skin_mod == "mcl_skins" then - local skin = mcl_skins.skins[name] - if skin then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "skins" then - local skin = skins.skins[name] - if skin and skins.get_type(skin) == skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "simple_skins" then - local skin = skins.skins[name] - if skin then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "u_skins" then - local skin = u_skins.u_skins[name] - if skin and u_skins.get_type(skin) == u_skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "wardrobe" then - local skin = wardrobe.playerSkins[name] - if skin then - armor.textures[name].skin = skin - end - end - if minetest.get_modpath("player_textures") then - local filename = minetest.get_modpath("player_textures").."/textures/player_"..name - local f = io.open(filename..".png") - if f then - f:close() - armor.textures[name].skin = "player_"..name..".png" - end - end - for i=1, ARMOR_INIT_TIMES do - minetest.after(ARMOR_INIT_DELAY * i, function(name) - local player = minetest.get_player_by_name(name) - if not player then - return - end - armor:set_player_armor(player) - end, player:get_player_name()) - end -end) - -minetest.register_on_player_hpchange(function(player, hp_change, reason) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]") - if name and hp_change < 0 then - local damage_type = armor.last_damage_types[name] - armor.last_damage_types[name] = nil - - -- Armor doesn't protect from set_hp (commands like /kill), - if reason.type == "set_hp" then - return hp_change - end - - local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall" - - -- Account for potion effects (armor doesn't save the target) - if reason.other == "poison" or reason.other == "harming" then - return hp_change - end - - local heal_max = 0 - local items = 0 - local armor_damage = math.max(1, math.floor(math.abs(hp_change)/4)) - - local total_points = 0 - local total_toughness = 0 - local epf = 0 - local thorns_damage = 0 - local thorns_damage_regular = 0 - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local enchantments = mcl_enchanting.get_enchantments(stack) - local pts = stack:get_definition().groups["mcl_armor_points"] or 0 - local tough = stack:get_definition().groups["mcl_armor_toughness"] or 0 - total_points = total_points + pts - total_toughness = total_toughness + tough - - local protection_level = enchantments.protection or 0 - if protection_level > 0 then - epf = epf + protection_level * 1 - end - local blast_protection_level = enchantments.blast_protection or 0 - if blast_protection_level > 0 and damage_type == "explosion" then - epf = epf + blast_protection_level * 2 - end - local fire_protection_level = enchantments.fire_protection or 0 - if fire_protection_level > 0 and (damage_type == "burning" or damage_type == "fireball" or reason.type == "node_damage" and - (reason.node == "mcl_fire:fire" or reason.node == "mcl_core:lava_source" or reason.node == "mcl_core:lava_flowing")) then - epf = epf + fire_protection_level * 2 - end - local projectile_protection_level = enchantments.projectile_protection or 0 - if projectile_protection_level and (damage_type == "projectile" or damage_type == "fireball") then - epf = epf + projectile_protection_level * 2 - end - local feather_falling_level = enchantments.feather_falling or 0 - if feather_falling_level and reason.type == "fall" then - epf = epf + feather_falling_level * 3 - end - - local did_thorns_damage = false - local thorns_level = enchantments.thorns or 0 - if thorns_level then - if thorns_level > 10 then - thorns_damage = thorns_damage + thorns_level - 10 - did_thorns_damage = true - elseif thorns_damage_regular < 4 and thorns_level * 0.15 > math.random() then - local thorns_damage_regular_new = math.min(4, thorns_damage_regular + math.random(4)) - thorns_damage = thorns_damage + thorns_damage_regular_new - thorns_damage_regular - thorns_damage_regular = thorns_damage_regular_new - did_thorns_damage = true - end - end - - -- Damage armor - local use = stack:get_definition().groups["mcl_armor_uses"] or 0 - if use > 0 and regular_reduction then - local unbreaking_level = enchantments.unbreaking or 0 - if unbreaking_level > 0 then - use = use / (0.6 + 0.4 / (unbreaking_level + 1)) - end - local wear = armor_damage * math.floor(65536/use) - if did_thorns_damage then - wear = wear * 3 - end - stack:add_wear(wear) - end - - local item = stack:get_name() - armor_inv:set_stack("armor", i, stack) - player_inv:set_stack("armor", i, stack) - items = items + 1 - if stack:get_count() == 0 then - armor:set_player_armor(player) - armor:update_inventory(player) - end - end - end - local damage = math.abs(hp_change) - - if regular_reduction then - -- Damage calculation formula (from ) - damage = damage * (1 - math.min(20, math.max((total_points/5), total_points - damage / (2+(total_toughness/4)))) / 25) - end - damage = damage * (1 - (math.min(20, epf) / 25)) - damage = math.floor(damage+0.5) - - if reason.type == "punch" and thorns_damage > 0 then - local obj = reason.object - if obj then - local luaentity = obj:get_luaentity() - if luaentity then - local shooter = obj._shooter - if shooter then - obj = shooter - end - end - obj:punch(player, 1.0, { - full_punch_interval=1.0, - damage_groups = {fleshy = thorns_damage}, - }) - end - end - - hp_change = -math.abs(damage) - - armor.def[name].count = items - armor:update_armor(player) - end - return hp_change -end, true) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua new file mode 100644 index 000000000..2606f8263 --- /dev/null +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -0,0 +1,104 @@ +local function use_durability(obj, inv, index, stack, uses) + local def = stack:get_definition() + mcl_util.use_item_durability(stack, uses) + if stack:is_empty() and def and def._on_break then + stack = def._on_break(obj) or stack + end + inv:set_stack("armor", index, stack) +end + +mcl_damage.register_modifier(function(obj, damage, reason) + local flags = reason.flags + + if flags.bypasses_armor and flags.bypasses_magic then + return damage + end + + local uses = math.max(1, math.floor(damage / 4)) + + local points = 0 + local toughness = 0 + local enchantment_protection_factor = 0 + + local thorns_damage_regular = 0 + local thorns_damage_irregular = 0 + local thorns_pieces = {} + + local inv = mcl_util.get_inventory(obj) + + if inv then + for name, element in pairs(mcl_armor.elements) do + local itemstack = inv:get_stack("armor", element.index) + if not itemstack:is_empty() then + local itemname = itemstack:get_name() + local enchantments = mcl_enchanting.get_enchantments(itemstack) + + if not flags.bypasses_armor and minetest.get_item_group(itemname, "non_combat_armor") == 0 then + points = points + minetest.get_item_group(itemname, "mcl_armor_points") + toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") + + use_durability(obj, inv, element.index, itemstack, uses) + end + + if not flags.bypasses_magic then + local function add_enchantments(tbl) + if tbl then + for _, enchantment in pairs(tbl) do + local level = enchantments[enchantment.id] + + if level and level > 0 then + enchantment_protection_factor = enchantment_protection_factor + level * enchantment.factor + end + end + end + end + + add_enchantments(mcl_armor.protection_enchantments.wildcard) + add_enchantments(mcl_armor.protection_enchantments.types[reason.type]) + + for flag, value in pairs(flags) do + if value then + add_enchantments(mcl_armor.protection_enchantments.flags[flag]) + end + end + end + + if reason.source and enchantments.thorns and enchantments.thorns > 0 then + local do_irregular_damage = enchantments.thorns > 10 + + if do_irregular_damage or thorns_damage_regular < 4 and math.random() < enchantments.thorns * 0.15 then + if do_irregular_damage then + thorns_damage_irregular = thorns_damage_irregular + enchantments.thorns - 10 + else + thorns_damage_regular = math.min(4, thorns_damage_regular + math.random(4)) + end + end + + table.insert(thorns_pieces, {index = element.index, itemstack = itemstack}) + end + end + end + end + + -- https://minecraft.gamepedia.com/Armor#Damage_protection + damage = damage * (1 - math.min(20, math.max((points / 5), points - damage / (2 + (toughness / 4)))) / 25) + + -- https://minecraft.gamepedia.com/Armor#Enchantments + damage = damage * (1 - math.min(20, enchantment_protection_factor) / 25) + + local thorns_damage = thorns_damage_regular + thorns_damage_irregular + + if thorns_damage > 0 and reason.type ~= "thorns" and reason.source ~= obj then + mcl_util.deal_damage(reason.source, thorns_damage, {type = "thorns", direct = obj}) + -- mcl_util.deal_damage may remove object immediately + if not reason.source:get_pos() then return end + + local thorns_item = thorns_pieces[math.random(#thorns_pieces)] + + use_durability(obj, inv, thorns_item.index, thorns_item.itemstack, 2) + end + + mcl_armor.update(obj) + + return math.floor(damage + 0.5) +end, 0) diff --git a/mods/ITEMS/mcl_armor/depends.txt b/mods/ITEMS/mcl_armor/depends.txt deleted file mode 100644 index 067cf61b1..000000000 --- a/mods/ITEMS/mcl_armor/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_player -mcl_fire? -ethereal? -bakedclay? -mcl_enchanting diff --git a/mods/ITEMS/mcl_armor/description.txt b/mods/ITEMS/mcl_armor/description.txt deleted file mode 100644 index b0a9b0a5a..000000000 --- a/mods/ITEMS/mcl_armor/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds craftable armor that is visible to other players. diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index c5502cf42..799bf2e9c 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -1,392 +1,68 @@ -local S = minetest.get_translator("mcl_armor") +local S = minetest.get_translator(minetest.get_current_modname()) -dofile(minetest.get_modpath(minetest.get_current_modname()).."/armor.lua") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/alias.lua") - --- Regisiter Head Armor - -local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.") -local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.") - -minetest.register_tool("mcl_armor:helmet_leather", { - description = S("Leather Cap"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_leather.png", - groups = {armor_head=1, mcl_armor_points=1, mcl_armor_uses=56, enchantability=15}, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", +mcl_armor = { + longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive."), + usage = S("To equip it, put it on the corresponding armor slot in your inventory menu."), + elements = { + head = { + name = "helmet", + description = "Helmet", + durability = 0.6857, + index = 2, + craft = function(m) + return { + { m, m, m}, + { m, "", m}, + {"", "", ""}, + } + end, + }, + torso = { + name = "chestplate", + description = "Chestplate", + durability = 1.0, + index = 3, + craft = function(m) + return { + { m, "", m}, + { m, m, m}, + { m, m, m}, + } + end, + }, + legs = { + name = "leggings", + description = "Leggings", + durability = 0.9375, + index = 4, + craft = function(m) + return { + { m, m, m}, + { m, "", m}, + { m, "", m}, + } + end, + }, + feet = { + name = "boots", + description = "Boots", + durability = 0.8125, + index = 5, + craft = function(m) + return { + { m, "", m}, + { m, "", m}, + } + end, + } }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) + player_view_range_factors = {}, +} -minetest.register_tool("mcl_armor:helmet_iron", { - description = S("Iron Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_iron.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_gold", { - description = S("Golden Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_gold.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=78, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_diamond",{ - description = S("Diamond Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_diamond.png", - groups = {armor_head=1, mcl_armor_points=3, mcl_armor_uses=364, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_chain", { - description = S("Chain Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_chain.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Regisiter Torso Armor - -minetest.register_tool("mcl_armor:chestplate_leather", { - description = S("Leather Tunic"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_leather.png", - groups = {armor_torso=1, mcl_armor_points=3, mcl_armor_uses=81, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_iron", { - description = S("Iron Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_iron.png", - groups = {armor_torso=1, mcl_armor_points=6, mcl_armor_uses=241, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_gold", { - description = S("Golden Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_gold.png", - groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=113, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_diamond",{ - description = S("Diamond Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_diamond.png", - groups = {armor_torso=1, mcl_armor_points=8, mcl_armor_uses=529, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_chain", { - description = S("Chain Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_chain.png", - groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=241, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Regisiter Leg Armor - -minetest.register_tool("mcl_armor:leggings_leather", { - description = S("Leather Pants"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_leather.png", - groups = {armor_legs=1, mcl_armor_points=2, mcl_armor_uses=76, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_iron", { - description = S("Iron Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_iron.png", - groups = {armor_legs=1, mcl_armor_points=5, mcl_armor_uses=226, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_gold", { - description = S("Golden Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_gold.png", - groups = {armor_legs=1, mcl_armor_points=3, mcl_armor_uses=106, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_diamond",{ - description = S("Diamond Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_diamond.png", - groups = {armor_legs=1, mcl_armor_points=6, mcl_armor_uses=496, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_chain", { - description = S("Chain Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_chain.png", - groups = {armor_legs=1, mcl_armor_points=4, mcl_armor_uses=226, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) --- Regisiter Boots - -minetest.register_tool("mcl_armor:boots_leather", { - description = S("Leather Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_leather.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=66, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_iron", { - description = S("Iron Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_iron.png", - groups = {armor_feet=1, mcl_armor_points=2, mcl_armor_uses=196, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_gold", { - description = S("Golden Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_gold.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=92, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_diamond",{ - description = S("Diamond Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_diamond.png", - groups = {armor_feet=1, mcl_armor_points=3, mcl_armor_uses=430, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_chain", { - description = S("Chain Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_chain.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=196, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Register Craft Recipies - -local craft_ingreds = { - leather = { "mcl_mobitems:leather" }, - iron = { "mcl_core:iron_ingot", "mcl_core:iron_nugget" }, - gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" }, - diamond = { "mcl_core:diamond" }, - chain = { nil, "mcl_core:iron_nugget"} , -} - -for k, v in pairs(craft_ingreds) do - -- material - local m = v[1] - -- cooking result - local c = v[2] - if m ~= nil then - minetest.register_craft({ - output = "mcl_armor:helmet_"..k, - recipe = { - {m, m, m}, - {m, "", m}, - {"", "", ""}, - }, - }) - minetest.register_craft({ - output = "mcl_armor:chestplate_"..k, - recipe = { - {m, "", m}, - {m, m, m}, - {m, m, m}, - }, - }) - minetest.register_craft({ - output = "mcl_armor:leggings_"..k, - recipe = { - {m, m, m}, - {m, "", m}, - {m, "", m}, - }, - }) - minetest.register_craft({ - output = "mcl_armor:boots_"..k, - recipe = { - {m, "", m}, - {m, "", m}, - }, - }) - end - if c ~= nil then - minetest.register_craft({ - type = "cooking", - output = c, - recipe = "mcl_armor:helmet_"..k, - cooktime = 10, - }) - minetest.register_craft({ - type = "cooking", - output = c, - recipe = "mcl_armor:chestplate_"..k, - cooktime = 10, - }) - minetest.register_craft({ - type = "cooking", - output = c, - recipe = "mcl_armor:leggings_"..k, - cooktime = 10, - }) - minetest.register_craft({ - type = "cooking", - output = c, - recipe = "mcl_armor:boots_"..k, - cooktime = 10, - }) - end -end +local modpath = minetest.get_modpath("mcl_armor") +dofile(modpath .. "/api.lua") +dofile(modpath .. "/player.lua") +dofile(modpath .. "/damage.lua") +dofile(modpath .. "/register.lua") +dofile(modpath .. "/alias.lua") diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.dk.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.dk.tr new file mode 100644 index 000000000..b7b92fd95 --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.dk.tr @@ -0,0 +1,48 @@ +# textdomain: mcl_armor +This is a piece of equippable armor which reduces the amount of damage you receive.=Dette er et stykke rustning du kan tage på for at reducere den mængde du tager. +To equip it, put it on the corresponding armor slot in your inventory menu.=For at tage den på, skal du putte den i den tilsvarende rustningsplads i din oppakningsmenu. +Leather Cap=Læderhat +Iron Helmet=Jernhjelm +Golden Helmet=Guldhjelm +Diamond Helmet=Diamanthjelm +Chain Helmet=Brynjehjelm +Netherite Helmet=Netherritehjelm +Leather Tunic=Lædertunika +Iron Chestplate=Jernbrystplade +Golden Chestplate=Guldbrystplade +Diamond Chestplate=Diamantbrystplade +Chain Chestplate=Brynjeskjorte +Netherite Chestplate=Netheritebrystplade +Leather Pants=Læderbukser +Iron Leggings=Jernbenplader +Golden Leggings=Guldbenplader +Diamond Leggings=Diamantbenplader +Chain Leggings=Brynjebukser +Netherite Leggings=Netheritebenplader +Leather Boots=Læderstøvler +Iron Boots=Jernstøvler +Golden Boots=Guldstøvler +Diamond Boots=Diamantstøvler +Chain Boots=Brynjestøvler +Netherite Boots=Netheritestøvler +Elytra=Elytra + +#Translations of enchantements +Increases underwater mining speed.=Øger udvindingshastigheden under vand. +Blast Protection=Eksplosionsbeskyttelse +Reduces explosion damage and knockback.=Reducerer eksplosionsskade og -tilbageslag. +Curse of Binding=Bindende forbandelse. +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Objektet kan ikke fjernes fra rustninspladser undtagen ved død, hvis den går i stykker ikke i kreativ tilstand. +Feather Falling=Fjerfald +Reduces fall damage.=Reduerer faldskade. +Fire Protection=Ildbeskyttelse +Reduces fire damage.=Reducerer ildskade. +Shooting consumes no regular arrows.=Det bruger ingen normale pile at skyde. +Shoot 3 arrows at the cost of one.=Skyd 3 pile for én pils pris. +Projectile Protection=Projektilbeskyttelse +Reduces projectile damage.=Reducerer projektilskade +Protection=Beskyttelse +Reduces most types of damage by 4% for each level.=Reducerer det fleste skadestyper med 4% for hvert level. +Thorns=Torne +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflekterer skade ved træfning, men koster holdbarhed ved hver brug. +Aqua Affinity=Vandaffinitet \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.es.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.es.tr index e770dff0c..572139c72 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.es.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.es.tr @@ -1,23 +1,48 @@ # 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ü. +This is a piece of equippable armor which reduces the amount of damage you receive.=Esta es una pieza de armadura que se puede equipar, la cual reduce la cantidad de daño que recives. +To equip it, put it on the corresponding armor slot in your inventory menu.=Para equiparla, colocala en la ranura de armadura en el menú de tu inventario. Leather Cap=Sombrero de cuero Iron Helmet=Casco de hierro Golden Helmet=Casco de oro Diamond Helmet=Casco de diamante Chain Helmet=Casco de cota de mallas +Netherite Helmet=Casco de netherita Leather Tunic=Túnica de cuero Iron Chestplate=Peto de hierro Golden Chestplate=Peto de oro Diamond Chestplate=Peto de diamante Chain Chestplate=Peto de cota de mallas +Netherite Chestplate=Peto de netherita Leather Pants=Pantalones de cuero Iron Leggings=Grebas de hierro Golden Leggings=Grebas de oro Diamond Leggings=Grebas de diamante Chain Leggings=Grebas de cota de mallas +Netherite Leggings=Grebas de netherita Leather Boots=Botas de cuero Iron Boots=Botas de hierro Golden Boots=Botas de oro Diamond Boots=Botas de diamante Chain Boots=Botas de cota de mallas +Netherite Boots=Botas de netherita +Elytra=Élitros + +#Translations of enchantements +Increases underwater mining speed.=Aumenta la velocidad de minado bajo el agua. +Blast Protection=Protección contra explosiones +Reduces explosion damage and knockback.=Reduce el daño de explosiones y su empuje. +Curse of Binding=Maldicón de ligamiento +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=El objeto no puede ser removido de las ranuras de inventario excepto al morir, al romperse, o en Modo Creativo. +Feather Falling=Caída de plumas +Reduces fall damage.=Reduce el daño por caída. +Fire Protection=Protección contra el fuego +Reduces fire damage.=Reduce el daño causado por fuego. +Shooting consumes no regular arrows.=Disparar no consume flechas normales. +Shoot 3 arrows at the cost of one.=Dispara 3 flechas por el costo de una. +Projectile Protection=Protección contra proyectiles +Reduces projectile damage.=Reduce el daño de proyectiles. +Protection=Protección +Reduces most types of damage by 4% for each level.=Reduce la mayoría de tipos de daño por 4% por cada nivel. +Thorns=Espinas +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Refleja una parte del daño infligido, a costa de reducir la durabilidad con cada activación. +Aqua Affinity=Afinidad acuática diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr index 6f55a73fe..b3a2c6dbc 100644 --- a/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.fr.tr @@ -1,23 +1,50 @@ # textdomain: mcl_armor This is a piece of equippable armor which reduces the amount of damage you receive.=Il s'agit d'un morceau d'armure équipable qui réduit la quantité de dégâts que vous recevez. To equip it, put it on the corresponding armor slot in your inventory menu.=Pour l'équiper, placez-le sur l'emplacement d'armure correspondant dans votre menu d'inventaire. -Leather Cap=Casquette en Cuir -Iron Helmet=Casque de Fer -Golden Helmet=Casque d'Or -Diamond Helmet=Casque de Diamant -Chain Helmet=Casque de Mailles -Leather Tunic=Tunique en Cuir -Iron Chestplate=Plastron de Fer -Golden Chestplate=Plastron d'Or -Diamond Chestplate=Plastron de Diamant -Chain Chestplate=Cotte de Mailles -Leather Pants=Pantalon de Cuir -Iron Leggings=Jambières de Fer -Golden Leggings=Jambières d'Or -Diamond Leggings=Jambières de Diamant -Chain Leggings=Jambières de Mailles -Leather Boots=Bottes de Cuir -Iron Boots=Bottes de Fer -Golden Boots=Bottes d'Or -Diamond Boots=Bottes de Diamant -Chain Boots=Bottes de Mailles +Leather Cap=Casquette en cuir +Iron Helmet=Casque de fer +Golden Helmet=Casque d'or +Diamond Helmet=Casque de diamant +Chain Helmet=Casque de mailles +Netherite Helmet=Casque de netherite +Leather Tunic=Tunique en cuir +Iron Chestplate=Plastron de fer +Golden Chestplate=Plastron d'or +Diamond Chestplate=Plastron de diamant +Chain Chestplate=Cotte de mailles +Netherite Chestplate=Plastron de netherite +Leather Pants=Pantalon de cuir +Iron Leggings=Jambières de fer +Golden Leggings=Jambières d'or +Diamond Leggings=Jambières de diamant +Chain Leggings=Jambières de mailles +Netherite Leggings=Jambières de netherite +Leather Boots=Bottes de cuir +Iron Boots=Bottes de fer +Golden Boots=Bottes d'or +Diamond Boots=Bottes de diamant +Chain Boots=Bottes de mailles +Netherite Boots=Bottes de netherite +Elytra=Élytres + +#Translations of enchantements +Increases underwater mining speed.=Augmente la vitesse de minage sous-marine. +Blast Protection=Protection contre les explosions +Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul. +Curse of Binding=Malédiction du lien éternel +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=L'objet ne peut pas être retiré des emplacements d'armure sauf en cas de mort, de rupture ou en mode créatif. +Feather Falling=Chute amortie +Reduces fall damage.=Réduit les dégats de chute. +Fire Protection=Protection contre le feu +Reduces fire damage.=Réduit les dégats de feu. +Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard. +Shoot 3 arrows at the cost of one.=Tirez 3 flèches pour le prix d'une. +Projectile Protection=Protection contre les projectiles +Reduces projectile damage.=Réduit les dégâts causés par les projectiles. +Protection=Protection +Reduces most types of damage by 4% for each level.=Réduit la plupart des types de dégâts de 4% pour chaque niveau. +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 + + diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr new file mode 100644 index 000000000..fc1f0f02b --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.ja.tr @@ -0,0 +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=革のキャップ +Iron Helmet=鉄のヘルメット +Golden Helmet=金のヘルメット +Diamond Helmet=ダイヤモンドのヘルメット +Chain Helmet=鎖のヘルメット +Netherite Helmet=ネザライトのヘルメット +Leather Tunic=革のチュニック +Iron Chestplate=鉄のチェストプレート +Golden Chestplate=金のチェストプレート +Diamond Chestplate=ダイヤモンドのチェストプレート +Chain Chestplate=鎖のチェストプレート +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.=1本分のコストで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=水中採掘 \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.pl.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.pl.tr new file mode 100644 index 000000000..32236113e --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.pl.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_armor +This is a piece of equippable armor which reduces the amount of damage you receive.=Jest to część możliwej do założenia zbroi, która zmniejsza otrzymywane obrażenia. +To equip it, put it on the corresponding armor slot in your inventory menu.=Aby ją założyć, upuść ją na odpowiadającym miejscu na zbroję na ekranie ekwipunku. +Leather Cap=Skórzana czapka +Iron Helmet=Żelazny hełm +Golden Helmet=Złoty hełm +Diamond Helmet=Diamentowy hełm +Chain Helmet=Kolczy hełm +Leather Tunic=Skórzana tunika +Iron Chestplate=Żelazny napierśnik +Golden Chestplate=Złoty napierśnik +Diamond Chestplate=Diamentowy napierśnik +Chain Chestplate=Kolczy napierśnik +Leather Pants=Skórzane spodnie +Iron Leggings=Żelazne nogawice +Golden Leggings=Złote nogawice +Diamond Leggings=Diamentowe nogawice +Chain Leggings=Kolcze nogawice +Leather Boots=Skórzane buty +Iron Boots=Żelazne buty +Golden Boots=Złote buty +Diamond Boots=Diamentowe buty +Chain Boots=Kolcze buty diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr new file mode 100644 index 000000000..b12f07026 --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.pt_BR.tr @@ -0,0 +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=Chapéu de Couro +Iron Helmet=Capacete de Ferro +Golden Helmet=Capacete de Ouro +Diamond Helmet=Capacete de Diamante +Chain Helmet=Capacete de Cota de Malha +Netherite Helmet=Capacete de Netherite +Leather Tunic=Túnica de Couro +Iron Chestplate=Peitoral de Ferro +Golden Chestplate=Peitoral de Ouro +Diamond Chestplate=Peitoral de Diamante +Chain Chestplate=Peitoral de Cota de Malha +Netherite Chestplate=Peitoral de Netherite +Leather Pants=Calças de Couro +Iron Leggings=Perneiras de Ferro +Golden Leggings=Perneiras de Ouro +Diamond Leggings=Perneiras de Diamante +Chain Leggings=Perneiras de Cota de Malha +Netherite Leggings=Perneiras de Netherite +Leather Boots=Botas de Couro +Iron Boots=Botas de Ferro +Golden Boots=Botas de Ouro +Diamond Boots=Botas de Diamante +Chain Boots=Botas de Cota de Malha +Netherite Boots=Botas de Netherite +Elytra=Elytra + +#Translations of enchantements +Increases underwater mining speed.=Aumenta a velocidade de mineração subaquática. +Blast Protection=Proteção Contra Explosão +Reduces explosion damage and knockback.=Reduz o dano e recúo de explosões. +Curse of Binding=Maldição do Vínculo +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Item não pode ser removido do espaço de armadura, exceto devido à morte, quebra ou no Modo Criativo. +Feather Falling=Pena Caindo +Reduces fall damage.=Reduz o dano de quedas. +Fire Protection=Proteçao Contra Fogo +Reduces fire damage.=Reduz o dano causado por fogo. +Shooting consumes no regular arrows.=Disparar não consome flechas normais. +Shoot 3 arrows at the cost of one.=Dispare 3 flechas ao custo de uma. +Projectile Protection=Proteção Contra Projéteis +Reduces projectile damage.=Reduz o dano causado por projéteis. +Protection=Proteção +Reduces most types of damage by 4% for each level.=Reduz a maioria dos tipos de dano por 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 tomado aos custos de reduzir a durabilidade com cada uso. +Aqua Affinity=Afinidade Aqua diff --git a/mods/ITEMS/mcl_armor/locale/mcl_armor.zh_TW.tr b/mods/ITEMS/mcl_armor/locale/mcl_armor.zh_TW.tr new file mode 100644 index 000000000..1dca10757 --- /dev/null +++ b/mods/ITEMS/mcl_armor/locale/mcl_armor.zh_TW.tr @@ -0,0 +1,23 @@ +# 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=皮革帽子 +Iron Helmet=鐵製頭盔 +Golden Helmet=黃金頭盔 +Diamond Helmet=鑽石頭盔 +Chain Helmet=鎖鏈頭盔 +Leather Tunic=皮革上衣 +Iron Chestplate=鐵製胸甲 +Golden Chestplate=黃金胸甲 +Diamond Chestplate=鑽石胸甲 +Chain Chestplate=鎖鏈胸甲 +Leather Pants=皮革褲子 +Iron Leggings=鐵製護腿 +Golden Leggings=黃金護腿 +Diamond Leggings=鑽石護腿 +Chain Leggings=鎖鏈護腿 +Leather Boots=皮革靴子 +Iron Boots=鐵製靴子 +Golden Boots=黃金靴子 +Diamond Boots=鑽石靴子 +Chain Boots=鎖鏈靴子 diff --git a/mods/ITEMS/mcl_armor/locale/template.txt b/mods/ITEMS/mcl_armor/locale/template.txt index 8a95fca02..4b4ad8385 100644 --- a/mods/ITEMS/mcl_armor/locale/template.txt +++ b/mods/ITEMS/mcl_armor/locale/template.txt @@ -6,18 +6,43 @@ Iron Helmet= Golden Helmet= Diamond Helmet= Chain Helmet= +Netherite Helmet= Leather Tunic= Iron Chestplate= Golden Chestplate= Diamond Chestplate= Chain Chestplate= +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=Malédiction du lien éternel +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.= +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.= +Aqua Affinity= \ No newline at end of file diff --git a/mods/ITEMS/mcl_armor/mod.conf b/mods/ITEMS/mcl_armor/mod.conf new file mode 100644 index 000000000..fad2e494c --- /dev/null +++ b/mods/ITEMS/mcl_armor/mod.conf @@ -0,0 +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 +optional_depends = mcl_fire, ethereal, bakedclay diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d index 0852c4cb1..9c1b290a6 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.b3d differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend index e940742c1..b41b3c575 100644 Binary files a/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend and b/mods/ITEMS/mcl_armor/models/mcl_armor_character.blend differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d new file mode 100644 index 000000000..15a131e94 Binary files /dev/null and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.b3d differ diff --git a/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend new file mode 100644 index 000000000..8c16536b2 Binary files /dev/null and b/mods/ITEMS/mcl_armor/models/mcl_armor_character_female.blend differ diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua new file mode 100644 index 000000000..281839379 --- /dev/null +++ b/mods/ITEMS/mcl_armor/player.lua @@ -0,0 +1,175 @@ +mcl_player.player_register_model("mcl_armor_character.b3d", { + animation_speed = 30, + textures = { + "character.png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + sneak_stand = {x=222, y=302}, + sneak_mine = {x=346, y=365}, + sneak_walk = {x=304, y=323}, + sneak_walk_mine = {x=325, y=344}, + swim_walk = {x=368, y=387}, + swim_walk_mine = {x=389, y=408}, + swim_stand = {x=434, y=434}, + swim_mine = {x=411, y=430}, + run_walk = {x=440, y=459}, + run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, + die = {x=498, y=498}, + fly = {x=502, y=581}, + bow_walk = {x=650, y=670}, + bow_sneak = {x=675, y=695}, + }, +}) + +mcl_player.player_register_model("mcl_armor_character_female.b3d", { + animation_speed = 30, + textures = { + "character.png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + sneak_stand = {x=222, y=302}, + sneak_mine = {x=346, y=365}, + sneak_walk = {x=304, y=323}, + sneak_walk_mine = {x=325, y=344}, + swim_walk = {x=368, y=387}, + swim_walk_mine = {x=389, y=408}, + swim_stand = {x=434, y=434}, + swim_mine = {x=411, y=430}, + run_walk = {x=440, y=459}, + run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, + die = {x=498, y=498}, + fly = {x=502, y=581}, + bow_walk = {x=650, y=670}, + bow_sneak = {x=675, y=695}, + }, +}) + +function mcl_armor.update_player(player, info) + mcl_player.player_set_armor(player, info.texture) + + local meta = player:get_meta() + meta:set_int("mcl_armor:armor_points", info.points) + + mcl_armor.player_view_range_factors[player] = info.view_range_factors +end + +local function is_armor_action(inventory_info) + return inventory_info.from_list == "armor" or inventory_info.to_list == "armor" or inventory_info.listname == "armor" +end + +local function limit_put(player, inventory, index, stack, count) + local def = stack:get_definition() + + if not def then + return 0 + end + + local element = def._mcl_armor_element + + if not element then + return 0 + end + + local element_index = mcl_armor.elements[element].index + + if index ~= 1 and index ~= element_index then + return 0 + end + + local old_stack = inventory:get_stack("armor", element_index) + + if old_stack:is_empty() or index ~= 1 and old_stack:get_name() ~= stack:get_name() and count <= 1 then + return count + else + return 0 + end +end + +local function limit_take(player, inventory, index, stack, count) + if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.is_creative_enabled(player:get_player_name()) then + return 0 + end + + return count +end + +minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info) + if not is_armor_action(inventory_info) then + return + end + + if action == "put" then + return limit_put(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count()) + elseif action == "take" then + return limit_take(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count()) + else + if inventory_info.from_list ~= "armor" then + return limit_put(player, inventory, inventory_info.to_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count) + elseif inventory_info.to_list ~= "armor" then + return limit_take(player, inventory, inventory_info.from_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count) + else + return 0 + end + end +end) + +local function on_put(player, inventory, index, stack) + if index == 1 then + mcl_armor.equip(stack, player) + inventory:set_stack("armor", 1, nil) + else + mcl_armor.on_equip(stack, player) + end +end + +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + if is_armor_action(inventory_info) then + if action == "put" then + on_put(player, inventory, inventory_info.index, inventory_info.stack) + elseif action == "take" then + mcl_armor.on_unequip(inventory_info.stack, player) + else + local stack = inventory:get_stack(inventory_info.to_list, inventory_info.to_index) + if inventory_info.to_list == "armor" then + on_put(player, inventory, inventory_info.to_index, stack) + elseif inventory_info.from_list == "armor" then + mcl_armor.on_unequip(stack, player) + end + end + end +end) + +minetest.register_on_joinplayer(function(player) + player:get_inventory():set_size("armor", 5) + if not minetest.global_exists("mcl_skins") then + mcl_player.player_set_model(player, "mcl_armor_character.b3d") + end + + minetest.after(1, function() + if player:is_player() then + mcl_armor.update(player) + end + end) +end) + +minetest.register_on_leaveplayer(function(player) + mcl_armor.player_view_range_factors[player] = nil +end) diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua new file mode 100644 index 000000000..c7fa91475 --- /dev/null +++ b/mods/ITEMS/mcl_armor/register.lua @@ -0,0 +1,231 @@ +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", + durability = 112, + enchantability = 25, + points = { + head = 2, + torso = 5, + legs = 3, + feet = 1, + }, + craft_material = "mcl_core:gold_ingot", + cook_material = "mcl_core:gold_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", +}) + +mcl_armor.register_set({ + name = "chain", + description = "Chain", + durability = 240, + enchantability = 12, + points = { + head = 2, + torso = 5, + legs = 4, + feet = 1, + }, + repair_material = "mcl_core:iron_ingot", + cook_material = "mcl_core:iron_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", +}) + +mcl_armor.register_set({ + name = "iron", + description = "Iron", + durability = 240, + enchantability = 9, + points = { + head = 2, + torso = 6, + legs = 5, + feet = 2, + }, + craft_material = "mcl_core:iron_ingot", + cook_material = "mcl_core:iron_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", +}) + +mcl_armor.register_set({ + name = "diamond", + description = "Diamond", + durability = 528, + enchantability = 10, + points = { + head = 3, + torso = 8, + legs = 6, + feet = 3, + }, + toughness = 2, + craft_material = "mcl_core:diamond", + sound_equip = "mcl_armor_equip_diamond", + sound_unequip = "mcl_armor_unequip_diamond", + _mcl_upgradable = true, + _mcl_upgrade_item_material = "_netherite", +}) + +mcl_armor.register_set({ + name = "netherite", + description = "Netherite", + durability = 555, + enchantability = 10, + points = { + head = 3, + torso = 8, + legs = 6, + feet = 3, + }, + groups = { fire_immune=1 }, + toughness = 2, + craft_material = "mcl_nether:netherite_ingot", + sound_equip = "mcl_armor_equip_diamond", + sound_unequip = "mcl_armor_unequip_diamond", +}) + +mcl_armor.register_protection_enchantment({ + id = "projectile_protection", + name = S("Projectile Protection"), + description = S("Reduces projectile damage."), + power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}}, + incompatible = {blast_protection = true, fire_protection = true, protection = true}, + factor = 2, + damage_flag = "is_projectile", +}) + +mcl_armor.register_protection_enchantment({ + id = "blast_protection", + name = S("Blast Protection"), + description = S("Reduces explosion damage and knockback."), + power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}}, + weight = 2, + incompatible = {fire_protection = true, protection = true, projectile_protection = true}, + factor = 2, + damage_flag = "is_explosion", +}) + +mcl_armor.register_protection_enchantment({ + id = "fire_protection", + name = S("Fire Protection"), + description = S("Reduces fire damage."), + power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}}, + incompatible = {blast_protection = true, protection = true, projectile_protection = true}, + factor = 2, + damage_flag = "is_fire", +}) + +mcl_armor.register_protection_enchantment({ + id = "protection", + name = S("Protection"), + description = S("Reduces most types of damage by 4% for each level."), + power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}}, + incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true}, + factor = 1, +}) + +mcl_armor.register_protection_enchantment({ + id = "feather_falling", + name = S("Feather Falling"), + description = S("Reduces fall damage."), + power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}}, + factor = 3, + primary = {combat_armor_feet = true}, + damage_type = "fall", +}) + +-- requires engine change +--[[mcl_enchanting.enchantments.aqua_affinity = { + name = S("Aqua Affinity"), + max_level = 1, + primary = {armor_head = true}, + secondary = {}, + disallow = {non_combat_armor = true}, + incompatible = {}, + weight = 2, + description = S("Increases underwater mining speed."), + curse = false, + on_enchant = function() end, + requires_tool = false, + treasure = false, + power_range_table = {{1, 41}}, + inv_combat_tab = true, + inv_tool_tab = false, +}]]-- + +mcl_enchanting.enchantments.curse_of_binding = { + name = S("Curse of Binding"), + max_level = 1, + primary = {}, + secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, + disallow = {}, + incompatible = {}, + weight = 1, + description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."), + curse = true, + on_enchant = function() end, + requires_tool = false, + treasure = true, + power_range_table = {{25, 50}}, + inv_combat_tab = true, + inv_tool_tab = false, +} + +mcl_enchanting.enchantments.thorns = { + name = S("Thorns"), + max_level = 3, + primary = {combat_armor_chestplate = true}, + secondary = {combat_armor = true}, + disallow = {}, + incompatible = {}, + weight = 1, + description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."), + curse = false, + on_enchant = function() end, + requires_tool = false, + treasure = false, + power_range_table = {{10, 61}, {30, 71}, {50, 81}}, + inv_combat_tab = true, + inv_tool_tab = false, +} + +-- Elytra + +minetest.register_tool("mcl_armor:elytra", { + description = S("Elytra"), + _doc_items_longdesc = mcl_armor.longdesc, + _doc_items_usagehelp = mcl_armor.usage, + inventory_image = "mcl_armor_inv_elytra.png", + groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10, enchantability = 1, elytra = 1}, + sounds = { + _mcl_armor_equip = "mcl_armor_equip_leather", + _mcl_armor_unequip = "mcl_armor_unequip_leather", + }, + 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" +}) diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_chain_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_chain_preview.png deleted file mode 100644 index bf028c272..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_chain_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_diamond_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_diamond_preview.png deleted file mode 100644 index 768d7bcde..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_diamond_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_gold_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_gold_preview.png deleted file mode 100644 index f384a602c..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_gold_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_iron_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_iron_preview.png deleted file mode 100644 index 18cecdf55..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_iron_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_leather_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_leather_preview.png deleted file mode 100644 index d0457ce9a..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_leather_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_chain_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_chain_preview.png deleted file mode 100644 index af9c982fe..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_chain_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond.png deleted file mode 100644 index 3679ae6a0..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond_preview.png deleted file mode 100644 index d43b3cede..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_diamond_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_gold_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_gold_preview.png deleted file mode 100644 index 746ddda0a..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_gold_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_iron_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_iron_preview.png deleted file mode 100644 index 200e51d9c..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_iron_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather.png deleted file mode 100644 index eaa53582f..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather_preview.png deleted file mode 100644 index 9d5a5a097..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_leather_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_chain_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_chain_preview.png deleted file mode 100644 index c76cd9d61..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_chain_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_diamond_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_diamond_preview.png deleted file mode 100644 index 1b8c5b117..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_diamond_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_gold_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_gold_preview.png deleted file mode 100644 index 4201916ca..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_gold_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_iron_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_iron_preview.png deleted file mode 100644 index 00584e8de..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_iron_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_leather_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_leather_preview.png deleted file mode 100644 index 9f27bacb5..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_leather_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_chain.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_chain.png deleted file mode 100644 index 66f9bdce5..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_chain.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png deleted file mode 100644 index dc452d413..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_gold.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_chain.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_chain.png deleted file mode 100644 index 9ab14863f..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_chain.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_chain.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_chain.png deleted file mode 100644 index f72a88da2..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_chain.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_chain.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_chain.png deleted file mode 100644 index c2641991e..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_chain.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_leather.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_leather.png deleted file mode 100644 index 41d49c373..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_leather.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_chain_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_chain_preview.png deleted file mode 100644 index 06a29c3c7..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_chain_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_diamond_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_diamond_preview.png deleted file mode 100644 index cbc9e032c..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_diamond_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_gold_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_gold_preview.png deleted file mode 100644 index 449eb5e1a..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_gold_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_iron_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_iron_preview.png deleted file mode 100644 index 452447fd7..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_iron_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_leather_preview.png b/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_leather_preview.png deleted file mode 100644 index 6c032d690..000000000 Binary files a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_leather_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_armor_stand/depends.txt b/mods/ITEMS/mcl_armor_stand/depends.txt deleted file mode 100644 index 02ce27d73..000000000 --- a/mods/ITEMS/mcl_armor_stand/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_armor -mcl_core -mcl_sounds -mcl_stairs -screwdriver? diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index c451b6de1..e23aba6b6 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -1,84 +1,41 @@ -local S = minetest.get_translator("mcl_armor_stand") +local S = minetest.get_translator(minetest.get_current_modname()) -local elements = {"head", "torso", "legs", "feet"} - -local function get_stand_object(pos) - local object = nil - local objects = minetest.get_objects_inside_radius(pos, 0.5) or {} - for _, obj in pairs(objects) do - local ent = obj:get_luaentity() - if ent then - if ent.name == "mcl_armor_stand:armor_entity" then - -- Remove duplicates - if object then - obj:remove() - else - object = obj - end - end - end - end - return object +-- Spawn a stand entity +local function spawn_stand_entity(pos, node) + local luaentity = minetest.add_entity(pos, "mcl_armor_stand:armor_entity"):get_luaentity() + luaentity:update_rotation(node or minetest.get_node(pos)) + return luaentity end -local function update_entity(pos) - local node = minetest.get_node(pos) - local object = get_stand_object(pos) - if object then - if not string.find(node.name, "mcl_armor_stand:") then - object:remove() - return +-- Find a stand entity or spawn one +local function get_stand_entity(pos, node) + for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_armor_stand:armor_entity" then + return luaentity end - else - object = minetest.add_entity(pos, "mcl_armor_stand:armor_entity") end - if object then - local texture = "blank.png" - local textures = {} - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local yaw = 0 - if inv then - for _, element in pairs(elements) do - local stack = inv:get_stack("armor_"..element, 1) - if stack:get_count() == 1 then - local item = stack:get_name() or "" - if minetest.registered_aliases[item] then - item = minetest.registered_aliases[item] - end - local def = stack:get_definition() or {} - local groups = def.groups or {} - if groups["armor_"..element] then - local texture = def.texture or item:gsub("%:", "_") - table.insert(textures, texture..".png") - end - end - end + return spawn_stand_entity(pos, node) +end + +-- Migrate the old inventory format +local function migrate_inventory(inv) + inv:set_size("armor", 5) + local lists = inv:get_lists() + for name, element in pairs(mcl_armor.elements) do + local listname = "armor_" .. name + local list = lists[listname] + if list then + inv:set_stack("armor", element.index, list[1]) + inv:set_size(listname, 0) end - if #textures > 0 then - texture = table.concat(textures, "^") - end - if node.param2 then - local rot = node.param2 % 4 - if rot == 1 then - yaw = 3 * math.pi / 2 - elseif rot == 2 then - yaw = math.pi - elseif rot == 3 then - yaw = math.pi / 2 - end - end - object:set_yaw(yaw) - object:set_properties({textures={texture}}) end end --- Drop all armor of the armor stand on the ground -local drop_armor = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - for _, element in pairs(elements) do - local stack = inv:get_stack("armor_"..element, 1) +-- Drop all armor on the ground when it got destroyed +local function drop_inventory(pos) + local inv = minetest.get_meta(pos):get_inventory() + for _, stack in pairs(inv:get_list("armor")) do 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) @@ -94,8 +51,8 @@ minetest.register_node("mcl_armor_stand:armor_stand", { _doc_items_usagehelp = S("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."), drawtype = "mesh", mesh = "3d_armor_stand.obj", - inventory_image = "3d_armor_stand_item.png", - wield_image = "3d_armor_stand_item.png", + inventory_image = "mcl_armor_stand_item.png", + wield_image = "mcl_armor_stand_item.png", tiles = {"default_wood.png", "mcl_stairs_stone_slab_top.png"}, paramtype = "light", paramtype2 = "facedir", @@ -111,136 +68,26 @@ minetest.register_node("mcl_armor_stand:armor_stand", { _mcl_hardness = 2, sounds = mcl_sounds.node_sound_wood_defaults(), on_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - for _, element in pairs(elements) do - inv:set_size("armor_"..element, 1) - end + spawn_stand_entity(pos) + end, + on_destruct = function(pos) + drop_inventory(pos) end, - -- Drop all armor on the ground when it got destroyed - on_destruct = drop_armor, - -- Put piece of armor on armor stand, or take one away on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local protname = clicker:get_player_name() + if minetest.is_protected(pos, protname) then minetest.record_protection_violation(pos, protname) return itemstack end - local inv = minetest.get_inventory({type = "node", pos = pos}) - if not inv then - return itemstack - end - - -- Check if player wields armor - local name = itemstack:get_name() - local list - for e=1, #elements do - local g = minetest.get_item_group(name, "armor_" .. elements[e]) - if g ~= nil and g ~= 0 then - list = "armor_" .. elements[e] - break - end - end - -- If player wields armor, put it on armor stand - local wielditem = clicker:get_wielded_item() - if list then - -- ... but only if the slot is free - local single_item = ItemStack(itemstack) - single_item:set_count(1) - if inv:is_empty(list) then - inv:add_item(list, single_item) - armor:play_equip_sound(single_item, nil, pos) - update_entity(pos) - itemstack:take_item() - return itemstack - end - end - - -- Take armor from stand if player has a free hand or wields the same armor type (if stackable) - for e=1, #elements do - local stand_armor = inv:get_stack("armor_" .. elements[e], 1) - if not stand_armor:is_empty() then - local pinv = clicker:get_inventory() - local taken = false - -- Empty hand - if wielditem:get_name() == "" then - pinv:set_stack("main", clicker:get_wield_index(), stand_armor) - taken = true - -- Stackable armor type (if not already full). This is the case for e.g. mob heads. - -- This is done purely for convenience. - elseif (wielditem:get_name() == stand_armor:get_name() and wielditem:get_count() < wielditem:get_stack_max()) then - wielditem:set_count(wielditem:get_count()+1) - pinv:set_stack("main", clicker:get_wield_index(), wielditem) - taken = true - end - if taken then - armor:play_equip_sound(stand_armor, nil, pos, true) - stand_armor:take_item() - inv:set_stack("armor_" .. elements[e], 1, stand_armor) - end - update_entity(pos) - return clicker:get_wielded_item() - end - end - update_entity(pos) - return itemstack - end, - after_place_node = function(pos) - minetest.add_entity(pos, "mcl_armor_stand:armor_entity") - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - end - local def = stack:get_definition() or {} - local groups = def.groups or {} - if groups[listname] then - return 1 - end - return 0 - end, - allow_metadata_inventory_move = function() - return 0 - end, - on_metadata_inventory_put = function(pos) - update_entity(pos) - end, - on_metadata_inventory_take = function(pos) - update_entity(pos) - end, - after_destruct = function(pos) - update_entity(pos) - end, - on_blast = function(pos, _, do_drop) - local object = get_stand_object(pos) - if object then - object:remove() - end - minetest.after(1, function(pos) - update_entity(pos) - end, pos) - minetest.remove_node(pos) - if do_drop then - minetest.add_item(pos, "mcl_armor_stand:armor_stand") - end + return mcl_armor.equip(itemstack, get_stand_entity(pos, node).object, true) end, on_rotate = function(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then node.param2 = (node.param2 + 1) % 4 minetest.swap_node(pos, node) - update_entity(pos) + get_stand_entity(pos, node):update_rotation(node) return true end return false @@ -248,50 +95,44 @@ minetest.register_node("mcl_armor_stand:armor_stand", { }) minetest.register_entity("mcl_armor_stand:armor_entity", { - physical = true, - visual = "mesh", - mesh = "3d_armor_entity.obj", - visual_size = {x=1, y=1}, - collisionbox = {-0.1,-0.4,-0.1, 0.1,1.3,0.1}, - pointable = false, - textures = {"blank.png"}, - pos = nil, - timer = 0, + initial_properties = { + physical = true, + visual = "mesh", + mesh = "3d_armor_entity.obj", + visual_size = {x=1, y=1}, + collisionbox = {-0.1,-0.4,-0.1, 0.1,1.3,0.1}, + pointable = false, + textures = {"blank.png"}, + timer = 0, + static_save = false, + }, on_activate = function(self) - local pos = self.object:get_pos() - self.object:set_armor_groups({immortal=1}) - if pos then - self.pos = vector.round(pos) - update_entity(pos) - end + self.object:set_armor_groups({immortal = 1}) + self.node_pos = vector.round(self.object:get_pos()) + self.inventory = minetest.get_meta(self.node_pos):get_inventory() + migrate_inventory(self.inventory) + mcl_armor.update(self.object) end, on_step = function(self, dtime) - if not self.pos then - return - end - self.timer = self.timer + dtime - if self.timer > 1 then - self.timer = 0 - local pos = self.object:get_pos() - if pos then - if vector.equals(vector.round(pos), self.pos) then - return - end - end - update_entity(self.pos) + if minetest.get_node(self.node_pos).name ~= "mcl_armor_stand:armor_stand" then self.object:remove() end end, + update_armor = function(self, info) + self.object:set_properties({textures = {info.texture}}) + end, + update_rotation = function(self, node) + self.object:set_yaw(minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2))) + end, }) --- FIXME: Armor helper entity can get destroyed by /clearobjects minetest.register_lbm({ label = "Respawn armor stand entities", name = "mcl_armor_stand:respawn_entities", nodenames = {"mcl_armor_stand:armor_stand"}, run_at_every_load = true, action = function(pos, node) - update_entity(pos, node) + spawn_stand_entity(pos, node) end, }) @@ -304,7 +145,6 @@ minetest.register_craft({ } }) - -- Legacy handling minetest.register_alias("3d_armor_stand:armor_stand", "mcl_armor_stand:armor_stand") minetest.register_entity(":3d_armor_stand:armor_entity", { diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.dk.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.dk.tr new file mode 100644 index 000000000..72056e26a --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.dk.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_armor_stand +Armor Stand=Rustningsstativ +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.=Et rustningsstativ er en udsmykningsgenstand som kan fremvise forskellige rustninger. Alt hvad spillere kan bære som rusning kan sættes på rustningsstativet. +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.=Placér blot et rustningsstykke på rustningsstativet. For at take den øverste rustningsstykke skal du vælge din hånd og bruge placér knappen på rustningsstativet. +Displays pieces of armor=Fremviser rustningsstykker. diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.fr.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.fr.tr index 867b3f043..b52038fe7 100644 --- a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.fr.tr +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.fr.tr @@ -2,4 +2,4 @@ Armor Stand=Support d'armure 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.=Un support d'armure est un objet décoratif qui peut afficher différentes pièces d'armure. Tout ce que les joueurs peuvent porter comme armure peut également être placé sur un support d'armure. 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.=Placez simplement un objet d'armure sur le support d'armure. Pour prendre la pièce d'armure du support d'armure, sélectionnez votre main et utilisez la touche "Placer" sur le support d'armure. -Displays pieces of armor=Displays pieces of armor +Displays pieces of armor=Expose des pièces d'armure diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr new file mode 100644 index 000000000..4f2892d2c --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.ja.tr @@ -0,0 +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=防具を個々に展示 diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pl.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pl.tr new file mode 100644 index 000000000..cc134a2f0 --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pl.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_armor_stand +Armor Stand=Stojak na zbroję +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.=Stojak na zbroję jest obiektem dekoracyjnym, na którym można wystawiać różne części zbroi. Cokolwiek co może być noszone przez gracza jako zbroja, może być wystawione na stojaku na zbroję. +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.=Aby to zrobić po prostu postaw przedmiot zbroi na stojaku. Aby wziąć górną część zbroi ze stojaka wybierz swoją dłoń i kliknij przycisk użyj na stojaku. +Displays pieces of armor=Prezentuje części zbroi + diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pt_BR.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pt_BR.tr new file mode 100644 index 000000000..2b80c0597 --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_armor_stand +Armor Stand=Suporte de Armadura +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.=O suporte de armadura é um objeto decorativo que pode exibir diferentes partes de armadura. Qualquer coisa que o jogador pode vestir como armadura também pode ser colocado no suporte de armadura. +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.=Apenas coloque um item de armadura no suporte de armadura. Para retirar a peça de armadura superior do suporte de armadura, selecione suas mãos e aperte o botão de colocar no suporte de armadura. +Displays pieces of armor=Exibe peças de armadura diff --git a/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.zh_TW.tr b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.zh_TW.tr new file mode 100644 index 000000000..d5d107e55 --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/locale/mcl_armor_stand.zh_TW.tr @@ -0,0 +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=展示盔甲 diff --git a/mods/ITEMS/mcl_armor_stand/mod.conf b/mods/ITEMS/mcl_armor_stand/mod.conf new file mode 100644 index 000000000..eb803dc56 --- /dev/null +++ b/mods/ITEMS/mcl_armor_stand/mod.conf @@ -0,0 +1,5 @@ +name = mcl_armor_stand +author = stujones11 +description = Adds an armor stand for armor storage and display. +depends = mcl_armor, mcl_core, mcl_sounds, mcl_stairs +optional_depends = screwdriver diff --git a/mods/ITEMS/mcl_armor_stand/models/3d_armor_entity.obj b/mods/ITEMS/mcl_armor_stand/models/3d_armor_entity.obj index 052f69255..37bc521e9 100644 --- a/mods/ITEMS/mcl_armor_stand/models/3d_armor_entity.obj +++ b/mods/ITEMS/mcl_armor_stand/models/3d_armor_entity.obj @@ -1,79 +1,132 @@ -# Blender v2.73 (sub 0) OBJ File: '3d_armor_entity_3.blend' +# Blender v2.92.0 OBJ File: '' # www.blender.org mtllib 3d_armor_entity.mtl +o Cube +v 1.000000 1.000000 -1.000000 +v 1.000000 -1.000000 -1.000000 +v 1.000000 1.000000 1.000000 +v 1.000000 -1.000000 1.000000 +v -1.000000 1.000000 -1.000000 +v -1.000000 -1.000000 -1.000000 +v -1.000000 1.000000 1.000000 +v -1.000000 -1.000000 1.000000 +vt 0.625000 0.500000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.625000 0.750000 +vt 0.375000 0.750000 +vt 0.625000 1.000000 +vt 0.375000 1.000000 +vt 0.375000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.250000 +vt 0.375000 0.250000 +vt 0.125000 0.500000 +vt 0.375000 0.500000 +vt 0.125000 0.750000 +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 +usemtl Material +s off +f 1/1/1 5/2/1 7/3/1 3/4/1 +f 4/5/2 3/4/2 7/6/2 8/7/2 +f 8/8/3 7/9/3 5/10/3 6/11/3 +f 6/12/4 2/13/4 4/5/4 8/14/4 +f 2/13/5 1/1/5 3/4/5 4/5/5 +f 6/11/6 5/10/6 1/1/6 2/13/6 o Player_Cube -v 2.200000 9.763893 1.200000 -v 2.200000 9.763893 -1.200000 +v 2.200000 9.763893 1.200001 v 2.200000 2.663871 1.200000 v 2.200000 2.663871 -1.200000 +v 2.200000 9.763893 -1.200000 v -2.200000 9.763893 -1.200000 -v -2.200000 9.763893 1.200000 -v -2.200000 2.663871 -1.200000 +v -2.200000 9.763893 1.200001 v -2.200000 2.663871 1.200000 -v 2.300000 13.863962 2.300000 -v 2.300000 13.863962 -2.300000 +v -2.200000 2.663871 -1.200000 +v 2.300000 13.863962 2.300001 v 2.300000 9.263885 2.300000 -v 2.300000 9.263885 -2.300000 -v -2.300000 13.863962 -2.300000 -v -2.300000 13.863962 2.300000 -v -2.300000 9.263885 -2.300000 +v 2.300000 9.263885 -2.299999 +v 2.300000 13.863962 -2.299999 +v -2.300000 13.863962 -2.299999 +v -2.300000 13.863962 2.300001 v -2.300000 9.263885 2.300000 +v -2.300000 9.263885 -2.299999 v -2.322686 2.473175 -1.300000 v -2.322686 2.473175 1.300000 v -4.713554 2.682348 1.300000 v -4.713554 2.682348 -1.300000 -v -1.686446 9.745432 -1.300000 -v -1.686446 9.745432 1.300000 +v -4.077313 9.954605 -1.299999 v -4.077313 9.954605 1.300000 -v -4.077313 9.954605 -1.300000 -v 4.077313 9.954605 -1.300000 -v 4.077313 9.954605 1.300000 +v -1.686446 9.745432 1.300000 +v -1.686446 9.745432 -1.299999 v 1.686446 9.745432 1.300000 -v 1.686446 9.745432 -1.300000 -v 4.713554 2.682348 -1.300000 -v 4.713554 2.682348 1.300000 v 2.322686 2.473175 1.300000 +v 4.713554 2.682348 1.300000 +v 4.077313 9.954605 1.300000 +v 1.686446 9.745432 -1.299999 v 2.322686 2.473175 -1.300000 +v 4.077313 9.954605 -1.299999 +v 4.713554 2.682348 -1.300000 +v 2.538733 2.980834 -1.210000 v 0.139099 2.938947 -1.200000 v 0.139099 2.938947 1.200000 -v 0.261266 -4.059988 1.200000 -v 0.261266 -4.059988 -1.200000 -v 2.660901 -4.018101 1.190000 -v 2.660901 -4.018101 -1.210000 v 2.538733 2.980834 1.190000 -v 2.538733 2.980834 -1.210000 -v -0.139099 2.938947 -1.200000 -v -0.139099 2.938947 1.200000 -v -0.261266 -4.059988 1.200000 -v -0.261266 -4.059988 -1.200000 +v 0.261266 -4.059988 -1.200000 +v 2.660901 -4.018101 -1.210000 +v 2.660901 -4.018101 1.190000 +v 0.261266 -4.059988 1.200000 v -2.538734 2.980834 -1.210000 v -2.538734 2.980834 1.190000 +v -0.139099 2.938947 1.200000 +v -0.139099 2.938947 -1.200000 +v -0.261266 -4.059988 1.200000 +v -0.261266 -4.059988 -1.200000 v -2.660901 -4.018101 -1.210000 v -2.660901 -4.018101 1.190000 +v 0.000000 -4.387500 -1.400000 +v 0.000000 -4.387500 1.400000 v -2.799999 -4.387500 1.390000 v -2.799999 -4.387500 -1.410000 v -2.800000 -0.812499 1.390000 v -2.800000 -0.812499 -1.410000 -v -0.000000 -4.387500 -1.400000 -v -0.000000 -4.387500 1.400000 -v -0.000000 -0.812499 1.400000 -v -0.000000 -0.812499 -1.400000 -v 2.800000 -0.812499 -1.410000 -v 2.800000 -0.812499 1.390000 -v 2.799999 -4.387500 -1.410000 -v 2.799999 -4.387500 1.390000 +v 0.000000 -0.812499 1.400000 +v 0.000000 -0.812499 -1.400000 +v 0.000000 -0.812499 -1.400000 v 0.000000 -4.387500 -1.400000 v 0.000000 -4.387500 1.400000 v 0.000000 -0.812499 1.400000 -v 0.000000 -0.812499 -1.400000 -v 2.267006 13.830965 2.267006 -v 2.267006 13.830965 -2.267006 +v 2.800000 -0.812499 -1.410000 +v 2.799999 -4.387500 -1.410000 +v 2.799999 -4.387500 1.390000 +v 2.800000 -0.812499 1.390000 +v 2.267006 13.830965 2.267007 +v 2.267006 13.830965 -2.267005 +v 2.267006 9.296881 -2.267005 v 2.267006 9.296881 2.267006 -v 2.267006 9.296881 -2.267006 -v -2.267006 13.830965 -2.267006 -v -2.267006 13.830965 2.267006 -v -2.267006 9.296881 -2.267006 +v -2.267006 13.830965 -2.267005 +v -2.267006 13.830965 2.267007 +v -2.267006 9.296881 -2.267005 v -2.267006 9.296881 2.267006 +v -4.168111 10.060661 1.681621 +v 1.741822 -5.305762 4.169018 +v 1.718504 -5.438008 3.407457 +v -6.641035 -3.963995 3.407457 +v 4.191429 8.586647 1.681621 +v -6.617718 -3.831752 4.169018 +v 4.168111 8.454401 0.920061 +v -4.191429 9.928415 0.920061 +v -4.191429 8.586648 1.681620 +v 6.617716 -3.831752 4.169018 +v 6.641035 -3.963997 3.407457 +v -1.718504 -5.438006 3.407457 +v 4.168111 10.060658 1.681621 +v -1.741822 -5.305762 4.169018 +v 4.191429 9.928414 0.920061 +v -4.168111 8.454404 0.920061 vt 0.250000 0.375000 vt 0.250000 0.000000 vt 0.312500 0.000000 @@ -81,6 +134,8 @@ vt 0.312500 0.375000 vt 0.437500 0.375000 vt 0.437500 0.500000 vt 0.312500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 vt 0.562500 0.375000 vt 0.562500 0.500000 vt 0.437500 0.000000 @@ -97,97 +152,308 @@ vt 0.750000 1.000000 vt 0.625000 1.000000 vt 0.875000 0.750000 vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 vt 0.750000 0.500000 +vt 0.875000 0.750000 vt 0.875000 0.500000 vt 1.000000 0.750000 vt 1.000000 0.500000 vt 0.750000 0.375000 +vt 0.750000 0.500000 vt 0.812500 0.500000 vt 0.812500 0.375000 vt 0.687500 0.375000 vt 0.687500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.375000 +vt 0.687500 0.375000 +vt 0.625000 0.375000 +vt 0.625000 0.000000 vt 0.687500 0.000000 vt 0.750000 0.000000 +vt 0.687500 0.000000 +vt 0.812500 0.375000 vt 0.812500 0.000000 vt 0.875000 0.375000 vt 0.875000 0.000000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.875000 0.000000 +vt 0.875000 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.000000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 vt 0.125000 0.375000 vt 0.062500 0.375000 vt 0.062500 0.500000 vt 0.125000 0.500000 vt 0.187500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 vt 0.187500 0.500000 vt 0.000000 0.375000 vt 0.000000 0.000000 vt 0.062500 0.000000 +vt 0.062500 0.375000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.187500 0.000000 +vt 0.187500 0.375000 +vt 0.125000 0.000000 +vt 0.062500 0.000000 +vt 0.187500 0.375000 vt 0.187500 0.000000 vt 0.125000 0.000000 -vt 0.437500 0.875000 -vt 0.437500 1.000000 -vt 0.375000 1.000000 -vt 0.375000 0.875000 -vt 0.250000 0.875000 -vt 0.312500 0.875000 -vt 0.312500 0.656250 -vt 0.250000 0.656250 -vt 0.500000 0.875000 -vt 0.437500 0.656250 -vt 0.500000 0.656250 -vt 0.375000 0.656250 -vt 0.312500 1.000000 -usemtl Armor +vt 0.125000 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.062500 0.500000 +vt 0.062500 0.375000 +vt 0.187500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.000000 +vt 0.125000 0.000000 +vt 0.250000 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.000000 +vt 0.250000 0.000000 +vt 0.000000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.000000 0.000000 +vt 0.187500 0.375000 +vt 0.187500 0.500000 +vt 0.125000 0.500000 +vt 0.125000 0.375000 +vt 0.381250 0.832812 +vt 0.381250 0.845312 +vt 0.375000 0.845312 +vt 0.375000 0.832812 +vt 0.362500 0.832812 +vt 0.368750 0.832812 +vt 0.368750 0.810938 +vt 0.362500 0.810938 +vt 0.387500 0.832812 +vt 0.381250 0.832812 +vt 0.381250 0.810938 +vt 0.387500 0.810938 +vt 0.375000 0.832812 +vt 0.368750 0.832812 +vt 0.368750 0.810938 +vt 0.375000 0.810938 +vt 0.381250 0.832812 +vt 0.375000 0.832812 +vt 0.375000 0.810938 +vt 0.381250 0.810938 +vt 0.375000 0.845312 +vt 0.368750 0.845312 +vt 0.381250 0.832812 +vt 0.381250 0.810938 +vt 0.375000 0.810938 +vt 0.375000 0.832812 +vt 0.375000 0.832812 +vt 0.375000 0.810938 +vt 0.368750 0.810938 +vt 0.368750 0.832812 +vt 0.387500 0.832812 +vt 0.387500 0.810938 +vt 0.381250 0.810938 +vt 0.381250 0.832812 +vt 0.362500 0.832812 +vt 0.362500 0.810938 +vt 0.368750 0.810938 +vt 0.368750 0.832812 +vt 0.381250 0.832812 +vt 0.375000 0.832812 +vt 0.375000 0.845312 +vt 0.381250 0.845312 +vt 0.368750 0.845312 +vt 0.375000 0.845312 +vt 0.500000 0.750000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.500000 +vt 0.750000 0.750000 +vt 0.625000 1.000000 +vt 0.750000 1.000000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.875000 1.000000 +vt 0.750000 0.500000 +vt 0.875000 0.750000 +vt 0.875000 0.500000 +vt 1.000000 0.750000 +vt 1.000000 0.500000 +vt 0.032859 0.558649 +vt 0.032859 0.998468 +vt 0.362724 0.998468 +vt 0.362724 0.558649 +vt 0.032859 0.558649 +vt 0.362724 0.558649 +vt 0.362724 0.998468 +vt 0.032859 0.998468 +vt 0.039157 0.992309 +vt 0.039157 0.656118 +vt 0.060169 0.656118 +vt 0.060169 0.992309 +vt -0.003415 0.501261 +vt 0.368238 0.501261 +vt 0.368238 0.563203 +vt -0.003415 0.563203 +vt 0.368238 0.996797 +vt -0.003415 0.996797 +vt -0.003415 0.934855 +vt 0.368238 0.934855 +vt 0.394691 0.498800 +vt 0.394691 0.994336 +vt 0.363720 0.994336 +vt 0.363720 0.498800 +vt 0.032859 0.998468 +vt 0.032859 0.558649 +vt 0.362724 0.558649 +vt 0.362724 0.998468 +vt 0.032859 0.998468 +vt 0.362724 0.998468 +vt 0.362724 0.558649 +vt 0.032859 0.558649 +vt 0.039157 0.656118 +vt 0.039157 0.992309 +vt 0.060169 0.992309 +vt 0.060169 0.656118 +vt -0.003415 0.996797 +vt 0.368238 0.996797 +vt 0.368238 0.934855 +vt -0.003415 0.934855 +vt 0.368238 0.501261 +vt -0.003415 0.501261 +vt -0.003415 0.563203 +vt 0.368238 0.563203 +vt 0.394691 0.994336 +vt 0.394691 0.498800 +vt 0.363720 0.498800 +vt 0.363720 0.994336 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -1.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.0872 -0.9962 0.0000 +vn 0.0872 0.9962 0.0000 +vn -0.9962 0.0872 0.0000 +vn 0.9962 -0.0872 0.0000 +vn -0.9962 -0.0872 0.0000 +vn 0.9962 0.0872 0.0000 +vn -0.0872 0.9962 0.0000 +vn 0.0872 -0.9962 0.0000 +vn -0.0175 0.9998 0.0000 +vn 0.0175 -0.9998 0.0000 +vn 0.9998 0.0175 0.0000 +vn 0.0042 0.0001 1.0000 +vn -0.0042 -0.0001 -1.0000 +vn -0.9998 -0.0175 0.0000 +vn 0.0175 0.9998 0.0000 +vn 0.9998 -0.0175 0.0000 +vn 0.0042 -0.0001 -1.0000 +vn -0.0042 0.0001 1.0000 +vn -0.9998 0.0175 0.0000 +vn -0.0175 -0.9998 0.0000 +vn -0.0036 -0.0000 1.0000 +vn 0.0036 0.0000 -1.0000 +vn -0.0036 0.0000 -1.0000 +vn 0.0036 -0.0000 1.0000 +vn 0.0302 0.1710 0.9848 +vn -0.0302 -0.1710 -0.9848 +vn 0.1710 0.9698 -0.1737 +vn 0.9848 -0.1736 0.0000 +vn -0.9848 0.1736 -0.0000 +vn -0.1710 -0.9698 0.1736 +vn -0.0302 0.1710 0.9848 +vn 0.0302 -0.1710 -0.9848 +vn -0.1710 0.9698 -0.1736 +vn 0.9848 0.1736 0.0000 +vn -0.9848 -0.1736 -0.0000 +vn 0.1710 -0.9698 0.1736 +usemtl None s off -f 1/1 3/2 4/3 2/4 -f 5/5 6/6 1/7 2/4 -f 8/6 7/5 4/8 3/9 -f 5/5 2/4 4/3 7/10 -f 7/10 8/11 6/12 5/5 -f 8/11 3/13 1/14 6/12 -f 9/15 11/16 12/17 10/18 -f 13/19 14/20 9/21 10/18 -f 12/22 11/23 16/20 15/19 -f 13/19 10/18 12/17 15/24 -f 14/22 13/19 15/24 16/25 -f 9/26 14/22 16/25 11/27 -f 17/28 18/24 19/29 20/30 -f 24/31 23/32 22/24 21/28 -f 23/31 24/14 20/13 19/33 -f 24/31 21/28 17/34 20/33 -f 21/28 22/30 18/35 17/34 -f 22/30 23/36 19/37 18/35 -f 27/30 31/35 30/37 26/36 -f 28/28 32/34 31/35 27/30 -f 25/31 29/33 32/34 28/28 -f 26/31 30/33 29/13 25/14 -f 25/31 28/28 27/24 26/32 -f 32/28 29/30 30/29 31/24 -f 40/38 33/39 34/40 39/41 -f 36/42 38/38 37/41 35/43 -f 39/44 37/45 38/46 40/39 -f 34/1 35/2 37/47 39/42 -f 40/38 38/48 36/46 33/39 -f 33/42 36/47 35/48 34/38 -f 45/38 46/41 42/40 41/39 -f 41/42 42/38 43/48 44/47 -f 45/38 41/39 44/46 47/48 -f 42/1 46/42 48/47 43/2 -f 46/44 45/39 47/46 48/45 -f 44/42 43/43 48/41 47/38 -f 53/49 54/50 49/51 50/52 -f 51/53 52/54 50/55 49/56 -f 55/57 51/49 49/58 54/59 -f 52/52 56/54 53/55 50/60 -f 56/49 55/52 54/60 53/58 -f 52/52 51/51 55/61 56/54 -f 64/49 61/58 62/60 63/52 -f 57/52 59/60 61/55 64/54 -f 63/57 62/59 60/58 58/49 -f 58/53 60/56 59/55 57/54 -f 61/49 59/52 60/51 62/50 -f 57/52 64/54 63/61 58/51 -f 65/15 66/18 68/17 67/16 -f 69/19 66/18 65/21 70/20 -f 68/22 71/19 72/20 67/23 -f 69/19 71/24 68/17 66/18 -f 70/22 72/25 71/24 69/19 -f 65/26 67/27 72/25 70/22 +f 9/15/7 10/16/7 11/17/7 12/18/7 +f 13/19/8 14/20/8 9/21/8 12/18/8 +f 15/22/9 16/23/9 11/24/9 10/25/9 +f 13/19/10 12/18/10 11/17/10 16/26/10 +f 16/26/11 15/27/11 14/28/11 13/19/11 +f 15/27/12 10/29/12 9/30/12 14/28/12 +f 17/31/7 18/32/7 19/33/7 20/34/7 +f 21/35/8 22/36/8 17/37/8 20/34/8 +f 19/38/9 18/39/9 23/40/9 24/41/9 +f 21/35/10 20/34/10 19/33/10 24/42/10 +f 22/43/11 21/35/11 24/42/11 23/44/11 +f 17/45/12 22/43/12 23/44/12 18/46/12 +f 25/47/13 26/48/13 27/49/13 28/50/13 +f 29/51/14 30/52/14 31/53/14 32/54/14 +f 30/55/15 29/56/15 28/57/15 27/58/15 +f 29/51/10 32/54/10 25/59/10 28/60/10 +f 32/54/16 31/61/16 26/62/16 25/59/16 +f 31/61/12 30/63/12 27/64/12 26/62/12 +f 33/65/12 34/66/12 35/67/12 36/68/12 +f 37/69/17 38/70/17 34/66/17 33/65/17 +f 39/71/10 40/72/10 38/70/10 37/69/10 +f 36/73/18 35/74/18 40/75/18 39/76/18 +f 39/71/19 37/69/19 33/77/19 36/78/19 +f 38/79/20 40/80/20 35/81/20 34/82/20 +f 41/83/21 42/84/21 43/85/21 44/86/21 +f 45/87/22 46/88/22 47/89/22 48/90/22 +f 44/91/23 47/92/23 46/93/23 41/94/23 +f 43/95/24 48/96/24 47/97/24 44/98/24 +f 41/83/25 46/99/25 45/100/25 42/84/25 +f 42/101/26 45/102/26 48/103/26 43/104/26 +f 49/105/27 50/106/27 51/107/27 52/108/27 +f 52/109/28 51/110/28 53/111/28 54/112/28 +f 49/105/29 52/108/29 54/113/29 55/114/29 +f 51/115/30 50/116/30 56/117/30 53/118/30 +f 50/119/31 49/120/31 55/121/31 56/122/31 +f 54/123/32 53/124/32 56/125/32 55/126/32 +f 57/127/9 58/128/9 59/129/9 60/130/9 +f 61/131/11 62/132/11 60/133/11 59/134/11 +f 63/135/33 61/136/33 59/137/33 58/138/33 +f 62/139/34 64/140/34 57/141/34 60/142/34 +f 64/143/7 63/144/7 58/145/7 57/146/7 +f 62/139/8 61/147/8 63/148/8 64/140/8 +f 65/149/11 66/150/11 67/151/11 68/152/11 +f 69/153/35 70/154/35 66/155/35 65/156/35 +f 68/157/36 67/158/36 71/159/36 72/160/36 +f 72/161/7 71/162/7 70/163/7 69/164/7 +f 66/165/9 70/166/9 71/167/9 67/168/9 +f 69/153/8 65/156/8 68/169/8 72/170/8 +f 73/171/11 74/172/11 75/173/11 76/174/11 +f 77/175/9 74/172/9 73/176/9 78/177/9 +f 75/178/8 79/179/8 80/180/8 76/181/8 +f 77/175/12 79/182/12 75/173/12 74/172/12 +f 78/183/7 80/184/7 79/182/7 77/175/7 +f 73/185/10 76/186/10 80/184/10 78/183/10 +f 85/187/37 81/188/37 86/189/37 82/190/37 +f 87/191/38 83/192/38 84/193/38 88/194/38 +f 81/195/39 85/196/39 87/197/39 88/198/39 +f 85/199/40 82/200/40 83/201/40 87/202/40 +f 86/203/41 81/204/41 88/205/41 84/206/41 +f 82/207/42 86/208/42 84/209/42 83/210/42 +f 93/211/43 89/212/43 94/213/43 90/214/43 +f 95/215/44 91/216/44 92/217/44 96/218/44 +f 89/219/45 93/220/45 95/221/45 96/222/45 +f 93/223/46 90/224/46 91/225/46 95/226/46 +f 94/227/47 89/228/47 96/229/47 92/230/47 +f 90/231/48 94/232/48 92/233/48 91/234/48 diff --git a/mods/ITEMS/mcl_bamboo/License.txt b/mods/ITEMS/mcl_bamboo/License.txt new file mode 100644 index 000000000..36caec951 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/License.txt @@ -0,0 +1,226 @@ + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 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/ITEMS/mcl_bamboo/README.md b/mods/ITEMS/mcl_bamboo/README.md new file mode 100644 index 000000000..b1f91e641 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/README.md @@ -0,0 +1,26 @@ +mcl_bamboo +========= + +This mod adds working, familiar bamboo nodes to your Mineclone 2 world. + +Code: MineClone2 dev team. Original (basic) bamboo code by: Small Joker. + +License for code: GPLv3. +License for images / textures: CC-BY-SA except where noted. +Images Created by Nicu, except for: + +* Inventory / wield image for Bamboo Stalk: created by RandomLegoBrick#8692 and is CC0. + +Dependencies: mcl_core, mcl_sounds, mcl_tools + +Optional Dependencies = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, +mesecons_button. +Note that "mcl_boats" may be used at a later date. + +Special thanks to Nicu for help with a ton of things from testing, to encouragement, to graphic design and nodebox work. +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 diff --git a/mods/ITEMS/mcl_bamboo/bamboo_base.lua b/mods/ITEMS/mcl_bamboo/bamboo_base.lua new file mode 100644 index 000000000..b9f67fc64 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/bamboo_base.lua @@ -0,0 +1,400 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 12/29/22 12:33 PM -- Restructure Date +--- Copyright (C) 2022 - 2023, Michieal. See License.txt + +-- CONSTS +local DOUBLE_DROP_CHANCE = 8 +-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it... +-- "BAMBOO" goes here. +local BAMBOO = "mcl_bamboo:bamboo" +local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap" +local BAMBOO_PLANK = BAMBOO .. "_plank" + +-- LOCALS +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local node_sound = mcl_sounds.node_sound_wood_defaults() +local pr = PseudoRandom((os.time() + 15766) * 12) -- switched from math.random() to PseudoRandom because the random wasn't very random. + +local on_rotate +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.disallow +end + +-- basic bamboo nodes. +local bamboo_def = { + description = S("Bamboo"), + tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo.png"}, + drawtype = "nodebox", + paramtype = "light", + groups = {handy = 1, axey = 1, choppy = 1, dig_by_piston = 1, plant = 1, non_mycelium_plant = 1, flammable = 3}, + sounds = node_sound, + + drop = { + max_items = 1, + -- From the API: + -- max_items: Maximum number of item lists to drop. + -- The entries in 'items' are processed in order. For each: + -- Item filtering is applied, chance of drop is applied, if both are + -- successful the entire item list is dropped. + -- Entry processing continues until the number of dropped item lists + -- equals 'max_items'. + -- Therefore, entries should progress from low to high drop chance. + items = { + -- Examples: + { + -- 1 in DOUBLE_DROP_CHANCE chance of dropping. + -- Default rarity is '1'. + rarity = DOUBLE_DROP_CHANCE, + items = {BAMBOO .. " 2"}, + }, + { + -- 1 in 1 chance of dropping. (Note: this means that it will drop 100% of the time.) + -- Default rarity is '1'. + rarity = 1, + items = {BAMBOO}, + }, + }, + }, + + inventory_image = "mcl_bamboo_bamboo_shoot.png", + wield_image = "mcl_bamboo_bamboo_shoot.png", + _mcl_blast_resistance = 1, + _mcl_hardness = 1.5, + node_box = { + type = "fixed", + fixed = { + {-0.175, -0.5, -0.195, 0.05, 0.5, 0.030}, + } + }, + collision_box = { + type = "fixed", + fixed = { + {-0.175, -0.5, -0.195, 0.05, 0.5, 0.030}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.175, -0.5, -0.195, 0.05, 0.5, 0.030}, + } + }, + node_placement_prediction = "", + + on_rotate = on_rotate, + + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + local node = minetest.get_node(pointed_thing.under) + local pos = pointed_thing.under + local nodename = node.name -- intentional use of nodename. + + mcl_bamboo.mcl_log("Node placement data:") + mcl_bamboo.mcl_log(dump(pointed_thing)) + mcl_bamboo.mcl_log("node name: " .. nodename) + + mcl_bamboo.mcl_log("Checking for protected placement of bamboo.") + if mcl_bamboo.is_protected(pos, placer) then + return + end + mcl_bamboo.mcl_log("placement of bamboo is not protected.") + + -- Use pointed node's on_rightclick function first, if present + 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 + mcl_bamboo.mcl_log("Attempting targeted node's on_rightclick.") + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + if mcl_bamboo.is_bamboo(nodename) == false and nodename ~= BAMBOO_ENDCAP_NAME then + -- not bamboo... + mcl_bamboo.mcl_log("not bamboo...") + if nodename ~= "mcl_flowerpots:flower_pot" then + if mcl_bamboo.is_dirt(nodename) == false then + mcl_bamboo.mcl_log("bamboo dirt node not found; node name: " .. nodename) + return + end + end + end + + mcl_bamboo.mcl_log("placing bamboo directly.") + + local dir = vector.subtract(pointed_thing.under, pointed_thing.above) + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + if wdir ~= 1 then + return + end + + local place_item = ItemStack(itemstack) -- make a copy so that we don't indirectly mess with the original. + + local bamboo_node = mcl_bamboo.is_bamboo(nodename) or 0 + mcl_bamboo.mcl_log("node name: " .. nodename .. "\nbamboo_node: " .. bamboo_node) + + local rand_height + local BAMBOO_MAX_HEIGHT = 16 -- maximum height of 16, per wiki. + local first_shoot + local meta + + if bamboo_node and bamboo_node > 0 then + place_item = ItemStack(mcl_bamboo.bamboo_index[bamboo_node]) + + -- height check for placing bamboo nodes. because... lmfao bamboo stalk to the sky. + -- variables used in more than one spot. + local chk_pos + local node_name = "" + local dist = 0 + local height = -1 + + local BAMBOO_SOIL_DIST = BAMBOO_MAX_HEIGHT * -1 + -- ------------------- + for py = -1, BAMBOO_SOIL_DIST, -1 do + chk_pos = vector.offset(pos, 0, py, 0) + node_name = minetest.get_node(chk_pos).name + if mcl_bamboo.is_dirt(node_name) then + first_shoot = vector.offset(chk_pos, 0, 1, 0) + break + end + if mcl_bamboo.is_bamboo(node_name) == false then + break + end + end + -- requires knowing where the soil node is. + if first_shoot == nil then + return + end + meta = minetest.get_meta(first_shoot) + if meta then + height = meta:get_int("height", -1) + end + + dist = vector.distance(first_shoot, pos) + 1 -- +1 for the ground offset. + mcl_bamboo.mcl_log("Distance: " .. dist .. " Height: " .. height .. " Bamboo to place: " .. mcl_bamboo.bamboo_index[bamboo_node]) + -- okay, so don't go beyond max height... + -- Height is determined when the first node grows or is placed. + -- here, it's not found, so let them do 4-5 nodes up. (should help it grow.) + if dist < 5 and height < 5 then + -- allow + else + -- else, it's complicated. + if dist > 5 and height < 5 then + return + end + end + + if dist > height - 1 then + -- height found. here, we let them do it until they reach where the endcap will go. + return + end + else + local placed_type = pr:next(1, 4) -- randomly choose which one to place. + mcl_bamboo.mcl_log("Place_Bamboo_Shoot--Type: " .. placed_type) + place_item = ItemStack(mcl_bamboo.bamboo_index[placed_type]) + rand_height = pr:next(BAMBOO_MAX_HEIGHT - 4, BAMBOO_MAX_HEIGHT) + end + + 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 + local _, position = minetest.item_place(place_item, placer, pointed_thing, fdir) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item(1) + end + if rand_height and rand_height > 1 then + if position then + mcl_bamboo.mcl_log("Setting Height Data...") + meta = minetest.get_meta(position) + if meta then + meta:set_int("height", rand_height) + end + end + end + return itemstack, pointed_thing.under + else + return + end + end, + + on_destruct = function(pos) + -- Node destructor; called before removing node. + local new_pos = vector.offset(pos, 0, 1, 0) + local node_above = minetest.get_node(new_pos) + local bamboo_node = mcl_bamboo.is_bamboo(node_above.name) or 0 + local istack = ItemStack(BAMBOO) + local sound_params = { + pos = new_pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + if node_above and ((bamboo_node and bamboo_node > 0) or node_above.name == BAMBOO_ENDCAP_NAME) then + minetest.remove_node(new_pos) + minetest.sound_play(node_sound.dug, sound_params, true) + if pr:next(1, DOUBLE_DROP_CHANCE) == 1 then + minetest.add_item(new_pos, istack) + end + minetest.add_item(new_pos, istack) + end + end, +} +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.tiles = {"mcl_bamboo_endcap.png"} +bamboo_top.drawtype = "plantlike_rooted" --"plantlike" +--bamboo_top.paramtype2 = "meshoptions" +--bamboo_top.param2 = 2 +-- bamboo_top.waving = 2 +bamboo_top.special_tiles = {{name = "mcl_bamboo_endcap.png"}} +bamboo_top.nodebox = nil +bamboo_top.selection_box = nil +bamboo_top.collision_box = nil + +bamboo_top.on_place = function(itemstack, _, _) + -- Should never occur... but, if it does, then nix it. + itemstack:set_name(BAMBOO) + return itemstack +end + +minetest.register_node(BAMBOO_ENDCAP_NAME, bamboo_top) + +local bamboo_block_def = { + description = S("Bamboo Block"), + tiles = {"mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_bottom.png", "mcl_bamboo_bamboo_block.png"}, + groups = {handy = 1, building_block = 1, axey = 1, flammable = 2, material_wood = 1, bamboo_block = 1, fire_encouragement = 5, fire_flammability = 5}, + sounds = node_sound, + paramtype2 = "facedir", + drops = "mcl_bamboo:bamboo_block", + _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, +} + +minetest.register_node("mcl_bamboo:bamboo_block", bamboo_block_def) + +local bamboo_stripped_block = table.copy(bamboo_block_def) +bamboo_stripped_block.on_rightclick = nil +bamboo_stripped_block.description = S("Stripped Bamboo Block") +bamboo_stripped_block.tiles = {"mcl_bamboo_bamboo_bottom_stripped.png", "mcl_bamboo_bamboo_bottom_stripped.png", + "mcl_bamboo_bamboo_block_stripped.png"} +minetest.register_node("mcl_bamboo:bamboo_block_stripped", bamboo_stripped_block) +minetest.register_node("mcl_bamboo:bamboo_plank", { + description = S("Bamboo Plank"), + _doc_items_longdesc = S("Bamboo Plank"), + _doc_items_hidden = false, + tiles = {"mcl_bamboo_bamboo_plank.png"}, + stack_max = 64, + is_ground_content = false, + groups = {handy = 1, axey = 1, flammable = 3, wood = 1, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 2, +}) + +-- Bamboo Part 2 Base nodes. +-- Bamboo Mosaic +local bamboo_mosaic = table.copy(minetest.registered_nodes[BAMBOO_PLANK]) +bamboo_mosaic.tiles = {"mcl_bamboo_bamboo_plank_mosaic.png"} +bamboo_mosaic.groups = {handy = 1, axey = 1, flammable = 3, fire_encouragement = 5, fire_flammability = 20} +bamboo_mosaic.description = S("Bamboo Mosaic Plank") +bamboo_mosaic._doc_items_longdesc = S("Bamboo Mosaic Plank") +minetest.register_node("mcl_bamboo:bamboo_mosaic", bamboo_mosaic) + +--[[ Bamboo alternative node types. Note that the table.copy's are very important! if you use a common node def and +make changes, even after registering them, the changes overwrite the previous node definitions, and in this case, +you will end up with 4 nodes all being type 3. --]] + +local bamboo_one_def = table.copy(bamboo_def) +bamboo_one_def.node_box = { + type = "fixed", + fixed = { + {-0.05, -0.5, 0.285, -0.275, 0.5, 0.06}, + } +} +bamboo_one_def.collision_box = { + -- see [Node boxes] for possibilities + type = "fixed", + fixed = { + {-0.05, -0.5, 0.285, -0.275, 0.5, 0.06}, + } +} +bamboo_one_def.selection_box = { + type = "fixed", + fixed = { + {-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} +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) + +bamboo_two_def.node_box = { + type = "fixed", + fixed = { + {0.25, -0.5, 0.325, 0.025, 0.5, 0.100}, + } +} +bamboo_two_def.collision_box = { + -- see [Node boxes] for possibilities + type = "fixed", + fixed = { + {0.25, -0.5, 0.325, 0.025, 0.5, 0.100}, + } +} +bamboo_two_def.selection_box = { + type = "fixed", + fixed = { + {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} +minetest.register_node(mcl_bamboo.bamboo_index[3], bamboo_two_def) +local bamboo_three_def = table.copy(bamboo_def) + +bamboo_three_def.node_box = { + type = "fixed", + fixed = { + {-0.125, -0.5, 0.125, -0.3125, 0.5, 0.3125}, + } +} +bamboo_three_def.collision_box = { + -- see [Node boxes] for possibilities + type = "fixed", + fixed = { + {-0.125, -0.5, 0.125, -0.3125, 0.5, 0.3125}, + } +} +bamboo_three_def.selection_box = { + type = "fixed", + fixed = { + {-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} +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 new file mode 100644 index 000000000..dbc8e6946 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/bamboo_items.lua @@ -0,0 +1,585 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 12/29/22 12:38 PM -- Restructure Date +--- Copyright (C) 2022 - 2023, Michieal. See License.txt + +-- FUTURE USE VARIABLE. MUST REMAIN FALSE UNTIL IT HAS BEEN FULLY IMPLEMENTED. DO NOT ENABLE. +local SIDE_SCAFFOLDING = false +local SIDE_SCAFFOLD_NAME = "mcl_bamboo:scaffolding_horizontal" +-- --------------------------------------------------------------------------- +local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding" +-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it... +-- "BAMBOO" goes here. +local BAMBOO = "mcl_bamboo:bamboo" +local BAMBOO_PLANK = BAMBOO .. "_plank" + +-- LOCALS +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local adj_nodes = { + vector.new(0, 0, 1), + vector.new(1, 0, 0), + vector.new(0, 0, -1), + vector.new(-1, 0, 0), +} +local node_sound = mcl_sounds.node_sound_wood_defaults() + +-- specific bamboo nodes (Items)... Pt. 1 +if minetest.get_modpath("mcl_flowerpots") then + mcl_bamboo.mcl_log("FlowerPot Section Entrance. Modpath exists.") + if mcl_flowerpots ~= nil then + -- Flower-potted Bamboo... + local flwr_name = BAMBOO + local flwr_def = { name = "bamboo_plant", + desc = S("Bamboo"), + image = "mcl_bamboo_bamboo_fpm.png", -- use with "register_potted_cube" + -- "mcl_bamboo_flower_pot.png", -- use with "register_potted_flower" + } + + -- Chose cube over "potted_flower" as "potted flower" looks bad. + mcl_flowerpots.register_potted_cube(flwr_name, flwr_def) -- mcl_flowerpots.register_potted_flower(flwr_name, flwr_def) + minetest.register_alias("bamboo_flower_pot", "mcl_flowerpots:flower_pot_bamboo_plant") + end +end + +if minetest.get_modpath("mcl_doors") then + if mcl_doors then + local name = "mcl_bamboo:bamboo_door" + local def = { + description = S("Bamboo Door"), + inventory_image = "mcl_bamboo_door_wield.png", + wield_image = "mcl_bamboo_door_wield.png", + _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."), + groups = { handy = 1, axey = 1, material_wood = 1, flammable = -1 }, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = "mcl_bamboo_door_bottom.png", + tiles_top = "mcl_bamboo_door_top.png", + sounds = mcl_sounds.node_sound_wood_defaults(), + } + + mcl_doors:register_door(name, def) + + name = "mcl_bamboo:bamboo_trapdoor" + local trap_def = { + description = S("Bamboo Trapdoor"), + groups = {}, + tile_front = "mcl_bamboo_trapdoor_side.png", + tile_side = "mcl_bamboo_trapdoor_side.png", + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + wield_image = "mcl_bamboo_trapdoor_side.png", + groups = { handy = 1, axey = 1, mesecon_effector_on = 1, material_wood = 1, flammable = -1 }, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), + } + + mcl_doors:register_trapdoor(name, trap_def) + + minetest.register_alias("bamboo_door", "mcl_bamboo:bamboo_door") + minetest.register_alias("bamboo_trapdoor", "mcl_bamboo:bamboo_trapdoor") + end +end + +if minetest.get_modpath("mcl_stairs") then + if mcl_stairs ~= nil then + mcl_stairs.register_stair_and_slab_simple( + "bamboo_block", + "mcl_bamboo:bamboo_block", + S("Bamboo Stair"), + S("Bamboo Slab"), + S("Double Bamboo Slab") + ) + mcl_stairs.register_stair_and_slab_simple( + "bamboo_stripped", + "mcl_bamboo:bamboo_block_stripped", + S("Stripped Bamboo Stair"), + S("Stripped Bamboo Slab"), + S("Double Stripped Bamboo Slab") + ) + mcl_stairs.register_stair_and_slab_simple( + "bamboo_plank", + BAMBOO_PLANK, + S("Bamboo Plank Stair"), + S("Bamboo Plank Slab"), + S("Double Bamboo Plank Slab") + ) + + -- let's add plank slabs to the wood_slab group. + local bamboo_plank_slab = "mcl_stairs:slab_bamboo_plank" + local node_groups = { + wood_slab = 1, + building_block = 1, + slab = 1, + axey = 1, + handy = 1, + stair = 1, + flammable = 1, + fire_encouragement = 5, + fire_flammability = 20 + } + + minetest.override_item(bamboo_plank_slab, { groups = node_groups }) + end +end + +if minetest.get_modpath("mesecons_pressureplates") then + + if mesecon ~= nil and mesecon.register_pressure_plate ~= nil then + -- make sure that pressure plates are installed. + + -- Bamboo Pressure Plate... + + -- Register a Pressure Plate (api command doc.) + -- basename: base name of the pressure plate + -- description: description displayed in the player's inventory + -- textures_off:textures of the pressure plate when inactive + -- textures_on: textures of the pressure plate when active + -- image_w: wield image of the pressure plate + -- image_i: inventory image of the pressure plate + -- recipe: crafting recipe of the pressure plate + -- sounds: sound table (like in minetest.register_node) + -- plusgroups: group memberships (attached_node=1 and not_in_creative_inventory=1 are already used) + -- activated_by: optimal table with elements denoting by which entities this pressure plate is triggered + -- Possible table fields: + -- * player=true: Player + -- * mob=true: Mob + -- By default, is triggered by all entities + -- longdesc: Customized long description for the in-game help (if omitted, a dummy text is used) + + mesecon.register_pressure_plate( + "mcl_bamboo:pressure_plate_bamboo_wood", + S("Bamboo Pressure Plate"), + { "mcl_bamboo_bamboo_plank.png" }, + { "mcl_bamboo_bamboo_plank.png" }, + "mcl_bamboo_bamboo_plank.png", + nil, + { { BAMBOO_PLANK, BAMBOO_PLANK } }, + mcl_sounds.node_sound_wood_defaults(), + { axey = 1, material_wood = 1 }, + nil, + S("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.")) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:pressure_plate_bamboo_wood_off", + burntime = 15 + }) + minetest.register_alias("bamboo_pressure_plate", "mcl_bamboo:pressure_plate_bamboo_wood") + + end +end + +if minetest.get_modpath("mcl_signs") then + mcl_bamboo.mcl_log("Signs Section Entrance. Modpath exists.") + if mcl_signs ~= nil 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") + mcl_signs.register_sign_craft("mcl_bamboo", BAMBOO_PLANK, "_bamboo") + minetest.register_alias("bamboo_sign", "mcl_signs:wall_sign_bamboo") + end +end + +if minetest.get_modpath("mcl_fences") then + mcl_bamboo.mcl_log("Fences Section Entrance. Modpath exists.") + + local id = "bamboo_fence" + 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. + + mcl_bamboo.mcl_log(dump(fence_id)) + mcl_bamboo.mcl_log(dump(gate_id)) +end + +if minetest.get_modpath("mesecons_button") then + if mesecon ~= nil then + mesecon.register_button( + "bamboo", + S("Bamboo Button"), + "mcl_bamboo_bamboo_plank.png", + BAMBOO_PLANK, + node_sound, + { 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."), + "mesecons_button_push") + end +end + +if minetest.get_modpath("mcl_stairs") then + if mcl_stairs ~= nil then + mcl_stairs.register_stair_and_slab_simple( + "bamboo_mosaic", + "mcl_bamboo:bamboo_mosaic", + S("Bamboo Mosaic Stair"), + S("Bamboo Mosaic Slab"), + S("Double Bamboo Mosaic Slab") + ) + end +end + +local disallow_on_rotate +if minetest.get_modpath("screwdriver") then + disallow_on_rotate = screwdriver.disallow +end + +minetest.register_node(SCAFFOLDING_NAME, { + description = S("Scaffolding"), + doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."), + doc_items_hidden = false, + tiles = { "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png" }, + drawtype = "nodebox", + paramtype = "light", + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { + { -0.5, 0.375, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, -0.5, -0.5, -0.375, 0.5, -0.375 }, + { 0.375, -0.5, -0.5, 0.5, 0.5, -0.375 }, + { 0.375, -0.5, 0.375, 0.5, 0.5, 0.5 }, + { -0.5, -0.5, 0.375, -0.375, 0.5, 0.5 }, + } + }, + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + }, + }, + buildable_to = false, + is_ground_content = false, + walkable = false, + climbable = true, + physical = true, + node_placement_prediction = "", + groups = { handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, dig_by_piston = 1, falling_node = 1, stack_falling = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + + on_rotate = disallow_on_rotate, + + on_place = function(itemstack, placer, pointed) + mcl_bamboo.mcl_log("Checking for protected placement of scaffolding.") + local node = minetest.get_node(pointed.under) + local pos = pointed.under + local h = 0 + local current_base_node = node -- Current Base Node. + local below_node = minetest.get_node(vector.offset(pos, 0, -1, 0)) -- current node below the current_base_node. + + mcl_bamboo.mcl_log("Below Node: " .. below_node.name) + + -- check protected placement. + if mcl_bamboo.is_protected(pos, placer) then + return + end + mcl_bamboo.mcl_log("placement of scaffolding is not protected.") + -- place on solid nodes + -- Need to add in a check here... to prevent placing scaffolds against doors, chests, etc. + -- Added in a quick check. need to test it. + if node.name ~= SCAFFOLDING_NAME then + -- Start temp fix: This is a temp fix... will NOT work in final scaffolding implementation. + -- Use pointed node's on_rightclick function first, if present + 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 + mcl_bamboo.mcl_log("attempting placement of bamboo via targeted node's on_rightclick.") + return minetest.registered_nodes[node.name].on_rightclick(pointed.under, node, placer, itemstack) or itemstack + end + end + -- End: Temp fix + + -- 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) + 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) + end + return itemstack + else + return + end + end + + --build up when placing on existing scaffold + --[[ + Quick explanation. scaffolding should be placed at the ground level ONLY. To do this, we look at a few + different nodes. Current node (current_node) is the top node being placed - make sure that it is air / unoccupied. + below_node (below node) is the node below the bottom node; Used to check to see if we are up in the air putting + more scaffolds on the top.. current_base_node (Current Base Node) is the targeted node for placement; we can only place + scaffolding on this one, to stack them up in the air. + --]] + repeat -- loop through, allowing placement. + pos = vector.offset(pos, 0, 1, 0) -- cleaned up vector. + local current_node = minetest.get_node(pos) -- current node. + if current_node.name == "air" then + -- first step to making scaffolding work like scaffolding should. + -- Prevent running up, and putting down new scaffolding + if current_base_node.name == SCAFFOLDING_NAME and below_node == SCAFFOLDING_NAME and SIDE_SCAFFOLDING == false then + return itemstack + end + + -- Make sure that the uppermost scaffolding doesn't violate protected areas. + if mcl_bamboo.is_protected(pos, placer) then + return itemstack + end + + -- okay, we're good. place the node and take the item unless we are in creative mode. + minetest.set_node(pos, node) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item(1) + end + -- set the wielded item to the correct itemstack. (possibly unneeded code. but, works.) + placer:set_wielded_item(itemstack) + return itemstack -- finally, return the itemstack to finish on_place. + end + h = h + 1 + until current_node.name ~= node.name or itemstack:get_count() == 0 or h >= 128 -- loop check. + end, + on_destruct = function(pos) + -- Node destructor; called before removing node. + local new_pos = vector.offset(pos, 0, 1, 0) + local node_above = minetest.get_node(new_pos) + if node_above and node_above.name == SCAFFOLDING_NAME then + local sound_params = { + pos = new_pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + minetest.remove_node(new_pos) + minetest.sound_play(node_sound.dug, sound_params, true) + local istack = ItemStack(SCAFFOLDING_NAME) + minetest.add_item(new_pos, istack) + end + end, +}) + +-- FOR FUTURE USE. DO NOT ENABLE. DO NOT UNCOMMENT OUT. THIS WILL BREAK THE SCAFFOLDING, IF NOT FINISHED. +-- YOU HAVE BEEN WARNED. +--[[ +if SIDE_SCAFFOLDING then +minetest.register_node(SCAFFOLDING_NAME, { + description = S("Scaffolding"), + doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."), + doc_items_hidden = false, + tiles = {"mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png"}, + drawtype = "nodebox", + paramtype = "light", + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.375}, + {0.375, -0.5, -0.5, 0.5, 0.5, -0.375}, + {0.375, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0.375, -0.375, 0.5, 0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + buildable_to = false, + is_ground_content = false, + walkable = false, + climbable = true, + physical = true, + node_placement_prediction = "", + groups = {handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, falling_node = 1, stack_falling = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + + on_rotate = disallow_on_rotate, + + on_place = function(itemstack, placer, pointed) + mcl_bamboo.mcl_log("Checking for protected placement of scaffolding.") + local node = minetest.get_node(pointed.under) + local pos = pointed.under + local dir = vector.subtract(pointed.under, pointed.above) + local wdir = minetest.dir_to_wallmounted(dir) + local h = 0 + mcl_bamboo.mcl_log("WDIR: " .. wdir) + local fdir = minetest.dir_to_facedir(dir, true) + mcl_bamboo.mcl_log("FDIR: " .. fdir) + + local down_two = minetest.get_node(vector.offset(pointed.under, 0, -1, 0)) + + if wdir == 1 then + -- standing placement. + + if mcl_bamboo.is_protected(pos, placer) then + return + end + mcl_bamboo.mcl_log("placement of scaffolding is not protected.") + -- place on solid nodes + if node.name ~= SCAFFOLDING_NAME 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 + return itemstack + end + --build up when placing on existing scaffold + repeat + pos.y = pos.y + 1 + local current_node = minetest.get_node(pos) + local current_base_node = node + local below_node = down_two + if current_node.name == "air" then + -- first step to making scaffolding work like Minecraft scaffolding. + if current_base_node.name == SCAFFOLDING_NAME and below_node == SCAFFOLDING_NAME and SIDE_SCAFFOLDING == false then + return itemstack + end + + if mcl_bamboo.is_protected(pos, placer) then + return + end + + minetest.set_node(pos, node) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item(1) + end + placer:set_wielded_item(itemstack) + return itemstack + end + h = h + 1 + until current_node.name ~= node.name or itemstack:get_count() == 0 or h >= 128 + + -- Commenting out untested code, for commit. + if SIDE_SCAFFOLDING == true then + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + -- local count = meta:get_int("count", 0) + + h = minetest.get_node(pointed.under).param2 + local new_pos = pointed.under + repeat + local ctrl = placer:get_player_control() + if ctrl and ctrl.sneak then + if node.name == SCAFFOLDING_NAME or node.name == SIDE_SCAFFOLD_NAME then + local param_2 = h + + local node_param2 = param_2 + 1 + fdir = fdir + 1 -- convert fdir to a base of one. + local target_offset = adj_nodes[fdir] + + new_pos = vector.offset(new_pos, target_offset.x, 0, target_offset.z) + if mcl_bamboo.is_protected(new_pos, placer) then + -- disallow placement in protected area + return + end + + itemstack:take_item(1) + if minetest.get_node(new_pos).name == "air" then + minetest.set_node(new_pos, {name = SIDE_SCAFFOLD_NAME, param2 = node_param2}) + if node_param2 >= 6 then + node_param2 = 6 + minetest.minetest.dig_node(new_pos) + end + end + return itemstack + + end + + h = h + 1 + + end + until h >= 7 or itemstack.get_count() <= 0 + end + end + end, + on_destruct = function(pos) + -- Node destructor; called before removing node. + local new_pos = vector.offset(pos, 0, 1, 0) + local node_above = minetest.get_node(new_pos) + if node_above and node_above.name == SCAFFOLDING_NAME then + local sound_params = { + pos = new_pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + minetest.remove_node(new_pos) + minetest.sound_play(node_sound.dug, sound_params, true) + local istack = ItemStack(SCAFFOLDING_NAME) + minetest.add_item(new_pos, istack) + end + end, +}) + +minetest.register_node(SIDE_SCAFFOLD_NAME, { + description = S("Scaffolding"), + doc_items_longdesc = S("Scaffolding block used to climb up or out across areas."), + doc_items_hidden = false, + tiles = {"mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_top.png", "mcl_bamboo_scaffolding_bottom.png"}, + drop = "mcl_bamboo:scaffolding", + drawtype = "nodebox", + paramtype = "light", + use_texture_alpha = "clip", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.375, -0.5, 0.5, 0.5, 0.5}, + {-0.5, -0.5, -0.5, -0.375, 0.5, -0.375}, + {0.375, -0.5, -0.5, 0.5, 0.5, -0.375}, + {0.375, -0.5, 0.375, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0.375, -0.375, 0.5, 0.5}, + {-0.5, -0.5, -0.5, 0.5, -0.375, 0.5}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + }, + }, + groups = {handy = 1, axey = 1, flammable = 3, building_block = 1, material_wood = 1, fire_encouragement = 5, fire_flammability = 20, not_in_creative_inventory = 1, falling_node = 1}, + _mcl_after_falling = function(pos) + if minetest.get_node(pos).name == "mcl_bamboo:scaffolding_horizontal" then + if minetest.get_node(vector.offset(pos, 0, 0, 0)).name ~= SCAFFOLDING_NAME then + minetest.remove_node(pos) + minetest.add_item(pos, SCAFFOLDING_NAME) + else + minetest.set_node(vector.offset(pos, 0, 1, 0), {name = SIDE_SCAFFOLD_NAME}) + end + end + end, + buildable_to = false, + is_ground_content = false, + walkable = false, + climbable = true, + physical = true, + + on_rotate = disallow_on_rotate, + + on_place = function(itemstack, placer, pointed_thing) + -- this function shouldn't be called, as this is never placed by the user. + -- it's placed only as a variant of regular scaffolding. + return false + end + + +}) +end +--]] diff --git a/mods/ITEMS/mcl_bamboo/globals.lua b/mods/ITEMS/mcl_bamboo/globals.lua new file mode 100644 index 000000000..f96395228 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/globals.lua @@ -0,0 +1,295 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 12/29/22 12:34 PM -- Restructure Date +--- Copyright (C) 2022 - 2023, Michieal. See License.txt + +local DEBUG = false + +local rand = math.random +math.randomseed((os.time() + 31) * 31415) -- try to make a valid seed +local BAMBOO_MAX_HEIGHT = 16 -- base height check. + +local BAMBOO_SOIL_DIST = BAMBOO_MAX_HEIGHT * -1 +local BAM_MAX_HEIGHT_STPCHK = BAMBOO_MAX_HEIGHT - 5 +local BAM_MAX_HEIGHT_TOP = BAMBOO_MAX_HEIGHT - 1 +local GROW_DOUBLE_CHANCE = 32 + +--Bamboo can be planted on moss blocks, grass blocks, dirt, coarse dirt, rooted dirt, gravel, mycelium, podzol, sand, red sand, or mud +mcl_bamboo.bamboo_dirt_nodes = { + "mcl_core:redsand", + "mcl_core:sand", + "mcl_core:dirt", + "mcl_core:coarse_dirt", + "mcl_core:dirt_with_grass", + "mcl_core:podzol", + "mcl_core:mycelium", + "mcl_lush_caves:rooted_dirt", + "mcl_lush_caves:moss", + "mcl_mud:mud", +} + +function mcl_bamboo.is_dirt(node_name) + local index = table.indexof(mcl_bamboo.bamboo_dirt_nodes, node_name) + if index == -1 then + return false + else + return true + end +end + +mcl_bamboo.bamboo_index = { + "mcl_bamboo:bamboo", + "mcl_bamboo:bamboo_1", + "mcl_bamboo:bamboo_2", + "mcl_bamboo:bamboo_3", +} + +function mcl_bamboo.is_bamboo(node_name) + local index = table.indexof(mcl_bamboo.bamboo_index, node_name) + if index == -1 then + return false + else + return index + end +end + +--- pos: node position; placer: ObjectRef that is placing the item +--- returns: true if protected, otherwise false. +function mcl_bamboo.is_protected(pos, placer) + local name = placer:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return true + end + return false +end + +local BAMBOO_ENDCAP_NAME = "mcl_bamboo:bamboo_endcap" + +-- For when I learn more about the pistons... +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)) + local node_name = node_below.name + + -- short circuit checks. + if mcl_bamboo.is_dirt(node_name) or mcl_bamboo.is_bamboo(node_name) or mcl_bamboo.is_bamboo(minetest.get_node(pos).name) == false then + return + end + + -- dig the node. + minetest.remove_node(pos) -- if that fails, remove the node + local istack = ItemStack("mcl_bamboo:bamboo") + local sound_params = { + pos = pos, + gain = 1.0, -- default + max_hear_distance = 10, -- default, uses a Euclidean metric + } + + minetest.remove_node(pos) + minetest.sound_play(mcl_sounds.node_sound_wood_defaults().dug, sound_params, true) + minetest.add_item(pos, istack) +end +--]] + +function mcl_bamboo.grow_bamboo(pos, bonemeal_applied) + local node_above = minetest.get_node(vector.offset(pos, 0, 1, 0)) + mcl_bamboo.mcl_log("Grow bamboo called; bonemeal: " .. tostring(bonemeal_applied)) + + if not bonemeal_applied and mcl_bamboo.is_bamboo(node_above.name) ~= false then + return false -- short circuit this function if we're trying to grow (std) the bamboo and it's not the top shoot. + end + if minetest.get_node_light(pos) < 8 then + return false + end + + -- variables used in more than one spot. + local first_shoot + local chk_pos + local soil_pos + local node_name = "" + local dist = 0 + local node_below + -- ------------------- + + mcl_bamboo.mcl_log("Grow bamboo; checking for soil: ") + -- the soil node below the bamboo. + for py = -1, BAMBOO_SOIL_DIST, -1 do + chk_pos = vector.offset(pos, 0, py, 0) + node_name = minetest.get_node(chk_pos).name + if mcl_bamboo.is_dirt(node_name) then + soil_pos = chk_pos + break + end + if mcl_bamboo.is_bamboo(node_name) == false then + break + end + end + -- requires knowing where the soil node is. + if soil_pos == nil then + return false -- returning false means don't use up the bonemeal. + end + + mcl_bamboo.mcl_log("Grow bamboo; soil found. ") + local grow_amount = rand(1, GROW_DOUBLE_CHANCE) + grow_amount = rand(1, GROW_DOUBLE_CHANCE) + grow_amount = rand(1, GROW_DOUBLE_CHANCE) -- because yeah, not truly random, or even a good prng. + grow_amount = rand(1, GROW_DOUBLE_CHANCE) + local init_height = rand(BAM_MAX_HEIGHT_STPCHK + 1, BAM_MAX_HEIGHT_TOP + 1) + mcl_bamboo.mcl_log("Grow bamboo; random height: " .. init_height) + + node_name = "" + + -- update: add randomized max height to first node's meta data. + first_shoot = vector.offset(soil_pos, 0, 1, 0) + local meta = minetest.get_meta(first_shoot) + node_below = minetest.get_node(first_shoot).name + + mcl_bamboo.mcl_log("Grow bamboo; checking height meta ") + -- check the meta data for the first node, to see how high to make the stalk. + if not meta then + -- if no metadata, set the metadata!!! + meta:set_int("height", init_height) + end + local height = meta:get_int("height", -1) + mcl_bamboo.mcl_log("Grow bamboo; meta-height: " .. height) + if height <= 10 then + height = init_height + meta:set_int("height", init_height) + end + + mcl_bamboo.mcl_log("Grow bamboo; height: " .. height) + + -- Bonemeal: Grows the bamboo by 1-2 stems. (per the minecraft wiki.) + if bonemeal_applied then + -- handle applying bonemeal. + for py = 1, BAM_MAX_HEIGHT_TOP do + -- find the top node of bamboo. + chk_pos = vector.offset(pos, 0, py, 0) + node_name = minetest.get_node(chk_pos).name + dist = vector.distance(soil_pos, chk_pos) + if mcl_bamboo.is_bamboo(node_name) == false or node_name == BAMBOO_ENDCAP_NAME then + break + end + end + + mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist) + + if node_name == BAMBOO_ENDCAP_NAME then + -- prevent overgrowth + return false + end + + -- check to see if we have a full stalk of bamboo. + if dist >= height - 1 then + if dist == height - 1 then + -- equals top of the stalk before the cap + if node_name == "air" then + mcl_bamboo.mcl_log("Grow bamboo; Placing endcap") + minetest.set_node(vector.offset(chk_pos, 0, 1, 0), { name = BAMBOO_ENDCAP_NAME }) + return true -- returning true means use up the bonemeal. + else + return false + end + else + -- okay, we're higher than the end cap, fail out. + return false -- returning false means don't use up the bonemeal. + end + end + + -- and now, the meat of the section... add bamboo to the stalk. + -- at this point, we should be lower than the generated maximum height. ~ about height -2 or lower. + if dist <= height - 2 then + if node_name == "air" then + -- here we can check to see if we can do up to 2 bamboo shoots onto the stalk + mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.") + minetest.set_node(chk_pos, { name = node_below }) + -- handle growing a second node. + if grow_amount == 2 then + chk_pos = vector.offset(chk_pos, 0, 1, 0) + if minetest.get_node(chk_pos).name == "air" then + mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!") + minetest.set_node(chk_pos, { name = node_below }) + end + end + return true -- exit out with a success. We've added 1-2 nodes, per the wiki. + end + end + end + + -- Non-Bonemeal growth. + for py = 1, BAM_MAX_HEIGHT_TOP do + -- Find the topmost node above the stalk, and check it for "air" + chk_pos = vector.offset(pos, 0, py, 0) + node_below = minetest.get_node(pos).name + node_name = minetest.get_node(chk_pos).name + dist = vector.distance(soil_pos, chk_pos) + + if node_name ~= "air" and mcl_bamboo.is_bamboo(node_name) == false then + break + end + + -- stop growing check. ie, handle endcap placement. + if dist >= height - 1 then + local above_node_name = minetest.get_node(vector.offset(chk_pos, 0, 1, 0)).name + if node_name == "air" and above_node_name == "air" then + if height - 1 == dist then + mcl_bamboo.mcl_log("Grow bamboo; Placing endcap") + minetest.set_node(chk_pos, { name = BAMBOO_ENDCAP_NAME }) + end + end + break + end + + -- handle regular node placement. + -- find the air node above the top shoot. place a node. And then, if short enough, + -- check for second node placement. + if node_name == "air" then + mcl_bamboo.mcl_log("Grow bamboo; dist: " .. dist) + mcl_bamboo.mcl_log("Grow bamboo; Placing bamboo.") + minetest.set_node(chk_pos, { name = node_below }) + -- handle growing a second node. (1 in 32 chance.) + if grow_amount == 2 and dist <= height - 2 then + chk_pos = vector.offset(chk_pos, 0, 1, 0) + if minetest.get_node(chk_pos).name == "air" then + mcl_bamboo.mcl_log("Grow bamboo; OOOH! It's twofer day!") + minetest.set_node(chk_pos, { name = node_below }) + end + end + break + end + end +end + +-- Add Groups function, courtesy of Warr1024. +function mcl_bamboo.add_groups(name, ...) + local def = minetest.registered_items[name] or error(name .. " not found") + local groups = {} + for k, v in pairs(def.groups) do + groups[k] = v + end + local function add_all(x, ...) + if not x then + return + end + groups[x] = 1 + return add_all(...) + end + addall(...) + return minetest.override_item(name, { groups = groups }) +end + +function mcl_bamboo.mcl_log(m, l) + if not m then + minetest.log("error", "expected string, received: " .. m) + return + end + if DEBUG then + if not l then + minetest.log("[mcl_bamboo]: " .. m) + else + minetest.log(l, "[mcl_bamboo]: " .. m) + end + end +end diff --git a/mods/ITEMS/mcl_bamboo/init.lua b/mods/ITEMS/mcl_bamboo/init.lua new file mode 100644 index 000000000..f2323b66c --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/init.lua @@ -0,0 +1,106 @@ +-- [bamboo] mod by SmallJoker, Made for MineClone 2 by Michieal (as mcl_bamboo). +-- Parts of mcl_scaffolding were used. Mcl_scaffolding originally created by Cora; Fixed and heavily reworked +-- for mcl_bamboo by Michieal. +-- Creation date: 12-01-2022 (Dec 1st, 2022) +-- License for Media: CC-BY-SA 4.0 (except where noted); Code: GPLv3 +-- Copyright (C) 2022 - 2023, Michieal. See License.txt + +-- LOCALS +local modname = minetest.get_current_modname() +-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it... +-- "BAMBOO" goes here. +local BAMBOO = "mcl_bamboo:bamboo" + +mcl_bamboo = {} + +-- BAMBOO GLOBALS +dofile(minetest.get_modpath(modname) .. "/globals.lua") +-- BAMBOO Base Nodes +dofile(minetest.get_modpath(modname) .. "/bamboo_base.lua") +-- BAMBOO ITEMS +dofile(minetest.get_modpath(modname) .. "/bamboo_items.lua") +-- BAMBOO RECIPES +dofile(minetest.get_modpath(modname) .. "/recipes.lua") + +-- ------------------------------------------------------------ + +--ABMs +minetest.register_abm({ + label = "Bamboo Grow", + nodenames = mcl_bamboo.bamboo_index, + interval = 10, + chance = 20, + action = function(pos, _) + mcl_bamboo.grow_bamboo(pos, false) + end, +}) + +--[[ TODO: Figure out how to make this work: +local function dropper_call(node, pushdir, stack, stackid) + mcl_bamboo.mcl_log("mvps_dropper call for bamboo:") + -- mcl_bamboo.break_orphaned() + + mcl_bamboo.mcl_log(dump(node)) + +end + +if minetest.get_modpath("mesecons_mvps") then + if mesecon then + mcl_bamboo.mcl_log("registering mvps_dropper for bamboo:") + for x = 1, #mcl_bamboo.bamboo_index do + mesecon.register_mvps_dropper(mcl_bamboo.bamboo_index[x],dropper_call) + mcl_bamboo.mcl_log("registering: " .. mcl_bamboo.bamboo_index[x]) + end + end +else +end +--]] + +minetest.register_abm({ + label = "Break Orphaned Bamboo", + nodenames = mcl_bamboo.bamboo_index, + interval = 1.5, + chance = 1, + action = function(pos, _) + mcl_bamboo.break_orphaned(pos) + end, +}) + + +-- Base Aliases. +local SCAFFOLDING_NAME = "mcl_bamboo:scaffolding" +minetest.register_alias("bamboo_block", "mcl_bamboo:bamboo_block") +minetest.register_alias("bamboo_strippedblock", "mcl_bamboo:bamboo_block_stripped") +minetest.register_alias("bamboo", BAMBOO) +minetest.register_alias("bamboo_plank", "mcl_bamboo:bamboo_plank") +minetest.register_alias("bamboo_mosaic", "mcl_bamboo:bamboo_mosaic") + +minetest.register_alias("mcl_stairs:stair_bamboo", "mcl_stairs:stair_bamboo_block") +minetest.register_alias("bamboo_stairs", "mcl_stairs:stair_bamboo_block") +minetest.register_alias("bamboo:bamboo", BAMBOO) +minetest.register_alias("scaffold", SCAFFOLDING_NAME) +minetest.register_alias("mcl_scaffolding:scaffolding", SCAFFOLDING_NAME) +minetest.register_alias("mcl_scaffolding:scaffolding_horizontal", SCAFFOLDING_NAME) + +minetest.register_alias("bamboo_fence", "mcl_fences:bamboo_fence") +minetest.register_alias("bamboo_fence_gate", "mcl_fences:bamboo_fence_gate") + +--[[ +todo -- make scaffolds do side scaffold blocks, so that they jut out. (Shelved.) +todo -- Also, make those blocks collapse (break) when a nearby connected scaffold breaks. + +waiting on specific things: +todo -- Raft -- need model +todo -- Raft with Chest. same. +todo -- handle bonemeal... (shelved until after redoing the bonemeal api). + +----------------------------------------------------------- +todo -- Add in Extras. -- Moved to Official Mod Pack. + +Notes: +When bone meal is used on it, it grows by 1–2 blocks. Bamboo can grow up to 12–16 blocks tall. +The top of a bamboo plant requires a light level of 9 or above to grow. + +Design Decision - to not make bamboo saplings, and not make them go through a ton of transformations. + +--]] diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr new file mode 100644 index 000000000..5e05302df --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.dk.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_bamboo + + +### 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 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. + +Bamboo=Bambus +Bamboo Button=Bambusknap +Bamboo Door.=Bambusdør +Bamboo Fence=Bambushegn +Bamboo Fence Gate=Bambushegnslåge +Bamboo Plank=Bambusplanke +Bamboo Plank Slab=Bambusplankeplade +Bamboo Plank Stair=Bambusplanketrappe +Bamboo Pressure Plate=Bambustrykplade +Bamboo Sign=Bambusskilt +Bamboo Slab=Bambusplade +Bamboo Stair=Bambustrappe +Bamboo Trapdoor.=Bambusfaldlem +Double Bamboo Plank Slab=Dobbelbambusplanke +Double Bamboo Slab=Dobbelbambusplade +Double Stripped Bamboo Slab=Afbarket dobbelbambus +Nether Brick Fence=Netherstenshegn +Scaffolding=Stillads +Scaffolding (horizontal)=Stillads (horisontal) +Scaffolding block used to climb up or out across areas.=Stilladsblok som bruges til at kravle op ad eller på tværs af områder +Stripped Bamboo Slab=Afbarket bambusplade +Stripped Bamboo Stair=Afbarket bambustrappe + +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Højre-klik eller send rødstensenergi til en faldlem for at åbne eller lukke den, + +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.=Træfaldlemme er horisontale barrierer som kan åbnes og lukkes med håndkraft eller med rødstensenergi. De kan udgøre den øverste eller den nederste del af en blok afhængigt af hvordan de placeres. Når de er åbne, kan man bruge dem ligesom en stige. + diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr new file mode 100644 index 000000000..e21beb760 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.es.tr @@ -0,0 +1,40 @@ +# textdomain: mcl_bamboo + +### bamboo_base.lua ### + +Bamboo Mosaic Plank=Madera de bambú de mosaico +Bamboo Plank=Madera de bambú +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 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. + +Bamboo=Bambú +Bamboo Button=Botón de bambú +Bamboo Door.=Puerta de bambú +Bamboo Fence=Valla de bambú +Bamboo Fence Gate=Puerta de valla de bambú +Bamboo Mosaic Slab=Losa de mosaico de bambú +Bamboo Mosaic Stair=Escaleras de mosaico de bambú +Bamboo Plank Slab=Losa de madera de bambú +Bamboo Plank Stair=Escalera de madera de bambú +Bamboo Pressure Plate=Placa de presión de bambú +Bamboo Slab=Losa de bambú +Bamboo Stair=Escalera de bambú +Bamboo Trapdoor.=Trampilla de bambú +Double Bamboo Mosaic Slab=Losa doble de mosaico de bambú +Double Bamboo Plank Slab=Losa doble de madera de bambú +Double Bamboo Slab=Losa doble de bambú +Double Stripped Bamboo Slab=Losa doble de bambú sin corteza +Scaffolding=Andamio +Scaffolding (horizontal)=Andamio (horizontal) +Scaffolding block used to climb up or out across areas.=El bloque de andamio sirve para subir o bajar entre zonas. +Stripped Bamboo Slab=Losa de bambú sin corteza +Stripped Bamboo Stair=Escalera de bambú sin corteza + +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Para abir o cerar una trampilla, haz click derecho o manda una señal de redstone hacia ella. + +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.=Las trampillas de madera son barreras horizontales que pueden ser abiertas y cerradas con la mano o por una señal de redstone. diff --git a/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr new file mode 100644 index 000000000..953d08811 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/mcl_bamboo.fr.tr @@ -0,0 +1,45 @@ +# textdomain: mcl_bamboo + +### bamboo_base.lua ### + +Bamboo=Bambou +Bamboo Mosaic Plank=Planche mosaïque de bambou +Bamboo Plank=Planche de bambou +Stripped Bamboo Block=Bloc de bambou écorcé +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 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. + +Bamboo=Bambou +Bamboo Button=Bouton en bambou +Bamboo Door=Porte de bambou +Bamboo Fence=Barrière de bambou +Bamboo Fence Gate=Portillon de bambou +Bamboo Mosaic Slab=Dalle mosaïque de bambou +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 Slab=Dalle de bambou +Bamboo Stair=Escalier de bambou +Bamboo Trapdoor=Trappe de bambou +Double Bamboo Mosaic Slab=Double dalle mosaïque de bambou +Double Bamboo Plank Slab=Double dalle de planches de bambou +Double Bamboo Slab=Double dalle de bambou +Double Stripped Bamboo Slab=Double dalle de bambou écorcée +Scaffolding=Échafaudage +Scaffolding (horizontal)=Échafaudage (horizontal) +Scaffolding block used to climb up or out across areas.=Les blocs d'échafaudage servent à escalader ou à sortir d'une zone. +Stripped Bamboo Slab=Dalle de bambou écorcée +Stripped Bamboo Stair=Escalier de bambou écorcée + +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Pour ouvrir ou fermer la trappe, cliquer droit ou lui envoyer un signal 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.=Les trappes de bois sont des barrières horizontales qui peuvent être ouvertes et fermées à la main ou par un signal redstone. Lorsqu'elles sont ouvertes, elles peuvent êtres escaladées comme une échelle. + +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. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en bois, faites un clic droit dessus ou fournissez à sa moitié inférieure un signal redstone. diff --git a/mods/ITEMS/mcl_bamboo/locale/template.txt b/mods/ITEMS/mcl_bamboo/locale/template.txt new file mode 100644 index 000000000..2d5c69383 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/locale/template.txt @@ -0,0 +1,45 @@ +# textdomain: mcl_bamboo + +### bamboo_base.lua ### + +Bamboo= +Bamboo Mosaic Plank= +Bamboo Plank= +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.= + +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= +Bamboo Door= +Bamboo Fence= +Bamboo Fence Gate= +Bamboo Mosaic Slab= +Bamboo Mosaic Stair= +Bamboo Plank Slab= +Bamboo Plank Stair= +Bamboo Pressure Plate= +Bamboo Slab= +Bamboo Stair= +Bamboo Trapdoor= +Double Bamboo Mosaic Slab= +Double Bamboo Plank Slab= +Double Bamboo Slab= +Double Stripped Bamboo Slab= +Scaffolding= +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.= + +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.= +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/mod.conf b/mods/ITEMS/mcl_bamboo/mod.conf new file mode 100644 index 000000000..1426b936f --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/mod.conf @@ -0,0 +1,4 @@ +name = mcl_bamboo +depends = mcl_core, mcl_sounds, mcl_tools +optional_depends = mcl_flowerpots, mclx_stairs, mcl_doors, mcl_signs, mesecons_pressureplates, mcl_fences, mesecons_button, mesecons_mvps +author = Michieal \ No newline at end of file diff --git a/mods/ITEMS/mcl_bamboo/recipes.lua b/mods/ITEMS/mcl_bamboo/recipes.lua new file mode 100644 index 000000000..74f9f9879 --- /dev/null +++ b/mods/ITEMS/mcl_bamboo/recipes.lua @@ -0,0 +1,200 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 12/29/22 12:46 PM -- Restructure Date +--- These are all of the fuel recipes and all of the crafting recipes, consolidated into one place. +--- Copyright (C) 2022 - 2023, Michieal. See License.txt + +-- Used everywhere. Often this is just the name, but it makes sense to me as BAMBOO, because that's how I think of it... +-- "BAMBOO" goes here. +local BAMBOO = "mcl_bamboo:bamboo" +local BAMBOO_PLANK = BAMBOO .. "_plank" +-- Craftings +-- Basic Bamboo craftings +minetest.register_craft({ + output = "mcl_core:stick", + recipe = { + {BAMBOO}, + {BAMBOO}, + } +}) + +minetest.register_craft({ + output = BAMBOO .. "_block", + recipe = { + {BAMBOO, BAMBOO, BAMBOO}, + {BAMBOO, BAMBOO, BAMBOO}, + {BAMBOO, BAMBOO, BAMBOO}, + } +}) + +minetest.register_craft({ + output = BAMBOO_PLANK .. " 2", + recipe = { + {BAMBOO .. "_block"}, + } +}) + +minetest.register_craft({ + output = BAMBOO_PLANK .. " 2", + recipe = { + {BAMBOO .. "_block_stripped"}, + } +}) + +minetest.register_craft({ + output = BAMBOO .. "_mosaic", + recipe = { + {"mcl_stairs:slab_bamboo_plank"}, + {"mcl_stairs:slab_bamboo_plank"}, + } +}) + +-- Bamboo specific items + +if minetest.get_modpath("mcl_doors") and mcl_doors then + minetest.register_craft({ + output = "mcl_bamboo:bamboo_door 3", + recipe = { + {BAMBOO_PLANK, BAMBOO_PLANK}, + {BAMBOO_PLANK, BAMBOO_PLANK}, + {BAMBOO_PLANK, BAMBOO_PLANK} + } + }) + minetest.register_craft({ + output = "mcl_bamboo:bamboo_trapdoor 2", + recipe = { + {BAMBOO_PLANK, BAMBOO_PLANK, BAMBOO_PLANK}, + {BAMBOO_PLANK, BAMBOO_PLANK, BAMBOO_PLANK}, + } + }) +end +if minetest.get_modpath("mcl_fences") then + minetest.register_craft({ + output = "mcl_bamboo:bamboo_fence 3", + recipe = { + {BAMBOO_PLANK, "mcl_core:stick", BAMBOO_PLANK}, + {BAMBOO_PLANK, "mcl_core:stick", BAMBOO_PLANK}, + } + }) + minetest.register_craft({ + output = "mcl_bamboo:bamboo_fence_gate", + recipe = { + {"mcl_core:stick", BAMBOO_PLANK, "mcl_core:stick"}, + {"mcl_core:stick", BAMBOO_PLANK, "mcl_core:stick"}, + } + }) +end + +minetest.register_craft({ + output = "mcl_bamboo:scaffolding 6", + recipe = {{BAMBOO, "mcl_mobitems:string", BAMBOO}, + {BAMBOO, "", BAMBOO}, + {BAMBOO, "", BAMBOO}} +}) + +-- Fuels +-- Basic Bamboo nodes +minetest.register_craft({ + type = "fuel", + recipe = BAMBOO, + burntime = 2.5, -- supposed to be 1/2 that of a stick, per minecraft wiki as of JE 1.19.3 +}) + +minetest.register_craft({ + type = "fuel", + recipe = BAMBOO .. "_block", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = BAMBOO .. "_block_stripped", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = BAMBOO_PLANK, + burntime = 7.5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = BAMBOO .. "_mosaic", + burntime = 7.5, +}) + +-- Bamboo Items +if minetest.get_modpath("mcl_doors") then + if mcl_doors then + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:bamboo_door", + burntime = 10, + }) + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:bamboo_trapdoor", + burntime = 15, + }) + end +end + +if minetest.get_modpath("mcl_stairs") then + if mcl_stairs ~= nil then + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_plank", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_block", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_stripped", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:stair_bamboo_plank", + burntime = 15, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:stair_bamboo_block", + burntime = 15, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:stair_bamboo_stripped", + burntime = 15, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:slab_bamboo_mosaic", + burntime = 7.5, + }) + minetest.register_craft({ + type = "fuel", + recipe = "mcl_stairs:stair_bamboo_mosaic", + burntime = 15, + }) + end +end + +minetest.register_craft({ + type = "fuel", + recipe = "mesecons_button:button_bamboo_off", + burntime = 5, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_bamboo:scaffolding", + burntime = 20 +}) diff --git a/mods/ITEMS/mcl_banners/depends.txt b/mods/ITEMS/mcl_banners/depends.txt deleted file mode 100644 index d7ac71050..000000000 --- a/mods/ITEMS/mcl_banners/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_sounds? -mcl_core? -mcl_wool? -mcl_cauldrons? -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_banners/description.txt b/mods/ITEMS/mcl_banners/description.txt deleted file mode 100644 index 5e748a2ea..000000000 --- a/mods/ITEMS/mcl_banners/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds decorative banners in different colors which can be emblazoned with patterns, offering a countless number of combinations. diff --git a/mods/ITEMS/mcl_banners/init.lua b/mods/ITEMS/mcl_banners/init.lua index ce76f47fd..18b50928a 100644 --- a/mods/ITEMS/mcl_banners/init.lua +++ b/mods/ITEMS/mcl_banners/init.lua @@ -1,6 +1,11 @@ -local S = minetest.get_translator("mcl_banners") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) local N = function(s) return s end +local mod_mcl_core = minetest.get_modpath("mcl_core") +local mod_doc = minetest.get_modpath("doc") + local node_sounds if minetest.get_modpath("mcl_sounds") then node_sounds = mcl_sounds.node_sound_wood_defaults() @@ -35,13 +40,60 @@ mcl_banners.colors = { ["unicolor_light_blue"] = {"light_blue", S("Light Blue Banner"), "mcl_wool:light_blue", "#4040CF", "mcl_dye:lightblue", N("Light Blue") }, } + +local pattern_names = { + "", + "border", + "bricks", + "circle", + "creeper", + "cross", + "curly_border", + "diagonal_up_left", + "diagonal_up_right", + "diagonal_right", + "diagonal_left", + "flower", + "gradient", + "gradient_up", + "half_horizontal_bottom", + "half_horizontal", + "half_vertical", + "half_vertical_right", + "thing", + "rhombus", + "skull", + "small_stripes", + "square_bottom_left", + "square_bottom_right", + "square_top_left", + "square_top_right", + "straight_cross", + "stripe_bottom", + "stripe_center", + "stripe_downleft", + "stripe_downright", + "stripe_left", + "stripe_middle", + "stripe_right", + "stripe_top", + "triangle_bottom", + "triangle_top", + "triangles_bottom", + "triangles_top", +} + local colors_reverse = {} for k,v in pairs(mcl_banners.colors) do colors_reverse["mcl_banners:banner_item_"..v[1]] = k end +function mcl_banners.color_reverse(itemname) + return colors_reverse[itemname] +end + -- Add pattern/emblazoning crafting recipes -dofile(minetest.get_modpath("mcl_banners").."/patterncraft.lua") +dofile(modpath.."/patterncraft.lua") -- Overlay ratios (0-255) local base_color_ratio = 224 @@ -50,30 +102,33 @@ local layer_ratio = 255 local standing_banner_entity_offset = { x=0, y=-0.499, z=0 } local hanging_banner_entity_offset = { x=0, y=-1.7, z=0 } -local rotation_level_to_yaw = function(rotation_level) +local function rotation_level_to_yaw(rotation_level) return (rotation_level * (math.pi/8)) + math.pi end -local on_dig_banner = function(pos, node, digger) +local function on_dig_banner(pos, node, digger) -- Check protection local name = digger:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return end - -- Drop item - local meta = minetest.get_meta(pos) - local item = meta:get_inventory():get_stack("banner", 1) - if not item:is_empty() then - minetest.handle_node_drops(pos, {item:to_string()}, digger) - else - minetest.handle_node_drops(pos, {"mcl_banners:banner_item_white"}, digger) - end + + local inv = minetest.get_meta(pos):get_inventory() + local item = inv:get_stack("banner", 1) + local item_str = item:is_empty() and "mcl_banners:banner_item_white" + or item:to_string() + + minetest.handle_node_drops(pos, { item_str }, digger) + + item:set_count(0) + inv:set_stack("banner", 1, item) + -- Remove node minetest.remove_node(pos) end -local on_destruct_banner = function(pos, hanging) +local function on_destruct_banner(pos, hanging) local offset, nodename if hanging then offset = hanging_banner_entity_offset @@ -91,17 +146,24 @@ local on_destruct_banner = function(pos, hanging) v:remove() end end + + -- Drop item only if it was not handled in on_dig_banner + local inv = minetest.get_meta(pos):get_inventory() + local item = inv:get_stack("banner", 1) + if not item:is_empty() then + minetest.handle_node_drops(pos, {item:to_string()}) + end end -local on_destruct_standing_banner = function(pos) +local function on_destruct_standing_banner(pos) return on_destruct_banner(pos, false) end -local on_destruct_hanging_banner = function(pos) +local function on_destruct_hanging_banner(pos) return on_destruct_banner(pos, true) end -local make_banner_texture = function(base_color, layers) +function mcl_banners.make_banner_texture(base_color, layers) local colorize if mcl_banners.colors[base_color] then colorize = mcl_banners.colors[base_color][4] @@ -123,15 +185,15 @@ local make_banner_texture = function(base_color, layers) finished_banner = finished_banner .. "^" .. layer end - return { finished_banner } + return finished_banner end - return { base } + return base else - return { "mcl_banners_banner_base.png" } + return "mcl_banners_banner_base.png" end end -local spawn_banner_entity = function(pos, hanging, itemstack) +local function spawn_banner_entity(pos, hanging, itemstack) local banner if hanging then banner = minetest.add_entity(pos, "mcl_banners:hanging_banner") @@ -144,10 +206,10 @@ local spawn_banner_entity = function(pos, hanging, itemstack) local imeta = itemstack:get_meta() local layers_raw = imeta:get_string("layers") local layers = minetest.deserialize(layers_raw) - local colorid = colors_reverse[itemstack:get_name()] + local colorid = mcl_banners.color_reverse(itemstack:get_name()) banner:get_luaentity():_set_textures(colorid, layers) local mname = imeta:get_string("name") - if mname ~= nil and mname ~= "" then + if mname and mname ~= "" then banner:get_luaentity()._item_name = mname banner:get_luaentity()._item_description = imeta:get_string("description") end @@ -155,7 +217,7 @@ local spawn_banner_entity = function(pos, hanging, itemstack) return banner end -local respawn_banner_entity = function(pos, node, force) +local function respawn_banner_entity(pos, node, force) local hanging = node.name == "mcl_banners:hanging_banner" local offset if hanging then @@ -300,24 +362,72 @@ minetest.register_node("mcl_banners:hanging_banner", { end, }) +-- for pattern_name, pattern in pairs(patterns) do for colorid, colortab in pairs(mcl_banners.colors) do + for i, pattern_name in ipairs(pattern_names) do local itemid = colortab[1] local desc = colortab[2] local wool = colortab[3] local colorize = colortab[4] - local itemstring = "mcl_banners:banner_item_"..itemid - local inv - if colorize then - inv = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")" + local itemstring + if pattern_name == "" then + itemstring = "mcl_banners:banner_item_" .. itemid else - inv = "mcl_banners_item_base.png^mcl_banners_item_overlay.png" + itemstring = "mcl_banners:banner_preview" .. "_" .. pattern_name .. "_" .. itemid end + local inv + local base + local finished_banner + if pattern_name == "" then + if colorize then + -- Base texture with base color + base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:"..colorize..")^[resize:32x32" + else + base = "mcl_banners_item_base.png^mcl_banners_item_overlay.png^[resize:32x32" + end + finished_banner = base + else + -- Banner item preview background + base = "mcl_banners_item_base.png^(mcl_banners_item_overlay.png^[colorize:#CCCCCC)^[resize:32x32" + + desc = S("Preview Banner") + + local pattern = "mcl_banners_" .. pattern_name .. ".png" + local color = colorize + + -- Generate layer texture + + -- TODO: The layer texture in the icon is squished + -- weirdly because the width/height aspect ratio of + -- the banner icon is 1:1.5, whereas the aspect ratio + -- of the banner entity is 1:2. A solution would be to + -- redraw the pattern textures as low-resolution pixel + -- art and use that instead. + + local layer = "(([combine:20x40:-2,-2="..pattern.."^[resize:16x24^[colorize:"..color..":"..layer_ratio.."))" + + function escape(text) + return text:gsub("%^", "\\%^"):gsub(":", "\\:") -- :gsub("%(", "\\%("):gsub("%)", "\\%)") + end + + finished_banner = "[combine:32x32:0,0=" .. escape(base) .. ":8,4=" .. escape(layer) + end + + inv = finished_banner + -- Banner items. - -- This is the player-visible banner item. It comes in 16 base colors. + -- This is the player-visible banner item. It comes in 16 base colors with a lot of patterns. -- The multiple items are really only needed for the different item images. -- TODO: Combine the items into only 1 item. + local groups + if pattern_name == "" then + groups = { banner = 1, deco_block = 1, flammable = -1 } + else + groups = { not_in_creative_inventory = 1 } + end + minetest.register_craftitem(itemstring, { description = desc, _tt_help = S("Paintable decoration"), @@ -326,7 +436,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do wield_image = inv, -- Banner group groups together the banner items, but not the nodes. -- Used for crafting. - groups = { banner = 1, deco_block = 1, flammable = -1 }, + groups = groups, stack_max = 16, on_place = function(itemstack, placer, pointed_thing) @@ -451,7 +561,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do end meta:set_int("rotation_level", rotation_level) - if banner_entity ~= nil then + if banner_entity then banner_entity:set_yaw(final_yaw) end @@ -477,7 +587,7 @@ for colorid, colortab in pairs(mcl_banners.colors) do end, }) - if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_wool") then + if mod_mcl_core and minetest.get_modpath("mcl_wool") and pattern_name == "" then minetest.register_craft({ output = itemstring, recipe = { @@ -488,13 +598,14 @@ for colorid, colortab in pairs(mcl_banners.colors) do }) end - if minetest.get_modpath("doc") then + if mod_doc then -- Add item to node alias doc.add_entry_alias("nodes", "mcl_banners:standing_banner", "craftitems", itemstring) end + end end -if minetest.get_modpath("doc") then +if mod_doc then -- Add item to node alias doc.add_entry_alias("nodes", "mcl_banners:standing_banner", "nodes", "mcl_banners:hanging_banner") end @@ -507,7 +618,7 @@ local entity_standing = { visual = "mesh", mesh = "amc_banner.b3d", visual_size = { x=2.499, y=2.499 }, - textures = make_banner_texture(), + textures = {mcl_banners.make_banner_texture()}, pointable = false, _base_color = nil, -- base color of banner @@ -527,7 +638,7 @@ local entity_standing = { self._layers = inp._layers self._name = inp._name self.object:set_properties({ - textures = make_banner_texture(self._base_color, self._layers), + textures = {mcl_banners.make_banner_texture(self._base_color, self._layers)}, }) end -- Make banner slowly swing @@ -538,7 +649,7 @@ local entity_standing = { -- Set the banner textures. This function can be used by external mods. -- Meaning of parameters: -- * self: Lua entity reference to entity. - -- * other parameters: Same meaning as in make_banner_texture + -- * other parameters: Same meaning as in mcl_banners.make_banner_texture _set_textures = function(self, base_color, layers) if base_color then self._base_color = base_color @@ -546,7 +657,7 @@ local entity_standing = { if layers then self._layers = layers end - self.object:set_properties({textures = make_banner_texture(self._base_color, self._layers)}) + self.object:set_properties({textures = {mcl_banners.make_banner_texture(self._base_color, self._layers)}}) end, } minetest.register_entity("mcl_banners:standing_banner", entity_standing) diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.de.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.de.tr index 3bf65629b..d5077dc75 100644 --- a/mods/ITEMS/mcl_banners/locale/mcl_banners.de.tr +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.de.tr @@ -22,7 +22,7 @@ Magenta=magenta Orange Banner=Orange Banner Orange=orange Purple Banner=Violettes Banner -Purple=violett +Violet=violett Brown Banner=Braunes Banner Brown=braun Pink Banner=Rosa Banner diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.dk.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.dk.tr new file mode 100644 index 000000000..6b1f2fc7d --- /dev/null +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.dk.tr @@ -0,0 +1,77 @@ +# textdomain: mcl_banners +White Banner=Hvidt vanner +White=Hvid +Grey Banner=Gråt banner +Grey=Grå +Light Grey Banner=Lysegråt banner +Light Grey=Lysegrå +Black Banner=Sort banner +Black=Sort +Red Banner=Rødt banner +Red=Rød +Yellow Banner=Gult banner +Yellow=Gul +Green Banner=Grønt banner +Green=Grøn +Cyan Banner=Cyanblåt banner +Cyan=Cyanblå +Blue Banner=Blåt banner +Blue=Blå +Magenta Banner=Magenta banner +Magenta=Magenta +Orange Banner=Orange banner +Orange=Orange +Purple Banner=Lilla banner +Violet=Lilla +Brown Banner=Brunt banner +Brown=Brund +Pink Banner=Lyserødt banner +Pink=Lyserøde +Lime Banner=Limegrønt banner +Lime=Limegrøn +Light Blue Banner=Lyseblåt banner +Light Blue=Lyseblå +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.=Bannere er høje, farverige udsmykningsblokke. De kan placeres på gulve og vægge. Bannere kan præges med et væld af mønste ved at bruge meget farvestof ved produktion. +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.=Brug håndværk til at tegne et mønster på banneret. Prægede bannere kan præges igen for at skabe forskellige mønstre. Du kan lave op til 12 lag ovenpå hinanden. Hvis banneret har en gradient, kan du kun lave 3 lag. +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.=Du kan kopiere menteret på et banner ved at placere to bannere i den samme farve i håndværksgitteret. Det ene skal være præget, det andet rent. Du kan også bruge et banner på en keddel med vand for at vaske det øverste lag af. +@1 Bordure=@1 kantbånd +@1 Bricks=@1 mursten +@1 Roundel=@1 rundstok +@1 Creeper Charge=@1 creeper +@1 Saltire=@1 saltire +@1 Bordure Indented=@1 kantbånd med savtakker +@1 Per Bend Inverted=@1 nederste venstre diagnoal halvfarvning +@1 Per Bend Sinister Inverted=@1 nederste højre diagonal halvfarvning +@1 Per Bend=@1 øverste højre diagonal halvfarvning +@1 Per Bend Sinister=@1 øverste venstre diagonal halvfarvning +@1 Flower Charge=@1 blomst +@1 Gradient=@1 gradvist oppefra +@1 Base Gradient=@1 gradvist nedefra +@1 Per Fess Inverted=@1 nederste halvdel +@1 Per Fess=@1 øverste halvdel +@1 Per Pale=@1 venstre halvdel +@1 Per Pale Inverted=@1 højre halvdel +@1 Thing Charge=Mojang +@1 Lozenge=Rhombe +@1 Skull Charge=@1 dødningehovde +@1 Paly=@1 lodrette striber +@1 Base Dexter Canton=@1 nederste højre hjørne +@1 Base Sinister Canton=@1 nederste venstre hjørne +@1 Chief Dexter Canton=@1 øverste højre hjørne +@1 Chief Sinister Canton=@1 øverste venstre hjørne +@1 Cross=@1 kryds +@1 Base=@1 bundstribe +@1 Pale=@1 lodret centerstribe +@1 Bend Sinister=@1 diagonal stribe fra nederste venstre hjørne +@1 Bend=@1 diagonal stribe fra nederste højre hjørne +@1 Pale Dexter=@1 venstrestribe +@1 Fess=@1 vandret midterstribe +@1 Pale Sinister=@1 højrestribe +@1 Chief=@1 topstribe +@1 Chevron=@1 bundtrekant +@1 Chevron Inverted=@1 toptrekant +@1 Base Indented=@1 savtakker i bunden +@1 Chief Indented=@1 savtakker i toppen +And one additional layer=Og ét yderligere lag +And @1 additional layers=Og @1 yderligere lag +Paintable decoration=Udsmykning som kan males diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr index ee8772728..78095a4a7 100644 --- a/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.fr.tr @@ -1,36 +1,37 @@ # textdomain: mcl_banners -White Banner=Bannière Blanche +White Banner=Bannière blanche White=Blanc -Grey Banner=Bannière Grise +Grey Banner=Bannière grise Grey=Gris -Light Grey Banner=Bannière Gris Clair -Light Grey=Gris Clair -Black Banner=Bannière Noir +Light Grey Banner=Bannière gris clair +Light Grey=Gris clair +Black Banner=Bannière noire Black=Noir Red Banner=Bannière Rouge Red=Rouge -Yellow Banner=Bannière Jaune +Yellow Banner=Bannière jaune Yellow=Jaune -Green Banner=Bannière Verte +Green Banner=Bannière verte Green=Vert -Cyan Banner=Bannière Cyan +Cyan Banner=Bannière cyan Cyan=Cyan -Blue Banner=Bannière Bleue +Blue Banner=Bannière bleue Blue=Blue -Magenta Banner=Bannière Magenta +Magenta Banner=Bannière magenta Magenta=Magenta -Orange Banner=Bannière Orange +Orange Banner=Bannière orange Orange=Orange -Purple Banner=Bannière Violette +Purple Banner=Bannière violette Violet=Violet -Brown Banner=Bannière Marron +Brown Banner=Bannière marron Brown=Marron -Pink Banner=Bannière Rose +Pink Banner=Bannière rose Pink=Rose -Lime Banner=Bannière Vert Clair -Lime=Vert Clair -Light Blue Banner=Bannière Bleue Clair -Light Blue=Bleu Clair +Lime Banner=Bannière vert Clair +Lime=Vert clair +Light Blue Banner=Bannière bleue clair +Light Blue=Bleu clair +Banner=Bannière 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.=Les bannières sont de grands blocs décoratifs colorés. Ils peuvent être placés au sol et aux murs. Les bannières peuvent arborées une variété de motifs en utilisant beaucoup de colorant dans l'artisanat. 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.=Utilisez l'artisanat pour dessiner un motif sur le dessus de la bannière. Les bannières blasonnées peuvent être à nouveau blasonnées pour combiner différents motifs. Vous pouvez dessiner jusqu'à 12 couches sur une bannière de cette façon. Si la bannière comprend un dégradé, seulement 3 couches sont possibles. 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.=Vous pouvez copier le motif d'une bannière en plaçant deux bannières de la même couleur dans la grille de fabrication: l'une doit être décorée, l'autre doit être propre. Enfin, vous pouvez utiliser une bannière sur un chaudron avec de l'eau pour laver sa couche la plus haute. @@ -46,12 +47,12 @@ You can copy the pattern of a banner by placing two banners of the same color in @1 Per Bend Sinister=Division oblique (@1) @1 Flower Charge=Figure Fleur (@1) @1 Gradient=Dégradé (@1) -@1 Base Gradient=Dégradé de couleurs (@1) +@1 Base Gradient=Dégradé de couleurs (@1) @1 Per Fess Inverted=Division inverse (@1) @1 Per Fess=Division (@1) @1 Per Pale=Division (@1) @1 Per Pale Inverted=Division inverse (@1) -@1 Thing Charge=Chose (@ 1) +@1 Thing Charge=Chose (@1) @1 Lozenge=Rhombus (@1) @1 Skull Charge=Figure de crâne (@1) @1 Paly=Pieux (@1) @@ -73,5 +74,5 @@ You can copy the pattern of a banner by placing two banners of the same color in @1 Base Indented=Pied dentelé (@1)t @1 Chief Indented=Tête dentelée (@1) And one additional layer=Et une couche supplémentaire -And @1 additional layer(s)=Et @1 couche(s) supplémentaire(s) +And @1 additional layers=Et @1 couches supplémentaires Paintable decoration=Décoration à peindre diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr new file mode 100644 index 000000000..7d2fd5b9e --- /dev/null +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.ja.tr @@ -0,0 +1,77 @@ +# textdomain: mcl_banners +White Banner=白色の旗 +White=白色 +Grey Banner=灰色の旗 +Grey=灰色 +Light Grey Banner=薄灰色の旗 +Light Grey=薄灰色 +Black Banner=黒色の旗 +Black=黒色 +Red Banner=赤色の旗 +Red=赤色 +Yellow Banner=黄色の旗 +Yellow=黄色 +Green Banner=緑色の旗 +Green=緑色 +Cyan Banner=青緑色の旗 +Cyan=青緑色 +Blue Banner=青色の旗 +Blue=青色 +Magenta Banner=赤紫色の旗 +Magenta=赤紫色 +Orange Banner=橙色の旗 +Orange=橙色 +Purple Banner=紫色の旗 +Violet=紫色 +Brown Banner=茶色の旗 +Brown=茶色 +Pink Banner=桃色の旗 +Pink=桃色 +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.=同じ色の旗を2枚並べて、旗の模様を写せます。1枚はエンブレム入りで、もう1枚はまっさらな状態であることが必要です。最後に、旗を大釜の上に置いて使うことで、その一番上のレイヤーを水で洗い流す事もできます。 +@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=さらにレイヤーを1枚追加 +And @1 additional layers=さらにレイヤーを@1枚追加 +Paintable decoration=塗装可能な装飾 diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.pl.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.pl.tr new file mode 100644 index 000000000..9a21c08cf --- /dev/null +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.pl.tr @@ -0,0 +1,77 @@ +# textdomain: mcl_banners +White Banner=Biały sztandar +White=Biały +Grey Banner=Szary sztandar +Grey=Szary +Light Grey Banner=Jasnoszary sztandar +Light Grey=Jasnoszary +Black Banner=Czarny sztandar +Black=Czarny +Red Banner=Czerwony sztandar +Red=Czerwony +Yellow Banner=Żółty sztandar +Yellow=Żółty +Green Banner=Zielony sztandar +Green=Zielony +Cyan Banner=Błękitny sztandar +Cyan=Błękitny +Blue Banner=Niebieski sztandar +Blue=Niebieski +Magenta Banner=Karmazynowy sztandar +Magenta=Karmazynowy +Orange Banner=Pomarańczowy sztandar +Orange=Pomarańczowy +Purple Banner=Fioletowy sztandar +Violet=Fioletowy +Brown Banner=Brązowy sztandar +Brown=Brązowy +Pink Banner=Różowy sztandar +Pink=Różowy +Lime Banner=Jasnozielony sztandar +Lime=Jasnozielony +Light Blue Banner=Jasnoniebieski sztandar +Light Blue=Jasnoniebieski +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.=Sztandary są kolorowymi dekoracyjnymi blokami. Mogą być postawione na ziemi i na ścianach. Sztandary mogą być upiększone różnymi wzorami przy użyciu sporej ilości farby podczas wytwarzania. +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.=Użyj wytwarzania aby narysować wzór na górze sztandaru. Upiększone sztandary mogą być upiększone ponownie by połączyć kilka wzorów. Możesz narysować do 12 warstw na sztandarze w ten sposób. Jeśli baner zawiera gradient tylko 3 warstwy są możliwe. +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.=Możesz skopiować wzór sztandaru kładąc dwa sztandary tego samego koloru w siatce wytwarzania. Jeden z nich musi być upiększony, drugi czysty. Możesz również użyć sztandar na kociołku z wodą aby zmyć górną warstwę. +@1 Bordure=@1 z obramowaniem +@1 Bricks=@1 murowany +@1 Roundel=@1 krąg +@1 Creeper Charge=@1 creeper +@1 Saltire=@1 skośny krzyż +@1 Bordure Indented=@1 z ząbkowanym obramowaniem +@1 Per Bend Inverted=@1 z lewą dolną połową +@1 Per Bend Sinister Inverted=@1 z prawą dolną połową +@1 Per Bend=@1 z prawą górną połową +@1 Per Bend Sinister=@1 z lewą górną połową +@1 Flower Charge=@1 kwiat +@1 Gradient=@1 gradient +@1 Base Gradient=@1 odwrócony +@1 Per Fess Inverted=@1 z dolną połową +@1 Per Fess=@1 z górną połową +@1 Per Pale=@1 z lewą połową +@1 Per Pale Inverted=@1 z prawą połową +@1 Thing Charge=@1 kształt czegoś +@1 Lozenge=@1 romb +@1 Skull Charge=@1 kształt czaszki +@1 Paly=@1 z pionowymi paskami +@1 Base Dexter Canton=@1 lewy dolny róg +@1 Base Sinister Canton=@1 prawy dolny róg +@1 Chief Dexter Canton=@1 lewy górny róg +@1 Chief Sinister Canton=@1 prawy górny róg +@1 Cross=@1 krzyż +@1 Base=@1 dolny +@1 Pale=@1 pionowy pasek +@1 Bend Sinister=@1 odwrócony skos +@1 Bend=@1 skos +@1 Pale Dexter=@1 lewy +@1 Fess=@1 poziomy pasek +@1 Pale Sinister=@1 prawy +@1 Chief=@1 górny +@1 Chevron=@1 dolny trójkąt +@1 Chevron Inverted=@1 górny trójkąt +@1 Base Indented=@1 ząbkowany dolny +@1 Chief Indented=@1 ząbkowany górny +And one additional layer=I jedna dodatkowa warstwa +And @1 additional layers=I @1 dodatkowych warstw +Paintable decoration=Dekoracja do malowania diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.pt_BR.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.pt_BR.tr new file mode 100644 index 000000000..2b9fd862d --- /dev/null +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.pt_BR.tr @@ -0,0 +1,77 @@ +# textdomain: mcl_banners +White Banner=Estandarte Branco +White=Branco +Grey Banner=Estandarte Cinza +Grey=Cinza +Light Grey Banner=Estandarte Cinza Claro +Light Grey=Cinza Claro +Black Banner=Estandarte Preto +Black=Preto +Red Banner=Estandarte Vermelho +Red=Vermelho +Yellow Banner=Estandarte Amarelo +Yellow=Amarelo +Green Banner=Estandarte Verde +Green=Verde +Cyan Banner=Estandarte Ciano +Cyan=Ciano +Blue Banner=Estandarte Azul +Blue=Azul +Magenta Banner=Estandarte Magenta +Magenta=Magenta +Orange Banner=Estandarte Laranja +Orange=Laranja +Purple Banner=Estandarte Roxo +Violet=Violeta +Brown Banner=Estandarte Marrom +Brown=Marrom +Pink Banner=Estandarte Rosa +Pink=Rosa +Lime Banner=Estandarte Lima +Lime=Lima +Light Blue Banner=Estandarte Azul Claro +Light Blue=Azul Claro +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.=Estandartes são altos e coloridos blocos decorativos. Podem ser colocados no chão ou em paredes. Estandartes podem ser brasonados com uma variedade de padrões usando muitos corantes na mesa de trabalho. +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.=Use a mesa de trabalho para desenhar um padrão sob o estandarte. Estandartes brasonados podem ser brasonados novamente para combinar diversos padrões. Você pode desenhar até 12 camadas em um estandarte dessa maneira. Se o estandarte possuir gradiente, apenas 3 camadas são possíveis. +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.=Você pode copiar o padrão de um estandarte colocando dois estandartes da mesma cor na mesa de trabalho - um necessita estar brasonado, o outro, limpo. Finalmente, você pode usar um estandarte em um calderão com água para lavar fora a camada mais recente. +@1 Bordure= +@1 Bricks= +@1 Roundel= +@1 Creeper Charge= +@1 Saltire= +@1 Bordure Indented= +@1 Per Bend Inverted= +@1 Per Bend Sinister Inverted= +@1 Per Bend= +@1 Per Bend Sinister= +@1 Flower Charge= +@1 Gradient= +@1 Base Gradient= +@1 Per Fess Inverted= +@1 Per Fess= +@1 Per Pale= +@1 Per Pale Inverted= +@1 Thing Charge= +@1 Lozenge= +@1 Skull Charge= +@1 Paly= +@1 Base Dexter Canton= +@1 Base Sinister Canton= +@1 Chief Dexter Canton= +@1 Chief Sinister Canton= +@1 Cross= +@1 Base= +@1 Pale= +@1 Bend Sinister= +@1 Bend= +@1 Pale Dexter= +@1 Fess= +@1 Pale Sinister= +@1 Chief= +@1 Chevron= +@1 Chevron Inverted= +@1 Base Indented= +@1 Chief Indented= +And one additional layer=E uma camada adicional +And @1 additional layers=E @1 camada adicional +Paintable decoration=Decoração pintável diff --git a/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr b/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr index 01993ae2f..a6cee5a67 100644 --- a/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr +++ b/mods/ITEMS/mcl_banners/locale/mcl_banners.ru.tr @@ -73,5 +73,5 @@ You can copy the pattern of a banner by placing two banners of the same color in @1 Base Indented=@1 Инвертированный основной @1 Chief Indented=@1 Инвертированный главный And one additional layer=И один индивидуальный слой -And @1 additional layer(s)=И @1 дополнительный(х) слой(я,ёв) +And @1 additional layers=И @1 дополнительныйх слойёв Paintable decoration=Художественное украшение diff --git a/mods/ITEMS/mcl_banners/locale/template.txt b/mods/ITEMS/mcl_banners/locale/template.txt index 944a1a7ac..357ff6b08 100644 --- a/mods/ITEMS/mcl_banners/locale/template.txt +++ b/mods/ITEMS/mcl_banners/locale/template.txt @@ -31,6 +31,7 @@ Lime Banner= Lime= 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.= 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.= @@ -73,5 +74,5 @@ You can copy the pattern of a banner by placing two banners of the same color in @1 Base Indented= @1 Chief Indented= And one additional layer= -And @1 additional layer(s)= +And @1 additional layers= Paintable decoration= diff --git a/mods/ITEMS/mcl_banners/mod.conf b/mods/ITEMS/mcl_banners/mod.conf index 211266581..8c3117206 100644 --- a/mods/ITEMS/mcl_banners/mod.conf +++ b/mods/ITEMS/mcl_banners/mod.conf @@ -1 +1,5 @@ name = mcl_banners +author = 22i +description = Adds decorative banners in different colors which can be emblazoned with patterns, offering a countless number of combinations. +depends = mcl_colors +optional_depends = mcl_sounds, mcl_core, mcl_wool, mcl_cauldrons, doc, screwdriver diff --git a/mods/ITEMS/mcl_banners/patterncraft.lua b/mods/ITEMS/mcl_banners/patterncraft.lua index e1f05ff11..767235b1e 100644 --- a/mods/ITEMS/mcl_banners/patterncraft.lua +++ b/mods/ITEMS/mcl_banners/patterncraft.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_banners") +local S = minetest.get_translator(minetest.get_current_modname()) local N = function(s) return s end -- Pattern crafting. This file contains the code for crafting all the @@ -8,9 +8,6 @@ local N = function(s) return s end -- Maximum number of layers which can be put on a banner by crafting. local max_layers_crafting = 12 --- Maximum number of layers when banner includes a gradient (workaround, see below). -local max_layers_gradient = 3 - -- Max. number lines in the descriptions for the banner layers. -- This is done to avoid huge tooltips. local max_layer_lines = 6 @@ -122,8 +119,7 @@ local patterns = { name = N("@1 Thing Charge"), type = "shapeless", - -- TODO: Replace with enchanted golden apple - { e, "mcl_core:apple_gold", d }, + { e, "mcl_core:apple_gold_enchanted", d }, }, ["rhombus"] = { name = N("@1 Lozenge"), @@ -253,8 +249,13 @@ for colorid, colortab in pairs(mcl_banners.colors) do dye_to_colorid_mapping[colortab[5]] = colorid end +local dye_to_itemid_mapping = {} +for colorid, colortab in pairs(mcl_banners.colors) do + dye_to_itemid_mapping[colortab[5]] = colortab[1] +end + -- Create a banner description containing all the layer names -mcl_banners.make_advanced_banner_description = function(description, layers) +function mcl_banners.make_advanced_banner_description(description, layers) if layers == nil or #layers == 0 then -- No layers, revert to default return "" @@ -281,7 +282,7 @@ mcl_banners.make_advanced_banner_description = function(description, layers) -- Final string concatenations: Just a list of strings local append = table.concat(layerstrings, "\n") - description = description .. "\n" .. minetest.colorize("#8F8F8F", append) + description = description .. "\n" .. minetest.colorize(mcl_colors.GRAY, append) return description end end @@ -291,7 +292,7 @@ Parameters same as for minetest.register_craft_predict. craft_predict is set true when called from minetest.craft_preview, in this case, this function MUST NOT change the crafting grid. ]] -local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_inv, craft_predict) +local function banner_pattern_craft(itemstack, player, old_craft_grid, craft_inv, craft_predict) if minetest.get_item_group(itemstack:get_name(), "banner") ~= 1 then return end @@ -393,16 +394,6 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i if #layers >= max_layers_crafting then return ItemStack("") end - -- Lower layer limit when banner includes any gradient. - -- Workaround to circumvent Minetest bug (https://github.com/minetest/minetest/issues/6210) - -- TODO: Remove this restriction when bug #6210 is fixed. - if #layers >= max_layers_gradient then - for l=1, #layers do - if layers[l].pattern == "gradient" or layers[l].pattern == "gradient_up" then - return ItemStack("") - end - end - end local matching_pattern local max_i = player:get_inventory():get_size("craft") @@ -421,7 +412,6 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i if (pitem == d and minetest.get_item_group(itemname, "dye") == 0) or (pitem == e and itemname ~= e and inv_i ~= banner_index) then pattern_ok = false break - else end inv_i = inv_i + 1 if inv_i > max_i then @@ -491,7 +481,14 @@ local banner_pattern_craft = function(itemstack, player, old_craft_grid, craft_i imeta:set_string("description", ometa:get_string("description")) imeta:set_string("name", mname) end - return itemstack + + if craft_predict then + local itemid_prefix = "mcl_banners:banner_preview" + local coloritemid = dye_to_itemid_mapping[dye] + return ItemStack(itemid_prefix .. "_" .. matching_pattern .. "_" .. coloritemid) + else + return itemstack + end end minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv) diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_triangle_top.png b/mods/ITEMS/mcl_banners/textures/mcl_banners_triangle_top.png deleted file mode 100644 index 7f626c26d..000000000 Binary files a/mods/ITEMS/mcl_banners/textures/mcl_banners_triangle_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_barrels/init.lua b/mods/ITEMS/mcl_barrels/init.lua new file mode 100644 index 000000000..714a80f09 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/init.lua @@ -0,0 +1,206 @@ +local S = minetest.get_translator("mcl_barrels") +local F = minetest.formspec_escape +local C = minetest.colorize + +--TODO: fix barrel rotation placement + +local open_barrels = {} + +local drop_content = mcl_util.drop_items_from_meta_container("main") + +local function on_blast(pos) + local node = minetest.get_node(pos) + drop_content(pos, node) + minetest.remove_node(pos) +end + +-- Simple protection checking functions +local function protection_check_move(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + 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 + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end +end + +local function barrel_open(pos, node, clicker) + local name = minetest.get_meta(pos):get_string("name") + + if name == "" then + name = S("Barrel") + end + + local playername = clicker:get_player_name() + + minetest.show_formspec(playername, + "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]", + "listring[current_player;main]", + }) + ) + + 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) +end + +local function close_forms(pos) + local players = minetest.get_connected_players() + 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) + end + end +end + +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) + end +end + +local function close_barrel(player) + local name = player:get_player_name() + local open = open_barrels[name] + if open == nil then + return + end + + update_after_close(open) + + open_barrels[name] = nil +end + +minetest.register_node("mcl_barrels:barrel_closed", { + description = S("Barrel"), + _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"}, + 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) + 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}, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + 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")) + end, + 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)) + 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)) + 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)) + end, + after_dig_node = drop_content, + on_blast = on_blast, + on_rightclick = barrel_open, + on_destruct = close_forms, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5, +}) + +minetest.register_node("mcl_barrels:barrel_open", { + description = S("Barrel Open"), + _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."), + _doc_items_create_entry = false, + 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}, + 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)) + 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)) + 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)) + end, + after_dig_node = drop_content, + on_blast = on_blast, + on_rightclick = barrel_open, + on_destruct = close_forms, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname:find("mcl_barrels:") == 1 and fields.quit then + close_barrel(player) + end +end) + +minetest.register_on_leaveplayer(function(player) + close_barrel(player) +end) + +--Minecraft Java Edition craft +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"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_barrels:barrel_closed", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.de.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.de.tr new file mode 100644 index 000000000..e1fa1b603 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.de.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel= +Barrels are containers which provide 27 inventory slots.= +To access its inventory, rightclick it. When broken, the items will drop out.= +27 inventory slots= \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.dk.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.dk.tr new file mode 100644 index 000000000..316305623 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.dk.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel=Tønde +Barrels are containers which provide 27 inventory slots.=Tønder er beholdere som kan give 27 oppakningspladser. +To access its inventory, rightclick it. When broken, the items will drop out.=For at tilgå dens indhold kan du højre-klikke. Når den ødelægges falder genstandene ud. +27 inventory slots=27 indholdsspladser. \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.es.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.es.tr new file mode 100644 index 000000000..33f10f77a --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.es.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel=Barril +Barrels are containers which provide 27 inventory slots.=Los barriles son contenedores que proveen 27 ranuras de inventario. +To access its inventory, rightclick it. When broken, the items will drop out.=Para acceder a su inventario, haz click derecho sobre el. Al romperse, los objetos caerán al suelo. +27 inventory slots=27 ranuras de inventario diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.fr.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.fr.tr new file mode 100644 index 000000000..0e93d1ee5 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel=Tonneau +Barrels are containers which provide 27 inventory slots.=Les tonneaux sont des conteneurs qui offrent 27 emplacements d'inventaire. +To access its inventory, rightclick it. When broken, the items will drop out.=Pour accéder à son inventaire, faites un clic droit dessus. Une fois cassés, les articles tomberont. +27 inventory slots=27 emplacements d'inventaire \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr new file mode 100644 index 000000000..3715310c0 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ja.tr @@ -0,0 +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 diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pl.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pl.tr new file mode 100644 index 000000000..e1fa1b603 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel= +Barrels are containers which provide 27 inventory slots.= +To access its inventory, rightclick it. When broken, the items will drop out.= +27 inventory slots= \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pt_BR.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pt_BR.tr new file mode 100644 index 000000000..b5a597f40 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel=Barril +Barrels are containers which provide 27 inventory slots.=Barris são recipientes que fornecem 27 espaços no inventário. +To access its inventory, rightclick it. When broken, the items will drop out.=Para acessar seu inventário, clique com o botão direito nele. Quando quebrado, os itens serão derrubados ao chão. +27 inventory slots=27 espaços de inventário diff --git a/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr new file mode 100644 index 000000000..2d860c532 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/mcl_barrels.ru.tr @@ -0,0 +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 diff --git a/mods/ITEMS/mcl_barrels/locale/template.txt b/mods/ITEMS/mcl_barrels/locale/template.txt new file mode 100644 index 000000000..e1fa1b603 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: mcl_barrels +Barrel= +Barrels are containers which provide 27 inventory slots.= +To access its inventory, rightclick it. When broken, the items will drop out.= +27 inventory slots= \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/mod.conf b/mods/ITEMS/mcl_barrels/mod.conf new file mode 100644 index 000000000..2b0088b79 --- /dev/null +++ b/mods/ITEMS/mcl_barrels/mod.conf @@ -0,0 +1,3 @@ +name = mcl_barrels +depends = mcl_util, mcl_formspec, mcl_sounds +author = AFCMS \ No newline at end of file diff --git a/mods/ITEMS/mcl_barrels/sounds/attribution.txt b/mods/ITEMS/mcl_barrels/sounds/attribution.txt new file mode 100644 index 000000000..38743d3ef --- /dev/null +++ b/mods/ITEMS/mcl_barrels/sounds/attribution.txt @@ -0,0 +1,2 @@ +barrel-open.ogg and barrel-close.ogg taken from https://freesound.org/people/quantumriver/sounds/552153/ +Licence: Creative Commons 0 (CC0) diff --git a/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_close.ogg b/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_close.ogg new file mode 100644 index 000000000..ccbb18c0f Binary files /dev/null and b/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_close.ogg differ diff --git a/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_open.ogg b/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_open.ogg new file mode 100644 index 000000000..c2c9f1d35 Binary files /dev/null and b/mods/ITEMS/mcl_barrels/sounds/mcl_barrels_default_barrel_open.ogg differ diff --git a/mods/ITEMS/mcl_beacons/init.lua b/mods/ITEMS/mcl_beacons/init.lua new file mode 100644 index 000000000..9941e9e50 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/init.lua @@ -0,0 +1,405 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +--[[ +there are strings in meta, which are being used to see which effect will be given to the player(s) +Valid strings: + swiftness + leaping + strenght + regeneration +]]-- + +mcl_beacons = { + blocks ={"mcl_core:diamondblock","mcl_core:ironblock","mcl_core:goldblock","mcl_core:emeraldblock","mcl_nether:netheriteblock"}, + fuel = {"mcl_core:diamond","mcl_core:emerald","mcl_core:iron_ingot","mcl_core:gold_ingot","mcl_nether:netherite_ingot"} +} +local beacon_blocklist = mcl_beacons.blocks +local beacon_fuellist = mcl_beacons.fuel + +local pallete_order = { + glass_cyan = 1, + pane_cyan_flat = 1, + pane_cyan = 1, + + glass_white = 2, + pane_white_flat = 2, + pane_white = 2, + + glass_brown = 3, + pane_brown_flat = 3, + pane_brown = 3, + + glass_blue = 4, + pane_blue_flat = 4, + pane_blue = 4, + + glass_light_blue = 5, + pane_light_blue_flat = 5, + pane_light_blue = 5, + + glass_pink = 6, + pane_pink_flat = 6, + pane_pink = 6, + + glass_purple = 7, + pane_purple_flat = 7, + pane_purple = 7, + + glass_red = 8, + pane_red_flat = 8, + pane_red = 8, + + glass_silver = 9, + pane_silver_flat = 9, + pane_silver = 9, + + glass_gray = 10, + pane_gray_flat = 10, + pane_gray = 10, + + glass_lime = 11, + pane_lime_flat = 11, + pane_lime = 11, + + glass_green = 12, + pane_green_flat = 12, + pane_green = 12, + + glass_orange = 13, + pane_orange_flat = 13, + pane_orange = 13, + + glass_yellow = 14, + pane_yellow_flat = 14, + pane_yellow = 14, + + glass_black = 15, + pane_black_flat = 15, + pane_black = 15, + + glass_magenta = 16, + pane_magenta_flat = 16, + pane_magenta = 16 +} + +local function get_beacon_beam(glass_nodename) + if glass_nodename == "air" then return 0 end + local glass_string = glass_nodename:split(':')[2] + if not pallete_order[glass_string] then return 0 end + return pallete_order[glass_string] +end + +minetest.register_node("mcl_beacons:beacon_beam", { + tiles = {"blank.png^[noalpha^[colorize:#b8bab9"}, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.1250, -0.5000, -0.1250, 0.1250, 0.5000, 0.1250} + } + }, + pointable= false, + light_source = 14, + walkable = false, + groups = {not_in_creative_inventory=1}, + _mcl_blast_resistance = 1200, + paramtype2 = "color", + palette = "beacon_beam_palette.png", + palette_index = 0, + buildable_to = true, +}) + +mesecon.register_mvps_stopper("mcl_beacons:beacon_beam") + +local formspec_string= + "size[11,14]".. + + "label[4.5,0.5;"..minetest.formspec_escape(S("Beacon:")).."]".. + "label[0.5,1;"..minetest.formspec_escape(S("Primary Power:")).."]".. + "label[0.5,8.25;"..minetest.formspec_escape( S("Inventory:")).."]".. + + "image[1,1.5;1,1;custom_beacom_symbol_4.png]".. + "image[1,3;1,1;custom_beacom_symbol_3.png]".. + "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,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;]".. + + "item_image[1,7;1,1;mcl_core:diamond]".. + "item_image[2.2,7;1,1;mcl_core:emerald]".. + "item_image[3.4,7;1,1;mcl_core:iron_ingot]".. + "item_image[4.6,7;1,1;mcl_core:gold_ingot]".. + "item_image[5.8,7;1,1;mcl_nether:netherite_ingot]".. + + mcl_formspec.get_itemslot_bg(7.2,7,1,1).. + "list[context;input;7.2,7;1,1;]".. + mcl_formspec.get_itemslot_bg(1,9,9,3).. + "list[current_player;main;1,9;9,3;9]".. + mcl_formspec.get_itemslot_bg(1,12.5,9,1).. + "list[current_player;main;1,12.5;9,1;]" + +local function remove_beacon_beam(pos) + for y=pos.y, pos.y+301 do + local node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + if node.name ~= "air" and node.name ~= "mcl_core:bedrock" and node.name ~= "mcl_core:void" then + if node.name == "ignore" then + 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 + end + end +end + +local function beacon_blockcheck(pos) + for y_offset = 1,4 do + local block_y = pos.y - y_offset + for block_x = (pos.x-y_offset),(pos.x+y_offset) do + for block_z = (pos.z-y_offset),(pos.z+y_offset) do + local valid_block = false --boolean which stores if block is valid or not + for _, beacon_block in pairs(beacon_blocklist) do + if beacon_block == minetest.get_node({x=block_x,y=block_y,z=block_z}).name and not valid_block then --is the block in the pyramid a valid beacon block + valid_block =true + end + end + if not valid_block then + return y_offset -1 --the last layer is complete, this one is missing or incomplete + end + end + end + if y_offset == 4 then --all checks are done, beacon is maxed + return y_offset + end + end +end + +local function clear_obstructed_beam(pos) + for y=pos.y+1, pos.y+100 do + local nodename = minetest.get_node({x=pos.x,y=y, z = pos.z}).name + if nodename ~= "mcl_core:bedrock" and nodename ~= "air" and nodename ~= "mcl_core:void" and nodename ~= "ignore" then --ignore means not loaded, let's just assume that's air + if nodename ~="mcl_beacons:beacon_beam" then + if minetest.get_item_group(nodename,"glass") == 0 and minetest.get_item_group(nodename,"material_glass") == 0 then + remove_beacon_beam(pos) + return true + end + end + end + end + + return false +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 +end + +local function apply_effects_to_all_players(pos) + local meta = minetest.get_meta(pos) + local effect_string = meta:get_string("effect") + local effect_level = meta:get_int("effect_level") + + 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 + return + end + + 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 + end +end + +minetest.register_node("mcl_beacons:beacon", { + description = S"Beacon", + drawtype = "mesh", + collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, + mesh = "mcl_beacon.b3d", + tiles = {"beacon_UV.png"}, + use_texture_alpha = "clip", + on_construct = function(pos) + 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) + end, + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local input = meta:get_inventory():get_stack("input",1) + if not input: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} --from mcl_anvils + minetest.add_item(p, input) + end + 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 + local sender_name = sender:get_player_name() + local power_level = beacon_blockcheck(pos) + if minetest.is_protected(pos, sender_name) then + minetest.record_protection_violation(pos, sender_name) + return + elseif power_level == 0 then + return + end + + 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 + + local valid_item = false + + for _, item in ipairs(beacon_fuellist) do + if input:get_name() == item then + valid_item = true + end + end + + if not valid_item then + return + end + + local successful = false + if fields.swiftness 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","swiftness") + successful = true + elseif fields.leaping 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","leaping") + successful = true + elseif fields.strenght 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","strenght") + 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 + end + if successful then + if power_level == 4 then + awards.unlock(sender:get_player_name(),"mcl:maxed_beacon") + end + 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 + local node = minetest.get_node({x=pos.x,y=y,z=pos.z}) + if node.name == ignore then + 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) + end + + if node.name == "air" then + minetest.set_node({x=pos.x,y=y,z=pos.z},{name="mcl_beacons:beacon_beam",param2=beam_palette_index}) + end + end + apply_effects_to_all_players(pos) --call it once outside the globalstep so the player gets the effect right after selecting it + end + end + end, + light_source = 14, + groups = {handy=1}, + drop = "mcl_beacons:beacon", + sounds = mcl_sounds.node_sound_glass_defaults(), + _mcl_hardness = 3, +}) + +mesecon.register_mvps_stopper("mcl_beacons:beacon") +mcl_wip.register_wip_item("mcl_beacons:beacon") + +function register_beaconblock (itemstring)--API function for other mods + table.insert(beacon_blocklist, itemstring) +end + +function register_beaconfuel(itemstring) + table.insert(beacon_fuellist, itemstring) +end + +minetest.register_abm{ + label="update beacon beam", + nodenames = {"mcl_beacons:beacon_beam"}, + interval = 1, + chance = 1, + action = function(pos) + local node_below = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + local node_above = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}) + local node_current = minetest.get_node(pos) + + if node_below.name == "air" then + if minetest.get_node({x=pos.x,y=pos.y-2,z=pos.z}).name == "mcl_beacons:beacon" then + minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=0}) + end + remove_beacon_beam(pos) + elseif node_above.name == "air" or (node_above.name == "mcl_beacons:beacon_beam" and node_above.param2 ~= node_current.param2) then + minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z},{name="mcl_beacons:beacon_beam",param2=node_current.param2}) + elseif minetest.get_item_group(node_above.name, "glass") ~= 0 or minetest.get_item_group(node_above.name,"material_glass") ~= 0 then + minetest.set_node({x=pos.x,y=pos.y+2,z=pos.z},{name="mcl_beacons:beacon_beam",param2=get_beacon_beam(node_above.name)}) + end + end, +} + +minetest.register_abm{ + label="apply beacon effects to players", + nodenames = {"mcl_beacons:beacon"}, + interval = 3, + chance = 1, + action = function(pos) + apply_effects_to_all_players(pos) + end, +} + +minetest.register_craft({ + output = "mcl_beacons:beacon", + 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_beacons/locale/mcl_beacons.de.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.de.tr new file mode 100644 index 000000000..d6f194a6c --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.de.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beacons +Beacon=Leuchtfeuer +Beacon:=Leuchtfeuer: +Primary Power:=Primäre Kraft: +Inventory:=Inventar: diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.dk.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.dk.tr new file mode 100644 index 000000000..cd019fe7c --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.dk.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_beacons +Beacon=Magisk fyrtårn +Beacon:=Magisk fyrtårn: +Primary Power:=Primær kraft: +Inventory:=Indhold: + diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr new file mode 100644 index 000000000..d95a6225e --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beacons +Beacon=Balise +Beacon:=Balise : +Primary Power:=Pouvoir primaire : +Inventory:=Inventaire : diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr new file mode 100644 index 000000000..ad2e79511 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.ja.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_beacons +Beacon=ビーコン +Beacon:=ビーコン: +Primary Power:=プライマリーパワー: +Inventory:=インベントリ: + diff --git a/mods/ITEMS/mcl_beacons/locale/mcl_beacons.pt_BR.tr b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.pt_BR.tr new file mode 100644 index 000000000..3446c32d7 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/mcl_beacons.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beacons +Beacon=Sinalizador +Beacon:=Sinalizador: +Primary Power:=Poder Primário: +Inventory:=Inventário: diff --git a/mods/ITEMS/mcl_beacons/locale/template.txt b/mods/ITEMS/mcl_beacons/locale/template.txt new file mode 100644 index 000000000..8f604d598 --- /dev/null +++ b/mods/ITEMS/mcl_beacons/locale/template.txt @@ -0,0 +1,6 @@ +# textdomain: mcl_beacons +Beacon= +Beacon:= +Primary Power:= +Inventory:= + diff --git a/mods/ITEMS/mcl_beacons/mod.conf b/mods/ITEMS/mcl_beacons/mod.conf new file mode 100644 index 000000000..a8b7a467a --- /dev/null +++ b/mods/ITEMS/mcl_beacons/mod.conf @@ -0,0 +1,3 @@ +name = mcl_beacons +author=chmodsayshello +depends=mcl_formspec, mcl_init, mcl_wip, mesecons_mvps, mcl_core, mcl_sounds, awards, mcl_achievements, mcl_mobitems, mcl_nether diff --git a/mods/ITEMS/mcl_beacons/models/mcl_beacon.b3d b/mods/ITEMS/mcl_beacons/models/mcl_beacon.b3d new file mode 100644 index 000000000..b491586d8 Binary files /dev/null and b/mods/ITEMS/mcl_beacons/models/mcl_beacon.b3d differ diff --git a/mods/ITEMS/mcl_beds/README.txt b/mods/ITEMS/mcl_beds/README.txt index cda6ebd92..c0d2549f2 100644 --- a/mods/ITEMS/mcl_beds/README.txt +++ b/mods/ITEMS/mcl_beds/README.txt @@ -12,15 +12,10 @@ Authors of media (textures) BlockMen (CC BY-SA 3.0) This mod adds a bed to Minetest which allows to skip the night. -To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped -immediately. If playing multiplayer you get shown how many other players are in bed too, -if all players are sleeping the night gets skipped. The night skip can be forced if more -than 50% of the players are lying in bed and use this option. - -Another feature is a controlled respawning. If you have slept in bed (not just lying in -it) your respawn point is set to the beds location and you will respawn there after +To sleep, rightclick the bed. +Another feature is a controlled respawning. If you have slept in bed your respawn point is set to the beds location and you will respawn there after death. -You can disable the respawn at beds by setting "enable_bed_respawn = false" in -minetest.conf. -You can disable the night skip feature by setting "enable_bed_night_skip = false" in -minetest.conf or by using the /set command in-game. + +Use the mcl_playersSleepingPercentage setting to enable/disable night skipping or set a percentage of how many players need to sleep to skip the night. + +mcl_beds.is_night([ time of day ]) - returns wether it's night with optional argument of a minetest time of day value between 0 and 1 diff --git a/mods/ITEMS/mcl_beds/api.lua b/mods/ITEMS/mcl_beds/api.lua index 7bc86d175..9d46eca39 100644 --- a/mods/ITEMS/mcl_beds/api.lua +++ b/mods/ITEMS/mcl_beds/api.lua @@ -1,23 +1,95 @@ -local S = minetest.get_translator("mcl_beds") +local S = minetest.get_translator(minetest.get_current_modname()) + +local minetest_get_node = minetest.get_node +local minetest_get_node_or_nil = minetest.get_node_or_nil +local minetest_remove_node = minetest.remove_node +local minetest_facedir_to_dir = minetest.facedir_to_dir +local vector_add = vector.add +local vector_subtract = vector.subtract + +local function get_bed_next_node(pos, node) + local node = node or minetest_get_node_or_nil(pos) + if not node then return end + + local dir = minetest_facedir_to_dir(node.param2) + + local pos2, bottom + if string.sub(node.name, -4) == "_top" then + pos2 = vector_subtract(pos, dir) + else + pos2 = vector_add(pos, dir) + bottom = true + end + + local node2 = minetest_get_node(pos2) + return pos2, node2, bottom, dir +end + +local function rotate(pos, node, user, mode, new_param2) + if mode ~= screwdriver.ROTATE_FACE then + return false + end + + local p, node2, bottom = get_bed_next_node(pos, node) + if not node2 then return end + + local name = node2.name + if not minetest.get_item_group(name, "bed") == 2 or not node.param2 == node2.param2 then return false end + + if bottom then + name = string.sub(name, 1, -5) + else + name = string.sub(name, 1, -8) + end + + if minetest.is_protected(p, user:get_player_name()) then + minetest.record_protection_violation(p, user:get_player_name()) + return false + end + + local newp + local new_dir = minetest_facedir_to_dir(new_param2) + + if bottom then + newp = vector_add(pos, new_dir) + else + newp = vector_subtract(pos, new_dir) + end + + local node3 = minetest_get_node_or_nil(newp) + if not node3 then return false end + + local node_def = minetest.registered_nodes[node3.name] + if not node_def or not node_def.buildable_to then return false end + + if minetest.is_protected(newp, user:get_player_name()) then + minetest.record_protection_violation(newp, user:get_player_name()) + return false + end + + node.param2 = new_param2 + -- do not remove_node here - it will trigger destroy_bed() + minetest.swap_node(p, {name = "air"}) + minetest.swap_node(pos, node) + minetest.swap_node(newp, {name = name .. (bottom and "_top" or "_bottom"), param2 = new_param2}) + + return true +end + local function destruct_bed(pos, oldnode) - local node = oldnode or minetest.get_node(pos) + local node = oldnode or minetest_get_node_or_nil(pos) if not node then return end - local dir = minetest.facedir_to_dir(node.param2) - local pos2, node2 - if string.sub(node.name, -4) == "_top" then - pos2 = vector.subtract(pos, dir) - node2 = minetest.get_node(pos2) - if node2 and string.sub(node2.name, -7) == "_bottom" then - minetest.remove_node(pos2) - end - minetest.check_for_falling(pos) - elseif string.sub(node.name, -7) == "_bottom" then - minetest.add_item(pos, node.name) - pos2 = vector.add(pos, dir) - node2 = minetest.get_node(pos2) + + local pos2, node2, bottom = get_bed_next_node(pos, oldnode) + + if bottom then if node2 and string.sub(node2.name, -4) == "_top" then - minetest.remove_node(pos2) + minetest_remove_node(pos2) + end + else + if node2 and string.sub(node2.name, -7) == "_bottom" then + minetest_remove_node(pos2) end end end @@ -50,49 +122,48 @@ end local default_sounds if minetest.get_modpath("mcl_sounds") then default_sounds = mcl_sounds.node_sound_wood_defaults({ - footstep = { gain = 0.5, name = "mcl_sounds_cloth" }, + footstep = mcl_sounds.node_sound_wool_defaults().footstep, }) end function mcl_beds.register_bed(name, def) - local node_box_bottom, selection_box_bottom, collision_box_bottom - if def.nodebox and def.nodebox.bottom then - node_box_bottom = { type = "fixed", fixed = def.nodebox.bottom } - end - if def.selectionbox and def.selectionbox.bottom then - selection_box_bottom = { type = "fixed", fixed = def.selectionbox.bottom } - end - if def.collisionbox and def.collisionbox.bottom then - collision_box_bottom = { type = "fixed", fixed = def.collisionbox.bottom } - end + local common_box = { + type = "fixed", + fixed = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + } + minetest.register_node(name .. "_bottom", { description = def.description, _tt_help = S("Allows you to sleep"), + _doc_items_longdesc = def._doc_items_longdesc or beddesc, _doc_items_usagehelp = def._doc_items_usagehelp or beduse, _doc_items_create_entry = def._doc_items_create_entry, _doc_items_entry_name = def._doc_items_entry_name, inventory_image = def.inventory_image, wield_image = def.wield_image, - drawtype = "nodebox", - tiles = def.tiles.bottom, + drawtype = "mesh", + mesh = "mcl_beds_bed_bottom.obj", + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, stack_max = 1, - groups = {handy=1, flammable = 3, bed = 1, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, deco_block = 1, flammable=-1}, + groups = {handy=1, bed = 1, dig_by_piston=1, bouncy=66, fall_damage_add_percent=-50, deco_block = 1, flammable=-1}, _mcl_hardness = 0.2, _mcl_blast_resistance = 1, sounds = def.sounds or default_sounds, - node_box = node_box_bottom, - selection_box = selection_box_bottom, - collision_box = collision_box_bottom, - drop = "", + selection_box = common_box, + collision_box = common_box, + drop = def.recipe and name or "", + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under -- Use pointed node's on_rightclick function first, if present - local node = minetest.get_node(under) + local node = minetest_get_node(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 @@ -100,7 +171,7 @@ function mcl_beds.register_bed(name, def) end local pos - local undername = minetest.get_node(under).name + local undername = minetest_get_node(under).name if minetest.registered_items[undername] and minetest.registered_items[undername].buildable_to then pos = under else @@ -113,13 +184,13 @@ function mcl_beds.register_bed(name, def) return itemstack end - local node_def = minetest.registered_nodes[minetest.get_node(pos).name] + local node_def = minetest.registered_nodes[minetest_get_node(pos).name] if not node_def or not node_def.buildable_to then return itemstack end local dir = minetest.dir_to_facedir(placer:get_look_dir()) - local botpos = vector.add(pos, minetest.facedir_to_dir(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 @@ -127,7 +198,7 @@ function mcl_beds.register_bed(name, def) return itemstack end - local botdef = minetest.registered_nodes[minetest.get_node(botpos).name] + local botdef = minetest.registered_nodes[minetest_get_node(botpos).name] if not botdef or not botdef.buildable_to then return itemstack end @@ -150,71 +221,34 @@ function mcl_beds.register_bed(name, def) return itemstack end, - on_rotate = function(pos, node, user, mode, new_param2) - local dir = minetest.facedir_to_dir(node.param2) - local p = vector.add(pos, dir) - local node2 = minetest.get_node_or_nil(p) - if not node2 or not minetest.get_item_group(node2.name, "bed") == 2 or - not node.param2 == node2.param2 then - return false - end - if minetest.is_protected(p, user:get_player_name()) then - minetest.record_protection_violation(p, user:get_player_name()) - return false - end - if mode ~= screwdriver.ROTATE_FACE then - return false - end - local newp = vector.add(pos, minetest.facedir_to_dir(new_param2)) - local node3 = minetest.get_node_or_nil(newp) - local node_def = node3 and minetest.registered_nodes[node3.name] - if not node_def or not node_def.buildable_to then - return false - end - if minetest.is_protected(newp, user:get_player_name()) then - minetest.record_protection_violation(newp, user:get_player_name()) - return false - end - node.param2 = new_param2 - -- do not remove_node here - it will trigger destroy_bed() - minetest.set_node(p, {name = "air"}) - minetest.set_node(pos, node) - minetest.set_node(newp, {name = name .. "_top", param2 = new_param2}) - return true - end, + on_rotate = rotate, }) - local node_box_top, selection_box_top, collision_box_top - if def.nodebox and def.nodebox.top then - node_box_top = { type = "fixed", fixed = def.nodebox.top } - end - if def.selectionbox and def.selectionbox.top then - selection_box_top = { type = "fixed", fixed = def.selectionbox.top } - end - if def.collisionbox and def.collisionbox.top then - collision_box_top = { type = "fixed", fixed = def.collisionbox.top } - end + minetest.register_node(name .. "_top", { - drawtype = "nodebox", - tiles = def.tiles.top, + drawtype = "mesh", + mesh = "mcl_beds_bed_top.obj", + tiles = def.tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", is_ground_content = false, -- FIXME: Should be bouncy=66, but this would be a higher bounciness than slime blocks! - groups = {handy = 1, flammable = 3, bed = 2, dig_by_piston=1, bouncy=33, fall_damage_add_percent=-50, not_in_creative_inventory = 1}, + groups = {handy = 1, flammable = -1, bed = 2, dig_by_piston=1, bouncy=33, fall_damage_add_percent=-50, not_in_creative_inventory = 1}, _mcl_hardness = 0.2, _mcl_blast_resistance = 1, sounds = def.sounds or default_sounds, - drop = "", - node_box = node_box_top, - selection_box = selection_box_top, - collision_box = collision_box_top, + drop = def.recipe and name or "", + selection_box = common_box, + collision_box = common_box, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) mcl_beds.on_rightclick(pos, clicker, true) return itemstack end, - on_rotate = false, + + on_rotate = rotate, after_destruct = destruct_bed, }) diff --git a/mods/ITEMS/mcl_beds/beds.lua b/mods/ITEMS/mcl_beds/beds.lua index 8f41c7a3f..7aa49f8c7 100644 --- a/mods/ITEMS/mcl_beds/beds.lua +++ b/mods/ITEMS/mcl_beds/beds.lua @@ -1,18 +1,6 @@ -local S = minetest.get_translator("mcl_beds") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") -local nodebox = { - bottom = { - {-0.5, -5/16, -0.5, 0.5, 0.06, 0.5}, - {-0.5, -0.5, -0.5, -5/16, -5/16, -5/16}, - {0.5, -0.5, -0.5, 5/16, -5/16, -5/16}, - }, - top = { - {-0.5, -5/16, -0.5, 0.5, 0.06, 0.5}, - {-0.5, -0.5, 0.5, -5/16, -5/16, 5/16}, - {0.5, -0.5, 0.5, 5/16, -5/16, 5/16}, - }, -} local colors = { -- { ID, decription, wool, dye } @@ -70,36 +58,13 @@ for c=1, #colors do description = colors[c][2], _doc_items_entry_name = entry_name, _doc_items_create_entry = create_entry, - inventory_image = "mcl_beds_bed_"..colorid..".png", - wield_image = "mcl_beds_bed_"..colorid..".png", + inventory_image = "mcl_beds_bed_"..colorid.."_inv.png", + wield_image = "mcl_beds_bed_"..colorid.."_inv.png", + tiles = { - bottom = { - "mcl_beds_bed_top_bottom_"..colorid..".png^[transformR90", - "default_wood.png^mcl_beds_bed_bottom_bottom.png", - "mcl_beds_bed_side_bottom_r_"..colorid..".png", - "mcl_beds_bed_side_bottom_r_"..colorid..".png^[transformfx", - "mcl_beds_bed_side_top_"..colorid..".png", - "mcl_beds_bed_side_bottom_"..colorid..".png" - }, - top = { - "mcl_beds_bed_top_top_"..colorid..".png^[transformR90", - "default_wood.png^mcl_beds_bed_bottom_top.png", - "mcl_beds_bed_side_top_r_"..colorid..".png", - "mcl_beds_bed_side_top_r_"..colorid..".png^[transformfx", - "mcl_beds_bed_side_top_"..colorid..".png", - "mcl_beds_bed_side_bottom_"..colorid..".png" - } - }, - nodebox = nodebox, - selectionbox = { - bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - }, - -- Simplified collision box because Minetest acts weird if we use the nodebox one - collisionbox = { - bottom = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, - top = {-0.5, -0.5, -0.5, 0.5, 0.06, 0.5}, + "mcl_beds_bed_"..colorid..".png" }, + recipe = main_recipe, }) if mod_doc and not is_canonical then diff --git a/mods/ITEMS/mcl_beds/depends.txt b/mods/ITEMS/mcl_beds/depends.txt deleted file mode 100644 index c7c874fd1..000000000 --- a/mods/ITEMS/mcl_beds/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -playerphysics -mcl_sounds? -mcl_worlds? -mcl_wool? -mcl_dye? -mcl_explosions? -mcl_weather? -mcl_spawn? -doc? diff --git a/mods/ITEMS/mcl_beds/functions.lua b/mods/ITEMS/mcl_beds/functions.lua index 8b1b82dfc..fdb4f8f41 100644 --- a/mods/ITEMS/mcl_beds/functions.lua +++ b/mods/ITEMS/mcl_beds/functions.lua @@ -1,49 +1,51 @@ -local S = minetest.get_translator("mcl_beds") +local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape -local pi = math.pi +local math = math +local vector = vector local player_in_bed = 0 local is_sp = minetest.is_singleplayer() -local weather_mod = minetest.get_modpath("mcl_weather") ~= nil -local explosions_mod = minetest.get_modpath("mcl_explosions") ~= nil +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 function mcl_log (message) + mcl_util.mcl_log (message, "[Beds]") +end -- Helper functions local function get_look_yaw(pos) local n = minetest.get_node(pos) - if n.param2 == 1 then - return pi / 2, n.param2 - elseif n.param2 == 3 then - return -pi / 2, n.param2 - elseif n.param2 == 0 then - return pi, n.param2 + local param = n.param2 + if param == 1 then + return math.pi / 2, param + elseif param == 3 then + return -math.pi / 2, param + elseif param == 0 then + return math.pi, param else - return 0, n.param2 + return 0, param end end +local function players_in_bed_setting() + return tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) or 100 +end + local function is_night_skip_enabled() - local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip") - if enable_night_skip == nil then - enable_night_skip = true - end - return enable_night_skip + return players_in_bed_setting() <= 100 end local function check_in_beds(players) - local in_bed = mcl_beds.player if not players then players = minetest.get_connected_players() end - - for n, player in ipairs(players) do - local name = player:get_player_name() - if not in_bed[name] then - return false - end + if player_in_bed <= 0 then + return false end - - return #players > 0 + return players_in_bed_setting() <= (player_in_bed * 100) / #players end -- These monsters do not prevent sleep @@ -60,6 +62,15 @@ local monster_exceptions = { ["mobs_mc:shulker"] = true, } +function mcl_beds.is_night(tod) + -- Values taken from Minecraft Wiki with offset of +600 + if not tod then + tod = minetest.get_timeofday() + end + tod = ( tod * 24000 ) % 24000 + return tod > 18541 or tod < 5458 +end + local function lay_down(player, pos, bed_pos, state, skip) local name = player:get_player_name() local hud_flags = player:hud_get_flags() @@ -76,8 +87,14 @@ local function lay_down(player, pos, bed_pos, state, skip) bed_center = {x = bed_pos.x - dir.x/2, y = bed_pos.y + 0.1, z = bed_pos.z - dir.z/2} -- save respawn position when entering bed - if minetest.get_modpath("mcl_spawn") and mcl_spawn.set_spawn_pos(player, bed_pos, false) then + if spawn_mod and mcl_spawn.set_spawn_pos(player, bed_pos, nil) then minetest.chat_send_player(name, S("New respawn position set!")) + awards.unlock(player:get_player_name(), "mcl:sweetDreams") + end + + + if not mcl_beds.is_night() and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then + return false, S("You can only sleep at night or during a thunderstorm.") end -- No sleeping if too far away @@ -86,7 +103,7 @@ local function lay_down(player, pos, bed_pos, state, skip) end for _, other_pos in pairs(mcl_beds.bed_pos) do - if vector.distance(bed_pos, other_pos) < 0.1 then + if vector.distance(bed_pos2, other_pos) < 0.1 then return false, S("This bed is already occupied!") end end @@ -100,20 +117,23 @@ local function lay_down(player, pos, bed_pos, state, skip) end -- No sleeping if monsters nearby. - -- The exceptions above apply. - -- Zombie pigmen only prevent sleep while they are hostle. - local objs = minetest.get_objects_inside_radius(bed_pos, 8) - for _, obj in ipairs(objs) do - if obj ~= nil and not obj:is_player() then + for _, obj in pairs(minetest.get_objects_inside_radius(bed_pos, 8)) do + if obj and not obj:is_player() then local ent = obj:get_luaentity() local mobname = ent.name local def = minetest.registered_entities[mobname] -- Approximation of monster detection range - if def._cmi_is_mob and ((mobname ~= "mobs_mc:pigman" and def.type == "monster" and not monster_exceptions[mobname]) or (mobname == "mobs_mc:pigman" and ent.state == "attack")) then - if math.abs(bed_pos.y - obj:get_pos().y) <= 5 then - return false, S("You can't sleep now, monsters are nearby!") + if def.is_mob and (def.type == "monster" or mobname == "mobs_mc:zombified_piglin") then + if monster_exceptions[mobname] or + (mobname == "mobs_mc:zombified_piglin" and ent.state ~= "attack") then + -- Some exceptions do not prevent sleep. Zombie piglin only prevent sleep while they are hostile. + else + if math.abs(bed_pos.y - obj:get_pos().y) <= 5 then + return false, S("You can't sleep now, monsters are nearby!") + end end end + end end end @@ -121,7 +141,7 @@ local function lay_down(player, pos, bed_pos, state, skip) -- stand up if state ~= nil and not state then local p = mcl_beds.pos[name] or nil - if mcl_beds.player[name] ~= nil then + if mcl_beds.player[name] then mcl_beds.player[name] = nil player_in_bed = player_in_bed - 1 end @@ -156,20 +176,13 @@ local function lay_down(player, pos, bed_pos, state, skip) local def2 = minetest.registered_nodes[n2.name] if def1.walkable or def2.walkable then return false, S("You can't sleep, the bed is obstructed!") - elseif (def1.damage_per_second ~= nil and def1.damage_per_second > 0) or (def2.damage_per_second ~= nil and def2.damage_per_second > 0) then + elseif (def1.damage_per_second and def1.damage_per_second > 0) or (def2.damage_per_second and def2.damage_per_second > 0) then return false, S("It's too dangerous to sleep here!") end - -- Check day of time and weather - local tod = minetest.get_timeofday() * 24000 - -- Values taken from Minecraft Wiki with offset of +6000 - if tod < 18541 and tod > 5458 and (not weather_mod or (mcl_weather.get_weather() ~= "thunder")) then - return false, S("You can only sleep at night or during a thunderstorm.") - end - mcl_beds.player[name] = 1 mcl_beds.pos[name] = pos - mcl_beds.bed_pos[name] = bed_pos + mcl_beds.bed_pos[name] = bed_pos2 player_in_bed = player_in_bed + 1 -- physics, eye_offset, etc player:set_eye_offset({x = 0, y = -13, z = 0}, {x = 0, y = 0, z = 0}) @@ -196,12 +209,17 @@ end local function update_formspecs(finished, ges) local ges = ges or #minetest.get_connected_players() local form_n = "size[12,5;true]" - local all_in_bed = ges == player_in_bed + local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges 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 if finished then for name,_ in pairs(mcl_beds.player) do @@ -219,9 +237,16 @@ local function update_formspecs(finished, ges) form_n = form_n .. bg_sleep form_n = form_n .. button_abort else - text = text .. "\n" .. S("You will fall asleep when all players are in bed.") + local comment = "You will fall asleep when " + if players_in_bed_setting() == 100 then + comment = S(comment .. "all players are in bed.") + else + comment = S(comment .. "@1% of all players are in bed.", players_in_bed_setting()) + end + text = text .. "\n" .. comment form_n = form_n .. bg_presleep form_n = form_n .. button_leave + form_n = form_n .. defaultmessagebutton --Players should only be able to see that button when: -Skipping the night is possible -There aren't enoght players sleeping yet end form_n = form_n .. "label[0.5,1;"..F(text).."]" else @@ -247,16 +272,26 @@ end -- Handle environment stuff related to sleeping: skip night and thunderstorm function mcl_beds.sleep() - local storm_skipped = mcl_beds.skip_thunderstorm() - -- Always clear weather - if weather_mod then - mcl_weather.change_weather("none") - end if is_night_skip_enabled() then - if not storm_skipped then + if weather_mod and mcl_weather.get_weather() == "thunder" then + local endtime = (mcl_weather.end_time - minetest.get_gametime()) * 72 / 24000 + minetest.set_timeofday((minetest.get_timeofday() + endtime) %1) + if mcl_beds.is_night() then + mcl_beds.skip_night() + mcl_beds.kick_players() + else + mcl_beds.kick_players() + end + -- Always clear weather + mcl_weather.change_weather("none") + elseif mcl_beds.is_night() and weather_mod then mcl_beds.skip_night() + mcl_beds.kick_players() + mcl_weather.change_weather("none") + elseif mcl_beds.is_night() and not weather_mod then + mcl_beds.skip_night() + mcl_beds.kick_players() end - mcl_beds.kick_players() end end @@ -272,7 +307,7 @@ end -- Throw a player out of bed function mcl_beds.kick_player(player) local name = player:get_player_name() - if mcl_beds.player[name] ~= nil then + if mcl_beds.player[name] then lay_down(player, nil, nil, false) update_formspecs(false) minetest.close_formspec(name, "mcl_beds_form") @@ -283,14 +318,35 @@ function mcl_beds.skip_night() minetest.set_timeofday(0.25) -- tod = 6000 end -function mcl_beds.skip_thunderstorm() - -- Skip thunderstorm - if weather_mod and mcl_weather.get_weather() == "thunder" then - -- Sleep for a half day (=minimum thunderstorm duration) - minetest.set_timeofday((minetest.get_timeofday() + 0.5) % 1) - return true +function mcl_beds.get_bed_top (pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + local bed_top_pos = vector.add(pos, dir) + local bed_top = minetest.get_node(bed_top_pos) + + if bed_top then + --mcl_log("Has a bed top") + else + --mcl_log("No bed top") end - return false + return bed_top_pos +end + +function mcl_beds.get_bed_bottom (pos) + local node = minetest.get_node(pos) + local dir = minetest.facedir_to_dir(node.param2) + mcl_log("Dir: " .. tostring(dir)) + local bed_bottom = vector.add(pos, -dir) + mcl_log("bed_bottom: " .. tostring(bed_bottom)) + + local bed_bottom_node = minetest.get_node(bed_bottom) + if bed_bottom_node then + mcl_log("Bed bottom node name:" .. bed_bottom_node.name) + else + mcl_log("Didn't get bed bottom") + end + + return bed_bottom end function mcl_beds.on_rightclick(pos, player, is_top) @@ -298,11 +354,15 @@ function mcl_beds.on_rightclick(pos, player, is_top) if player:get_meta():get_string("mcl_beds:sleeping") == "true" then return end - if minetest.get_modpath("mcl_worlds") then + 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) + 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 @@ -314,17 +374,15 @@ function mcl_beds.on_rightclick(pos, player, is_top) -- move to bed if not mcl_beds.player[name] then - local success, message + local message if is_top then - success, message = lay_down(player, ppos, pos) + message = select(2, lay_down(player, ppos, pos)) else - local node = minetest.get_node(pos) - local dir = minetest.facedir_to_dir(node.param2) - local other = vector.add(pos, dir) - success, message = lay_down(player, ppos, other) + local other = mcl_beds.get_bed_top (pos) + message = select(2, lay_down(player, ppos, other)) end if message then - mcl_tmp_message.message(player, message) + mcl_title.set(player, "actionbar", {text=message, color="white", stay=60}) end else lay_down(player, nil, nil, false) @@ -343,7 +401,6 @@ function mcl_beds.on_rightclick(pos, player, is_top) end end - -- Callbacks minetest.register_on_joinplayer(function(player) local meta = player:get_meta() @@ -358,6 +415,7 @@ minetest.register_on_joinplayer(function(player) end) minetest.register_on_leaveplayer(function(player) + lay_down(player, nil, nil, false, true) local players = minetest.get_connected_players() local name = player:get_player_name() for n, player in ipairs(players) do @@ -377,10 +435,69 @@ minetest.register_on_leaveplayer(function(player) 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 +local playermessagecounter = {} +--[[ + This table stores how many messages a player XY has sent (only while being in a bed) within 10 secs + It gets reset after 10 secs using a globalstep +--]] + +local chatbuttonused = false +local globalstep_timer = 0 +minetest.register_globalstep(function(dtime) + globalstep_timer = globalstep_timer + dtime + if globalstep_timer >= 10 then + globalstep_timer = 0 + playermessagecounter = {} + chatbuttonused = false + end +end) + +local function exceeded_rate_limit(playername) --Note: will also take care of increasing value and sending feedback message if needed + if playermessagecounter[playername] == nil then + playermessagecounter[playername] = 0 + end + if playermessagecounter[playername] >= message_rate_limit then -- == should do as well + minetest.chat_send_player(playername,S("You exceeded the maximum number of messages per 10 seconds!") .. " (" .. tostring(message_rate_limit) .. ")") + return true + end + playermessagecounter[playername] = playermessagecounter[playername] + 1 + return false +end + +local function shout_priv_check(player) + if not minetest.check_player_privs(player,"shout") then + minetest.chat_send_player(player:get_player_name(),S("You are missing the 'shout' privilege! It's required in order to talk in chat...")) + return false + end + return true +end + minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= "mcl_beds_form" then return end + + local custom_sleep_message + if fields.chatsubmit and fields.chatmessage ~= "" then + custom_sleep_message = fields.chatmessage + end + + if custom_sleep_message or fields.defaultmessage then + if chatbuttonused then + local time_to_wait = math.ceil(10-globalstep_timer) + minetest.chat_send_player(player:get_player_name(),S("Sorry, but you have to wait @1 seconds until you may use this button again!", tostring(time_to_wait))) + return + end + + if (not exceeded_rate_limit(player:get_player_name())) and shout_priv_check(player) then + chatbuttonused = true + local message = custom_sleep_message or S("Hey! Would you guys mind sleeping?") + minetest.chat_send_all(minetest.format_chat_message(player:get_player_name(), message)) + end + return + end + if fields.quit or fields.leave then lay_down(player, nil, nil, false) update_formspecs(false) diff --git a/mods/ITEMS/mcl_beds/init.lua b/mods/ITEMS/mcl_beds/init.lua index 4c25b5390..ad9dbdded 100644 --- a/mods/ITEMS/mcl_beds/init.lua +++ b/mods/ITEMS/mcl_beds/init.lua @@ -10,3 +10,4 @@ local modpath = minetest.get_modpath("mcl_beds") dofile(modpath .. "/functions.lua") dofile(modpath .. "/api.lua") dofile(modpath .. "/beds.lua") +dofile(modpath .. "/respawn_anchor.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr index 16592115e..97867b44b 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.de.tr @@ -37,5 +37,13 @@ Players in bed: @1/@2=Spieler im Bett: @1/@2 Note: Night skip is disabled.=Anmerkung: Überspringen der Nacht deaktiviert. You're sleeping.=Sie schlafen. You will fall asleep when all players are in bed.=Sie werden einschlafen, wenn alle Spieler im Bett sind. +You will fall asleep when @1% of all players are in bed.=Sie werden einschlafen, wenn @1% der Spieler im Bett sind. You're in bed.=Sie sind im Bett. Allows you to sleep=Zum Einschafen +Respawn Anchor=Seelenanker +Chat:=Chat: +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 diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.dk.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.dk.tr new file mode 100644 index 000000000..453ec05df --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.dk.tr @@ -0,0 +1,43 @@ +# textdomain: mcl_beds +Beds allow you to sleep at night and make the time pass faster.=Senge giver dig mulighed for at sove om natten, og få tiden til at gå hurtigere. +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.=For at lægge dig til at sove i en seng skal du stå tæt på den og højre-klikke. Man kan kun sove når solen går ned, om natten eller i tordenvejr. +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.=Du har hørt om andre verdener hvor en seng var udgangspunktet for dit næste liv, men denne verden er ikke en af dem. +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.=Ved at bruge en sætter du udgangspunktet for dit næste liv. Hvis du dør, vil dit næste liv starte i denne seng, medmindre sengen bliver blokeret eller ødelagt. +In this world, going to bed won't skip the night, but it will skip thunderstorms.=I denne verden, springer det ikke natten over at sove, men det springer tordenvejr over. +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.=Du kan springe natten over ved at sove. Natten bliver sprunget over hvis alle spillere i verdenen sover. Natten bliver sprunget over efter at have sovet i nogle få sekunder. Tordenvejr kan springes over på samme måde. +Bed=Seng +Red Bed=Rød seng +Blue Bed=Blå seng +Cyan Bed=Cyanblå seng +Grey Bed=Grå seng +Light Grey Bed=Lysegrå seng +Black Bed=Sort senge +Yellow Bed=Gul senge +Green Bed=Grøn seng +Magenta Bed=Magenta seng +Orange Bed=Orange seng +Purple Bed=Lilla seng +Brown Bed=Brun seng +Pink Bed=Lyserød seng +Lime Bed=Limegrøn seng +Light Blue Bed=Lyseblå seng +White Bed=Hvid seng +You can't sleep, the bed's too far away!=Du kan ikke gå i seng, sengen er for langt væk! +This bed is already occupied!=Denne seng er optaget! +You have to stop moving before going to bed!=Du skal stå stille før du kan gå i seng. +You can't sleep now, monsters are nearby!=Du kan ikke lægge dig til at sove nu, der er monstre tæt på! +You can't sleep, the bed is obstructed!=Du kan ikke gå i seng, denne seng er blokeret! +It's too dangerous to sleep here!=Det er for farligt at sove her! +New respawn position set! But you can only sleep at night or during a thunderstorm.=Nyt genopståelsespunt sat! Men du kan kun sover om natten eller under et tordenvejr. +You can only sleep at night or during a thunderstorm.=Du kan kun sover om natten eller under et tordenvejr. +New respawn position set!=Nyt genopståelsespunkt sat! +Leave bed=Forlad seng +Abort sleep=Afbryd søvn +Players in bed: @1/@2=@1 af @2 spillere er gået i seng. +Note: Night skip is disabled.=Bemærk: Det er slået fra at springe natten over. +You're sleeping.=Du sover. +You will fall asleep when all players are in bed.=Du falder i søvn når alle andre spillere er gået i seng. +You will fall asleep when @1% of all players are in bed.=Du falder i søvn når @1% af alle spillere er gået i seng. +You're in bed.=Du er gået i seng. +Allows you to sleep=Gør dig i stand til at sove. +Respawn Anchor=Genopståelsesanker diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr index d85d48bf1..cc69db33b 100644 --- a/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.fr.tr @@ -6,36 +6,38 @@ By using a bed, you set the starting point for your next life. If you die, you w In this world, going to bed won't skip the night, but it will skip thunderstorms.=Dans ce monde, aller au lit ne sautera pas la nuit, mais cela évitera les orages. 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.=Dormir vous permet de sauter la nuit. La nuit est sautée lorsque tous les joueurs de ce monde se sont endormis. La nuit est sautée après avoir dormi quelques secondes. Les orages peuvent être évités de la même manière. Bed=Lit -Red Bed=Lit Rouge -Blue Bed=Lit Bleu -Cyan Bed=Lit Cyan -Grey Bed=Lit Gris -Light Grey Bed=Lit Gris Clair -Black Bed=Lit Noir -Yellow Bed=Lit Jaune -Green Bed=Lit Vert -Magenta Bed=Lit Magenta -Orange Bed=Lit Orange -Purple Bed=Lit Violet -Brown Bed=Lit Marron -Pink Bed=Lit Rose -Lime Bed=Lit Vert Clair -Light Blue Bed=Lit Bleu Clair -White Bed=Lit Blanc -You can't sleep, the bed's too far away!=Vous ne pouvez pas dormir, le lit est trop loin! -This bed is already occupied!=Ce lit est déjà occupé! -You have to stop moving before going to bed!=Vous devez arrêter de bouger avant de vous coucher! -You can't sleep now, monsters are nearby!=Vous ne pouvez pas dormir maintenant, les monstres sont à proximité! -You can't sleep, the bed is obstructed!=Vous ne pouvez pas dormir, le lit est obstrué! -It's too dangerous to sleep here!=C'est trop dangereux de dormir ici! -New respawn position set! But you can only sleep at night or during a thunderstorm.=Nouvelle position de réapparition définie! Mais vous ne pouvez dormir que la nuit ou pendant un orage. +Red Bed=Lit rouge +Blue Bed=Lit bleu +Cyan Bed=Lit cyan +Grey Bed=Lit gris +Light Grey Bed=Lit gris clair +Black Bed=Lit noir +Yellow Bed=Lit jaune +Green Bed=Lit vert +Magenta Bed=Lit magenta +Orange Bed=Lit orange +Purple Bed=Lit violet +Brown Bed=Lit marron +Pink Bed=Lit rose +Lime Bed=Lit vert clair +Light Blue Bed=Lit bleu clair +White Bed=Lit blanc +You can't sleep, the bed's too far away!=Vous ne pouvez pas dormir, le lit est trop loin ! +This bed is already occupied!=Ce lit est déjà occupé ! +You have to stop moving before going to bed!=Vous devez arrêter de bouger avant de vous coucher ! +You can't sleep now, monsters are nearby!=Vous ne pouvez pas dormir maintenant, les monstres sont à proximité ! +You can't sleep, the bed is obstructed!=Vous ne pouvez pas dormir, le lit est obstrué ! +It's too dangerous to sleep here!=C'est trop dangereux de dormir ici ! +New respawn position set! But you can only sleep at night or during a thunderstorm.=Nouvelle position de réapparition définie ! Mais vous ne pouvez dormir que la nuit ou pendant un orage. You can only sleep at night or during a thunderstorm.=Vous ne pouvez dormir que la nuit ou pendant un orage. -New respawn position set!=Nouvelle position de réapparition définie! +New respawn position set!=Nouvelle position de réapparition définie ! Leave bed=Quitter le lit Abort sleep=Abandonner le sommeil -Players in bed: @1/@2=Joueurs au lit: @1/@2 -Note: Night skip is disabled.=Remarque: Le saut de nuit est désactivé. +Players in bed: @1/@2=Joueurs au lit : @1/@2 +Note: Night skip is disabled.=Remarque : Le saut de nuit est désactivé. You're sleeping.=Tu dors. You will fall asleep when all players are in bed.=Vous vous endormirez lorsque tous les joueurs seront au lit. +You will fall asleep when @1% of all players are in bed.=Vous vous endormirez lorsque @1% de tous les joueurs seront au lit. You're in bed.=Tu es au lit. Allows you to sleep=Vous permet de dormir +Respawn Anchor=Ancre de réapparition diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr new file mode 100644 index 000000000..51162b762 --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.ja.tr @@ -0,0 +1,43 @@ +# 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.=ベッドで寝るには、その近くに立って右クリックします。寝られるのは、日没後の夜間、あるいは雷雨の間のみです。また、その周辺に危険がないことも条件です。 +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.=寝ることで夜をスキップできます。スキップされるのは、このワールドのすべてのプレイヤーが寝たときです。数秒間眠ったのち、夜がスキップされます。雷雨も同様にスキップできます。 +Bed=ベッド +Red Bed=赤色のベッド +Blue Bed=青色のベッド +Cyan Bed=青緑色のベッド +Grey Bed=灰色のベッド +Light Grey Bed=薄灰色のベッド +Black Bed=黒色のベッド +Yellow Bed=黄色のベッド +Green Bed=緑色のベッド +Magenta Bed=赤紫色のベッド +Orange Bed=橙色のベッド +Purple Bed=紫色のベッド +Brown Bed=茶色のベッド +Pink Bed=桃色のベッド +Lime Bed=黄緑色のベッド +Light Blue Bed=空色のベッド +White Bed=白色のベッド +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!=今は眠れません…モンスターが近くにいます! +You can't sleep, the bed is obstructed!=ベッドが妨げられていて、寝られません! +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=睡眠を中断する +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.=プレイヤー全員がベッドに入ると、眠りにつきます。 +You will fall asleep when @1% of all players are in bed.=全プレイヤー(@1%)がベッドに入ると、眠りにつきます。 +You're in bed.=ベッドにいます。 +Allows you to sleep=睡眠を許可する +Respawn Anchor=リスポーンアンカー diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.pl.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.pl.tr new file mode 100644 index 000000000..3a1d8f6ce --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.pl.tr @@ -0,0 +1,41 @@ +# textdomain: mcl_beds +Beds allow you to sleep at night and make the time pass faster.=Łóżka pozwalają na spanie w nocy i sprawiają, że czas płynie szybciej. +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.=Aby użyć łóżka stań blisko niego i kliknij je prawym przyciskiem myszy aby na nim zasnąć. Spać można tylko przy zachodzie słońca, w nocy lub podczas burz. Łóżko nie może być również narażone na niebezpieczeństwo. +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.=Słyszałaś o światach w których łóżko byłoby twoim punktem wyjścia w następnym życiu. Ten świat nie jest jednym z nich. +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.=Korzystając z łóżka ustawiasz punkt wyjścia w następnym życiu. Jeśli umrzesz, odrodzisz się przy tym łóżku chyba, że zostanie zniszczone lub zawalone. +In this world, going to bed won't skip the night, but it will skip thunderstorms.=W tym świecie pójście do łóżka nie ominie nocy, jednak może pominąć burze. +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.=Spanie pozwala pominąć noc. Noc jest pomijana gdy wszyscy gracze w tym świecie pójdą spać. Jest ona pomijana po kilku sekundach. Burze można pomijać w ten sam sposób. +Bed=Łóżko +Red Bed=Czerwone łóżko +Blue Bed=Niebieskie łóżko +Cyan Bed=Błękitne łóżko +Grey Bed=Szare łóżko +Light Grey Bed=Jasnoszare łóżko +Black Bed=Czarne łóżko +Yellow Bed=Żółte łóżko +Green Bed=Zielone łóżko +Magenta Bed=Karmazynowe łóżko +Orange Bed=Pomarańczowe łóżko +Purple Bed=Fioletowe łóżko +Brown Bed=Brązowe łóżko +Pink Bed=Różowe łóżko +Lime Bed=Jasnozielone łóżko +Light Blue Bed=Jasnoniebieskie łóżko +White Bed=Białe łóżko +You can't sleep, the bed's too far away!=Nie możesz spać, łóżko jest zbyt daleko! +This bed is already occupied!=To łóżko jest zajęte! +You have to stop moving before going to bed!=Musisz przestać się poruszać przed pójściem do spania! +You can't sleep now, monsters are nearby!=Nie możesz spać, w pobliżu są potwory! +You can't sleep, the bed is obstructed!=Nie możesz spać, łóżko jest zawalone! +It's too dangerous to sleep here!=Tu jest zbyt niebezpiecznie by spać! +New respawn position set! But you can only sleep at night or during a thunderstorm.=Nowa pozycja do odrodzenia ustawiona! Ale możesz spać tylko podczas nocy, bądź burzy. +You can only sleep at night or during a thunderstorm.=Możesz spać tylko podczas nocy, bądź burzy. +New respawn position set!=Nowa pozycja odradzania ustawiona! +Leave bed=Opuść łóżka +Abort sleep=Przerwij sen +Players in bed: @1/@2=Graczy w łóżkach: @1/@2 +Note: Night skip is disabled.=Uwaga: Pomijanie nocy wyłączone. +You're sleeping.=Śpisz. +You will fall asleep when all players are in bed.=Zaśniesz gdy wszyscy gracze będą w łóżkach. +You're in bed.=Jesteś w łóżku. +Allows you to sleep=Pozwala spać diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.pt_BR.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.pt_BR.tr new file mode 100644 index 000000000..0cb9ad89d --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.pt_BR.tr @@ -0,0 +1,43 @@ +# textdomain: mcl_beds +Beds allow you to sleep at night and make the time pass faster.=Camas permitem que você durma durante a noite e faz o tempo passar mais rápido. +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.=Para utilizar uma cama, se aproxime dela e clique com o botão direito para dormir na cama. Dormir só funciona quando o sol se põe, a noite ou durante uma tempestade. +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.=Você andou escutando de outros mundos onde uma cama colocaria o ponto de partida de sua próxima vida. Mas esse mundo não é um deles. +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.=Ao utilizar uma cama, você marca o ponto de partida de sua próxima vida. Se você morrer, voce começará sua nova vida nesta cama, a não ser que ela está obstruída ou foi destruída. +In this world, going to bed won't skip the night, but it will skip thunderstorms.=Neste mundo, ir para a cama não pulará a noite, mas pulará tempestades. +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.=Dormir permite que você pule a noite. A noite é pulada quando todos os jogadores deste mundo forem dormir. A noite é pulada depois de dormir por alguns segundos. Tempestades podem ser puladas da mesma maneira. +Bed=Cama +Red Bed=Cama Vermelha +Blue Bed=Cama Azul +Cyan Bed=Cama Ciana +Grey Bed=Cama Cinza +Light Grey Bed=Cama Cinza Clara +Black Bed=Cama Preta +Yellow Bed=Cama Amarela +Green Bed=Cama Verde +Magenta Bed=Cama Magenta +Orange Bed=Cama Laranja +Purple Bed=Cama Roxa +Brown Bed=Cama Marrom +Pink Bed=Cama Rosa +Lime Bed=Cama Lima +Light Blue Bed=Cama Azul Clara +White Bed=Cama Brabca +You can't sleep, the bed's too far away!=Você não pode dormir, a cama está muito longe! +This bed is already occupied!=Esta cama já está ocupada! +You have to stop moving before going to bed!=Você precisa parar de se mover antes de deitar na cama! +You can't sleep now, monsters are nearby!=Você não pode dormir agora, há monstros perto! +You can't sleep, the bed is obstructed!=Você não pode dormir, a cama está obstruída! +It's too dangerous to sleep here!=É muito perigoso dormir aqui! +New respawn position set! But you can only sleep at night or during a thunderstorm.=Nova posição de respawn marcada! Mas você só pode dormir a noite ou durante uma tempestade. +You can only sleep at night or during a thunderstorm.=Você só pode dormir a noite ou durante uma tempestade. +New respawn position set!=Nova posição de respawn marcada! +Leave bed=Sair da cama +Abort sleep=Abortar dormir +Players in bed: @1/@2=Jogadores na cama: @1/@2 +Note: Night skip is disabled.=Nota: avançar a noite está desabilitado. +You're sleeping.=Voce está dormindo. +You will fall asleep when all players are in bed.=Você cairá no sono quando todos os jogadores estiverem na cama. +You will fall asleep when @1% of all players are in bed.=Você cairá no sono quando @1% de todos os jogadores estiverem na cama. +You're in bed.=Você está na cama. +Allows you to sleep=Permite que você durma +Respawn Anchor=Âncora de Respawn diff --git a/mods/ITEMS/mcl_beds/locale/mcl_beds.zh_TW.tr b/mods/ITEMS/mcl_beds/locale/mcl_beds.zh_TW.tr new file mode 100644 index 000000000..fd0a58629 --- /dev/null +++ b/mods/ITEMS/mcl_beds/locale/mcl_beds.zh_TW.tr @@ -0,0 +1,41 @@ +# 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.=要使用床,站在靠近床的地方,右鍵點擊床,就可以在床上睡覺。只有在太陽落山、晚上或雷雨時才能睡覺。床也必須遠離任何危險。 +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.=睡覺可以跳過夜晚。當這個世界的所有玩家都進入睡眠狀態幾秒後,夜晚就會被跳過。雷雨也可以用同樣的方式跳過。 +Bed=床 +Red Bed=紅色床 +Blue Bed=藍色床 +Cyan Bed=青色床 +Grey Bed=灰色床 +Light Grey Bed=淺灰色床 +Black Bed=黑色床 +Yellow Bed=黃色床 +Green Bed=綠色床 +Magenta Bed=洋紅色床 +Orange Bed=橙色床 +Purple Bed=紫色床 +Brown Bed=棕色床 +Pink Bed=粉紅色床 +Lime Bed=淺綠色床 +Light Blue Bed=淺藍色床 +White Bed=白色床 +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!=你無法休息,有怪物在附近遊蕩! +You can't sleep, the bed is obstructed!=你無法休息,床已被阻擋! +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=醒來 +Players in bed: @1/@2=@2位玩家中的@1位在床上 +Note: Night skip is disabled.=注意:睡覺以跳過夜晚被停用 +You're sleeping.=你睡着了。 +You will fall asleep when all players are in bed.=你會在所有玩家在床上時睡着 +You're in bed.=你在床上。 +Allows you to sleep=允許你睡覺 diff --git a/mods/ITEMS/mcl_beds/locale/template.txt b/mods/ITEMS/mcl_beds/locale/template.txt index 8301dfa33..42e59509e 100644 --- a/mods/ITEMS/mcl_beds/locale/template.txt +++ b/mods/ITEMS/mcl_beds/locale/template.txt @@ -37,5 +37,13 @@ Players in bed: @1/@2= 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.= You're in bed.= Allows you to sleep= +Respawn Anchor= +Chat:= +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 diff --git a/mods/ITEMS/mcl_beds/mod.conf b/mods/ITEMS/mcl_beds/mod.conf index 62645f3b4..fc6d54f1f 100644 --- a/mods/ITEMS/mcl_beds/mod.conf +++ b/mods/ITEMS/mcl_beds/mod.conf @@ -1 +1,5 @@ name = mcl_beds +author = BlockMen +description = +depends = playerphysics +optional_depends = mcl_sounds, mcl_worlds, mcl_wool, mcl_dye, mcl_explosions, mcl_weather, mcl_spawn, doc, mesecons \ No newline at end of file diff --git a/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj new file mode 100644 index 000000000..0e2fe2da9 --- /dev/null +++ b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_bottom.obj @@ -0,0 +1,290 @@ +# Made in Blockbench 3.6.6 +mtllib mcl_beds_bed_bottom.mtl +o cube +v 0.5 0.0625 0.5 +v 0.5 0.0625 -0.5 +v 0.5 -0.3125 0.5 +v 0.5 -0.3125 -0.5 +v -0.5 0.0625 -0.5 +v -0.5 0.0625 0.5 +v -0.5 -0.3125 -0.5 +v -0.5 -0.3125 0.5 +vt 0.09375 0.5625 +vt 0 0.5625 +vt 0.09375 0.3125 +vt 0 0.5625 +vt 0 0.3125 +vt 0.09375 0.3125 +vt 0.34375 0.3125 +vt 0.4375 0.3125 +vt 0.34375 0.5625 +vt 0.4375 0.3125 +vt 0.4375 0.5625 +vt 0.34375 0.5625 +vt 0.34375 0.3125 +vt 0.34375 0.5625 +vt 0.09375 0.3125 +vt 0.34375 0.5625 +vt 0.09375 0.5625 +vt 0.09375 0.3125 +vt 0.43750000000000006 0.5625 +vt 0.43750000000000006 0.3125 +vt 0.6875 0.5625 +vt 0.43750000000000006 0.3125 +vt 0.6875 0.3125 +vt 0.6875 0.5625 +vt 0 0.015625 +vt 0 0 +vt 0.125 0.015625 +vt 0 0 +vt 0.125 0 +vt 0.125 0.015625 +vt 0.59375 0.5625 +vt 0.59375 0.65625 +vt 0.34374999999999994 0.5625 +vt 0.59375 0.65625 +vt 0.34374999999999994 0.65625 +vt 0.34374999999999994 0.5625 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 1/1/1 3/2/2 2/3/3 +f 3/4/4 4/5/5 2/6/6 +usemtl m_0 +f 5/7/7 7/8/8 6/9/9 +f 7/10/10 8/11/11 6/12/12 +usemtl m_0 +f 5/13/13 6/14/14 2/15/15 +f 6/16/16 1/17/17 2/18/18 +usemtl m_0 +f 8/19/19 7/20/20 3/21/21 +f 7/22/22 4/23/23 3/24/24 +usemtl m_0 +f 2/31/31 4/32/32 5/33/33 +f 4/34/34 7/35/35 5/36/36 +o cube +v -0.3125 -0.3125 -0.3125 +v -0.3125 -0.3125 -0.5 +v -0.3125 -0.5 -0.3125 +v -0.3125 -0.5 -0.5 +v -0.5 -0.3125 -0.5 +v -0.5 -0.3125 -0.3125 +v -0.5 -0.5 -0.5 +v -0.5 -0.5 -0.3125 +vt 0.921875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.625 +vt 0.96875 0.671875 +vt 0.828125 0.765625 +vt 0.828125 0.71875 +vt 0.875 0.765625 +vt 0.828125 0.71875 +vt 0.875 0.71875 +vt 0.875 0.765625 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 1 +vt 0 0.953125 +vt 0.921875 0.765625 +vt 0.921875 0.8125 +vt 0.875 0.765625 +vt 0.921875 0.8125 +vt 0.875 0.8125 +vt 0.875 0.765625 +vt 0.875 0.765625 +vt 0.875 0.71875 +vt 0.921875 0.765625 +vt 0.875 0.71875 +vt 0.921875 0.71875 +vt 0.921875 0.765625 +vt 0.78125 0.765625 +vt 0.78125 0.71875 +vt 0.828125 0.765625 +vt 0.78125 0.71875 +vt 0.828125 0.71875 +vt 0.828125 0.765625 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 9/37/37 11/38/38 10/39/39 +f 11/40/40 12/41/41 10/42/42 +usemtl m_0 +f 13/43/43 15/44/44 14/45/45 +f 15/46/46 16/47/47 14/48/48 +usemtl m_0 +f 16/55/55 15/56/56 11/57/57 +f 15/58/58 12/59/59 11/60/60 +usemtl m_0 +f 14/61/61 16/62/62 9/63/63 +f 16/64/64 11/65/65 9/66/66 +usemtl m_0 +f 10/67/67 12/68/68 13/69/69 +f 12/70/70 15/71/71 13/72/72 +o cube +v 0.5 -0.3125 -0.3125 +v 0.5 -0.3125 -0.5 +v 0.5 -0.5 -0.3125 +v 0.5 -0.5 -0.5 +v 0.3125 -0.3125 -0.5 +v 0.3125 -0.3125 -0.3125 +v 0.3125 -0.5 -0.5 +v 0.3125 -0.5 -0.3125 +vt 0.78125 0.953125 +vt 0.78125 0.90625 +vt 0.828125 0.953125 +vt 0.78125 0.90625 +vt 0.828125 0.90625 +vt 0.828125 0.953125 +vt 0.875 0.953125 +vt 0.875 0.90625 +vt 0.921875 0.953125 +vt 0.875 0.90625 +vt 0.921875 0.90625 +vt 0.921875 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 1 +vt 0 0.953125 +vt 0.921875 0.953125 +vt 0.921875 1 +vt 0.875 0.953125 +vt 0.921875 1 +vt 0.875 1 +vt 0.875 0.953125 +vt 0.921875 0.953125 +vt 0.921875 0.90625 +vt 0.96875 0.953125 +vt 0.921875 0.90625 +vt 0.96875 0.90625 +vt 0.96875 0.953125 +vt 0.828125 0.953125 +vt 0.828125 0.90625 +vt 0.875 0.953125 +vt 0.828125 0.90625 +vt 0.875 0.90625 +vt 0.875 0.953125 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn 1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn -1 0 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +vn 0 0 -1 +usemtl m_0 +f 17/73/73 19/74/74 18/75/75 +f 19/76/76 20/77/77 18/78/78 +usemtl m_0 +f 21/79/79 23/80/80 22/81/81 +f 23/82/82 24/83/83 22/84/84 +usemtl m_0 +f 24/91/91 23/92/92 19/93/93 +f 23/94/94 20/95/95 19/96/96 +usemtl m_0 +f 22/97/97 24/98/98 17/99/99 +f 24/100/100 19/101/101 17/102/102 +usemtl m_0 +f 18/103/103 20/104/104 21/105/105 +f 20/106/106 23/107/107 21/108/108 diff --git a/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj new file mode 100644 index 000000000..9a34a27ec --- /dev/null +++ b/mods/ITEMS/mcl_beds/models/mcl_beds_bed_top.obj @@ -0,0 +1,299 @@ +# Made in Blockbench 3.6.6 +mtllib mcl_beds_bed_top.mtl +o cube +v -0.5000000000000001 0.0625 -0.49999999999999994 +v -0.49999999999999994 0.0625 0.5000000000000001 +v -0.5000000000000001 -0.3125 -0.49999999999999994 +v -0.49999999999999994 -0.3125 0.5000000000000001 +v 0.5000000000000001 0.0625 0.49999999999999994 +v 0.49999999999999994 0.0625 -0.5000000000000001 +v 0.5000000000000001 -0.3125 0.49999999999999994 +v 0.49999999999999994 -0.3125 -0.5000000000000001 +vt 0.34374999999999994 0.65625 +vt 0.43749999999999994 0.65625 +vt 0.34374999999999994 0.90625 +vt 0.43749999999999994 0.65625 +vt 0.43749999999999994 0.90625 +vt 0.34374999999999994 0.90625 +vt 0.09375 0.90625 +vt 0 0.90625 +vt 0.09375 0.65625 +vt 0 0.90625 +vt 0 0.65625 +vt 0.09375 0.65625 +vt 0.09375 0.90625 +vt 0.09375 0.65625 +vt 0.34375 0.90625 +vt 0.09375 0.65625 +vt 0.34375 0.65625 +vt 0.34375 0.90625 +vt 0.6874843749999999 0.6562812499999999 +vt 0.6874843749999999 0.90628125 +vt 0.437484375 0.6562812499999999 +vt 0.6874843749999999 0.90628125 +vt 0.437484375 0.90628125 +vt 0.437484375 0.6562812499999999 +vt 0 1 +vt 0 0.875 +vt 0.1875 1 +vt 0 0.875 +vt 0.1875 0.875 +vt 0.1875 1 +vt 0.34375 0.90625 +vt 0.34375 1 +vt 0.09375 0.90625 +vt 0.34375 1 +vt 0.09375 1 +vt 0.09375 0.90625 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 1/1/1 3/2/2 2/3/3 +f 3/4/4 4/5/5 2/6/6 +usemtl m_0 +f 5/7/7 7/8/8 6/9/9 +f 7/10/10 8/11/11 6/12/12 +usemtl m_0 +f 5/13/13 6/14/14 2/15/15 +f 6/16/16 1/17/17 2/18/18 +usemtl m_0 +f 8/19/19 7/20/20 3/21/21 +f 7/22/22 4/23/23 3/24/24 +usemtl none +f 6/25/25 8/26/26 1/27/27 +f 8/28/28 3/29/29 1/30/30 +usemtl m_0 +f 2/31/31 4/32/32 5/33/33 +f 4/34/34 7/35/35 5/36/36 +o cube +v 0.31250000000000006 -0.3125 0.31249999999999994 +v 0.31250000000000006 -0.3125 0.49999999999999994 +v 0.31250000000000006 -0.5 0.31249999999999994 +v 0.31250000000000006 -0.5 0.49999999999999994 +v 0.5000000000000001 -0.3125 0.49999999999999994 +v 0.5 -0.3125 0.31249999999999994 +v 0.5000000000000001 -0.5 0.49999999999999994 +v 0.5 -0.5 0.31249999999999994 +vt 0.921875 0.859375 +vt 0.921875 0.8125 +vt 0.96875 0.859375 +vt 0.921875 0.8125 +vt 0.96875 0.8125 +vt 0.96875 0.859375 +vt 0.828125 0.859375 +vt 0.828125 0.8125 +vt 0.875 0.859375 +vt 0.828125 0.8125 +vt 0.875 0.8125 +vt 0.875 0.859375 +vt 0 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0.875 0.90625 +vt 0.875 0.859375 +vt 0.921875 0.90625 +vt 0.875 0.859375 +vt 0.921875 0.859375 +vt 0.921875 0.90625 +vt 0.875 0.859375 +vt 0.875 0.8125 +vt 0.921875 0.859375 +vt 0.875 0.8125 +vt 0.921875 0.8125 +vt 0.921875 0.859375 +vt 0.78125 0.859375 +vt 0.78125 0.8125 +vt 0.828125 0.859375 +vt 0.78125 0.8125 +vt 0.828125 0.8125 +vt 0.828125 0.859375 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 9/37/37 11/38/38 10/39/39 +f 11/40/40 12/41/41 10/42/42 +usemtl m_0 +f 13/43/43 15/44/44 14/45/45 +f 15/46/46 16/47/47 14/48/48 +usemtl none +f 13/49/49 14/50/50 10/51/51 +f 14/52/52 9/53/53 10/54/54 +usemtl m_0 +f 16/55/55 15/56/56 11/57/57 +f 15/58/58 12/59/59 11/60/60 +usemtl m_0 +f 14/61/61 16/62/62 9/63/63 +f 16/64/64 11/65/65 9/66/66 +usemtl m_0 +f 10/67/67 12/68/68 13/69/69 +f 12/70/70 15/71/71 13/72/72 +o cube +v -0.5 -0.3125 0.31249999999999994 +v -0.4999999999999999 -0.3125 0.49999999999999994 +v -0.5 -0.5 0.31249999999999994 +v -0.4999999999999999 -0.5 0.49999999999999994 +v -0.3124999999999999 -0.3125 0.4999999999999999 +v -0.3125 -0.3125 0.3124999999999999 +v -0.3124999999999999 -0.5 0.4999999999999999 +v -0.3125 -0.5 0.3124999999999999 +vt 0.78125 0.671875 +vt 0.78125 0.625 +vt 0.828125 0.671875 +vt 0.78125 0.625 +vt 0.828125 0.625 +vt 0.828125 0.671875 +vt 0.875 0.671875 +vt 0.875 0.625 +vt 0.921875 0.671875 +vt 0.875 0.625 +vt 0.921875 0.625 +vt 0.921875 0.671875 +vt 0 1 +vt 0 0.953125 +vt 0.046875 1 +vt 0 0.953125 +vt 0.046875 0.953125 +vt 0.046875 1 +vt 0.87496875 0.7187656250000001 +vt 0.87496875 0.6719062499999999 +vt 0.921828125 0.7187656250000001 +vt 0.87496875 0.6719062499999999 +vt 0.921828125 0.6719062499999999 +vt 0.921828125 0.7187656250000001 +vt 0.921875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.671875 +vt 0.921875 0.625 +vt 0.96875 0.625 +vt 0.96875 0.671875 +vt 0.828125 0.671875 +vt 0.828125 0.625 +vt 0.875 0.671875 +vt 0.828125 0.625 +vt 0.875 0.625 +vt 0.875 0.671875 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn -1 0 1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 1 0 -1.2246467991473532e-16 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn 0 -1 0 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn -1.2246467991473532e-16 0 -1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +vn 1.2246467991473532e-16 0 1 +usemtl m_0 +f 17/73/73 19/74/74 18/75/75 +f 19/76/76 20/77/77 18/78/78 +usemtl m_0 +f 21/79/79 23/80/80 22/81/81 +f 23/82/82 24/83/83 22/84/84 +usemtl none +f 21/85/85 22/86/86 18/87/87 +f 22/88/88 17/89/89 18/90/90 +usemtl m_0 +f 24/91/91 23/92/92 19/93/93 +f 23/94/94 20/95/95 19/96/96 +usemtl m_0 +f 22/97/97 24/98/98 17/99/99 +f 24/100/100 19/101/101 17/102/102 +usemtl m_0 +f 18/103/103 20/104/104 21/105/105 +f 20/106/106 23/107/107 21/108/108 diff --git a/mods/ITEMS/mcl_beds/respawn_anchor.lua b/mods/ITEMS/mcl_beds/respawn_anchor.lua new file mode 100644 index 000000000..781a82953 --- /dev/null +++ b/mods/ITEMS/mcl_beds/respawn_anchor.lua @@ -0,0 +1,79 @@ +--TODO: Add sounds for the respawn anchor (charge sounds etc.) + +--Nether ends at y -29077 +--Nether roof at y -28933 +local S = minetest.get_translator(minetest.get_current_modname()) +--local mod_doc = minetest.get_modpath("doc") -> maybe add documentation ? + +for i=0,4 do + + local function rightclick(pos, node, player, itemstack) + if itemstack.get_name(itemstack) == "mcl_nether:glowstone" and i ~= 4 then + minetest.set_node(pos, {name="mcl_beds:respawn_anchor_charged_" .. i+1}) + itemstack:take_item() + elseif mcl_worlds.pos_to_dimension(pos) ~= "nether" then + if node.name ~= "mcl_beds:respawn_anchor" then --only charged respawn anchors are exploding in the overworld & end in minecraft + mcl_explosions.explode(pos, 5, {drop_chance = 0, fire = true}) + end + elseif string.match(node.name, "mcl_beds:respawn_anchor_charged_") then + minetest.chat_send_player(player.get_player_name(player), S"New respawn position set!") + mcl_spawn.set_spawn_pos(player, pos, nil) + if i == 4 then + awards.unlock(player:get_player_name(), "mcl:notQuiteNineLives") + end + end + end + + + if i == 0 then + minetest.register_node("mcl_beds:respawn_anchor",{ + description=S("Respawn Anchor"), + tiles = { + "respawn_anchor_top_off.png", + "respawn_anchor_bottom.png", + "respawn_anchor_side0.png" + }, + on_rightclick = rightclick, + groups = {pickaxey=1, material_stone=1}, + _mcl_hardness = 22.5, + sounds= mcl_sounds.node_sound_stone_defaults(), + use_texture_alpha = "blend", + }) + mesecon.register_mvps_stopper("mcl_beds:respawn_anchor") + else + minetest.register_node("mcl_beds:respawn_anchor_charged_"..i,{ + description=S("Respawn Anchor"), + tiles = { + { + name = "respawn_anchor_top_on.png^[noalpha", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + "respawn_anchor_bottom.png", + "respawn_anchor_side"..i ..".png" + }, + on_rightclick = rightclick, + groups = {pickaxey=1, material_stone=1, not_in_creative_inventory=1}, + _mcl_hardness = 22.5, + sounds= mcl_sounds.node_sound_stone_defaults(), + drop = { + max_items = 1, + items = { + {items = {"mcl_beds:respawn_anchor"}}, + } + }, + light_source = math.min((4 * i) - 1, minetest.LIGHT_MAX), + use_texture_alpha = "blend", + }) + mesecon.register_mvps_stopper("mcl_beds:respawn_anchor_charged_"..i) + end + end + + +minetest.register_craft({ + output = "mcl_beds:respawn_anchor", + recipe = { + {"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"}, + {"mcl_nether:glowstone", "mcl_nether:glowstone", "mcl_nether:glowstone"}, + {"mcl_core:crying_obsidian", "mcl_core:crying_obsidian", "mcl_core:crying_obsidian"} + } + }) diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png deleted file mode 100644 index 35c9d59ca..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png deleted file mode 100644 index 87a0e2abd..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_bottom_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png deleted file mode 100644 index 302bc5b40..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png deleted file mode 100644 index 0d5b3f412..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png deleted file mode 100644 index 25983a530..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png deleted file mode 100644 index 94614b075..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png deleted file mode 100644 index f4990d58f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png deleted file mode 100644 index 40727ca8e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png deleted file mode 100644 index dec15108d..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png deleted file mode 100644 index fef72ce3b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png deleted file mode 100644 index f1cfdde62..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png deleted file mode 100644 index e8faf315e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png deleted file mode 100644 index f536a7960..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png deleted file mode 100644 index acdf05e87..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png deleted file mode 100644 index 84c1b31f2..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png deleted file mode 100644 index 474a8f6fb..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png deleted file mode 100644 index fe1e8e425..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png deleted file mode 100644 index 5eacdf654..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png deleted file mode 100644 index d98f4263a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png deleted file mode 100644 index 02e80ed96..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png deleted file mode 100644 index c3ca6ed88..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png deleted file mode 100644 index d33985789..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png deleted file mode 100644 index 273f0f570..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png deleted file mode 100644 index 65333f73a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png deleted file mode 100644 index 5907ad86f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png deleted file mode 100644 index 0bfa0a1b7..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png deleted file mode 100644 index b324086d6..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png deleted file mode 100644 index 0269dc778..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png deleted file mode 100644 index 1ed1e0239..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png deleted file mode 100644 index 378b63341..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_r_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png deleted file mode 100644 index 103570e14..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png deleted file mode 100644 index 490298dd1..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png deleted file mode 100644 index 8cdbd2b1d..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png deleted file mode 100644 index fed97cded..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_bottom_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png deleted file mode 100644 index 5bfa983c3..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png deleted file mode 100644 index ecf58cd03..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png deleted file mode 100644 index f1473c36a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png deleted file mode 100644 index e3c466ece..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png deleted file mode 100644 index e59981a4c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png deleted file mode 100644 index 65052ad02..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png deleted file mode 100644 index 974ac6566..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png deleted file mode 100644 index 88c367407..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png deleted file mode 100644 index 04bdc7ddf..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png deleted file mode 100644 index 5271b820a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png deleted file mode 100644 index ca6b5047a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png deleted file mode 100644 index 740824b38..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png deleted file mode 100644 index 638bdd508..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png deleted file mode 100644 index b0739432e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png deleted file mode 100644 index 1e536432e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png deleted file mode 100644 index a3d9c8c2b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_r_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png deleted file mode 100644 index 39fb8c580..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_side_top_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png deleted file mode 100644 index 046e847a6..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png deleted file mode 100644 index 0c6affda8..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png deleted file mode 100644 index cf3eaa405..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png deleted file mode 100644 index 2963d1da2..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png deleted file mode 100644 index d1cd63897..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_gray.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png deleted file mode 100644 index 4eda85f33..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png deleted file mode 100644 index 1aa01946e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png deleted file mode 100644 index 949efb20e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png deleted file mode 100644 index 14ad57bd1..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png deleted file mode 100644 index ce9e6a3de..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png deleted file mode 100644 index 036ec1169..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png deleted file mode 100644 index b94a3d989..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png deleted file mode 100644 index bf053e334..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png deleted file mode 100644 index 77668f201..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png deleted file mode 100644 index d17a506e3..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png deleted file mode 100644 index ee8105119..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png deleted file mode 100644 index d10fb92fa..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_bottom_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png deleted file mode 100644 index 1c2c0abcd..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png deleted file mode 100644 index ccc492158..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png deleted file mode 100644 index d18faece8..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png deleted file mode 100644 index 0bddf475e..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png deleted file mode 100644 index 00b23cd8a..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png deleted file mode 100644 index 1c4903075..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png deleted file mode 100644 index df13cf007..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png deleted file mode 100644 index b9194be16..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png deleted file mode 100644 index 215ef796c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png deleted file mode 100644 index 473caf37f..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png deleted file mode 100644 index ac8b29b9b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png deleted file mode 100644 index e29210540..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png deleted file mode 100644 index a418835b5..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png deleted file mode 100644 index 51609fb0c..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png deleted file mode 100644 index d2dc47702..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png b/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png deleted file mode 100644 index 10edecc3b..000000000 Binary files a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_top_top_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_beehives/init.lua b/mods/ITEMS/mcl_beehives/init.lua new file mode 100644 index 000000000..82b3cae5f --- /dev/null +++ b/mods/ITEMS/mcl_beehives/init.lua @@ -0,0 +1,245 @@ +------------------ +---- Beehives ---- +------------------ + +-- Variables +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 is_creative = minetest.is_creative_enabled(player:get_player_name()) + + 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 + + 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 + local honey = "mcl_honey:honey_bottle" + if inv:room_for_item("main", honey) then + node.name = beehive + minetest.set_node(pos, node) + 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 + end + elseif shears then + minetest.add_item(pos, "mcl_honey:honeycomb 3") + node.name = beehive + minetest.set_node(pos, node) + if not campfire[1] then mcl_util.deal_damage(player, 10) end + end +end + +-- Dig Function for Beehives +local dig_hive = function(pos, node, oldmetadata, digger) + local wield_item = digger:get_wielded_item() + local beehive = string.find(node.name, "mcl_beehives:beehive") + local beenest = string.find(node.name, "mcl_beehives:bee_nest") + 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 beehive then + if not is_creative then + minetest.add_item(pos, "mcl_beehives:beehive") + if not silk_touch then mcl_util.deal_damage(digger, 10) end + elseif is_creative and inv:room_for_item("main", "mcl_beehives:beehive") and not inv:contains_item("main", "mcl_beehives:beehive") then + inv:add_item("main", "mcl_beehives:beehive") + end + elseif beenest then + if not is_creative then + if silk_touch then + minetest.add_item(pos, "mcl_beehives:bee_nest") + awards.unlock(digger:get_player_name(), "mcl:total_beelocation") + else + mcl_util.deal_damage(digger, 10) + end + elseif is_creative and inv:room_for_item("main", "mcl_beehives:bee_nest") and not inv:contains_item("main", "mcl_beehives:bee_nest") then + inv:add_item("main", "mcl_beehives:bee_nest") + end + end +end + +-- Beehive +minetest.register_node("mcl_beehives:beehive", { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + drop = "", + after_dig_node = dig_hive, +}) + +for l = 1, 4 do + minetest.register_node("mcl_beehives:beehive_" .. l, { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, not_in_creative_inventory = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + drop = "", + after_dig_node = dig_hive, + }) +end + +minetest.register_node("mcl_beehives:beehive_5", { + description = S("Beehive"), + _doc_items_longdesc = S("Artificial bee nest."), + tiles = { + "mcl_beehives_beehive_end.png", "mcl_beehives_beehive_end.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_side.png", + "mcl_beehives_beehive_side.png", "mcl_beehives_beehive_front_honey.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 5, material_wood = 1, not_in_creative_inventory = 1, beehive = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, + on_rightclick = honey_harvest, + drop = "", + after_dig_node = dig_hive, +}) + +-- Bee Nest +minetest.register_node("mcl_beehives:bee_nest", { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + drop = "", + after_dig_node = dig_hive, +}) + +for i = 1, 4 do + minetest.register_node("mcl_beehives:bee_nest_"..i, { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, not_in_creative_inventory = 1, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + drop = "", + after_dig_node = dig_hive, + }) +end + +minetest.register_node("mcl_beehives:bee_nest_5", { + description = S("Bee Nest"), + _doc_items_longdesc = S("A naturally generating block that houses bees and a tasty treat...if you can get it."), + tiles = { + "mcl_beehives_bee_nest_top.png", "mcl_beehives_bee_nest_bottom.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_side.png", + "mcl_beehives_bee_nest_side.png", "mcl_beehives_bee_nest_front_honey.png", + }, + paramtype2 = "facedir", + groups = { axey = 1, deco_block = 1, flammable = 0, fire_flammability = 30, not_in_creative_inventory = 1, bee_nest = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 0.3, + _mcl_hardness = 0.3, + on_rightclick = honey_harvest, + drop = "", + after_dig_node = dig_hive, +}) + +-- Crafting +minetest.register_craft({ + output = "mcl_beehives:beehive", + recipe = { + { "group:wood", "group:wood", "group:wood" }, + { "mcl_honey:honeycomb", "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + { "group:wood", "group:wood", "group:wood" }, + }, +}) + +-- Temporary ABM to update honey levels +minetest.register_abm({ + label = "Update Beehive Honey Levels", + nodenames = "group:beehive", + interval = 500, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local beehive = "mcl_beehives:beehive" + if node.name == beehive then + node.name = beehive.."_1" + minetest.set_node(pos, node) + elseif node.name == beehive.."_1" then + node.name = beehive.."_2" + minetest.set_node(pos, node) + elseif node.name == beehive.."_2" then + node.name = beehive.."_3" + minetest.set_node(pos, node) + elseif node.name == beehive.."_3" then + node.name = beehive.."_4" + minetest.set_node(pos, node) + elseif node.name == beehive.."_4" then + node.name = beehive.."_5" + minetest.set_node(pos, node) + end + end, +}) + +minetest.register_abm({ + label = "Update Bee Nest Honey Levels", + nodenames = "group:bee_nest", + interval = 500, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local beehive = "mcl_beehives:bee_nest" + if node.name == beehive then + node.name = beehive.."_1" + minetest.set_node(pos, node) + elseif node.name == beehive.."_1" then + node.name = beehive.."_2" + minetest.set_node(pos, node) + elseif node.name == beehive.."_2" then + node.name = beehive.."_3" + minetest.set_node(pos, node) + elseif node.name == beehive.."_3" then + node.name = beehive.."_4" + minetest.set_node(pos, node) + elseif node.name == beehive.."_4" then + node.name = beehive.."_5" + minetest.set_node(pos, node) + end + end, +}) diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr new file mode 100644 index 000000000..61510cbc1 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.dk.tr @@ -0,0 +1,4 @@ +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 diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.fr.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.fr.tr new file mode 100644 index 000000000..45e66fa12 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_beehives +Beehive=Ruche +Artificial bee nest.=Ruche artificielle. +Bee Nest=Nid d'abeilles +A naturally generating block that houses bees and a tasty treat...if you can get it.=Un bloc généré naturellement qui héberge les abeilles et une délicieuse friandise... Si vous pouvez la récupérer. diff --git a/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.tr b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.tr new file mode 100644 index 000000000..273cefae8 --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/mcl_beehives.ja.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_beehives/locale/template.txt b/mods/ITEMS/mcl_beehives/locale/template.txt new file mode 100644 index 000000000..ff4be403c --- /dev/null +++ b/mods/ITEMS/mcl_beehives/locale/template.txt @@ -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_beehives/mod.conf b/mods/ITEMS/mcl_beehives/mod.conf new file mode 100644 index 000000000..0a7855bec --- /dev/null +++ b/mods/ITEMS/mcl_beehives/mod.conf @@ -0,0 +1,4 @@ +name = mcl_beehives +author = PrairieWind +description = Adds beehives and bee nests to MineClone 2. +depends = mcl_util, mcl_enchanting diff --git a/mods/ITEMS/mcl_bells/README.md b/mods/ITEMS/mcl_bells/README.md new file mode 100644 index 000000000..53cba890c --- /dev/null +++ b/mods/ITEMS/mcl_bells/README.md @@ -0,0 +1,16 @@ +mcl_bells +--------- +Village bells for MineClone2, originally imported from mcl5, heavily modified by cora. + +License of media files +---------------------- +* sounds/bell_stroke.ogg - cc0 http://creativecommons.org/publicdomain/zero/1.0/ + * created by edsward + * modified by sorcerykid + * obtained from https://freesound.org/people/edsward/sounds/341866/ + +* textures/mcl_bells_bell.png - cc4-by-sa https://creativecommons.org/licenses/by-sa/4.0/ + * from pixelperfection by XSSheep and NovaWostra ( https://www.planetminecraft.com/texture-pack/pixel-perfection-chorus-edit/ ) + +* textures/mcl_bells_bell_*.png - cc0 http://creativecommons.org/publicdomain/zero/1.0/ + * created by cora diff --git a/mods/ITEMS/mcl_bells/init.lua b/mods/ITEMS/mcl_bells/init.lua new file mode 100644 index 000000000..32bdfe3d7 --- /dev/null +++ b/mods/ITEMS/mcl_bells/init.lua @@ -0,0 +1,50 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_bells = {} + +local has_mcl_wip = minetest.get_modpath("mcl_wip") + +function mcl_bells.ring_once(pos) + minetest.sound_play( "mcl_bells_bell_stroke", { pos = pos, gain = 1.5, max_hear_distance = 150,}) + local vv=minetest.get_objects_inside_radius(pos,150) + for _,o in pairs(vv) do + if o.type == "npc" then + o:get_luaentity():gopath(pos,function() end) + end + end +end + +minetest.register_node("mcl_bells:bell", { + description = S("Bell"), + inventory_image = "mcl_bells_bell.png", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 }, + { -6/16, -6/16, -6/16, 6/16, 6/16, 6/16 }, + { -2/16, 6/16, -2/16, 2/16, 8/16, 2/16 }, + } + }, + --tiles = { "blank.png" }, + tiles = { + "mcl_bells_bell_top.png", + "mcl_bells_bell_bottom.png", + "mcl_bells_bell_side.png", + }, + is_ground_content = false, + groups = {pickaxey=2, deco_block=1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 5, + _mcl_hardness = 5, + on_rightclick = mcl_bells.ring_once, + use_texture_alpha = "clip", + mesecons = {effector = { + action_on = mcl_bells.ring_once, + rules = mesecon.rules.flat, + }}, +}) + +if has_mcl_wip then + mcl_wip.register_wip_item("mcl_bells:bell") +end diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.dk.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.dk.tr new file mode 100644 index 000000000..6089d8f6b --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.dk.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=Klokke diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.es.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.es.tr new file mode 100644 index 000000000..b11750b3e --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.es.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=Campana diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr new file mode 100644 index 000000000..cfd5a65c9 --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.fr.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=Cloche diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr new file mode 100644 index 000000000..2a8ee56ea --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=鐘 diff --git a/mods/ITEMS/mcl_bells/locale/mcl_bells.pt_BR.tr b/mods/ITEMS/mcl_bells/locale/mcl_bells.pt_BR.tr new file mode 100644 index 000000000..a64a13324 --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/mcl_bells.pt_BR.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell=Sino diff --git a/mods/ITEMS/mcl_bells/locale/template.txt b/mods/ITEMS/mcl_bells/locale/template.txt new file mode 100644 index 000000000..c6475fb83 --- /dev/null +++ b/mods/ITEMS/mcl_bells/locale/template.txt @@ -0,0 +1,2 @@ +# textdomain: mcl_bells +Bell= diff --git a/mods/ITEMS/mcl_bells/mod.conf b/mods/ITEMS/mcl_bells/mod.conf new file mode 100644 index 000000000..e25b1fc5c --- /dev/null +++ b/mods/ITEMS/mcl_bells/mod.conf @@ -0,0 +1,3 @@ +name = mcl_bells +depends = mesecons +optional_depends = mcl_wip \ No newline at end of file diff --git a/mods/ITEMS/mcl_bells/sounds/mcl_bells_bell_stroke.ogg b/mods/ITEMS/mcl_bells/sounds/mcl_bells_bell_stroke.ogg new file mode 100755 index 000000000..023d1f946 Binary files /dev/null and b/mods/ITEMS/mcl_bells/sounds/mcl_bells_bell_stroke.ogg differ diff --git a/mods/ITEMS/mcl_blackstone/README.md b/mods/ITEMS/mcl_blackstone/README.md new file mode 100644 index 000000000..d2e385f04 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/README.md @@ -0,0 +1,11 @@ +# Blackstone Mod + +This mod adds new Blocks: Blackstone, Basalt, Soul Fire, Soul Torch etc. + +## Version: + +Its version 1.0.2 + +## License + +CC BY-SA 4.0 diff --git a/mods/ITEMS/mcl_blackstone/init.lua b/mods/ITEMS/mcl_blackstone/init.lua new file mode 100644 index 000000000..fd05465d3 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/init.lua @@ -0,0 +1,364 @@ +local S = minetest.get_translator("mcl_blackstone") + + +local on_rotate +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.rotate_3way +end + +--Blocks +minetest.register_node("mcl_blackstone:blackstone", { + description = S("Blackstone"), + tiles = {"mcl_blackstone_top.png", "mcl_blackstone_top.png", "mcl_blackstone_side.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1, cobble=1}, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, +}) +minetest.register_node("mcl_blackstone:blackstone_gilded", { + description = S("Gilded Blackstone"), + tiles = {"mcl_blackstone_gilded.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1, xp=1}, + drop = { + max_items = 1, + items = { + {items = {"mcl_core:gold_nugget 2"},rarity = 40}, + {items = {"mcl_core:gold_nugget 3"},rarity = 40}, + {items = {"mcl_core:gold_nugget 4"},rarity = 40}, + {items = {"mcl_core:gold_nugget 5"},rarity = 40}, + -- 4x 1 in 40 chance adds up to a 10% chance + {items = {"mcl_blackstone:blackstone_gilded"}, rarity = 1}, + } + }, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_core:gold_nugget"}, + min_count = 2, + max_count = 5, + cap = 5, + }, +}) +minetest.register_node("mcl_blackstone:nether_gold", { + description = S("Nether Gold Ore"), + tiles = {"mcl_nether_gold_ore.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1, xp=1}, + drop = { + max_items = 1, + items = { + {items = {"mcl_core:gold_nugget 6"},rarity = 5}, + {items = {"mcl_core:gold_nugget 5"},rarity = 5}, + {items = {"mcl_core:gold_nugget 4"},rarity = 5}, + {items = {"mcl_core:gold_nugget 3"},rarity = 5}, + {items = {"mcl_core:gold_nugget 2"},rarity = 1}, + } + }, + _mcl_blast_resistance = 3, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, +}) +minetest.register_node("mcl_blackstone:basalt_polished", { + description = S("Polished Basalt"), + tiles = {"mcl_blackstone_basalt_top_polished.png", "mcl_blackstone_basalt_top_polished.png", "mcl_blackstone_basalt_side_polished.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + on_rotate = on_rotate, + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, +}) +minetest.register_node("mcl_blackstone:basalt", { + description = S("Basalt"), + tiles = {"mcl_blackstone_basalt_top.png", "mcl_blackstone_basalt_top.png", "mcl_blackstone_basalt_side.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + on_rotate = on_rotate, + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, +}) +minetest.register_node("mcl_blackstone:basalt_smooth", { + description = S("Smooth Basalt"), + tiles = {"mcl_blackstone_basalt_smooth.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 4.2, + _mcl_hardness = 1.25, +}) +minetest.register_node("mcl_blackstone:blackstone_polished", { + description = S("Polished Blackstone"), + tiles = {"mcl_blackstone_polished.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 6, + _mcl_hardness = 2, +}) +minetest.register_node("mcl_blackstone:blackstone_chiseled_polished", { + description = S("Chiseled Polished Blackstone"), + tiles = {"mcl_blackstone_chiseled_polished.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, +}) +minetest.register_node("mcl_blackstone:blackstone_brick_polished", { + description = S("Polished Blackstone Bricks"), + tiles = {"mcl_blackstone_polished_bricks.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, +}) +minetest.register_node("mcl_blackstone:quartz_brick", { + description = S("Quartz Bricks"), + tiles = {"mcl_backstone_quartz_bricks.png"}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + groups = {cracky = 3, pickaxey=1, material_stone=1}, + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, +}) +minetest.register_node("mcl_blackstone:soul_soil", { + description = S("Soul Soil"), + tiles = {"mcl_blackstone_soul_soil.png"}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_sand_defaults(), + groups = { cracky = 3, handy = 1, shovely = 1, soul_block = 1 }, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, +}) +minetest.register_node("mcl_blackstone:soul_fire", { + description = S("Eternal Soul Fire"), + _doc_items_longdesc = minetest.registered_nodes["mcl_fire:eternal_fire"]._doc_items_longdesc , + drawtype = "firelike", + tiles = { + { + name = "soul_fire_basic_flame_animated.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 1 + }, + }, + }, + inventory_image = "soul_fire_basic_flame.png", + paramtype = "light", + light_source = 10, + walkable = false, + buildable_to = true, + sunlight_propagates = true, + damage_per_second = 2, + _mcl_node_death_message = minetest.registered_nodes["mcl_fire:fire"]._mcl_node_death_message, + groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8}, + floodable = true, + drop = "", + on_flood = function(pos, oldnode, newnode) + if minetest.get_item_group(newnode.name, "water") > 0 then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + end, + on_construct=function(pos) + local under = minetest.get_node(vector.offset(pos,0,-1,0)).name + if minetest.get_item_group(under,"soul_block") > 0 then + minetest.swap_node(pos, {name = "air"}) + end + end +}) + +local old_onconstruct=minetest.registered_nodes["mcl_fire:fire"].on_construct +minetest.registered_nodes["mcl_fire:fire"].on_construct=function(pos) + local under = minetest.get_node(vector.offset(pos,0,-1,0)).name + if minetest.get_item_group(under,"soul_block") > 0 then + minetest.swap_node(pos, {name = "mcl_blackstone:soul_fire"}) + end + old_onconstruct(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")) + +--Wall +mcl_walls.register_wall("mcl_blackstone:wall", S("Blackstone Wall"), "mcl_blackstone:blackstone") + +--lavacooling + +minetest.register_abm({ + label = "Lava cooling (basalt)", + nodenames = {"group:lava"}, + neighbors = {"mcl_core:ice"}, + interval = 1, + chance = 1, + min_y = mcl_vars.mg_end_min, + action = function(pos, node, active_object_count, active_object_count_wider) + local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "mcl_core:ice") + local lavatype = minetest.registered_nodes[node.name].liquidtype + for w=1, #water do + local waternode = minetest.get_node(water[w]) + local watertype = minetest.registered_nodes[waternode.name].liquidtype + if water[w].y < pos.y and water[w].x == pos.x and water[w].z == pos.z then + minetest.set_node(water[w], {name="mcl_blackstone:basalt"}) + elseif lavatype == "flowing" and water[w].y == pos.y and (water[w].x == pos.x or water[w].z == pos.z) then + minetest.set_node(pos, {name="mcl_blackstone:basalt"}) + elseif lavatype == "flowing" and water[w].y > pos.y and water[w].x == pos.x and water[w].z == pos.z then + minetest.set_node(pos, {name="mcl_blackstone:basalt"}) + end + end + end, +}) + +minetest.register_abm({ + label = "Lava cooling (blackstone)", + nodenames = {"group:lava"}, + neighbors = {"mcl_core:packed_ice"}, + interval = 1, + chance = 1, + min_y = mcl_vars.mg_end_min, + action = function(pos, node, active_object_count, active_object_count_wider) + local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "mcl_core:packed_ice") + local lavatype = minetest.registered_nodes[node.name].liquidtype + for w=1, #water do + local waternode = minetest.get_node(water[w]) + local watertype = minetest.registered_nodes[waternode.name].liquidtype + if water[w].y < pos.y and water[w].x == pos.x and water[w].z == pos.z then + minetest.set_node(water[w], {name="mcl_blackstone:blackstone"}) + elseif lavatype == "flowing" and water[w].y == pos.y and (water[w].x == pos.x or water[w].z == pos.z) then + minetest.set_node(pos, {name="mcl_blackstone:blackstone"}) + elseif lavatype == "flowing" and water[w].y > pos.y and water[w].x == pos.x and water[w].z == pos.z then + minetest.set_node(pos, {name="mcl_blackstone:blackstone"}) + end + end + end, +}) + +--crafting +minetest.register_craft({ + output = "mcl_blackstone:blackstone_polished 4", + recipe = { + {"mcl_blackstone:blackstone","mcl_blackstone:blackstone"}, + {"mcl_blackstone:blackstone","mcl_blackstone:blackstone"}, + } +}) +minetest.register_craft({ + output = "mcl_blackstone:basalt_polished 4", + recipe = { + {"mcl_blackstone:basalt","mcl_blackstone:basalt"}, + {"mcl_blackstone:basalt","mcl_blackstone:basalt"}, + } +}) +minetest.register_craft({ + output = "mcl_blackstone:blackstone_chiseled_polished 2", + recipe = { + {"mcl_blackstone:blackstone_polished"}, + {"mcl_blackstone:blackstone_polished"}, + } +}) +minetest.register_craft({ + output = "mcl_blackstone:blackstone_brick_polished 4", + recipe = { + {"mcl_blackstone:blackstone_polished","mcl_blackstone:blackstone_polished"}, + {"mcl_blackstone:blackstone_polished","mcl_blackstone:blackstone_polished"}, + } +}) +minetest.register_craft({ + output = "mcl_blackstone:quartz_brick 4", + recipe = { + {"mcl_nether:quartz_block","mcl_nether:quartz_block"}, + {"mcl_nether:quartz_block","mcl_nether:quartz_block"}, + } +}) +minetest.register_craft({ + type = "cooking", + output = "mcl_core:gold_ingot", + recipe = "mcl_blackstone:nether_gold", + cooktime = 10, +}) +minetest.register_craft({ + type = "cooking", + output = "mcl_core:gold_ingot", + recipe = "mcl_blackstone:blackstone_gilded", + cooktime = 10, +}) +minetest.register_craft({ + type = "cooking", + output = "mcl_nether:quartz_smooth", + recipe = "mcl_nether:quartz_block", + cooktime = 10, +}) +--[[ Commented out for now because there the discussion how to handle this is ongoing] +--Generating +local specialstones = { "mcl_blackstone:blackstone", "mcl_blackstone:basalt", "mcl_blackstone:soul_soil" } +for s=1, #specialstones do + local node = specialstones[s] + minetest.register_ore({ + ore_type = "blob", + ore = node, + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 830, + clust_num_ores = 28, + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "blob", + ore = node, + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 8*8*8, + clust_num_ores = 40, + clust_size = 5, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) +end + +if minetest.settings:get_bool("mcl_generate_ores", true) then + +end +--]] +--soul torch +mcl_torches.register_torch({ + name="soul_torch", + description=S("Soul Torch"), + doc_items_longdesc = S("Torches are light sources which can be placed at the side or on the top of most blocks."), + doc_items_hidden = false, + icon="soul_torch_on_floor.png", + tiles = {{ + name = "soul_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + light = 12, --soul torches are a bit dimmer than normal torches + groups = {dig_immediate = 3, deco_block = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + particles = true, + flame_type = 2, +}) + +minetest.register_craft({ + output = "mcl_blackstone:soul_torch 4", + recipe = { + {"group:coal"}, + { "mcl_core:stick" }, + { "group:soul_block" }, + } +}) diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr new file mode 100644 index 000000000..11cf26fcd --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.de.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +Blackstone=Schwarzstein +Polished Blackstone=Polierter Schwarzstein +Chiseled Polished Blackstone=Gemeißelter polierter Schwarzstein +Polished Blackstone Bricks=Polierter Schwarzsteinziegel +Basalt=Basalt +Polished Basalt=Polierter Basalt +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 +Quartz Bricks=Quartz Ziegel +Soul Torch=Seelenfakel +Soul Lantern=Seelenlaterne +Soul Soil=Seelenerde +Eternal Soul Fire=Seelenfeuer +Gilded Blackstone=Vergoldeter Schwarzstein +Nether Gold Ore=Nethergolderz +Smooth Basalt=Glatter Basalt + +@1 has been cooked crisp.=@1 wurde knusprig gebraten. +@1 felt the burn.=@1 ist völlig verbrannt. +@1 died in the flames.=@1 starb in den Flammen. +@1 died in a fire.=@1 starb in einem Feuer. diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.dk.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.dk.tr new file mode 100644 index 000000000..0a5f4ce38 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.dk.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +Blackstone=Sortsten +Polished Blackstone=Poleret sortsten +Chiseled Polished Blackstone=Majslet poleret sortsten +Polished Blackstone Bricks=Poleret sortsten-mursten +Basalt=Basalt +Polished Basalt=Poleret basalt +Blackstone Slab=Sortstensflise +Polished Blackstone Slab=Poleret sortstensflise +Chiseled Polished Blackstone Slab=Majslet poleret sortstensflise +Polished Blackstone Brick Slab=Poleret sortstens-murstensflise +Blackstone Stair=Sortstenstrappe +Polished Blackstone Stair=Poleret sortstenstrappe +Chiseled Polished Blackstone Stair=Majslet poleret sortstenstrappe +Polished Blackstone Brick Stair=Poleret sortstens-murstenstrappe +Quartz Bricks=Qvarts-mursten +Soul Torch=Sjæleildsfakkel +Soul Lantern=Sjældeildslaterne +Soul Soil=Sjælejord +Eternal Soul Fire=Evig sjæleild +Gilded Blackstone=Forgyldt sortsten +Nether Gold Ore=Nether guldmalm +Smooth Basalt=Glat basalt +Blackstone Wall=Sorstensmur +Double Blackstone Slab=Dobbelt sortstensflise +Polished Double Blackstone Slab=Poleret dobbelt sortstensflise +Double Chiseled Polished Blackstone Slab=Dobbelt majslet poleret sortstensflise +Double Polished Blackstone Brick Slab=Dobbelt poleret sortstens-murstensflise \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr new file mode 100644 index 000000000..65d52d8a9 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.fr.tr @@ -0,0 +1,29 @@ +# textdomain: mcl_blackstone +Blackstone=Roche noire +Polished Blackstone=Pierre noire +Chiseled Polished Blackstone=Pierre noire sculptée +Polished Blackstone Bricks=Briques de pierre noire +Basalt=Basalte +Polished Basalt=Basalte taillé +Blackstone Slab=Dalle de roche noire +Polished Blackstone Slab=Dalle de pierre noire +Chiseled Polished Blackstone Slab=Dalle de pierre noire sculptée +Polished Blackstone Brick Slab=Dalle de briques de pierre noire +Blackstone Stair=Escalier de roche noire +Polished Blackstone Stair=Escalier de pierre noire +Chiseled Polished Blackstone Stair=Escalier de pierre noire sculptée +Polished Blackstone Brick Stair=Escalier de briques de pierre noire +Quartz Bricks=Briques de quartz +Soul Torch=Torche des âmes +Torches are light sources which can be placed at the side or on the top of most blocks.=Les torches sont des sources lumineuses qui peuvent être placées sur le côté ou sur le dessus de la plupart des blocs. +Soul Lantern=Lanterne des âmes +Soul Soil=Terre des âmes +Eternal Soul Fire=Feu éternel des âmes +Gilded Blackstone=Roche noire dorée +Nether Gold Ore=Minerai d'or du Nether +Smooth Basalt=Basalte lisse +Blackstone Wall=Muret de roche noire +Double Blackstone Slab=Double dalle de roche noire +Polished Double Blackstone Slab=Double dalle de pierre noire +Double Chiseled Polished Blackstone Slab=Double dalle de pierre noire sculptée +Double Polished Blackstone Brick Slab=Double dalle de briques de pierre noire diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr new file mode 100644 index 000000000..b85a4a9d6 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.ja.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +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=磨かれたブラックストーンレンガの階段 +Quartz Bricks=クォーツレンガ +Soul Torch=ソウルトーチ +Soul Lantern=ソウルランタン +Soul Soil=ソウルソイル +Eternal Soul Fire=永続的な魂の炎 +Gilded Blackstone=金色のブラックストーン +Nether Gold Ore=ネザー金鉱石 +Smooth Basalt=滑らかな玄武岩 +Blackstone Wall=ブラックストーンの塀 +Double Blackstone Slab=ブラックストーンの2重スラブ +Polished Double Blackstone Slab=磨かれたブラックストーンの2重スラブ +Double Chiseled Polished Blackstone Slab=模様入りの磨かれたブラックストーンの2重スラブ +Double Polished Blackstone Brick Slab=磨かれたブラックストーンレンガの2重スラブ \ No newline at end of file diff --git a/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.pt_BR.tr b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.pt_BR.tr new file mode 100644 index 000000000..e91d54e07 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/mcl_blackstone.pt_BR.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_blackstone +Blackstone=Rocha-negra +Polished Blackstone=Rocha-negra Polida +Chiseled Polished Blackstone=Rocha-negra Polida Cinzelada +Polished Blackstone Bricks=Tijolo de Rocha-negra Polida +Basalt=Basalto +Polished Basalt=Basalto Polido +Blackstone Slab=Laje de Rocha-negra +Polished Blackstone Slab=Laje de Rocha-negra Polida +Chiseled Polished Blackstone Slab=Laje de Rocha-negra Polida Cinzelada +Polished Blackstone Brick Slab=Laje de Tijolo de Rocha-negra Polida +Blackstone Stair=Escada de Rocha-negra +Polished Blackstone Stair=Escada de Rocha-negra Polida +Chiseled Polished Blackstone Stair=Escada de Rocha-negra Polida Cinzelada +Polished Blackstone Brick Stair=Escada de Tijolo de Rocha-negra Polida +Quartz Bricks=Tijolos de Quartzo +Soul Torch=Tocha de Alma +Soul Lantern=Lanterna de Alma +Soul Soil=Solo de Alma +Eternal Soul Fire=Eterno Fogo de Alma +Gilded Blackstone=Rocha-negra Dourada +Nether Gold Ore=Minério de Ouro do Nether +Smooth Basalt=Basalto Liso +Blackstone Wall=Muro de Rocha-negra +Double Blackstone Slab=Dupla Laje de Rocha-negra +Polished Double Blackstone Slab=Dupla Laje de Rocha-negra Polida +Double Chiseled Polished Blackstone Slab=Dupla Laje de Rocha-negra Polida Cinzelada +Double Polished Blackstone Brick Slab=Dupla Laje de Tijolo de Rocha-negra Polida diff --git a/mods/ITEMS/mcl_blackstone/locale/template.txt b/mods/ITEMS/mcl_blackstone/locale/template.txt new file mode 100644 index 000000000..54b1be346 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/locale/template.txt @@ -0,0 +1,29 @@ +# textdomain: mcl_blackstone +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= +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= +Smooth Basalt= +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 new file mode 100644 index 000000000..8728f5b01 --- /dev/null +++ b/mods/ITEMS/mcl_blackstone/mod.conf @@ -0,0 +1,3 @@ +name = mcl_blackstone +author = debian044 +depends = mcl_core, screwdriver, mcl_stairs, mclx_stairs, mcl_walls, mclx_fences, mcl_torches, mcl_fire diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts new file mode 100644 index 000000000..7ec39bacf Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_1.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts new file mode 100644 index 000000000..bafc88993 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_2.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts new file mode 100644 index 000000000..39809dda9 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_3.mts differ diff --git a/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts new file mode 100644 index 000000000..2acfefe70 Binary files /dev/null and b/mods/ITEMS/mcl_blackstone/schematics/mcl_blackstone_nether_fossil_4.mts differ diff --git a/mods/ITEMS/mcl_blast_furnace/README.md b/mods/ITEMS/mcl_blast_furnace/README.md new file mode 100644 index 000000000..e96c21942 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/README.md @@ -0,0 +1,13 @@ +Blast Furnaces for MineClone 2. +Heavily based on Minetest Game (default/furnace.lua) and the MineClone 2 Furnaces. + +License of source code +---------------------- +LGPLv2.1 +Based on code from Minetest Game. +Modified by Wuzzy. +MCl 2 Furances modified by PrairieWind. + +License of media +---------------- +See the main MineClone 2 README.md file. diff --git a/mods/ITEMS/mcl_blast_furnace/init.lua b/mods/ITEMS/mcl_blast_furnace/init.lua new file mode 100644 index 000000000..e8e6e81c8 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/init.lua @@ -0,0 +1,573 @@ + +local S = minetest.get_translator(minetest.get_current_modname()) + +local LIGHT_ACTIVE_FURNACE = 13 + +-- +-- 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("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]" +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]".. + -- 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]" + +local receive_fields = function(pos, formname, fields, sender) + if fields.craftguide then + mcl_craftguide.show(sender:get_player_name()) + end +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 xp = meta:get_int("xp") + if xp > 0 then + if player then + mcl_experience.add_xp(player, xp) + else + mcl_experience.throw_xp(vector.add(pos, dir), xp) + end + meta:set_int("xp", 0) + end +end + +-- +-- Node callback functions that are the same for active and inactive furnace +-- + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + end + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if listname == "fuel" then + -- 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}}) + if output.time ~= 0 then + -- Only allow to place 1 item if fuel get replaced by recipe. + -- This is the case for lava buckets. + local replace_item = decremented_input.items[1] + if replace_item:is_empty() then + -- For most fuels, just allow to place everything + return stack:get_count() + else + if inv:get_stack(listname, index):get_count() == 0 then + return 1 + else + return 0 + end + end + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + end + return stack:get_count() +end + +local function on_metadata_inventory_take(pos, listname, index, stack, player) + -- Award smelting achievements + if listname == "dst" then + if stack:get_name() == "mcl_core:iron_ingot" then + awards.unlock(player:get_player_name(), "mcl:acquireIron") + end + give_xp(pos, player) + end +end + +local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "dst" then + give_xp(pos, player) + end +end + +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 } + 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 } + 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 } + 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 } + else + return + end + mcl_particles.add_node_particlespawner(pos, { + amount = 4, + 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 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.4, + maxsize = 0.8, + texture = "mcl_particles_flame.png", + glow = LIGHT_ACTIVE_FURNACE, + }, "low") +end + +local function swap_node(pos, name) + local node = minetest.get_node(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) + if name == "mcl_blast_furnace:blast_furnace_active" then + spawn_flames(pos, node.param2) + else + mcl_particles.delete_node_particlespawners(pos) + end +end + +local function blast_furnace_reset_delta_time(pos) + local meta = minetest.get_meta(pos) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) + if (time_speed < 0.1) then + return + end + local time_multiplier = 86400 / time_speed + local current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier) + + -- TODO: Change meta:get/set_string() to get/set_float() for "last_gametime". + -- In Windows *_float() works OK but under Linux it returns rounded unusable values like 449540.000000000 + local last_game_time = meta:get_string("last_gametime") + if last_game_time then + last_game_time = tonumber(last_game_time) + end + if not last_game_time or last_game_time < 1 or math.abs(last_game_time - current_game_time) <= 1.5 then + return + end + + meta:set_string("last_gametime", tostring(current_game_time)) +end + +local function blast_furnace_get_delta_time(pos, elapsed) + local meta = minetest.get_meta(pos) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) + local current_game_time + if (time_speed < 0.1) then + return meta, elapsed + else + local time_multiplier = 86400 / time_speed + current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier) + end + + local last_game_time = meta:get_string("last_gametime") + if last_game_time then + last_game_time = tonumber(last_game_time) + end + if not last_game_time or last_game_time < 1 then + last_game_time = current_game_time - 0.1 + elseif last_game_time == current_game_time then + current_game_time = current_game_time + 1.0 + end + + local elapsed_game_time = .0 + current_game_time - last_game_time + + meta:set_string("last_gametime", tostring(current_game_time)) + + return meta, elapsed_game_time +end + +local function blast_furnace_node_timer(pos, elapsed) + -- + -- Inizialize metadata + -- + local meta, elapsed_game_time = blast_furnace_get_delta_time(pos, elapsed) + + local fuel_time = meta:get_float("fuel_time") or 0 + local src_time = meta:get_float("src_time") or 0 + local src_item = meta:get_string("src_item") or "" + local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 + + local inv = meta:get_inventory() + local srclist, fuellist + + local cookable, cooked + local active = true + local fuel + + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") + + -- Check if src item has been changed + if srclist[1]:get_name() ~= src_item then + -- Reset cooking progress in this case + src_time = 0 + src_item = srclist[1]:get_name() + end + + local update = true + while elapsed_game_time > 0.00001 and update do + -- + -- Cooking + -- + + -- Run the blast_furnace at twice the speed of a furnace. + local el = elapsed_game_time * 2 + + -- Check if we have cookable content: cookable + local aftercooked + 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 + if not inv:room_for_item("dst", cooked.item) then + cookable = false + end + end + + if cookable then -- fuel lasts long enough, adjust el to cooking duration + el = math.min(el, cooked.time - src_time) + end + + -- Check if we have enough fuel to burn + active = fuel_time < fuel_totaltime + 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}) + + if fuel.time == 0 then + -- No valid fuel in fuel list -- stop + fuel_totaltime = 0 + src_time = 0 + update = false + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + fuel_time = 0 + fuel_totaltime = fuel.time + el = math.min(el, fuel_totaltime) + active = true + fuellist = inv:get_list("fuel") + end + elseif active then + el = math.min(el, fuel_totaltime - fuel_time) + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + el + end + + -- If there is a cookable item then check if it is ready yet + if cookable and active then + src_time = src_time + el + -- Place result in dst list if done + if src_time >= cooked.time then + inv:add_item("dst", cooked.item) + inv:set_stack("src", 1, aftercooked.items[1]) + 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 + end + end + + elapsed_game_time = elapsed_game_time - el + end + + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist and srclist[1]:is_empty() then + src_time = 0 + end + + -- + -- Update formspec and node + -- + local formspec = inactive_formspec + local item_percent = 0 + if cookable then + item_percent = math.floor(src_time / cooked.time * 100) + end + + local result = false + + if active then + local fuel_percent = 0 + if fuel_totaltime > 0 then + fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) + end + formspec = active_formspec(fuel_percent, item_percent) + swap_node(pos, "mcl_blast_furnace:blast_furnace_active") + -- make sure timer restarts automatically + result = true + else + swap_node(pos, "mcl_blast_furnace:blast_furnace") + -- stop timer on the inactive furnace + minetest.get_node_timer(pos):stop() + end + + -- + -- Set meta values + -- + meta:set_float("fuel_totaltime", fuel_totaltime) + meta:set_float("fuel_time", fuel_time) + meta:set_float("src_time", src_time) + if srclist then + meta:set_string("src_item", src_item) + else + meta:set_string("src_item", "") + end + meta:set_string("formspec", formspec) + + return result +end + +local on_rotate, after_rotate_active +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.rotate_simple + after_rotate_active = function(pos) + local node = minetest.get_node(pos) + mcl_particles.delete_node_particlespawners(pos) + if node.name == "mcl_blast_furnace:blast_furnace" then + return + end + spawn_flames(pos, node.param2) + end +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_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."), + _doc_items_hidden = false, + tiles = { + "blast_furnace_top.png", "blast_furnace_top.png", + "blast_furnace_side.png", "blast_furnace_side.png", + "blast_furnace_side.png", "blast_furnace_front.png" + }, + paramtype2 = "facedir", + groups = {pickaxey=1, container=4, deco_block=1, material_stone=1}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + + on_timer = blast_furnace_node_timer, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() + meta:from_table(oldmetadata) + local inv = meta:get_inventory() + 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) + end + end + meta:from_table(meta2) + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", inactive_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("fuel", 1) + inv:set_size("dst", 1) + end, + on_destruct = function(pos) + mcl_particles.delete_node_particlespawners(pos) + give_xp(pos) + end, + + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + -- Reset accumulated game time when player works with furnace: + blast_furnace_reset_delta_time(pos) + minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + end, + on_metadata_inventory_put = function(pos) + -- Reset accumulated game time when player works with furnace: + blast_furnace_reset_delta_time(pos) + -- start timer function, it will sort out whether furnace can burn or not. + minetest.get_node_timer(pos):start(1.0) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + -- Reset accumulated game time when player works with furnace: + blast_furnace_reset_delta_time(pos) + -- start timer function, it will helpful if player clears dst slot + minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_take(pos, listname, index, stack, player) + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + on_receive_fields = receive_fields, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + on_rotate = on_rotate, +}) + +minetest.register_node("mcl_blast_furnace:blast_furnace_active", { + description = S("Burning Blast Furnace"), + _doc_items_create_entry = false, + 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}}, + }, + 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}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_timer = blast_furnace_node_timer, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta + meta:from_table(oldmetadata) + local inv = meta:get_inventory() + 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) + end + end + meta:from_table(meta2:to_table()) + end, + + on_construct = function(pos) + local node = minetest.get_node(pos) + spawn_flames(pos, node.param2) + end, + on_destruct = function(pos) + mcl_particles.delete_node_particlespawners(pos) + give_xp(pos) + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + on_metadata_inventory_move = on_metadata_inventory_move, + on_metadata_inventory_take = on_metadata_inventory_take, + on_receive_fields = receive_fields, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + on_rotate = on_rotate, + after_rotate = after_rotate_active, +}) + +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:stone_smooth", "mcl_core:stone_smooth", "mcl_core:stone_smooth" }, + } +}) + +-- Add entry alias for the Help +if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_blast_furnace:blast_furnace", "nodes", "mcl_blast_furnace:blast_furnace_active") +end + +minetest.register_lbm({ + label = "Active blast_furnace flame particles", + name = "mcl_blast_furnace:flames", + 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.dk.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.dk.tr new file mode 100644 index 000000000..82e74c0fe --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.dk.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory=Indhold +Blast Furnace=Højovn +Smelts ores faster than furnace=Smelter malm hurtere end en normal ovn. +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Brug opskriftsbogen for at se hvad du kan smelte, hvad du kan bruge som brændsel og hvor længe det brænder. +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Brug ovnen for at åbne ovnmenuen. \nPut ovnbrændsel i den nederste plads og det som skal smeltes i den øverste plads.\nOvnen vil langsom bruge dens brændsel til at smelte genstanden.\nResultatet vil blive puttet i pladsen på højre side. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=Højovne kan, ved brug af brændsel, smelte flere genstande, hovedsageligt malm og rustning, og lave dem til noget andet. +Active Blast Furnace=Aktiv højovn \ No newline at end of file diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.es.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.es.tr new file mode 100644 index 000000000..bdae19760 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.es.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_blast_furnace +Inventory=Inventario +Blast Furnace=Alto horno +Smelts ores faster than furnace=Funde menas más rápido que el horno +Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn.=Use el libro de recetas para ver que menas puede fundir, qué puede usar como combustible y durante cuánto tiempo arderá. +Use the blast furnace to open the furnace menu.=Use el alto horno para abrir el menú del horno. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Coloque un combustible de horno en la ranura inferior y el material de origen en la ranura superior. +The blast furnace will slowly use its fuel to smelt the item.=El alto horno usará lentamente su combustible para fundir el artículo. +The result will be placed into the output slot at the right side.=El resultado se colocará en la ranura de salida en el lado derecho. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace.=Los altos hornos funden varios artículos, principalmente menas y armadura, usando combustible de horno, pero el doble de rápido que un horno normal. +Active Blast Furnace=Alto horno activo diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr new file mode 100644 index 000000000..a6c6a8de3 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.fr.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_blast_furnace +Inventory=Inventaire +Blast Furnace=Haut fourneau +Smelts ores faster than furnace=Fond le minerai plus vite que le four +Use the recipe book to see what ores you can smelt, what you can use as fuel and how long it will burn.=Utiliser le livre de recettes pour voir quels minerais vous pouvez fondre, ce que vous pouvez utiliser comme combustible et combien de temps ça va brûler. +Use the blast furnace to open the furnace menu.=Utiliser le haut fourneau pour ouvrir le menu. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Placer le combustible dans la case en bas et le matériau source dans la case du haut. +The blast furnace will slowly use its fuel to smelt the item.=Le haut fourneau utilisera son combustible pour fondre lentement l'objet. +The result will be placed into the output slot at the right side.=Le résultat sera placé dans la case de sortie à droite. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, but twice as fast as a normal furnace.=Les hauts fourneaux fondent plusieurs objets, principalement du minerai et des pièces d'armure, mais deux fois plus vite qu'un fourneau normal. +Active Blast Furnace=Haut fourneau actif diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr new file mode 100644 index 000000000..2ac902b2d --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory=インベントリ +Blast Furnace=溶鉱炉 +Smelts ores faster than furnace=かまどより早く製錬 +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=レシピ本で、何を製錬するか、何を燃料にするか、どのくらい燃えるかを確認します。 +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=炉を使用して溶鉱炉メニューを開きます。\n下側のスロットに炉の燃料を、上側のスロットに原料をセットします。\n炉はゆっくりと燃料を使い、アイテムを製錬します。\n右側の出力スロットに製錬結果が置かれます。 +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=溶鉱炉は燃料を使用して、いくつかのアイテム(主に鉱石や防具など)を製錬し、別のものに変えます。 +Active Blast Furnace=溶鉱炉 稼動中 \ No newline at end of file diff --git a/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.pt_BR.tr b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.pt_BR.tr new file mode 100644 index 000000000..93d1c87e4 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/mcl_blast_furnace.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_blast_furnace +Inventory=Inventário +Blast Furnace=Alto-Forno +Smelts ores faster than furnace=Funde minérios mais rápido do que a fornalha +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Utilize o livro de receitas para ver o que você pode fundir, o que você pode usar de combustível e o quanto irá queimar. +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Utilize o alto-forno para abrir o menu. \nColoque o combustível no espaço inferior e a matéria-prima no espaço superior. \nO resultado será colocado no espaço de saída, ao lado direito. +Blast Furnaces smelt several items, mainly ores and armor, using a furnace fuel, into something else.=Alto-Forno derrete diversos itens, principalmente minérios e armaduras, utilizando um combustível, em algo diferente. +Active Blast Furnace=Alto-Forno Ativo diff --git a/mods/ITEMS/mcl_blast_furnace/locale/template.txt b/mods/ITEMS/mcl_blast_furnace/locale/template.txt new file mode 100644 index 000000000..46841046d --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/locale/template.txt @@ -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/mod.conf b/mods/ITEMS/mcl_blast_furnace/mod.conf new file mode 100644 index 000000000..e330e80e4 --- /dev/null +++ b/mods/ITEMS/mcl_blast_furnace/mod.conf @@ -0,0 +1,3 @@ +name = mcl_blast_furnace +depends = mcl_init, mcl_formspec, mcl_core, mcl_furnaces, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_books/depends.txt b/mods/ITEMS/mcl_books/depends.txt deleted file mode 100644 index e1ecc48c7..000000000 --- a/mods/ITEMS/mcl_books/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_init? -mcl_core? -mcl_sounds? -mcl_mobitems? -mcl_dye? diff --git a/mods/ITEMS/mcl_books/init.lua b/mods/ITEMS/mcl_books/init.lua index 45208c413..af84feb66 100644 --- a/mods/ITEMS/mcl_books/init.lua +++ b/mods/ITEMS/mcl_books/init.lua @@ -1,8 +1,12 @@ -local S =minetest.get_translator("mcl_books") +local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +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 header = "" if minetest.get_modpath("mcl_init") then header = "no_prepend[]" .. mcl_vars.gui_nonbg .. mcl_vars.gui_bg_color .. @@ -21,16 +25,16 @@ minetest.register_craftitem("mcl_books:book", { if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then minetest.register_craft({ - type = 'shapeless', - output = 'mcl_books:book', - recipe = { 'mcl_core:paper', 'mcl_core:paper', 'mcl_core:paper', 'mcl_mobitems:leather', } + type = "shapeless", + output = "mcl_books:book", + recipe = { "mcl_core:paper", "mcl_core:paper", "mcl_core:paper", "mcl_mobitems:leather", } }) end -- Get the included text out of the book item -- itemstack: Book item -- meta: Meta of book (optional) -local get_text = function(itemstack) +local function get_text(itemstack) -- Grab the text local meta = itemstack:get_meta() local text = meta:get_string("text") @@ -56,7 +60,7 @@ local get_text = function(itemstack) return text end -local make_description = function(title, author, generation) +local function make_description(title, author, generation) local desc if generation == 0 then desc = S("“@1”", title) @@ -67,15 +71,15 @@ local make_description = function(title, author, generation) else desc = S("Tattered Book") end - desc = desc .. "\n" .. minetest.colorize("#AAAAAA", S("by @1", author)) + desc = desc .. "\n" .. minetest.colorize(mcl_colors.GRAY, S("by @1", author)) return desc end -local cap_text_length = function(text, max_length) +local function cap_text_length(text, max_length) return string.sub(text, 1, max_length) end -local write = function(itemstack, user, pointed_thing) +local function write(itemstack, user, pointed_thing) -- Call on_rightclick if the pointed node defines it if pointed_thing.type == "node" then local node = minetest.get_node(pointed_thing.under) @@ -96,7 +100,7 @@ local write = function(itemstack, user, pointed_thing) minetest.show_formspec(user:get_player_name(), "mcl_books:writable_book", formspec) end -local read = function(itemstack, user, pointed_thing) +local function read(itemstack, user, pointed_thing) -- Call on_rightclick if the pointed node defines it if pointed_thing.type == "node" then local node = minetest.get_node(pointed_thing.under) @@ -238,11 +242,9 @@ minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craf end local original - local index for i = 1, player:get_inventory():get_size("craft") do if old_craft_grid[i]:get_name() == "mcl_books:written_book" then original = old_craft_grid[i] - index = i end end if not original then @@ -333,6 +335,76 @@ if minetest.get_modpath("mcl_sounds") then wood_sound = mcl_sounds.node_sound_wood_defaults() end +-- Bookshelf GUI +local drop_content = mcl_util.drop_items_from_meta_container("main") + +local function on_blast(pos) + local node = minetest.get_node(pos) + drop_content(pos, node) + minetest.remove_node(pos) +end + +-- Simple protection checking functions +local function protection_check_move(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + 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 + minetest.record_protection_violation(pos, name) + return 0 + elseif minetest.get_item_group(stack:get_name(), "book") ~= 0 or stack:get_name() == "mcl_enchanting:book_enchanted" then + return stack:get_count() + else + return 0 + end +end + +local function bookshelf_gui(pos, node, clicker) + if not bookshelf_inv then return end + local name = minetest.get_meta(pos):get_string("name") + + if name == "" then + name = S("Bookshelf") + end + + local playername = clicker:get_player_name() + + minetest.show_formspec(playername, + "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]", + "listring[current_player;main]", + }) + ) +end + +local function close_forms(pos) + local players = minetest.get_connected_players() + 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) + end + end +end + -- Bookshelf minetest.register_node("mcl_books:bookshelf", { description = S("Bookshelf"), @@ -340,20 +412,50 @@ minetest.register_node("mcl_books:bookshelf", { 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, flammable=3,building_block=1, material_wood=1, fire_encouragement=30, fire_flammability=20}, + groups = { + handy=1, axey=1, deco_block=1, material_wood=1, + flammable=3, fire_encouragement=30, fire_flammability=20, container=1 + }, drop = "mcl_books:book 3", sounds = wood_sound, _mcl_blast_resistance = 1.5, _mcl_hardness = 1.5, _mcl_silk_touch_drop = true, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + 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")) + end, + 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 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)) + 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)) + end, + after_dig_node = drop_content, + on_blast = on_blast, + on_rightclick = bookshelf_gui, + on_destruct = close_forms, }) minetest.register_craft({ - output = 'mcl_books:bookshelf', + 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"}, } }) diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.dk.tr b/mods/ITEMS/mcl_books/locale/mcl_books.dk.tr new file mode 100644 index 000000000..cdf19e542 --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.dk.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_books +Book=Bog +Books are used to make bookshelves and book and quills.=Bøger bruges til at lave bogreoler og bog og fjerpen +“@1”="@1" +Copy of “@1”=Kopi af "@1" +Copy of Copy of “@1”=Kopi af kopi af "@1" +Tattered Book=Flosset bog +by @1=af @1 +# as in “to sign a book” +Sign=Underskriv +Done=Færdig +This item can be used to write down some notes.=Denne genstand kan bruges til at skrive notater. +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 den i hånden, højre-klik så for at læse og redigere aktuelle notater. Du kan redigere teksten så ofte du har lyst. Du kan også signere bogen hvilken gør den til en skrevet bog som du kan gemme, men som ikke kan redigeres mere. +A book can hold up to 4500 characters. The title length is limited to 64 characters.=En bog kan indeholde op til 4500 anslag. Titellængden er begrænset til 64 anslag. +Enter book title:=Indtast bogens titel: +by @1=af @1 +Note: The book will no longer be editable after signing=Bemærk: Bogen vil ikke længere kunne redigeres efter signering. +Sign and Close=Signér og luk +Cancel=Afbryd +Nameless Book=Unavngiven bog +Written Book=Skrevet bog +Written books contain some text written by someone. They can be read and copied, but not edited.=Skrevne bøger indeholder tekst som nogen har skrevet. De kan læses og kopieres, men ikke redigeres. +Hold it in your hand, then rightclick to read the book.=Hold den i hånden og højre-klik for at læse bogen. +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.=For at kopiere teksten i den skrevne bog skal du placere den i arbejdsgitteret sammen med en (eller flere) bog og fjerdpen og udfør. Den skrevne bog bliver ikke opbrugt. Kopier kan ikke kopieres. +Bookshelf=Bogreol +Bookshelves are used for decoration.=Bogreoler bruges til udsmykning. +Book and Quill=Bog og fjerdpen +Write down some notes=Skriv nogle notater diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.es.tr b/mods/ITEMS/mcl_books/locale/mcl_books.es.tr index d1e0d947a..880ecc16a 100644 --- a/mods/ITEMS/mcl_books/locale/mcl_books.es.tr +++ b/mods/ITEMS/mcl_books/locale/mcl_books.es.tr @@ -3,15 +3,17 @@ Book=Libro Books are used to make bookshelves and book and quills.=Los libros se usan para hacer estanterías, libros y plumas. “@1”="@1“ Copy of “@1”=Copia de "@1“ -Copy of Copy of “@1”=Kopie von Kopie von „@1“ +Copy of Copy of “@1”=Copia de la copia de "@1" Tatter ed Book=Libro andrajoso by @1=por @1 +# as in “to sign a book” Sign=Firmar Done=Hecho This item can be used to write down some notes.=Este elemento se puede usar para escribir algunas notas. 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.=Sosténgalo en la mano, luego haga clic derecho para leer las notas actuales y luego edite. Puede editar el texto con la frecuencia que desee. También puede firmar el libro que lo convierte en un libro escrito que puede apilar, pero ya no se puede editar. A book can hold up to 4500 characters. The title length is limited to 64 characters.=Un libro puede contener hasta 4500 caracteres. La longitud del título está limitada a 64 caracteres. Enter book title:=Inserta el título del libro: +by @1=por @1 Note: The book will no longer be editable after signing=Nota: El libro ya no será editable después de firmarlo Sign and Close=Firmar y cerrar libro Cancel=Cancelar @@ -23,3 +25,4 @@ To copy the text of the written book, place it into the crafting grid together w Bookshelf=Librería Bookshelves are used for decoration.=Las librerías se utilizan para la decoración. Book and Quill=Libro y pluma +Write down some notes=Escribe algunas notas diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr b/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr index 7024cf5d0..40f564270 100644 --- a/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr +++ b/mods/ITEMS/mcl_books/locale/mcl_books.fr.tr @@ -1,6 +1,6 @@ # textdomain: mcl_books Book=Livre -Books are used to make bookshelves and book and quills.=Les livres sont utilisés pour fabriquer des étagères et des livres et des plumes. +Books are used to make bookshelves and book and quills.=Les livres sont utilisés pour fabriquer des étagères et des livres avec des plumes. “@1”="@1" Copy of “@1”=Copie de "@1" Copy of Copy of “@1”=Copie de Copie de "@1" @@ -9,20 +9,20 @@ by @1=ar @1 # as in “to sign a book” Sign=Signer Done=Terminé -This item can be used to write down some notes.=Cet élément peut être utilisé pour écrire certaines 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.=Tenez-le dans la main, puis faites un clic droit pour lire les notes actuelles et modifiez-les ensuite. Vous pouvez modifier le texte aussi souvent que vous le souhaitez. Vous pouvez également signer le livre qui le transforme en livre écrit que vous pouvez empiler, mais il ne peut plus être édité. +This item can be used to write down some notes.=Cet élément peut être utilisé pour prendre quelques 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.=Tenez-le dans la main, puis faites un clic droit pour lire les notes actuelles et modifiez-les ensuite. Vous pouvez modifier le texte aussi souvent que vous le souhaitez. Vous pouvez également signer le livre ce qui le transforme en livre écrit que vous pouvez empiler, mais il ne peut plus être édité. A book can hold up to 4500 characters. The title length is limited to 64 characters.=Un livre peut contenir jusqu'à 4500 caractères. La longueur du titre est limitée à 64 caractères. -Enter book title:=Entrez le titre du livre: +Enter book title:=Entrez le titre du livre : by @1=par @1 -Note: The book will no longer be editable after signing=Remarque: le livre ne sera plus modifiable après la signature +Note: The book will no longer be editable after signing=Remarque : le livre ne sera plus modifiable après la signature Sign and Close=Signez et fermez Cancel=Annuler Nameless Book=Livre sans nom Written Book=Livre écrit Written books contain some text written by someone. They can be read and copied, but not edited.=Les livres écrits contiennent du texte écrit par quelqu'un. Ils peuvent être lus et copiés, mais pas modifiés. Hold it in your hand, then rightclick to read the book.=Tenez-le dans votre main, puis faites un clic droit pour lire le livre. -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.=Pour copier le texte du livre écrit, placez-le dans la grille d'artisanat avec un livre et une plume (ou plusieurs de ceux-ci) et de l'artisanat. Le livre écrit ne sera pas consommé. Les copies de copies ne peuvent pas être copiées. +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.=Pour copier le texte du livre écrit, placez-le dans la grille d'artisanat avec un livre et une plume (ou plusieurs) et récupérez le résultat. Le livre copié ne sera pas consommé. Les copies de copies ne peuvent pas être copiées. Bookshelf=Bibliothèque Bookshelves are used for decoration.=Les bibliothèques sont utilisées pour la décoration. -Book and Quill=Livre et Plume -Write down some notes=Notez quelques notes +Book and Quill=Livre et plume +Write down some notes=Prenez quelques notes diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr b/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr new file mode 100644 index 000000000..8f3755c42 --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.ja.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_books +Book=本 +Books are used to make bookshelves and book and quills.=本は、本棚や本と羽根ペンの材料として使われています。 +“@1”=“@1” +Copy of “@1”=“@1”のコピー +Copy of Copy of “@1”=“@1”のコピーのコピー +Tattered Book=ボロボロの本 +by @1=@1 著 +# as in “to sign a book” +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.=手に持って右クリックすると、現在のメモを読み込んでから編集できます。編集は何度でも可能です。また、署名をすることで記入済みの本となり、スタックが可能になりますが、編集はできなくなります。 +A book can hold up to 4500 characters. The title length is limited to 64 characters.=1冊に4500文字まで収録可能です。タイトルの長さは64文字までです。 +Enter book title:=本の題名を入力: +by @1=@1 著 +Note: The book will no longer be editable after signing=注:署名後の本は編集不能 +Sign and Close=署名して閉じる +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.=記入済みの本のテキストをコピーするには、本と羽根ペン(またはそれらの複数)と一緒にクラフトグリッドに置き、クラフトします。記入済みの本は消費されません。「コピーのコピー」をコピーすることはできません。 +Bookshelf=本棚 +Bookshelves are used for decoration.=本棚は飾りとして使用します。 +Book and Quill=本と羽根ペン +Write down some notes=メモを書く diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.pl.tr b/mods/ITEMS/mcl_books/locale/mcl_books.pl.tr new file mode 100644 index 000000000..8ef0db873 --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.pl.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_books +Book=Książka +Books are used to make bookshelves and book and quills.=Książki są używane do tworzenia półek z książkami oraz książek z piórem. +“@1”=„@1” +Copy of “@1”=Kopia „@” +Copy of Copy of “@1”=Kopia kopii „@” +Tattered Book=Podarta książka +by @1=autorstwa @1 +# as in “to sign a book” +Sign=Podpisz +Done=Skończone +This item can be used to write down some notes.=Ten przedmiot może być wykorzystany do zapisania notatek +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.=Weź ją do ręki, następnie kliknij prawym przyciskiem by przeczytać notatki i je edytować. Możesz edytować tekst tak często jak tylko chcesz. Możesz także podpisać książkę, co zamienia ją w zapisaną książkę, którą można grupować, ale nie można jej edytować. +A book can hold up to 4500 characters. The title length is limited to 64 characters.=W książce zmieści się maksymalnie 4500 znaków. Długość tytułu jest ograniczona do 64 znaków. +Enter book title:=Wprowadź tytuł książki: +by @1=autorstwa @1 +Note: The book will no longer be editable after signing=Uwaga: Książki nie da się edytować po podpisaniu +Sign and Close=Podpisz i zamknij +Cancel=Anuluj +Nameless Book=Nienazwana książka +Written Book=Zapisana książka +Written books contain some text written by someone. They can be read and copied, but not edited.=Zapisane książki przechowują tekst napisany przez kogoś. Mogą być czytane i kopiowane, ale nie edytowane. +Hold it in your hand, then rightclick to read the book.=Weź ją do ręki i kliknij prawym, aby przeczytać książkę. +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.=Aby skopiować tekst z zapisanej książki umieść ją w siatce wytwarzania z książką z piórem (lub kilkoma) i wytwarzaj. Zapisana książka nie zostanie wykorzystana. Kopie kopii nie mogą być kopiowane. +Bookshelf=Półka z książkami +Bookshelves are used for decoration.=Półki z książkami są używane jako dekoracje +Book and Quill=Książka z piórem +Write down some notes=Zapisz jakieś notatki diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr b/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr new file mode 100644 index 000000000..fbbb543fd --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.pt_BR.tr @@ -0,0 +1,28 @@ +# textdomain: mcl_books +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 Copy of “@1”=Cópia da Cópia de "@1" +Tattered Book=Livro Esfarrapado +by @1=por @1 +# as in “to sign a book” +Sign=Assinar +Done=Finalizar +This item can be used to write down some notes.=Este item pode ser utilizado para escrever algumas anotações. +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.=Segure na mão e aperte o botão direito para ler e editar as anotações. Você pode editar o texto o quanto quiser. Você pode assinar o livro, o que o torna em um livro escrito em que você pode empilhar, mas não poderá ser editado mais. +A book can hold up to 4500 characters. The title length is limited to 64 characters.=Um livro pode conter até 4500 caracteres. O tamanho do título é limitado a 64 caracteres. +Enter book title:=Entre com o título do livro: +by @1=por @1 +Note: The book will no longer be editable after signing=Nota: o livro não será mais editável após assinar +Sign and Close=Assinar e Fechar +Cancel=Cancelar +Nameless Book=Livro sem título +Written Book=Livro Escrito +Written books contain some text written by someone. They can be read and copied, but not edited.=Livros escritos contém textos escritos por alguém. Eles podem ser lidos e copiados, mas não editados. +Hold it in your hand, then rightclick to read the book.=Segure em sua mão e aperte o botão direito para ler o livro. +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.=Para copiar o texto de um livro escrito, coloque-o na mesa de trabalho junto de um livro e pena (ou vários deste) e copie. O livro escrito não será consumido. Copias de copias não poderão ser copiadas. +Bookshelf=Estante de Livros +Bookshelves are used for decoration.=Estante de livros são utilizadas para decoração. +Book and Quill=Livro e Pena +Write down some notes=Escreve algumas anotações diff --git a/mods/ITEMS/mcl_books/locale/mcl_books.zh_TW.tr b/mods/ITEMS/mcl_books/locale/mcl_books.zh_TW.tr new file mode 100644 index 000000000..eb3ab51a7 --- /dev/null +++ b/mods/ITEMS/mcl_books/locale/mcl_books.zh_TW.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_books +Book=書 +Books are used to make bookshelves and book and quills.=書籍用於製作書櫃以及書和羽毛筆。 +“@1”=「@1」 +Copy of “@1”=「@1」的複本 +Copy of Copy of “@1”=「@1」的複本的複本 +Tattered Book=破舊的書 +by @1=由 @1 篇寫 +# as in “to sign a book” +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.=把它拿在手裡,然後右鍵閱讀當前的筆記,然後進行編輯。你可以隨心所欲地編輯文字。你也可以在書上署名名,這就把它變成了一本完成的書,你可以把它疊起來,但它不能再被編輯了。 +A book can hold up to 4500 characters. The title length is limited to 64 characters.=一本書最多可以容納4500個字符。標題長度限制為64個字符。 +Enter book title:=輸入書本標題: +Note: The book will no longer be editable after signing=注意:在署名後,它不能再被編輯了。 +Sign and Close=署名並退出 +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.=要復製完成的書的文本,請將其與書和羽毛筆(或多個)一起放入製作網格,然後製作。完成的書不會被消耗掉。複本的複本不能被複製。 +Bookshelf=書櫃 +Bookshelves are used for decoration.=書櫃是一種裝飾行方塊 +Book and Quill=書和羽毛筆 +Write down some notes=寫下一些筆記 diff --git a/mods/ITEMS/mcl_books/mod.conf b/mods/ITEMS/mcl_books/mod.conf index 9597005c1..cfa1f7622 100644 --- a/mods/ITEMS/mcl_books/mod.conf +++ b/mods/ITEMS/mcl_books/mod.conf @@ -1 +1,5 @@ name = mcl_books +author = celeron55 +description = Books mod for MCL2 +depends = mcl_util, mcl_formspec +optional_depends = mcl_init, mcl_core, mcl_sounds, mcl_mobitems, mcl_dye, mcl_colors diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index ff6875770..2181d7b98 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -1,20 +1,40 @@ -local S = minetest.get_translator("mcl_bows") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_target = minetest.get_modpath("mcl_target") +local enable_pvp = minetest.settings:get_bool("enable_pvp") + +local math = math +local vector = vector -- Time in seconds after which a stuck arrow is deleted local ARROW_TIMEOUT = 60 -- Time after which stuck arrow is rechecked for being stuck local STUCK_RECHECK_TIME = 5 -local GRAVITY = 9.81 +--local GRAVITY = 9.81 local YAW_OFFSET = -math.pi/2 -local dir_to_pitch = function(dir) - local dir2 = vector.normalize(dir) +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) local xz = math.abs(dir.x) + math.abs(dir.z) return -math.atan2(-dir.y, xz) end +local function random_arrow_positions(positions, placement) + if positions == "x" then + return math.random(-4, 4) + elseif positions == "y" then + return math.random(0, 10) + end + if placement == "front" and positions == "z" then + return 3 + elseif placement == "back" and positions == "z" then + return -3 + end + return 0 +end + local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") @@ -26,7 +46,7 @@ S("An arrow fired from a bow has a regular damage of 1-9. At full charge, there' S("Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons."), _doc_items_usagehelp = S("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."), inventory_image = "mcl_bows_arrow_inv.png", - groups = { ammo=1, ammo_bow=1, ammo_bow_regular=1 }, + groups = { ammo=1, ammo_bow=1, ammo_bow_regular=1, ammo_crossbow=1 }, _on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir) -- Shoot arrow local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) @@ -35,52 +55,13 @@ S("Arrows might get stuck on solid blocks and can be retrieved again. They are a end, }) --- This is a fake node, used as model for the arrow entity. --- It's not supposed to be usable as item or real node. --- TODO: Use a proper mesh for the arrow entity -minetest.register_node("mcl_bows:arrow_box", { - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - -- Shaft - {-6.5/17, -1.5/17, -1.5/17, -4.5/17, 1.5/17, 1.5/17}, - {-4.5/17, -0.5/17, -0.5/17, 5.5/17, 0.5/17, 0.5/17}, - {5.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, - -- Tip - {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, - {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, - -- Fletching - {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, - {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, - {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, - {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, - - {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, - {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, - {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, - {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, - } - }, - tiles = {"mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow_back.png", "mcl_bows_arrow_front.png", "mcl_bows_arrow.png", "mcl_bows_arrow.png^[transformFX"}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = {not_in_creative_inventory=1, dig_immediate=3}, - drop = "", - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mcl_bows] Trying to construct mcl_bows:arrow_box at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, -}) - local ARROW_ENTITY={ physical = true, - visual = "wielditem", - visual_size = {x=0.4, y=0.4}, - textures = {"mcl_bows:arrow_box"}, + pointable = false, + visual = "mesh", + mesh = "mcl_bows_arrow.obj", + visual_size = {x=-1, y=1}, + textures = {"mcl_bows_arrow.png"}, collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, collide_with_objects = false, _fire_damage_resistant = true, @@ -94,33 +75,33 @@ local ARROW_ENTITY={ _stuckrechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow _stuckin=nil, --Position of node in which arow is stuck. _shooter=nil, -- ObjectRef of player or mob who shot it - + _is_arrow = true, + _in_player = false, + _blocked = false, _viscosity=0, -- Viscosity of node the arrow is currently in _deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession } -- Destroy arrow entity self at pos and drops it as an item -local spawn_item = function(self, pos) +local function spawn_item(self, pos) if not minetest.is_creative_enabled("") then local item = minetest.add_item(pos, "mcl_bows:arrow") - item:set_velocity({x=0, y=0, z=0}) + item:set_velocity(vector.new(0, 0, 0)) item:set_yaw(self.object:get_yaw()) end mcl_burning.extinguish(self.object) self.object:remove() end -local damage_particles = function(pos, is_critical) +local function damage_particles(pos, is_critical) if is_critical then minetest.add_particlespawner({ amount = 15, time = 0.1, - minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, - maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, - minvel = {x=-0.1, y=-0.1, z=-0.1}, - maxvel = {x=0.1, y=0.1, z=0.1}, - minacc = {x=0, y=0, z=0}, - maxacc = {x=0, y=0, z=0}, + minpos = vector.offset(pos, -0.5, -0.5, -0.5), + maxpos = vector.offset(pos, 0.5, 0.5, 0.5), + minvel = vector.new(-0.1, -0.1, -0.1), + maxvel = vector.new(0.1, 0.1, 0.1), minexptime = 1, maxexptime = 2, minsize = 1.5, @@ -132,12 +113,15 @@ local damage_particles = function(pos, is_critical) end end -ARROW_ENTITY.on_step = function(self, dtime) - mcl_burning.tick(self.object, dtime) +function ARROW_ENTITY.on_step(self, dtime) + mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end + + self._time_in_air = self._time_in_air + .001 local pos = self.object:get_pos() - local dpos = table.copy(pos) -- digital pos - dpos = vector.round(dpos) + local dpos = vector.round(vector.new(pos)) -- digital pos local node = minetest.get_node(dpos) if self._stuck then @@ -184,11 +168,27 @@ ARROW_ENTITY.on_step = function(self, dtime) -- Check for object "collision". Done every tick (hopefully this is not too stressing) else - -- We just check for any hurtable objects nearby. - -- The radius of 3 is fairly liberal, but anything lower than than will cause - -- arrow to hilariously go through mobs often. - -- TODO: Implement an ACTUAL collision detection (engine support needed). - local objs = minetest.get_objects_inside_radius(pos, 1.5) + + if self._damage >= 9 and self._in_player == false then + minetest.add_particlespawner({ + amount = 20, + time = .2, + minpos = vector.new(0,0,0), + maxpos = vector.new(0,0,0), + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + attached = self.object, + collisiondetection = false, + vertical = false, + texture = "mobs_mc_arrow_particle.png", + glow = 1, + }) + end + local closest_object local closest_distance @@ -196,36 +196,38 @@ ARROW_ENTITY.on_step = function(self, dtime) self._deflection_cooloff = self._deflection_cooloff - dtime end - -- Iterate through all objects and remember the closest attackable object - for k, obj in pairs(objs) do - local ok = false - -- Arrows can only damage players and mobs - if obj ~= self._shooter and obj:is_player() then - ok = true - elseif obj:get_luaentity() ~= nil then - if obj ~= self._shooter and (obj:get_luaentity()._cmi_is_mob or obj:get_luaentity()._hittable_by_projectile) then + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end end - end - - if ok then - local dist = vector.distance(pos, obj:get_pos()) - if not closest_object or not closest_distance then - closest_object = obj - closest_distance = dist - elseif dist < closest_distance then - closest_object = obj - closest_distance = dist + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end end end end - -- If an attackable object was found, we will damage the closest one only - if closest_object ~= nil then + if closest_object then local obj = closest_object local is_player = obj:is_player() local lua = obj:get_luaentity() - if obj ~= self._shooter and (is_player or (lua and (lua._cmi_is_mob or lua._hittable_by_projectile))) then + if obj == self._shooter and self._time_in_air > 1.02 or obj ~= self._shooter and (is_player or (lua and (lua.is_mob or lua._hittable_by_projectile))) then if obj:get_hp() > 0 then -- Check if there is no solid node between arrow and object local ray = minetest.raycast(self.object:get_pos(), obj:get_pos(), true) @@ -247,22 +249,71 @@ ARROW_ENTITY.on_step = function(self, dtime) -- Punch target object but avoid hurting enderman. if not lua or lua.name ~= "mobs_mc:enderman" then - if obj:is_player() and rawget(_G, "armor") and armor.last_damage_types then - armor.last_damage_types[obj:get_player_name()] = "projectile" + if not self._in_player then + damage_particles(vector.add(pos, vector.multiply(self.object:get_velocity(), 0.1)), self._is_critical) end - damage_particles(self.object:get_pos(), self._is_critical) if mcl_burning.is_burning(self.object) then - mcl_burning.set_on_fire(obj, 4) + mcl_burning.set_on_fire(obj, 5) + end + if not self._in_player and not self._blocked then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, self.object:get_velocity()) + if obj:is_player() then + if not mcl_shields.is_blocking(obj) then + local placement + self._placement = math.random(1, 2) + if self._placement == 1 then + placement = "front" + else + placement = "back" + end + self._in_player = true + if self._placement == 2 then + self._rotation_station = 90 + else + self._rotation_station = -90 + end + self._y_position = random_arrow_positions("y", placement) + self._x_position = random_arrow_positions("x", placement) + if self._y_position > 6 and self._x_position < 2 and self._x_position > -2 then + self._attach_parent = "Head" + self._y_position = self._y_position - 6 + elseif self._x_position > 2 then + self._attach_parent = "Arm_Right" + self._y_position = self._y_position - 3 + self._x_position = self._x_position - 2 + elseif self._x_position < -2 then + self._attach_parent = "Arm_Left" + self._y_position = self._y_position - 3 + self._x_position = self._x_position + 2 + else + self._attach_parent = "Body" + end + self._z_rotation = math.random(-30, 30) + self._y_rotation = math.random( -30, 30) + self.object:set_attach( + obj, self._attach_parent, + vector.new(self._x_position, self._y_position, random_arrow_positions("z", placement)), + vector.new(0, self._rotation_station + self._y_rotation, self._z_rotation) + ) + else + self._blocked = true + self.object:set_velocity(vector.multiply(self.object:get_velocity(), -0.25)) + end + minetest.after(150, function() + self.object:remove() + end) + else + self.object:remove() + end end - obj:punch(self.object, 1.0, { - full_punch_interval=1.0, - damage_groups={fleshy=self._damage}, - }, self.object:get_velocity()) end if is_player then - if self._shooter and self._shooter:is_player() then + if self._shooter and self._shooter:is_player() and not self._in_player and not self._blocked then -- “Ding” sound for hitting another player minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) end @@ -279,10 +330,16 @@ ARROW_ENTITY.on_step = function(self, dtime) end end end - minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + if not self._in_player and not self._blocked then + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + end + end + if not obj:is_player() then + mcl_burning.extinguish(self.object) + if self._piercing == 0 then + self.object:remove() + end end - mcl_burning.extinguish(self.object) - self.object:remove() return end end @@ -299,9 +356,9 @@ ARROW_ENTITY.on_step = function(self, dtime) local dir if math.abs(vel.y) < 0.00001 then if self._lastpos.y < pos.y then - dir = {x=0, y=1, z=0} + dir = vector.new(0, 1, 0) else - dir = {x=0, y=-1, z=0} + dir = vector.new(0, -1, 0) end else dir = minetest.facedir_to_dir(minetest.dir_to_facedir(minetest.yaw_to_dir(self.object:get_yaw()-YAW_OFFSET))) @@ -329,8 +386,8 @@ ARROW_ENTITY.on_step = function(self, dtime) self._stucktimer = 0 self._stuckrechecktimer = 0 - self.object:set_velocity({x=0, y=0, z=0}) - self.object:set_acceleration({x=0, y=0, z=0}) + self.object:set_velocity(vector.new(0, 0, 0)) + self.object:set_acceleration(vector.new(0, 0, 0)) minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) @@ -338,6 +395,11 @@ ARROW_ENTITY.on_step = function(self, dtime) tnt.ignite(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 + end + -- Push the button! Push, push, push the button! if mod_button and minetest.get_item_group(node.name, "button") > 0 and minetest.get_item_group(node.name, "button_push_by_arrow") == 1 then local bdir = minetest.wallmounted_to_dir(node.param2) @@ -353,7 +415,7 @@ ARROW_ENTITY.on_step = function(self, dtime) if not v then v = 0 end - local old_v = self._viscosity + --local old_v = self._viscosity self._viscosity = v local vpenalty = math.max(0.1, 0.98 - 0.1 * v) if math.abs(vel.x) > 0.001 then @@ -375,18 +437,18 @@ ARROW_ENTITY.on_step = function(self, dtime) end -- Update internal variable - self._lastpos={x=pos.x, y=pos.y, z=pos.z} + self._lastpos = pos end -- Force recheck of stuck arrows when punched. -- Otherwise, punching has no effect. -ARROW_ENTITY.on_punch = function(self) +function ARROW_ENTITY.on_punch(self) if self._stuck then self._stuckrechecktimer = STUCK_RECHECK_TIME end end -ARROW_ENTITY.get_staticdata = function(self) +function ARROW_ENTITY.get_staticdata(self) local out = { lastpos = self._lastpos, startpos = self._startpos, @@ -394,6 +456,7 @@ ARROW_ENTITY.get_staticdata = function(self) is_critical = self._is_critical, stuck = self._stuck, stuckin = self._stuckin, + stuckin_player = self._in_player, } if self._stuck then -- If _stucktimer is missing for some reason, assume the maximum @@ -408,7 +471,8 @@ ARROW_ENTITY.get_staticdata = function(self) return minetest.serialize(out) end -ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s) +function ARROW_ENTITY.on_activate(self, staticdata, dtime_s) + self._time_in_air = 1.0 local data = minetest.deserialize(staticdata) if data then self._stuck = data.stuck @@ -441,23 +505,36 @@ ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s) self._shooter = shooter end end + + if data.stuckin_player then + self.object:remove() + end end self.object:set_armor_groups({ immortal = 1 }) end +minetest.register_on_respawnplayer(function(player) + for _, obj in pairs(player:get_children()) do + local ent = obj:get_luaentity() + if ent and ent.name and string.find(ent.name, "mcl_bows:arrow_entity") then + obj:remove() + end + end +end) + minetest.register_entity("mcl_bows:arrow_entity", ARROW_ENTITY) if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then minetest.register_craft({ - output = 'mcl_bows:arrow 4', + output = "mcl_bows:arrow 4", recipe = { - {'mcl_core:flint'}, - {'mcl_core:stick'}, - {'mcl_mobitems:feather'} + {"mcl_core:flint"}, + {"mcl_core:stick"}, + {"mcl_mobitems:feather"} } }) end -if minetest.get_modpath("doc_identifier") ~= nil then +if minetest.get_modpath("doc_identifier") then doc.sub.identifier.register_object("mcl_bows:arrow_entity", "craftitems", "mcl_bows:arrow") end diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 87820071d..23b6b4310 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_bows") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_bows = {} @@ -33,7 +33,7 @@ local bow_load = {} -- Another player table, this one stores the wield index of the bow being charged local bow_index = {} -mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical, bow_stack, collectable) +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 power = BOW_MAX_SPEED --19 @@ -59,13 +59,14 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag obj:set_yaw(yaw-math.pi/2) local le = obj:get_luaentity() le._shooter = shooter + le._source_object = shooter le._damage = damage le._is_critical = is_critical le._startpos = pos le._knockback = knockback le._collectable = collectable minetest.sound_play("mcl_bows_bow_shoot", {pos=pos, max_hear_distance=16}, true) - if shooter ~= nil and shooter:is_player() then + if shooter and shooter:is_player() then if obj:get_luaentity().player == "" then obj:get_luaentity().player = shooter end @@ -74,7 +75,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag return obj end -local get_arrow = function(player) +local function get_arrow(player) local inv = player:get_inventory() local arrow_stack, arrow_stack_id for i=1, inv:get_size("main") do @@ -88,7 +89,7 @@ local get_arrow = function(player) return arrow_stack, arrow_stack_id end -local player_shoot_arrow = function(itemstack, player, power, damage, is_critical) +local function player_shoot_arrow(itemstack, player, power, damage, is_critical) local arrow_stack, arrow_stack_id = get_arrow(player) local arrow_itemstring local has_infinity_enchantment = mcl_enchanting.has_enchantment(player:get_wielded_item(), "infinity") @@ -133,7 +134,7 @@ S("The speed and damage of the arrow increases the longer you charge. The regula _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_durability = BOW_DURABILITY, inventory_image = "mcl_bows_bow.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, stack_max = 1, range = 4, -- Trick to disable digging as well @@ -161,7 +162,7 @@ S("The speed and damage of the arrow increases the longer you charge. The regula }) -- Iterates through player inventory and resets all the bows in "charging" state back to their original stage -local reset_bows = function(player) +local function reset_bows(player) local inv = player:get_inventory() local list = inv:get_list("main") for place, stack in pairs(list) do @@ -181,7 +182,7 @@ local reset_bows = function(player) end -- Resets the bow charging state and player speed. To be used when the player is no longer charging the bow -local reset_bow_state = function(player, also_reset_bows) +local function reset_bow_state(player, also_reset_bows) bow_load[player:get_player_name()] = nil bow_index[player:get_player_name()] = nil if minetest.get_modpath("playerphysics") then @@ -198,7 +199,7 @@ for level=0, 2 do description = S("Bow"), _doc_items_create_entry = false, inventory_image = "mcl_bows_bow_"..level..".png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, + wield_scale = mcl_vars.tool_wield_scale, stack_max = 1, range = 0, -- Pointing range to 0 to prevent punching with bow :D groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1}, @@ -227,11 +228,10 @@ end controls.register_on_release(function(player, key, time) if key~="RMB" then return end - local inv = minetest.get_inventory({type="player", name=player:get_player_name()}) + --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 wielditem:get_name()=="mcl_bows:bow_0_enchanted" or wielditem:get_name()=="mcl_bows:bow_1_enchanted" or wielditem:get_name()=="mcl_bows:bow_2_enchanted") then - local has_shot = false local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) local speed, damage @@ -271,7 +271,7 @@ controls.register_on_release(function(player, key, time) damage = math.max(1, math.floor(9 * charge_ratio)) end - has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) + local has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) if enchanted then wielditem:set_name("mcl_bows:bow_enchanted") @@ -298,7 +298,7 @@ controls.register_on_hold(function(player, key, time) if key ~= "RMB" or not (creative or get_arrow(player)) then return end - local inv = minetest.get_inventory({type="player", name=name}) + --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()) @@ -345,7 +345,7 @@ minetest.register_globalstep(function(dtime) local name = player:get_player_name() local wielditem = player:get_wielded_item() local wieldindex = player:get_wield_index() - local controls = player:get_player_control() + --local controls = player:get_player_control() if type(bow_load[name]) == "number" and ((wielditem:get_name()~="mcl_bows:bow_0" and wielditem:get_name()~="mcl_bows:bow_1" and wielditem:get_name()~="mcl_bows:bow_2" and wielditem:get_name()~="mcl_bows:bow_0_enchanted" and wielditem:get_name()~="mcl_bows:bow_1_enchanted" and wielditem:get_name()~="mcl_bows:bow_2_enchanted") or wieldindex ~= bow_index[name]) then reset_bow_state(player, true) end @@ -362,19 +362,19 @@ end) if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then minetest.register_craft({ - output = 'mcl_bows:bow', + output = "mcl_bows:bow", recipe = { - {'', 'mcl_core:stick', 'mcl_mobitems:string'}, - {'mcl_core:stick', '', 'mcl_mobitems:string'}, - {'', 'mcl_core:stick', 'mcl_mobitems:string'}, + {"", "mcl_core:stick", "mcl_mobitems:string"}, + {"mcl_core:stick", "", "mcl_mobitems:string"}, + {"", "mcl_core:stick", "mcl_mobitems:string"}, } }) minetest.register_craft({ - output = 'mcl_bows:bow', + output = "mcl_bows:bow", recipe = { - {'mcl_mobitems:string', 'mcl_core:stick', ''}, - {'mcl_mobitems:string', '', 'mcl_core:stick'}, - {'mcl_mobitems:string', 'mcl_core:stick', ''}, + {"mcl_mobitems:string", "mcl_core:stick", ""}, + {"mcl_mobitems:string", "", "mcl_core:stick"}, + {"mcl_mobitems:string", "mcl_core:stick", ""}, } }) end diff --git a/mods/ITEMS/mcl_bows/crossbow.lua b/mods/ITEMS/mcl_bows/crossbow.lua new file mode 100644 index 000000000..73d3f96f4 --- /dev/null +++ b/mods/ITEMS/mcl_bows/crossbow.lua @@ -0,0 +1,454 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_bows_s = {} + +-- local arrows = { +-- ["mcl_bows:arrow"] = "mcl_bows:arrow_entity", +-- } + +local GRAVITY = 9.81 +local BOW_DURABILITY = 385 + +-- Charging time in microseconds +local _BOW_CHARGE_TIME_HALF = 350000 -- bow level 1 +local _BOW_CHARGE_TIME_FULL = 900000 -- bow level 2 (full charge) + +local BOW_CHARGE_TIME_HALF = 350000 -- bow level 1 +local BOW_CHARGE_TIME_FULL = 900000 -- bow level 2 (full charge) + +-- Factor to multiply with player speed while player uses bow +-- This emulates the sneak speed. +local PLAYER_USE_CROSSBOW_SPEED = tonumber(minetest.settings:get("movement_speed_crouch")) / tonumber(minetest.settings:get("movement_speed_walk")) + +-- TODO: Use Minecraft speed (ca. 53 m/s) +-- Currently nerfed because at full speed the arrow would easily get out of the range of the loaded map. +local BOW_MAX_SPEED = 68 + +local function play_load_sound(id, pos) + minetest.sound_play("mcl_bows_crossbow_drawback_"..id, {pos=pos, max_hear_distance=12}, true) +end + +--[[ Store the charging state of each player. +keys: player name +value: +nil = not charging or player not existing +number: currently charging, the number is the time from minetest.get_us_time + in which the charging has started +]] +local bow_load = {} + +-- Another player table, this one stores the wield index of the bow being charged +local bow_index = {} + +function mcl_bows_s.shoot_arrow_crossbow(arrow_item, pos, dir, yaw, shooter, power, damage, is_critical, crossbow_stack, collectable) + local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrow_item.."_entity") + if power == nil then + power = BOW_MAX_SPEED --19 + end + if damage == nil then + damage = 3 + end + local knockback + if crossbow_stack then + local enchantments = mcl_enchanting.get_enchantments(crossbow_stack) + if enchantments.piercing then + obj:get_luaentity()._piercing = 1 * enchantments.piercing + else + obj:get_luaentity()._piercing = 0 + end + end + obj:set_velocity({x=dir.x*power, y=dir.y*power, z=dir.z*power}) + obj:set_acceleration({x=0, y=-GRAVITY, z=0}) + obj:set_yaw(yaw-math.pi/2) + local le = obj:get_luaentity() + le._shooter = shooter + le._source_object = shooter + le._damage = damage + le._is_critical = is_critical + le._startpos = pos + le._knockback = knockback + le._collectable = collectable + minetest.sound_play("mcl_bows_crossbow_shoot", {pos=pos, max_hear_distance=16}, true) + if shooter and shooter:is_player() then + if obj:get_luaentity().player == "" then + obj:get_luaentity().player = shooter + end + obj:get_luaentity().node = shooter:get_inventory():get_stack("main", 1):get_name() + end + return obj +end + +local function get_arrow(player) + local inv = player:get_inventory() + local arrow_stack, arrow_stack_id + for i=1, inv:get_size("main") do + local it = inv:get_stack("main", i) + if not it:is_empty() and minetest.get_item_group(it:get_name(), "ammo_crossbow") ~= 0 then + arrow_stack = it + arrow_stack_id = i + break + end + end + return arrow_stack, arrow_stack_id +end + +local function player_shoot_arrow(wielditem, player, power, damage, is_critical) + local has_multishot_enchantment = mcl_enchanting.has_enchantment(player:get_wielded_item(), "multishot") + local arrow_itemstring = wielditem:get_meta():get("arrow") + + if not arrow_itemstring then + return false + end + + local playerpos = player:get_pos() + local dir = player:get_look_dir() + local yaw = player:get_look_horizontal() + + if has_multishot_enchantment then + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, {x=dir.x, y=dir.y, z=dir.z + .2}, yaw, player, power, damage, is_critical, player:get_wielded_item(), false) + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, {x=dir.x, y=dir.y, z=dir.z - .2}, yaw, player, power, damage, is_critical, player:get_wielded_item(), false) + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage, is_critical, player:get_wielded_item(), true) + else + mcl_bows_s.shoot_arrow_crossbow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage, is_critical, player:get_wielded_item(), true) + end + return true +end + +-- Bow item, uncharged state +minetest.register_tool("mcl_bows:crossbow", { + description = S("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_durability = BOW_DURABILITY, + inventory_image = "mcl_bows_crossbow.png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 4, + -- Trick to disable digging as well + on_use = function() return end, + on_place = function(itemstack, player, pointed_thing) + if pointed_thing and pointed_thing.type == "node" then + -- Call on_rightclick if the pointed node defines it + 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 + end + + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + on_secondary_use = function(itemstack) + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1}, + _mcl_uses = 326, +}) + +minetest.register_tool("mcl_bows:crossbow_loaded", { + description = S("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 load an arrow into the chamber, then to shoot press left mouse."), + _doc_items_durability = BOW_DURABILITY, + inventory_image = "mcl_bows_crossbow_3.png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 4, + -- Trick to disable digging as well + on_use = function() return end, + on_place = function(itemstack, player, pointed_thing) + if pointed_thing and pointed_thing.type == "node" then + -- Call on_rightclick if the pointed node defines it + 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 + end + + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + on_secondary_use = function(itemstack) + itemstack:get_meta():set_string("active", "true") + return itemstack + end, + groups = {weapon=1,weapon_ranged=1,crossbow=1,enchantability=1,not_in_creative_inventory=1}, + _mcl_uses = 326, +}) + +-- Iterates through player inventory and resets all the bows in "charging" state back to their original stage +local function reset_bows(player) + local inv = player:get_inventory() + local list = inv:get_list("main") + for place, stack in pairs(list) do + if stack:get_name() == "mcl_bows:crossbow" or stack:get_name() == "mcl_bows:crossbow_enchanted" then + stack:get_meta():set_string("active", "") + elseif stack:get_name()=="mcl_bows:crossbow_0" or stack:get_name()=="mcl_bows:crossbow_1" or stack:get_name()=="mcl_bows:crossbow_2" then + stack:set_name("mcl_bows:crossbow") + stack:get_meta():set_string("active", "") + list[place] = stack + elseif stack:get_name()=="mcl_bows:crossbow_0_enchanted" or stack:get_name()=="mcl_bows:crossbow_1_enchanted" or stack:get_name()=="mcl_bows:crossbow_2_enchanted" then + stack:set_name("mcl_bows:crossbow_enchanted") + stack:get_meta():set_string("active", "") + list[place] = stack + end + end + inv:set_list("main", list) +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) + bow_load[player:get_player_name()] = nil + bow_index[player:get_player_name()] = nil + if minetest.get_modpath("playerphysics") then + playerphysics.remove_physics_factor(player, "speed", "mcl_bows:use_crossbow") + end + if also_reset_bows then + reset_bows(player) + end +end + +-- Bow in charging state +for level=0, 2 do + minetest.register_tool("mcl_bows:crossbow_"..level, { + description = S("Crossbow"), + _doc_items_create_entry = false, + inventory_image = "mcl_bows_crossbow_"..level..".png", + wield_scale = mcl_vars.tool_wield_scale, + stack_max = 1, + range = 0, -- Pointing range to 0 to prevent punching with bow :D + groups = {not_in_creative_inventory=1, not_in_craft_guide=1, bow=1, enchantability=1}, + -- Trick to disable digging as well + on_use = function() return end, + on_drop = function(itemstack, dropper, pos) + reset_bow_state(dropper) + itemstack:get_meta():set_string("active", "") + if mcl_enchanting.is_enchanted(itemstack:get_name()) then + itemstack:set_name("mcl_bows:crossbow_enchanted") + else + itemstack:set_name("mcl_bows:crossbow") + end + minetest.item_drop(itemstack, dropper, pos) + itemstack:take_item() + return itemstack + end, + -- Prevent accidental interaction with itemframes and other nodes + on_place = function(itemstack) + return itemstack + end, + _mcl_uses = 385, + }) +end + + +controls.register_on_release(function(player, key, time) + if key~="RMB" 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 + local arrow_stack, arrow_stack_id = get_arrow(player) + local arrow_itemstring + + if minetest.is_creative_enabled(player:get_player_name()) then + if arrow_stack then + arrow_itemstring = arrow_stack:get_name() + else + arrow_itemstring = "mcl_bows:arrow" + end + else + arrow_itemstring = arrow_stack:get_name() + arrow_stack:take_item() + player:get_inventory():set_stack("main", arrow_stack_id, arrow_stack) + end + + wielditem:get_meta():set_string("arrow", arrow_itemstring) + + if wielditem:get_name()=="mcl_bows:crossbow_2" then + wielditem:set_name("mcl_bows:crossbow_loaded") + else + wielditem:set_name("mcl_bows:crossbow_loaded_enchanted") + end + player:set_wielded_item(wielditem) + minetest.sound_play("mcl_bows_crossbow_load", {pos=player:get_pos(), max_hear_distance=16}, true) + else + reset_bow_state(player, true) + end +end) + +controls.register_on_press(function(player, key, time) + if key~="LMB" then return end + local wielditem = player:get_wielded_item() + if wielditem:get_name()=="mcl_bows:crossbow_loaded" or wielditem:get_name()=="mcl_bows:crossbow_loaded_enchanted" then + local enchanted = mcl_enchanting.is_enchanted(wielditem:get_name()) + local speed, damage + local p_load = bow_load[player:get_player_name()] + local charge + -- Type sanity check + if type(p_load) == "number" then + charge = minetest.get_us_time() - p_load + else + -- In case something goes wrong ... + -- Just assume minimum charge. + charge = 0 + minetest.log("warning", "[mcl_bows] Player "..player:get_player_name().." fires arrow with non-numeric bow_load!") + end + charge = math.max(math.min(charge, BOW_CHARGE_TIME_FULL), 0) + + local charge_ratio = charge / BOW_CHARGE_TIME_FULL + charge_ratio = math.max(math.min(charge_ratio, 1), 0) + + -- Calculate damage and speed + -- 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 + is_critical = true + else + damage = 9 + end + + local has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) + + if enchanted then + wielditem:set_name("mcl_bows:crossbow_enchanted") + else + wielditem:set_name("mcl_bows:crossbow") + end + + if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then + local durability = BOW_DURABILITY + local unbreaking = mcl_enchanting.get_enchantment(wielditem, "unbreaking") + local multishot = mcl_enchanting.get_enchantment(wielditem, "multishot") + if unbreaking > 0 then + durability = durability * (unbreaking + 1) + end + if multishot then + durability = durability / 3 + end + wielditem:add_wear(65535/durability) + end + player:set_wielded_item(wielditem) + reset_bow_state(player, true) + end +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 + return + end + --local inv = minetest.get_inventory({type="player", name=name}) + local wielditem = player:get_wielded_item() + local enchantments = mcl_enchanting.get_enchantments(wielditem) + if enchantments.quick_charge then + BOW_CHARGE_TIME_HALF = _BOW_CHARGE_TIME_HALF - (enchantments.quick_charge * 0.13 * 1000000 * .5) + BOW_CHARGE_TIME_FULL = _BOW_CHARGE_TIME_FULL - (enchantments.quick_charge * 0.13 * 1000000) + else + BOW_CHARGE_TIME_HALF = _BOW_CHARGE_TIME_HALF + 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() + else + if player:get_wield_index() == bow_index[name] then + if type(bow_load[name]) == "number" then + if wielditem:get_name() == "mcl_bows:crossbow_0" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then + wielditem:set_name("mcl_bows:crossbow_1") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_0_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_HALF then + wielditem:set_name("mcl_bows:crossbow_1_enchanted") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_1" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then + wielditem:set_name("mcl_bows:crossbow_2") + play_load_sound(2, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_1_enchanted" and minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then + wielditem:set_name("mcl_bows:crossbow_2_enchanted") + play_load_sound(2, player:get_pos()) + end + else + if wielditem:get_name() == "mcl_bows:crossbow_0" or wielditem:get_name() == "mcl_bows:crossbow_1" or wielditem:get_name() == "mcl_bows:crossbow_2" then + wielditem:set_name("mcl_bows:crossbow") + play_load_sound(1, player:get_pos()) + elseif wielditem:get_name() == "mcl_bows:crossbow_0_enchanted" or wielditem:get_name() == "mcl_bows:crossbow_1_enchanted" or wielditem:get_name() == "mcl_bows:crossbow_2_enchanted" then + wielditem:set_name("mcl_bows:crossbow_enchanted") + play_load_sound(1, player:get_pos()) + end + end + player:set_wielded_item(wielditem) + else + reset_bow_state(player, true) + end + end +end) + +minetest.register_globalstep(function(dtime) + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local wielditem = player:get_wielded_item() + local wieldindex = player:get_wield_index() + --local controls = player:get_player_control() + if type(bow_load[name]) == "number" and ((wielditem:get_name()~="mcl_bows:crossbow_0" and wielditem:get_name()~="mcl_bows:crossbow_1" and wielditem:get_name()~="mcl_bows:crossbow_2" and wielditem:get_name()~="mcl_bows:crossbow_0_enchanted" and wielditem:get_name()~="mcl_bows:crossbow_1_enchanted" and wielditem:get_name()~="mcl_bows:crossbow_2_enchanted") or wieldindex ~= bow_index[name]) then + reset_bow_state(player, true) + end + end +end) + +minetest.register_on_joinplayer(function(player) + reset_bows(player) +end) + +minetest.register_on_leaveplayer(function(player) + reset_bow_state(player, true) +end) + +if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then + minetest.register_craft({ + output = "mcl_bows:crossbow", + recipe = { + {"mcl_core:stick", "mcl_core:iron_ingot", "mcl_core:stick"}, + {"mcl_mobitems:string", "mcl_bows:arrow", "mcl_mobitems:string"}, + {"", "mcl_core:stick", ""}, + } + }) +end + +minetest.register_craft({ + type = "fuel", + recipe = "group:bow", + burntime = 15, +}) + +-- Add entry aliases for the Help +if minetest.get_modpath("doc") then + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_0") + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_1") + doc.add_entry_alias("tools", "mcl_bows:crossbow", "tools", "mcl_bows:crossbow_2") +end diff --git a/mods/ITEMS/mcl_bows/depends.txt b/mods/ITEMS/mcl_bows/depends.txt deleted file mode 100644 index a797e7184..000000000 --- a/mods/ITEMS/mcl_bows/depends.txt +++ /dev/null @@ -1,11 +0,0 @@ -controls -awards? -mcl_achievements? -mcl_core? -mcl_mobitems? -playerphysics? -doc? -doc_identifier? -mesecons_button? -mcl_particles -mcl_enchanting diff --git a/mods/ITEMS/mcl_bows/init.lua b/mods/ITEMS/mcl_bows/init.lua index a2745d950..d5b06dac7 100644 --- a/mods/ITEMS/mcl_bows/init.lua +++ b/mods/ITEMS/mcl_bows/init.lua @@ -1,5 +1,11 @@ +--Bow dofile(minetest.get_modpath("mcl_bows") .. "/arrow.lua") dofile(minetest.get_modpath("mcl_bows") .. "/bow.lua") +dofile(minetest.get_modpath("mcl_bows") .. "/rocket.lua") +--Crossbow +dofile(minetest.get_modpath("mcl_bows") .. "/crossbow.lua") + +--Compatiblility with older MineClone worlds minetest.register_alias("mcl_throwing:bow", "mcl_bows:bow") minetest.register_alias("mcl_throwing:arrow", "mcl_bows:arrow") diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr index 539afdcf0..4ed4d8640 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.es.tr @@ -8,4 +8,11 @@ Bow=Arco Bows are ranged weapons to shoot arrows at your foes.=Los arcos son armas a distancia para disparar flechas a tus enemigos. 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.=La velocidad y el daño de la flecha aumentan cuanto más tiempo tenses. El daño regular de la flecha está entre 1 y 9. A plena carga, también hay un 20% de un golpe crítico, que en vez de eso causa 10 de daño. 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 el arco, primero debes de tener al menos una flecha en cualquier parte de su inventario (a menos que esté en modo creativo). Mantenga presionado el botón derecho del mouse para tensar, suelte para disparar. -Bow=Arco \ No newline at end of file +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 +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. +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.=Para usar la ballesta, primero debes tener por lo menos una flecha en cualquier raunura de tu inventario (excepto en modo creativo).Mantén presionado el botón derecho del ratón para cargar, suelta para disparar. diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr index 313081e48..901be04df 100644 --- a/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.fr.tr @@ -10,6 +10,9 @@ The speed and damage of the arrow increases the longer you charge. The regular d 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.=Pour utiliser l'arc, 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. Bow=Arc Ammunition=Munition -Damage from bow: 1-10=Dégâts de l'arc: 1-10 -Damage from dispenser: 3=Dégâts du distributeur: 3 +Damage from bow: 1-10=Dégâts de l'arc : 1-10 +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. diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr new file mode 100644 index 000000000..517622b47 --- /dev/null +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.ja.tr @@ -0,0 +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.=矢を弓の弾として使うには、インベントリのどこかに入れるだけでよく、使い切るまで自動的に装填されます。矢をディスペンサーの弾薬として使用するには、ディスペンサーのインベントリに入れます。ブロックに刺さった矢を回収するには、ブロックの近くまで歩くだけです。 +Bow=弓 +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.=弓を使用するには、まずインベントリのどこかに少なくとも1本の矢が入っている必要があります(クリエイティブモードを除く)。マウスの右ボタンを押したままでタメ、離すと射ます。 +Bow=弓 +Ammunition=弾 +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 shoot.=クロスボウを使用するには、まずインベントリのどこかに少なくとも1本の矢が入っている必要があります(クリエイティブモードを除く)。マウスの右ボタンを押したままでタメ、離すと射ます。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.pl.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.pl.tr new file mode 100644 index 000000000..a518ac0ea --- /dev/null +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.pl.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_bows +Arrow=Strzała +Arrows are ammunition for bows and dispensers.=Strzały są amunicją do łuku i dozowników. +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.=Strzała wypuszczona z łuku ma typowe obrażania 1-9. Przy pełnym napięciu jest szansa 20% na trafienie krytyczne zadające 10 obrażeń. Strzała wystrzelona z dozownika zawsze zadaje 3 obrażenia. +Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=Strzały zatrzymują się na stałych blokach i mogą być wówczas odzyskane. Są również w stanie klikać drewniane przyciski. +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.=Aby użyć strzał jako amunicję do łuku umieść je gdziekolwiek w twoim ekwipunku, będą użyte automatyczne. Aby użyć strzał jako amunicję do dozownika umieść je w jego ekwipunku. Aby odzyskać strzałę wbitą w blok po prostu podejdź do niej. +Bow=Łuk +Bows are ranged weapons to shoot arrows at your foes.=Łuki to bronie dystansowe do strzelania strzałami w twoich przeciwników. +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.=Szybkość i obrażenia strzały wzrastają im dłużej ją naciągasz. Zwykłe obrażenia strzały są pomiędzy 1 a 9. Przy pełnym napięciu jest szansa 20% na trafienie krytyczne zadające 10 obrażeń. +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.=Aby użyć łuku musisz mieć przynajmniej jedną strzałę gdziekolwiek w twoim ekwipunku (chyba, że to tryb Kreatywny). Przytrzymaj prawy przycisk myszy aby napiąć łuk, puść by strzelić. +Bow=Łuk +Ammunition=Amunicja +Damage from bow: 1-10=Obrażenia z łuku 1-10 +Damage from dispenser: 3=Obrażenia z dozownika: 3 +Launches arrows=Strzela strzałami + diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr new file mode 100644 index 000000000..66044f8a0 --- /dev/null +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.pt_BR.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_bows +Arrow=Flecha +Arrows are ammunition for bows and dispensers.=Flechas são munições para arcos e dispensores. +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.=Uma flecha disparada de um arco tem um dano regular variando entre 1-9. Quando puxado o arco por completo há uma chance de 20% de acerto crítico, causando 10 de dano. Uma flecha disparada de um dispensor sempre provocará 3 de dano. +Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons.=Flechas poderão ficar presas em blocos sólidos e podem ser recuperadas novamente. Elas também são capazes de empurrar botões de madeira. +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.=Para usar flechas como munição para um arco, apenas as coloque em seu inventário, elas serão consumidas automaticamente. Para usar flechas como munição de dispensores, coloque as no inventário do dispensor. Para recuperar uma flecha presa em um bloco, simplemente se aproxime dela. +Bow=Arco +Bows are ranged weapons to shoot arrows at your foes.=Arcos são armas de longo alcance que disparam flechas em seus inimigos. +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 +Damage from bow: 1-10=Dano provocado pelo arco: 1-10 +Damage from dispenser: 3=Dano provocado pelo dispensor: 3 +Launches arrows=Dispara flechas +Crossbow=Besta +Crossbows are ranged weapons to shoot arrows at your foes.=Bestas são armas de longo alcance que disparam flechas em seus inimigos. +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.=Para usar a besta, 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, solte-o para disparar. diff --git a/mods/ITEMS/mcl_bows/locale/mcl_bows.zh_TW.tr b/mods/ITEMS/mcl_bows/locale/mcl_bows.zh_TW.tr new file mode 100644 index 000000000..6b59895d3 --- /dev/null +++ b/mods/ITEMS/mcl_bows/locale/mcl_bows.zh_TW.tr @@ -0,0 +1,14 @@ +# 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.=要把箭作為弓的彈藥,只需把它們放在你物品欄的任何地方,它們就會被自動使用。要使用箭作為發射器的彈藥,把它們放在發射器的物品欄中。要取回插在方塊上的箭,只需走到它附近。 +Bow=弓 +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.=要使用這把弓,你首先需要在你物品欄的任何地方至少有一支箭(除非在創造模式下)。按住鼠標右鍵充電,鬆開即可射擊。 +Ammunition=彈藥 +Damage from bow: 1-10=從弓發射時的傷害:1-10 +Damage from dispenser: 3=從發射器發射時的傷害:3 +Launches arrows=發射箭 diff --git a/mods/ITEMS/mcl_bows/locale/template.txt b/mods/ITEMS/mcl_bows/locale/template.txt index 228b61709..ebdea9525 100644 --- a/mods/ITEMS/mcl_bows/locale/template.txt +++ b/mods/ITEMS/mcl_bows/locale/template.txt @@ -13,3 +13,6 @@ Ammunition= Damage from bow: 1-10= 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 diff --git a/mods/ITEMS/mcl_bows/mod.conf b/mods/ITEMS/mcl_bows/mod.conf new file mode 100644 index 000000000..7b174826a --- /dev/null +++ b/mods/ITEMS/mcl_bows/mod.conf @@ -0,0 +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 +optional_depends = awards, mcl_achievements, mcl_core, mcl_mobitems, playerphysics, doc, doc_identifier, mesecons_button + diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj b/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj new file mode 100644 index 000000000..bee2c0f4b --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_arrow.obj @@ -0,0 +1,56 @@ +# Blender v2.92.0 OBJ File: '' +# www.blender.org +mtllib mcl_bows_arrow.mtl +o Plane +v 3.782006 1.444249 -0.000500 +v 3.782006 -1.443249 -0.000500 +v -3.782006 -1.443249 -0.000500 +v -3.782006 1.444249 -0.000500 +v 3.331104 -1.100076 -1.064829 +v 3.331104 1.069925 -1.064830 +v 3.331104 1.069925 1.085017 +v 3.331104 -1.100076 1.085017 +v 3.782006 0.001000 -1.443750 +v -3.782006 0.001000 -1.443749 +v -3.782006 0.001000 1.443750 +v 3.782006 0.001000 1.443749 +v 3.782006 1.444249 0.000500 +v -3.782006 1.444249 0.000500 +v -3.782006 -1.443249 0.000500 +v 3.782006 -1.443249 0.000500 +v 3.782006 0.000000 -1.443750 +v 3.782006 -0.000000 1.443749 +v -3.782006 -0.000000 1.443750 +v -3.782006 0.000000 -1.443749 +vt -0.000893 0.835148 +vt -0.000893 1.008567 +vt 0.486244 1.008567 +vt 0.486244 0.835148 +vt 0.159016 0.682983 +vt 0.159016 0.849928 +vt -0.005031 0.849928 +vt -0.005031 0.682983 +vt -0.000893 0.835148 +vt 0.486244 0.835148 +vt 0.486244 1.008567 +vt -0.000893 1.008567 +vt -0.000893 0.835148 +vt 0.486244 0.835148 +vt 0.486244 1.008567 +vt -0.000893 1.008567 +vt -0.000893 0.835148 +vt -0.000893 1.008567 +vt 0.486244 1.008567 +vt 0.486244 0.835148 +vn 0.0000 0.0000 -1.0000 +vn 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +vn 0.0000 -0.0000 1.0000 +vn -0.0000 -1.0000 -0.0000 +usemtl Material.002 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 6/6/2 7/7/2 8/8/2 +f 9/9/3 10/10/3 11/11/3 12/12/3 +f 13/13/4 14/14/4 15/15/4 16/16/4 +f 17/17/5 18/18/5 19/19/5 20/20/5 diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d new file mode 100644 index 000000000..0a34f1eaa Binary files /dev/null and b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.b3d differ diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl new file mode 100644 index 000000000..f231bdf4c --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.mtl @@ -0,0 +1,10 @@ +# Blender MTL File: 'None' +# Material Count: 1 + +newmtl None +Ns 500 +Ka 0.8 0.8 0.8 +Kd 0.8 0.8 0.8 +Ks 0.8 0.8 0.8 +d 1 +illum 2 diff --git a/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj new file mode 100644 index 000000000..e2bd11d34 --- /dev/null +++ b/mods/ITEMS/mcl_bows/models/mcl_bows_rocket.obj @@ -0,0 +1,1016 @@ +# Blender v3.0.0 Alpha OBJ File: '' +# www.blender.org +mtllib mcl_bows_rocket.mtl +o Plane +v -1.414214 -0.063116 0.000000 +v 0.000000 -0.063116 1.414214 +v -0.000000 -0.063116 -1.414214 +v 1.414214 -0.063116 -0.000000 +v -1.414214 -0.062205 0.000000 +v 0.000000 -0.062205 1.414214 +v -0.000000 -0.062205 -1.414214 +v 1.414214 -0.062205 -0.000000 +v -1.414214 -0.060838 0.000000 +v 0.000000 -0.060838 1.414214 +v -0.000000 -0.060838 -1.414214 +v 1.414214 -0.060838 -0.000000 +v -1.414214 -0.059926 0.000000 +v 0.000000 -0.059926 1.414214 +v -0.000000 -0.059926 -1.414214 +v 1.414214 -0.059926 -0.000000 +v -1.414214 -0.058559 0.000000 +v 0.000000 -0.058559 1.414214 +v -0.000000 -0.058559 -1.414214 +v 1.414214 -0.058559 -0.000000 +v -1.414214 -0.057648 0.000000 +v 0.000000 -0.057648 1.414214 +v -0.000000 -0.057648 -1.414214 +v 1.414214 -0.057648 -0.000000 +v -1.414214 -0.056281 0.000000 +v 0.000000 -0.056281 1.414214 +v -0.000000 -0.056281 -1.414214 +v 1.414214 -0.056281 -0.000000 +v -1.414214 -0.055369 0.000000 +v 0.000000 -0.055369 1.414214 +v -0.000000 -0.055369 -1.414214 +v 1.414214 -0.055369 -0.000000 +v -1.414214 -0.054002 0.000000 +v 0.000000 -0.054002 1.414214 +v -0.000000 -0.054002 -1.414214 +v 1.414214 -0.054002 -0.000000 +v -1.414214 -0.053091 0.000000 +v 0.000000 -0.053091 1.414214 +v -0.000000 -0.053091 -1.414214 +v 1.414214 -0.053091 -0.000000 +v -1.414214 -0.051723 0.000000 +v 0.000000 -0.051723 1.414214 +v -0.000000 -0.051723 -1.414214 +v 1.414214 -0.051723 -0.000000 +v -1.414214 -0.050812 0.000000 +v 0.000000 -0.050812 1.414214 +v -0.000000 -0.050812 -1.414214 +v 1.414214 -0.050812 -0.000000 +v -1.414214 -0.049445 0.000000 +v 0.000000 -0.049445 1.414214 +v -0.000000 -0.049445 -1.414214 +v 1.414214 -0.049445 -0.000000 +v -1.414214 -0.048533 0.000000 +v 0.000000 -0.048533 1.414214 +v -0.000000 -0.048533 -1.414214 +v 1.414214 -0.048533 -0.000000 +v -1.414214 -0.047166 0.000000 +v 0.000000 -0.047166 1.414214 +v -0.000000 -0.047166 -1.414214 +v 1.414214 -0.047166 -0.000000 +v -1.414214 -0.046255 0.000000 +v 0.000000 -0.046255 1.414214 +v -0.000000 -0.046255 -1.414214 +v 1.414214 -0.046255 -0.000000 +v -1.414214 -0.044888 0.000000 +v 0.000000 -0.044888 1.414214 +v -0.000000 -0.044888 -1.414214 +v 1.414214 -0.044888 -0.000000 +v -1.414214 -0.043976 0.000000 +v 0.000000 -0.043976 1.414214 +v -0.000000 -0.043976 -1.414214 +v 1.414214 -0.043976 -0.000000 +v -1.414214 -0.042609 0.000000 +v 0.000000 -0.042609 1.414214 +v -0.000000 -0.042609 -1.414214 +v 1.414214 -0.042609 -0.000000 +v -1.414214 -0.041698 0.000000 +v 0.000000 -0.041698 1.414214 +v -0.000000 -0.041698 -1.414214 +v 1.414214 -0.041698 -0.000000 +v -1.414214 -0.040331 0.000000 +v 0.000000 -0.040331 1.414214 +v -0.000000 -0.040331 -1.414214 +v 1.414214 -0.040331 -0.000000 +v -1.414214 -0.039419 0.000000 +v 0.000000 -0.039419 1.414214 +v -0.000000 -0.039419 -1.414214 +v 1.414214 -0.039419 -0.000000 +v -1.414214 -0.038052 0.000000 +v 0.000000 -0.038052 1.414214 +v -0.000000 -0.038052 -1.414214 +v 1.414214 -0.038052 -0.000000 +v -1.414214 -0.037141 0.000000 +v 0.000000 -0.037141 1.414214 +v -0.000000 -0.037141 -1.414214 +v 1.414214 -0.037141 -0.000000 +v -1.414214 -0.035773 0.000000 +v 0.000000 -0.035773 1.414214 +v -0.000000 -0.035773 -1.414214 +v 1.414214 -0.035773 -0.000000 +v -1.414214 -0.034862 0.000000 +v 0.000000 -0.034862 1.414214 +v -0.000000 -0.034862 -1.414214 +v 1.414214 -0.034862 -0.000000 +v -1.414214 -0.033495 0.000000 +v 0.000000 -0.033495 1.414214 +v -0.000000 -0.033495 -1.414214 +v 1.414214 -0.033495 -0.000000 +v -1.414214 -0.032583 0.000000 +v 0.000000 -0.032583 1.414214 +v -0.000000 -0.032583 -1.414214 +v 1.414214 -0.032583 -0.000000 +v -1.414214 -0.031216 0.000000 +v 0.000000 -0.031216 1.414214 +v -0.000000 -0.031216 -1.414214 +v 1.414214 -0.031216 -0.000000 +v -1.414214 -0.030305 0.000000 +v 0.000000 -0.030305 1.414214 +v -0.000000 -0.030305 -1.414214 +v 1.414214 -0.030305 -0.000000 +v -1.414214 -0.028938 0.000000 +v 0.000000 -0.028938 1.414214 +v -0.000000 -0.028938 -1.414214 +v 1.414214 -0.028938 -0.000000 +v -1.414214 -0.028026 0.000000 +v 0.000000 -0.028026 1.414214 +v -0.000000 -0.028026 -1.414214 +v 1.414214 -0.028026 -0.000000 +v -1.414214 -0.026659 0.000000 +v 0.000000 -0.026659 1.414214 +v -0.000000 -0.026659 -1.414214 +v 1.414214 -0.026659 -0.000000 +v -1.414214 -0.025748 0.000000 +v 0.000000 -0.025748 1.414214 +v -0.000000 -0.025748 -1.414214 +v 1.414214 -0.025748 -0.000000 +v -1.414214 -0.024381 0.000000 +v 0.000000 -0.024381 1.414214 +v -0.000000 -0.024381 -1.414214 +v 1.414214 -0.024381 -0.000000 +v -1.414214 -0.023469 0.000000 +v 0.000000 -0.023469 1.414214 +v -0.000000 -0.023469 -1.414214 +v 1.414214 -0.023469 -0.000000 +v -1.414214 -0.022102 0.000000 +v 0.000000 -0.022102 1.414214 +v -0.000000 -0.022102 -1.414214 +v 1.414214 -0.022102 -0.000000 +v -1.414214 -0.021191 0.000000 +v 0.000000 -0.021191 1.414214 +v -0.000000 -0.021191 -1.414214 +v 1.414214 -0.021191 -0.000000 +v -1.414214 -0.019824 0.000000 +v 0.000000 -0.019824 1.414214 +v -0.000000 -0.019824 -1.414214 +v 1.414214 -0.019824 -0.000000 +v -1.414214 -0.018912 0.000000 +v 0.000000 -0.018912 1.414214 +v -0.000000 -0.018912 -1.414214 +v 1.414214 -0.018912 -0.000000 +v -1.414214 -0.017545 0.000000 +v 0.000000 -0.017545 1.414214 +v -0.000000 -0.017545 -1.414214 +v 1.414214 -0.017545 -0.000000 +v -1.414214 -0.016634 0.000000 +v 0.000000 -0.016634 1.414214 +v -0.000000 -0.016634 -1.414214 +v 1.414214 -0.016634 -0.000000 +v -1.414214 -0.015266 0.000000 +v 0.000000 -0.015266 1.414214 +v -0.000000 -0.015266 -1.414214 +v 1.414214 -0.015266 -0.000000 +v -1.414214 -0.014355 0.000000 +v 0.000000 -0.014355 1.414214 +v -0.000000 -0.014355 -1.414214 +v 1.414214 -0.014355 -0.000000 +v -1.414214 -0.012988 0.000000 +v 0.000000 -0.012988 1.414214 +v -0.000000 -0.012988 -1.414214 +v 1.414214 -0.012988 -0.000000 +v -1.414214 -0.012076 0.000000 +v 0.000000 -0.012076 1.414214 +v -0.000000 -0.012076 -1.414214 +v 1.414214 -0.012076 -0.000000 +v -1.414214 -0.010709 0.000000 +v 0.000000 -0.010709 1.414214 +v -0.000000 -0.010709 -1.414214 +v 1.414214 -0.010709 -0.000000 +v -1.414214 -0.009798 0.000000 +v 0.000000 -0.009798 1.414214 +v -0.000000 -0.009798 -1.414214 +v 1.414214 -0.009798 -0.000000 +v -1.414214 -0.008431 0.000000 +v 0.000000 -0.008431 1.414214 +v -0.000000 -0.008431 -1.414214 +v 1.414214 -0.008431 -0.000000 +v -1.414214 -0.007519 0.000000 +v 0.000000 -0.007519 1.414214 +v -0.000000 -0.007519 -1.414214 +v 1.414214 -0.007519 -0.000000 +v -1.414214 -0.006152 0.000000 +v 0.000000 -0.006152 1.414214 +v -0.000000 -0.006152 -1.414214 +v 1.414214 -0.006152 -0.000000 +v -1.414214 -0.005241 0.000000 +v 0.000000 -0.005241 1.414214 +v -0.000000 -0.005241 -1.414214 +v 1.414214 -0.005241 -0.000000 +v -1.414214 -0.003874 0.000000 +v 0.000000 -0.003874 1.414214 +v -0.000000 -0.003874 -1.414214 +v 1.414214 -0.003874 -0.000000 +v -1.414214 -0.002962 0.000000 +v 0.000000 -0.002962 1.414214 +v -0.000000 -0.002962 -1.414214 +v 1.414214 -0.002962 -0.000000 +v -1.414214 -0.001595 0.000000 +v 0.000000 -0.001595 1.414214 +v -0.000000 -0.001595 -1.414214 +v 1.414214 -0.001595 -0.000000 +v -1.414214 -0.000684 0.000000 +v 0.000000 -0.000684 1.414214 +v -0.000000 -0.000684 -1.414214 +v 1.414214 -0.000684 -0.000000 +v -1.414214 0.000684 0.000000 +v 0.000000 0.000684 1.414214 +v -0.000000 0.000684 -1.414214 +v 1.414214 0.000684 -0.000000 +v -1.414214 0.001595 0.000000 +v 0.000000 0.001595 1.414214 +v -0.000000 0.001595 -1.414214 +v 1.414214 0.001595 -0.000000 +v -1.414214 0.002962 0.000000 +v 0.000000 0.002962 1.414214 +v -0.000000 0.002962 -1.414214 +v 1.414214 0.002962 -0.000000 +v -1.414214 0.003874 0.000000 +v 0.000000 0.003874 1.414214 +v -0.000000 0.003874 -1.414214 +v 1.414214 0.003874 -0.000000 +v -1.414214 0.005241 0.000000 +v 0.000000 0.005241 1.414214 +v -0.000000 0.005241 -1.414214 +v 1.414214 0.005241 -0.000000 +v -1.414214 0.006152 0.000000 +v 0.000000 0.006152 1.414214 +v -0.000000 0.006152 -1.414214 +v 1.414214 0.006152 -0.000000 +v -1.414214 0.007519 0.000000 +v 0.000000 0.007519 1.414214 +v -0.000000 0.007519 -1.414214 +v 1.414214 0.007519 -0.000000 +v -1.414214 0.008431 0.000000 +v 0.000000 0.008431 1.414214 +v -0.000000 0.008431 -1.414214 +v 1.414214 0.008431 -0.000000 +v -1.414214 0.009798 0.000000 +v 0.000000 0.009798 1.414214 +v -0.000000 0.009798 -1.414214 +v 1.414214 0.009798 -0.000000 +v -1.414214 0.010709 0.000000 +v 0.000000 0.010709 1.414214 +v -0.000000 0.010709 -1.414214 +v 1.414214 0.010709 -0.000000 +v -1.414214 0.012076 0.000000 +v 0.000000 0.012076 1.414214 +v -0.000000 0.012076 -1.414214 +v 1.414214 0.012076 -0.000000 +v -1.414214 0.012988 0.000000 +v 0.000000 0.012988 1.414214 +v -0.000000 0.012988 -1.414214 +v 1.414214 0.012988 -0.000000 +v -1.414214 0.014355 0.000000 +v 0.000000 0.014355 1.414214 +v -0.000000 0.014355 -1.414214 +v 1.414214 0.014355 -0.000000 +v -1.414214 0.015266 0.000000 +v 0.000000 0.015266 1.414214 +v -0.000000 0.015266 -1.414214 +v 1.414214 0.015266 -0.000000 +v -1.414214 0.016634 0.000000 +v 0.000000 0.016634 1.414214 +v -0.000000 0.016634 -1.414214 +v 1.414214 0.016634 -0.000000 +v -1.414214 0.017545 0.000000 +v 0.000000 0.017545 1.414214 +v -0.000000 0.017545 -1.414214 +v 1.414214 0.017545 -0.000000 +v -1.414214 0.018912 0.000000 +v 0.000000 0.018912 1.414214 +v -0.000000 0.018912 -1.414214 +v 1.414214 0.018912 -0.000000 +v -1.414214 0.019824 0.000000 +v 0.000000 0.019824 1.414214 +v -0.000000 0.019824 -1.414214 +v 1.414214 0.019824 -0.000000 +v -1.414214 0.021191 0.000000 +v 0.000000 0.021191 1.414214 +v -0.000000 0.021191 -1.414214 +v 1.414214 0.021191 -0.000000 +v -1.414214 0.022102 0.000000 +v 0.000000 0.022102 1.414214 +v -0.000000 0.022102 -1.414214 +v 1.414214 0.022102 -0.000000 +v -1.414214 0.023469 0.000000 +v 0.000000 0.023469 1.414214 +v -0.000000 0.023469 -1.414214 +v 1.414214 0.023469 -0.000000 +v -1.414214 0.024381 0.000000 +v 0.000000 0.024381 1.414214 +v -0.000000 0.024381 -1.414214 +v 1.414214 0.024381 -0.000000 +v -1.414214 0.025748 0.000000 +v 0.000000 0.025748 1.414214 +v -0.000000 0.025748 -1.414214 +v 1.414214 0.025748 -0.000000 +v -1.414214 0.026659 0.000000 +v 0.000000 0.026659 1.414214 +v -0.000000 0.026659 -1.414214 +v 1.414214 0.026659 -0.000000 +v -1.414214 0.028026 0.000000 +v 0.000000 0.028026 1.414214 +v -0.000000 0.028026 -1.414214 +v 1.414214 0.028026 -0.000000 +v -1.414214 0.028938 0.000000 +v 0.000000 0.028938 1.414214 +v -0.000000 0.028938 -1.414214 +v 1.414214 0.028938 -0.000000 +v -1.414214 0.030305 0.000000 +v 0.000000 0.030305 1.414214 +v -0.000000 0.030305 -1.414214 +v 1.414214 0.030305 -0.000000 +v -1.414214 0.031216 0.000000 +v 0.000000 0.031216 1.414214 +v -0.000000 0.031216 -1.414214 +v 1.414214 0.031216 -0.000000 +v -1.414214 0.032584 0.000000 +v 0.000000 0.032584 1.414214 +v -0.000000 0.032584 -1.414214 +v 1.414214 0.032584 -0.000000 +v -1.414214 0.033495 0.000000 +v 0.000000 0.033495 1.414214 +v -0.000000 0.033495 -1.414214 +v 1.414214 0.033495 -0.000000 +v -1.414214 0.034862 0.000000 +v 0.000000 0.034862 1.414214 +v -0.000000 0.034862 -1.414214 +v 1.414214 0.034862 -0.000000 +v -1.414214 0.035774 0.000000 +v 0.000000 0.035774 1.414214 +v -0.000000 0.035774 -1.414214 +v 1.414214 0.035774 -0.000000 +v -1.414214 0.037141 0.000000 +v 0.000000 0.037141 1.414214 +v -0.000000 0.037141 -1.414214 +v 1.414214 0.037141 -0.000000 +v -1.414214 0.038052 0.000000 +v 0.000000 0.038052 1.414214 +v -0.000000 0.038052 -1.414214 +v 1.414214 0.038052 -0.000000 +v -1.414214 0.039419 0.000000 +v 0.000000 0.039419 1.414214 +v -0.000000 0.039419 -1.414214 +v 1.414214 0.039419 -0.000000 +v -1.414214 0.040331 0.000000 +v 0.000000 0.040331 1.414214 +v -0.000000 0.040331 -1.414214 +v 1.414214 0.040331 -0.000000 +v -1.414214 0.041698 0.000000 +v 0.000000 0.041698 1.414214 +v -0.000000 0.041698 -1.414214 +v 1.414214 0.041698 -0.000000 +v -1.414214 0.042609 0.000000 +v 0.000000 0.042609 1.414214 +v -0.000000 0.042609 -1.414214 +v 1.414214 0.042609 -0.000000 +v -1.414214 0.043976 0.000000 +v 0.000000 0.043976 1.414214 +v -0.000000 0.043976 -1.414214 +v 1.414214 0.043976 -0.000000 +v -1.414214 0.044888 0.000000 +v 0.000000 0.044888 1.414214 +v -0.000000 0.044888 -1.414214 +v 1.414214 0.044888 -0.000000 +v -1.414214 0.046255 0.000000 +v 0.000000 0.046255 1.414214 +v -0.000000 0.046255 -1.414214 +v 1.414214 0.046255 -0.000000 +v -1.414214 0.047166 0.000000 +v 0.000000 0.047166 1.414214 +v -0.000000 0.047166 -1.414214 +v 1.414214 0.047166 -0.000000 +v -1.414214 0.048533 0.000000 +v 0.000000 0.048533 1.414214 +v -0.000000 0.048533 -1.414214 +v 1.414214 0.048533 -0.000000 +v -1.414214 0.049445 0.000000 +v 0.000000 0.049445 1.414214 +v -0.000000 0.049445 -1.414214 +v 1.414214 0.049445 -0.000000 +v -1.414214 0.050812 0.000000 +v 0.000000 0.050812 1.414214 +v -0.000000 0.050812 -1.414214 +v 1.414214 0.050812 -0.000000 +v -1.414214 0.051723 0.000000 +v 0.000000 0.051723 1.414214 +v -0.000000 0.051723 -1.414214 +v 1.414214 0.051723 -0.000000 +v -1.414214 0.053091 0.000000 +v 0.000000 0.053091 1.414214 +v -0.000000 0.053091 -1.414214 +v 1.414214 0.053091 -0.000000 +v -1.414214 0.054002 0.000000 +v 0.000000 0.054002 1.414214 +v -0.000000 0.054002 -1.414214 +v 1.414214 0.054002 -0.000000 +v -1.414214 0.055369 0.000000 +v 0.000000 0.055369 1.414214 +v -0.000000 0.055369 -1.414214 +v 1.414214 0.055369 -0.000000 +v -1.414214 0.056281 0.000000 +v 0.000000 0.056281 1.414214 +v -0.000000 0.056281 -1.414214 +v 1.414214 0.056281 -0.000000 +v -1.414214 0.057648 0.000000 +v 0.000000 0.057648 1.414214 +v -0.000000 0.057648 -1.414214 +v 1.414214 0.057648 -0.000000 +v -1.414214 0.058559 0.000000 +v 0.000000 0.058559 1.414214 +v -0.000000 0.058559 -1.414214 +v 1.414214 0.058559 -0.000000 +v -1.414214 0.059926 0.000000 +v 0.000000 0.059926 1.414214 +v -0.000000 0.059926 -1.414214 +v 1.414214 0.059926 -0.000000 +v -1.414214 0.060838 0.000000 +v 0.000000 0.060838 1.414214 +v -0.000000 0.060838 -1.414214 +v 1.414214 0.060838 -0.000000 +v -1.414214 0.062205 0.000000 +v 0.000000 0.062205 1.414214 +v -0.000000 0.062205 -1.414214 +v 1.414214 0.062205 -0.000000 +v -1.414214 0.063116 0.000000 +v 0.000000 0.063116 1.414214 +v -0.000000 0.063116 -1.414214 +v 1.414214 0.063116 -0.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +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 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 0.000000 1.000000 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl None +s off +f 1/1/1 3/2/1 4/3/1 2/4/1 +f 5/5/2 6/6/2 8/7/2 7/8/2 +f 9/9/1 11/10/1 12/11/1 10/12/1 +f 13/13/2 14/14/2 16/15/2 15/16/2 +f 17/17/1 19/18/1 20/19/1 18/20/1 +f 21/21/2 22/22/2 24/23/2 23/24/2 +f 25/25/1 27/26/1 28/27/1 26/28/1 +f 29/29/2 30/30/2 32/31/2 31/32/2 +f 33/33/1 35/34/1 36/35/1 34/36/1 +f 37/37/2 38/38/2 40/39/2 39/40/2 +f 41/41/1 43/42/1 44/43/1 42/44/1 +f 45/45/2 46/46/2 48/47/2 47/48/2 +f 49/49/1 51/50/1 52/51/1 50/52/1 +f 53/53/2 54/54/2 56/55/2 55/56/2 +f 57/57/1 59/58/1 60/59/1 58/60/1 +f 61/61/2 62/62/2 64/63/2 63/64/2 +f 65/65/1 67/66/1 68/67/1 66/68/1 +f 69/69/2 70/70/2 72/71/2 71/72/2 +f 73/73/1 75/74/1 76/75/1 74/76/1 +f 77/77/2 78/78/2 80/79/2 79/80/2 +f 81/81/1 83/82/1 84/83/1 82/84/1 +f 85/85/2 86/86/2 88/87/2 87/88/2 +f 89/89/1 91/90/1 92/91/1 90/92/1 +f 93/93/2 94/94/2 96/95/2 95/96/2 +f 97/97/1 99/98/1 100/99/1 98/100/1 +f 101/101/2 102/102/2 104/103/2 103/104/2 +f 105/105/1 107/106/1 108/107/1 106/108/1 +f 109/109/2 110/110/2 112/111/2 111/112/2 +f 113/113/1 115/114/1 116/115/1 114/116/1 +f 117/117/2 118/118/2 120/119/2 119/120/2 +f 121/121/1 123/122/1 124/123/1 122/124/1 +f 125/125/2 126/126/2 128/127/2 127/128/2 +f 129/129/1 131/130/1 132/131/1 130/132/1 +f 133/133/2 134/134/2 136/135/2 135/136/2 +f 137/137/1 139/138/1 140/139/1 138/140/1 +f 141/141/2 142/142/2 144/143/2 143/144/2 +f 145/145/1 147/146/1 148/147/1 146/148/1 +f 149/149/2 150/150/2 152/151/2 151/152/2 +f 153/153/1 155/154/1 156/155/1 154/156/1 +f 157/157/2 158/158/2 160/159/2 159/160/2 +f 161/161/1 163/162/1 164/163/1 162/164/1 +f 165/165/2 166/166/2 168/167/2 167/168/2 +f 169/169/1 171/170/1 172/171/1 170/172/1 +f 173/173/2 174/174/2 176/175/2 175/176/2 +f 177/177/1 179/178/1 180/179/1 178/180/1 +f 181/181/2 182/182/2 184/183/2 183/184/2 +f 185/185/1 187/186/1 188/187/1 186/188/1 +f 189/189/2 190/190/2 192/191/2 191/192/2 +f 193/193/1 195/194/1 196/195/1 194/196/1 +f 197/197/2 198/198/2 200/199/2 199/200/2 +f 201/201/1 203/202/1 204/203/1 202/204/1 +f 205/205/2 206/206/2 208/207/2 207/208/2 +f 209/209/1 211/210/1 212/211/1 210/212/1 +f 213/213/2 214/214/2 216/215/2 215/216/2 +f 217/217/1 219/218/1 220/219/1 218/220/1 +f 221/221/2 222/222/2 224/223/2 223/224/2 +f 225/225/1 227/226/1 228/227/1 226/228/1 +f 229/229/2 230/230/2 232/231/2 231/232/2 +f 233/233/1 235/234/1 236/235/1 234/236/1 +f 237/237/2 238/238/2 240/239/2 239/240/2 +f 241/241/1 243/242/1 244/243/1 242/244/1 +f 245/245/2 246/246/2 248/247/2 247/248/2 +f 249/249/1 251/250/1 252/251/1 250/252/1 +f 253/253/2 254/254/2 256/255/2 255/256/2 +f 257/257/1 259/258/1 260/259/1 258/260/1 +f 261/261/2 262/262/2 264/263/2 263/264/2 +f 265/265/1 267/266/1 268/267/1 266/268/1 +f 269/269/2 270/270/2 272/271/2 271/272/2 +f 273/273/1 275/274/1 276/275/1 274/276/1 +f 277/277/2 278/278/2 280/279/2 279/280/2 +f 281/281/1 283/282/1 284/283/1 282/284/1 +f 285/285/2 286/286/2 288/287/2 287/288/2 +f 289/289/1 291/290/1 292/291/1 290/292/1 +f 293/293/2 294/294/2 296/295/2 295/296/2 +f 297/297/1 299/298/1 300/299/1 298/300/1 +f 301/301/2 302/302/2 304/303/2 303/304/2 +f 305/305/1 307/306/1 308/307/1 306/308/1 +f 309/309/2 310/310/2 312/311/2 311/312/2 +f 313/313/1 315/314/1 316/315/1 314/316/1 +f 317/317/2 318/318/2 320/319/2 319/320/2 +f 321/321/1 323/322/1 324/323/1 322/324/1 +f 325/325/2 326/326/2 328/327/2 327/328/2 +f 329/329/1 331/330/1 332/331/1 330/332/1 +f 333/333/2 334/334/2 336/335/2 335/336/2 +f 337/337/1 339/338/1 340/339/1 338/340/1 +f 341/341/2 342/342/2 344/343/2 343/344/2 +f 345/345/1 347/346/1 348/347/1 346/348/1 +f 349/349/2 350/350/2 352/351/2 351/352/2 +f 353/353/1 355/354/1 356/355/1 354/356/1 +f 357/357/2 358/358/2 360/359/2 359/360/2 +f 361/361/1 363/362/1 364/363/1 362/364/1 +f 365/365/2 366/366/2 368/367/2 367/368/2 +f 369/369/1 371/370/1 372/371/1 370/372/1 +f 373/373/2 374/374/2 376/375/2 375/376/2 +f 377/377/1 379/378/1 380/379/1 378/380/1 +f 381/381/2 382/382/2 384/383/2 383/384/2 +f 385/385/1 387/386/1 388/387/1 386/388/1 +f 389/389/2 390/390/2 392/391/2 391/392/2 +f 393/393/1 395/394/1 396/395/1 394/396/1 +f 397/397/2 398/398/2 400/399/2 399/400/2 +f 401/401/1 403/402/1 404/403/1 402/404/1 +f 405/405/2 406/406/2 408/407/2 407/408/2 +f 409/409/1 411/410/1 412/411/1 410/412/1 +f 413/413/2 414/414/2 416/415/2 415/416/2 +f 417/417/1 419/418/1 420/419/1 418/420/1 +f 421/421/2 422/422/2 424/423/2 423/424/2 +f 425/425/1 427/426/1 428/427/1 426/428/1 +f 429/429/2 430/430/2 432/431/2 431/432/2 +f 433/433/1 435/434/1 436/435/1 434/436/1 +f 437/437/2 438/438/2 440/439/2 439/440/2 +f 441/441/1 443/442/1 444/443/1 442/444/1 +f 445/445/2 446/446/2 448/447/2 447/448/2 diff --git a/mods/ITEMS/mcl_bows/rocket.lua b/mods/ITEMS/mcl_bows/rocket.lua new file mode 100644 index 000000000..e71c0c122 --- /dev/null +++ b/mods/ITEMS/mcl_bows/rocket.lua @@ -0,0 +1,709 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math +local vector = vector + +-- Time in seconds after which a stuck arrow is deleted +local ARROW_TIMEOUT = 1 +-- Time after which stuck arrow is rechecked for being stuck +local STUCK_RECHECK_TIME = 0.1 + +--local GRAVITY = 9.81 + +local YAW_OFFSET = -math.pi/2 + +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local function damage_explosion(self, damagemulitplier) + if self._harmless then return end + local p = self.object:get_pos() + if not p then return end + mcl_explosions.explode(p, 3, {}) + local objects = minetest.get_objects_inside_radius(p, 8) + 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 + 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()) + end + end +end + +local function particle_explosion(self) + local particle_pattern = math.random(1, 3) + local fpitch + --local true_type + local type = math.random(1, 2) + local size = math.random(1, 3) + local colors = {"red", "yellow", "blue", "green", "white"} + local this_colors = {colors[math.random(#colors)], colors[math.random(#colors)], colors[math.random(#colors)]} + + if size == 1 then + fpitch = math.random(200, 300) + elseif size == 2 then + fpitch = math.random(100, 130) + else + fpitch = math.random(60, 70) + end + + --[[if type == 1 then + true_type = "Popper" + else + true_type = "Floof" + end]] + + if type == 1 then + minetest.sound_play("mcl_bows_firework", { + pos = self.object:get_pos(), + max_hear_distance = 100, + gain = 3.0, + pitch = fpitch/100 + }, true) + else + minetest.sound_play("mcl_bows_firework_soft", { + pos = self.object:get_pos(), + max_hear_distance = 100, + gain = 4.0, + pitch = fpitch/100 + }, true) + end + + if particle_pattern == 1 then + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-7 * size,-7 * size,-7 * size), + maxvel = vector.new(7 * size,7 * size,7 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-2 * size,-2 * size,-2 * size), + maxvel = vector.new(2 * size,2 * size,2 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 100 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-14 * size,-14 * size,-14 * size), + maxvel = vector.new(14 * size,14 * size,14 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + elseif particle_pattern == 2 then + + minetest.add_particlespawner({ + amount = 240 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-5 * size,-5 * size,-5 * size), + maxvel = vector.new(5 * size,5 * size,5 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 500 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-2 * size,-2 * size,-2 * size), + maxvel = vector.new(2 * size,2 * size,2 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 350 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-3 * size,-3 * size,-3 * size), + maxvel = vector.new(3 * size,3 * size,3 * size), + minexptime = .6 * size / 2, + maxexptime = .9 * size / 2, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + elseif particle_pattern == 3 then + + minetest.add_particlespawner({ + amount = 400 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-6 * size,-4 * size,-6 * size), + maxvel = vector.new(6 * size,4 * size,6 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[1]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 120 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-8 * size,6 * size,-8 * size), + maxvel = vector.new(8 * size,6 * size,8 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[2]..".png", + glow = 14, + }) + minetest.add_particlespawner({ + amount = 130 * size, + time = 0.0001, + minpos = self.object:get_pos(), + maxpos = self.object:get_pos(), + minvel = vector.new(-3 * size,3 * size,-3 * size), + maxvel = vector.new(3 * size,3 * size,3 * size), + minexptime = .6 * size, + maxexptime = .9 * size, + minsize = 2 * size, + maxsize = 3 * size, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_firework_"..this_colors[3]..".png", + glow = 14, + }) + end + + return size + +end + +local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") +local mod_button = minetest.get_modpath("mesecons_button") +local mod_target = minetest.get_modpath("mcl_target") +local enable_pvp = minetest.settings:get_bool("enable_pvp") + +minetest.register_craftitem("mcl_bows:rocket", { + description = S("Arrow"), + _tt_help = S("Ammunition").."\n"..S("Damage from bow: 1-10").."\n"..S("Damage from dispenser: 3"), + _doc_items_longdesc = S("Arrows are ammunition for bows and dispensers.").."\n".. +S("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.").."\n".. +S("Arrows might get stuck on solid blocks and can be retrieved again. They are also capable of pushing wooden buttons."), + _doc_items_usagehelp = S("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."), + inventory_image = "mcl_bows_rocket.png", + groups = { ammo=1, ammo_crossbow=1, ammo_bow_regular=1 }, + _on_dispense = function(itemstack, dispenserpos, droppos, dropnode, dropdir) + -- Shoot arrow + local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) + local yaw = math.atan2(dropdir.z, dropdir.x) + YAW_OFFSET + mcl_bows.shoot_arrow(itemstack:get_name(), shootpos, dropdir, yaw, nil, 19, 3) + end, +}) + + + +local ARROW_ENTITY={ + physical = true, + pointable = false, + visual = "mesh", + mesh = "mcl_bows_rocket.obj", + visual_size = {x=2.5, y=2.5}, + textures = {"mcl_bows_rocket.png"}, + collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, + collide_with_objects = false, + _fire_damage_resistant = true, + + _lastpos={}, + _startpos=nil, + _damage=1, -- Damage on impact + _is_critical=false, -- Whether this arrow would deal critical damage + _stuck=false, -- Whether arrow is stuck + _fuse=nil,-- Amount of time (in seconds) the arrow has been stuck so far + _fuserechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow + _stuckin=nil, --Position of node in which arow is stuck. + _shooter=nil, -- ObjectRef of player or mob who shot it + _is_arrow = true, + + _viscosity=0, -- Viscosity of node the arrow is currently in + _deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession +} + +-- Destroy arrow entity self at pos and drops it as an item +local function spawn_item(self, pos) + if not minetest.is_creative_enabled("") then + local item = minetest.add_item(pos, "mcl_bows:rocket") + item:set_velocity({x=0, y=0, z=0}) + item:set_yaw(self.object:get_yaw()) + end + mcl_burning.extinguish(self.object) + self.object:remove() +end + +local function damage_particles(pos, is_critical) + if is_critical then + minetest.add_particlespawner({ + amount = 15, + time = 0.1, + minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, + maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, + minvel = {x=-0.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + }) + end +end + +function ARROW_ENTITY.on_step(self, dtime) + mcl_burning.tick(self.object, dtime, self) + -- mcl_burning.tick may remove object immediately + if not self.object:get_pos() then return end + + self._time_in_air = self._time_in_air + .001 + + + local pos = self.object:get_pos() + local dpos = table.copy(pos) -- digital pos + dpos = vector.round(dpos) + local node = minetest.get_node(dpos) + + if not self._fuse then + self._fuse = 0 + end + if not self._fuserechecktimer then + self._fuserechecktimer = 0 + end + + self._fuse = self._fuse + dtime + self._fuserechecktimer = self._fuserechecktimer + dtime + + if self._fuse > ARROW_TIMEOUT then + self._stuck = true + end + if self._stuck then + if self._fuse > ARROW_TIMEOUT then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + -- Drop arrow as item when it is no longer stuck + -- FIXME: Arrows are a bit slow to react and continue to float in mid air for a few seconds. + if self._fuserechecktimer > STUCK_RECHECK_TIME then + local stuckin_def + if self._stuckin then + stuckin_def = minetest.registered_nodes[minetest.get_node(self._stuckin).name] + end + -- TODO: In MC, arrow just falls down without turning into an item + if stuckin_def and stuckin_def.walkable == false then + spawn_item(self, pos) + return + end + self._fuserechecktimer = 0 + end + -- Pickup arrow if player is nearby (not in Creative Mode) + local objects = minetest.get_objects_inside_radius(pos, 1) + for _,obj in ipairs(objects) do + if obj:is_player() then + if self._collectable and not minetest.is_creative_enabled(obj:get_player_name()) then + if obj:get_inventory():room_for_item("main", "mcl_bows:rocket") then + obj:get_inventory():add_item("main", "mcl_bows:rocket") + minetest.sound_play("item_drop_pickup", { + pos = pos, + max_hear_distance = 16, + gain = 1.0, + }, true) + end + end + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + + -- Check for object "collision". Done every tick (hopefully this is not too stressing) + else + + if self._in_player == false then + minetest.add_particlespawner({ + amount = 1, + time = .0001, + minpos = pos, + maxpos = pos, + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_bows_rocket_particle.png", + glow = 1, + }) + end + -- We just check for any hurtable objects nearby. + -- The radius of 3 is fairly liberal, but anything lower than than will cause + -- arrow to hilariously go through mobs often. + -- TODO: Implement an ACTUAL collision detection (engine support needed). + local objs = minetest.get_objects_inside_radius(pos, 1.5) + local closest_object + local closest_distance + + if self._deflection_cooloff > 0 then + self._deflection_cooloff = self._deflection_cooloff - dtime + end + + -- Iterate through all objects and remember the closest attackable object + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then + ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end + end + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end + end + end + end + + + -- If an attackable object was found, we will damage the closest one only + + if closest_object then + local obj = closest_object + local is_player = obj:is_player() + local lua = obj:get_luaentity() + if obj == self._shooter and self._time_in_air > 1.02 or obj ~= self._shooter and (is_player or (lua and (lua.is_mob or lua._hittable_by_projectile))) then + if obj:get_hp() > 0 then + -- Check if there is no solid node between arrow and object + local ray = minetest.raycast(self.object:get_pos(), obj:get_pos(), true) + for pointed_thing in ray do + if pointed_thing.type == "object" and pointed_thing.ref == closest_object then + -- Target reached! We can proceed now. + break + elseif pointed_thing.type == "node" then + local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name + local def = minetest.registered_nodes[nn] + if (not def) or def.walkable then + -- There's a node in the way. Delete arrow without damage + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + end + + -- Punch target object but avoid hurting enderman. + if not lua or lua.name ~= "mobs_mc:enderman" then + if self._in_player == false then + damage_particles(self.object:get_pos(), self._is_critical) + end + if mcl_burning.is_burning(self.object) then + mcl_burning.set_on_fire(obj, 5) + end + if self._in_player == false then + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=self._damage}, + }, self.object:get_velocity()) + if obj:is_player() then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + mcl_burning.extinguish(self.object) + self.object:remove() + end + end + end + + + if is_player then + if self._shooter and self._shooter:is_player() and self._in_player == false then + -- “Ding” sound for hitting another player + minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) + end + end + + if lua then + local entity_name = lua.name + -- Achievement for hitting skeleton, wither skeleton or stray (TODO) with an arrow at least 50 meters away + -- NOTE: Range has been reduced because mobs unload much earlier than that ... >_> + -- TODO: This achievement should be given for the kill, not just a hit + if self._shooter and self._shooter:is_player() and vector.distance(pos, self._startpos) >= 20 then + if mod_awards and (entity_name == "mobs_mc:skeleton" or entity_name == "mobs_mc:stray" or entity_name == "mobs_mc:witherskeleton") then + awards.unlock(self._shooter:get_player_name(), "mcl:snipeSkeleton") + end + end + end + if self._in_player == false then + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + end + end + if not obj:is_player() then + mcl_burning.extinguish(self.object) + if self._piercing == 0 then + local eploded_particle = particle_explosion(self) + damage_explosion(self, eploded_particle * 17) + self.object:remove() + end + end + return + end + end + end + + -- Check for node collision + if self._lastpos.x~=nil and not self._stuck then + local def = minetest.registered_nodes[node.name] + local vel = self.object:get_velocity() + -- Arrow has stopped in one axis, so it probably hit something. + -- This detection is a bit clunky, but sadly, MT does not offer a direct collision detection for us. :-( + if (math.abs(vel.x) < 0.0001) or (math.abs(vel.z) < 0.0001) or (math.abs(vel.y) < 0.00001) then + -- Check for the node to which the arrow is pointing + local dir + if math.abs(vel.y) < 0.00001 then + if self._lastpos.y < pos.y then + dir = {x=0, y=1, z=0} + else + dir = {x=0, y=-1, z=0} + end + else + dir = minetest.facedir_to_dir(minetest.dir_to_facedir(minetest.yaw_to_dir(self.object:get_yaw()-YAW_OFFSET))) + end + self._stuckin = vector.add(dpos, dir) + local snode = minetest.get_node(self._stuckin) + local sdef = minetest.registered_nodes[snode.name] + + -- If node is non-walkable, unknown or ignore, don't make arrow stuck. + -- This causes a deflection in the engine. + if not sdef or sdef.walkable == false or snode.name == "ignore" then + self._stuckin = nil + if self._deflection_cooloff <= 0 then + -- Lose 1/3 of velocity on deflection + local newvel = vector.multiply(vel, 0.6667) + + self.object:set_velocity(newvel) + -- Reset deflection cooloff timer to prevent many deflections happening in quick succession + self._deflection_cooloff = 1.0 + end + else + + -- Node was walkable, make arrow stuck + self._stuck = true + self._fuserechecktimer = 0 + + self.object:set_velocity({x=0, y=0, z=0}) + self.object:set_acceleration({x=0, y=0, z=0}) + + minetest.sound_play({name="mcl_bows_hit_other", gain=0.3}, {pos=self.object:get_pos(), max_hear_distance=16}, true) + + if mcl_burning.is_burning(self.object) and snode.name == "mcl_tnt:tnt" then + tnt.ignite(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 + end + + -- Push the button! Push, push, push the button! + if mod_button and minetest.get_item_group(node.name, "button") > 0 and minetest.get_item_group(node.name, "button_push_by_arrow") == 1 then + local bdir = minetest.wallmounted_to_dir(node.param2) + -- Check the button orientation + if vector.equals(vector.add(dpos, bdir), self._stuckin) then + mesecon.push_button(dpos, node) + end + end + end + elseif (def and def.liquidtype ~= "none") then + -- Slow down arrow in liquids + local v = def.liquid_viscosity + if not v then + v = 0 + end + --local old_v = self._viscosity + self._viscosity = v + local vpenalty = math.max(0.1, 0.98 - 0.1 * v) + if math.abs(vel.x) > 0.001 then + vel.x = vel.x * vpenalty + end + if math.abs(vel.z) > 0.001 then + vel.z = vel.z * vpenalty + end + self.object:set_velocity(vel) + end + end + + -- Update yaw + if not self._stuck then + local vel = self.object:get_velocity() + local yaw = minetest.dir_to_yaw(vel)+YAW_OFFSET + local pitch = dir_to_pitch(vel) + self.object:set_rotation({ x = 0, y = yaw, z = pitch }) + end + + -- Update internal variable + self._lastpos={x=pos.x, y=pos.y, z=pos.z} +end + +-- Force recheck of stuck arrows when punched. +-- Otherwise, punching has no effect. +function ARROW_ENTITY.on_punch(self) + if self._stuck then + self._fuserechecktimer = STUCK_RECHECK_TIME + end +end + +function ARROW_ENTITY.get_staticdata(self) + local out = { + lastpos = self._lastpos, + startpos = self._startpos, + damage = self._damage, + is_critical = self._is_critical, + stuck = self._stuck, + stuckin = self._stuckin, + } + if self._stuck then + -- If _fuse is missing for some reason, assume the maximum + if not self._fuse then + self._fuse = ARROW_TIMEOUT + end + out.stuckstarttime = minetest.get_gametime() - self._fuse + end + if self._shooter and self._shooter:is_player() then + out.shootername = self._shooter:get_player_name() + end + return minetest.serialize(out) +end + +function ARROW_ENTITY.on_activate(self, staticdata, dtime_s) + self._time_in_air = 1.0 + self._in_player = false + local data = minetest.deserialize(staticdata) + if data then + self._stuck = data.stuck + if data.stuck then + if data.stuckstarttime then + -- First, check if the stuck arrow is aleady past its life timer. + -- If yes, delete it. + self._fuse = minetest.get_gametime() - data.stuckstarttime + if self._fuse > ARROW_TIMEOUT then + mcl_burning.extinguish(self.object) + self.object:remove() + return + end + end + + self._fuse = 2 + -- Perform a stuck recheck on the next step. + self._fuserechecktimer = STUCK_RECHECK_TIME + + self._stuckin = data.stuckin + end + + -- Get the remaining arrow state + self._lastpos = data.lastpos + self._startpos = data.startpos + self._damage = data.damage + self._is_critical = data.is_critical + if data.shootername then + local shooter = minetest.get_player_by_name(data.shootername) + if shooter and shooter:is_player() then + self._shooter = shooter + end + end + end + self.object:set_armor_groups({ immortal = 1 }) +end + +minetest.register_entity("mcl_bows:rocket_entity", ARROW_ENTITY) + +if minetest.get_modpath("mcl_core") and minetest.get_modpath("mcl_mobitems") then + minetest.register_craft({ + output = "mcl_bows:rocket 1", + recipe = { + {"mcl_core:paper"}, + {"mcl_fireworks:rocket_2"}, + {"mcl_bows:arrow"}, + } + }) +end + +if minetest.get_modpath("doc_identifier") then + doc.sub.identifier.register_object("mcl_bows:rocket_entity", "craftitems", "mcl_bows:rocket") +end diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg new file mode 100644 index 000000000..f4f81b307 Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_0.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_1.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_1.ogg new file mode 100644 index 000000000..c8c06b4fa Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_1.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_2.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_2.ogg new file mode 100644 index 000000000..4ddd20c42 Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_drawback_2.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg new file mode 100644 index 000000000..02d2fd1af Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_load.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg new file mode 100644 index 000000000..a7d7b69d1 Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_crossbow_shoot.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework.ogg new file mode 100644 index 000000000..ea9a4c4be Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework.ogg differ diff --git a/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg b/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg new file mode 100644 index 000000000..8b2e7bc5b Binary files /dev/null and b/mods/ITEMS/mcl_bows/sounds/mcl_bows_firework_soft.ogg differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png deleted file mode 100644 index 278d910f2..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png deleted file mode 100644 index 18164e90a..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_inv.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_inv.png deleted file mode 100644 index 8635d28a1..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png deleted file mode 100644 index 2ca26c58a..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_overlay.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_bow.png deleted file mode 100644 index 7d695bc93..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_0.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_0.png deleted file mode 100644 index 8bb41ea44..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_0.png and /dev/null differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_1.png b/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_1.png deleted file mode 100644 index f85304e40..000000000 Binary files a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/init.lua b/mods/ITEMS/mcl_brewing/init.lua index 7725acdfd..9c6879430 100644 --- a/mods/ITEMS/mcl_brewing/init.lua +++ b/mods/ITEMS/mcl_brewing/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_brewing") +local S = minetest.get_translator(minetest.get_current_modname()) local function active_brewing_formspec(fuel_percent, brew_percent) @@ -10,9 +10,9 @@ local function active_brewing_formspec(fuel_percent, brew_percent) mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.75;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.75,9,1).. - "list[current_name;fuel;0.5,1.75;1,1;]".. + "list[context;fuel;0.5,1.75;1,1;]".. mcl_formspec.get_itemslot_bg(0.5,1.75,1,1).."image[0.5,1.75;1,1;mcl_brewing_fuel_bg.png]".. - "list[current_name;input;2.75,0.5;1,1;]".. + "list[context;input;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. "list[context;stand;4.5,2.5;1,1;]".. mcl_formspec.get_itemslot_bg(4.5,2.5,1,1).."image[4.5,2.5;1,1;mcl_brewing_bottle_bg.png]".. @@ -28,8 +28,8 @@ local function active_brewing_formspec(fuel_percent, brew_percent) (brew_percent)..":mcl_brewing_bubbles_active.png]".. "listring[current_player;main]".. - "listring[current_name;fuel]".. - "listring[current_name;input]".. + "listring[context;fuel]".. + "listring[context;input]".. "listring[context;stand]" end @@ -41,9 +41,9 @@ local brewing_formspec = "size[9,8.75]".. mcl_formspec.get_itemslot_bg(0,4.5,9,3).. "list[current_player;main;0,7.75;9,1;]".. mcl_formspec.get_itemslot_bg(0,7.75,9,1).. - "list[current_name;fuel;0.5,1.75;1,1;]".. + "list[context;fuel;0.5,1.75;1,1;]".. mcl_formspec.get_itemslot_bg(0.5,1.75,1,1).."image[0.5,1.75;1,1;mcl_brewing_fuel_bg.png]".. - "list[current_name;input;2.75,0.5;1,1;]".. + "list[context;input;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. "list[context;stand;4.5,2.5;1,1;]".. mcl_formspec.get_itemslot_bg(4.5,2.5,1,1).."image[4.5,2.5;1,1;mcl_brewing_bottle_bg.png]".. @@ -56,19 +56,19 @@ local brewing_formspec = "size[9,8.75]".. "image[2.76,1.4;1,2.15;mcl_brewing_bubbles.png]".. "listring[current_player;main]".. - "listring[current_name;fuel]".. - "listring[current_name;input]".. + "listring[context;fuel]".. + "listring[context;input]".. "listring[context;stand]" -local function swap_node(pos, name) +--[[local function swap_node(pos, name) local node = minetest.get_node(pos) if node.name == name then return end node.name = name minetest.swap_node(pos, node) -end +end]] local function brewable(inv) @@ -110,12 +110,13 @@ local function brewing_stand_timer(pos, elapsed) local BREW_TIME = 20 -- all brews brew the same local BURN_TIME = BREW_TIME * 10 - local input_item = meta:get_string("input_item") or "" + --local input_item = meta:get_string("input_item") or "" local stand_timer = meta:get_float("stand_timer") or 0 local fuel = meta:get_float("fuel") or 0 local inv = meta:get_inventory() - local input_list, stand_list, fuel_list, brew_output, d + --local input_list, stand_list, fuel_list + local brew_output, d local input_count, fuel_name, fuel_count, formspec, fuel_percent, brew_percent local update = true @@ -124,9 +125,9 @@ local function brewing_stand_timer(pos, elapsed) update = false - input_list = inv:get_list("input") - stand_list = inv:get_list("stand") - fuel_list = inv:get_list("fuel") + --input_list = inv:get_list("input") + --stand_list = inv:get_list("stand") + --fuel_list = inv:get_list("fuel") -- TODO ... fix this. Goal is to reset the process if the stand changes -- for i=1, inv:get_size("stand", i) do -- reset the process due to change @@ -237,7 +238,7 @@ local function brewing_stand_timer(pos, elapsed) end -local function allow_metadata_inventory_put(pos, listname, index, stack, player) +--[[local function allow_metadata_inventory_put(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) @@ -273,7 +274,7 @@ local function allow_metadata_inventory_put(pos, listname, index, stack, player) elseif listname == "stand" then return 0 end -end +end]] -- Drop input items of brewing_stand at pos with metadata meta @@ -315,14 +316,16 @@ local doc_string = S("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.").."\n".. S("Different combinations of brewing materials and liquids will give different results. Try to experiment!") -local tiles = {"mcl_brewing_top.png", --top - "mcl_brewing_base.png", --bottom - "mcl_brewing_side.png", --right - "mcl_brewing_side.png", --left - "mcl_brewing_side.png", --back - "mcl_brewing_side.png^[transformFX"} --front +local tiles = { + "mcl_brewing_top.png", --top + "mcl_brewing_base.png", --bottom + "mcl_brewing_side.png", --right + "mcl_brewing_side.png", --left + "mcl_brewing_side.png", --back + "mcl_brewing_side.png^[transformFX", --front +} -local allow_put = function(pos, listname, index, stack, player) +local function allow_put(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) @@ -332,7 +335,7 @@ local allow_put = function(pos, listname, index, stack, player) end end -local on_put = function(pos, listname, index, stack, player) +local function on_put(pos, listname, index, stack, player) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local str = "" @@ -349,23 +352,26 @@ local on_put = function(pos, listname, index, stack, player) --some code here to enforce only potions getting placed on stands end -local after_dig = function(pos, oldnode, oldmetadata, digger) +--[[local function after_dig(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) meta:from_table(oldmetadata) drop_brewing_stand_items(pos, meta) -end +end]] -local on_destruct = function(pos) +local function on_destruct(pos) local meta = minetest.get_meta(pos) drop_brewing_stand_items(pos, meta) end -local allow_take = function(pos, listname, index, stack, player) +local function allow_take(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) return 0 else + if listname == "stand" then + awards.unlock(name, "mcl:localBrewery") + end return stack:get_count() end end @@ -378,6 +384,7 @@ minetest.register_node("mcl_brewing:stand_000", { _tt_help = S("Brew Potions"), groups = {pickaxey=1, brewitem=1 }, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -444,6 +451,7 @@ minetest.register_node("mcl_brewing:stand_100", { _tt_help = S("Brew Potions"), groups = {pickaxey=1, 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", paramtype = "light", sunlight_propagates = true, @@ -488,7 +496,6 @@ minetest.register_node("mcl_brewing:stand_100", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -498,7 +505,6 @@ minetest.register_node("mcl_brewing:stand_100", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -506,16 +512,17 @@ minetest.register_node("mcl_brewing:stand_100", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -561,7 +568,6 @@ minetest.register_node("mcl_brewing:stand_010", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -571,7 +577,6 @@ minetest.register_node("mcl_brewing:stand_010", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -579,16 +584,17 @@ minetest.register_node("mcl_brewing:stand_010", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -598,7 +604,6 @@ minetest.register_node("mcl_brewing:stand_001", { node_box = { type = "fixed", fixed = { - {-1/16, -5/16, -1/16, 1/16, 8/16, 1/16}, -- heat plume { 2/16, -8/16, -8/16, 8/16, -6/16, -2/16}, -- base {-8/16, -8/16, -8/16, -2/16, -6/16, -2/16}, -- base @@ -630,7 +635,6 @@ minetest.register_node("mcl_brewing:stand_001", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -640,7 +644,6 @@ minetest.register_node("mcl_brewing:stand_001", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -648,16 +651,17 @@ minetest.register_node("mcl_brewing:stand_001", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -667,7 +671,6 @@ minetest.register_node("mcl_brewing:stand_110", { node_box = { type = "fixed", fixed = { - {-1/16, -5/16, -1/16, 1/16, 8/16, 1/16}, -- heat plume { 2/16, -8/16, -8/16, 8/16, -6/16, -2/16}, -- base {-8/16, -8/16, -8/16, -2/16, -6/16, -2/16}, -- base @@ -709,7 +712,6 @@ minetest.register_node("mcl_brewing:stand_110", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -719,7 +721,6 @@ minetest.register_node("mcl_brewing:stand_110", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -727,16 +728,17 @@ minetest.register_node("mcl_brewing:stand_110", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -746,7 +748,6 @@ minetest.register_node("mcl_brewing:stand_101", { node_box = { type = "fixed", fixed = { - {-1/16, -5/16, -1/16, 1/16, 8/16, 1/16}, -- heat plume { 2/16, -8/16, -8/16, 8/16, -6/16, -2/16}, -- base {-8/16, -8/16, -8/16, -2/16, -6/16, -2/16}, -- base @@ -784,7 +785,6 @@ minetest.register_node("mcl_brewing:stand_101", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -794,7 +794,6 @@ minetest.register_node("mcl_brewing:stand_101", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -802,16 +801,17 @@ minetest.register_node("mcl_brewing:stand_101", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -821,7 +821,6 @@ minetest.register_node("mcl_brewing:stand_011", { node_box = { type = "fixed", fixed = { - {-1/16, -5/16, -1/16, 1/16, 8/16, 1/16}, -- heat plume { 2/16, -8/16, -8/16, 8/16, -6/16, -2/16}, -- base {-8/16, -8/16, -8/16, -2/16, -6/16, -2/16}, -- base @@ -859,7 +858,6 @@ minetest.register_node("mcl_brewing:stand_011", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -869,7 +867,6 @@ minetest.register_node("mcl_brewing:stand_011", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -877,16 +874,17 @@ minetest.register_node("mcl_brewing:stand_011", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) + 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}, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, drop = "mcl_brewing:stand", paramtype = "light", sunlight_propagates = true, @@ -896,7 +894,6 @@ minetest.register_node("mcl_brewing:stand_111", { node_box = { type = "fixed", fixed = { - {-1/16, -5/16, -1/16, 1/16, 8/16, 1/16}, -- heat plume { 2/16, -8/16, -8/16, 8/16, -6/16, -2/16}, -- base {-8/16, -8/16, -8/16, -2/16, -6/16, -2/16}, -- base @@ -941,7 +938,6 @@ minetest.register_node("mcl_brewing:stand_111", { allow_metadata_inventory_put = allow_put, on_metadata_inventory_put = on_put, on_metadata_inventory_take = on_put, - on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() @@ -951,7 +947,6 @@ minetest.register_node("mcl_brewing:stand_111", { local form = brewing_formspec meta:set_string("formspec", form) end, - on_receive_fields = function(pos, formname, fields, sender) local sender_name = sender:get_player_name() if minetest.is_protected(pos, sender_name) then @@ -959,7 +954,6 @@ minetest.register_node("mcl_brewing:stand_111", { return end end, - on_timer = brewing_stand_timer, on_rotate = on_rotate, }) @@ -968,7 +962,7 @@ minetest.register_craft({ output = "mcl_brewing:stand_000", recipe = { { "", "mcl_mobitems:blaze_rod", "" }, - { "mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble" }, + { "group:cobble", "group:cobble", "group:cobble" }, } }) diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr index 232026fba..6137edf55 100644 --- a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.fr.tr @@ -5,6 +5,6 @@ To use a brewing stand, rightclick it.=Pour utiliser un alambic, faites un clic To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Pour distiller, vous avez besoin de poudre de blaze comme carburant, d'un ingrédient à distiller et d'au moins 1 bouteille en verre remplie d'un liquide. Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Placez la poudre de blaze dans l'emplacement de gauche, l'ingrédient à distiller dans l'emplacement du milieu et 1 à 3 bouteilles dans les emplacements restantes. 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.=Lorsque vous avez trouvé une bonne combinaison, la distillation commencera automatiquement et de la vapeur commencera à apparaître, consommant le carburant et l'ingrédient à distiller. Les potions seront bientôt prêtes. -Different combinations of brewing materials and liquids will give different results. Try to experiment!=Différentes combinaisons d'ingrédients et de liquides donneront des résultats différents. Essayez d'expérimenter! -The stand allows you to brew potions!=L'alambic permet de produire des potions! +Different combinations of brewing materials and liquids will give different results. Try to experiment!=Différentes combinaisons d'ingrédients et de liquides donneront des résultats différents. Essayez d'expérimenter ! +The stand allows you to brew potions!=L'alambic permet de produire des potions ! Brew Potions=Potions diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr new file mode 100644 index 000000000..684a99b8f --- /dev/null +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.ja.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_brewing +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.=良い組み合わせであれば、自動的に醸造が開始され蒸気が発生し、燃料と醸造材料を消費していきます。やがてポーションが完成するでしょう。 +Different combinations of brewing materials and liquids will give different results. Try to experiment!=醸造材料と液体の組み合わせが異なれば、得られる結果も異なります。ぜひ試してみてください! +The stand allows you to brew potions!=このスタンドは、あなたのポーション醸造を許す! +Brew Potions=ポーションの醸造 diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pl.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pl.tr new file mode 100644 index 000000000..cdcc1f887 --- /dev/null +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_brewing +Brewing Stand=Statyw alchemiczny +Inventory=Ekwipunek +To use a brewing stand, rightclick it.=Aby użyć statywu alchemicznego kliknij go prawym przyciskiem myszy. +To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Aby warzyć mikstury potrzebujesz płomiennego proszku, materiału do warzenia i przynajmniej jedną butelkę wypełnioną płynem. +Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Wstaw płomienny proszek po lewej, materiał do warzenia w środku i 1-3 butelek w pozostałych. +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.=Kiedy znajdziesz odpowiednią kombinację, warzenie rozpocznie się automatycznie, pojawi się para, a paliwo i materiał zaczną się zużywać. Mikstury wkrótce będą gotowe. +Different combinations of brewing materials and liquids will give different results. Try to experiment!=Różne kombinacje materiałów i płynów dadzą inne rezultaty. Spróbuj poeksperymentować! +The stand allows you to brew potions!=Statyw pozwala na warzenie mikstur! +Brew Potions=Uwarz mikstury. diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pt_BR.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pt_BR.tr new file mode 100644 index 000000000..8209bf3ce --- /dev/null +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_brewing +Brewing Stand=Suporte de Fermentação +Inventory=Inventário +To use a brewing stand, rightclick it.=Para usar um suporte de fermentação, clique-o com o botão direito. +To brew, you need blaze powder as fuel, a brewing material and at least 1 glass bottle filled with a liquid.=Para fermentar, você precisa de Pó de Blaze como combutível, um material de fermentação e pelo menos 1 garrafa de vidro preenchida com líquido. +Place the blaze powder in the left slot, the brewing material in the middle slot and 1-3 bottles in the remaining slots.=Coloque o Pó de Blaze no espaço da esquerda, o material de fermentaçaõ no espaço do meio e 1-3 garrafas nos espaços restantes. +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.=Quando você encontrar uma boa combinação, a fermentação irá iniciar automaticamente e vapores começarão a aparecer, consumindo o combustível e o material de fermentação. A poção em breve estará pronta. +Different combinations of brewing materials and liquids will give different results. Try to experiment!=Diferentes combinações de materiais de fermentação e líquidos lhe darão diferentes resultados. Tente experimentar! +The stand allows you to brew potions!=O suporte permite que você produza poções. +Brew Potions=Produz Poções diff --git a/mods/ITEMS/mcl_brewing/locale/mcl_brewing.zh_TW.tr b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.zh_TW.tr new file mode 100644 index 000000000..da4b70890 --- /dev/null +++ b/mods/ITEMS/mcl_brewing/locale/mcl_brewing.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_brewing +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.=當你找到一個好的組合時,釀造將自動開始,並開始出現蒸汽,耗盡燃料和釀造材料。藥水很快就會準備好。 +Different combinations of brewing materials and liquids will give different results. Try to experiment!=釀造材料和液體的不同組合會產生不同的結果。試著去實驗吧! +The stand allows you to brew potions!=釀造台可以讓你釀製藥水! +Brew Potions=釀造藥水 diff --git a/mods/ITEMS/mcl_brewing/mod.conf b/mods/ITEMS/mcl_brewing/mod.conf index 28df9cf42..0f6217f09 100644 --- a/mods/ITEMS/mcl_brewing/mod.conf +++ b/mods/ITEMS/mcl_brewing/mod.conf @@ -1,3 +1,4 @@ name = mcl_brewing +author = bzoss depends = mcl_init, mcl_formspec, mcl_sounds, mcl_potions, mcl_mobitems -optional_depends = mcl_core, doc, screwdriver +optional_depends = mcl_core, doc, screwdriver, mesecons_mvps diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_base.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_base.png deleted file mode 100644 index 8831ffb9b..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_base.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bottle_bg.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bottle_bg.png deleted file mode 100644 index c0c4fd2be..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bottle_bg.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubble_sprite.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubble_sprite.png deleted file mode 100644 index 74447439e..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubble_sprite.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles.png deleted file mode 100644 index 780352408..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles_active.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles_active.png deleted file mode 100644 index 2a367807a..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_bubbles_active.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner.png deleted file mode 100644 index e2e8e8afe..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner_active.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner_active.png deleted file mode 100644 index 93655b673..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_burner_active.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_fuel_bg.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_fuel_bg.png deleted file mode 100644 index fd730958a..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_fuel_bg.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_inventory.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_inventory.png deleted file mode 100644 index 0ed2f4029..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_inventory.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_potion_bg.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_potion_bg.png deleted file mode 100644 index 818e41d4b..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_potion_bg.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_side.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_side.png deleted file mode 100644 index 057a405e0..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_top.png b/mods/ITEMS/mcl_brewing/textures/mcl_brewing_top.png deleted file mode 100644 index 81e000053..000000000 Binary files a/mods/ITEMS/mcl_brewing/textures/mcl_brewing_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_buckets/API.md b/mods/ITEMS/mcl_buckets/API.md new file mode 100644 index 000000000..94ec48de5 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/API.md @@ -0,0 +1,54 @@ +# mcl_buckets +Add an API to register buckets to mcl + +## mcl_buckets.register_liquid(def) + +Register a new liquid +Accept folowing params: +* source_place: a string or function. + * string: name of the node to place + * function(pos): will returns name of the node to place with pos being the placement position +* source_take: table of liquid source node names to take +* bucketname: itemstring of the new bucket item +* inventory_image: texture of the new bucket item (ignored if itemname == nil) +* name: user-visible bucket description +* longdesc: long explanatory description (for help) +* usagehelp: short usage explanation (for help) +* tt_help: very short tooltip help +* extra_check(pos, placer): (optional) function(pos) +* groups: optional list of item groups + + +**Usage exemple:** +```lua +mcl_buckets.register_liquid({ + bucketname = "dummy:bucket_dummy", + --source_place = "dummy:dummy_source", + source_place = function(pos) + if condition then + return "dummy:dummy_source" + else + return "dummy:dummy_source_nether" + end + end, + source_take = {"dummy:dummy_source"}, + inventory_image = "bucket_dummy.png", + name = S("Dummy liquid Bucket"), + longdesc = S("This bucket is filled with a dummy liquid."), + usagehelp = S("Place it to empty the bucket and create a dummy liquid source."), + tt_help = S("Places a dummy liquid source"), + extra_check = function(pos, placer) + --pos = pos where the liquid should be placed + --placer people who tried to place the bucket (can be nil) + + --no liquid node will be placed + --the bucket will not be emptied + --return false, false + + --liquid node will be placed + --the bucket will be emptied + return true, true + end, + groups = { dummy_group = 123 }, +}) +``` \ No newline at end of file diff --git a/mods/ITEMS/mcl_buckets/README.md b/mods/ITEMS/mcl_buckets/README.md new file mode 100644 index 000000000..b783cc133 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/README.md @@ -0,0 +1,19 @@ +# MineClone2 Bucket (`mcl_bucket`) +Originally taken from Minetest Game, adapted for MineClone2. + +This mod add buckets to the game, including an API to register your own (see `API.md`). + +## License + +Copyright (C) 2011-2012 Kahrl + +Copyright (C) 2011-2012 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +http://www.gnu.org/licenses/lgpl-2.1.html + + diff --git a/mods/ITEMS/mcl_buckets/README.txt b/mods/ITEMS/mcl_buckets/README.txt deleted file mode 100644 index 06862d589..000000000 --- a/mods/ITEMS/mcl_buckets/README.txt +++ /dev/null @@ -1,16 +0,0 @@ -Bucket mod. -Originally taken from Minetest Game, adapted for MineClone 2. - -License of source code: ------------------------ -Copyright (C) 2011-2012 Kahrl -Copyright (C) 2011-2012 celeron55, Perttu Ahola - -This program is free software; you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -http://www.gnu.org/licenses/lgpl-2.1.html - - diff --git a/mods/ITEMS/mcl_buckets/depends.txt b/mods/ITEMS/mcl_buckets/depends.txt deleted file mode 100644 index eb9bca8d8..000000000 --- a/mods/ITEMS/mcl_buckets/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_worlds -mcl_core? -mclx_core? -doc? diff --git a/mods/ITEMS/mcl_buckets/fishbuckets.lua b/mods/ITEMS/mcl_buckets/fishbuckets.lua new file mode 100644 index 000000000..185f72486 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/fishbuckets.lua @@ -0,0 +1,71 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Fish Buckets +local fish_names = { + ["cod"] = "Cod", + ["salmon"] = "Salmon", + ["tropical_fish"] = "Tropical Fish", + ["axolotl"] = "Axolotl", + --["pufferfish"] = "Pufferfish", --FIXME add pufferfish +} + +local fishbucket_prefix = "mcl_buckets:bucket_" + +local function on_place_fish(itemstack, placer, pointed_thing) + + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + 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) + local props = itemstack:get_meta():get_string("properties") + if props ~= "" then + o:set_properties(minetest.deserialize(props)) + end + local water = "mcl_core:water_source" + if n.name == "mclx_core:river_water_source" then + water = n.name + elseif n.name == "mclx_core:river_water_flowing" then + water = nil + end + if mcl_worlds.pos_to_dimension(pos) == "nether" then + water = nil + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + if water then + minetest.set_node(pos,{name = water}) + end + if not placer or not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack = ItemStack("mcl_buckets:bucket_empty") + end + end + end + return itemstack +end + +for techname, fishname in pairs(fish_names) do + minetest.register_craftitem(fishbucket_prefix .. techname, { + description = S("Bucket of @1", S(fishname)), + _doc_items_longdesc = S("This bucket is filled with water and @1.", S(fishname)), + _doc_items_usagehelp = S("Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.", S(fishname), S(fishname)), + _tt_help = S("Places a water source and a @1.", S(fishname)), + inventory_image = "mcl_buckets_" .. techname .. "_bucket.png", + stack_max = 1, + groups = {bucket = 1, fish_bucket = 1}, + liquids_pointable = false, + on_place = on_place_fish, + on_secondary_use = on_place_fish, + _on_dispense = function(stack, pos, droppos, dropnode, dropdir) + return on_place_fish(stack, nil, {above=droppos}) + end, + }) + + minetest.register_alias("mcl_fishing:bucket_" .. techname, "mcl_buckets:bucket_" .. techname) +end diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 3a06272b3..6aebbc759 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -1,187 +1,323 @@ -local S = minetest.get_translator("mcl_buckets") - --- Minetest 0.4 mod: bucket -- See README.txt for licensing and other information. +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local use_select_box = minetest.settings:get_bool("mcl_buckets_use_select_box", false) +-- Compatibility with old bucket mod minetest.register_alias("bucket:bucket_empty", "mcl_buckets:bucket_empty") minetest.register_alias("bucket:bucket_water", "mcl_buckets:bucket_water") minetest.register_alias("bucket:bucket_lava", "mcl_buckets:bucket_lava") local mod_doc = minetest.get_modpath("doc") local mod_mcl_core = minetest.get_modpath("mcl_core") -local mod_mclx_core = minetest.get_modpath("mclx_core") +--local mod_mclx_core = minetest.get_modpath("mclx_core") -if mod_mcl_core then - minetest.register_craft({ - output = 'mcl_buckets:bucket_empty 1', - recipe = { - {'mcl_core:iron_ingot', '', 'mcl_core:iron_ingot'}, - {'', 'mcl_core:iron_ingot', ''}, - } - }) -end +-- Localize some functions for faster access +local vector = vector +local math = math +local string = string -mcl_buckets = {} -mcl_buckets.liquids = {} +local raycast = minetest.raycast +local get_node = minetest.get_node +local set_node = minetest.set_node +local add_node = minetest.add_node +local add_item = minetest.add_item + +local registered_nodes = minetest.registered_nodes +local get_item_group = minetest.get_item_group +local is_creative_enabled = minetest.is_creative_enabled +local is_protected = minetest.is_protected +local record_protection_violation = minetest.record_protection_violation + + +minetest.register_craft({ + output = "mcl_buckets:bucket_empty 1", + recipe = { + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, + {"", "mcl_core:iron_ingot", ""}, + }, +}) + + +mcl_buckets = { + liquids = {}, + buckets = {}, +} -- Sound helper functions for placing and taking liquids -local sound_place = function(itemname, pos) - local def = minetest.registered_nodes[itemname] +local function sound_place(itemname, pos) + local def = registered_nodes[itemname] if def and def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end end -local sound_take = function(itemname, pos) - local def = minetest.registered_nodes[itemname] +local function sound_take(itemname, pos) + local def = registered_nodes[itemname] if def and def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end end -local place_liquid = function(pos, itemstring) - local fullness = minetest.registered_nodes[itemstring].liquid_range +local function place_liquid(pos, itemstring) sound_place(itemstring, pos) - minetest.add_node(pos, {name=itemstring, param2=fullness}) + set_node(pos, {name=itemstring}) end --- Register a new liquid --- source_place = a string or function. --- * string: name of the node to place --- * function(pos): will returns name of the node to place with pos being the placement position --- source_take = table of liquid source node names to take --- itemname = itemstring of the new bucket item (or nil if liquid is not takeable) --- inventory_image = texture of the new bucket item (ignored if itemname == nil) --- name = user-visible bucket description --- longdesc = long explanatory description (for help) --- usagehelp = short usage explanation (for help) --- tt_help = very short tooltip help --- extra_check(pos, placer) = optional function(pos) which can returns false to avoid placing the liquid. --- placer is object/player who is placing the liquid, can be nil --- groups = optional list of item groups --- --- This function can be called from any mod (which depends on this one) -function mcl_buckets.register_liquid(source_place, source_take, itemname, inventory_image, name, longdesc, usagehelp, tt_help, extra_check, groups) - for i=1, #source_take do - mcl_buckets.liquids[source_take[i]] = { - source_place = source_place, - source_take = source_take[i], - itemname = itemname, +local function give_bucket(new_bucket, itemstack, user) + local inv = user:get_inventory() + if is_creative_enabled(user:get_player_name()) then + --TODO: is a full bucket added if inv doesn't contain one? + return itemstack + else + if itemstack:get_count() == 1 then + return new_bucket + else + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + add_item(user:get_pos(), new_bucket) + end + itemstack:take_item() + return itemstack + end + end +end + +local pointable_sources = {} + +local function get_node_place(source_place, place_pos) + local node_place + if type(source_place) == "function" then + node_place = source_place(place_pos) + else + node_place = source_place + end + return node_place +end + +local function get_extra_check(check, pos, user) + local result + local take_bucket + if check then + result, take_bucket = check(pos, user) + if result == nil then result = true end + if take_bucket == nil then take_bucket = true end + else + result = true + take_bucket = true + end + return result, take_bucket +end + +local function get_bucket_drop(itemstack, user, take_bucket) + -- Handle bucket item and inventory stuff + if take_bucket and not is_creative_enabled(user:get_player_name()) then + -- Add empty bucket and put it into inventory, if possible. + -- Drop empty bucket otherwise. + local new_bucket = ItemStack("mcl_buckets:bucket_empty") + if itemstack:get_count() == 1 then + return new_bucket + else + local inv = user:get_inventory() + if inv:room_for_item("main", new_bucket) then + inv:add_item("main", new_bucket) + else + add_item(user:get_pos(), new_bucket) + end + itemstack:take_item() + return itemstack + end + else + return itemstack + end +end + +local function bucket_get_pointed_thing(user) + local start = user:get_pos() + start.y = start.y + user:get_properties().eye_height + local look_dir = user:get_look_dir() + local _end = vector.add(start, vector.multiply(look_dir, 5)) + + local ray = raycast(start, _end, false, true) + for pointed_thing in ray do + local name = get_node(pointed_thing.under).name + local def = registered_nodes[name] + if not def or def.drawtype ~= "flowingliquid" then + return pointed_thing + end + end +end + +local function on_place_bucket(itemstack, user, pointed_thing) + if not use_select_box then + pointed_thing = bucket_get_pointed_thing(user) + end + + -- Must be pointing to node + if not pointed_thing or pointed_thing.type ~= "node" then + return + end + + -- Call on_rightclick if the pointed node defines it + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end + + local bucket_def = mcl_buckets.buckets[itemstack:get_name()] + for _, pos in pairs({ pointed_thing.under, pointed_thing.above }) do + local node = get_node(pos) + local node_def = registered_nodes[node.name] + + if node_def and node_def.buildable_to or get_item_group(node.name, "cauldron") == 1 or minetest.get_node(pos).name == "mcl_mangrove:mangrove_roots" then + local result, take_bucket = get_extra_check(bucket_def.extra_check, pos, user) + if result then + local node_place = get_node_place(bucket_def.source_place, pos) + local player_name = user:get_player_name() + + -- Check protection + if is_protected(pos, player_name) then + record_protection_violation(pos, player_name) + return itemstack + end + + -- Place liquid + place_liquid(pos, node_place) + + -- Update doc mod + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + end + return get_bucket_drop(itemstack, user, take_bucket) + end + end + return itemstack +end + +local function on_place_bucket_empty(itemstack, user, pointed_thing) + if not use_select_box then + pointed_thing = bucket_get_pointed_thing(user) + end + + -- Must be pointing to node + if not pointed_thing or pointed_thing.type ~= "node" then + return itemstack + end + + -- Call on_rightclick if the pointed node defines it + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack + end + + local new_bucket + local under = pointed_thing.under + local node_name = get_node(under).name + if pointable_sources[node_name] then + if is_protected(under, user:get_player_name()) then + record_protection_violation(under, user:get_player_name()) + end + local liquid_def = mcl_buckets.liquids[node_name] + if liquid_def then + -- Fill bucket, but not in Creative Mode + -- FIXME: remove this line + --if not is_creative_enabled(user:get_player_name()) then + if not false then + new_bucket = ItemStack({name = liquid_def.bucketname}) + if liquid_def.on_take then + liquid_def.on_take(user) + end + end + add_node(under, {name="air"}) + sound_take(node_name, under) + + if mod_doc and doc.entry_exists("nodes", node_name) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_name) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + else + minetest.log("error", string.format("[mcl_buckets] Node [%s] has invalid group [_mcl_bucket_pointable]!", node_name)) + end + return itemstack + else + -- FIXME: replace this ugly code by cauldrons API + if node_name == "mcl_cauldrons:cauldron_3" then + -- Take water out of full cauldron + set_node(under, {name="mcl_cauldrons:cauldron"}) + if not is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_water") + end + sound_take("mcl_core:water_source", under) + elseif node_name == "mcl_cauldrons:cauldron_3r" then + -- Take river water out of full cauldron + set_node(under, {name="mcl_cauldrons:cauldron"}) + if not is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_river_water") + end + sound_take("mclx_core:river_water_source", under) + elseif node_name == "mcl_cauldrons:cauldron_3_lava" then + set_node(under, {name="mcl_cauldrons:cauldron"}) + if not is_creative_enabled(user:get_player_name()) then + new_bucket = ItemStack("mcl_buckets:bucket_lava") + end + sound_take("mcl_core:lava_source", under) + end + if new_bucket then + return give_bucket(new_bucket, itemstack, user) + end + end + return itemstack +end + +function mcl_buckets.register_liquid(def) + for _,source in ipairs(def.source_take) do + mcl_buckets.liquids[source] = { + source_place = def.source_place, + source_take = source, + on_take = def.on_take, + bucketname = def.bucketname, } - if type(source_place) == "string" then - mcl_buckets.liquids[source_place] = mcl_buckets.liquids[source_take[i]] + pointable_sources[source] = true + if type(def.source_place) == "string" then + mcl_buckets.liquids[def.source_place] = mcl_buckets.liquids[source] end end - if itemname ~= nil then - minetest.register_craftitem(itemname, { - description = name, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - _tt_help = tt_help, - inventory_image = inventory_image, - stack_max = 16, - groups = groups, - on_place = function(itemstack, user, pointed_thing) - -- Must be pointing to node - if pointed_thing.type ~= "node" then - return - end + mcl_buckets.buckets[def.bucketname] = def - local node = minetest.get_node(pointed_thing.under) - local place_pos = pointed_thing.under - local nn = node.name - -- Call on_rightclick if the pointed node defines it - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(place_pos, node, user, itemstack) or itemstack - end - end - - local node_place - if type(source_place) == "function" then - node_place = source_place(place_pos) - else - node_place = source_place - end - -- Check if pointing to a buildable node - local item = itemstack:get_name() - - if extra_check and extra_check(place_pos, user) == false then - -- Fail placement of liquid - elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then - -- buildable; replace the node - local pns = user:get_player_name() - if minetest.is_protected(place_pos, pns) then - minetest.record_protection_violation(place_pos, pns) - return itemstack - end - place_liquid(place_pos, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- not buildable to; place the liquid above - -- check if the node above can be replaced - local abovenode = minetest.get_node(pointed_thing.above) - if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then - local pn = user:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) then - minetest.record_protection_violation(pointed_thing.above, pn) - return itemstack - end - place_liquid(pointed_thing.above, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - else - -- do not remove the bucket with the liquid - return - end - end - - -- Handle bucket item and inventory stuff - if not minetest.is_creative_enabled(user:get_player_name()) then - -- Add empty bucket and put it into inventory, if possible. - -- Drop empty bucket otherwise. - local new_bucket = ItemStack("mcl_buckets:bucket_empty") - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - itemstack:take_item() - return itemstack - end - else - return - end - end, - _on_dispense = function(stack, pos, droppos, dropnode, dropdir) - local iname = stack:get_name() - local buildable = minetest.registered_nodes[dropnode.name].buildable_to - - if extra_check and extra_check(droppos, nil) == false then - -- Fail placement of liquid - elseif buildable then - -- buildable; replace the node - local node_place - if type(source_place) == "function" then - node_place = source_place(droppos) - else - node_place = source_place - end - place_liquid(droppos, node_place) - stack:set_name("mcl_buckets:bucket_empty") - end - return stack - end, - }) + if def.bucketname == nil or def.bucketname == "" then + error(string.format("[mcl_bucket] Invalid itemname then registering [%s]!", def.name)) end + + minetest.register_craftitem(def.bucketname, { + description = def.name, + _doc_items_longdesc = def.longdesc, + _doc_items_usagehelp = def.usagehelp, + _tt_help = def.tt_help, + inventory_image = def.inventory_image, + stack_max = 1, + groups = def.groups, + liquids_pointable = use_select_box, + on_place = on_place_bucket, + on_secondary_use = on_place_bucket, + _on_dispense = function(stack, pos, droppos, dropnode, dropdir) + local buildable = registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" + if not buildable then return stack end + local result, take_bucket = get_extra_check(def.extra_check, droppos, nil) + if result then -- Fail placement of liquid if result is false + place_liquid(droppos, get_node_place(def.source_place, droppos)) + end + if take_bucket then + stack:set_name("mcl_buckets:bucket_empty") + end + return stack + end, + }) end minetest.register_craftitem("mcl_buckets:bucket_empty", { @@ -189,217 +325,36 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { _doc_items_longdesc = S("A bucket can be used to collect and release liquids."), _doc_items_usagehelp = S("Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else."), _tt_help = S("Collects liquids"), - - liquids_pointable = true, - inventory_image = "bucket.png", + inventory_image = "mcl_buckets_bucket.png", stack_max = 16, - on_place = function(itemstack, user, pointed_thing) - -- Must be pointing to node - if pointed_thing.type ~= "node" then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - local node = minetest.get_node(pointed_thing.under) - local nn = node.name - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].on_rightclick then - return minetest.registered_nodes[nn].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end - end - - -- Can't steal liquids - if minetest.is_protected(pointed_thing.above, user:get_player_name()) then - minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) - return itemstack - end - - -- Check if pointing to a liquid source - local liquiddef = mcl_buckets.liquids[nn] - local new_bucket - if liquiddef ~= nil and liquiddef.itemname ~= nil and (nn == liquiddef.source_take) then - - -- Fill bucket, but not in Creative Mode - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack({name = liquiddef.itemname}) - end - - minetest.add_node(pointed_thing.under, {name="air"}) - sound_take(nn, pointed_thing.under) - - if mod_doc and doc.entry_exists("nodes", nn) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", nn) - end - - elseif nn == "mcl_cauldrons:cauldron_3" then - -- Take water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_water") - end - sound_take("mcl_core:water_source", pointed_thing.under) - elseif nn == "mcl_cauldrons:cauldron_3r" then - -- Take river water out of full cauldron - minetest.set_node(pointed_thing.under, {name="mcl_cauldrons:cauldron"}) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack("mcl_buckets:bucket_river_water") - end - sound_take("mclx_core:river_water_source", pointed_thing.under) - end - - -- Add liquid bucket and put it into inventory, if possible. - -- Drop new bucket otherwise. - if new_bucket then - if itemstack:get_count() == 1 then - return new_bucket - else - local inv = user:get_inventory() - if inv:room_for_item("main", new_bucket) then - inv:add_item("main", new_bucket) - else - minetest.add_item(user:get_pos(), new_bucket) - end - if not minetest.is_creative_enabled(user:get_player_name()) then - itemstack:take_item() - end - return itemstack - end - end - end, + liquids_pointable = use_select_box, + on_place = on_place_bucket_empty, + on_secondary_use = on_place_bucket_empty, _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Fill empty bucket with liquid or drop bucket if no liquid local collect_liquid = false local liquiddef = mcl_buckets.liquids[dropnode.name] local new_bucket - if liquiddef ~= nil and liquiddef.itemname ~= nil and (dropnode.name == liquiddef.source_take) then + if liquiddef and liquiddef.bucketname and (dropnode.name == liquiddef.source_take) then -- Fill bucket - new_bucket = ItemStack({name = liquiddef.itemname}) + new_bucket = ItemStack({name = liquiddef.bucketname}) sound_take(dropnode.name, droppos) collect_liquid = true end if collect_liquid then - minetest.set_node(droppos, {name="air"}) + set_node(droppos, {name="air"}) -- Fill bucket with liquid stack = new_bucket else -- No liquid found: Drop empty bucket - minetest.add_item(droppos, stack) + add_item(droppos, stack) stack:take_item() end return stack end, }) -if mod_mcl_core then - -- Lava bucket - mcl_buckets.register_liquid( - function(pos) - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - return "mcl_nether:nether_lava_source" - else - return "mcl_core:lava_source" - end - end, - {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, - "mcl_buckets:bucket_lava", - "bucket_lava.png", - S("Lava Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), - S("Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!"), - S("Places a lava source") - ) - - -- Water bucket - mcl_buckets.register_liquid( - "mcl_core:water_source", - {"mcl_core:water_source"}, - "mcl_buckets:bucket_water", - "bucket_water.png", - S("Water Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with water."), - S("Place it to empty the bucket and create a water source."), - S("Places a water source"), - function(pos, placer) - -- Check protection - local placer_name = "" - if placer ~= nil then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end - local nn = minetest.get_node(pos).name - -- Pour water into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3" then - minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) - end - sound_place("mcl_core:water_source", pos) - return false - -- Evaporate water if used in Nether (except on cauldron) - else - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end - end - end, - { water_bucket = 1 } - ) -end - -if mod_mclx_core then - -- River water bucket - mcl_buckets.register_liquid( - "mclx_core:river_water_source", - {"mclx_core:river_water_source"}, - "mcl_buckets:bucket_river_water", - "bucket_river_water.png", - S("River Water Bucket"), - S("A bucket can be used to collect and release liquids. This one is filled with river water."), - S("Place it to empty the bucket and create a river water source."), - S("Places a river water source"), - function(pos, placer) - -- Check protection - local placer_name = "" - if placer ~= nil then - placer_name = placer:get_player_name() - end - if placer and minetest.is_protected(pos, placer_name) then - minetest.record_protection_violation(pos, placer_name) - return false - end - local nn = minetest.get_node(pos).name - -- Pour into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3r" then - minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) - end - sound_place("mcl_core:water_source", pos) - return false - else - -- Evaporate water if used in Nether (except on cauldron) - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end - end - end, - { water_bucket = 1 } - ) -end - -minetest.register_craft({ - type = "fuel", - recipe = "mcl_buckets:bucket_lava", - burntime = 1000, - replacements = {{"mcl_buckets:bucket_lava", "mcl_buckets:bucket_empty"}}, -}) +dofile(modpath.."/register.lua") +dofile(modpath.."/fishbuckets.lua") diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr index 4320f7509..62fdba15a 100644 --- a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.fr.tr @@ -1,17 +1,25 @@ # textdomain: mcl_buckets -Empty Bucket=Seau Vide +Empty Bucket=Seau vide A bucket can be used to collect and release liquids.=Un seau peut être utilisé pour recueillir et libérer les liquides. Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Frappez une source de liquide pour la collecter. Vous pouvez ensuite utiliser le seau rempli pour placer le liquide ailleurs. Lava Bucket=Seau de Lave -A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli de lave chaude, contenue en toute sécurité à l'intérieur. Utiliser avec pré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!=Eloignez-vous et placez le seau pour le vider et créez une source de lave à cet endroit. Ne vous brûlez pas! -Water Bucket=Seau d'Eau +A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli de lave chaude, contenue en toute sécurité à l'intérieur. À utiliser avec pré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!=Éloignez-vous et placez le seau pour le vider et créez une source de lave à cet endroit. Ne vous brûlez pas ! +Water Bucket=Seau d'eau A bucket can be used to collect and release liquids. This one is filled with water.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli d'eau. Place it to empty the bucket and create a water source.=Placez-le pour vider le seau et créer une source d'eau. -River Water Bucket=Seau d'Eau de Rivière +River Water Bucket=Seau d'eau de rivière A bucket can be used to collect and release liquids. This one is filled with river water.=Un seau peut être utilisé pour recueillir et libérer les liquides. Celui-ci est rempli d'eau de rivière. Place it to empty the bucket and create a river water source.=Placez-le pour vider le seau et créer une source d'eau de rivière. Collects liquids=Collecte des liquides Places a lava source=Place une source de lave Places a water source=Place une source d'eau Places a river water source=Place une source d'eau de rivière +Axolotl=Axolotl +Cod=Morue +Salmon=Saumon +Tropical Fish=Poisson tropical +Bucket of @1=Seau de @1 +This bucket is filled with water and @1.=Ce seau est rempli d'eau et de @1. +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.=Le placer pour vider le seau et placer un @1. S'obtient en faisant un clic droit sur un @2 avec un seau d'eau. +Places a water source and a @1.=Placer une source d'eau et un @1. diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr new file mode 100644 index 000000000..9da7d4dfb --- /dev/null +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.ja.tr @@ -0,0 +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.=液体の源に使うと、それを回収します。何処かに満ちたバケツを使うと、液体を配置できます。 +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!=安全な距離を取り、バケツを置いて空にし、この場所に溶岩源を作ります。ヤケドしないように! +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.=これを置いてバケツを空にし、水源を作ります。 +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.=これを置いてバケツを空にし、河川水源を作ります。 +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 fish with a bucket of water.=バケツを空にするために@1を置きます。@2入りバケツを右クリックすると魚を入手します。 +Places a water source and a @1 fish.=水源と、@1の魚を配置 diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pl.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pl.tr new file mode 100644 index 000000000..f7593b14e --- /dev/null +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pl.tr @@ -0,0 +1,17 @@ +# textdomain: mcl_buckets +Empty Bucket=Puste wiadro +A bucket can be used to collect and release liquids.=Wiadro może być użyte do zbierania i wylewania płynów. +Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Uderz w źródło płynu aby je zebrać. Możesz następnie użyć pełnego wiadra aby postawić płyn gdzie indziej. +Lava Bucket=Wiadro lawy +A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.= Wiadro może być użyte do zbierania i wylewania płynów. To jest wypełnione lawą, bezpiecznie przechowywaną w środku. Używać z rozwagą. +Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Odejdź na bezpieczną odległość i umieść wiadro aby je opróżnić i utworzyć źródło lawy w danym miejscu. Nie poparz się! +Water Bucket=Wiadro wody +A bucket can be used to collect and release liquids. This one is filled with water.=Wiadro może być użyte do zbierania i wylewania płynów. To jest wypełnione wodą. +Place it to empty the bucket and create a water source.=Umieść je aby opróżnić wiadro i utworzyć źródło wody. +River Water Bucket=Wiadro wody rzecznej +A bucket can be used to collect and release liquids. This one is filled with river water.= Wiadro może być użyte do zbierania i wylewania płynów. To jest wypełnione wodą rzeczną. +Place it to empty the bucket and create a river water source.=Umieść je aby opróżnić wiadro i utworzyć źródło wody rzecznej. +Collects liquids=Zbiera płyny +Places a lava source=Umieszcza źródło lawy +Places a water source=Umieszcza źródło wody +Places a river water source=Umieszcza źródło wody rzecznej diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pt_BR.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pt_BR.tr new file mode 100644 index 000000000..c419d76fe --- /dev/null +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.pt_BR.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_buckets +Empty Bucket=Balde Vazio +A bucket can be used to collect and release liquids.=Um balde pode ser utilizado para coletar e soltar líquidos. +Punch a liquid source to collect it. You can then use the filled bucket to place the liquid somewhere else.=Soque uma fonte de líquido para coletá-la. Voce pode usar um balde cheio para colocar o líquido em algum outro lugar. +Lava Bucket=Balde com Lava +A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com lava quente, contido seguramente dentro. Utilize com cautela. +Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!=Tome uma distância segura e coloque o balde para esvaziá-lo e criar uma fonte de lava no local. Não se queime! +Water Bucket=Balde com Água +A bucket can be used to collect and release liquids. This one is filled with water.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com água. +Place it to empty the bucket and create a water source.=Coloque-o para esvaziar o balde e criar uma fonte de água. +River Water Bucket=Balde com Água de Rio +A bucket can be used to collect and release liquids. This one is filled with river water.=Um balde pode ser utilizado para coletar e soltar líquidos. Este está preenchido com água de rio. +Place it to empty the bucket and create a river water source.=Coloque-o para esvaziar o balde e criar uma fonte de água de rio. +Collects liquids=Coleta líquidos +Places a lava source=Coloca uma fonte de lava +Places a water source=Coloca uma fonte de água +Places a river water source=Coloca uma fonte de água de rio +Cod=Bacalhau +Salmon=Salmão +Tropical Fish=Peixe Tropical +Bucket of @1=Balde com @1 +This bucket is filled with water and @1.=Este balde está preenchido com água e @1 +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 fish with a bucket of water.=Coloque-o para esvaziar o balde e colocar um @1. Obtenha-o ao clicar com o botão direito em um peixe @2 com um balde com água. +Places a water source and a @1 fish.=Coloca a fonte de água e um peixe @1. diff --git a/mods/ITEMS/mcl_buckets/locale/mcl_buckets.zh_TW.tr b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.zh_TW.tr new file mode 100644 index 000000000..a9db929b2 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/locale/mcl_buckets.zh_TW.tr @@ -0,0 +1,17 @@ +# 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.=擊打一個液體源頭來收集它。然後你可以用裝滿的桶把液體放在其他地方。 +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!=在安全距離內,將熔岩倒出,在這個地方創造一個熔岩源頭。不要燒到自己! +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.=放置它以清空水桶並創建水源。 +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.=放置它以清空水桶並創建河水源。 +Collects liquids=攜帶流體 +Places a lava source=放置熔岩源頭 +Places a water source=放置水源 +Places a river water source=放置河水源頭 diff --git a/mods/ITEMS/mcl_buckets/locale/template.txt b/mods/ITEMS/mcl_buckets/locale/template.txt index 174d1b76b..29aaeace9 100644 --- a/mods/ITEMS/mcl_buckets/locale/template.txt +++ b/mods/ITEMS/mcl_buckets/locale/template.txt @@ -15,3 +15,11 @@ Collects liquids= Places a lava source= Places a water source= Places a river water source= +Axolotl= +Cod= +Salmon= +Tropical Fish= +Bucket of @1= +This bucket is filled with water and @1.= +Place it to empty the bucket and place a @1. Obtain by right clicking on a @2 with a bucket of water.= +Places a water source and a @1.= diff --git a/mods/ITEMS/mcl_buckets/mod.conf b/mods/ITEMS/mcl_buckets/mod.conf new file mode 100644 index 000000000..ba945b033 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/mod.conf @@ -0,0 +1,6 @@ +name = mcl_buckets +author = Kahrl +description = +depends = mcl_worlds, mcl_util, controls +optional_depends = mcl_core, mclx_core, doc + diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua new file mode 100644 index 000000000..1d247e827 --- /dev/null +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -0,0 +1,126 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +local mod_mcl_core = minetest.get_modpath("mcl_core") +local mod_mclx_core = minetest.get_modpath("mclx_core") +local has_awards = minetest.get_modpath("awards") + +local function sound_place(itemname, pos) + local def = minetest.registered_nodes[itemname] + if def and def.sounds and def.sounds.place then + minetest.sound_play(def.sounds.place, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) + end +end + +if mod_mcl_core then + -- Lava bucket + mcl_buckets.register_liquid({ + source_place = function(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + return "mcl_nether:nether_lava_source" + else + return "mcl_core:lava_source" + end + end, + source_take = {"mcl_core:lava_source", "mcl_nether:nether_lava_source"}, + on_take = function(user) + if has_awards and user and user:is_player() then + awards.unlock(user:get_player_name(), "mcl:hotStuff") + end + end, + extra_check = function(pos, placer) + local nn = minetest.get_node(pos).name + if minetest.get_item_group(nn, "cauldron") ~= 0 then + if nn ~= "mcl_cauldrons:cauldron_3_lava" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3_lava"}) + end + sound_place("mcl_core:lava_source", pos) + return false, true + end + end, + bucketname = "mcl_buckets:bucket_lava", + inventory_image = "mcl_buckets_lava_bucket.png", + name = S("Lava Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with hot lava, safely contained inside. Use with caution."), + usagehelp = S("Get in a safe distance and place the bucket to empty it and create a lava source at this spot. Don't burn yourself!"), + tt_help = S("Places a lava source") + }) + + -- Water bucket + mcl_buckets.register_liquid({ + source_place = "mcl_core:water_source", + source_take = {"mcl_core:water_source"}, + bucketname = "mcl_buckets:bucket_water", + inventory_image = "mcl_buckets_water_bucket.png", + name = S("Water Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with water."), + usagehelp = S("Place it to empty the bucket and create a water source."), + tt_help = S("Places a water source"), + extra_check = function(pos, placer) + local nn = minetest.get_node(pos).name + local dim = mcl_worlds.pos_to_dimension(pos) + -- Pour water into cauldron + if minetest.get_item_group(nn, "cauldron") ~= 0 then + -- Put water into cauldron + if nn ~= "mcl_cauldrons:cauldron_3" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) + end + sound_place("mcl_core:water_source", pos) + return false, true + -- Put water into mangrove roots + elseif minetest.get_node(pos).name == "mcl_mangrove:mangrove_roots" and dim ~= "nether" then + minetest.set_node(pos, {name="mcl_mangrove:water_logged_roots"}) + sound_place("mcl_core:water_source", pos) + return false, true + -- Evaporate water if used in Nether (except on cauldron) + elseif dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + return false, true + end + end, + groups = { water_bucket = 1 }, + }) +end + +if mod_mclx_core then + -- River water bucket + mcl_buckets.register_liquid({ + source_place = "mclx_core:river_water_source", + source_take = {"mclx_core:river_water_source"}, + bucketname = "mcl_buckets:bucket_river_water", + inventory_image = "mcl_buckets_river_water_bucket.png", + name = S("River Water Bucket"), + longdesc = S("A bucket can be used to collect and release liquids. This one is filled with river water."), + usagehelp = S("Place it to empty the bucket and create a river water source."), + tt_help = S("Places a river water source"), + extra_check = function(pos, placer) + local nn = minetest.get_node(pos).name + local dim = mcl_worlds.pos_to_dimension(pos) + -- Pour into cauldron + if minetest.get_item_group(nn, "cauldron") ~= 0 then + -- Put water into cauldron + if nn ~= "mcl_cauldrons:cauldron_3r" then + minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) + end + sound_place("mcl_core:water_source", pos) + return false, true + -- Put river water into mangrove roots + elseif minetest.get_node(pos).name == "mcl_mangrove:mangrove_roots" and dim ~= "nether" then + minetest.set_node(pos, {name="mcl_mangrove:river_water_logged_roots"}) + sound_place("mcl_core:water_source", pos) + return false, true + -- Evaporate water if used in Nether (except on cauldron) + elseif dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + return false, true + end + end, + groups = { water_bucket = 1 }, + }) +end + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_buckets:bucket_lava", + burntime = 1000, + replacements = {{"mcl_buckets:bucket_lava", "mcl_buckets:bucket_empty"}}, +}) diff --git a/mods/ITEMS/mcl_cake/depends.txt b/mods/ITEMS/mcl_cake/depends.txt deleted file mode 100644 index 1ed0ada15..000000000 --- a/mods/ITEMS/mcl_cake/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_core -mcl_sounds -mcl_hunger -mcl_buckets -mcl_farming -mcl_mobitems -doc? diff --git a/mods/ITEMS/mcl_cake/init.lua b/mods/ITEMS/mcl_cake/init.lua index cc6d50633..1b0824e77 100644 --- a/mods/ITEMS/mcl_cake/init.lua +++ b/mods/ITEMS/mcl_cake/init.lua @@ -1,147 +1,156 @@ ---[[ -#!#!#!#Cake mod created by Jordan4ibanez#!#!# -#!#!#!#Released under CC Attribution-ShareAlike 3.0 Unported #!#!# -]]-- - -local CAKE_HUNGER_POINTS = 2 - -local S = minetest.get_translator("mcl_cake") - -local cake_texture = {"cake_top.png","cake_bottom.png","cake_inner.png","cake_side.png","cake_side.png","cake_side.png"} -local slice_1 = { -7/16, -8/16, -7/16, -5/16, 0/16, 7/16} -local slice_2 = { -7/16, -8/16, -7/16, -3/16, 0/16, 7/16} -local slice_3 = { -7/16, -8/16, -7/16, -1/16, 0/16, 7/16} -local slice_4 = { -7/16, -8/16, -7/16, 1/16, 0/16, 7/16} -local slice_5 = { -7/16, -8/16, -7/16, 3/16, 0/16, 7/16} -local slice_6 = { -7/16, -8/16, -7/16, 5/16, 0/16, 7/16} - -local full_cake = { -7/16, -8/16, -7/16, 7/16, 0/16, 7/16} - -minetest.register_craft({ - output = "mcl_cake:cake", - recipe = { - {'mcl_mobitems:milk_bucket', 'mcl_mobitems:milk_bucket', 'mcl_mobitems:milk_bucket'}, - {'mcl_core:sugar', 'mcl_throwing:egg', 'mcl_core:sugar'}, - {'mcl_farming:wheat_item', 'mcl_farming:wheat_item', 'mcl_farming:wheat_item'}, - }, - replacements = { - {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, - {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, - {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, - }, -}) - -minetest.register_node("mcl_cake:cake", { - description = S("Cake"), - _tt_help = S("With 7 tasty slices!").."\n"..S("Hunger points: +@1 per slice", CAKE_HUNGER_POINTS), - _doc_items_longdesc = S("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."), - _doc_items_usagehelp = S("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."), - tiles = {"cake_top.png","cake_bottom.png","cake_side.png","cake_side.png","cake_side.png","cake_side.png"}, - inventory_image = "cake.png", - wield_image = "cake.png", - paramtype = "light", - is_ground_content = false, - drawtype = "nodebox", - selection_box = { - type = "fixed", - fixed = full_cake - }, - node_box = { - type = "fixed", - fixed = full_cake - }, - stack_max = 1, - groups = {handy=1, cake=7, food=2,no_eat_delay=1, attached_node=1, dig_by_piston=1, comparator_signal=14}, - drop = '', - on_rightclick = function(pos, node, clicker, itemstack) - -- Cake is subject to protection - local name = clicker:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - local newcake = minetest.do_item_eat(2, ItemStack("mcl_cake:cake_6"), ItemStack("mcl_cake:cake"), clicker, {type="nothing"}) - -- Check if we were allowed to eat - if newcake:get_name() ~= "mcl_cake:cake" or minetest.is_creative_enabled(clicker:get_player_name()) then - minetest.add_node(pos,{type="node",name="mcl_cake:cake_6",param2=0}) - end - end, - sounds = mcl_sounds.node_sound_leaves_defaults(), - - _food_particles = false, - _mcl_saturation = 0.4, - _mcl_blast_resistance = 0.5, - _mcl_hardness = 0.5, -}) - -local register_slice = function(level, nodebox, desc) - local this = "mcl_cake:cake_"..level - local after_eat = "mcl_cake:cake_"..(level-1) - local on_rightclick - if level > 1 then - on_rightclick = function(pos, node, clicker, itemstack) - local name = clicker:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - local newcake = minetest.do_item_eat(CAKE_HUNGER_POINTS, ItemStack(after_eat), ItemStack(this), clicker, {type="nothing"}) - -- Check if we were allowed to eat - if newcake:get_name() ~= this or minetest.is_creative_enabled(clicker:get_player_name()) then - minetest.add_node(pos,{type="node",name=after_eat,param2=0}) - end - end - else - -- Last slice - on_rightclick = function(pos, node, clicker, itemstack) - local name = clicker:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - local newcake = minetest.do_item_eat(CAKE_HUNGER_POINTS, ItemStack("mcl:cake:cake 0"), ItemStack("mcl_cake:cake_1"), clicker, {type="nothing"}) - -- Check if we were allowed to eat - if newcake:get_name() ~= this or minetest.is_creative_enabled(clicker:get_player_name()) then - minetest.remove_node(pos) - core.check_for_falling(pos) - end - end - end - - minetest.register_node(this, { - description = desc, - _doc_items_create_entry = false, - tiles = cake_texture, - paramtype = "light", - is_ground_content = false, - drawtype = "nodebox", - selection_box = { - type = "fixed", - fixed = nodebox, - }, - node_box = { - type = "fixed", - fixed = nodebox, - }, - groups = {handy=1, cake=level, food=2,no_eat_delay=1,attached_node=1,not_in_creative_inventory=1,dig_by_piston=1,comparator_signal=level*2}, - drop = '', - on_rightclick = on_rightclick, - sounds = mcl_sounds.node_sound_leaves_defaults(), - - _food_particles = false, - _mcl_saturation = 0.4, - _mcl_blast_resistance = 0.5, - _mcl_hardness = 0.5, - }) - - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_cake:cake", "nodes", "mcl_cake:cake_"..level) - end -end - -register_slice(6, slice_6, S("Cake (6 Slices Left)")) -register_slice(5, slice_5, S("Cake (5 Slices Left)")) -register_slice(4, slice_4, S("Cake (4 Slices Left)")) -register_slice(3, slice_3, S("Cake (3 Slices Left)")) -register_slice(2, slice_2, S("Cake (2 Slices Left)")) -register_slice(1, slice_1, S("Cake (1 Slice Left)")) +--[[ +#!#!#!#Cake mod created by Jordan4ibanez#!#!# +#!#!#!#Released under CC Attribution-ShareAlike 3.0 Unported #!#!# +]]-- + +local CAKE_HUNGER_POINTS = 2 + +local S = minetest.get_translator(minetest.get_current_modname()) + +local cake_texture = {"cake_top.png","cake_bottom.png","cake_inner.png","cake_side.png","cake_side.png","cake_side.png"} +local slice_1 = { -7/16, -8/16, -7/16, -5/16, 0/16, 7/16} +local slice_2 = { -7/16, -8/16, -7/16, -3/16, 0/16, 7/16} +local slice_3 = { -7/16, -8/16, -7/16, -1/16, 0/16, 7/16} +local slice_4 = { -7/16, -8/16, -7/16, 1/16, 0/16, 7/16} +local slice_5 = { -7/16, -8/16, -7/16, 3/16, 0/16, 7/16} +local slice_6 = { -7/16, -8/16, -7/16, 5/16, 0/16, 7/16} + +local full_cake = { -7/16, -8/16, -7/16, 7/16, 0/16, 7/16} + +minetest.register_craft({ + output = "mcl_cake:cake", + recipe = { + {"mcl_mobitems:milk_bucket", "mcl_mobitems:milk_bucket", "mcl_mobitems:milk_bucket"}, + {"mcl_core:sugar", "mcl_throwing:egg", "mcl_core:sugar"}, + {"mcl_farming:wheat_item", "mcl_farming:wheat_item", "mcl_farming:wheat_item"}, + }, + replacements = { + {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, + {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, + {"mcl_mobitems:milk_bucket", "mcl_buckets:bucket_empty"}, + }, +}) + +minetest.register_node("mcl_cake:cake", { + description = S("Cake"), + _tt_help = S("With 7 tasty slices!").."\n"..S("Hunger points: +@1 per slice", CAKE_HUNGER_POINTS), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("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."), + tiles = {"cake_top.png","cake_bottom.png","cake_side.png","cake_side.png","cake_side.png","cake_side.png"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + inventory_image = "cake.png", + wield_image = "cake.png", + paramtype = "light", + is_ground_content = false, + drawtype = "nodebox", + selection_box = { + type = "fixed", + fixed = full_cake + }, + node_box = { + type = "fixed", + fixed = full_cake + }, + stack_max = 1, + groups = { + handy = 1, attached_node = 1, dig_by_piston = 1, comparator_signal = 14, + cake = 7, food = 2, no_eat_delay = 1, compostability = 100 + }, + drop = "", + on_rightclick = function(pos, node, clicker, itemstack) + -- Cake is subject to protection + local name = clicker:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return + end + local newcake = minetest.do_item_eat(2, ItemStack("mcl_cake:cake_6"), ItemStack("mcl_cake:cake"), clicker, {type="nothing"}) + -- Check if we were allowed to eat + if newcake:get_name() ~= "mcl_cake:cake" or minetest.is_creative_enabled(clicker:get_player_name()) then + minetest.add_node(pos,{type="node",name="mcl_cake:cake_6",param2=0}) + end + end, + sounds = mcl_sounds.node_sound_leaves_defaults(), + + _food_particles = false, + _mcl_saturation = 0.4, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, +}) + +local register_slice = function(level, nodebox, desc) + local this = "mcl_cake:cake_"..level + local after_eat = "mcl_cake:cake_"..(level-1) + local on_rightclick + if level > 1 then + on_rightclick = function(pos, node, clicker, itemstack) + local name = clicker:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return + end + local newcake = minetest.do_item_eat(CAKE_HUNGER_POINTS, ItemStack(after_eat), ItemStack(this), clicker, {type="nothing"}) + -- Check if we were allowed to eat + if newcake:get_name() ~= this or minetest.is_creative_enabled(clicker:get_player_name()) then + minetest.add_node(pos,{type="node",name=after_eat,param2=0}) + end + end + else + -- Last slice + on_rightclick = function(pos, node, clicker, itemstack) + local name = clicker:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return + end + local newcake = minetest.do_item_eat(CAKE_HUNGER_POINTS, ItemStack("mcl:cake:cake 0"), ItemStack("mcl_cake:cake_1"), clicker, {type="nothing"}) + -- Check if we were allowed to eat + if newcake:get_name() ~= this or minetest.is_creative_enabled(clicker:get_player_name()) then + minetest.remove_node(pos) + minetest.check_for_falling(pos) + end + end + end + + minetest.register_node(this, { + description = desc, + _doc_items_create_entry = false, + tiles = cake_texture, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + is_ground_content = false, + drawtype = "nodebox", + selection_box = { + type = "fixed", + fixed = nodebox, + }, + node_box = { + type = "fixed", + fixed = nodebox, + }, + groups = { + handy = 1, attached_node = 1, not_in_creative_inventory = 1, + dig_by_piston = 1, cake = level, comparator_signal = level * 2, + food = 2, no_eat_delay = 1 + }, + drop = "", + on_rightclick = on_rightclick, + sounds = mcl_sounds.node_sound_leaves_defaults(), + + _food_particles = false, + _mcl_saturation = 0.4, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, + }) + + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_cake:cake", "nodes", "mcl_cake:cake_"..level) + end +end + +register_slice(6, slice_6, S("Cake (6 Slices Left)")) +register_slice(5, slice_5, S("Cake (5 Slices Left)")) +register_slice(4, slice_4, S("Cake (4 Slices Left)")) +register_slice(3, slice_3, S("Cake (3 Slices Left)")) +register_slice(2, slice_2, S("Cake (2 Slices Left)")) +register_slice(1, slice_1, S("Cake (1 Slice Left)")) diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.es.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.es.tr index 261d581e1..3cec57b8b 100644 --- a/mods/ITEMS/mcl_cake/locale/mcl_cake.es.tr +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.es.tr @@ -8,3 +8,5 @@ Cake (4 Slices Left)=Tarta (Quedan 4 trozos) Cake (3 Slices Left)=Tarta (Quedan 3 trozos) Cake (2 Slices Left)=Tarta (Quedan 2 trozos) Cake (1 Slice Left)=Tarta (Queda 1 trozo) +With 7 tasty slices!=¡Con 7 deliciosas rebanadas! +Hunger points: +@1 per slice=Puntos de hambre: +@1 por rebanada diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.fr.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.fr.tr index 06e3b7ceb..55e5c8772 100644 --- a/mods/ITEMS/mcl_cake/locale/mcl_cake.fr.tr +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.fr.tr @@ -8,5 +8,5 @@ Cake (4 Slices Left)=Gâteau (reste 4 tranches) Cake (3 Slices Left)=Gâteau (reste 3 tranches) Cake (2 Slices Left)=Gâteau (reste 2 tranches) Cake (1 Slice Left)=Gâteau (reste 1 tranche) -With 7 tasty slices!=Avec 7 tranches savoureuses! -Hunger points: +@1 per slice=Points de faim: +@1 par tranche +With 7 tasty slices!=Avec 7 tranches savoureuses ! +Hunger points: +@1 per slice=Points de faim : +@1 par tranche diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr new file mode 100644 index 000000000..69b0dd78f --- /dev/null +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.ja.tr @@ -0,0 +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口分に切ってあります。1口につき満腹度が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/1切れ diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.pl.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.pl.tr new file mode 100644 index 000000000..f90e665e7 --- /dev/null +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.pl.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_cake +Cake=Ciasto +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.=Ciasto może być postawione i zjedzone by odzyskać punkty głodu. Ciasto ma 7 kawałków. Każdy kawałek przywraca dwa punkty głodu i 0.4 punktu nasycenia. Ciasta zostaną zniszczone przy próbie wykopania, lub gdy blok pod nimi zostanie zniszczony. +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.=Postaw ciasto gdziekolwiek, następnie kliknij prawym by zjeść pojedynczy kawałek. Nie możesz jeść ciasta gdy twój pasek głodu jest pełny. +Cake (6 Slices Left)=Ciasto (pozostały 6 kawałki) +Cake (5 Slices Left)=Ciasto (pozostały 5 kawałki) +Cake (4 Slices Left)=Ciasto (pozostały 4 kawałki) +Cake (3 Slices Left)=Ciasto (pozostały 3 kawałki) +Cake (2 Slices Left)=Ciasto (pozostały 2 kawałki) +Cake (1 Slice Left)=Ciasto (pozostał 1 kawałek) +With 7 tasty slices!=Z 7 pysznymi kawałkami! +Hunger points: +@1 per slice=Punkty głodu: +@1 za kawałek diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.pt_BR.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.pt_BR.tr new file mode 100644 index 000000000..d465e1812 --- /dev/null +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.pt_BR.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_cake +Cake=Bolo +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.=Bolos podem ser colocados e comidos para restaurar pontos de fome. Um bolo tem 7 pedaços. Cada pedaço restaura 2 pontos de fome e 0.4 pontos de saturação. Bolos serão destruídos quando eles, ou o bloco abaixo deles, é quebrado. +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.=Coloque o bolo em qualquer lugar, e então aperte o botão direito nele para comer um pedaço. Você não consegue comer bolo quando sua barra de fome estiver cheia. +Cake (6 Slices Left)=Bolo (6 Pedaços Restantes) +Cake (5 Slices Left)=Bolo (5 Pedaços Restantes) +Cake (4 Slices Left)=Bolo (4 Pedaços Restantes) +Cake (3 Slices Left)=Bolo (3 Pedaços Restantes) +Cake (2 Slices Left)=Bolo (2 Pedaços Restantes) +Cake (1 Slice Left)=Bolo (1 Pedaço Restante) +With 7 tasty slices!=Com 7 deliciosos pedaços! +Hunger points: +@1 per slice=Pontos de fome: +@1 por pedaço diff --git a/mods/ITEMS/mcl_cake/locale/mcl_cake.zh_TW.tr b/mods/ITEMS/mcl_cake/locale/mcl_cake.zh_TW.tr new file mode 100644 index 000000000..702791b49 --- /dev/null +++ b/mods/ITEMS/mcl_cake/locale/mcl_cake.zh_TW.tr @@ -0,0 +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.=將蛋糕放在任何地方,然後右鍵單擊以吃一小片。 當您的飢餓條已滿時,您不能從蛋糕上吃東西。 +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!=有七塊美味的蛋糕! +Hunger points: +@1 per slice=飢餓值:每片 +@1 diff --git a/mods/ITEMS/mcl_cake/mod.conf b/mods/ITEMS/mcl_cake/mod.conf index 2a76657f5..e7260468e 100644 --- a/mods/ITEMS/mcl_cake/mod.conf +++ b/mods/ITEMS/mcl_cake/mod.conf @@ -1 +1,4 @@ name = mcl_cake +description = Add cakes to mcl +depends = mcl_core, mcl_sounds, mcl_hunger, mcl_buckets, mcl_farming, mcl_mobitems +optional_depends = doc diff --git a/mods/ITEMS/mcl_cake/textures/cake.png b/mods/ITEMS/mcl_cake/textures/cake.png deleted file mode 100644 index 736faa6db..000000000 Binary files a/mods/ITEMS/mcl_cake/textures/cake.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cake/textures/cake_bottom.png b/mods/ITEMS/mcl_cake/textures/cake_bottom.png deleted file mode 100644 index d64db7f7d..000000000 Binary files a/mods/ITEMS/mcl_cake/textures/cake_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cake/textures/cake_side.png b/mods/ITEMS/mcl_cake/textures/cake_side.png deleted file mode 100644 index 3d4643e41..000000000 Binary files a/mods/ITEMS/mcl_cake/textures/cake_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cake/textures/cake_top.png b/mods/ITEMS/mcl_cake/textures/cake_top.png deleted file mode 100644 index 576c3fe8c..000000000 Binary files a/mods/ITEMS/mcl_cake/textures/cake_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_campfires/API.md b/mods/ITEMS/mcl_campfires/API.md new file mode 100644 index 000000000..abf61c6f1 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/API.md @@ -0,0 +1,26 @@ +MineClone 2 Campfire API +======================== +`mcl_campfires.register_campfire` +--------------------------------- +Used to register campfires. + +**Example Usage** +``` +mcl_campfires.register_campfire("mcl_campfires:campfire", { + description = S("Campfire"), + inv_texture = "mcl_campfires_campfire_inv.png", + fire_texture = "mcl_campfires_campfire_fire.png", + lit_logs_texture = "mcl_campfires_campfire_log_lit.png", + drops = "mcl_core:charcoal_lump 2", + lightlevel = 14, + damage = 1, +}) +``` +**Values** +* description - human readable node name. +* inv_texture - campfire inventory texture. +* fire_texture - texture of the campfire fire. +* 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 diff --git a/mods/ITEMS/mcl_campfires/README.md b/mods/ITEMS/mcl_campfires/README.md new file mode 100644 index 000000000..8747aa7e3 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/README.md @@ -0,0 +1,21 @@ +mcl_campfires +=============== +Adds the campfire and its soul variant. + +License of code +--------------- +See the main MineClone 2 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. + +License of media +---------------- +See the main MineClone 2 README.md file for license on most of the textures. + +For the following textures: +mcl_campfires_campfire_inv.png +mcl_campfires_soul_campfire_inv.png +License: CC0 1.0 Universal (CC0 1.0) +Author: RandomLegoBrick diff --git a/mods/ITEMS/mcl_campfires/api.lua b/mods/ITEMS/mcl_campfires/api.lua new file mode 100644 index 000000000..8b0aff85e --- /dev/null +++ b/mods/ITEMS/mcl_campfires/api.lua @@ -0,0 +1,117 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +mcl_campfires = {} + +function mcl_campfires.register_campfire(name, def) + -- Define Campfire + minetest.register_node(name, { + description = def.description, + _tt_help = S("Cooks food and keeps bees happy."), + _doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."), + inventory_image = def.inv_texture, + wield_image = def.inv_texture, + drawtype = "mesh", + mesh = "mcl_campfires_campfire.obj", + tiles = {{name="mcl_campfires_log.png"},}, + 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 + end, + drop = def.drops, + _mcl_silk_touch_drop = {name}, + mcl_sounds.node_sound_wood_defaults(), + selection_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top + }, + collision_box = { + type = 'fixed', + fixed = {-.5, -.5, -.5, .5, -.05, .5}, + }, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + }) + + --Define Lit Campfire + minetest.register_node(name.."_lit", { + description = def.description, + _tt_help = S("Cooks food and keeps bees happy."), + _doc_items_longdesc = S("Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap."), + 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 + }} + }, + use_texture_alpha = "clip", + groups = { handy=1, axey=1, material_wood=1, campfire=1, lit_campfire=1 }, + paramtype = "light", + paramtype2 = "facedir", + 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) + end + end, + drop = def.drops, + _mcl_silk_touch_drop = {name.."_lit"}, + light_source = def.lightlevel, + mcl_sounds.node_sound_wood_defaults(), + selection_box = { + type = "fixed", + fixed = {-.5, -.5, -.5, .5, -.05, .5}, --left, bottom, front, right, top + }, + collision_box = { + type = "fixed", + fixed = {-.5, -.5, -.5, .5, -.05, .5}, + }, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + damage_per_second = def.damage, + }) +end + +local function burn_in_campfire(obj) + local p = obj:get_pos() + if p then + local n = minetest.find_node_near(p,0.4,{"group:lit_campfire"},true) + if n then + mcl_burning.set_on_fire(obj, 5) + end + end +end + +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 + burn_in_campfire(pl) + end + for _,ent in pairs(minetest.luaentities) do + if ent.is_mob then + burn_in_campfire(ent.object) + end + end +end) diff --git a/mods/ITEMS/mcl_campfires/init.lua b/mods/ITEMS/mcl_campfires/init.lua new file mode 100644 index 000000000..058ba50ed --- /dev/null +++ b/mods/ITEMS/mcl_campfires/init.lua @@ -0,0 +1,9 @@ +-- TO-DO: +-- * Add Smoke Particles +-- * Add Spark Particles +-- * Add Cooking Meat +-- * Add Working Sounds +local modname = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modname.."/api.lua") -- Load API File +dofile(modname.."/register.lua") -- Load Campfire Registration File diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.es.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.es.tr new file mode 100644 index 000000000..e941ad9bc --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.es.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=Fogata +Soul Campfire=Fogata de almas +Cooks food and keeps bees happy.=Cocina comida y mantiene a las abejas felices. +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Las fogatas tienen múltiples usos, incluyendo mantener a las abejas felices, cocinar carne cruda y pescado, y como trampa. diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr new file mode 100644 index 000000000..0708aaeb7 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=Feu de camp +Soul Campfire=Feu de camp des âmes +Cooks food and keeps bees happy.=Cuit la nourriture et garde les abeilles heureuses +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Les feux de camp ont des usages multiples, incluant garder les abeilles heureuses, cuisiner de la viande crue et du poisson, et comme piège. \ No newline at end of file diff --git a/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.tr new file mode 100644 index 000000000..cf311ebd2 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.ja.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/locale/mcl_campfires.pt_BR.tr b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.pt_BR.tr new file mode 100644 index 000000000..27757ee41 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/mcl_campfires.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_campfires +Campfire=Fogueira +Soul Campfire=Fogueira de Almas +Cooks food and keeps bees happy.=Cozinhe comida e mantenha as abelhas felizes. +Campfires have multiple uses, including keeping bees happy, cooking raw meat and fish, and as a trap.=Fogueiras possuem multiplos usos, incluindo manter abelhas felizes, cozinhar carnes cruas e peixes e como uma armadilha. diff --git a/mods/ITEMS/mcl_campfires/locale/template.txt b/mods/ITEMS/mcl_campfires/locale/template.txt new file mode 100644 index 000000000..d357de0ed --- /dev/null +++ b/mods/ITEMS/mcl_campfires/locale/template.txt @@ -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 new file mode 100644 index 000000000..5c4b77dda --- /dev/null +++ b/mods/ITEMS/mcl_campfires/mod.conf @@ -0,0 +1,3 @@ +name = mcl_campfires +depends = mcl_sounds +author = PrairieWind, Gerold55 \ 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 new file mode 100644 index 000000000..a559fdd4f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire.obj @@ -0,0 +1,224 @@ +# Blender v2.78 (sub 0) OBJ File: '' +# 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 +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 diff --git a/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl new file mode 100644 index 000000000..7355efe9f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.mtl @@ -0,0 +1,35 @@ +# 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 new file mode 100644 index 000000000..92a377303 --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire1.obj @@ -0,0 +1,248 @@ +# 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 new file mode 100644 index 000000000..a17acc05f --- /dev/null +++ b/mods/ITEMS/mcl_campfires/models/mcl_campfires_campfire_lit.obj @@ -0,0 +1,225 @@ +# 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 new file mode 100644 index 000000000..87e9f415a --- /dev/null +++ b/mods/ITEMS/mcl_campfires/register.lua @@ -0,0 +1,42 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Register Plain Campfire +mcl_campfires.register_campfire("mcl_campfires:campfire", { + description = S("Campfire"), + inv_texture = "mcl_campfires_campfire_inv.png", + fire_texture = "mcl_campfires_campfire_fire.png", + lit_logs_texture = "mcl_campfires_campfire_log_lit.png", + drops = "mcl_core:charcoal_lump 2", + lightlevel = 14, + damage = 1, +}) + +-- Register Soul Campfire +mcl_campfires.register_campfire("mcl_campfires:soul_campfire", { + description = S("Soul Campfire"), + inv_texture = "mcl_campfires_soul_campfire_inv.png", + fire_texture = "mcl_campfires_soul_campfire_fire.png", + lit_logs_texture = "mcl_campfires_soul_campfire_log_lit.png", + drops = "mcl_blackstone:soul_soil", + lightlevel = 10, + damage = 2, +}) + +-- Register Campfire Crafting +minetest.register_craft({ + output = "mcl_campfires:campfire_lit", + recipe = { + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "group:coal", "mcl_core:stick" }, + { "group:tree", "group:tree", "group:tree" }, + } +}) + +minetest.register_craft({ + output = "mcl_campfires:soul_campfire_lit", + recipe = { + { "", "mcl_core:stick", "" }, + { "mcl_core:stick", "group:soul_block", "mcl_core:stick" }, + { "group:tree", "group:tree", "group:tree" }, + } +}) diff --git a/mods/ITEMS/mcl_cartography_table/README.md b/mods/ITEMS/mcl_cartography_table/README.md new file mode 100644 index 000000000..4818b6784 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/README.md @@ -0,0 +1,13 @@ +mcl_cartography_table +------------------- +Cartography Tables, by PrairieWind + +Adds Cartography Tables to MineClone 2/5. + +License of source code +---------------------- +LGPLv2.1 + +License of media +---------------- +See the main MineClone 2 README.md file. \ No newline at end of file diff --git a/mods/ITEMS/mcl_cartography_table/init.lua b/mods/ITEMS/mcl_cartography_table/init.lua new file mode 100644 index 000000000..dca9493ee --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/init.lua @@ -0,0 +1,28 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +-- Cartography Table Code. Used to create and copy maps. TODO: Needs a GUI still. + +minetest.register_node("mcl_cartography_table:cartography_table", { + description = S("Cartography Table"), + _tt_help = S("Used to create or copy maps"), + _doc_items_longdesc = S("Is used to create or copy maps for use.."), + tiles = { + "mcl_cartography_table_top.png", "mcl_cartography_table_side3.png", + "mcl_cartography_table_side3.png", "mcl_cartography_table_side2.png", + "mcl_cartography_table_side3.png", "mcl_cartography_table_side1.png" + }, + paramtype2 = "facedir", + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 + }) + + +minetest.register_craft({ + output = "mcl_cartography_table:cartography_table", + recipe = { + { "mcl_core:paper", "mcl_core:paper", "" }, + { "group:wood", "group:wood", "" }, + { "group:wood", "group:wood", "" }, + } +}) diff --git a/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr new file mode 100644 index 000000000..7f0b128d0 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table=Table de cartographie +Used to create or copy maps=Utilisée pour créer ou copier des cartes +Is used to create or copy maps for use..=Est utilisée pour créer ou copier des cartes.. diff --git a/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.tr new file mode 100644 index 000000000..91c01c2d0 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.ja.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_cartography_table/locale/mcl_cartography_table.pt_BR.tr b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.pt_BR.tr new file mode 100644 index 000000000..da5e8e0af --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/mcl_cartography_table.pt_BR.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_cartography_table +Cartography Table=Mesa de Cartografia +Used to create or copy maps=Utilizada para criar ou copiar mapas +Is used to create or copy maps for use..=É usada para criar ou copiar mapas para uso.. diff --git a/mods/ITEMS/mcl_cartography_table/locale/template.txt b/mods/ITEMS/mcl_cartography_table/locale/template.txt new file mode 100644 index 000000000..e85502e31 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/locale/template.txt @@ -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_cartography_table/mod.conf b/mods/ITEMS/mcl_cartography_table/mod.conf new file mode 100644 index 000000000..0a80c0111 --- /dev/null +++ b/mods/ITEMS/mcl_cartography_table/mod.conf @@ -0,0 +1,4 @@ +name = mcl_cartography_table +author = PrairieWind +depends = mcl_core, mcl_sounds, mcl_tools +description = Adds the cartography table villager workstation to MineClone 2/5. Used to copy and create maps. \ No newline at end of file diff --git a/mods/ITEMS/mcl_cauldrons/depends.txt b/mods/ITEMS/mcl_cauldrons/depends.txt deleted file mode 100644 index 2c344c60c..000000000 --- a/mods/ITEMS/mcl_cauldrons/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mclx_core? -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index a82a0b53a..c84e3bb88 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -1,11 +1,11 @@ -local S = minetest.get_translator("mcl_cauldron") +local S = minetest.get_translator(minetest.get_current_modname()) -- Cauldron mod, adds cauldrons. -- TODO: Extinguish fire of burning entities -- Convenience function because the cauldron nodeboxes are very similar -local create_cauldron_nodebox = function(water_level) +local function create_cauldron_nodebox(water_level) local floor_y if water_level == 0 then -- empty floor_y = -0.1875 @@ -36,25 +36,20 @@ local create_cauldron_nodebox = function(water_level) } end -local cauldron_nodeboxes = {} -for w=0,3 do - cauldron_nodeboxes[w] = create_cauldron_nodebox(w) -end - - -- Empty cauldron minetest.register_node("mcl_cauldrons:cauldron", { description = S("Cauldron"), _tt_help = S("Stores water"), - _doc_items_longdesc = S("Cauldrons are used to store water and slowly fill up under rain."), - _doc_items_usagehelp = S("Place a water pucket 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."), + _doc_items_longdesc = S("Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners."), + _doc_items_usagehelp = S("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."), wield_image = "mcl_cauldrons_cauldron.png", inventory_image = "mcl_cauldrons_cauldron.png", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, drawtype = "nodebox", paramtype = "light", is_ground_content = false, groups = {pickaxey=1, deco_block=1, cauldron=1}, - node_box = cauldron_nodeboxes[0], + node_box = create_cauldron_nodebox(0), selection_box = { type = "regular" }, tiles = { "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_top.png", @@ -67,24 +62,28 @@ minetest.register_node("mcl_cauldrons:cauldron", { }) -- Template function for cauldrons with water -local register_filled_cauldron = function(water_level, description, river_water) +local function register_filled_cauldron(water_level, description, liquid) local id = "mcl_cauldrons:cauldron_"..water_level local water_tex - if river_water then + if liquid == "river_water" then id = id .. "r" - water_tex = "default_river_water_source_animated.png^[verticalframe:16:0" + water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#0084FF" + elseif liquid == "lava" then + id = id .. "_lava" + water_tex = "default_lava_source_animated.png^[verticalframe:16:0" else - water_tex = "default_water_source_animated.png^[verticalframe:16:0" + water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" end minetest.register_node(id, { description = description, _doc_items_create_entry = false, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, drawtype = "nodebox", paramtype = "light", is_ground_content = false, groups = {pickaxey=1, not_in_creative_inventory=1, cauldron=(1+water_level), cauldron_filled=water_level, comparator_signal=water_level}, - node_box = cauldron_nodeboxes[water_level], - collision_box = cauldron_nodeboxes[0], + node_box = create_cauldron_nodebox(water_level), + collision_box = create_cauldron_nodebox(0), selection_box = { type = "regular" }, tiles = { "("..water_tex..")^mcl_cauldrons_cauldron_top.png", @@ -104,14 +103,12 @@ local register_filled_cauldron = function(water_level, description, river_water) end -- Filled cauldrons (3 levels) -register_filled_cauldron(1, S("Cauldron (1/3 Water)")) -register_filled_cauldron(2, S("Cauldron (2/3 Water)")) -register_filled_cauldron(3, S("Cauldron (3/3 Water)")) - -if minetest.get_modpath("mclx_core") then - register_filled_cauldron(1, S("Cauldron (1/3 River Water)"), true) - register_filled_cauldron(2, S("Cauldron (2/3 River Water)"), true) - register_filled_cauldron(3, S("Cauldron (3/3 River Water)"), true) +for i=1,3 do + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)")) + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)"),"lava") + if minetest.get_modpath("mclx_core") then + register_filled_cauldron(i, S("Cauldron (" ..i .. "/3 Water)"),"river_water") + end end minetest.register_craft({ @@ -123,19 +120,36 @@ minetest.register_craft({ } }) -minetest.register_abm({ - label = "cauldrons", - nodenames = {"group:cauldron_filled"}, - interval = 0.5, - chance = 1, - action = function(pos, node) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0.4)) do - if mcl_burning.is_burning(obj) then - mcl_burning.extinguish(obj) - local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 - minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)}) - break +local function cauldron_extinguish(obj,pos) + local node = minetest.get_node(pos) + if mcl_burning.is_burning(obj) then + mcl_burning.extinguish(obj) + local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 + minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)}) + end +end + +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 n = minetest.find_node_near(pl:get_pos(),0.4,{"group:cauldron_filled"},true) + if n and not minetest.get_node(n).name:find("lava") then + cauldron_extinguish(pl,n) + elseif n and minetest.get_node(n).name:find("lava") then + mcl_burning.set_on_fire(pl, 5) + end + end + for _,ent in pairs(minetest.luaentities) do + if ent.object:get_pos() and ent.is_mob then + local n = minetest.find_node_near(ent.object:get_pos(),0.4,{"group:cauldron_filled"},true) + if n and not minetest.get_node(n).name:find("lava") then + cauldron_extinguish(ent.object,n) + elseif n and minetest.get_node(n).name:find("lava") then + mcl_burning.set_on_fire(ent.object, 5) end end end -}) +end) diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr index 72432b04c..fa2ae6874 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.de.tr @@ -1,7 +1,7 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Kessel -Cauldrons are used to store water and slowly fill up under rain.=Kessel werden benutzt, um Wasser zu lagern, im Regen werden sie langsam aufgefüllt. -Place a water pucket 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.=Platzieren Sie einen Wassereinmer in den Kessel, um ihn mit Wasser zu füllen. Platzieren Sie einen leeren Eimer auf einen vollen Kessel, um das Wasser aufzusammeln. Platzieren Sie eine Wasserflasche in den Kessel, um ihn zu einem Drittel mit Wasser zu füllen. +Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Kessel werden benutzt, um Wasser zu lagern, im Regen werden sie langsam aufgefüllt. Kessel können auch verwendet werden, um Banner abzuwaschen. +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.=Platzieren Sie einen Wassereinmer in den Kessel, um ihn mit Wasser zu füllen. Platzieren Sie einen leeren Eimer auf einen vollen Kessel, um das Wasser aufzusammeln. Platzieren Sie eine Wasserflasche in den Kessel, um ihn zu einem Drittel mit Wasser zu füllen. Benutzen Sie ein bemaltes Banner auf den Kessel, um die oberste Schicht abzuwaschen. Cauldron (1/3 Water)=Kessel (1/3 Wasser) Cauldron (2/3 Water)=Kessel (2/3 Wasser) Cauldron (3/3 Water)=Kessel (3/3 Wasser) diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr index 5f7f9fc31..8222a93a6 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.es.tr @@ -1,10 +1,11 @@ -# textdomain: mcl_cauldron +# textdomain: mcl_cauldrons Cauldron=Caldera Cauldrons are used to store water and slowly fill up under rain.=Los calderos se usan para almacenar agua y llenarse lentamente bajo la lluvia. -Place a water pucket 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.=Coloque un cubo de agua en el caldero para llenarlo con agua. Coloque un cubo vacío en un caldero lleno para recuperar el agua. Coloque una botella de agua en el caldero para llenar el caldero hasta un tercio con agua. Coloque una botella de vidrio en un caldero con agua para recuperar un tercio del agua. +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.=Coloque un cubo de agua en el caldero para llenarlo con agua. Coloque un cubo vacío en un caldero lleno para recuperar el agua. Coloque una botella de agua en el caldero para llenar el caldero hasta un tercio con agua. Coloque una botella de vidrio en un caldero con agua para recuperar un tercio del agua. Cauldron (1/3 Water)=Caldera (1/3 de agua) Cauldron (2/3 Water)=Caldera (2/3 de agua) Cauldron (3/3 Water)=Caldera (3/3 de agua) Cauldron (1/3 River Water)=Caldera (1/3 de agua de río) Cauldron (2/3 River Water)=Caldera (2/3 de agua de río) -Cauldron (3/3 River Water)=Caldera (3/3 de agua de río) \ No newline at end of file +Cauldron (3/3 River Water)=Caldera (3/3 de agua de río) +Stores water=Almacena agua diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr new file mode 100644 index 000000000..da0a3495a --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.ja.tr @@ -0,0 +1,11 @@ +# 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.=大釜に水入りバケツを置くと、水で満たします。満杯の大釜に空のバケツを置くと、水を回収します。大釜に水入り瓶を置くと、大釜に1段階分(容積の1/3)の水を注ぎます。水入りの大釜にガラス瓶を置くと、大釜から1段階分の水を回収します。水入りの大釜にエンブレム入りの旗を使うと、その一番上にあるレイヤーを洗い落とします。 +Cauldron (1/3 Water)=大釜(水 1/3) +Cauldron (2/3 Water)=大釜(水 2/3) +Cauldron (3/3 Water)=大釜(水 3/3) +Cauldron (1/3 River Water)=大釜(河川水 1/3) +Cauldron (2/3 River Water)=大釜(河川水 2/3) +Cauldron (3/3 River Water)=大釜(河川水 3/3) +Stores water=水を溜めておく diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr new file mode 100644 index 000000000..32adf9851 --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pl.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_cauldrons +Cauldron=Kocioł +Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Kotły są wykorzystywane do przechowywania wody oraz powoli wypełniają się podczas deszczu. +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.=Umieść wiadro wody w kotle by wypełnić go wodą. Umieść puste wiadro na pełnym kotle by odzyskać wodę. Umieść szklaną butelkę w kotle z wodą aby odzyskać jedną trzecią wody. Użyj upiększonego sztandaru na kotle z wodą aby zmyć górną warstwę. +Cauldron (1/3 Water)=Kocioł (1/3 wody) +Cauldron (2/3 Water)=Kocioł (2/3 wody) +Cauldron (3/3 Water)=Kocioł (3/3 wody) +Cauldron (1/3 River Water)=Kocioł (1/3 rzecznej wody) +Cauldron (2/3 River Water)=Kocioł (2/3 rzecznej wody) +Cauldron (3/3 River Water)=Kocioł (3/3 rzecznej wody) +Stores water=Przechowuje wodę diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pt_BR.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pt_BR.tr new file mode 100644 index 000000000..5259b3822 --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.pt_BR.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_cauldrons +Cauldron=Caldeirão +Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Caldeirões são usados para armazenar água e acumular lentamente água da chuva. +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.=Coloque um balde com água no Caldeirão para enchê-lo com água. Coloque um balde vazio em um Caldeirão cheio para recuperar a água. Coloque uma garrafa com água no Caldeirão para preenchê-lo a um terço com água. Coloque uma garrafa de vidro no Caldeirão com água para recuperar um terço da água. Use um estandarte brasonado no Caldeirão com água para lavar sua primeira camada. +Cauldron (1/3 Water)=Caldeirão (1/3 Água) +Cauldron (2/3 Water)=Caldeirão (2/3 Água) +Cauldron (3/3 Water)=Caldeirão (3/3 Água) +Cauldron (1/3 River Water)=Caldeirão (1/3 Água de Rio) +Cauldron (2/3 River Water)=Caldeirão (2/3 Água de Rio) +Cauldron (3/3 River Water)=Caldeirão (3/3 Água de Rio) +Stores water=Armazena água diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr new file mode 100644 index 000000000..40e37e129 --- /dev/null +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_cauldrons.zh_TW.tr @@ -0,0 +1,11 @@ +# 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 pucket 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 水) +Cauldron (1/3 River Water)=鍋釜(1/3 河水) +Cauldron (2/3 River Water)=鍋釜(2/3 河水) +Cauldron (3/3 River Water)=鍋釜(3/3 河水) +Stores water=儲存水 diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr index 03b0e9be8..76c85e8e9 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.fr.tr @@ -1,7 +1,7 @@ -# textdomain: mcl_cauldron -Cauldron=Chaudrons +# textdomain: mcl_cauldrons +Cauldron=Chaudron Cauldrons are used to store water and slowly fill up under rain. They can also be used to wash off banners.=Les chaudrons sont utilisés pour stocker l'eau et se remplissent lentement sous la pluie. Ils peuvent également être utilisés pour laver les bannières. -Place a water pucket 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.=Placez une marmite d'eau dans le chaudron pour le remplir d'eau. Placez un seau vide sur un chaudron plein pour récupérer l'eau. Placez une bouteille d'eau dans le chaudron pour remplir le chaudron au tiers avec de l'eau. Placez une bouteille en verre dans un chaudron avec de l'eau pour récupérer un tiers de l'eau. Utilisez une bannière blasonnée sur un chaudron avec de l'eau pour laver sa couche supérieure. +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.=Placez une marmite d'eau dans le chaudron pour le remplir d'eau. Placez un seau vide sur un chaudron plein pour récupérer l'eau. Placez une bouteille d'eau dans le chaudron pour remplir le chaudron au tiers avec de l'eau. Placez une bouteille en verre dans un chaudron avec de l'eau pour récupérer un tiers de l'eau. Utilisez une bannière blasonnée sur un chaudron avec de l'eau pour laver sa couche supérieure. Cauldron (1/3 Water)=Chaudron (1/3 d'eau) Cauldron (2/3 Water)=Chaudron (2/3 d'eau) Cauldron (3/3 Water)=Chaudron (3/3 d'eau) diff --git a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr index ff43a5775..272ff7c44 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr +++ b/mods/ITEMS/mcl_cauldrons/locale/mcl_chaudrons.ru.tr @@ -1,7 +1,7 @@ -# textdomain: mcl_cauldron +# 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 pucket 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.=Попытайтесь поместить ведро воды в котёл, чтобы наполнить его водой. Попытка поместить пустое ведро приведёт к освобождению котла. Поместите в котёл бутылку воды, чтобы наполнить его на треть. +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_cauldrons/locale/template.txt b/mods/ITEMS/mcl_cauldrons/locale/template.txt index b4385631a..4c476e166 100644 --- a/mods/ITEMS/mcl_cauldrons/locale/template.txt +++ b/mods/ITEMS/mcl_cauldrons/locale/template.txt @@ -1,7 +1,7 @@ -# textdomain: mcl_cauldron +# 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 pucket 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.= +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)= Cauldron (2/3 Water)= Cauldron (3/3 Water)= diff --git a/mods/ITEMS/mcl_cauldrons/mod.conf b/mods/ITEMS/mcl_cauldrons/mod.conf index 1bedf9d73..36d5b303b 100644 --- a/mods/ITEMS/mcl_cauldrons/mod.conf +++ b/mods/ITEMS/mcl_cauldrons/mod.conf @@ -1 +1,3 @@ name = mcl_cauldrons +depends = mcl_core, mcl_sounds +optional_depends = mclx_core, doc, mcl_burning diff --git a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron.png b/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron.png deleted file mode 100644 index d373012fa..000000000 Binary files a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cherry_blossom/crafting.lua b/mods/ITEMS/mcl_cherry_blossom/crafting.lua new file mode 100644 index 000000000..f26b2af96 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/crafting.lua @@ -0,0 +1,86 @@ +-- Crafting +local planks = "mcl_cherry_blossom:cherrywood" +local logs = "mcl_cherry_blossom:cherrytree" +local stripped_logs = "mcl_cherry_blossom:stripped_cherrytree" + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherrytree_bark 3", + recipe = { + { logs, logs }, + { logs, logs }, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:stripped_cherrytree_bark 3", + recipe = { + { stripped_logs, stripped_logs }, + { stripped_logs, stripped_logs }, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherrywood 4", + recipe = { + { logs }, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherry_door 3", + recipe = { + {planks, planks}, + {planks, planks}, + {planks, planks} + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherry_trapdoor 2", + recipe = { + {planks, planks, planks}, + {planks, planks, planks}, + } +}) + +minetest.register_craft({ + output = "mcl_cherry_blossom:cherry_fence 3", + recipe = { + {planks, "mcl_core:stick", planks}, + {planks, "mcl_core:stick", planks}, + } +}) +minetest.register_craft({ + output = "mcl_cherry_blossom:cherry_fence_gate", + recipe = { + {"mcl_core:stick", planks, "mcl_core:stick"}, + {"mcl_core:stick", planks, "mcl_core:stick"}, + } +}) + +mcl_signs.register_sign_craft("mcl_cherry_blossom", "mcl_cherry_blossom:cherrywood", "_cherrywood") + +-- Smelting +minetest.register_craft({ + type = "fuel", + recipe = "mcl_cherry_blossom:cherry_door", + burntime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_cherry_blossom:cherry_trapdoor", + burntime = 15, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_cherry_blossom:pressure_plate_cherrywood_off", + burntime = 15 +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mesecons_button:button_cherrywood_off", + burntime = 5, +}) diff --git a/mods/ITEMS/mcl_cherry_blossom/growth.lua b/mods/ITEMS/mcl_cherry_blossom/growth.lua new file mode 100644 index 000000000..28cedea28 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/growth.lua @@ -0,0 +1,53 @@ +-- Tree Growth +-- TODO: Use better spawning behavior and wood api when wood api is finished. +function mcl_cherry_blossom.generate_cherry_tree(pos) + local pr = PseudoRandom(pos.x+pos.y+pos.z) + local r = pr:next(1,3) + local modpath = minetest.get_modpath("mcl_cherry_blossom") + local path = modpath.."/schematics/mcl_cherry_blossom_tree_"..tostring(r)..".mts" + if mcl_core.check_growth_width(pos,7,8) then + minetest.set_node(pos, {name = "air"}) + if r == 1 then + minetest.place_schematic(vector.offset(pos, -2, 0, -2), path, "random", nil, false) + elseif r == 2 then + minetest.place_schematic(vector.offset(pos, -2, 0, -2), path, nil, nil, false) + elseif r == 3 then + minetest.place_schematic(vector.offset(pos, -3, 0, -3), path, nil, nil, false) + end + end +end + +minetest.register_abm({ + label = "Cherry Tree Growth", + nodenames = "mcl_cherry_blossom:cherrysapling", + interval = 30, + chance = 5, + action = function(pos,node) + mcl_cherry_blossom.generate_cherry_tree(pos) + end, +}) + +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", + collision_removal = false, + collisiondetection = false, +} + + +minetest.register_abm({ + label = "Cherry Blossom Particles", + nodenames = {"mcl_cherry_blossom:cherryleaves"}, + interval = 5, + chance = 10, + action = function(pos, node) + minetest.after(math.random(0.1,1.5),function() + 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) + minetest.add_particle(pt) + end) + end +}) diff --git a/mods/ITEMS/mcl_cherry_blossom/init.lua b/mods/ITEMS/mcl_cherry_blossom/init.lua new file mode 100644 index 000000000..f80d198c3 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/init.lua @@ -0,0 +1,6 @@ +mcl_cherry_blossom = {} +local modpath = minetest.get_modpath("mcl_cherry_blossom") + +dofile(modpath.."/nodes.lua") -- Load Nodes +dofile(modpath.."/crafting.lua") -- Load Crafting Recipes +dofile(modpath.."/growth.lua") -- Load Cherry Blossom Tree Growth diff --git a/mods/ITEMS/mcl_cherry_blossom/locale/template.txt b/mods/ITEMS/mcl_cherry_blossom/locale/template.txt new file mode 100644 index 000000000..39ba7026a --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/locale/template.txt @@ -0,0 +1,24 @@ +# textdomain: mcl_cherry_blossom +Cherry Log= +The trunk of a cherry blossom tree.= +Stripped Cherry Log= +The stripped trunk of a cherry blossom tree.= +Cherry Bark= +This is a decorative block surrounded by the bark of a tree trunk.= +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 Sapling= +Cherry blossom sapling can be planted to grow cherry trees.= +Cherry Door= +Cherry Trapdoor= +Cherry Stairs= +Cherry Slab= +Double Cherry Slab= +Cherry Sign= +Cherry Fence= +Cherry Gate= +Cherry Pressure Plate= +Cherry Button= diff --git a/mods/ITEMS/mcl_cherry_blossom/mod.conf b/mods/ITEMS/mcl_cherry_blossom/mod.conf new file mode 100644 index 000000000..91c346e85 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/mod.conf @@ -0,0 +1,3 @@ +name = mcl_cherry_blossom +author = PrairieWind, Wbjitscool, SmokeyDope +depends = mcl_sounds, mcl_util, mcl_core, mcl_doors, mcl_stairs, mcl_signs, mcl_fences, mesecons_pressureplates, mesecons_button, mcl_boats diff --git a/mods/ITEMS/mcl_cherry_blossom/nodes.lua b/mods/ITEMS/mcl_cherry_blossom/nodes.lua new file mode 100644 index 000000000..4b6803123 --- /dev/null +++ b/mods/ITEMS/mcl_cherry_blossom/nodes.lua @@ -0,0 +1,96 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Logs +mcl_core.register_tree_trunk("cherrytree", S("Cherry Log"), S("Cherry Bark"), + S("The trunk of a cherry blossom tree."), + "mcl_cherry_blossom_log_top.png", "mcl_cherry_blossom_log.png", "mcl_cherry_blossom:stripped_cherrytree") + +-- Stripped +mcl_core.register_stripped_trunk("stripped_cherrytree", S("Stripped Cherry Log"), S("Stripped Cherry Wood"), + S("The stripped trunk of a cherry blossom tree."), S("The stripped wood of a cherry blossom tree."), + "mcl_cherry_blossom_log_top_stripped.png", "mcl_cherry_blossom_log_stripped.png") + +--Planks +mcl_core.register_wooden_planks("cherrywood", S("Cherry Wood Planks"), {"mcl_cherry_blossom_planks.png"}) + +-- Leaves +mcl_core.register_leaves("cherryleaves", S("Cherry Leaves"), + S("Cherry blossom leaves are grown from cherry blossom trees."), {"mcl_cherry_blossom_leaves.png"}, + nil, "none", nil, "mcl_cherry_blossom:cherrysapling", false, {20, 16, 12, 10}) + +-- Sapling +mcl_core.register_sapling("cherrysapling", S("Cherry Sapling"), + S("Cherry blossom sapling can be planted to grow cherry trees."), nil, + "mcl_cherry_blossom_sapling.png", {-4/16, -0.5, -4/16, 4/16, 0.25, 4/16}) + +-- Door and Trapdoor +mcl_doors:register_door("mcl_cherry_blossom:cherry_door", { + description = S("Cherry Door"), + inventory_image = "mcl_cherry_blossom_door_inv.png", + groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = "mcl_cherry_blossom_door_bottom.png", + tiles_top = "mcl_cherry_blossom_door_top.png", + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_cherry_blossom:cherry_trapdoor", { + description = S("Cherry Trapdoor"), + tile_front = "mcl_cherry_blossom_trapdoor.png", + tile_side = "mcl_cherry_blossom_trapdoor_side.png", + wield_image = "mcl_cherry_blossom_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +-- Stairs and Slabs +mcl_stairs.register_stair("cherrywood", "mcl_cherry_blossom:cherrywood", + {handy=1,axey=1, flammable=3,wood_stairs=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_cherry_blossom_planks.png"}, + S("Cherry Stairs"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + "woodlike") +mcl_stairs.register_slab("cherrywood", "mcl_cherry_blossom:cherrywood", + {handy=1,axey=1, flammable=3,wood_slab=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_cherry_blossom_planks.png"}, + S("Cherry Slab"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + S("Double Cherry Slab")) + +-- Signs +mcl_signs.register_sign_custom("mcl_cherry_blossom", "_cherrywood", + "mcl_cherry_blossom_sign.png", nil, + "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()) + +-- Redstone +mesecon.register_pressure_plate( + "mcl_cherry_blossom:pressure_plate_cherrywood", + S("Cherry Pressure Plate"), + {"mcl_cherry_blossom_planks.png"}, + {"mcl_cherry_blossom_planks.png"}, + "mcl_cherry_blossom_planks.png", + nil, + {{"mcl_cherry_blossom:cherrywood", "mcl_cherry_blossom:cherrywood"}}, + mcl_sounds.node_sound_wood_defaults(), + {axey=1, material_wood=1}, + nil) + +mesecon.register_button( + "cherrywood", + S("Cherry Button"), + "mcl_cherry_blossom_planks.png", + "mcl_cherry_blossom:cherrywood", + mcl_sounds.node_sound_wood_defaults(), + {material_wood=1,handy=1,axey=1}, + 1.5, + true, + nil, + "mesecons_button_push_wood") diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_1.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_1.mts new file mode 100644 index 000000000..1b06acf8f Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_1.mts differ diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_2.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_2.mts new file mode 100644 index 000000000..0434e56e1 Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_2.mts differ diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_3.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_3.mts new file mode 100644 index 000000000..d436b47bc Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_3.mts differ diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_1.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_1.mts new file mode 100644 index 000000000..6cc8a5825 Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_1.mts differ diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_2.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_2.mts new file mode 100644 index 000000000..67d17f34d Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_2.mts differ diff --git a/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_3.mts b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_3.mts new file mode 100644 index 000000000..872599716 Binary files /dev/null and b/mods/ITEMS/mcl_cherry_blossom/schematics/mcl_cherry_blossom_tree_beehive_3.mts differ diff --git a/mods/ITEMS/mcl_chests/depends.txt b/mods/ITEMS/mcl_chests/depends.txt deleted file mode 100644 index af11d5f6c..000000000 --- a/mods/ITEMS/mcl_chests/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_formspec -mcl_core -mcl_sounds -mcl_end -mesecons -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_chests/init.lua b/mods/ITEMS/mcl_chests/init.lua index 0f1e44c10..38437c73f 100644 --- a/mods/ITEMS/mcl_chests/init.lua +++ b/mods/ITEMS/mcl_chests/init.lua @@ -1,6 +1,43 @@ -local S = minetest.get_translator("mcl_chests") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") +-- 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 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"} +end + +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"} +end + +local tiles_chest_ender_small = {"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"} +end + -- Chest Entity local animate_chests = (minetest.settings:get_bool("animated_chests") ~= false) local entity_animations = { @@ -11,17 +48,14 @@ local entity_animations = { }, chest = { speed = 25, - open = {x = 0, y = 10}, - open_partly = {x = 0, y = 7}, - close = {x = 10, y = 20}, - close_partly = {x = 13, y = 20}, + open = {x = 0, y = 7}, + close = {x = 13, y = 20}, } } minetest.register_entity("mcl_chests:chest", { initial_properties = { visual = "mesh", - visual_size = {x = 3, y = 3}, pointable = false, physical = false, static_save = false, @@ -34,15 +68,12 @@ minetest.register_entity("mcl_chests:chest", { self.object:set_animation(anim, anim_table.speed, 0, false) end, - open = function(self, playername, partly) + open = function(self, playername) self.players[playername] = true if not self.is_open then - self:set_animation(partly and "open_partly" or "open") - minetest.sound_play(self.sound_prefix .. "_open", { - pos = self.node_pos, - }) + self:set_animation("open") + minetest.sound_play(self.sound_prefix .. "_open", {pos=self.node_pos, gain=0.5, max_hear_distance = 16}, true) self.is_open = true - self.opened_partly = partly end end, @@ -50,15 +81,12 @@ minetest.register_entity("mcl_chests:chest", { local playerlist = self.players playerlist[playername] = nil if self.is_open then - for _ in pairs(playerlist) do + if next(playerlist) then return end - self:set_animation(self.opened_partly and "close_partly" or "close") - minetest.sound_play(self.sound_prefix .. "_close", { - pos = self.node_pos, - }) + self:set_animation("close") + minetest.sound_play(self.sound_prefix .. "_close", {pos=self.node_pos, gain=0.3, max_hear_distance = 16}, true) self.is_open = false - self.opened_partly = false end end, @@ -109,7 +137,6 @@ minetest.register_entity("mcl_chests:chest", { local function get_entity_pos(pos, dir, double) pos = vector.new(pos) - pos.y = pos.y - 0.49 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)) @@ -118,7 +145,7 @@ local function get_entity_pos(pos, dir, double) end local function find_entity(pos) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0)) do local luaentity = obj:get_luaentity() if luaentity and luaentity.name == "mcl_chests:chest" then return luaentity @@ -162,30 +189,30 @@ end --[[ List of open chests. Key: Player name Value: - If player is using a chest: { pos = } - Otherwise: nil ]] + If player is using a chest: { pos = } + Otherwise: nil ]] local open_chests = {} -local function back_is_blocked(pos, dir) +--[[local function back_is_blocked(pos, dir) pos = vector.add(pos, dir) local def = minetest.registered_nodes[minetest.get_node(pos).name] pos.y = pos.y + 1 local def2 = minetest.registered_nodes[minetest.get_node(pos).name] return not def or def.groups.opaque == 1 or not def2 or def2.groups.opaque == 1 -end +end]] + -- To be called if a player opened a chest -local player_chest_open = function(player, pos, node_name, textures, param2, double, sound, mesh, shulker) +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} if animate_chests then local dir = minetest.facedir_to_dir(param2) - local blocked = not shulker and (back_is_blocked(pos, dir) or double and back_is_blocked(mcl_util.get_double_container_neighbor_pos(pos, param2, node_name:sub(-4)), dir)) - find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name, blocked) + find_or_create_entity(pos, node_name, textures, param2, double, sound, mesh, shulker and "shulker" or "chest", dir):open(name) end end -- Simple protection checking functions -local protection_check_move = function(pos, from_list, from_index, to_list, to_index, count, player) +local function protection_check_move(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) @@ -194,7 +221,7 @@ local protection_check_move = function(pos, from_list, from_index, to_list, to_i return count end end -local protection_check_put_take = function(pos, listname, index, stack, player) +local function protection_check_put_take(pos, listname, index, stack, player) local name = player:get_player_name() if minetest.is_protected(pos, name) then minetest.record_protection_violation(pos, name) @@ -207,7 +234,7 @@ end local trapped_chest_mesecons_rules = mesecon.rules.pplate -- To be called when a chest is closed (only relevant for trapped chest atm) -local chest_update_after_close = function(pos) +local function chest_update_after_close(pos) local node = minetest.get_node(pos) if node.name == "mcl_chests:trapped_chest_on_small" then @@ -216,7 +243,7 @@ local chest_update_after_close = function(pos) 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + 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") @@ -228,13 +255,13 @@ local chest_update_after_close = function(pos) 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + 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 -- To be called if a player closed a chest -local player_chest_close = function(player) +local function player_chest_close(player) local name = player:get_player_name() local open_chest = open_chests[name] if open_chest == nil then @@ -249,566 +276,556 @@ local player_chest_close = function(player) end -- This is a helper function to register both chests and trapped chests. Trapped chests will make use of the additional parameters -local register_chest = function(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 -else - 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. -if not canonical_basename then - canonical_basename = basename -end - -local double_chest_add_item = function(top_inv, bottom_inv, listname, stack) - if not stack or stack:is_empty() then - return +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 + else + 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. + if not canonical_basename then + canonical_basename = basename end - local name = stack:get_name() + local function double_chest_add_item(top_inv, bottom_inv, listname, stack) + if not stack or stack:is_empty() then + return + end - local top_off = function(inv, stack) - for c, chest_stack in ipairs(inv:get_list(listname)) do + local name = stack:get_name() + + local function top_off(inv, stack) + for c, chest_stack in ipairs(inv:get_list(listname)) do + if stack:is_empty() then + break + end + + if chest_stack:get_name() == name and chest_stack:get_free_space() > 0 then + stack = chest_stack:add_item(stack) + inv:set_stack(listname, c, chest_stack) + end + end + + return stack + end + + stack = top_off(top_inv, stack) + stack = top_off(bottom_inv, stack) + + if not stack:is_empty() then + stack = top_inv:add_item(listname, stack) + if not stack:is_empty() then + bottom_inv:add_item(listname, stack) + end + end + end + + local drop_items_chest = mcl_util.drop_items_from_meta_container("main") + + local function on_chest_blast(pos) + local node = minetest.get_node(pos) + drop_items_chest(pos, node) + minetest.remove_node(pos) + end + + local function limit_put_list(stack, list) + for _, other in ipairs(list) do + stack = other:add_item(stack) if stack:is_empty() then break end - - if chest_stack:get_name() == name and chest_stack:get_free_space() > 0 then - stack = chest_stack:add_item(stack) - inv:set_stack(listname, c, chest_stack) - end end - return stack end - stack = top_off(top_inv, stack) - stack = top_off(bottom_inv, stack) + local function limit_put(stack, inv1, inv2) + local leftover = ItemStack(stack) + leftover = limit_put_list(leftover, inv1:get_list("main")) + leftover = limit_put_list(leftover, inv2:get_list("main")) + return stack:get_count() - leftover:get_count() + end - if not stack:is_empty() then - stack = top_inv:add_item(listname, stack) - if not stack:is_empty() then - bottom_inv:add_item(listname, stack) + local small_name = "mcl_chests:"..basename.."_small" + local small_textures = tiles_table.small + local left_name = "mcl_chests:"..basename.."_left" + local left_textures = tiles_table.double + + minetest.register_node("mcl_chests:"..basename, { + description = desc, + _tt_help = tt_help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + _doc_items_hidden = hidden, + drawtype = "mesh", + mesh = "mcl_chests_chest.b3d", + tiles = small_textures, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sounds = mcl_sounds.node_sound_wood_defaults(), + groups = {deco_block=1}, + on_construct = function(pos, node) + local node = minetest.get_node(pos) + node.name = small_name + minetest.set_node(pos, node) + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) + end, + }) + + local function close_forms(canonical_basename, pos) + local players = minetest.get_connected_players() + 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) + end end end -end -local drop_items_chest = function(pos, oldnode, oldmetadata) - local meta = minetest.get_meta(pos) - local meta2 = meta - if oldmetadata then - meta:from_table(oldmetadata) - end - local inv = meta:get_inventory() - 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) - end - end - meta:from_table(meta2:to_table()) -end + minetest.register_node(small_name, { + description = desc, + _tt_help = tt_help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + _doc_items_hidden = hidden, + drawtype = "nodebox", + node_box = { + type = "fixed", + 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, + _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}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_wood_defaults(), + on_construct = function(pos) + local param2 = minetest.get_node(pos).param2 + local meta = minetest.get_meta(pos) + --[[ This is a workaround for Minetest issue 5894 + . + Apparently if we don't do this, large chests initially don't work when + placed at chunk borders, and some chests randomly don't work after + placing. ]] + -- FIXME: Remove this workaround when the bug has been fixed. + -- BEGIN OF WORKAROUND -- + meta:set_string("workaround", "ignore_me") + meta:set_string("workaround", nil) -- Done to keep metadata clean + -- END OF WORKAROUND -- + local inv = meta:get_inventory() + 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 . + This list is a hidden input-only list and immediately puts items into the appropriate chest. + It is only used for listrings and hoppers. This workaround is not that bad because it only + requires a simple “inventory allows” check for large chests.]] + -- FIXME: Refactor the listrings as soon Minetest supports alternative listrings + -- 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}) + 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") + local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") + 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") + end + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) + end, + after_dig_node = drop_items_chest, + on_blast = on_chest_blast, + 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 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)) + -- BEGIN OF LISTRING WORKAROUND + if listname == "input" then + 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)) + end, + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5, -local on_chest_blast = function(pos) - local node = minetest.get_node(pos) - drop_items_chest(pos, node) - minetest.remove_node(pos) -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 + end + local name = minetest.get_meta(pos):get_string("name") + if name == "" then + name = S("Chest") + end -local function limit_put_list(stack, list) - for _, other in ipairs(list) do - stack = other:add_item(stack) - if stack:is_empty() then - break - end - end - return stack -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]") -local function limit_put(stack, inv1, inv2) - local leftover = ItemStack(stack) - leftover = limit_put_list(leftover, inv1:get_list("main")) - leftover = limit_put_list(leftover, inv2:get_list("main")) - return stack:get_count() - leftover:get_count() -end + if on_rightclick_addendum then + on_rightclick_addendum(pos, node, clicker) + end -local small_name = "mcl_chests:"..basename.."_small" -local small_textures = tiles_table.small -local left_name = "mcl_chests:"..basename.."_left" -local left_textures = tiles_table.double + player_chest_open(clicker, pos, small_name, small_textures, node.param2, false, "default_chest", "mcl_chests_chest") + end, -minetest.register_node("mcl_chests:"..basename, { - description = desc, - _tt_help = tt_help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - _doc_items_hidden = hidden, - drawtype = "mesh", - mesh = "mcl_chests_chest.obj", - tiles = small_textures, - paramtype = "light", - paramtype2 = "facedir", - stack_max = 64, - sounds = mcl_sounds.node_sound_wood_defaults(), - groups = {deco_block=1}, - on_construct = function(pos, node) - local node = minetest.get_node(pos) - node.name = small_name - minetest.set_node(pos, node) - end, - after_place_node = function(pos, placer, itemstack, pointed_thing) - minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) - end, -}) + on_destruct = function(pos) + close_forms(canonical_basename, pos) + end, + mesecons = mesecons, + on_rotate = simple_rotate, + }) -local function close_forms(canonical_basename, pos) - local players = minetest.get_connected_players() - 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) - end - end -end - -minetest.register_node(small_name, { - description = desc, - _tt_help = tt_help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - _doc_items_hidden = hidden, - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.4375, 0.375, 0.4375}, - }, - tiles = {"mcl_chests_blank.png"}, - _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}, - is_ground_content = false, - sounds = mcl_sounds.node_sound_wood_defaults(), - on_construct = function(pos) - local param2 = minetest.get_node(pos).param2 - local meta = minetest.get_meta(pos) - --[[ This is a workaround for Minetest issue 5894 - . - Apparently if we don't do this, large chests initially don't work when - placed at chunk borders, and some chests randomly don't work after - placing. ]] - -- FIXME: Remove this workaround when the bug has been fixed. - -- BEGIN OF WORKAROUND -- - meta:set_string("workaround", "ignore_me") - meta:set_string("workaround", nil) -- Done to keep metadata clean - -- END OF WORKAROUND -- - local inv = meta:get_inventory() - 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 . - This list is a hidden input-only list and immediately puts items into the appropriate chest. - It is only used for listrings and hoppers. This workaround is not that bad because it only - requires a simple “inventory allows” check for large chests.]] - -- FIXME: Refactor the listrings as soon Minetest supports alternative listrings - -- 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}) - 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.register_node(left_name, { + drawtype = "nodebox", + node_box = { + type = "fixed", + 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, + _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}, + drop = drop, + is_ground_content = false, + sounds = mcl_sounds.node_sound_wood_defaults(), + on_construct = function(pos) + local n = minetest.get_node(pos) + local param2 = n.param2 local p = mcl_util.get_double_container_neighbor_pos(pos, param2, "left") - 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") - end - end, - after_place_node = function(pos, placer, itemstack, pointed_thing) - minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) - end, - after_dig_node = drop_items_chest, - on_blast = on_chest_blast, - 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 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)) - -- BEGIN OF LISTRING WORKAROUND - if listname == "input" then - 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)) - end, - _mcl_blast_resistance = 2.5, - _mcl_hardness = 2.5, + 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") + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) + end, + on_destruct = function(pos) + local n = minetest.get_node(pos) + if n.name == small_name then + return + 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 - end - local name = minetest.get_meta(pos):get_string("name") - if name == "" then - name = S("Chest") - end + close_forms(canonical_basename, pos) - 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]") + 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 + return + end + close_forms(canonical_basename, p) - 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") - end, - - on_destruct = function(pos) - close_forms(canonical_basename, pos) - end, - mesecons = mesecons, - on_rotate = simple_rotate, -}) - -minetest.register_node(left_name, { - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = {-0.4375, -0.5, -0.4375, 0.5, 0.375, 0.4375}, - }, - tiles = {"mcl_chests_blank.png"}, - _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}, - drop = drop, - is_ground_content = false, - sounds = mcl_sounds.node_sound_wood_defaults(), - on_construct = function(pos) - 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" - minetest.swap_node(pos, n) - end - create_entity(pos, left_name, left_textures, param2, true, "default_chest", "mcl_chests_chest", "chest") - end, - after_place_node = function(pos, placer, itemstack, pointed_thing) - minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) - end, - on_destruct = function(pos) - local n = minetest.get_node(pos) - if n.name == small_name then - return - end - - close_forms(canonical_basename, 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:"..basename.."_right" then - return - end - close_forms(canonical_basename, p) - - minetest.swap_node(p, { name = small_name, param2 = param2 }) - create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") - end, - after_dig_node = drop_items_chest, - on_blast = on_chest_blast, - allow_metadata_inventory_move = protection_check_move, - allow_metadata_inventory_take = protection_check_put_take, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - -- BEGIN OF LISTRING WORKAROUND - elseif listname == "input" then - 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}) - return limit_put(stack, inv, other_inv) - --[[if inv:room_for_item("main", stack) then - return -1 - else - - if other_inv:room_for_item("main", stack) then + minetest.swap_node(p, { name = small_name, param2 = param2 }) + create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") + end, + after_dig_node = drop_items_chest, + on_blast = on_chest_blast, + allow_metadata_inventory_move = protection_check_move, + allow_metadata_inventory_take = protection_check_put_take, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + -- BEGIN OF LISTRING WORKAROUND + elseif listname == "input" then + 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}) + return limit_put(stack, inv, other_inv) + --[[if inv:room_for_item("main", stack) then return -1 else - return 0 - end - 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)) - 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)) - -- BEGIN OF LISTRING WORKAROUND - if listname == "input" then - 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}) - inv:set_stack("input", 1, nil) + if other_inv:room_for_item("main", stack) then + return -1 + else + return 0 + end + 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)) + 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)) + -- BEGIN OF LISTRING WORKAROUND + if listname == "input" then + 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}) - double_chest_add_item(inv, other_inv, "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)) - end, - _mcl_blast_resistance = 2.5, - _mcl_hardness = 2.5, + inv:set_stack("input", 1, nil) - on_rightclick = function(pos, node, clicker) - local pos_other = mcl_util.get_double_container_neighbor_pos(pos, node.param2, "left") - 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 + double_chest_add_item(inv, other_inv, "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)) + 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] + + 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 return false - end + end - local name = minetest.get_meta(pos):get_string("name") - if name == "" then - name = minetest.get_meta(pos_other):get_string("name") - end - if name == "" then - name = S("Large Chest") - end + local name = minetest.get_meta(pos):get_string("name") + if name == "" then + name = minetest.get_meta(pos_other):get_string("name") + end + if name == "" then + name = S("Large Chest") + 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]") + 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]") - if on_rightclick_addendum_left then - on_rightclick_addendum_left(pos, node, clicker) - end + 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") - end, - mesecons = mesecons, - on_rotate = no_rotate, -}) + player_chest_open(clicker, pos, left_name, left_textures, node.param2, true, "default_chest", "mcl_chests_chest") + end, + mesecons = mesecons, + on_rotate = no_rotate, + }) -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}, - }, - tiles = {"mcl_chests_blank.png"}, - 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(), - on_construct = function(pos) - 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" - minetest.swap_node(pos, n) - end - end, - after_place_node = function(pos, placer, itemstack, pointed_thing) - minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) - end, - on_destruct = function(pos) - local n = minetest.get_node(pos) - if n.name == small_name then - return - end + 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}, + }, + 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(), + on_construct = function(pos) + 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" + minetest.swap_node(pos, n) + end + end, + after_place_node = function(pos, placer, itemstack, pointed_thing) + minetest.get_meta(pos):set_string("name", itemstack:get_meta():get_string("name")) + end, + on_destruct = function(pos) + local n = minetest.get_node(pos) + if n.name == small_name then + return + end - close_forms(canonical_basename, pos) + close_forms(canonical_basename, 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:"..basename.."_left" then - return - end - close_forms(canonical_basename, p) + 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 + return + end + close_forms(canonical_basename, p) - minetest.swap_node(p, { name = small_name, param2 = param2 }) - create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") - local meta = minetest.get_meta(pos) - end, - after_dig_node = drop_items_chest, - on_blast = on_chest_blast, - allow_metadata_inventory_move = protection_check_move, - allow_metadata_inventory_take = protection_check_put_take, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - -- 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}) - --[[if other_inv:room_for_item("main", stack) then - return -1 - else - if inv:room_for_item("main", stack) then + minetest.swap_node(p, { name = small_name, param2 = param2 }) + create_entity(p, small_name, small_textures, param2, false, "default_chest", "mcl_chests_chest", "chest") + end, + after_dig_node = drop_items_chest, + on_blast = on_chest_blast, + allow_metadata_inventory_move = protection_check_move, + allow_metadata_inventory_take = protection_check_put_take, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + -- 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}) + --[[if other_inv:room_for_item("main", stack) then return -1 else - return 0 - end - end--]] - return limit_put(stack, other_inv, inv) - -- 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)) - 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)) - -- 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}) + if inv:room_for_item("main", stack) then + return -1 + else + return 0 + end + end--]] + return limit_put(stack, other_inv, inv) + -- 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)) + 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)) + -- 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}) - inv:set_stack("input", 1, nil) + inv:set_stack("input", 1, nil) - double_chest_add_item(other_inv, inv, "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)) - end, - _mcl_blast_resistance = 2.5, - _mcl_hardness = 2.5, + double_chest_add_item(other_inv, inv, "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)) + 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 - end + 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 + end - local name = minetest.get_meta(pos_other):get_string("name") - if name == "" then - name = minetest.get_meta(pos):get_string("name") - end - if name == "" then - name = S("Large Chest") - end + local name = minetest.get_meta(pos_other):get_string("name") + if name == "" then + name = minetest.get_meta(pos):get_string("name") + end + if name == "" then + name = S("Large Chest") + end - minetest.show_formspec(clicker:get_player_name(), - "mcl_chests:"..canonical_basename.."_"..pos.x.."_"..pos.y.."_"..pos.z, + 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_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]") + "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]") - if on_rightclick_addendum_right then - on_rightclick_addendum_right(pos, node, clicker) - end + 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") - end, - mesecons = mesecons, - on_rotate = no_rotate, -}) + 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, + }) -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") -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") + end --- END OF register_chest FUNCTION BODY + -- END OF register_chest FUNCTION BODY end local chestusage = S("To access its inventory, rightclick it. When broken, the items will drop out.") @@ -819,33 +836,15 @@ register_chest("chest", chestusage, S("27 inventory slots") .. "\n" .. S("Can be combined to a large chest"), { - small = {"mcl_chests_normal.png"}, - double = {"mcl_chests_normal_double.png"}, - 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"},]]-- + small = tiles_chest_normal_small, + double = tiles_chest_normal_double, }, false ) local traptiles = { - small = {"mcl_chests_trapped.png"}, - double = {"mcl_chests_trapped_double.png"}, - inv = {"mcl_chests_chest_trapped_top.png", "mcl_chests_chest_trapped_bottom.png", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_back.png", "mcl_chests_chest_trapped_front.png"}, - --[[left = {"mcl_chests_chest_trapped_top_big.png", "mcl_chests_chest_trapped_top_big.png", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_side_big.png^[transformFX", "mcl_chests_chest_trapped_front_big.png"}, - right = {"mcl_chests_chest_trapped_top_big.png^[transformFX", "mcl_chests_chest_trapped_top_big.png^[transformFX", - "mcl_chests_chest_trapped_right.png", "mcl_chests_chest_trapped_left.png", - "mcl_chests_chest_trapped_side_big.png", "mcl_chests_chest_trapped_front_big.png^[transformFX"},]]-- + small = tiles_chest_trapped_small, + double = tiles_chest_trapped_double, } register_chest("trapped_chest", @@ -869,7 +868,7 @@ register_chest("trapped_chest", 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + 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") @@ -883,7 +882,7 @@ register_chest("trapped_chest", 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_on_left") + 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 ) @@ -899,7 +898,7 @@ register_chest("trapped_chest_on", "trapped_chest" ) -local function close_if_trapped_chest(pos, player) +--[[local function close_if_trapped_chest(pos, player) local node = minetest.get_node(pos) if node.name == "mcl_chests:trapped_chest_on_small" then @@ -910,7 +909,7 @@ local function close_if_trapped_chest(pos, player) player_chest_close(player) 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + 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") @@ -924,12 +923,12 @@ local function close_if_trapped_chest(pos, player) 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", {"mcl_chests_trapped_double.png"}, node.param2, true, "default_chest", "mcl_chests_chest", "chest"):reinitialize("mcl_chests:trapped_chest_left") + 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) player_chest_close(player) end -end +end]] -- Disable chest when it has been closed minetest.register_on_player_receive_fields(function(player, formname, fields) @@ -945,23 +944,23 @@ minetest.register_on_leaveplayer(function(player) end) minetest.register_craft({ - output = 'mcl_chests:chest', + 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', + type = "fuel", + recipe = "mcl_chests:chest", burntime = 15 }) minetest.register_craft({ - type = 'fuel', - recipe = 'mcl_chests:trapped_chest', + type = "fuel", + recipe = "mcl_chests:trapped_chest", burntime = 15 }) @@ -971,8 +970,9 @@ minetest.register_node("mcl_chests: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.obj", - tiles = {"mcl_chests_ender.png"}, + mesh = "mcl_chests_chest.b3d", + tiles = tiles_chest_ender_small, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", stack_max = 64, @@ -1006,16 +1006,14 @@ minetest.register_node("mcl_chests:ender_chest_small", { 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.4375, 0.375, 0.4375}, }, - _chest_entity_textures = {"mcl_chests_ender.png"}, + _chest_entity_textures = ender_chest_texture, _chest_entity_sound = "mcl_chests_enderchest", _chest_entity_mesh = "mcl_chests_chest", _chest_entity_animation_type = "chest", - tiles = {"mcl_chests_blank.png"}, - --[[{"mcl_chests_ender_chest_top.png", "mcl_chests_ender_chest_bottom.png", - "mcl_chests_ender_chest_right.png", "mcl_chests_ender_chest_left.png", - "mcl_chests_ender_chest_back.png", "mcl_chests_ender_chest_front.png"},]]-- + tiles = {"blank.png^[resize:16x16"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, -- 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}, @@ -1026,12 +1024,15 @@ minetest.register_node("mcl_chests:ender_chest_small", { sounds = mcl_sounds.node_sound_stone_defaults(), drop = "mcl_core:obsidian 8", on_construct = function(pos) - local meta = minetest.get_meta(pos) - meta:set_string("formspec", formspec_ender_chest) - create_entity(pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, 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) - player_chest_open(clicker, pos, "mcl_chests:ender_chest_small", {"mcl_chests_ender.png"}, node.param2, false, "mcl_chests_enderchest", "mcl_chests_chest") + 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 + 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") end, on_receive_fields = function(pos, formname, fields, sender) if fields.quit then @@ -1049,12 +1050,26 @@ minetest.register_on_joinplayer(function(player) 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 + 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 + return 0 + end + end +end) + minetest.register_craft({ - output = 'mcl_chests:ender_chest', + 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"}, } }) @@ -1104,14 +1119,14 @@ local function formspec_shulker_box(name) end return "size[9,8.75]".. "label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", name)).."]".. - "list[current_name;main;0,0.5;9,3;]".. + "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[current_name;main]".. + "listring[context;main]".. "listring[current_player;main]" end @@ -1129,7 +1144,7 @@ for color, desc in pairs(boxtypes) do 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.") + 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 @@ -1146,14 +1161,9 @@ for color, desc in pairs(boxtypes) do _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, drawtype = "mesh", - mesh = "mcl_chests_shulker.obj", - --[["mcl_chests_"..color.."_shulker_box_top.png", -- top - "[combine:16x16:-32,-28="..mob_texture, -- bottom - "[combine:16x16:0,-36="..mob_texture..":0,-16="..mob_texture, -- side - "[combine:16x16:-32,-36="..mob_texture..":-32,-16="..mob_texture, -- side - "[combine:16x16:-16,-36="..mob_texture..":-16,-16="..mob_texture, -- side - "[combine:16x16:-48,-36="..mob_texture..":-48,-16="..mob_texture, -- side]]-- + 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}, is_ground_content = false, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -1209,7 +1219,12 @@ for color, desc in pairs(boxtypes) do _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, drawtype = "nodebox", - tiles = {"mcl_chests_blank.png"}, + node_box = { + type = "fixed", + 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}, _chest_entity_sound = "mcl_chests_shulker", _chest_entity_mesh = "mcl_chests_shulker", @@ -1308,23 +1323,22 @@ for color, desc in pairs(boxtypes) do 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 minetest.register_craft({ - output = 'mcl_chests:violet_shulker_box', + 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 minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) - local new = itemstack:get_name() if minetest.get_item_group(itemstack:get_name(), "shulker_box") ~= 1 then return end @@ -1348,7 +1362,7 @@ 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 - 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({ @@ -1403,3 +1417,13 @@ minetest.register_lbm({ meta:set_string("formspec", formspec_shulker_box) end, }) + +minetest.register_lbm({ + label = "Upgrade old ender chest formspec", + name = "mcl_chests:replace_old_ender_form", + nodenames = {"mcl_chests:ender_chest_small"}, + run_at_every_load = false, + action = function(pos, node) + minetest.get_meta(pos):set_string("formspec", "") + end, +}) diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.es.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.es.tr index 9d44bacca..ef3e0d9e3 100644 --- a/mods/ITEMS/mcl_chests/locale/mcl_chests.es.tr +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.es.tr @@ -28,3 +28,9 @@ To access the inventory of a shulker box, place and right-click it. To take a sh Shulker Box=Caja de shulker Large Chest=Arcón Inventory=Inventario +27 inventory slots=27 ranuras de inventario +Can be carried around with its contents=Puede llevarse con sus contenidos +Can be combined to a large chest=Se puede combinar para convertirse en un cofre grande +27 interdimensional inventory slots=27 ranuras de inventario interdimensionales +Put items inside, retrieve them from any ender chest=Pon objetos dentro, recupéralos desde cualquier cofre de ender +Emits a redstone signal when opened=Emite una señal de redstone al abrirse diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.fr.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.fr.tr index b84dac022..a9bf3672e 100644 --- a/mods/ITEMS/mcl_chests/locale/mcl_chests.fr.tr +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.fr.tr @@ -2,35 +2,35 @@ Chest=Coffre 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.=Les coffres sont des conteneurs qui offrent 27 emplacements d'inventaire. Les coffres peuvent être transformés en grands coffres avec une capacité double en plaçant deux coffres l'un à côté de l'autre. To access its inventory, rightclick it. When broken, the items will drop out.=Pour accéder à son inventaire, faites un clic droit dessus. Une fois cassés, les articles tomberont. -Trapped Chest=Coffre Piégé +Trapped Chest=Coffre piégé 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.=Un coffre piégé est un conteneur qui fournit 27 emplacements d'inventaire. Lorsqu'il est ouvert, il envoie un signal redstone à ses blocs adjacents tant qu'il reste ouvert. Les coffres piégés peuvent être transformés en grands coffres piégés avec une capacité double en plaçant deux coffres piégés l'un à côté de l'autre. Ender Chest=Coffre Ender 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.=Les coffres Ender vous donnent accès à un seul inventaire interdimensionnel personnel avec 27 emplacements. Cet inventaire est le même quel que soit le coffre d'ender d'où vous y accédez. Si vous placez un objet dans un coffre d'ender, vous le trouverez dans tous les autres coffres d'ender. Chaque joueur ne verra que ses propres objets, mais pas ceux des autres joueurs. Rightclick the ender chest to access your personal interdimensional inventory.=Faites un clic droit sur le coffre d'ender pour accéder à votre inventaire interdimensionnel personnel. -White Shulker Box=Boîte de Shulter Blanche -Light Grey Shulker Box=Boîte de Shulter Gris Clair -Orange Shulker Box=Boîte de Shulter Orange -Cyan Shulker Box=Boîte de Shulter Cyan -Magenta Shulker Box=Boîte de Shulter Magenta -Purple Shulker Box=Boîte de Shulter Violette -Light Blue Shulker Box=Boîte de Shulter Bleu Clair -Blue Shulker Box=Boîte de Shulter Bleue -Yellow Shulker Box=Boîte de Shulter Jaune -Brown Shulker Box=Boîte de Shulter Marron -Lime Shulker Box=Boîte de Shulter Vert Clair -Green Shulker Box=Boîte de Shulter Verte -Pink Shulker Box=Boîte de Shulter Rose -Red Shulker Box=Boîte de Shulter Rouge -Grey Shulker Box=Boîte de Shulter Grise -Black Shulker Box=Boîte de Shulter Noire -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.=Une boîte shulker est un conteneur portable qui fournit 27 emplacements d'inventaire pour tout article, à l'exception des boîtes shulker. Les boîtes Shulker conservent leur inventaire lorsqu'elles sont brisées, de sorte que les boîtes Shulker ainsi que leur contenu peuvent être considérés comme un seul élément. Les boîtes Shulker sont disponibles dans de nombreuses couleurs différentes. -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.=Pour accéder à l'inventaire d'une boîte shulker, placez-la et cliquez dessus avec le bouton droit. Pour emporter une boîte shulker et son contenu, il suffit de la casser et de la récupérer, les objets ne tomberont pas. Replacez la boîte shulker pour pouvoir récupérer son contenu. -Shulker Box=Boîte de Shulter -Large Chest=Coffre Large +White Shulker Box=Boîte de Shulker blanche +Light Grey Shulker Box=Boîte de Shulker gris clair +Orange Shulker Box=Boîte de Shulker orange +Cyan Shulker Box=Boîte de Shulker cyan +Magenta Shulker Box=Boîte de Shulker magenta +Purple Shulker Box=Boîte de Shulker violette +Light Blue Shulker Box=Boîte de Shulker bleu clair +Blue Shulker Box=Boîte de Shulker bleue +Yellow Shulker Box=Boîte de Shulker jaune +Brown Shulker Box=Boîte de Shulker marron +Lime Shulker Box=Boîte de Shulker vert clair +Green Shulker Box=Boîte de Shulker verte +Pink Shulker Box=Boîte de Shulker rose +Red Shulker Box=Boîte de Shulker rouge +Grey Shulker Box=Boîte de Shulker grise +Black Shulker Box=Boîte de Shulker noire +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.=Une boîte de Shulker est un conteneur portable qui fournit 27 emplacements d'inventaire pour tout article, à l'exception des boîtes de Shulker. Les boîtes de Shulker conservent leur inventaire lorsqu'elles sont brisées, de sorte que les boîtes de Shulker ainsi que leur contenu peuvent être considérés comme un seul élément. Les boîtes de Shulker sont disponibles dans de nombreuses couleurs différentes. +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.=Pour accéder à l'inventaire d'une boîte de Shulker, placez-la et cliquez dessus avec le bouton droit. Pour emporter une boîte de Shulker et son contenu, il suffit de la casser et de la récupérer, les objets ne tomberont pas. Replacez la boîte de Shulker pour pouvoir récupérer son contenu. +Shulker Box=Boîte de Shulker +Large Chest=Grand coffre Inventory=Inventaire 27 inventory slots=27 emplacements d'inventaire Can be carried around with its contents=Peut être transporté avec son contenu -Can be combined to a large chest=Peut être combiné à un grand coffre +Can be combined to a large chest=Peut être combiné pour former un grand coffre 27 interdimensional inventory slots=27 emplacements d'inventaire interdimensionnels Put items inside, retrieve them from any ender chest=Mettez des objets à l'intérieur, récupérez-les dans n'importe quel coffre Emits a redstone signal when opened=Émet un signal redstone à l'ouverture diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr new file mode 100644 index 000000000..8f6525411 --- /dev/null +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.ja.tr @@ -0,0 +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個のインベントリースロットを備える収納箱です。チェストを2つ並べると、2倍の容量を備えるラージチェストになります。 +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個のインベントリースロットを備える収納箱です。それを開いている間は、隣接するブロックにレッドストーン信号を送ります。トラップチェストを2つ並べると、2倍の容量を備えるラージトラップチェストになります。 +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.=エンダーチェストからは、「ただ1つの、個人専用の次元間インベントリ」にアクセスできます。そのインベントリには27個のスロットが備わっています。どのエンダーチェストを開けても、そのただ1つのインベントリにアクセスする仕組みになっています。例えば、あるエンダーチェストにアイテムを入れておくと、他にあるどのエンダーチェストからでもそのアイテムが見え、取り出せます。このインベントリは各プレイヤー専用であるため、他のプレイヤーが開けた時は、そのプレイヤーには当人専用のインベントリが見えています。つまり他人のインベントリにはアクセスできません。 +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=空色のシュルカーボックス +Blue Shulker Box=青色のシュルカーボックス +Yellow Shulker Box=黄色のシュルカーボックス +Brown 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個のインベントリスロットを備える「持ち運び可能な収納箱」で、シュルカーボックス以外のアイテムを保管できます。シュルカーボックスは壊れても、中身をドロップアウトせず保持したそのままで、1つのアイテムとしてドロップされます。それを回収し再設置できます。シュルカーボックスにはさまざまな色があります。 +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=中身を入れたまま持ち運び可能 +Can be combined to a large 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_chests/locale/mcl_chests.pl.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.pl.tr new file mode 100644 index 000000000..b4eee74eb --- /dev/null +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.pl.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_chests +Chest=Skrzynia +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.=Skrzynie to pojemniki zawierające 27 miejsc ekwipunku. Skrzynie można zmienić w wielkie skrzynie z podwojoną pojemnością kładąc dwie skrzynie jedna obok drugiej. +To access its inventory, rightclick it. When broken, the items will drop out.=Aby zarządzać jej ekwipunkiem kliknij prawym przyciskiem. Po zniszczeniu przedmioty z niej wypadną. +Trapped Chest=Skrzynia-pułapka +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.=Skrzynia pułapka jest pojemnikiem zawierającym 27 miejsc ekwipunku. Gdy jest otwarta wysyła ona zasila czerwienit na sąsiadujących blokach tak długo jak jest otwarta. Skrzynie-pułapki można zmienić w wielkie skrzynie-pułapki z podwojoną pojemnością przez położenie dwóch skrzynek-pułapek jedna obok drugiej. +Ender Chest=Skrzynia kresu +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.=Skrzynie kresu dają dostęp do pojedynczego, osobistego, międzywymiarowego ekwipunku z 27 miejscami. Ten ekwipunek będzie zawierał to samo niezależnie od skrzyni kresu z której nim zarządzasz. Jeśli włożysz przedmiot do jednej skrzyni kresu, znajdziesz go we wszystkich innych. każdy gracz będzie widział tylko swoje przedmioty, a nie innych graczy. +Rightclick the ender chest to access your personal interdimensional inventory.=Kliknij prawym w skrzynię kresu aby mieć dostęp do twojego osobistego, międzywymiarowego ekwipunku. +White Shulker Box=Biała shulkerowa skrzynia +Light Grey Shulker Box=Jasnoszara shulkerowa skrzynia +Orange Shulker Box=Pomarańczowa shulkerowa skrzynia +Cyan Shulker Box=Błękitna shulkerowa skrzynia +Magenta Shulker Box=Karmazynowa shulkerowa skrzynia +Purple Shulker Box=Fioletowa shulkerowa skrzynia +Light Blue Shulker Box=Jasnoniebieska shulkerowa skrzynia +Blue Shulker Box=Niebieska shulkerowa skrzynia +Yellow Shulker Box=Żółta shulkerowa skrzynia +Brown Shulker Box=Brązowa shulkerowa skrzynia +Lime Shulker Box=Jasnozielona shulkerowa skrzynia +Green Shulker Box=Zielona shulkerowa skrzynia +Pink Shulker Box=Różowa shulkerowa skrzynia +Red Shulker Box=Czerwona shulkerowa skrzynia +Grey Shulker Box=Szara shulkerowa skrzynia +Black Shulker Box=Czarna shulkerowa skrzynia +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.=Shulkerowe skrzynie to przenośny pojemnik udostępniający 27 miejsc ekwipunku na dowolny przedmiot z wyjątkiem shulkerowych skrzyń. Shulkerowe skrzynie nie tracą swojego ekwipunku po zniszczeniu, więc te skrzynie razem z całą zawartością mogą być przechowywane jako pojedynczy przedmiot. +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.=Aby dostać się do przedmiotów w shulkerowej skrzyni postaw ją i naciśnij ją prawym. Aby wziąć shulkerową skrzynię i jej zawartość ze sobą, zniszcz ją i zbierz, przedmioty nie wypadną. +Shulker Box=Shulkerowa skrzynia +Large Chest=Duża skrzynia +Inventory=Ekwipunek +27 inventory slots=27 miejsc ekwipunku +Can be carried around with its contents=Może być przenoszona razem z zawartością +Can be combined to a large chest=Może być połączona w dużą skrzynię +27 interdimensional inventory slots=27 międzywymiarowych miejsc ekwipunku +Put items inside, retrieve them from any ender chest=Włóż do niej przedmioty, miej do nich dostęp z dowolnej skrzyni kresu +Emits a redstone signal when opened=Aktywuje pobliski czerwienit gdy otwarta diff --git a/mods/ITEMS/mcl_chests/locale/mcl_chests.pt_BR.tr b/mods/ITEMS/mcl_chests/locale/mcl_chests.pt_BR.tr new file mode 100644 index 000000000..e0ca131c3 --- /dev/null +++ b/mods/ITEMS/mcl_chests/locale/mcl_chests.pt_BR.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_chests +Chest=Baú +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.=Baús são recipientes que fornecem um inventário com 27 espaços. Baús podem ser convertidos em baús largos com o dobro da capacidade ao colocar dois baús um ao lado do outro. +To access its inventory, rightclick it. When broken, the items will drop out.=Para acessar seu inventário, clique-o com o botão direito. Quando quebrado, os itens serão derrubados no chão. +Trapped Chest=Baú com armadilha +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.=Um baú com armadilha é um recipiente que fornece um inventário com 27 espaços. Quando aberto, envia um sinal de redstone para os blocos adjacentes enquanto estiver aberto. Baús com armadilhas podem se tornar báus largos com armadilha com o dobro da capacidade ao colocar dois baús com armadilha um ao lado do outro. +Ender Chest=Baú de Ender +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.=Baús de ender lhe garantem acesso à um inventário pessoal interdimensional com 27 espaços. Esse inventário é o mesmo independente do baú do ender que você acessar. Se você colocar um item em um baú de ender, você o encontrará em todos os outros baús de ender. Cada jogador poderá ver seus próprios itens, mas não os de outros jogadores. +Rightclick the ender chest to access your personal interdimensional inventory.=Aperte com o botão direito no baú de ender para acessar seu inventário pessoal interdimensional. +White Shulker Box=Caixa de Shulker Branca +Light Grey Shulker Box=Caixa de Shulker Cinza-Clara +Orange Shulker Box=Caixa de Shulker Laranja +Cyan Shulker Box=Caixa de Shulker Ciano +Magenta Shulker Box=Caixa de Shulker Magenta +Purple Shulker Box=Caixa de Shulker Roxa +Light Blue Shulker Box=Caixa de Shulker Azul-Clara +Blue Shulker Box=Caixa de Shulker Azul +Yellow Shulker Box=Caixa de Shulker Amarela +Brown Shulker Box=Caixa de Shulker Marrom +Lime Shulker Box=Caixa de Shulker Lima +Green Shulker Box=Caixa de Shulker Verde +Pink Shulker Box=Caixa de Shulker Rosa +Red Shulker Box=Caixa de Shulker Vermelha +Grey Shulker Box=Caixa de Shulker Cinza +Black Shulker Box=Caixa de Shulker Preta +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.=Uma caixa de shulker é um recipiente portátil que fornece um inventário com 27 espaços para qualquer item exceto outras caixas de shulker. Caixas de shulker retêm seus inventários quando quebradas, portanto caixas de shulker, assim como seu conteúdo, podem ser carregadas como um único item. Caixas de shulker vêm em diferentes cores. +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.=Para acessar o inventário de uma caixa de shulker, coloque-a e aperte-a com o botão direito. Para levar uma caixa de shulker com seu conteúdo com você, apenas quebre-a e a colete, os itens não cairão no chão. Coloque a caixa de shulker novamente para conseguir retirar seu conteúdo. +Shulker Box=Caixa de Shulker +Large Chest=Baú Largo +Inventory=Inventário +27 inventory slots=27 espaços de inventário +Can be carried around with its contents=Pode ser carregada com seu conteúdo +Can be combined to a large chest=Pode ser combinado para um baú largo +27 interdimensional inventory slots=27 espaços de inventário interdimensional +Put items inside, retrieve them from any ender chest=Coloque itens dentro, retire-os a partir de qualquer báu de ender +Emits a redstone signal when opened=Emite um sinal de redstone quando aberto diff --git a/mods/ITEMS/mcl_chests/mod.conf b/mods/ITEMS/mcl_chests/mod.conf new file mode 100644 index 000000000..0ff5129ca --- /dev/null +++ b/mods/ITEMS/mcl_chests/mod.conf @@ -0,0 +1,3 @@ +name = mcl_chests +depends = mcl_init, mcl_formspec, mcl_core, mcl_sounds, mcl_end, mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d index e82c7e363..5cc1b8edc 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj b/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj deleted file mode 100644 index 36268146f..000000000 --- a/mods/ITEMS/mcl_chests/models/mcl_chests_chest.obj +++ /dev/null @@ -1,91 +0,0 @@ -# Blender v2.76 (sub 0) OBJ File: 'chest.small.facedir.blend' -# www.blender.org -mtllib chest.small.facedir.mtl -o chest_upper_upper -v 0.062513 -0.063134 -0.500468 -v 0.062513 0.186920 -0.500468 -v 0.062514 -0.063134 -0.437955 -v 0.062514 0.186920 -0.437955 -v -0.062514 -0.063134 -0.500468 -v -0.062514 0.186920 -0.500468 -v -0.062514 -0.063134 -0.437955 -v -0.062514 0.186920 -0.437955 -v 0.437907 0.061263 -0.438085 -v 0.437907 0.373830 -0.438085 -v 0.437907 0.061263 0.437729 -v 0.437907 0.373830 0.437729 -v -0.437907 0.061263 -0.438085 -v -0.437907 0.373830 -0.438085 -v -0.437907 0.061263 0.437729 -v -0.437907 0.373830 0.437729 -v 0.437595 -0.500754 -0.437772 -v 0.437595 0.124381 -0.437772 -v 0.437595 -0.500754 0.437417 -v 0.437595 0.124381 0.437417 -v -0.437595 -0.500754 -0.437772 -v -0.437595 0.124381 -0.437772 -v -0.437595 -0.500754 0.437417 -v -0.437595 0.124381 0.437417 -vt 0.015625 0.921875 -vt 0.015625 0.984375 -vt 0.000000 0.984375 -vt 0.000000 0.921875 -vt 0.093750 0.921875 -vt 0.093750 0.984375 -vt 0.062500 0.984375 -vt 0.062500 0.921875 -vt 0.046875 0.984375 -vt 0.046875 0.921875 -vt 0.078125 0.984375 -vt 0.078125 1.000000 -vt 0.046875 1.000000 -vt 0.015625 1.000000 -vt 0.218750 0.703125 -vt 0.218750 0.781250 -vt 0.000000 0.781250 -vt 0.000000 0.703125 -vt 0.875000 0.703125 -vt 0.875000 0.781250 -vt 0.656250 0.781250 -vt 0.656250 0.703125 -vt 0.437500 0.781250 -vt 0.437500 0.703125 -vt 0.656250 1.000000 -vt 0.437500 1.000000 -vt 0.218750 1.000000 -vt 0.218750 0.328125 -vt 0.218750 0.484375 -vt -0.000000 0.484375 -vt -0.000000 0.328125 -vt 0.875000 0.328125 -vt 0.875000 0.484375 -vt 0.656250 0.484375 -vt 0.656250 0.328125 -vt 0.437500 0.484375 -vt 0.437500 0.328125 -vn 1.000000 0.000000 -0.000000 -vn 0.000000 0.000000 1.000000 -vn -1.000000 0.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 0.000000 -1.000000 0.000000 -vn 0.000000 1.000000 0.000000 -usemtl None -s off -f 1/1/1 2/2/1 4/3/1 3/4/1 -f 3/5/2 4/6/2 8/7/2 7/8/2 -f 7/8/3 8/7/3 6/9/3 5/10/3 -f 5/10/4 6/9/4 2/2/4 1/1/4 -f 3/9/5 7/11/5 5/12/5 1/13/5 -f 8/13/6 4/14/6 2/2/6 6/9/6 -f 9/15/1 10/16/1 12/17/1 11/18/1 -f 11/19/2 12/20/2 16/21/2 15/22/2 -f 15/22/3 16/21/3 14/23/3 13/24/3 -f 13/24/4 14/23/4 10/16/4 9/15/4 -f 11/25/5 15/26/5 13/23/5 9/21/5 -f 16/26/6 12/27/6 10/16/6 14/23/6 -f 17/28/1 18/29/1 20/30/1 19/31/1 -f 19/32/2 20/33/2 24/34/2 23/35/2 -f 23/35/3 24/34/3 22/36/3 21/37/3 -f 21/37/4 22/36/4 18/29/4 17/28/4 -f 19/22/5 23/24/5 21/36/5 17/34/5 -f 24/24/6 20/15/6 18/29/6 22/36/6 diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d index 86c44bfeb..578b3cb72 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_chest_double.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d index 86dde145b..58508348a 100644 Binary files a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d and b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.b3d differ diff --git a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj b/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj deleted file mode 100644 index ca12b682e..000000000 --- a/mods/ITEMS/mcl_chests/models/mcl_chests_shulker.obj +++ /dev/null @@ -1,159 +0,0 @@ -# Blender v2.79 (sub 0) OBJ File: 'shulkerbox2.blend' -# www.blender.org -mtllib shulkerbox2.mtl -o low1_Cube.006 -v -0.500000 -0.500001 0.500000 -v -0.500000 0.062499 0.500000 -v -0.500000 -0.500001 -0.500000 -v -0.500000 0.062499 -0.500000 -v 0.500000 -0.500001 0.500000 -v 0.500000 0.062499 0.500000 -v 0.500000 -0.500001 -0.500000 -v 0.500000 0.062499 -0.500000 -vt 0.250000 0.187500 -vt -0.000000 0.187500 -vt -0.000000 0.312500 -vt 0.250000 0.312500 -vt 1.000000 0.187500 -vt 0.750000 0.187500 -vt 0.750000 0.312500 -vt 1.000000 0.312500 -vt 0.500000 0.187500 -vt 0.500000 0.312500 -vt 0.750000 0.562500 -vt 0.750000 0.312500 -vt 0.500000 0.312500 -vt 0.500000 0.562500 -vt 0.500000 0.562500 -vt 0.250000 0.562500 -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 -usemtl None -s off -f 1/1/1 3/2/1 4/3/1 2/4/1 -f 3/5/2 7/6/2 8/7/2 4/8/2 -f 7/6/3 5/9/3 6/10/3 8/7/3 -f 5/9/4 1/1/4 2/4/4 6/10/4 -f 3/11/5 1/12/5 5/13/5 7/14/5 -f 8/15/6 6/10/6 2/4/6 4/16/6 -o top1_Cube.005 -v -0.500313 -0.220552 0.500313 -v -0.500313 0.530073 0.500313 -v -0.500313 -0.220552 -0.500313 -v -0.500313 0.530073 -0.500313 -v 0.500313 -0.220552 0.500313 -v 0.500313 0.530073 0.500313 -v 0.500313 -0.220552 -0.500313 -v 0.500313 0.530073 -0.500313 -vt 0.250000 0.562500 -vt -0.000000 0.562500 -vt -0.000000 0.750000 -vt 0.250000 0.750000 -vt 1.000000 0.562500 -vt 0.750000 0.562500 -vt 0.750000 0.750000 -vt 1.000000 0.750000 -vt 0.500000 0.562500 -vt 0.500000 0.750000 -vt 0.750000 1.000000 -vt 0.750000 0.750000 -vt 0.500000 0.750000 -vt 0.500000 1.000000 -vt 0.500000 1.000000 -vt 0.250000 1.000000 -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 -usemtl None -s off -f 9/17/7 11/18/7 12/19/7 10/20/7 -f 11/21/8 15/22/8 16/23/8 12/24/8 -f 15/22/9 13/25/9 14/26/9 16/23/9 -f 13/25/10 9/17/10 10/20/10 14/26/10 -f 11/27/11 9/28/11 13/29/11 15/30/11 -f 16/31/12 14/26/12 10/20/12 12/32/12 -o top2_Cube.002 -v -0.500247 -0.220392 0.500247 -v -0.500247 0.530234 0.500247 -v -0.500247 -0.220392 -0.500378 -v -0.500247 0.530234 -0.500378 -v 0.500378 -0.220392 0.500247 -v 0.500378 0.530234 0.500247 -v 0.500378 -0.220392 -0.500378 -v 0.500378 0.530234 -0.500378 -vt 0.250000 0.562500 -vt 0.250000 0.750000 -vt -0.000000 0.750000 -vt -0.000000 0.562500 -vt 1.000000 0.562500 -vt 1.000000 0.750000 -vt 0.750000 0.750000 -vt 0.750000 0.562500 -vt 0.500000 0.750000 -vt 0.500000 0.562500 -vt 0.750000 1.000000 -vt 0.500000 1.000000 -vt 0.500000 0.750000 -vt 0.750000 0.750000 -vt 0.500000 1.000000 -vt 0.250000 1.000000 -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 -usemtl None -s off -f 17/33/13 18/34/13 20/35/13 19/36/13 -f 19/37/14 20/38/14 24/39/14 23/40/14 -f 23/40/15 24/39/15 22/41/15 21/42/15 -f 21/42/16 22/41/16 18/34/16 17/33/16 -f 19/43/17 23/44/17 21/45/17 17/46/17 -f 24/47/18 20/48/18 18/34/18 22/41/18 -o low2_Cube.001 -v -0.499935 -0.499936 0.499935 -v -0.499935 0.062565 0.499935 -v -0.499935 -0.499936 -0.500066 -v -0.499935 0.062565 -0.500066 -v 0.500066 -0.499936 0.499935 -v 0.500066 0.062565 0.499935 -v 0.500066 -0.499936 -0.500066 -v 0.500066 0.062565 -0.500066 -vt 0.250000 0.187500 -vt 0.250000 0.312500 -vt -0.000000 0.312500 -vt -0.000000 0.187500 -vt 1.000000 0.187500 -vt 1.000000 0.312500 -vt 0.750000 0.312500 -vt 0.750000 0.187500 -vt 0.500000 0.312500 -vt 0.500000 0.187500 -vt 0.750000 0.562500 -vt 0.500000 0.562500 -vt 0.500000 0.312500 -vt 0.750000 0.312500 -vt 0.500000 0.562500 -vt 0.250000 0.562500 -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 -usemtl None -s off -f 25/49/19 26/50/19 28/51/19 27/52/19 -f 27/53/20 28/54/20 32/55/20 31/56/20 -f 31/56/21 32/55/21 30/57/21 29/58/21 -f 29/58/22 30/57/22 26/50/22 25/49/22 -f 27/59/23 31/60/23 29/61/23 25/62/23 -f 32/63/24 28/64/24 26/50/24 30/57/24 diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_front.png b/mods/ITEMS/mcl_chests/textures/default_chest_front.png deleted file mode 100644 index 866a33984..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png deleted file mode 100644 index bde286673..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_front_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png deleted file mode 100644 index deb006807..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_side_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_top.png b/mods/ITEMS/mcl_chests/textures/default_chest_top.png deleted file mode 100644 index 5c1beb4b5..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png b/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png deleted file mode 100644 index de56e2cab..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/default_chest_top_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png deleted file mode 100644 index a8564e42e..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_black_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png deleted file mode 100644 index baee128d4..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_blank.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png deleted file mode 100644 index 608887df4..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_blue_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png deleted file mode 100644 index 95b6cbdc8..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_brown_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png deleted file mode 100644 index f347e921a..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png deleted file mode 100644 index cb43e55e2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png deleted file mode 100644 index d420aaba0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png deleted file mode 100644 index 4536ada86..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png deleted file mode 100644 index f347e921a..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png deleted file mode 100644 index cb43e55e2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png deleted file mode 100644 index 67cc716bd..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png deleted file mode 100644 index b65bfc231..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_front_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png deleted file mode 100644 index d420aaba0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png deleted file mode 100644 index 4536ada86..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png deleted file mode 100644 index deb006807..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_side_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png deleted file mode 100644 index 5c1beb4b5..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png deleted file mode 100644 index de56e2cab..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_chest_trapped_top_big.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png deleted file mode 100644 index d8fe60f50..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_cyan_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png deleted file mode 100644 index a0d32088b..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_green_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png deleted file mode 100644 index 8859361ec..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_dark_grey_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png deleted file mode 100644 index 7cfbe1d7d..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png deleted file mode 100644 index 03a61a59c..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png deleted file mode 100644 index bbc68e78b..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_front.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png deleted file mode 100644 index 1a0ceaef2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png deleted file mode 100644 index f547532f2..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png deleted file mode 100644 index c109aa826..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender_chest_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png deleted file mode 100644 index 513612da9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_green_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png deleted file mode 100644 index e483f6ed7..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_grey_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png deleted file mode 100644 index 9efc68fe0..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_lightblue_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png deleted file mode 100644 index 9f167d4d9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_magenta_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png deleted file mode 100644 index 5133f53ff..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png deleted file mode 100644 index a8793f600..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png deleted file mode 100644 index 166f9c3da..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_orange_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png deleted file mode 100644 index a69548c31..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_pink_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png deleted file mode 100644 index 8c458cdd9..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_red_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png deleted file mode 100644 index de21d8f2f..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png deleted file mode 100644 index 95f768f97..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png deleted file mode 100644 index eb461d395..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_violet_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png deleted file mode 100644 index 8c12525bd..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_white_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png deleted file mode 100644 index 5e657412d..000000000 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_yellow_shulker_box_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/depends.txt b/mods/ITEMS/mcl_clock/depends.txt deleted file mode 100644 index 514d78143..000000000 --- a/mods/ITEMS/mcl_clock/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_init -mcl_worlds -mesecons -doc? diff --git a/mods/ITEMS/mcl_clock/description.txt b/mods/ITEMS/mcl_clock/description.txt deleted file mode 100644 index 1b7157aad..000000000 --- a/mods/ITEMS/mcl_clock/description.txt +++ /dev/null @@ -1 +0,0 @@ -A fantasy clock item roughly shows the time of day. diff --git a/mods/ITEMS/mcl_clock/init.lua b/mods/ITEMS/mcl_clock/init.lua index 0532bf5f7..65b32b91e 100644 --- a/mods/ITEMS/mcl_clock/init.lua +++ b/mods/ITEMS/mcl_clock/init.lua @@ -1,7 +1,7 @@ -local S = minetest.get_translator("mcl_clock") +local S = minetest.get_translator(minetest.get_current_modname()) --[[ - mcl_clock, renew of the renew of the watch mod + mcl_clock, renew of the renew of the mcl_clock mod Original from Echo, here: http://forum.minetest.net/viewtopic.php?id=3795 ]]-- @@ -11,8 +11,7 @@ mcl_clock = {} -- This is the itemstring of the default clock item. It is used for the default inventory image, help entries, and the like mcl_clock.stereotype = "mcl_clock:clock" -local watch = {} -watch.old_time = -1 +mcl_clock.old_time = -1 local clock_frames = 64 @@ -22,30 +21,30 @@ local random_timer_trigger = 1.0 -- random clock spinning tick in seconds. Incre local random_frame = math.random(0, clock_frames-1) -- Image of all possible faces -watch.images = {} +mcl_clock.images = {} for frame=0, clock_frames-1 do local sframe = tostring(frame) if string.len(sframe) == 1 then sframe = "0" .. sframe end - table.insert(watch.images, "mcl_clock_clock_"..sframe..".png") + table.insert(mcl_clock.images, "mcl_clock_clock_"..sframe..".png") end local function round(num) return math.floor(num + 0.5) end -function watch.get_clock_frame() +function mcl_clock.get_clock_frame() local t = clock_frames * minetest.get_timeofday() t = round(t) if t == clock_frames then t = 0 end return tostring(t) end -local doc_mod = minetest.get_modpath("doc") ~= nil +local doc_mod = minetest.get_modpath("doc") -- Register items -function watch.register_item(name, image, creative, frame) +function mcl_clock.register_item(name, image, creative, frame) local g = 1 if creative then g = 0 @@ -78,7 +77,7 @@ end local force_clock_update_timer = 0 minetest.register_globalstep(function(dtime) - local now = watch.get_clock_frame() + local now = mcl_clock.get_clock_frame() force_clock_update_timer = force_clock_update_timer + dtime random_timer = random_timer + dtime -- This causes the random spinning of the clock @@ -87,17 +86,16 @@ minetest.register_globalstep(function(dtime) random_timer = 0 end - if watch.old_time == now and force_clock_update_timer < 60 then + if mcl_clock.old_time == now and force_clock_update_timer < 60 then return end force_clock_update_timer = 0 - watch.old_time = now + mcl_clock.old_time = now + mcl_clock.random_frame = random_frame - local players = minetest.get_connected_players() - for p, player in ipairs(players) do - for s, stack in ipairs(player:get_inventory():get_list("main")) do - local dim = mcl_worlds.pos_to_dimension(player:get_pos()) + for p, player in pairs(minetest.get_connected_players()) do + for s, stack in pairs(player:get_inventory():get_list("main")) do local frame -- Clocks do not work in certain zones if not mcl_worlds.clock_works(player:get_pos()) then @@ -105,6 +103,7 @@ minetest.register_globalstep(function(dtime) else frame = now end + local count = stack:get_count() if stack:get_name() == mcl_clock.stereotype then player:get_inventory():set_stack("main", s, "mcl_clock:clock_"..frame.." "..count) @@ -118,7 +117,7 @@ end) -- Immediately set correct clock time after crafting minetest.register_on_craft(function(itemstack) if itemstack:get_name() == mcl_clock.stereotype then - itemstack:set_name("mcl_clock:clock_"..watch.get_clock_frame()) + itemstack:set_name("mcl_clock:clock_"..mcl_clock.get_clock_frame()) end end) @@ -126,14 +125,14 @@ end) minetest.register_craft({ output = mcl_clock.stereotype, recipe = { - {'', 'mcl_core:gold_ingot', ''}, - {'mcl_core:gold_ingot', 'mesecons:redstone', 'mcl_core:gold_ingot'}, - {'', 'mcl_core:gold_ingot', ''} + {"", "mcl_core:gold_ingot", ""}, + {"mcl_core:gold_ingot", "mesecons:redstone", "mcl_core:gold_ingot"}, + {"", "mcl_core:gold_ingot", ""} } }) -- Clock tool -watch.register_item(mcl_clock.stereotype, watch.images[1], true, 1) +mcl_clock.register_item(mcl_clock.stereotype, mcl_clock.images[1], true, 1) -- Faces for a=0,clock_frames-1,1 do @@ -143,6 +142,6 @@ for a=0,clock_frames-1,1 do else b = b + 32 end - watch.register_item("mcl_clock:clock_"..tostring(a), watch.images[b+1], false, a+1) + mcl_clock.register_item("mcl_clock:clock_"..tostring(a), mcl_clock.images[b+1], false, a+1) end diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.es.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.es.tr index c8841fc6e..6f8581fcc 100644 --- a/mods/ITEMS/mcl_clock/locale/mcl_clock.es.tr +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.es.tr @@ -1,4 +1,5 @@ # textdomain: mcl_clock Clocks are tools which shows the current time of day in the Overworld.=Los relojes son herramientas que muestran la hora del día en el mundo. 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.=El reloj contiene un disco giratorio con un símbolo del sol (disco amarillo) y un símbolo de la luna y un pequeño "puntero" que muestra la hora actual del día al estimar la posición real del sol y la luna en el cielo. El mediodía está representado por el símbolo del sol y la medianoche está representado por el símbolo de la luna. -Clock=Reloj \ No newline at end of file +Clock=Reloj +Displays the time of day in the Overworld=Muestra la hora del día en el mundo. diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr new file mode 100644 index 000000000..454788a29 --- /dev/null +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.ja.tr @@ -0,0 +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.=この時計は、太陽マーク(黄色い円)と月マークが描かれた回転ディスクと、小さな「ポインター」で構成されています。太陽と月の位置から現在時刻を推定しましょう。ポインターにちょうど太陽マークがきた時が正午、月マークなら零時です。 +Clock=時計 +Displays the time of day in the Overworld=オーバーワールドの現在時刻を表示 diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.pl.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.pl.tr new file mode 100644 index 000000000..6cb110dd8 --- /dev/null +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_clock +Clocks are tools which shows the current time of day in the Overworld.=Zegary to narzędzia pokazujące aktualną godzinę na Powierzchni. +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.=Zegar zawiera obracające się kółko z symbolami słońca (żółte kółko) i symbolem księżyca oraz małym wskaźnikiem pokazującym aktualną godzinę przez oszacowanie prawdziwej pozycji słońca i księżyca na niebie. Południe jest reprezentowane przez symbol słońca, a północ przez symbol księżyca. +Clock=Zegar +Displays the time of day in the Overworld=Pokazuje aktualną godzinę na Powierzchni diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.pt_BR.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.pt_BR.tr new file mode 100644 index 000000000..a8d8ac178 --- /dev/null +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.pt_BR.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_clock +Clocks are tools which shows the current time of day in the Overworld.=Relógios são ferramentas que mostram o tempo do dia na Superfície. +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.=O relógio contêm um disco rotatório com um simbolo do sol (disco amarelo) e um símbolo da lua com um pequeno "ponteiro" que mostra o momento atual do dia estimando a posição real do sol e da lua no céu. Meio-dia é representado pelo símbolo do sol e meia-noite é representado pelo símbolo da lua. +Clock=Relógio +Displays the time of day in the Overworld=Mostra o tempo do dia na Superfície diff --git a/mods/ITEMS/mcl_clock/locale/mcl_clock.zh_TW.tr b/mods/ITEMS/mcl_clock/locale/mcl_clock.zh_TW.tr new file mode 100644 index 000000000..c6834373f --- /dev/null +++ b/mods/ITEMS/mcl_clock/locale/mcl_clock.zh_TW.tr @@ -0,0 +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.=時鐘包含一個帶有太陽符號(黃色圓盤)和月亮符號的旋轉圓盤,以及一個小「指針」,通過估計太陽和月亮在天空中的實際位置來顯示當前的時間。正午由太陽符號表示,午夜由月亮符號表示。 +Clock=時鐘 +Displays the time of day in the Overworld=顯示世界上當前的時間 diff --git a/mods/ITEMS/mcl_clock/mod.conf b/mods/ITEMS/mcl_clock/mod.conf index ba0d83eaa..e358ff29a 100644 --- a/mods/ITEMS/mcl_clock/mod.conf +++ b/mods/ITEMS/mcl_clock/mod.conf @@ -1 +1,4 @@ name = mcl_clock +description = A fantasy clock item roughly shows the time of day. +depends = mcl_init, mcl_worlds, mesecons +optional_depends = doc diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_07.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_07.png deleted file mode 100644 index 1e5d7c969..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_07.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_10.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_10.png deleted file mode 100644 index 68395a4c1..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_10.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_11.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_11.png deleted file mode 100644 index 8fcf0a83d..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_11.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_13.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_13.png deleted file mode 100644 index 501c5fa7d..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_13.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_14.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_14.png deleted file mode 100644 index 1f750d28c..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_14.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_15.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_15.png deleted file mode 100644 index 1126230cf..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_15.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_16.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_16.png deleted file mode 100644 index 7e13698a9..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_16.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_17.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_17.png deleted file mode 100644 index cc6af9240..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_17.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_18.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_18.png deleted file mode 100644 index beb08e694..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_18.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_20.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_20.png deleted file mode 100644 index 9f54e4a23..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_20.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_22.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_22.png deleted file mode 100644 index 8db493f6e..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_22.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_23.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_23.png deleted file mode 100644 index d7913629b..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_23.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_40.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_40.png deleted file mode 100644 index 9ce1c7091..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_40.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_43.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_43.png deleted file mode 100644 index 34521c99f..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_43.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_45.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_45.png deleted file mode 100644 index 8ba8622b6..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_45.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_46.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_46.png deleted file mode 100644 index 9f865c02b..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_46.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_48.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_48.png deleted file mode 100644 index 33300e32e..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_48.png and /dev/null differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_51.png b/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_51.png deleted file mode 100644 index f2b767437..000000000 Binary files a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_51.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cocoas/depends.txt b/mods/ITEMS/mcl_cocoas/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/mcl_cocoas/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/mcl_cocoas/description.txt b/mods/ITEMS/mcl_cocoas/description.txt deleted file mode 100644 index 1af5d7ce0..000000000 --- a/mods/ITEMS/mcl_cocoas/description.txt +++ /dev/null @@ -1 +0,0 @@ -Cocoa pods which grow at jungle trees. Does not include cocoa beans. diff --git a/mods/ITEMS/mcl_cocoas/init.lua b/mods/ITEMS/mcl_cocoas/init.lua index b02a168e5..0792972be 100644 --- a/mods/ITEMS/mcl_cocoas/init.lua +++ b/mods/ITEMS/mcl_cocoas/init.lua @@ -1,12 +1,9 @@ -local S = minetest.get_translator("mcl_cocoas") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_cocoas = {} -- Place cocoa -function mcl_cocoas.place(itemstack, placer, pointed_thing, plantname) - - local pt = pointed_thing - +local function cocoa_place(itemstack, placer, pt, plantname) -- check if pointing at a node if not pt or pt.type ~= "node" then return @@ -22,7 +19,7 @@ function mcl_cocoas.place(itemstack, placer, pointed_thing, plantname) -- Am I right-clicking on something that has a custom on_rightclick set? if placer and not placer:get_player_control().sneak then if minetest.registered_nodes[under.name] and minetest.registered_nodes[under.name].on_rightclick then - return minetest.registered_nodes[under.name].on_rightclick(pointed_thing.under, under, placer, itemstack) or itemstack + return minetest.registered_nodes[under.name].on_rightclick(pt.under, under, placer, itemstack) or itemstack end end @@ -65,35 +62,21 @@ function mcl_cocoas.grow(pos) return false end --- Note: cocoa beans are implemented as mcl_dye:brown - -- Cocoa definition -- 1st stage - ---[[ TODO: Use a mesh for cocoas for perfect texture compability. ]] local crop_def = { description = S("Premature Cocoa Pod"), _doc_items_create_entry = true, _doc_items_longdesc = S("Cocoa pods grow on the side of jungle trees in 3 stages."), - drawtype = "nodebox", - tiles = { - "[combine:16x16:6,1=mcl_cocoas_cocoa_stage_0.png", "[combine:16x16:6,11=mcl_cocoas_cocoa_stage_0.png", - "mcl_cocoas_cocoa_stage_0.png", "mcl_cocoas_cocoa_stage_0.png^[transformFX", - "[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png", "[combine:16x16:-5,0=mcl_cocoas_cocoa_stage_0.png", - }, + drawtype = "mesh", + mesh = "mcl_cocoas_cocoa_stage_0.obj", + tiles = {"mcl_cocoas_cocoa_stage_0.png"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, paramtype = "light", sunlight_propagates = true, paramtype2 = "facedir", walkable = true, - drop = "mcl_dye:brown", - node_box = { - type = "fixed", - fixed = { - {-0.125, -0.0625, 0.1875, 0.125, 0.25, 0.4375}, -- Pod - -- FIXME: This has a thickness of 0. Is this OK in Minetest? - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, - }, + drop = "mcl_cocoas:cocoa_beans", collision_box = { type = "fixed", fixed = { @@ -107,7 +90,11 @@ local crop_def = { }, }, groups = { - handy=1,axey=1, cocoa=1, not_in_creative_inventory=1, dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, attached_node_facedir=1, + handy = 1, axey = 1, + dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, + attached_node_facedir=1, + not_in_creative_inventory=1, + cocoa=1 }, sounds = mcl_sounds.node_sound_wood_defaults(), on_rotate = false, @@ -121,18 +108,8 @@ minetest.register_node("mcl_cocoas:cocoa_1", table.copy(crop_def)) crop_def.description = S("Medium Cocoa Pod") crop_def._doc_items_create_entry = false crop_def.groups.cocoa = 2 -crop_def.tiles = { - "[combine:16x16:5,1=mcl_cocoas_cocoa_stage_1.png", "[combine:16x16:5,9=mcl_cocoas_cocoa_stage_1.png", - "mcl_cocoas_cocoa_stage_1.png", "mcl_cocoas_cocoa_stage_1.png^[transformFX", - "[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png", "[combine:16x16:-4,0=mcl_cocoas_cocoa_stage_1.png", -} -crop_def.node_box = { - type = "fixed", - fixed = { - {-0.1875, -0.1875, 0.0625, 0.1875, 0.25, 0.4375}, -- Pod - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, -} +crop_def.mesh = "mcl_cocoas_cocoa_stage_1.obj" +crop_def.tiles = {"mcl_cocoas_cocoa_stage_1.png"} crop_def.collision_box = { type = "fixed", fixed = { @@ -153,20 +130,8 @@ crop_def.description = S("Mature Cocoa Pod") crop_def._doc_items_longdesc = S("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.") crop_def._doc_items_create_entry = true crop_def.groups.cocoa = 3 -crop_def.tiles = { - -- The following 2 textures were derived from the original because the size of the top/bottom is slightly different :-( - -- TODO: Find a way to *only* use the base texture - "mcl_cocoas_cocoa_top_stage_2.png", "mcl_cocoas_cocoa_top_stage_2.png^[transformFY", - "mcl_cocoas_cocoa_stage_2.png", "mcl_cocoas_cocoa_stage_2.png^[transformFX", - "[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png", "[combine:16x16:-3,0=mcl_cocoas_cocoa_stage_2.png", -} -crop_def.node_box = { - type = "fixed", - fixed = { - {-0.25, -0.3125, -0.0625, 0.25, 0.25, 0.4375}, -- Pod - {0, 0.25, 0.25, 0, 0.5, 0.5}, -- Stem - }, -} +crop_def.mesh = "mcl_cocoas_cocoa_stage_2.obj" +crop_def.tiles = {"mcl_cocoas_cocoa_stage_2.png"} crop_def.collision_box = { type = "fixed", fixed = { @@ -179,9 +144,20 @@ crop_def.selection_box = { {-0.25, -0.3125, -0.0625, 0.25, 0.5, 0.5}, }, } -crop_def.drop = "mcl_dye:brown 3" +crop_def.drop = "mcl_cocoas:cocoa_beans 3" minetest.register_node("mcl_cocoas:cocoa_3", table.copy(crop_def)) +minetest.register_craftitem("mcl_cocoas:cocoa_beans", { + description = S("Cocoa Beans"), + _tt_help = S("Grows at the side of jungle trees"), + _doc_items_longdesc = S("Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye."), + _doc_items_usagehelp = S("Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."), + inventory_image = "mcl_cocoas_cocoa_beans.png", + groups = {craftitem = 1, compostability = 65}, + on_place = function(itemstack, placer, pointed_thing) + return cocoa_place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1") + end, +}) minetest.register_abm({ label = "Cocoa pod growth", @@ -199,4 +175,3 @@ minetest.register_abm({ if minetest.get_modpath("doc") then doc.add_entry_alias("nodes", "mcl_cocoas:cocoa_1", "nodes", "mcl_cocoas:cocoa_2") end - diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr index 479e3845e..3740c41cf 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.de.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Kakaobohnen +Grows at the side of jungle trees=Wächst an der Seite von Dschungelbäumen +Cocoa beans can be used to plant cocoa pods, bake chocolate cookies or craft brown dye.=Kakaobohnen können benutzt werden, um Kakao anzupflanzen, Kekse zu backen oder braune Farbstoffe herzustellen. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Rechtsklicken Sie an die Seite eines Dschungelbaumstamms (Dschungelholz), um eine junge Kakaoschote zu pflanzen. Premature Cocoa Pod=Junge Kakaoschote Cocoa pods grow on the side of jungle trees in 3 stages.=Kakaoschoten wachsen an der Seite von Dschungelbäumen in 3 Stufen. Medium Cocoa Pod=Mittelgroße Kakaoschote diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr index e1477c79c..c76fc512f 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.es.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Granos de cacao +Grows at the side of jungle trees=Crece al lado de los árboles de la jungla +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Los granos de cacao se pueden usar para plantar cacao, hornear galletas o hacer tintes marrones. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Haga clic derecho en el costado del tronco de un árbol de la jungla para plantar un cacao joven. Premature Cocoa Pod=Vaina de cacao prematura Cocoa pods grow on the side of jungle trees in 3 stages.=Las vainas de cacao crecen al lado de los árboles de jungla en 3 etapas. Medium Cocoa Pod=Vaina de cacao mediana diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr index bf5468953..5d64eb5be 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.fr.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Fèves de Cacao +Grows at the side of jungle trees=Pousse à côté des arbres de la jungle +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Les fèves de cacao peuvent être utilisées pour planter du cacao, faire des biscuits ou fabriquer de la teinture brune. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Clic droit sur le côté d'un tronc d'arbre de la jungle (Bois Acajou) pour planter un jeune cacaoyer. Premature Cocoa Pod=Gousse de cacao prématurée Cocoa pods grow on the side of jungle trees in 3 stages.=Les cabosses de cacao poussent sur le côté des arbres d'Acajou en 3 étapes. Medium Cocoa Pod=Gousse de cacao moyenne diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr new file mode 100644 index 000000000..56117c811 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ja.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_cocoas +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.=成熟したカカオの実は、ジャングルの木で最大まで成長し、カカオ豆を収穫できるようになった状態です。これ以上は成長しません。 diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr new file mode 100644 index 000000000..83df9be7a --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_cocoas +Cocoa Beans=Ziarna kakaowe +Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew +Cocoa beans can be used to plant cocoa, bake cookies or craft brown dye.=Ziarna kakaowe mogą być używane do sadzenia kakao, pieczenia ciasteczek lub robienia brązowego barwnika. +Right click on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao. +Premature Cocoa Pod=Niedojrzała roślina kakao +Cocoa pods grow on the side of jungle trees in 3 stages.=Roślina kakao rośnie na bokach tropikalnych drzew w 3 etapach +Medium Cocoa Pod=Średnio-dojrzała roślina kakao +Mature Cocoa Pod=Dojrzała roślina kakao +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.=Dojrzała roślina kakao wyrosła na drzewie tropikalnym do swojego pełnego rozmiaru i jest gotowa by ją zebrać dla ziaren kakao. Nie urośnie już więcej. diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr new file mode 100644 index 000000000..4501fc1be --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.pt_BR.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_cocoas +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 +Mature Cocoa Pod=Vagem de Cacau Madura +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.=Uma vagem de cacau madura cresceu em uma árvore de selva até seu tamanho máximo e está pronta para ser colhida em sementes de cacau. Não crescerá mais. diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr index 524c28bcc..064c01fd3 100644 --- a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.ru.tr @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans=Какао-бобы +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.=Кликните правой по боковой части ствола дерева джунглей, чтобы посадить молодое какао. Premature Cocoa Pod=Молодой стручок какао Cocoa pods grow on the side of jungle trees in 3 stages.=Стручки какао растут на деревьях джунглей в 3 этапа. Medium Cocoa Pod=Средний стручок какао diff --git a/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr new file mode 100644 index 000000000..038746155 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/locale/mcl_cocoas.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_cocoas +Cocoa Beans=可可豆 +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.=右鍵點擊叢林木的一側,可以種植一個可可。 +Premature Cocoa Pod=成長中的可可豆莢(第1階段) +Cocoa pods grow on the side of jungle trees in 3 stages.=可可莢果分3個階段生長在叢林樹的側面。 +Medium Cocoa Pod=成長中的可可豆莢(第2階段) +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.=一個成熟的可可豆莢在叢林樹上成熟,它已經準備好被收穫成可可豆了。它不會再長了。 diff --git a/mods/ITEMS/mcl_cocoas/locale/template.txt b/mods/ITEMS/mcl_cocoas/locale/template.txt index f68318cae..cb8c5bbfd 100644 --- a/mods/ITEMS/mcl_cocoas/locale/template.txt +++ b/mods/ITEMS/mcl_cocoas/locale/template.txt @@ -1,4 +1,8 @@ # textdomain: mcl_cocoas +Cocoa Beans= +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.= Premature Cocoa Pod= Cocoa pods grow on the side of jungle trees in 3 stages.= Medium Cocoa Pod= diff --git a/mods/ITEMS/mcl_cocoas/mod.conf b/mods/ITEMS/mcl_cocoas/mod.conf index 923ea9785..867636191 100644 --- a/mods/ITEMS/mcl_cocoas/mod.conf +++ b/mods/ITEMS/mcl_cocoas/mod.conf @@ -1 +1,4 @@ name = mcl_cocoas +description = Cocoa pods which grow at jungle trees. Does not include cocoa beans. +depends = mcl_sounds, mcl_core +optional_depends = doc \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj new file mode 100644 index 000000000..35dbb2d00 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_0.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 0.mtl + +o cube +v 0.125 0.25 0.4375 +v 0.125 0.25 0.1875 +v 0.125 -0.0625 0.4375 +v 0.125 -0.0625 0.1875 +v -0.125 0.25 0.1875 +v -0.125 0.25 0.4375 +v -0.125 -0.0625 0.1875 +v -0.125 -0.0625 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0.6875 0.75 +vt 0.9375 0.75 +vt 0.9375 0.4375 +vt 0.6875 0.4375 +vt 0 1 +vt 0.25 1 +vt 0.25 0.75 +vt 0 0.75 +vt 0 1 +vt 0.25 1 +vt 0.25 0.75 +vt 0 0.75 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_a7cd0525-4079-c203-6c53-7d43da5fa1e5 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_a7cd0525-4079-c203-6c53-7d43da5fa1e5 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj new file mode 100644 index 000000000..2a5277856 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_1.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 1.mtl + +o cube +v 0.1875 0.25 0.4375 +v 0.1875 0.25 0.0625 +v 0.1875 -0.1875 0.4375 +v 0.1875 -0.1875 0.0625 +v -0.1875 0.25 0.0625 +v -0.1875 0.25 0.4375 +v -0.1875 -0.1875 0.0625 +v -0.1875 -0.1875 0.4375 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0.5625 0.75 +vt 0.9375 0.75 +vt 0.9375 0.3125 +vt 0.5625 0.3125 +vt 0 1 +vt 0.375 1 +vt 0.375 0.625 +vt 0 0.625 +vt 0 1 +vt 0.375 1 +vt 0.375 0.625 +vt 0 0.625 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_3316e529-b95a-149b-2db3-3eee58b06c25 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_3316e529-b95a-149b-2db3-3eee58b06c25 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj new file mode 100644 index 000000000..8dfd20af1 --- /dev/null +++ b/mods/ITEMS/mcl_cocoas/models/mcl_cocoas_cocoa_stage_2.obj @@ -0,0 +1,95 @@ +# Made in Blockbench 4.5.1 +mtllib Cocoa Pod 2 Fixed.mtl + +o cube +v 0.25 0.25 0.4375 +v 0.25 0.25 -0.0625 +v 0.25 -0.3125 0.4375 +v 0.25 -0.3125 -0.0625 +v -0.25 0.25 -0.0625 +v -0.25 0.25 0.4375 +v -0.25 -0.3125 -0.0625 +v -0.25 -0.3125 0.4375 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0.5 0.75 +vt 1 0.75 +vt 1 0.1875 +vt 0.5 0.1875 +vt 0 1 +vt 0.5 1 +vt 0.5 0.5 +vt 0 0.5 +vt 0 1 +vt 0.5 1 +vt 0.5 0.5 +vt 0 0.5 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_9809ffe0-030e-1955-c510-8df6b242b4e2 +f 4/4/1 7/3/1 5/2/1 2/1/1 +f 3/8/2 4/7/2 2/6/2 1/5/2 +f 8/12/3 3/11/3 1/10/3 6/9/3 +f 7/16/4 8/15/4 6/14/4 5/13/4 +f 6/20/5 1/19/5 2/18/5 5/17/5 +f 7/24/6 4/23/6 3/22/6 8/21/6 +o cube +v 0 0.5 0.5 +v 0 0.5 0.25 +v 0 0.25 0.5 +v 0 0.25 0.25 +v 0 0.5 0.25 +v 0 0.5 0.5 +v 0 0.25 0.25 +v 0 0.25 0.5 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0.75 1 +vt 1 1 +vt 1 0.75 +vt 0.75 0.75 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vt 0 0.25 +vt 0 0.25 +vt 0 0 +vt 0 0 +vn 0 0 -1 +vn 1 0 0 +vn 0 0 1 +vn -1 0 0 +vn 0 1 0 +vn 0 -1 0 +usemtl m_9809ffe0-030e-1955-c510-8df6b242b4e2 +f 12/28/7 15/27/7 13/26/7 10/25/7 +f 11/32/8 12/31/8 10/30/8 9/29/8 +f 16/36/9 11/35/9 9/34/9 14/33/9 +f 15/40/10 16/39/10 14/38/10 13/37/10 +f 14/44/11 9/43/11 10/42/11 13/41/11 +f 15/48/12 12/47/12 11/46/12 16/45/12 \ No newline at end of file diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png deleted file mode 100644 index de58245f4..000000000 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_0.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png deleted file mode 100644 index 47bc159b7..000000000 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png b/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png deleted file mode 100644 index 4e12f623b..000000000 Binary files a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_top_stage_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/depends.txt b/mods/ITEMS/mcl_colorblocks/depends.txt deleted file mode 100644 index c9db3b289..000000000 --- a/mods/ITEMS/mcl_colorblocks/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_dye -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_colorblocks/description.txt b/mods/ITEMS/mcl_colorblocks/description.txt deleted file mode 100644 index ff77b29a6..000000000 --- a/mods/ITEMS/mcl_colorblocks/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds blocks which can be colored, namely hardened clay. diff --git a/mods/ITEMS/mcl_colorblocks/init.lua b/mods/ITEMS/mcl_colorblocks/init.lua index 4981b39b0..6eec8a9df 100644 --- a/mods/ITEMS/mcl_colorblocks/init.lua +++ b/mods/ITEMS/mcl_colorblocks/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_colorblocks") +local S = minetest.get_translator(minetest.get_current_modname()) local doc_mod = minetest.get_modpath("doc") local block = {} @@ -173,20 +173,20 @@ for _, row in ipairs(block.dyes) do -- Crafting recipes if craft_color_group then minetest.register_craft({ - output = 'mcl_colorblocks:hardened_clay_'..name..' 8', + output = "mcl_colorblocks:hardened_clay_"..name.." 8", recipe = { - {'mcl_colorblocks:hardened_clay', 'mcl_colorblocks:hardened_clay', 'mcl_colorblocks:hardened_clay'}, - {'mcl_colorblocks:hardened_clay', 'mcl_dye:'..craft_color_group, 'mcl_colorblocks:hardened_clay'}, - {'mcl_colorblocks:hardened_clay', 'mcl_colorblocks:hardened_clay', 'mcl_colorblocks:hardened_clay'}, + {"mcl_colorblocks:hardened_clay", "mcl_colorblocks:hardened_clay", "mcl_colorblocks:hardened_clay"}, + {"mcl_colorblocks:hardened_clay", "mcl_dye:"..craft_color_group, "mcl_colorblocks:hardened_clay"}, + {"mcl_colorblocks:hardened_clay", "mcl_colorblocks:hardened_clay", "mcl_colorblocks:hardened_clay"}, }, }) minetest.register_craft({ type = "shapeless", - output = 'mcl_colorblocks:concrete_powder_'..name..' 8', + output = "mcl_colorblocks:concrete_powder_"..name.." 8", recipe = { - 'mcl_core:sand', 'mcl_core:gravel', 'mcl_core:sand', - 'mcl_core:gravel', 'mcl_dye:'..craft_color_group, 'mcl_core:gravel', - 'mcl_core:sand', 'mcl_core:gravel', 'mcl_core:sand', + "mcl_core:sand", "mcl_core:gravel", "mcl_core:sand", + "mcl_core:gravel", "mcl_dye:"..craft_color_group, "mcl_core:gravel", + "mcl_core:sand", "mcl_core:gravel", "mcl_core:sand", } }) diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr index d457364ef..f71b54063 100644 --- a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.fr.tr @@ -1,76 +1,76 @@ # textdomain: mcl_colorblocks -White Terracotta=Terre Cuite Blanche -White Glazed Terracotta=Terre Cuite Emaillé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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 Concrete Powder=Béton en Poudre Bleu Clair -Light Blue Concrete=Béton Bleu Clair +White Terracotta=Terre cuite blanche +White Glazed Terracotta=Terre cuite emaillé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 Concrete=Béton gris +Light Grey Terracotta=Terre cuite gris clair +Light Grey Glazed Terracotta=Terre cuite emaillé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 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 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 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 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 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 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 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 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 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 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 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 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 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=Terre Cuite +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é -Glazed Terracotta=Terre Cuite Emaillée -Concrete Powder=Béton en Poudre +Colored Terracotta=Terre cuite colorée +Glazed Terracotta=Terre cuite emaillé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.ja.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ja.tr new file mode 100644 index 000000000..153b1a55a --- /dev/null +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.ja.tr @@ -0,0 +1,76 @@ +# textdomain: mcl_colorblocks +White Terracotta=白色のテラコッタ +White Glazed Terracotta=白色の彩釉テラコッタ +White Concrete Powder=白色のコンクリートパウダー +White Concrete=白色のコンクリート +Grey Terracotta=灰色のテラコッタ +Grey Glazed Terracotta=灰色の彩釉テラコッタ +Grey Concrete Powder=灰色のコンクリートパウダー +Grey Concrete=灰色のコンクリート +Light Grey Terracotta=薄灰色のテラコッタ +Light Grey Glazed Terracotta=薄灰色の彩釉テラコッタ +Light Grey Concrete Powder=薄灰色のコンクリートパウダー +Light Grey Concrete=薄灰色のコンクリート +Black Terracotta=黒色のテラコッタ +Black Glazed Terracotta=黒色の彩釉テラコッタ +Black Concrete Powder=黒色のコンクリートパウダー +Black Concrete=黒色のコンクリート +Red Terracotta=赤色のテラコッタ +Red Glazed Terracotta=赤色の彩釉テラコッタ +Red Concrete Powder=赤色のコンクリートパウダー +Red Concrete=赤色のコンクリート +Yellow Terracotta=黄色のテラコッタ +Yellow Glazed Terracotta=黄色の彩釉テラコッタ +Yellow Concrete Powder=黄色のコンクリートパウダー +Yellow Concrete=黄色のコンクリート +Green Terracotta=緑色のテラコッタ +Green Glazed Terracotta=緑色の彩釉テラコッタ +Green Concrete Powder=緑色のコンクリートパウダー +Green 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=赤紫色のコンクリート +Orange Terracotta=橙色のテラコッタ +Orange Glazed Terracotta=橙色の彩釉テラコッタ +Orange Concrete Powder=橙色のコンクリートパウダー +Orange Concrete=橙色のコンクリート +Purple Terracotta=紫色のテラコッタ +Purple Glazed Terracotta=紫色の彩釉テラコッタ +Purple Concrete Powder=紫色のコンクリートパウダー +Purple Concrete=紫色のコンクリート +Brown Terracotta=茶色のテラコッタ +Brown Glazed Terracotta=茶色の彩釉テラコッタ +Brown Concrete Powder=茶色のコンクリートパウダー +Brown Concrete=茶色のコンクリート +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.=テラコッタは基本的な建築材料です。さまざまな色があります。 +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.=テラコッタは基本的な建築材料で、さまざまな色があります。このブロックは無着色です。 +Colored Terracotta=色付きテラコッタ +Glazed Terracotta=彩釉テラコッタ +Concrete Powder=コンクリートパウダー +Concrete=コンクリート +Turns into concrete on water contact=水との接触でコンクリートに変化 diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pl.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pl.tr new file mode 100644 index 000000000..90a6f2431 --- /dev/null +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pl.tr @@ -0,0 +1,76 @@ +# textdomain: mcl_colorblocks +White Terracotta=Biała terakota +White Glazed Terracotta=Biała glazurowana terakota +White Concrete Powder=Biały cement +White Concrete=Biały beton +Grey Terracotta=Szara terakota +Grey Glazed Terracotta=Szara glazurowana terakota +Grey Concrete Powder=Szary cement +Grey Concrete=Szary beton +Light Grey Terracotta=Jasnoszara terakota +Light Grey Glazed Terracotta=Jasnoszara glazurowana terakota +Light Grey Concrete Powder=Jasnoszary cement +Light Grey Concrete=Jasnoszary beton +Black Terracotta=Czarna terakota +Black Glazed Terracotta=Czarna glazurowana terakota +Black Concrete Powder=Czarny cement +Black Concrete=Czarny beton +Red Terracotta=Czerwona terakota +Red Glazed Terracotta=Czerwona glazurowana terakota +Red Concrete Powder=Czerwony cement +Red Concrete=Czerwony beton +Yellow Terracotta=Żółta terakota +Yellow Glazed Terracotta=Żółta glazurowana terakota +Yellow Concrete Powder=Żółty cement +Yellow Concrete=Żółty beton +Green Terracotta=Zielona terakota +Green Glazed Terracotta=Zielona glazurowana terakota +Green Concrete Powder=Zielony cement +Green Concrete=Zielony beton +Cyan Terracotta=Błękitna terakota +Cyan Glazed Terracotta=Błękitna glazurowana terakota +Cyan Concrete Powder=Błękitny cement +Cyan Concrete=Błękitny beton +Blue Terracotta=Niebieska terakota +Blue Glazed Terracotta=Niebieska glazurowana terakota +Blue Concrete Powder=Niebieski cement +Blue Concrete=Niebieski beton +Magenta Terracotta=Karmazynowa terakota +Magenta Glazed Terracotta=Karmazynowa glazurowana terakota +Magenta Concrete Powder=Karmazynowy cement +Magenta Concrete=Karmazynowy beton +Orange Terracotta=Pomarańczowa terakota +Orange Glazed Terracotta=Pomarańczowa glazurowana terakota +Orange Concrete Powder=Pomarańczowy cement +Orange Concrete=Pomarańczowy beton +Purple Terracotta=Fioletowa terakota +Purple Glazed Terracotta=Fioletowa glazurowana terakota +Purple Concrete Powder=Fioletowy cement +Purple Concrete=Fioletowy beton +Brown Terracotta=Brązowa terakota +Brown Glazed Terracotta=Brązowa glazurowana terakota +Brown Concrete Powder=Brązowy cement +Brown Concrete=Brązowy beton +Pink Terracotta=Różowa terakota +Pink Glazed Terracotta=Różowa glazurowana terakota +Pink Concrete Powder=Różowy cement +Pink Concrete=Różowy beton +Lime Terracotta=Jasnozielona terakota +Lime Glazed Terracotta=Jasnozielona glazurowana terakota +Lime Concrete Powder=Jasnozielony cement +Lime Concrete=Jasnozielony beton +Light Blue Terracotta=Jasnoniebieska terakota +Light Blue Glazed Terracotta=Jasnoniebieska glazurowana terakota +Light Blue Concrete Powder=Jasnoniebieski cement +Light Blue Concrete=Jasnoniebieski beton +Terracotta is a basic building material. It comes in many different colors.=Terakota jest podstawowym blokiem budowlanym. Może mieć wiele różnych kolorów. +Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=Glazurowana terakota jest dekoracyjnym blokiem ze złożonym wzorem. Może być obracana przez stawianie jej w różnych kierunkach. +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.=Cement jest używany do stworzenia betonu, ale może być również sam użyty jako dekoracja. Może mieć wiele różnych kolorów. Cement zamienia się w beton tego samego koloru gdy wejdzie w kontakt z wodą. +Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Beton jest blokiem dekoracyjnym, który może mieć wiele różnych kolorów. Jest warty uwagi ze względu na swój czysty i wyrazisty kolor. +Terracotta=Terakota +Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=Terakota jest podstawowym blokiem budowlanym, który może mieć wiele różnych kolorów. Ten konkretny blok nie ma żadnego koloru. +Colored Terracotta=Barwiona terakota +Glazed Terracotta=Glazurowana terakota +Concrete Powder=Cement +Concrete=Beton +Turns into concrete on water contact=Zamienia się w beton w kontakcie z wodą diff --git a/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pt_BR.tr b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pt_BR.tr new file mode 100644 index 000000000..aa1236f90 --- /dev/null +++ b/mods/ITEMS/mcl_colorblocks/locale/mcl_colorblocks.pt_BR.tr @@ -0,0 +1,76 @@ +# textdomain: mcl_colorblocks +White Terracotta=Terracota Branca +White Glazed Terracotta=Terracota Esmaltada Branca +White Concrete Powder=Pó de Concreto Branco +White Concrete=Concreto Branco +Grey Terracotta=Terracota Cinza +Grey Glazed Terracotta=Terracota Esmaltada Cinza +Grey Concrete Powder=Pó de Concreto Cinza +Grey Concrete=Concreto Cinza +Light Grey Terracotta=Terracota Cinza-Clara +Light Grey Glazed Terracotta=Terracota Esmaltada Cinza-Clara +Light Grey Concrete Powder=Pó de Concreto Cinza-Claro +Light Grey Concrete=Concreto Cinza-Claro +Black Terracotta=Terracota Preta +Black Glazed Terracotta=Terracota Esmaltada Preta +Black Concrete Powder=Pó de Concreto Preto +Black Concrete=Concreto Preto +Red Terracotta=Terracota Vermalha +Red Glazed Terracotta=Terracota Esmaltada Vermelha +Red Concrete Powder=Pó de Concreto Vermelho +Red Concrete=Concreto Vermelho +Yellow Terracotta=Terracota Amarela +Yellow Glazed Terracotta=Terracota Esmaltada Amarela +Yellow Concrete Powder=Pó de Concreto Amarelo +Yellow Concrete=Concreto Amarelo +Green Terracotta=Terracota Verde +Green Glazed Terracotta=Terracota Esmaltada Verde +Green Concrete Powder=Pó de Concreto Verde +Green Concrete=Concreto Verde +Cyan Terracotta=Terracota Ciano +Cyan Glazed Terracotta=Terracota Esmaltada Ciano +Cyan Concrete Powder=Pó de Concreto Ciano +Cyan Concrete=Concreto Ciano +Blue Terracotta=Terracota Azul +Blue Glazed Terracotta=Terracota Esmaltada Azul +Blue Concrete Powder=Pó de Concreto Azul +Blue Concrete=Concreto Azul +Magenta Terracotta=Terracota Magenta +Magenta Glazed Terracotta=Terracota Esmaltada Magenta +Magenta Concrete Powder=Pó de Concreto Magenta +Magenta Concrete=Concreto Magenta +Orange Terracotta=Terracota Laranja +Orange Glazed Terracotta=Terracota Esmaltada Laranja +Orange Concrete Powder=Pó de Concreto Laranja +Orange Concrete=Concreto Laranja +Purple Terracotta=Terracota Roxa +Purple Glazed Terracotta=Terracota Esmaltada Roxa +Purple Concrete Powder=Pó de Concreto Roxo +Purple Concrete=Concreto Roxo +Brown Terracotta=Terracota Marrom +Brown Glazed Terracotta=Terracota Esmaltada Marrom +Brown Concrete Powder=Pó de Concreto Marrom +Brown Concrete=Concreto Marrom +Pink Terracotta=Terracota Rosa +Pink Glazed Terracotta=Terracota Esmaltada Rosa +Pink Concrete Powder=Pó de Concreto Rosa +Pink Concrete=Concreto Rosa +Lime Terracotta=Terracota Lima +Lime Glazed Terracotta=Terracota Esmaltada Lima +Lime Concrete Powder=Pó de Concreto Lima +Lime Concrete=Concreto Lima +Light Blue Terracotta=Terracota Azul-Clara +Light Blue Glazed Terracotta=Terracota Esmaltada Azul-Clara +Light Blue Concrete Powder=Pó de Concreto Azul-Claro +Light Blue Concrete=Concreto Azul-Claro +Terracotta is a basic building material. It comes in many different colors.=Terracota é um material de construção básico. +Glazed terracotta is a decorative block with a complex pattern. It can be rotated by placing it in different directions.=Terracota esmaltada é um bloco decorativo com padrões complexos. Pode ser rotacionado ao ser colocado em diferentes direções. +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.=Pó de concreto é utilizado para fabricar concreto, mas também pode ser usado como um bloco de decoração. Vem em diferentes cores. Pó de concreto se torna concreto da mesma cor quando entra em contato com água. +Concrete is a decorative block which comes in many different colors. It is notable for having a very strong and clean color.=Concreto é um bloco decorativo que vem em diferentes cores. É notável por possuir uma coloração forte e limpa. +Terracotta=Terracota +Terracotta is a basic building material which comes in many different colors. This particular block is uncolored.=Terracota é um material de construção básico que vem em diferentes cores. Este bloco em particular é incolor. +Colored Terracotta=Terracota Colorida +Glazed Terracotta=Terracota Esmaltada +Concrete Powder=Pó de Concreto +Concrete=Concreto +Turns into concrete on water contact=Se torna concreto em contato com água diff --git a/mods/ITEMS/mcl_colorblocks/mod.conf b/mods/ITEMS/mcl_colorblocks/mod.conf index 2d6ffb1c2..dab0ce589 100644 --- a/mods/ITEMS/mcl_colorblocks/mod.conf +++ b/mods/ITEMS/mcl_colorblocks/mod.conf @@ -1 +1,4 @@ name = mcl_colorblocks +description = Adds blocks which can be colored, namely hardened clay. +depends = mcl_core, mcl_sounds, mcl_dye +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_blue.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_blue.png deleted file mode 100644 index 530be0509..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_brown.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_brown.png deleted file mode 100644 index 3344f0757..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_green.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_green.png deleted file mode 100644 index 5d1e5366c..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_grey.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_grey.png deleted file mode 100644 index 885b62fc7..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_light_blue.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_light_blue.png deleted file mode 100644 index a6afea9d7..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_lime.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_lime.png deleted file mode 100644 index d7ac27946..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_magenta.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_magenta.png deleted file mode 100644 index 258efb786..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_pink.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_pink.png deleted file mode 100644 index 75dfa29a1..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_black.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_black.png deleted file mode 100644 index f3447237b..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_blue.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_blue.png deleted file mode 100644 index 12c64fc6d..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_brown.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_brown.png deleted file mode 100644 index 9e355c8a4..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_grey.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_grey.png deleted file mode 100644 index 23d957a8f..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_lime.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_lime.png deleted file mode 100644 index 536e5edc3..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_pink.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_pink.png deleted file mode 100644 index 4a949719f..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_red.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_red.png deleted file mode 100644 index 32195ff46..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_silver.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_silver.png deleted file mode 100644 index 37edd79b9..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_silver.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_yellow.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_yellow.png deleted file mode 100644 index 83d693e09..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_red.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_red.png deleted file mode 100644 index a02379ed3..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_white.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_white.png deleted file mode 100644 index 4561f6538..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_white.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_yellow.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_yellow.png deleted file mode 100644 index 990a5d2d9..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_blue.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_blue.png deleted file mode 100644 index 1fd064eae..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_light_blue.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_light_blue.png deleted file mode 100644 index f78fa94a1..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_lime.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_lime.png deleted file mode 100644 index 7e944f5f7..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_orange.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_orange.png deleted file mode 100644 index 470d56943..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_orange.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_pink.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_pink.png deleted file mode 100644 index 7e71e8c8b..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_pink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_purple.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_purple.png deleted file mode 100644 index f9d025bf9..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_purple.png and /dev/null differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_yellow.png b/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_yellow.png deleted file mode 100644 index 2f2bb4474..000000000 Binary files a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_yellow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_compass/API.md b/mods/ITEMS/mcl_compass/API.md new file mode 100644 index 000000000..8a8e7247e --- /dev/null +++ b/mods/ITEMS/mcl_compass/API.md @@ -0,0 +1,20 @@ +# mcl_compass + +# Compass API + +##mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame +Default compass craftitem. This is also the image that is shown in the inventory. + +##mcl_compass/init.lua:function mcl_compass.get_compass_itemname(pos, dir, itemstack) +Returns the itemname of a compass with needle direction matching the +current compass position. + + pos: position of the compass; + dir: rotational orientation of the compass; + itemstack: the compass including its optional lodestone metadata. + +##mcl_compass/init.lua:function mcl_compass.get_compass_image(pos, dir) +-- Returns partial itemname of a compass with needle direction matching compass position. +-- Legacy compatibility function for mods using older api. + + diff --git a/mods/ITEMS/mcl_compass/depends.txt b/mods/ITEMS/mcl_compass/depends.txt deleted file mode 100644 index 53261d53c..000000000 --- a/mods/ITEMS/mcl_compass/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_worlds -mesecons -doc? diff --git a/mods/ITEMS/mcl_compass/description.txt b/mods/ITEMS/mcl_compass/description.txt deleted file mode 100644 index 221a9f6d9..000000000 --- a/mods/ITEMS/mcl_compass/description.txt +++ /dev/null @@ -1 +0,0 @@ -A compass item which points towards the world origin. diff --git a/mods/ITEMS/mcl_compass/init.lua b/mods/ITEMS/mcl_compass/init.lua index b0cf5627e..2905c0b3b 100644 --- a/mods/ITEMS/mcl_compass/init.lua +++ b/mods/ITEMS/mcl_compass/init.lua @@ -1,121 +1,333 @@ -local S = minetest.get_translator("mcl_compass") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_compass = {} +local compass_types = { + { + name = "compass", + desc = S("Compass"), + tt = S("Points to the world origin"), + longdesc = S("Compasses are tools which point to the world origin (X=0, Z=0) or the spawn point in the Overworld."), + usagehelp = S("A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly."), + }, + { + name = "compass_lodestone", + desc = S("Lodestone Compass"), + tt = S("Points to a lodestone"), + longdesc = S("Lodestone compasses resemble regular compasses, but they point to a specific lodestone."), + usagehelp = S("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."), + }, + { + name = "compass_recovery", + desc = S("Recovery Compass"), + tt = S("Points to your last death location"), + longdesc = S("Recovery Compasses are compasses that point to your last death location"), + usagehelp = S("Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around"), + } +} + +-- Number of dynamic compass images (and items registered.) local compass_frames = 32 -local default_spawn_settings = minetest.settings:get("static_spawnpoint") +-- The image/item that is craftable and shown in inventories. +local stereotype_frame = 18 --- Timer for random compass spinning -local random_timer = 0 -local random_timer_trigger = 0.5 -- random compass spinning tick in seconds. Increase if there are performance problems +-- random compass spinning tick in seconds. +-- Increase if there are performance problems. +local spin_timer_tick = 0.5 -local random_frame = math.random(0, compass_frames-1) +-- Local aliases to globals for better lua performance +local m_deg = math.deg +local m_atan2 = math.atan2 +local m_floor = math.floor +local m_rnd = math.random +local vec_new = vector.new +local string_find = string.find +local string_to_pos = minetest.string_to_pos +local get_connected_players = minetest.get_connected_players +local get_item_group = minetest.get_item_group +local setting_get_pos = minetest.setting_get_pos +local compass_works = mcl_worlds.compass_works +local y_to_layer = mcl_worlds.y_to_layer -minetest.register_globalstep(function(dtime) - random_timer = random_timer + dtime - local players = minetest.get_connected_players() +-- Initialize random compass frame for spinning compass. It is updated in +-- the compass globalstep function. +local random_frame = m_rnd(0, compass_frames-1) - if random_timer >= random_timer_trigger then - random_frame = (random_frame + math.random(-1, 1)) % compass_frames - random_timer = 0 - end - for i,player in ipairs(players) do - local function has_compass(player) - for _,stack in ipairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 then - return true - end - end - return false +local function get_far_node(pos, itemstack) --code from minetest dev wiki: https://dev.minetest.net/minetest.get_node, some edits have been made to add a cooldown for force loads + local node = minetest.get_node(pos) + if node.name == "ignore" then + local tstamp = tonumber(itemstack:get_meta():get_string("last_forceload")) + if tstamp == nil then --this is only relevant for new lodestone compasses, the ones that have never performes a forceload yet + itemstack:get_meta():set_string("last_forceload", tostring(os.time(os.date("!*t")))) + tstamp = tonumber(os.time(os.date("!*t"))) end - if has_compass(player) then - local pos = player:get_pos() - local dim = mcl_worlds.pos_to_dimension(pos) - local compass_image - -- Compasses do not work in certain zones - if not mcl_worlds.compass_works(pos) then - compass_image = random_frame - else - local spawn = {x=0,y=0,z=0} - local ssp = minetest.setting_get_pos("static_spawnpoint") - if ssp then - spawn = ssp - if type(spawn) ~= "table" or type(spawn.x) ~= "number" or type(spawn.y) ~= "number" or type(spawn.z) ~= "number" then - spawn = {x=0,y=0,z=0} + if tonumber(os.time(os.date("!*t"))) - tstamp > 180 then --current time in secounds - old time in secounds, if it is over 180 (3 mins): forceload + itemstack:get_meta():set_string("last_forceload", tostring(os.time(os.date("!*t")))) + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node(pos) + else + node = {name="mcl_compass:lodestone"} --cooldown not over yet, pretend like there is something... + end + end + return node +end + +--- Get compass needle angle. +-- Returns the angle that the compass needle should point at expressed in +-- 360 degrees divided by the number of possible compass image frames.. +-- +-- pos: position of the compass; +-- target: position that the needle points towards; +-- dir: rotational direction of the compass. +-- +local function get_compass_angle(pos, target, dir) + local angle_north = m_deg(m_atan2(target.x - pos.x, target.z - pos.z)) + if angle_north < 0 then angle_north = angle_north + 360 end + local angle_dir = -m_deg(dir) + local angle_relative = (angle_north - angle_dir + 180) % 360 + return m_floor((angle_relative/11.25) + 0.5) % compass_frames +end + +--- Get compass image frame. +-- Returns the compass image frame with the needle direction matching the +-- compass' current position. +-- +-- pos: position of the compass; +-- dir: rotational direction of the compass. +-- itemstack: the compass including its optional lodestone metadata. +-- +local function get_compass_frame(pos, dir, itemstack) + if not string_find(itemstack:get_name(), "_lodestone") then -- normal compass + -- Compasses only work in the overworld + if compass_works(pos) then + local spawn_pos = setting_get_pos("static_spawnpoint") + or vec_new(0, 0, 0) + return get_compass_angle(pos, spawn_pos, dir) + else + return random_frame + end + else -- lodestone compass + local lpos_str = itemstack:get_meta():get_string("pointsto") + local lpos = string_to_pos(lpos_str) + if not lpos then + minetest.log("warning", "mcl_compass: invalid lodestone position!") + return random_frame + end + local _, l_dim = y_to_layer(lpos.y) + local _, p_dim = y_to_layer(pos.y) + -- compass and lodestone must be in the same dimension + if l_dim == p_dim then + --check if lodestone still exists + if get_far_node(lpos, itemstack).name == "mcl_compass:lodestone" then + return get_compass_angle(pos, lpos, dir) + else -- lodestone got destroyed + return random_frame + end + else + return random_frame + end + end +end + +-- Export stereotype item for other mods to use +mcl_compass.stereotype = "mcl_compass:" .. stereotype_frame + +--- Get partial compass itemname. +-- Returns partial itemname of a compass with needle direction matching compass position. +-- Legacy compatibility function for mods using older api. +-- +function mcl_compass.get_compass_image(pos, dir) + minetest.log("warning", "mcl_compass: deprecated function " .. + "get_compass_image() called, use get_compass_itemname().") + local itemstack = ItemStack(mcl_compass.stereotype) + return get_compass_frame(pos, dir, itemstack) +end + +--- Get compass itemname. +-- Returns the itemname of a compass with needle direction matching the +-- current compass position. +-- +-- pos: position of the compass; +-- dir: rotational orientation of the compass; +-- itemstack: the compass including its optional lodestone metadata. +-- +function mcl_compass.get_compass_itemname(pos, dir, itemstack) + if not itemstack then + minetest.log("warning", "mcl_compass.get_compass_image called without itemstack!") + return "mcl_compass:" .. stereotype_frame + end + local frame = get_compass_frame(pos, dir, itemstack) + if itemstack:get_meta():get_string("pointsto") ~= "" then + return "mcl_compass:" .. frame .. "_lodestone" + else + return "mcl_compass:" .. frame + end +end + +-- Timer for randomly spinning compass. +-- Gets updated and checked in the globalstep function. +local spin_timer = 0 + +-- Compass globalstep function. +-- * updates random spin counter and random frame of spinning compasses; +-- * updates all compasses in player's inventories to match the correct +-- needle orientations for their current positions. +-- +minetest.register_globalstep(function(dtime) + spin_timer = spin_timer + dtime + if spin_timer >= spin_timer_tick then + random_frame = (random_frame + m_rnd(-1, 1)) % compass_frames + spin_timer = 0 + end + + local compass_nr, compass_frame + local pos, dir, inv + for _, player in pairs(get_connected_players()) do + pos = player:get_pos() + dir = player:get_look_horizontal() + inv = player:get_inventory() + for j, stack in pairs(inv:get_list("main")) do + compass_nr = get_item_group(stack:get_name(), "compass") + if compass_nr ~= 0 and not string_find(stack:get_name(), "_recovery") then + -- check if current compass image still matches true orientation + compass_frame = get_compass_frame(pos, dir, stack) + if compass_nr - 1 ~= compass_frame then + + if string_find(stack:get_name(), "_lodestone") then + stack:set_name("mcl_compass:" .. compass_frame .. "_lodestone") + awards.unlock(player:get_player_name(), "mcl:countryLode") + else + stack:set_name("mcl_compass:" .. compass_frame) + end + inv:set_stack("main", j, stack) + end + elseif compass_nr ~= 0 then + local meta = player:get_meta() + local posstring = meta:get_string("mcl_compass:recovery_pos") + if not posstring or posstring == "" then + stack:set_name("mcl_compass:"..random_frame .. "_recovery") + else + local targetpos = minetest.string_to_pos(posstring) + local _, target_dim = y_to_layer(targetpos.y) + local _, p_dim = y_to_layer(pos.y) + if p_dim ~= target_dim then + stack:set_name("mcl_compass:"..random_frame.."_recovery") + else + stack:set_name("mcl_compass:"..get_compass_angle(pos,targetpos,dir).."_recovery") end end - local dir = player:get_look_horizontal() - local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z)) - if angle_north < 0 then angle_north = angle_north + 360 end - local angle_dir = -math.deg(dir) - local angle_relative = (angle_north - angle_dir + 180) % 360 - compass_image = math.floor((angle_relative/11.25) + 0.5) % compass_frames - end - - for j,stack in ipairs(player:get_inventory():get_list("main")) do - if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and - minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then - local itemname = "mcl_compass:"..compass_image - stack:set_name(itemname) - player:get_inventory():set_stack("main", j, stack) - end + inv:set_stack("main",j,stack) end end end end) -local images = {} -for frame = 0, compass_frames-1 do - local s = string.format("%02d", frame) - table.insert(images, "mcl_compass_compass_"..s..".png") -end +-- +-- Node and craftitem definitions +-- +local doc_mod = minetest.get_modpath("doc") -local doc_mod = minetest.get_modpath("doc") ~= nil - -local stereotype_frame = 18 -for i,img in ipairs(images) do - local inv = 1 - if i == stereotype_frame then - inv = 0 +for _, item in pairs(compass_types) do + local name_fmt, img_fmt + if item.name == "compass" then + name_fmt = "mcl_compass:%d" + img_fmt = "mcl_compass_compass_%02d.png" + elseif item.name == "compass_lodestone" then + name_fmt = "mcl_compass:%d_lodestone" + img_fmt = "mcl_compass_compass_%02d.png^[colorize:purple:50" + elseif item.name == "compass_recovery" then + name_fmt = "mcl_compass:%d_recovery" + img_fmt = "mcl_compass_recovery_compass_%02d.png" end - local use_doc, longdesc, usagehelp, tt - use_doc = i == stereotype_frame - if use_doc then - tt = S("Points to the world origin") - longdesc = S("Compasses are tools which point to the world origin (X=0, Z=0) or the spawn point in the Overworld.") - end - local itemstring = "mcl_compass:"..(i-1) - minetest.register_craftitem(itemstring, { - description = S("Compass"), - _tt_help = tt, - _doc_items_create_entry = use_doc, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - inventory_image = img, - wield_image = img, - stack_max = 64, - groups = {not_in_creative_inventory=inv, compass=i, tool=1, disable_repair=1 } - }) + for i = 0, compass_frames - 1 do + local itemstring = string.format(name_fmt, i) + local def = { + description = item.desc, + _tt_help = item.tt, + inventory_image = string.format(img_fmt, i), + wield_image = string.format(img_fmt, i), + groups = {compass = i + 1, tool = 1, disable_repair = 1}, + } + if i == stereotype_frame then + def._doc_items_longdesc = item.longdesc + def._doc_items_usagehelp = item.usagehelp + if string.match(itemstring, "lodestone") then + def.groups.not_in_creative_inventory = 1 + end + else + def._doc_items_create_entry = false + def.groups.not_in_creative_inventory = 1 + end + minetest.register_craftitem(itemstring, table.copy(def)) - -- Help aliases. Makes sure the lookup tool works correctly - if not use_doc and doc_mod then - doc.add_entry_alias("craftitems", "mcl_compass:"..(stereotype_frame-1), "craftitems", itemstring) + -- Help aliases. Makes sure the lookup tool works correctly + if doc_mod and i ~= stereotype_frame then + doc.add_entry_alias("craftitems", "mcl_compass:"..(stereotype_frame), "craftitems", itemstring) + end end end minetest.register_craft({ - output = 'mcl_compass:'..stereotype_frame, + output = "mcl_compass:" .. stereotype_frame, recipe = { - {'', 'mcl_core:iron_ingot', ''}, - {'mcl_core:iron_ingot', 'mesecons:redstone', 'mcl_core:iron_ingot'}, - {'', 'mcl_core:iron_ingot', ''} + {"", "mcl_core:iron_ingot", ""}, + {"mcl_core:iron_ingot", "mesecons:redstone", "mcl_core:iron_ingot"}, + {"", "mcl_core:iron_ingot", ""} } }) -minetest.register_alias("mcl_compass:compass", "mcl_compass:"..stereotype_frame) +minetest.register_craft({ --TODO: update once echo shards are a thing + output = "mcl_compass:" .. random_frame .. "_recovery", + recipe = { + {"","mcl_nether:netherite_ingot",""}, + {"mcl_core:diamondblock","mcl_compass:" .. stereotype_frame ,"mcl_core:diamondblock"}, + {"mcl_core:diamondblock","mcl_core:diamondblock","mcl_core:diamondblock"} --- Export stereotype item for other mods to use -mcl_compass.stereotype = "mcl_compass:"..tostring(stereotype_frame) + } +}) + +minetest.register_alias("mcl_compass:compass", "mcl_compass:" .. stereotype_frame) +minetest.register_node("mcl_compass:lodestone",{ + description=S("Lodestone"), + on_rightclick = function(pos, node, player, itemstack) + local name = itemstack.get_name(itemstack) + if string_find(name,"mcl_compass:") then + if name ~= "mcl_compass:lodestone" then + itemstack:get_meta():set_string("pointsto", minetest.pos_to_string(pos)) + local dir = player:get_look_horizontal() + local frame = get_compass_frame(pos, dir, itemstack) + itemstack:set_name("mcl_compass:" .. frame .. "_lodestone") + end + end + end, + tiles = { + "lodestone_top.png", + "lodestone_bottom.png", + "lodestone_side1.png", + "lodestone_side2.png", + "lodestone_side3.png", + "lodestone_side4.png" + }, + groups = {pickaxey=1, material_stone=1}, + _mcl_hardness = 1.5, + _mcl_blast_resistance = 6, + sounds = mcl_sounds.node_sound_stone_defaults() +}) + +minetest.register_craft({ + output = "mcl_compass:lodestone", + recipe = { + {"mcl_core:stonebrickcarved","mcl_core:stonebrickcarved","mcl_core:stonebrickcarved"}, + {"mcl_core:stonebrickcarved", "mcl_nether:netherite_ingot", "mcl_core:stonebrickcarved"}, + {"mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved", "mcl_core:stonebrickcarved"} + } +}) + +--set recovery meta +minetest.register_on_dieplayer(function(player) + local meta = player:get_meta(); + meta:set_string("mcl_compass:recovery_pos",minetest.pos_to_string(player:get_pos())) +end) \ No newline at end of file diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr index a78b70c01..9ae821e2b 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.de.tr @@ -1,4 +1,13 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder den Einstiegspunkt der Welt zeigen. Compass=Kompass Points to the world origin=Zeigt zum Startpunkt der Welt +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasse sind Werkzeuge, die zum Ursprungspunkt der Welt (X@=0, Z@=0) oder zum Einstiegspunkt der Welt zeigen. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Ein Kompass zeigt immer zum Weltspawn in der Oberwelt. In sämtlichen anderen Dimensionen dreht er sich zufällig. +Lodestone Compass=Leitstein Kompass +Points to a lodestone=Zeigt zu einem Leitstein +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Leitstein Kompasse ähneln normalen Kompassen, aber sie zeigen zu einen spezifischen Leitstein. +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.=Ein Leitstein Kompass kann mit einem normalen Kompass erstellt werden indem man ihn auf einem Leitstein benutzt. Nachdem er ein Leitstein Kompass geworden ist, wird er immer zu seinem Leitstein zeigen, sofern sie in der selben Dimension sind. Wenn sie nicht in der selben Dimension sind, dreht sich der Leitstein Kompass zufällig, wie ein normaler Kompass außerhalb der Oberwelt. Ein Leitstein Kompass kann mit einem anderem Leitstein verknüpft werden. +Recovery Compass=Wiederherstellungskompass +Points to your last death location=Zeigt zu dem Ort, an dem Sie zuletzt verendet sind +Recovery Compasses are compasses that point to your last death location=Wiederhelstellungskompasse sind Kompasse, die zu dem Ort zeigen, an dem Sie zuletzt gestorben sind +Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around=Wiederherstellungskompasse zeigen immer zu dem Ort Ihres letzten Todes, falls Sie noch nicht gestorben sind drehen sie sich zufällig diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr index 4f9fd5294..77b36cad9 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.es.tr @@ -1,3 +1,9 @@ # 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. -Compass=Brújula \ No newline at end of file +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.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr index 89299fde7..87dc31650 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.fr.tr @@ -1,4 +1,14 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Les boussoles sont des outils qui pointent vers l'origine du monde (X@=0,Z@=0) ou le point d'apparition dans l'Overworld. Compass=Boussole Points to the world origin=Pointe vers l'origine mondiale +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Les boussoles sont des outils qui pointent vers l'origine du monde (X@=0,Z@=0) ou le point d'apparition dans l'Overworld. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Une boussole pointe toujours vers le point d'apparition quand le joueur est dans l'overworld. Dans d'autres dimensions elle tourne au hasard. +Lodestone Compass=Boussole magnétisée +Points to a lodestone=Pointe vers une magnétite +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Les boussoles magnétisées ressemblent à des boussoles normales, mais pointent vers une magnétite spécifique. +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.=Une boussole magnétisée peut être crée à partir d'une boussole normale en l'utilisant sur une magnétite. Après être devenue une boussole magnétisée, elle pointera toujours vers sa magnétite liée, pourvu qu'elle soit dans la même dimension. Si ce n'est pas le cas, la boussole magnétisée tourne au hasard, comme une boussole normale hors de l'overworld. Une boussole magnétisée peut être liée à une autre magnétite. +Lodestone=Magnétite +Recovery Compass=Boussole de récupération +Points to your last death location=Pointe vers le lieu de votre dernière mort +Recovery Compasses are compasses that point to your last death location=Les boussoles de récupération sont des boussoles qui pointent vers le lieu de votre dernière mort +Recovery Compasses always point to the location of your last death, in case you haven't died yet, it will just randomly spin around=Les boussoles de récupération pointent toujours vers le lieu de votre dernière mort, si vous n'êtes jamais mort, elle va juste tourner aléatoirement diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr new file mode 100644 index 000000000..00783e840 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.ja.tr @@ -0,0 +1,10 @@ +# 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.=ロードストーンコンパスは、ロードストーンの上で通常のコンパスを使用することにより作成できます。 ロードストーンコンパスとなった後は、同じ次元にあるならば、常にリンクしたロードストーンを指すようになります。同じ次元にない場合、オーバーワールド外の通常コンパスと同様、ランダムに回転します。 ロードストーンコンパスは他のロードストーンとの再リンクが可能です。 +Lodestone=ロードストーン diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr new file mode 100644 index 000000000..33ac4b204 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.pl.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_compass +Compass=Kompas +Points to the world origin=Wskazuje na początek świata +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Kompasy to narzędzia które wskazują na punkt początku świata (X@=0, Z@=0) lub na miejsce odrodzenia na Powierzchni. +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.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.pt_BR.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.pt_BR.tr new file mode 100644 index 000000000..3e16f329d --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.pt_BR.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_compass +Compass=Bússola +Points to the world origin=Aponta para a origem do mundo +Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Bússolas são ferramentas que aponta para a origem do mundo (X@=0, Z@=0) ou para o lugar de spawn na Superfície. +A Compass always points to the world spawn point when the player is in the overworld. In other dimensions, it spins randomly.=Uma bússola sempre aponta para o lugar de spawn do mundo quando o jogador está na superfície. Em outras dimensões, ela gira aleatoriamente. +Lodestone Compass=Bússola Magnetizada +Points to a lodestone=Aponta para uma magnetita +Lodestone compasses resemble regular compasses, but they point to a specific lodestone.=Bússolas magnetizadas lembram bússolas comuns, mas apontam para uma 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.=Uma bússola magnetizada pode ser feita a partir de uma bússola comum ao utilizá-la em uma magnetita. Após se tornar uma bússola magnetizada, sempre apontará para a magnetita vinculada desde que estejam na mesma dimensão. Se não estão na mesma dimensão, uma bússola magnetizada girará aleatoriamente, similar a uma bússola comum quando está fora da superfície. Uma bússola magnetizada pode ser revinculada com outra magnetita. +Lodestone=Magnetita diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr index dadf20c7d..7fd98de87 100644 --- a/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.ru.tr @@ -1,4 +1,9 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.=Компас - инструмент, показывающий на начало мира (X@=0, Z@=0) или на точку возрождения в Верхнем Мире. 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.= diff --git a/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr b/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr new file mode 100644 index 000000000..257487a55 --- /dev/null +++ b/mods/ITEMS/mcl_compass/locale/mcl_compass.zh_TW.tr @@ -0,0 +1,9 @@ +# 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.= diff --git a/mods/ITEMS/mcl_compass/locale/template.txt b/mods/ITEMS/mcl_compass/locale/template.txt index 462a08bc4..e1b7ae7f9 100644 --- a/mods/ITEMS/mcl_compass/locale/template.txt +++ b/mods/ITEMS/mcl_compass/locale/template.txt @@ -1,4 +1,14 @@ # textdomain: mcl_compass -Compasses are tools which point to the world origin (X@=0, Z@=0) or the spawn point in the Overworld.= 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.= +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_compass/mod.conf b/mods/ITEMS/mcl_compass/mod.conf index 8c9e0a652..f63a6f307 100644 --- a/mods/ITEMS/mcl_compass/mod.conf +++ b/mods/ITEMS/mcl_compass/mod.conf @@ -1 +1,4 @@ name = mcl_compass +description = A compass item which points towards the world origin. +depends = mcl_core, mcl_worlds, mesecons, mcl_sounds +optional_depends = doc \ No newline at end of file diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_00.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_00.png deleted file mode 100644 index 5ba59433d..000000000 Binary files a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_00.png and /dev/null differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_01.png b/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_01.png deleted file mode 100644 index 4688db60d..000000000 Binary files a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_01.png and /dev/null differ diff --git a/mods/ITEMS/mcl_composters/init.lua b/mods/ITEMS/mcl_composters/init.lua new file mode 100644 index 000000000..d60422afd --- /dev/null +++ b/mods/ITEMS/mcl_composters/init.lua @@ -0,0 +1,287 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +-- +-- Composter mod, adds composters. +-- +-- Copyleft 2022 by kabou +-- GNU General Public Licence 3.0 +-- + +local composter_description = S( + "Composter" +) +local composter_longdesc = S( + "Composters can convert various organic items into bonemeal." +) +local composter_usagehelp = S( + "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." +) + +minetest.register_craft({ + output = "mcl_composters:composter", + recipe = { + {"group:wood_slab", "", "group:wood_slab"}, + {"group:wood_slab", "", "group:wood_slab"}, + {"group:wood_slab", "group:wood_slab", "group:wood_slab"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_composters:composter", + burntime = 15, +}) + +local get_item_group = minetest.get_item_group +local is_creative_enabled = minetest.is_creative_enabled +local registered_nodes = minetest.registered_nodes +local swap_node = minetest.swap_node +local get_node_timer = minetest.get_node_timer +local add_item = minetest.add_item +local vector_offset = vector.offset +local is_protected = minetest.is_protected +local record_protection_violation = minetest.record_protection_violation + +--- Fill the composter when rightclicked. +-- +-- `on_rightclick` handler for composter blocks of all fill levels except +-- for the "ready" composter (see: composter_harvest). +-- If the item used on the composter block is compostable, there is a chance +-- that the level of the composter may increase, depending on the value of +-- compostability of the item. +-- +-- parameters are the standard parameters passed to `on_rightclick`. +-- returns the remaining itemstack. +-- +local function composter_add_item(pos, node, player, itemstack, pointed_thing) + if not player or (player:get_player_control() and player:get_player_control().sneak) then + return itemstack + end + local name = player:get_player_name() + if is_protected(pos, name) then + record_protection_violation(pos, name) + return itemstack + end + if not itemstack or itemstack:is_empty() then + return itemstack + end + local itemname = itemstack:get_name() + local chance = get_item_group(itemname, "compostability") + if chance > 0 then + if not is_creative_enabled(player:get_player_name()) then + itemstack:take_item() + minetest.sound_play({name="default_gravel_dug", gain=1}, { + pos = pos, + 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) + timer:start(1) + end + end + end + return itemstack +end + +--- Update a full composter block to ready for harvesting. +-- +-- `on_timer` handler. The timer is set in function 'composter_add_item' +-- when the composter level has reached 7. +-- +-- pos: position of the composter block. +-- returns false, thereby cancelling further activity of the timer. +-- +local function composter_ready(pos) + swap_node(pos, {name = "mcl_composters:composter_ready"}) + -- maybe spawn particles again? + minetest.sound_play({name="default_dig_snappy", gain=1}, { + pos = pos, + max_hear_distance = 16, + }, true) + return false +end + +--- Spawn bone meal item and reset composter block. +-- +-- `on_rightclick` handler for the "ready" composter block. Causes a +-- bone meal item to be spawned from the composter and resets the +-- composter block to an empty composter block. +-- +-- parameterss are the standard parameters passed to `on_rightclick`. +-- returns itemstack (unchanged in this function). +-- +local function composter_harvest(pos, node, player, itemstack, pointed_thing) + if not player or (player:get_player_control() and player:get_player_control().sneak) then + return itemstack + end + local name = player:get_player_name() + if is_protected(pos, name) then + record_protection_violation(pos, name) + return itemstack + end + -- reset ready type composter to empty type + swap_node(pos, {name="mcl_composters:composter"}) + -- spawn bone meal item + add_item(pos, "mcl_bone_meal:bone_meal") + -- TODO play some sounds + return itemstack +end + +--- Construct composter nodeboxes with varying levels of compost. +-- +-- level: compost level in the composter +-- returns a nodebox definition table. +-- +local function composter_get_nodeboxes(level) + local top_y_tbl = {[0]=-7, -5, -3, -1, 1, 3, 5, 7} + local top_y = top_y_tbl[level] / 16 + return { + type = "fixed", + fixed = { + {-0.5, -0.5, -0.5, -0.375, 0.5, 0.5}, -- Left wall + { 0.375, -0.5, -0.5, 0.5, 0.5, 0.5}, -- Right wall + {-0.375, -0.5, 0.375, 0.375, 0.5, 0.5}, -- Back wall + {-0.375, -0.5, -0.5, 0.375, 0.5, -0.375}, -- Front wall + {-0.5, -0.5, -0.5, 0.5, top_y, 0.5}, -- Bottom level + } + } +end + +--- Register empty composter node. +-- +-- This is the craftable base model that can be placed in an inventory. +-- +minetest.register_node("mcl_composters:composter", { + description = composter_description, + _tt_help = S("Converts organic items into bonemeal"), + _doc_items_longdesc = composter_longdesc, + _doc_items_usagehelp = composter_usagehelp, + paramtype = "light", + drawtype = "nodebox", + node_box = composter_get_nodeboxes(0), + selection_box = {type = "regular"}, + tiles = { + "mcl_composter_bottom.png^mcl_composter_top.png", + "mcl_composter_bottom.png", + "mcl_composter_side.png" + }, + is_ground_content = false, + groups = { + handy=1, material_wood=1, deco_block=1, dirtifier=1, + flammable=2, fire_encouragement=3, fire_flammability=4, + }, + 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 +}) + +--- Template function for composters with compost. +-- +-- For each fill level a custom node is registered. +-- +local function register_filled_composter(level) + local id = "mcl_composters:composter_"..level + minetest.register_node(id, { + description = S("Composter") .. " (" .. level .. "/7 " .. S("filled") .. ")", + _doc_items_create_entry = false, + paramtype = "light", + drawtype = "nodebox", + node_box = composter_get_nodeboxes(level), + selection_box = {type = "regular"}, + tiles = { + "mcl_composter_compost.png^mcl_composter_top.png", + "mcl_composter_bottom.png", + "mcl_composter_side.png" + }, + is_ground_content = false, + groups = { + 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 + }, + sounds = mcl_sounds.node_sound_wood_defaults(), + drop = "mcl_composters:composter", + _mcl_hardness = 0.6, + _mcl_blast_resistance = 0.6, + _mcl_compost_level = level, + on_rightclick = composter_add_item, + on_timer = composter_ready + }) + + -- Add entry aliases for the Help + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_composters:composter", "nodes", id) + end +end + +--- Register filled composters (7 levels). +-- +for level = 1, 7 do + register_filled_composter(level) +end + +--- Register composter that is ready to be harvested. +-- +minetest.register_node("mcl_composters:composter_ready", { + description = S("Composter") .. "(" .. S("ready for harvest") .. ")", + _doc_items_create_entry = false, + paramtype = "light", + drawtype = "nodebox", + node_box = composter_get_nodeboxes(7), + selection_box = {type = "regular"}, + tiles = { + "mcl_composter_ready.png^mcl_composter_top.png", + "mcl_composter_bottom.png", + "mcl_composter_side.png" + }, + is_ground_content = false, + groups = { + 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 + }, + 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 +}) + +-- Add entry aliases for the Help +if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_composters:composter", + "nodes", "mcl_composters:composter_ready" ) +end diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr new file mode 100644 index 000000000..0f4e665e6 --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.fr.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_composters +Composter=Composteur +Composters can convert various organic items into bonemeal.=Les composteurs peuvent convertir divers objets organiques en farine d'os. +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.=Utiliser des objets organiques sur le composteur pour le remplir de couches de compost. Chaque fois qu'un objet est mis dans le composteur, il y a une chance d'ajouter une nouvelle couche de compost au composteur. Certains objets ont une plus grande chance que d'autres d'ajouter une couche supplémentaire. Après l'avoir rempli de 7 couches de compost, le composteur est plein. Après un délai d'approximativement une seconde, le composteur est prêt et on peut récupérer la farine d'os. Cliquer droit le composteur permet de récupérer la farine d'os et de vider le composteur. +filled=rempli +ready for harvest=prêt pour la récolte +Converts organic items into bonemeal=Convertit les objets organiques en farine d'os. diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr new file mode 100644 index 000000000..6d8908486 --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.ja.tr @@ -0,0 +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."=コンポスターに有機物を入れて、堆肥の層を作りましょう。コンポスターに有機物を入れるたびに、次の堆肥の層が追加されるチャンスが起きます。 追加される確率がより高くなっているアイテムもいくつかあります。 7層分の堆肥が充填されると、コンポスターは満杯となります。その約1秒後に、骨粉を取り出せる準備が完了します。右クリックして骨粉を取り出すと、コンポスターは空になります。 +filled=充足 +ready for harvest=収穫可能 +Converts organic items into bonemeal=有機物を骨粉に変える diff --git a/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr b/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr new file mode 100644 index 000000000..db472dad4 --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/mcl_composters.ru.tr @@ -0,0 +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 diff --git a/mods/ITEMS/mcl_composters/locale/template.txt b/mods/ITEMS/mcl_composters/locale/template.txt new file mode 100644 index 000000000..f3329719a --- /dev/null +++ b/mods/ITEMS/mcl_composters/locale/template.txt @@ -0,0 +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= diff --git a/mods/ITEMS/mcl_composters/mod.conf b/mods/ITEMS/mcl_composters/mod.conf new file mode 100644 index 000000000..86d729887 --- /dev/null +++ b/mods/ITEMS/mcl_composters/mod.conf @@ -0,0 +1,5 @@ +name = mcl_composters +author = kabou +description = Composters can convert various organic items into bonemeal. +depends = mcl_core, mcl_sounds, mcl_dye +optional_depends = doc diff --git a/mods/ITEMS/mcl_copper/README.md b/mods/ITEMS/mcl_copper/README.md new file mode 100644 index 000000000..6a6f2d7d2 --- /dev/null +++ b/mods/ITEMS/mcl_copper/README.md @@ -0,0 +1,7 @@ +# MineClone2 Copper + +### by NO11 + +Adds copper ore, blocks and items. + +![screenshot](./screenshot.png) diff --git a/mods/ITEMS/mcl_copper/crafting.lua b/mods/ITEMS/mcl_copper/crafting.lua new file mode 100644 index 000000000..ce280fcdf --- /dev/null +++ b/mods/ITEMS/mcl_copper/crafting.lua @@ -0,0 +1,94 @@ +minetest.register_craft({ + output = "mcl_copper:block_raw", + recipe = { + { "mcl_copper:raw_copper", "mcl_copper:raw_copper", "mcl_copper:raw_copper" }, + { "mcl_copper:raw_copper", "mcl_copper:raw_copper", "mcl_copper:raw_copper" }, + { "mcl_copper:raw_copper", "mcl_copper:raw_copper", "mcl_copper:raw_copper" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:block", + recipe = { + { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, + { "mcl_copper:copper_ingot", "mcl_copper:copper_ingot" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:block_cut 4", + recipe = { + { "mcl_copper:block", "mcl_copper:block" }, + { "mcl_copper:block", "mcl_copper:block" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:block_exposed_cut 4", + recipe = { + { "mcl_copper:block_exposed", "mcl_copper:block_exposed" }, + { "mcl_copper:block_exposed", "mcl_copper:block_exposed" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:block_oxidized_cut 4", + recipe = { + { "mcl_copper:block_oxidized", "mcl_copper:block_oxidized" }, + { "mcl_copper:block_oxidized", "mcl_copper:block_oxidized" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:mcl_copper:block_weathered_cut 4", + recipe = { + { "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, + { "mcl_copper:block_weathered", "mcl_copper:block_weathered" }, + }, +}) + +local waxable_blocks = { "block", "block_cut", "block_exposed", "block_exposed_cut", "block_weathered", "block_weathered_cut", "block_oxidized", "block_oxidized_cut" } + +for _, w in ipairs(waxable_blocks) do + minetest.register_craft({ + output = "mcl_copper:waxed_"..w, + recipe = { + { "mcl_copper:"..w, "mcl_honey:honeycomb" }, + }, + }) +end + +minetest.register_craft({ + output = "mcl_copper:copper_ingot 4", + recipe = { + { "mcl_copper:block" }, + }, +}) + +minetest.register_craft({ + output = "mcl_copper:raw_copper 9", + recipe = { + { "mcl_copper:block_raw" }, + }, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_copper:copper_ingot", + recipe = "mcl_copper:raw_copper", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_copper:copper_ingot", + recipe = "mcl_copper:stone_with_copper", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_copper:block", + recipe = "mcl_copper:block_raw", + cooktime = 90, +}) diff --git a/mods/ITEMS/mcl_copper/functions.lua b/mods/ITEMS/mcl_copper/functions.lua new file mode 100644 index 000000000..bd289f60f --- /dev/null +++ b/mods/ITEMS/mcl_copper/functions.lua @@ -0,0 +1,132 @@ +local stair_oxidization = { + { "cut", "exposed_cut" }, + { "cut_inner", "exposed_cut_inner" }, + { "cut_outer", "exposed_cut_outer" }, + { "exposed_cut", "weathered_cut" }, + { "exposed_cut_inner", "weathered_cut_inner" }, + { "exposed_cut_outer", "weathered_cut_outer" }, + { "weathered_cut", "oxidized_cut" }, + { "weathered_cut_inner", "oxidized_cut_inner" }, + { "weathered_cut_outer", "oxidized_cut_outer" } +} + +local slab_oxidization = { + { "cut", "exposed_cut" }, + { "cut_top", "exposed_cut_top" }, + { "cut_double", "exposed_cut_double" }, + { "exposed_cut", "weathered_cut" }, + { "exposed_cut_top", "weathered_cut_top" }, + { "exposed_cut_double", "weathered_cut_double" }, + { "weathered_cut", "oxidized_cut" }, + { "weathered_cut_top", "oxidized_cut_top" }, + { "weathered_cut_double", "oxidized_cut_double" }, +} + +local def +local def_variant_oxidized +local def_variant_waxed +local def_variant_scraped + +-- set up oxidized and waxed variants. +for i = 1, #stair_oxidization do + -- stairs + def = "mcl_stairs:stair_copper_" .. stair_oxidization[i][1] + def_variant_oxidized = "mcl_stairs:stair_copper_" .. stair_oxidization[i][2] + minetest.override_item(def, { _mcl_oxidized_variant = def_variant_oxidized }) + + def_variant_waxed = "mcl_stairs:stair_waxed_copper_" .. stair_oxidization[i][1] + minetest.override_item(def, { _mcl_waxed_variant = def_variant_waxed }) + + -- slabs + def = "mcl_stairs:slab_copper_" .. slab_oxidization[i][1] + def_variant_oxidized = "mcl_stairs:slab_copper_" .. slab_oxidization[i][2] + minetest.override_item(def, { _mcl_oxidized_variant = def_variant_oxidized }) + + def_variant_waxed = "mcl_stairs:slab_waxed_copper_" .. slab_oxidization[i][1] + minetest.override_item(def, { _mcl_waxed_variant = def_variant_waxed }) +end + +-- Set up scraped variants. +for i = 1, #stair_oxidization do + -- does both stairs and slabs. + if i > 3 then + def = "mcl_stairs:stair_copper_" .. stair_oxidization[i][1] + def_variant_scraped = "mcl_stairs:stair_copper_" .. stair_oxidization[i - 3][1] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:slab_copper_" .. slab_oxidization[i][1] + def_variant_scraped = "mcl_stairs:slab_copper_" .. slab_oxidization[i - 3][1] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + end + if i > 6 then + def = "mcl_stairs:stair_copper_" .. stair_oxidization[i][2] + def_variant_scraped = "mcl_stairs:stair_copper_" .. stair_oxidization[i][1] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:slab_copper_" .. slab_oxidization[i][2] + def_variant_scraped = "mcl_stairs:slab_copper_" .. slab_oxidization[i][1] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + end +end + +-- Set up scraped variants for waxed stairs. +local waxed_variants = { + { "waxed_copper_cut", "copper_cut" }, + { "waxed_copper_exposed_cut", "copper_exposed_cut" }, + { "waxed_copper_weathered_cut", "copper_weathered_cut" }, + { "waxed_copper_oxidized_cut", "copper_oxidized_cut" }, +} + +for i = 1, #waxed_variants do + -- stairs + def = "mcl_stairs:stair_" .. waxed_variants[i][1] + def_variant_scraped = "mcl_stairs:stair_" .. waxed_variants[i][2] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:stair_" .. waxed_variants[i][1] .. "_inner" + def_variant_scraped = "mcl_stairs:stair_" .. waxed_variants[i][2] .. "_inner" + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:stair_" .. waxed_variants[i][1] .. "_outer" + def_variant_scraped = "mcl_stairs:stair_" .. waxed_variants[i][2] .. "_outer" + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + -- slab + def = "mcl_stairs:slab_" .. waxed_variants[i][1] + def_variant_scraped = "mcl_stairs:slab_" .. waxed_variants[i][2] + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:slab_" .. waxed_variants[i][1] .. "_top" + def_variant_scraped = "mcl_stairs:slab_" .. waxed_variants[i][2] .. "_top" + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + + def = "mcl_stairs:slab_" .. waxed_variants[i][1] .. "_double" + def_variant_scraped = "mcl_stairs:slab_" .. waxed_variants[i][2] .. "_double" + minetest.override_item(def, { _mcl_stripped_variant = def_variant_scraped }) + +end + +-- Waxed Oxidized Slabs and Stairs +local oxidized_slabs = { + "oxidized_cut", + "oxidized_cut_double", + "oxidized_cut_top" +} + +for i = 1, #oxidized_slabs do + def = "mcl_stairs:slab_copper_" .. oxidized_slabs[i] + def_variant_waxed = "mcl_stairs:slab_waxed_copper_" .. oxidized_slabs[i] + minetest.override_item(def, { _mcl_waxed_variant = def_variant_waxed }) +end + +local oxidized_stairs = { + "oxidized_cut", + "oxidized_cut_inner", + "oxidized_cut_outer" +} + +for i = 1, #oxidized_stairs do + def = "mcl_stairs:stair_copper_" .. oxidized_stairs[i] + def_variant_waxed = "mcl_stairs:stair_waxed_copper_" .. oxidized_stairs[i] + minetest.override_item(def, { _mcl_waxed_variant = def_variant_waxed }) +end diff --git a/mods/ITEMS/mcl_copper/init.lua b/mods/ITEMS/mcl_copper/init.lua new file mode 100644 index 000000000..01ece6d54 --- /dev/null +++ b/mods/ITEMS/mcl_copper/init.lua @@ -0,0 +1,8 @@ +local path = minetest.get_modpath("mcl_copper") + +mcl_copper = {} -- initialize global variable. + +dofile(path .. "/nodes.lua") +dofile(path .. "/items.lua") +dofile(path .. "/crafting.lua") +dofile(path .. "/functions.lua") diff --git a/mods/ITEMS/mcl_copper/items.lua b/mods/ITEMS/mcl_copper/items.lua new file mode 100644 index 000000000..694e693dc --- /dev/null +++ b/mods/ITEMS/mcl_copper/items.lua @@ -0,0 +1,15 @@ +local S = minetest.get_translator("mcl_copper") + +minetest.register_craftitem("mcl_copper:copper_ingot", { + description = S("Copper Ingot"), + _doc_items_longdesc = S("Molten Raw Copper. It is used to craft blocks."), + inventory_image = "mcl_copper_ingot.png", + groups = { craftitem = 1 }, +}) + +minetest.register_craftitem("mcl_copper:raw_copper", { + description = S("Raw Copper"), + _doc_items_longdesc = S("Raw Copper. Mine a Copper Ore to get it."), + inventory_image = "mcl_copper_raw.png", + groups = { craftitem = 1, blast_furnace_smeltable = 1 }, +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.de.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.de.tr new file mode 100644 index 000000000..cc2290e1e --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.de.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=Ein Kupferblock wird meistens als dekorativer Block verwendet. +A block used for compact raw copper storage.=Ein Block für die kompakte Lagerung von Rohkupfer. +Block of Copper=Kupferblock +Block of Raw Copper=Rohkupferblock +Copper Ingot=Kupfer Barren +Copper Ore=Kupfererz +Cut copper is a decorative block.=Ein Geschnittener Kupferblock ist ein dekorativer Block. +Cut Copper=Geschnittener Kupferblock +Double Slab of Cut Copper=Doppelte Geschnittene Kupferstufe +Double Slab of Exposed Cut Copper=Doppelte Angelaufene Geschnittene Kupferstufe +Double Slab of Oxidized Cut Copper=Doppelte Oxidierte Geschnittene Kupferstufe +Double Slab of Weathered Cut Copper=Doppelte Verwitterte Geschnittene Kupferstufe +Exposed copper is a decorative block.=Ein Angelaufener Kupferblock ist ein dekorativer Block. +Exposed Copper=Angelaufener Kupferblock +Exposed cut copper is a decorative block.=Ein Angelaufener geschnittener Kupferblock ist ein dekorativer Block. +Exposed Cut Copper=Angelaufener geschnittener Kupferblock +Molten Raw Copper. It is used to craft blocks.=Geschmolzenes Rohkupfer. Es wird verwendet, um Blöcke herzustellen. +Oxidized copper is a decorative block.=Ein Oxidierter Kupferblockist ist ein dekorativer Block. +Oxidized Copper=Oxidierter Kupferblock +Oxidized cut copper is a decorative block.=Ein Oxidierter geschnittener Kupferblock ist ein dekorativer Block. +Oxidized Cut Copper=Oxidierter geschnittener Kupferblock +Raw Copper. Mine a Copper Ore to get it.=Bauen sie ein Kupfererz ab, um es zu erhalten. +Raw Copper=Rohkupfer +Slab of Cut Copper=Geschnittene Kupferstufe +Slab of Exposed Cut Copper=Angelaufene Geschnittene Kupferstufe +Slab of Oxidized Cut Copper=Oxidierte Geschnittene Kupferstufe +Slab of Weathered Cut Copper=Verwitterte Geschnittene Kupferstufe +Some copper contained in stone, it is pretty common and can be found below sea level.=Stein, in dem etwas Kupfer enthalten ist. Es ist ziemlich häufig und kann unter dem Meeresspiegel gefunden werden. +Stairs of Cut Copper=Geschnittene Kupfertreppe +Stairs of Exposed Cut Copper=Angelaufene Geschnittene Kupfertreppe +Stairs of Oxidized Cut Copper=Oxidierte Geschnittene Kupfertreppe +Stairs of Weathered Cut Copper=Verwitterte Geschnittene Kupfertreppe +Weathered copper is a decorative block.=Ein Verwitterter Kupferblock ist ein dekorativer Block. +Weathered Copper=Verwitterter Kupferblock +Weathered cut copper is a decorative block.=Ein Verwitterter geschnittener Kupferblock ist ein dekorativer Block. +Weathered Cut Copper=Verwitterter geschnittener Kupferblock diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr new file mode 100644 index 000000000..a2fb94c36 --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.fr.tr @@ -0,0 +1,57 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=Le bloc de cuivre est surtout un bloc décoratif. +A block used for compact raw copper storage.=Un bloc utilisé pour le stockage compact de cuivre brut. +Block of Copper=Bloc de cuivre +Waxed Block of Copper=Bloc de cuivre ciré +Block of Raw Copper=Bloc de cuivre brut +Copper Ingot=Lingot de cuivre +Copper Ore=Minerai de cuivre +Cut copper is a decorative block.=Le cuivre taillé est un bloc décoratif. +Cut Copper=Cuivre taillé +Waxed Cut Copper=Cuivre taillé ciré +Double Slab of Cut Copper=Double dalle de cuivre taillé +Double Slab of Exposed Cut Copper=Double dalle de cuivre taillé exposé +Double Slab of Oxidized Cut Copper=Double dalle de cuivre taillé oxydé +Double Slab of Weathered Cut Copper=Double dalle de cuivre taillé érodé +Waxed Double Slab of Cut Copper=Double dalle de cuivre taillé ciré +Waxed Double Slab of Exposed Cut Copper=Double dalle de cuivre taillé exposé ciré +Waxed Double Slab of Oxidized Cut Copper=Double dalle de cuivre taillé oxydé ciré +Waxed Double Slab of Weathered Cut Copper=Double dalle de cuivre taillé érodé ciré +Exposed copper is a decorative block.=Le cuivre exposé est un bloc décoratif. +Exposed Copper=Cuivre exposé +Waxed Exposed Copper=Cuivre exposé ciré +Exposed cut copper is a decorative block.=Le cuivre taillé exposé est un bloc décoratif. +Exposed Cut Copper=Cuivre taillé exposé +Waxed Exposed Cut Copper=Cuivre taillé exposé ciré +Molten Raw Copper. It is used to craft blocks.=Cuivre brut fondu. Utilisé pour fabriquer des blocs. +Oxidized copper is a decorative block.=Le cuivre oxydé est un bloc décoratif. +Oxidized Copper=Cuivre oxydé +Waxed Oxidized Copper=Cuivre oxydé ciré +Oxidized cut copper is a decorative block.=Le cuivre taillé oxydé est un bloc décoratif. +Oxidized Cut Copper=Cuivre taillé oxydé +Waxed Oxidized Cut Copper=Cuivre taillé oxydé ciré +Raw Copper. Mine a Copper Ore to get it.=Cuivre brut. Creuser dans du minerai de cuivre pour l'obtenir. +Raw Copper=Cuivre brut +Slab of Cut Copper=Dalle de cuivre taillé +Slab of Exposed Cut Copper=Dalle de cuivre taillé exposé +Slab of Oxidized Cut Copper=Dalle de cuivre taillé oxydé +Slab of Weathered Cut Copper=Dalle de cuivre taillé érodé +Waxed Slab of Cut Copper=Dalle de cuivre taillé ciré +Waxed Slab of Exposed Cut Copper=Dalle de cuivre taillé exposé ciré +Waxed Slab of Oxidized Cut Copper=Dalle de cuivre taillé oxydé ciré +Waxed Slab of Weathered Cut Copper=Dalle de cuivre taillé érodé ciré +Some copper contained in stone, it is pretty common and can be found below sea level.=Un peu de cuivre se trouve dans la pierre, il est plutôt répandu et peut être trouvé sous le niveau de la mer. +Stairs of Cut Copper=Escalier de cuivre taillé +Stairs of Exposed Cut Copper=Escalier de cuivre taillé exposé +Stairs of Oxidized Cut Copper=Escalier de cuivre taillé oxydé +Stairs of Weathered Cut Copper=Escalier de cuivre taillé érodé +Waxed Stairs of Cut Copper=Escalier de cuivre taillé ciré +Waxed Stairs of Exposed Cut Copper=Escalier de cuivre taillé exposé ciré +Waxed Stairs of Oxidized Cut Copper=Escalier de cuivre taillé oxydé ciré +Waxed Stairs of Weathered Cut Copper=Escalier de cuivre taillé érodé ciré +Weathered copper is a decorative block.=Le cuivre érodé est un bloc décoratif. +Weathered Copper=Cuivre érodé +Waxed Weathered Copper=Cuivre érodé ciré +Weathered cut copper is a decorative block.=Le cuivre taillé érodé est un bloc décoratif. +Weathered Cut Copper=Cuivre taillé érodé +Waxed Weathered Cut Copper=Cuivre taillé érodé ciré diff --git a/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.tr new file mode 100644 index 000000000..f6f204e78 --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.ja.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=溝入り銅の2重スラブ +Double Slab of Exposed Cut Copper=少し酸化した溝入り銅の2重スラブ +Double Slab of Oxidized Cut Copper=殆ど酸化した溝入り銅の2重スラブ +Double Slab of Weathered Cut Copper=半ば酸化した溝入り銅の2重スラブ +Waxed Double Slab of Cut Copper=錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Exposed Cut Copper=少し酸化した錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Oxidized Cut Copper=殆ど酸化した錆止め済み溝入り銅の2重スラブ +Waxed Double Slab of Weathered Cut Copper=半ば酸化した錆止め済み溝入り銅の2重スラブ +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/locale/mcl_copper.pt_BR.tr b/mods/ITEMS/mcl_copper/locale/mcl_copper.pt_BR.tr new file mode 100644 index 000000000..18aeb1304 --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/mcl_copper.pt_BR.tr @@ -0,0 +1,57 @@ +# textdomain: mcl_copper +A block of copper is mostly a decorative block.=Um bloco de cobre é principalmente um bloco decorativo. +A block used for compact raw copper storage.=Um bloco usado para armazenar minério de cobre compactado. +Block of Copper=Bloco de Cobre +Waxed Block of Copper=Bloco de Cobre Encerado +Block of Raw Copper=Bloco de Cobre Crú +Copper Ingot=Lingote de Cobre +Copper Ore=Minério de Cobre +Cut copper is a decorative block.=Cobre lapidado é um bloco decorativo +Cut Copper=Cobre Lapidado +Waxed Cut Copper=Cobre Lapidado Encerado +Double Slab of Cut Copper=Laje Dupla de Cobre Lapidado +Double Slab of Exposed Cut Copper=Laje Dupla de Cobre Lapidado Exposto +Double Slab of Oxidized Cut Copper=Laje Dupla de Cobre Lapidado Oxidado +Double Slab of Weathered Cut Copper=Laje Dupla de Cobre Lapidado Desgastado +Waxed Double Slab of Cut Copper=Laje Dupla de Cobre Lapidado Encerado +Waxed Double Slab of Exposed Cut Copper=Laje Dupla de Cobre Lapidado Exposto Encerado +Waxed Double Slab of Oxidized Cut Copper=Laje Dupla de Cobre Lapidado Oxidado Encerado +Waxed Double Slab of Weathered Cut Copper=Laje Dupla de Cobre Lapidado Desgastado Encerado +Exposed copper is a decorative block.=Cobre exposto é um bloco decorativo. +Exposed Copper=Cobre Exposto +Waxed Exposed Copper=Cobre Exposto Encerado +Exposed cut copper is a decorative block.=Cobre lapidado encerado é um bloco decorativo. +Exposed Cut Copper=Cobre Lapidado Exposto +Waxed Exposed Cut Copper=Cobre Lapidado Exposto Encerado +Molten Raw Copper. It is used to craft blocks.=Minério de Cobre Fundido. É utilizado para fabricar blocos. +Oxidized copper is a decorative block.=Cobre oxidado é um bloco decorativo. +Oxidized Copper=Cobre Oxidado +Waxed Oxidized Copper=Cobre Oxidado Encerado +Oxidized cut copper is a decorative block.=Cobre lapidado oxidado é um bloco decorativo. +Oxidized Cut Copper=Cobre Lapidado Oxidado +Waxed Oxidized Cut Copper=Cobre Lapidado Oxidado Encerado +Raw Copper. Mine a Copper Ore to get it.=Cobre Crú. Minere um minério de cobre para obtê-lo. +Raw Copper=Cobre Crú +Slab of Cut Copper=Laje de Cobre Lapidado +Slab of Exposed Cut Copper=Laje de Cobre Lapidado Exposto +Slab of Oxidized Cut Copper=Laje de Cobre Lapidado Oxidado +Slab of Weathered Cut Copper=Laje de Cobre Lapidado Desgastado +Waxed Slab of Cut Copper=Laje de Cobre Lapidado Encerado +Waxed Slab of Exposed Cut Copper=Laje de Cobre Lapidado Exposto Encerado +Waxed Slab of Oxidized Cut Copper=Laje de Cobre Lapidado Oxidado Encerado +Waxed Slab of Weathered Cut Copper=Laje de Cobre Lapidado Desgastado Encerado +Some copper contained in stone, it is pretty common and can be found below sea level.=Um pouco de cobre contido em rocha, é bem comum e pode ser encontrado abaixo do nível do mar. +Stairs of Cut Copper=Escadas de Cobre Lapidado +Stairs of Exposed Cut Copper=Escadas de Cobre Lapidado Exposto +Stairs of Oxidized Cut Copper=Escadas de Cobre Lapidado Oxidado +Stairs of Weathered Cut Copper=Escadas de Cobre Lapidado Desgastado +Waxed Stairs of Cut Copper=Escadas de Cobre Lapidado Encerado +Waxed Stairs of Exposed Cut Copper=Escadas de Cobre Lapidado Exposto Encerado +Waxed Stairs of Oxidized Cut Copper=Escadas de Cobre Lapidado Oxidado Encerado +Waxed Stairs of Weathered Cut Copper=Escadas de Cobre Lapidado Desgastado Encerado +Weathered copper is a decorative block.=Cobre desgastado é um bloco decorativo. +Weathered Copper=Cobre Desgastado +Waxed Weathered Copper=Cobre Desgastado Encerado +Weathered cut copper is a decorative block.=Cobre lapidado desgastado é um bloco decorativo. +Weathered Cut Copper=Cobre Lapidado Desgastado +Waxed Weathered Cut Copper=Cobre Lapidado Desgastado Encerado diff --git a/mods/ITEMS/mcl_copper/locale/template.txt b/mods/ITEMS/mcl_copper/locale/template.txt new file mode 100644 index 000000000..7022780ff --- /dev/null +++ b/mods/ITEMS/mcl_copper/locale/template.txt @@ -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 new file mode 100644 index 000000000..a48ee56f7 --- /dev/null +++ b/mods/ITEMS/mcl_copper/mod.conf @@ -0,0 +1,4 @@ +name = mcl_copper +author = NO11 +depends = mcl_core, mcl_sounds, mcl_stairs, mcl_util, mcl_oxidation +description = Adds Copper Ore, blocks and items. diff --git a/mods/ITEMS/mcl_copper/nodes.lua b/mods/ITEMS/mcl_copper/nodes.lua new file mode 100644 index 000000000..af5a49a1c --- /dev/null +++ b/mods/ITEMS/mcl_copper/nodes.lua @@ -0,0 +1,342 @@ +local S = minetest.get_translator("mcl_copper") + +minetest.register_node("mcl_copper:stone_with_copper", { + description = S("Copper Ore"), + _doc_items_longdesc = S("Some copper contained in stone, it is pretty common and can be found below sea level."), + tiles = {"default_stone.png^mcl_copper_ore.png"}, + is_ground_content = true, + groups = {pickaxey = 3, building_block = 1, material_stone = 1, blast_furnace_smeltable=1}, + drop = "mcl_copper:raw_copper", + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, +}) + +minetest.register_node("mcl_copper:block_raw", { + description = S("Block of Raw Copper"), + _doc_items_longdesc = S("A block used for compact raw copper storage."), + tiles = {"mcl_copper_block_raw.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, blast_furnace_smeltable = 1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, +}) + +minetest.register_node("mcl_copper:block", { + description = S("Block of Copper"), + _doc_items_longdesc = S("A block of copper is mostly a decorative block."), + tiles = {"mcl_copper_block.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 3, + _mcl_oxidized_variant = "mcl_copper:block_exposed", + _mcl_waxed_variant = "mcl_copper:waxed_block", +}) + +minetest.register_node("mcl_copper:waxed_block", { + description = S("Waxed Block of Copper"), + _doc_items_longdesc = S("A block of copper is mostly a decorative block."), + tiles = {"mcl_copper_block.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 3, + _mcl_stripped_variant = "mcl_copper:block", +}) + +minetest.register_node("mcl_copper:block_exposed", { + description = S("Exposed Copper"), + _doc_items_longdesc = S("Exposed copper is a decorative block."), + tiles = {"mcl_copper_exposed.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_oxidized_variant = "mcl_copper:block_weathered", + _mcl_waxed_variant = "mcl_copper:waxed_block_exposed", + _mcl_stripped_variant = "mcl_copper:block", +}) + +minetest.register_node("mcl_copper:waxed_block_exposed", { + description = S("Waxed Exposed Copper"), + _doc_items_longdesc = S("Exposed copper is a decorative block."), + tiles = {"mcl_copper_exposed.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_exposed", +}) + +minetest.register_node("mcl_copper:block_weathered", { + description = S("Weathered Copper"), + _doc_items_longdesc = S("Weathered copper is a decorative block."), + tiles = {"mcl_copper_weathered.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_oxidized_variant = "mcl_copper:block_oxidized", + _mcl_waxed_variant = "mcl_copper:waxed_block_weathered", + _mcl_stripped_variant = "mcl_copper:block_exposed", +}) + +minetest.register_node("mcl_copper:waxed_block_weathered", { + description = S("Waxed Weathered Copper"), + _doc_items_longdesc = S("Weathered copper is a decorative block."), + tiles = {"mcl_copper_weathered.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_weathered", +}) + +minetest.register_node("mcl_copper:block_oxidized", { + description = S("Oxidized Copper"), + _doc_items_longdesc = S("Oxidized copper is a decorative block."), + tiles = {"mcl_copper_oxidized.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_waxed_variant = "mcl_copper:waxed_block_oxidized", + _mcl_stripped_variant = "mcl_copper:block_weathered", +}) + +minetest.register_node("mcl_copper:waxed_block_oxidized", { + description = S("Waxed Oxidized Copper"), + _doc_items_longdesc = S("Oxidized copper is a decorative block."), + tiles = {"mcl_copper_oxidized.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_oxidized", +}) + +minetest.register_node("mcl_copper:block_cut", { + description = S("Cut Copper"), + _doc_items_longdesc = S("Cut copper is a decorative block."), + tiles = {"mcl_copper_block_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_oxidized_variant = "mcl_copper:block_exposed_cut", + _mcl_waxed_variant = "mcl_copper:waxed_block_cut", +}) + +minetest.register_node("mcl_copper:waxed_block_cut", { + description = S("Waxed Cut Copper"), + _doc_items_longdesc = S("Cut copper is a decorative block."), + tiles = {"mcl_copper_block_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_cut", +}) + +minetest.register_node("mcl_copper:block_exposed_cut", { + description = S("Exposed Cut Copper"), + _doc_items_longdesc = S("Exposed cut copper is a decorative block."), + tiles = {"mcl_copper_exposed_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_waxed_variant = "mcl_copper:waxed_block_exposed_cut", + _mcl_oxidized_variant = "mcl_copper:block_weathered_cut", + _mcl_stripped_variant = "mcl_copper:block_cut", +}) + +minetest.register_node("mcl_copper:waxed_block_exposed_cut", { + description = S("Waxed Exposed Cut Copper"), + _doc_items_longdesc = S("Exposed cut copper is a decorative block."), + tiles = {"mcl_copper_exposed_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_exposed_cut", +}) + +minetest.register_node("mcl_copper:block_weathered_cut", { + description = S("Weathered Cut Copper"), + _doc_items_longdesc = S("Weathered cut copper is a decorative block."), + tiles = {"mcl_copper_weathered_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, oxidizable = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_exposed_cut", + _mcl_oxidized_variant = "mcl_copper:block_oxidized_cut", + _mcl_waxed_variant = "mcl_copper:waxed_block_weathered_cut", +}) + +minetest.register_node("mcl_copper:waxed_block_weathered_cut", { + description = S("Waxed Weathered Cut Copper"), + _doc_items_longdesc = S("Weathered cut copper is a decorative block."), + tiles = {"mcl_copper_weathered_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_weathered_cut", +}) + +minetest.register_node("mcl_copper:block_oxidized_cut", { + description = S("Oxidized Cut Copper"), + _doc_items_longdesc = S("Oxidized cut copper is a decorative block."), + tiles = {"mcl_copper_oxidized_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_weathered_cut", + _mcl_waxed_variant = "mcl_copper:waxed_block_oxidized_cut", +}) + +minetest.register_node("mcl_copper:waxed_block_oxidized_cut", { + description = S("Waxed Oxidized Cut Copper"), + _doc_items_longdesc = S("Oxidized cut copper is a decorative block."), + tiles = {"mcl_copper_oxidized_cut.png"}, + is_ground_content = false, + groups = {pickaxey = 2, building_block = 1, waxed = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + _mcl_stripped_variant = "mcl_copper:block_oxidized_cut", +}) + +mcl_stairs.register_slab("copper_cut", "mcl_copper:block_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Slab of Cut Copper"), + nil, nil, nil, + S("Double Slab of Cut Copper")) + +mcl_stairs.register_slab("waxed_copper_cut", "mcl_copper:waxed_block_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Waxed Slab of Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Cut Copper")) + +mcl_stairs.register_slab("copper_exposed_cut", "mcl_copper:block_exposed_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Slab of Exposed Cut Copper"), + nil, nil, nil, + S("Double Slab of Exposed Cut Copper")) + +mcl_stairs.register_slab("waxed_copper_exposed_cut", "mcl_copper:waxed_block_exposed_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Waxed Slab of Exposed Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Exposed Cut Copper")) + +mcl_stairs.register_slab("copper_weathered_cut", "mcl_copper:block_weathered_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Slab of Weathered Cut Copper"), + nil, nil, nil, + S("Double Slab of Weathered Cut Copper")) + +mcl_stairs.register_slab("waxed_copper_weathered_cut", "mcl_copper:waxed_block_weathered_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Waxed Slab of Weathered Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Weathered Cut Copper")) + +mcl_stairs.register_slab("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Slab of Oxidized Cut Copper"), + nil, nil, nil, + S("Double Slab of Oxidized Cut Copper")) + +mcl_stairs.register_slab("waxed_copper_oxidized_cut", "mcl_copper:waxed_block_oxidized_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Waxed Slab of Oxidized Cut Copper"), + nil, nil, nil, + S("Waxed Double Slab of Oxidized Cut Copper")) + +mcl_stairs.register_stair("copper_cut", "mcl_copper:block_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Stairs of Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("waxed_copper_cut", "mcl_copper:waxed_block_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png", "mcl_copper_block_cut.png"}, + S("Waxed Stairs of Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("copper_exposed_cut", "mcl_copper:block_exposed_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Stairs of Exposed Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("waxed_copper_exposed_cut", "mcl_copper:waxed_block_exposed_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png", "mcl_copper_exposed_cut.png"}, + S("Waxed Stairs of Exposed Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("copper_weathered_cut", "mcl_copper:block_weathered_cut", + {pickaxey = 2, oxidizable = 1}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Stairs of Weathered Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("waxed_copper_weathered_cut", "mcl_copper:waxed_block_weathered_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png", "mcl_copper_weathered_cut.png"}, + S("Waxed Stairs of Weathered Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("copper_oxidized_cut", "mcl_copper:block_oxidized_cut", + {pickaxey = 2}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Stairs of Oxidized Cut Copper"), + nil, 6, nil, + "woodlike") + +mcl_stairs.register_stair("waxed_copper_oxidized_cut", "mcl_copper:waxed_block_oxidized_cut", + {pickaxey = 2, waxed = 1}, + {"mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png", "mcl_copper_oxidized_cut.png"}, + S("Waxed Stairs of Oxidized Cut Copper"), + nil, 6, nil, + "woodlike") diff --git a/mods/ITEMS/mcl_core/crafting.lua b/mods/ITEMS/mcl_core/crafting.lua index a0ad38a77..ffba04a7b 100644 --- a/mods/ITEMS/mcl_core/crafting.lua +++ b/mods/ITEMS/mcl_core/crafting.lua @@ -4,213 +4,196 @@ -- Crafting definition -- +local function craft_planks(output, input) + minetest.register_craft({ + output = "mcl_core:"..output.."wood 4", + recipe = { + {"mcl_core:"..input}, + } + }) +end + +local planks = { + {"", "oak"}, + {"dark", "dark_oak"}, + {"jungle", "jungle"}, + {"acacia", "acacia"}, + {"spruce", "spruce"}, + {"birch", "birch"} +} + +for _, p in pairs(planks) do + craft_planks(p[1], p[1].."tree") + craft_planks(p[1], p[1].."tree_bark") + craft_planks(p[1], "stripped_"..p[2]) + craft_planks(p[1], "stripped_"..p[2].."_bark") +end + minetest.register_craft({ - output = 'mcl_core:wood 4', + type = "shapeless", + output = "mcl_core:mossycobble", + recipe = { "mcl_core:cobble", "mcl_core:vine" }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_core:stonebrickmossy", + recipe = { "mcl_core:stonebrick", "mcl_core:vine" }, +}) + +minetest.register_craft({ + output = "mcl_core:coarse_dirt 4", recipe = { - {'mcl_core:tree'}, + {"mcl_core:dirt", "mcl_core:gravel"}, + {"mcl_core:gravel", "mcl_core:dirt"}, + } +}) +minetest.register_craft({ + output = "mcl_core:coarse_dirt 4", + recipe = { + {"mcl_core:gravel", "mcl_core:dirt"}, + {"mcl_core:dirt", "mcl_core:gravel"}, } }) minetest.register_craft({ - output = 'mcl_core:darkwood 4', + output = "mcl_core:sandstonesmooth 4", recipe = { - {'mcl_core:darktree'}, + {"mcl_core:sandstone","mcl_core:sandstone"}, + {"mcl_core:sandstone","mcl_core:sandstone"}, } }) minetest.register_craft({ - output = 'mcl_core:junglewood 4', + output = "mcl_core:redsandstonesmooth 4", recipe = { - {'mcl_core:jungletree'}, + {"mcl_core:redsandstone","mcl_core:redsandstone"}, + {"mcl_core:redsandstone","mcl_core:redsandstone"}, } }) minetest.register_craft({ - output = 'mcl_core:acaciawood 4', + output = "mcl_core:granite_smooth 4", recipe = { - {'mcl_core:acaciatree'}, - } -}) - -minetest.register_craft({ - output = 'mcl_core:sprucewood 4', - recipe = { - {'mcl_core:sprucetree'}, - } -}) - -minetest.register_craft({ - output = 'mcl_core:birchwood 4', - recipe = { - {'mcl_core:birchtree'}, - } -}) - -minetest.register_craft({ - type = 'shapeless', - output = 'mcl_core:mossycobble', - recipe = { 'mcl_core:cobble', 'mcl_core:vine' }, -}) - -minetest.register_craft({ - type = 'shapeless', - output = 'mcl_core:stonebrickmossy', - recipe = { 'mcl_core:stonebrick', 'mcl_core:vine' }, -}) - -minetest.register_craft({ - output = 'mcl_core:coarse_dirt 4', - recipe = { - {'mcl_core:dirt', 'mcl_core:gravel'}, - {'mcl_core:gravel', 'mcl_core:dirt'}, - } -}) -minetest.register_craft({ - output = 'mcl_core:coarse_dirt 4', - recipe = { - {'mcl_core:gravel', 'mcl_core:dirt'}, - {'mcl_core:dirt', 'mcl_core:gravel'}, - } -}) - -minetest.register_craft({ - output = 'mcl_core:sandstonesmooth 4', - recipe = { - {'mcl_core:sandstone','mcl_core:sandstone'}, - {'mcl_core:sandstone','mcl_core:sandstone'}, - } -}) - -minetest.register_craft({ - output = 'mcl_core:redsandstonesmooth 4', - recipe = { - {'mcl_core:redsandstone','mcl_core:redsandstone'}, - {'mcl_core:redsandstone','mcl_core:redsandstone'}, - } -}) - -minetest.register_craft({ - output = 'mcl_core:granite_smooth 4', - recipe = { - {'mcl_core:granite', 'mcl_core:granite'}, - {'mcl_core:granite', 'mcl_core:granite'} + {"mcl_core:granite", "mcl_core:granite"}, + {"mcl_core:granite", "mcl_core:granite"} }, }) minetest.register_craft({ - output = 'mcl_core:andesite_smooth 4', + output = "mcl_core:andesite_smooth 4", recipe = { - {'mcl_core:andesite', 'mcl_core:andesite'}, - {'mcl_core:andesite', 'mcl_core:andesite'} + {"mcl_core:andesite", "mcl_core:andesite"}, + {"mcl_core:andesite", "mcl_core:andesite"} }, }) minetest.register_craft({ - output = 'mcl_core:diorite_smooth 4', + output = "mcl_core:diorite_smooth 4", recipe = { - {'mcl_core:diorite', 'mcl_core:diorite'}, - {'mcl_core:diorite', 'mcl_core:diorite'} + {"mcl_core:diorite", "mcl_core:diorite"}, + {"mcl_core:diorite", "mcl_core:diorite"} }, }) minetest.register_craft({ type = "shapeless", - output = 'mcl_core:granite', - recipe = {'mcl_core:diorite', 'mcl_nether:quartz'}, + output = "mcl_core:granite", + recipe = {"mcl_core:diorite", "mcl_nether:quartz"}, }) minetest.register_craft({ type = "shapeless", - output = 'mcl_core:andesite 2', - recipe = {'mcl_core:diorite', 'mcl_core:cobble'}, + output = "mcl_core:andesite 2", + recipe = {"mcl_core:diorite", "mcl_core:cobble"}, }) minetest.register_craft({ - output = 'mcl_core:diorite 2', + output = "mcl_core:diorite 2", recipe = { - {'mcl_core:cobble', 'mcl_nether:quartz'}, - {'mcl_nether:quartz', 'mcl_core:cobble'}, + {"mcl_core:cobble", "mcl_nether:quartz"}, + {"mcl_nether:quartz", "mcl_core:cobble"}, } }) minetest.register_craft({ - output = 'mcl_core:diorite 2', + output = "mcl_core:diorite 2", recipe = { - {'mcl_nether:quartz', 'mcl_core:cobble'}, - {'mcl_core:cobble', 'mcl_nether:quartz'}, + {"mcl_nether:quartz", "mcl_core:cobble"}, + {"mcl_core:cobble", "mcl_nether:quartz"}, } }) minetest.register_craft({ output = "mcl_core:bone_block", recipe = { - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, - { "mcl_dye:white", "mcl_dye:white", "mcl_dye:white" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, + { "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal", "mcl_bone_meal:bone_meal" }, }, }) minetest.register_craft({ - output = "mcl_dye:white 9", + output = "mcl_bone_meal:bone_meal 9", recipe = { { "mcl_core:bone_block" }, }, }) minetest.register_craft({ - output = 'mcl_core:stick 4', + output = "mcl_core:stick 4", recipe = { - {'group:wood'}, - {'group:wood'}, + {"group:wood"}, + {"group:wood"}, } }) minetest.register_craft({ - output = 'mcl_core:coalblock', + output = "mcl_core:coalblock", recipe = { - {'mcl_core:coal_lump', 'mcl_core:coal_lump', 'mcl_core:coal_lump'}, - {'mcl_core:coal_lump', 'mcl_core:coal_lump', 'mcl_core:coal_lump'}, - {'mcl_core:coal_lump', 'mcl_core:coal_lump', 'mcl_core:coal_lump'}, + {"mcl_core:coal_lump", "mcl_core:coal_lump", "mcl_core:coal_lump"}, + {"mcl_core:coal_lump", "mcl_core:coal_lump", "mcl_core:coal_lump"}, + {"mcl_core:coal_lump", "mcl_core:coal_lump", "mcl_core:coal_lump"}, } }) minetest.register_craft({ - output = 'mcl_core:coal_lump 9', + output = "mcl_core:coal_lump 9", recipe = { - {'mcl_core:coalblock'}, + {"mcl_core:coalblock"}, } }) minetest.register_craft({ - output = 'mcl_core:ironblock', + output = "mcl_core:ironblock", recipe = { - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, } }) minetest.register_craft({ - output = 'mcl_core:iron_ingot 9', + output = "mcl_core:iron_ingot 9", recipe = { - {'mcl_core:ironblock'}, + {"mcl_core:ironblock"}, } }) minetest.register_craft({ - output = 'mcl_core:goldblock', + output = "mcl_core:goldblock", recipe = { - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, } }) minetest.register_craft({ - output = 'mcl_core:gold_ingot 9', + output = "mcl_core:gold_ingot 9", recipe = { - {'mcl_core:goldblock'}, + {"mcl_core:goldblock"}, } }) @@ -244,119 +227,119 @@ minetest.register_craft({ minetest.register_craft({ type = "cooking", - output = 'mcl_core:iron_nugget', - recipe = 'mobs_mc:iron_horse_armor', + output = "mcl_core:iron_nugget", + recipe = "mcl_mobitems:iron_horse_armor", cooktime = 10, }) minetest.register_craft({ type = "cooking", - output = 'mcl_core:gold_nugget', - recipe = 'mobs_mc:gold_horse_armor', + output = "mcl_core:gold_nugget", + recipe = "mcl_mobitems:gold_horse_armor", cooktime = 10, }) minetest.register_craft({ - output = 'mcl_core:sandstone', + output = "mcl_core:sandstone", recipe = { - {'mcl_core:sand', 'mcl_core:sand'}, - {'mcl_core:sand', 'mcl_core:sand'}, + {"mcl_core:sand", "mcl_core:sand"}, + {"mcl_core:sand", "mcl_core:sand"}, } }) minetest.register_craft({ - output = 'mcl_core:redsandstone', + output = "mcl_core:redsandstone", recipe = { - {'mcl_core:redsand', 'mcl_core:redsand'}, - {'mcl_core:redsand', 'mcl_core:redsand'}, + {"mcl_core:redsand", "mcl_core:redsand"}, + {"mcl_core:redsand", "mcl_core:redsand"}, } }) minetest.register_craft({ - output = 'mcl_core:clay', + output = "mcl_core:clay", recipe = { - {'mcl_core:clay_lump', 'mcl_core:clay_lump'}, - {'mcl_core:clay_lump', 'mcl_core:clay_lump'}, + {"mcl_core:clay_lump", "mcl_core:clay_lump"}, + {"mcl_core:clay_lump", "mcl_core:clay_lump"}, } }) minetest.register_craft({ - output = 'mcl_core:brick_block', + output = "mcl_core:brick_block", recipe = { - {'mcl_core:brick', 'mcl_core:brick'}, - {'mcl_core:brick', 'mcl_core:brick'}, + {"mcl_core:brick", "mcl_core:brick"}, + {"mcl_core:brick", "mcl_core:brick"}, } }) minetest.register_craft({ - output = 'mcl_core:paper 3', + output = "mcl_core:paper 3", recipe = { - {'mcl_core:reeds', 'mcl_core:reeds', 'mcl_core:reeds'}, + {"mcl_core:reeds", "mcl_core:reeds", "mcl_core:reeds"}, } }) minetest.register_craft({ - output = 'mcl_core:ladder 3', + output = "mcl_core:ladder 3", recipe = { - {'mcl_core:stick', '', 'mcl_core:stick'}, - {'mcl_core:stick', 'mcl_core:stick', 'mcl_core:stick'}, - {'mcl_core:stick', '', 'mcl_core:stick'}, + {"mcl_core:stick", "", "mcl_core:stick"}, + {"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"}, + {"mcl_core:stick", "", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_core:stonebrick 4', + output = "mcl_core:stonebrick 4", recipe = { - {'mcl_core:stone', 'mcl_core:stone'}, - {'mcl_core:stone', 'mcl_core:stone'}, + {"mcl_core:stone", "mcl_core:stone"}, + {"mcl_core:stone", "mcl_core:stone"}, } }) minetest.register_craft({ - output = 'mcl_core:lapisblock', + output = "mcl_core:lapisblock", recipe = { - {'mcl_dye:blue', 'mcl_dye:blue', 'mcl_dye:blue'}, - {'mcl_dye:blue', 'mcl_dye:blue', 'mcl_dye:blue'}, - {'mcl_dye:blue', 'mcl_dye:blue', 'mcl_dye:blue'}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, + {"mcl_core:lapis", "mcl_core:lapis", "mcl_core:lapis"}, } }) minetest.register_craft({ - output = 'mcl_dye:blue 9', + output = "mcl_core:lapis 9", recipe = { - {'mcl_core:lapisblock'}, + {"mcl_core:lapisblock"}, } }) minetest.register_craft({ output = "mcl_core:emeraldblock", recipe = { - {'mcl_core:emerald', 'mcl_core:emerald', 'mcl_core:emerald'}, - {'mcl_core:emerald', 'mcl_core:emerald', 'mcl_core:emerald'}, - {'mcl_core:emerald', 'mcl_core:emerald', 'mcl_core:emerald'}, + {"mcl_core:emerald", "mcl_core:emerald", "mcl_core:emerald"}, + {"mcl_core:emerald", "mcl_core:emerald", "mcl_core:emerald"}, + {"mcl_core:emerald", "mcl_core:emerald", "mcl_core:emerald"}, } }) minetest.register_craft({ - output = 'mcl_core:emerald 9', + output = "mcl_core:emerald 9", recipe = { - {'mcl_core:emeraldblock'}, + {"mcl_core:emeraldblock"}, } }) minetest.register_craft({ output = "mcl_core:diamondblock", recipe = { - {'mcl_core:diamond', 'mcl_core:diamond', 'mcl_core:diamond'}, - {'mcl_core:diamond', 'mcl_core:diamond', 'mcl_core:diamond'}, - {'mcl_core:diamond', 'mcl_core:diamond', 'mcl_core:diamond'}, + {"mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond"}, + {"mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond"}, + {"mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond"}, } }) minetest.register_craft({ - output = 'mcl_core:diamond 9', + output = "mcl_core:diamond 9", recipe = { - {'mcl_core:diamondblock'}, + {"mcl_core:diamondblock"}, } }) @@ -364,7 +347,7 @@ minetest.register_craft({ output = "mcl_core:apple_gold", recipe = { {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, - {"mcl_core:gold_ingot", 'mcl_core:apple', "mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot", "mcl_core:apple", "mcl_core:gold_ingot"}, {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, } }) @@ -385,22 +368,28 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mcl_core:snowblock', + output = "mcl_core:snowblock", recipe = { - {'mcl_throwing:snowball', 'mcl_throwing:snowball'}, - {'mcl_throwing:snowball', 'mcl_throwing:snowball'}, + {"mcl_throwing:snowball", "mcl_throwing:snowball"}, + {"mcl_throwing:snowball", "mcl_throwing:snowball"}, } }) minetest.register_craft({ - output = 'mcl_core:snow 6', + output = "mcl_core:snow 6", recipe = { - {'mcl_core:snowblock', 'mcl_core:snowblock', 'mcl_core:snowblock'}, + {"mcl_core:snowblock", "mcl_core:snowblock", "mcl_core:snowblock"}, } }) --- TODO: Add crafting recipe: 9 ice → 1 packed ice --- Add it when silk touch tools work. +minetest.register_craft({ + output = 'mcl_core:packed_ice 1', + recipe = { + {'mcl_core:ice', 'mcl_core:ice', 'mcl_core:ice'}, + {'mcl_core:ice', 'mcl_core:ice', 'mcl_core:ice'}, + {'mcl_core:ice', 'mcl_core:ice', 'mcl_core:ice'}, + } +}) -- -- Crafting (tool repair) @@ -493,7 +482,7 @@ minetest.register_craft({ minetest.register_craft({ type = "cooking", - output = "mcl_dye:blue", + output = "mcl_core:lapis", recipe = "mcl_core:stone_with_lapis", cooktime = 10, }) diff --git a/mods/ITEMS/mcl_core/craftitems.lua b/mods/ITEMS/mcl_core/craftitems.lua index 7cffcb785..32a5f7cbc 100644 --- a/mods/ITEMS/mcl_core/craftitems.lua +++ b/mods/ITEMS/mcl_core/craftitems.lua @@ -1,6 +1,8 @@ -- mods/default/craftitems.lua -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) + +local enable_fapples = minetest.settings:get_bool("mcl_enable_fapples",true) -- -- Crafting items @@ -13,6 +15,7 @@ minetest.register_craftitem("mcl_core:stick", { inventory_image = "default_stick.png", stack_max = 64, groups = { craftitem=1, stick=1 }, + _mcl_toollike_wield = true, }) minetest.register_craftitem("mcl_core:paper", { @@ -27,7 +30,6 @@ minetest.register_craftitem("mcl_core:coal_lump", { description = S("Coal"), _doc_items_longdesc = S("“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."), _doc_items_hidden = false, - groups = { coal=1 }, inventory_image = "default_coal_lump.png", stack_max = 64, groups = { craftitem=1, coal=1 }, @@ -37,7 +39,6 @@ minetest.register_craftitem("mcl_core:charcoal_lump", { description = S("Charcoal"), _doc_items_longdesc = S("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."), _doc_items_hidden = false, - groups = { coal=1 }, inventory_image = "mcl_core_charcoal.png", stack_max = 64, groups = { craftitem=1, coal=1 }, @@ -94,12 +95,20 @@ minetest.register_craftitem("mcl_core:gold_ingot", { minetest.register_craftitem("mcl_core:emerald", { description = S("Emerald"), - _doc_items_longdesc = S("Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting."), + _doc_items_longdesc = S("Emeralds are used in villager trades as currency."), inventory_image = "mcl_core_emerald.png", stack_max = 64, groups = { craftitem=1 }, }) +minetest.register_craftitem("mcl_core:lapis", { + description = S("Lapis Lazuli"), + _doc_items_longdesc = S("Lapis Lazuli are required for enchanting items on an enchanting table."), + inventory_image = "mcl_core_lapis.png", + stack_max = 64, + groups = { craftitem=1 }, +}) + minetest.register_craftitem("mcl_core:brick", { description = S("Brick"), _doc_items_longdesc = S("Bricks are used to craft brick blocks."), @@ -140,7 +149,7 @@ minetest.register_craftitem("mcl_core:apple", { stack_max = 64, on_place = minetest.item_eat(4), on_secondary_use = minetest.item_eat(4), - groups = { food = 2, eatable = 4 }, + groups = { food = 2, eatable = 4, compostability = 65 }, _mcl_saturation = 2.4, }) @@ -163,8 +172,11 @@ local function eat_gapple(itemstack, placer, pointed_thing) regen_duration, absorbtion_factor = 20, 4 mcl_potions.fire_resistance_func(placer, 1, 300) mcl_potions.leaping_func(placer, 1, 300) + if enable_fapples then + mcl_potions.swiftness_func(placer, absorbtion_factor, 120) + end end - mcl_potions.swiftness_func(placer, absorbtion_factor, 120) -- TODO: Absorbtion + -- TODO: Absorbtion mcl_potions.regeneration_func(placer, 2, regen_duration) return gapple_hunger_restore(itemstack, placer, pointed_thing) end diff --git a/mods/ITEMS/mcl_core/depends.txt b/mods/ITEMS/mcl_core/depends.txt deleted file mode 100644 index fb9861814..000000000 --- a/mods/ITEMS/mcl_core/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_sounds -mcl_particles -mcl_util -mcl_worlds -doc_items -doc? -mcl_enchanting diff --git a/mods/ITEMS/mcl_core/description.txt b/mods/ITEMS/mcl_core/description.txt deleted file mode 100644 index 96229f774..000000000 --- a/mods/ITEMS/mcl_core/description.txt +++ /dev/null @@ -1 +0,0 @@ -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. diff --git a/mods/ITEMS/mcl_core/functions.lua b/mods/ITEMS/mcl_core/functions.lua index 3d47336f3..b7623bf11 100644 --- a/mods/ITEMS/mcl_core/functions.lua +++ b/mods/ITEMS/mcl_core/functions.lua @@ -2,8 +2,13 @@ -- Lava vs water interactions -- +local modpath = minetest.get_modpath(minetest.get_current_modname()) + local mg_name = minetest.get_mapgen_setting("mg_name") +local math = math +local vector = vector + local OAK_TREE_ID = 1 local DARK_OAK_TREE_ID = 2 local SPRUCE_TREE_ID = 3 @@ -17,14 +22,15 @@ minetest.register_abm({ neighbors = {"group:water"}, interval = 1, chance = 1, + min_y = mcl_vars.mg_end_min, action = function(pos, node, active_object_count, active_object_count_wider) local water = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+1, z=pos.z+1}, "group:water") local lavatype = minetest.registered_nodes[node.name].liquidtype for w=1, #water do - local waternode = minetest.get_node(water[w]) - local watertype = minetest.registered_nodes[waternode.name].liquidtype + --local waternode = minetest.get_node(water[w]) + --local watertype = minetest.registered_nodes[waternode.name].liquidtype -- Lava on top of water: Water turns into stone if water[w].y < pos.y and water[w].x == pos.x and water[w].z == pos.z then minetest.set_node(water[w], {name="mcl_core:stone"}) @@ -53,7 +59,7 @@ minetest.register_abm({ -- -- Functions -mcl_core.grow_cactus = function(pos, node) +function mcl_core.grow_cactus(pos, node) pos.y = pos.y-1 local name = minetest.get_node(pos).name if minetest.get_item_group(name, "sand") ~= 0 then @@ -71,7 +77,7 @@ mcl_core.grow_cactus = function(pos, node) end end -mcl_core.grow_reeds = function(pos, node) +function mcl_core.grow_reeds(pos, node) pos.y = pos.y-1 local name = minetest.get_node(pos).name if minetest.get_item_group(name, "soil_sugarcane") ~= 0 then @@ -114,8 +120,8 @@ local function drop_attached_node(p) end -- Helper function for node actions for liquid flow -local liquid_flow_action = function(pos, group, action) - local check_detach = function(pos, xp, yp, zp) +local function liquid_flow_action(pos, group, action) + local function check_detach(pos, xp, yp, zp) local p = {x=pos.x+xp, y=pos.y+yp, z=pos.z+zp} local n = minetest.get_node_or_nil(p) if not n then @@ -169,16 +175,17 @@ minetest.register_abm({ nodenames = {"group:destroy_by_lava_flow"}, neighbors = {"group:lava"}, interval = 1, - chance = 1, + chance = 5, action = function(pos, node, active_object_count, active_object_count_wider) liquid_flow_action(pos, "lava", function(pos) minetest.remove_node(pos) minetest.sound_play("builtin_item_lava", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - core.check_for_falling(pos) + minetest.check_for_falling(pos) end) end, }) +-- Cactus mechanisms minetest.register_abm({ label = "Cactus growth", nodenames = {"mcl_core:cactus"}, @@ -190,6 +197,36 @@ minetest.register_abm({ end, }) +minetest.register_abm({ + label = "Cactus mechanisms", + nodenames = {"mcl_core:cactus"}, + interval = 1, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + for _, object in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do + local entity = object:get_luaentity() + if entity and entity.name == "__builtin:item" then + object:remove() + end + end + local posses = { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } } + for _, p in pairs(posses) do + local ndef = minetest.registered_nodes[minetest.get_node(vector.new(pos.x + p[1], pos.y, pos.z + p[2])).name] + if ndef and ndef.walkable then + local posy = pos.y + while minetest.get_node(vector.new(pos.x, posy, pos.z)).name == "mcl_core:cactus" do + local pos = vector.new(pos.x, posy, pos.z) + minetest.dig_node(pos) + -- minetest.add_item(vector.offset(pos, math.random(-0.5, 0.5), 0, math.random(-0.5, 0.5)), "mcl_core:cactus") + posy = posy + 1 + end + break + end + end + end, +}) + + minetest.register_abm({ label = "Sugar canes growth", nodenames = {"mcl_core:reeds"}, @@ -231,7 +268,7 @@ end -- Check if a node stops a tree from growing. Torches, plants, wood, tree, -- leaves and dirt does not affect tree growth. local function node_stops_growth(node) - if node.name == 'air' then + if node.name == "air" then return false end @@ -276,6 +313,7 @@ local function check_growth_width(pos, width, height) end return true end +mcl_core.check_growth_width = check_growth_width -- Check if a tree with id can grow at a position. Options is a table of flags -- for varieties of trees. The 'two_by_two' option is used to check if there is @@ -320,13 +358,12 @@ end -- oak tree. function mcl_core.generate_tree(pos, tree_type, options) pos.y = pos.y-1 - local nodename = minetest.get_node(pos).name + --local nodename = minetest.get_node(pos).name pos.y = pos.y+1 if not minetest.get_node_light(pos) then return end - local node local two_by_two = options and options.two_by_two local balloon = options and options.balloon @@ -368,13 +405,14 @@ function mcl_core.generate_tree(pos, tree_type, options) elseif tree_type == BIRCH_TREE_ID then mcl_core.generate_birch_tree(pos) end + mcl_core.update_sapling_foliage_colors(pos) end -- Classic oak in v6 style function mcl_core.generate_v6_oak_tree(pos) local trunk = "mcl_core:tree" local leaves = "mcl_core:leaves" - local node = {name = ""} + local node for dy=1,4 do pos.y = pos.y+dy if minetest.get_node(pos).name ~= "air" then @@ -393,10 +431,10 @@ function mcl_core.generate_v6_oak_tree(pos) node = {name = leaves} pos.y = pos.y+3 - local rarity = 0 + --[[local rarity = 0 if math.random(0, 10) == 3 then rarity = 1 - end + end]] for dx=-2,2 do for dz=-2,2 do for dy=0,3 do @@ -442,12 +480,12 @@ function mcl_core.generate_balloon_oak_tree(pos) local s = math.random(1, 12) if s == 1 then -- Small balloon oak - path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_oak_balloon.mts" + path = modpath .. "/schematics/mcl_core_oak_balloon.mts" offset = { x = -2, y = -1, z = -2 } else -- Large balloon oak local t = math.random(1, 4) - path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_oak_large_"..t..".mts" + path = modpath .. "/schematics/mcl_core_oak_large_"..t..".mts" if t == 1 or t == 3 then offset = { x = -3, y = -1, z = -3 } elseif t == 2 or t == 4 then @@ -458,16 +496,16 @@ function mcl_core.generate_balloon_oak_tree(pos) end -- Oak -function mcl_core.generate_oak_tree(pos) - local path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_oak_classic.mts" - local offset = { x = -2, y = -1, z = -2 } +local path_oak_tree = modpath.."/schematics/mcl_core_oak_classic.mts" - minetest.place_schematic(vector.add(pos, offset), path, "random", nil, false) +function mcl_core.generate_oak_tree(pos) + local offset = { x = -2, y = -1, z = -2 } + minetest.place_schematic(vector.add(pos, offset), path_oak_tree, "random", nil, false) end -- Birch function mcl_core.generate_birch_tree(pos) - local path = minetest.get_modpath("mcl_core") .. + local path = modpath .. "/schematics/mcl_core_birch.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, path, "random", nil, false) end @@ -579,28 +617,53 @@ function mcl_core.generate_v6_spruce_tree(pos) vm:write_to_map() end -mcl_core.generate_spruce_tree = function(pos) +function mcl_core.generate_spruce_tree(pos) local r = math.random(1, 3) - local path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_spruce_"..r..".mts" + local path = modpath .. "/schematics/mcl_core_spruce_"..r..".mts" minetest.place_schematic({ x = pos.x - 3, y = pos.y - 1, z = pos.z - 3 }, path, "0", nil, false) end -mcl_core.generate_huge_spruce_tree = function(pos) +local function find_necorner(p) + local n=minetest.get_node_or_nil(vector.offset(p,0,1,1)) + local e=minetest.get_node_or_nil(vector.offset(p,1,1,0)) + if n and n.name == "mcl_core:sprucetree" then + p=vector.offset(p,0,0,1) + end + if e and e.name == "mcl_core:sprucetree" then + p=vector.offset(p,1,0,0) + end + return p +end + +local function generate_spruce_podzol(ps) + local pos=find_necorner(ps) + local pos1=vector.offset(pos,-6,-6,-6) + local pos2=vector.offset(pos,6,6,6) + local nn=minetest.find_nodes_in_area_under_air(pos1, pos2, {"group:dirt"}) + for k,v in pairs(nn) do + if math.random(vector.distance(pos,v)) < 4 and not (math.abs(pos.x-v.x) == 6 and math.abs(pos.z-v.z) == 6) then --leave out the corners + minetest.set_node(v,{name="mcl_core:podzol"}) + end + end +end + +function mcl_core.generate_huge_spruce_tree(pos) local r1 = math.random(1, 2) local r2 = math.random(1, 4) local path local offset = { x = -4, y = -1, z = -5 } if r1 <= 2 then -- Mega Spruce Taiga (full canopy) - path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_spruce_huge_"..r2..".mts" + path = modpath.."/schematics/mcl_core_spruce_huge_"..r2..".mts" else -- Mega Taiga (leaves only at top) if r2 == 1 or r2 == 3 then offset = { x = -3, y = -1, z = -4} end - path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_spruce_huge_up_"..r2..".mts" + path = modpath.."/schematics/mcl_core_spruce_huge_up_"..r2..".mts" end minetest.place_schematic(vector.add(pos, offset), path, "0", nil, false) + generate_spruce_podzol(pos) end -- END of spruce tree functions -- @@ -616,15 +679,14 @@ function mcl_core.generate_acacia_tree(pos) elseif r == 1 or r == 5 then offset = { x = -5, y = -1, z = -5 } end - local path = minetest.get_modpath("mcl_core") .. "/schematics/mcl_core_acacia_"..r..".mts" + local path = modpath.."/schematics/mcl_core_acacia_"..r..".mts" minetest.place_schematic(vector.add(pos, offset), path, "random", nil, false) end -- Generate dark oak tree with 2×2 trunk. -- With pos being the lower X and the higher Z value of the trunk function mcl_core.generate_dark_oak_tree(pos) - local path = minetest.get_modpath("mcl_core") .. - "/schematics/mcl_core_dark_oak.mts" + local path = modpath.."/schematics/mcl_core_dark_oak.mts" minetest.place_schematic({x = pos.x - 3, y = pos.y - 1, z = pos.z - 4}, path, "random", nil, false) end @@ -724,8 +786,7 @@ function mcl_core.generate_v6_jungle_tree(pos) end function mcl_core.generate_jungle_tree(pos) - local path = minetest.get_modpath("mcl_core") .. - "/schematics/mcl_core_jungle_tree.mts" + local path = modpath.."/schematics/mcl_core_jungle_tree.mts" minetest.place_schematic({x = pos.x - 2, y = pos.y - 1, z = pos.z - 2}, path, "random", nil, false) end @@ -734,8 +795,7 @@ end function mcl_core.generate_huge_jungle_tree(pos) -- 2 variants local r = math.random(1, 2) - local path = minetest.get_modpath("mcl_core") .. - "/schematics/mcl_core_jungle_tree_huge_"..r..".mts" + local path = modpath.."/schematics/mcl_core_jungle_tree_huge_"..r..".mts" minetest.place_schematic({x = pos.x - 6, y = pos.y - 1, z = pos.z - 7}, path, "random", nil, false) end @@ -743,18 +803,20 @@ end local grass_spread_randomizer = PseudoRandom(minetest.get_mapgen_setting("seed")) -- Return appropriate grass block node for pos -function mcl_core.get_grass_block_type(pos) - local biome_data = minetest.get_biome_data(pos) - local index = 0 - if biome_data then - local biome = biome_data.biome - local biome_name = minetest.get_biome_name(biome) - local reg_biome = minetest.registered_biomes[biome_name] - if reg_biome then - index = reg_biome._mcl_palette_index - end - end - return {name="mcl_core:dirt_with_grass", param2=index} +function mcl_core.get_grass_block_type(pos, requested_grass_block_name) + local grass_palette_index = mcl_util.get_palette_indexes_from_pos(pos).grass_palette_index + local grass_block_name = requested_grass_block_name or minetest.get_node(pos).name + return {name = grass_block_name, param2 = grass_palette_index} +end + +-- Return appropriate foliage block node for pos +function mcl_core.get_foliage_block_type(pos) + return {name = minetest.get_node(pos).name, param2 = mcl_util.get_palette_indexes_from_pos(pos).foliage_palette_index} +end + +-- Return appropriate water block node for pos +function mcl_core.get_water_block_type(pos) + return {name = minetest.get_node(pos).name, param2 = mcl_util.get_palette_indexes_from_pos(pos).water_palette_index} end ------------------------------ @@ -768,18 +830,18 @@ minetest.register_abm({ chance = 20, catch_up = false, action = function(pos) - if pos == nil then - return - end - local can_change = false + if pos == nil then return end + local above = {x=pos.x, y=pos.y+1, z=pos.z} local abovenode = minetest.get_node(above) if minetest.get_item_group(abovenode.name, "liquid") ~= 0 or minetest.get_item_group(abovenode.name, "opaque") == 1 then -- Never grow directly below liquids or opaque blocks return end + local light_self = minetest.get_node_light(above) if not light_self then return end + --[[ Try to find a spreading dirt-type block (e.g. grass block or mycelium) within a 3×5×3 area, with the source block being on the 2nd-topmost layer. ]] local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+3, z=pos.z+1}, "group:spreading_dirt_type") @@ -798,16 +860,17 @@ minetest.register_abm({ if light_self >= 4 and light_source >= 9 then -- All checks passed! Let's spread the grass/mycelium! + local n2 = minetest.get_node(p2) if minetest.get_item_group(n2.name, "grass_block") ~= 0 then - n2 = mcl_core.get_grass_block_type(pos) + n2 = mcl_core.get_grass_block_type(pos, "mcl_core:dirt_with_grass") end minetest.set_node(pos, {name=n2.name}) -- If this was mycelium, uproot plant above if n2.name == "mcl_core:mycelium" then local tad = minetest.registered_nodes[minetest.get_node(above).name] - if tad.groups and tad.groups.non_mycelium_plant then + if tad and tad.groups and tad.groups.non_mycelium_plant then minetest.dig_node(above) end end @@ -865,28 +928,17 @@ minetest.register_lbm({ label = "Replace legacy dry grass", name = "mcl_core:replace_legacy_dry_grass_0_65_0", nodenames = {"mcl_core:dirt_with_dry_grass", "mcl_core:dirt_with_dry_grass_snow"}, + run_at_every_load = true, action = function(pos, node) - local biome_data = minetest.get_biome_data(pos) - if biome_data then - local biome = biome_data.biome - local biome_name = minetest.get_biome_name(biome) - local reg_biome = minetest.registered_biomes[biome_name] - if reg_biome then - if node.name == "mcl_core:dirt_with_dry_grass_snow" then - node.name = "mcl_core:dirt_with_grass_snow" - else - node.name = "mcl_core:dirt_with_grass" - end - node.param2 = reg_biome._mcl_palette_index - -- Fall back to savanna palette index - if not node.param2 then - node.param2 = SAVANNA_INDEX - end - minetest.set_node(pos, node) - return - end + if node.name == "mcl_core:dirt_with_dry_grass_snow" then + node.name = "mcl_core:dirt_with_grass_snow" + else + node.name = "mcl_core:dirt_with_grass" + end + -- use savanna palette index to simulate dry grass. + if not node.param2 then + node.param2 = SAVANNA_INDEX end - node.param2 = SAVANNA_INDEX minetest.set_node(pos, node) return end, @@ -897,7 +949,7 @@ minetest.register_lbm({ -------------------------- local treelight = 9 -local sapling_grow_action = function(tree_id, soil_needed, one_by_one, two_by_two, sapling) +local function sapling_grow_action(tree_id, soil_needed, one_by_one, two_by_two, sapling) return function(pos) local meta = minetest.get_meta(pos) if meta:get("grown") then return end @@ -939,7 +991,7 @@ local sapling_grow_action = function(tree_id, soil_needed, one_by_one, two_by_tw -- This sapling grows in a special way when there are 4 saplings in a 2×2 pattern if two_by_two then -- Check 8 surrounding saplings and try to find a 2×2 pattern - local is_sapling = function(pos, sapling) + local function is_sapling(pos, sapling) return minetest.get_node(pos).name == sapling end local p2 = {x=pos.x+1, y=pos.y, z=pos.z} @@ -1005,7 +1057,7 @@ local sapling_grow_action = function(tree_id, soil_needed, one_by_one, two_by_tw if one_by_one and check_tree_growth(pos, tree_id) then -- Single sapling minetest.set_node(pos, {name="air"}) - local r = math.random(1, 12) + --local r = math.random(1, 12) mcl_core.generate_tree(pos, tree_id) return end @@ -1022,11 +1074,21 @@ local grow_acacia = sapling_grow_action(ACACIA_TREE_ID, 2, true, false) local grow_spruce = sapling_grow_action(SPRUCE_TREE_ID, 1, true, true, "mcl_core:sprucesapling") local grow_birch = sapling_grow_action(BIRCH_TREE_ID, 1, true, false) +function mcl_core.update_sapling_foliage_colors(pos) + local pos1, pos2 = vector.offset(pos, -8, 0, -8), vector.offset(pos, 8, 30, 8) + local fnode + local foliage = minetest.find_nodes_in_area(pos1, pos2, {"group:foliage_palette", "group:foliage_palette_wallmounted"}) + for _, fpos in pairs(foliage) do + fnode = minetest.get_node(fpos) + minetest.set_node(fpos, fnode) + end +end + -- Attempts to grow the sapling at the specified position -- pos: Position -- node: Node table of the node at this position, from minetest.get_node -- Returns true on success and false on failure -mcl_core.grow_sapling = function(pos, node) +function mcl_core.grow_sapling(pos, node) local grow if node.name == "mcl_core:sapling" then grow = grow_oak @@ -1226,12 +1288,12 @@ minetest.register_abm({ if not mcl_core.check_vines_supported(pos, node) then minetest.remove_node(pos) vinedecay_particles(pos, node) - core.check_for_falling(pos) + minetest.check_for_falling(pos) return end -- Add vines below pos (if empty) - local spread_down = function(origin, target, dir, node) + local function spread_down(origin, target, dir, node) if math.random(1, 2) == 1 then if minetest.get_node(target).name == "air" then minetest.add_node(target, {name = "mcl_core:vine", param2 = node.param2}) @@ -1240,7 +1302,7 @@ minetest.register_abm({ end -- Add vines above pos if it is backed up - local spread_up = function(origin, target, dir, node) + local function spread_up(origin, target, dir, node) local vines_in_area = minetest.find_nodes_in_area({x=origin.x-4, y=origin.y-1, z=origin.z-4}, {x=origin.x+4, y=origin.y+1, z=origin.z+4}, "mcl_core:vine") -- Less then 4 vines blocks around the ticked vines block (remember the ticked block is counted by above function as well) if #vines_in_area < 5 then @@ -1259,7 +1321,7 @@ minetest.register_abm({ end end - local spread_horizontal = function(origin, target, dir, node) + local function spread_horizontal(origin, target, dir, node) local vines_in_area = minetest.find_nodes_in_area({x=origin.x-4, y=origin.y-1, z=origin.z-4}, {x=origin.x+4, y=origin.y+1, z=origin.z+4}, "mcl_core:vine") -- Less then 4 vines blocks around the ticked vines block (remember the ticked block is counted by above function as well) if #vines_in_area < 5 then @@ -1296,118 +1358,55 @@ minetest.register_abm({ }) -- Returns true of the node supports vines -mcl_core.supports_vines = function(nodename) +function mcl_core.supports_vines(nodename) local def = minetest.registered_nodes[nodename] -- Rules: 1) walkable 2) full cube - return def.walkable and + return def and def.walkable and (def.node_box == nil or def.node_box.type == "regular") and (def.collision_box == nil or def.collision_box.type == "regular") end -- Leaf Decay - --- To enable leaf decay for a node, add it to the "leafdecay" group. -- --- The rating of the group determines how far from a node in the group "tree" --- the node can be without decaying. +-- Whenever a tree trunk node is removed, all `group:leaves` nodes in a radius +-- of 6 blocks are checked from the trunk node's `after_destruct` handler. +-- Any such nodes within that radius that has no trunk node present within a +-- distance of 6 blocks is replaced with a `group:orphan_leaves` node. -- --- If param2 of the node is ~= 0, the node will always be preserved. Thus, if --- the player places a node of that kind, you will want to set param2=1 or so. --- - -mcl_core.leafdecay_trunk_cache = {} -mcl_core.leafdecay_enable_cache = true --- Spread the load of finding trunks -mcl_core.leafdecay_trunk_find_allow_accumulator = 0 - -minetest.register_globalstep(function(dtime) - local finds_per_second = 5000 - mcl_core.leafdecay_trunk_find_allow_accumulator = - math.floor(dtime * finds_per_second) -end) - +-- The `group:orphan_leaves` nodes are gradually decayed in this ABM. minetest.register_abm({ label = "Leaf decay", - nodenames = {"group:leafdecay"}, - neighbors = {"air", "group:liquid"}, - -- A low interval and a high inverse chance spreads the load - interval = 2, - chance = 5, + nodenames = {"group:orphan_leaves"}, + interval = 5, + chance = 10, + action = function(pos, node) + -- Spawn item entities for any of the leaf's drops + local itemstacks = minetest.get_node_drops(node.name) + for _, itemname in pairs(itemstacks) do + local p_drop = vector.offset(pos, math.random() - 0.5, math.random() - 0.5, math.random() - 0.5) + minetest.add_item(p_drop, itemname) + end + -- Remove the decayed node + minetest.remove_node(pos) + leafdecay_particles(pos, node) + minetest.check_for_falling(pos) - action = function(p0, node, _, _) - local do_preserve = false - local d = minetest.registered_nodes[node.name].groups.leafdecay - if not d or d == 0 then - return - end - local n0 = minetest.get_node(p0) - if n0.param2 ~= 0 then - -- Prevent leafdecay for player-placed leaves. - -- param2 is set to 1 after it was placed by the player - return - end - local p0_hash = nil - if mcl_core.leafdecay_enable_cache then - p0_hash = minetest.hash_node_position(p0) - local trunkp = mcl_core.leafdecay_trunk_cache[p0_hash] - if trunkp then - local n = minetest.get_node(trunkp) - local reg = minetest.registered_nodes[n.name] - -- Assume ignore is a trunk, to make the thing work at the border of the active area - if n.name == "ignore" or (reg and reg.groups.tree and reg.groups.tree ~= 0) then - return - end - -- Cache is invalid - table.remove(mcl_core.leafdecay_trunk_cache, p0_hash) - end - end - if mcl_core.leafdecay_trunk_find_allow_accumulator <= 0 then - return - end - mcl_core.leafdecay_trunk_find_allow_accumulator = - mcl_core.leafdecay_trunk_find_allow_accumulator - 1 - -- Assume ignore is a trunk, to make the thing work at the border of the active area - local p1 = minetest.find_node_near(p0, d, {"ignore", "group:tree"}) - if p1 then - do_preserve = true - if mcl_core.leafdecay_enable_cache then - -- Cache the trunk - mcl_core.leafdecay_trunk_cache[p0_hash] = p1 - end - end - if not do_preserve then - -- Drop stuff other than the node itself - local itemstacks = minetest.get_node_drops(n0.name) - for _, itemname in ipairs(itemstacks) do - local p_drop = { - x = p0.x - 0.5 + math.random(), - y = p0.y - 0.5 + math.random(), - z = p0.z - 0.5 + math.random(), - } - minetest.add_item(p_drop, itemname) - end - -- Remove node - minetest.remove_node(p0) - leafdecay_particles(p0, n0) - core.check_for_falling(p0) - - -- Kill depending vines immediately to skip the vines decay delay - local surround = { - { x = 0, y = 0, z = -1 }, - { x = 0, y = 0, z = 1 }, - { x = -1, y = 0, z = 0 }, - { x = 1, y = 0, z = 0 }, - { x = 0, y = -1, z = -1 }, - } - for s=1, #surround do - local spos = vector.add(p0, surround[s]) - local maybe_vine = minetest.get_node(spos) - local surround_inverse = vector.multiply(surround[s], -1) - if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then - minetest.remove_node(spos) - vinedecay_particles(spos, maybe_vine) - core.check_for_falling(spos) - end + -- Kill depending vines immediately to skip the vines decay delay + local surround = { + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = -1, z = -1 }, + } + for s=1, #surround do + local spos = vector.add(pos, surround[s]) + local maybe_vine = minetest.get_node(spos) + --local surround_inverse = vector.multiply(surround[s], -1) + if maybe_vine.name == "mcl_core:vine" and (not mcl_core.check_vines_supported(spos, maybe_vine)) then + minetest.remove_node(spos) + vinedecay_particles(spos, maybe_vine) + minetest.check_for_falling(spos) end end end @@ -1430,7 +1429,7 @@ minetest.register_abm({ minetest.remove_node(p0) vinedecay_particles(p0, node) -- Just in case a falling node happens to float above vines - core.check_for_falling(p0) + minetest.check_for_falling(p0) end end }) @@ -1516,7 +1515,7 @@ end -- -- The snowable nodes also MUST have _mcl_snowed defined to contain the name -- of the snowed node. -mcl_core.register_snowed_node = function(itemstring_snowed, itemstring_clear, tiles, sounds, clear_colorization, desc) +function mcl_core.register_snowed_node(itemstring_snowed, itemstring_clear, tiles, sounds, clear_colorization, desc, grass_palette) local def = table.copy(minetest.registered_nodes[itemstring_clear]) local create_doc_alias if def.description then @@ -1530,6 +1529,7 @@ mcl_core.register_snowed_node = function(itemstring_snowed, itemstring_clear, ti def._doc_items_usagehelp = nil def._doc_items_create_entry = false def.groups.not_in_creative_inventory = 1 + def.groups.grass_palette = grass_palette if def.groups.grass_block == 1 then def.groups.grass_block_no_snow = nil def.groups.grass_block_snow = 1 @@ -1560,7 +1560,7 @@ mcl_core.register_snowed_node = function(itemstring_snowed, itemstring_clear, ti end if not sounds then def.sounds = mcl_sounds.node_sound_dirt_defaults({ - footstep = { name = "pedology_snow_soft_footstep", gain = 0.5 } + footstep = mcl_sounds.node_sound_snow_defaults().footstep, }) else def.sounds = sounds @@ -1579,7 +1579,7 @@ end -- Reverts a snowed dirtlike node at pos to its original snow-less form. -- This function assumes there is no snow cover node above. This function -- MUST NOT be called if there is a snow cover node above pos. -mcl_core.clear_snow_dirt = function(pos, node) +function mcl_core.clear_snow_dirt(pos, node) local def = minetest.registered_nodes[node.name] if def._mcl_snowless then minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2}) @@ -1591,7 +1591,7 @@ end -- on_construct -- Makes constructed snowable node snowed if placed below a snow cover node. -mcl_core.on_snowable_construct = function(pos) +function mcl_core.on_snowable_construct(pos) -- Myself local node = minetest.get_node(pos) @@ -1619,7 +1619,7 @@ end -- on_construct -- Makes snowable node below snowed. -mcl_core.on_snow_construct = function(pos) +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] @@ -1629,7 +1629,7 @@ mcl_core.on_snow_construct = function(pos) end -- after_destruct -- Clears snowed dirtlike node below. -mcl_core.after_snow_destruct = function(pos) +function mcl_core.after_snow_destruct(pos) local nn = minetest.get_node(pos).name -- No-op if snow was replaced with snow if minetest.get_item_group(nn, "snow_cover") == 1 then @@ -1640,3 +1640,36 @@ mcl_core.after_snow_destruct = function(pos) mcl_core.clear_snow_dirt(npos, node) end + +-- Obsidian crying + +local crobby_particle = { + velocity = vector.new(0,0,0), + size = math.random(1.3,2.5), + texture = "mcl_core_crying_obsidian_tear.png", + collision_removal = false, +} + + +minetest.register_abm({ + label = "Obsidian cries", + nodenames = {"mcl_core:crying_obsidian"}, + interval = 5, + chance = 10, + action = function(pos, node) + minetest.after(math.random(0.1,1.5),function() + local pt = table.copy(crobby_particle) + pt.acceleration = vector.new(0,0,0) + pt.collisiondetection = false + pt.expirationtime = math.random(0.5,1.5) + pt.pos = vector.offset(pos,math.random(-0.5,0.5),-0.51,math.random(-0.5,0.5)) + minetest.add_particle(pt) + minetest.after(pt.expirationtime,function() + pt.acceleration = vector.new(0,-9,0) + pt.collisiondetection = true + pt.expirationtime = math.random(1.2,4.5) + minetest.add_particle(pt) + end) + end) + end +}) diff --git a/mods/ITEMS/mcl_core/init.lua b/mods/ITEMS/mcl_core/init.lua index 520f158bd..c345d057b 100644 --- a/mods/ITEMS/mcl_core/init.lua +++ b/mods/ITEMS/mcl_core/init.lua @@ -3,8 +3,21 @@ mcl_core = {} -- Repair percentage for toolrepair mcl_core.repair = 0.05 +mcl_autogroup.register_diggroup("handy") +mcl_autogroup.register_diggroup("pickaxey", { + levels = { "wood", "gold", "stone", "iron", "diamond" } +}) +mcl_autogroup.register_diggroup("axey") +mcl_autogroup.register_diggroup("shovely") +mcl_autogroup.register_diggroup("shearsy") +mcl_autogroup.register_diggroup("shearsy_wool") +mcl_autogroup.register_diggroup("shearsy_cobweb") +mcl_autogroup.register_diggroup("swordy") +mcl_autogroup.register_diggroup("swordy_cobweb") +mcl_autogroup.register_diggroup("hoey") + -- Load files -local modpath = minetest.get_modpath("mcl_core") +local modpath = minetest.get_modpath(minetest.get_current_modname()) dofile(modpath.."/functions.lua") dofile(modpath.."/nodes_base.lua") -- Simple solid cubic nodes with simple definitions dofile(modpath.."/nodes_liquid.lua") -- Liquids diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr index 57ef530a0..4f9071825 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.de.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.de.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=Andesit ist ein magmatisches Gestein. Apple=Apfel Apples are food items which can be eaten.=Äpfel sind essbare Gegenstände. Barrier=Barriere -Barriers are invisble 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.=Barrieren sind unsichtbare feste Blöcke. Sie sind nützlich, um Grenzen für Abenteuerkarten und ähnliches zu bauen. Monster und Tiere werden auf Barrieren nicht auftauchen, und Zäune verbinden sich nicht mit Barrieren. Andere Blöcke können an Barrieren gebaut werden, wie bei allen anderen Blöcken. +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.=Barrieren sind unsichtbare feste Blöcke. Sie sind nützlich, um Grenzen für Abenteuerkarten und ähnliches zu bauen. Monster und Tiere werden auf Barrieren nicht auftauchen, und Zäune verbinden sich nicht mit Barrieren. Andere Blöcke können an Barrieren gebaut werden, wie bei allen anderen Blöcken. Bedrock=Grundgestein Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Grundgestein ist ein sehr harter Gesteinstyp. Er kann unter normalen Umständen nicht abgebaut, zerstört, aufgesammelt oder verschoben werden, außer im Kreativmodus. Birch Bark=Birkenrinde @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Smaragd Emerald Ore=Smaragderz Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen. +Emeralds are used in villager trades as currency.= Flint=Feuerstein Flint is a raw material.=Feuerstein ist ein Rohstoff. Flowing Lava=Fließende Lava @@ -130,6 +130,8 @@ Jungle Wood=Dschungelholz Jungle Wood Planks=Dschungelholzplanken Jungle leaves are grown from jungle trees.=Dschungelblätter wachsen an Dschungelbäumen. Ladder=Leiter +Lapis Lazuli=Lapislazuli +Lapis Lazuli are required for enchanting items on an enchanting table.=Lapislazuli werden zum Verzaubern von Gegenständen auf einem Zaubertisch benötigt. Lapis Lazuli Block=Lapislazuliblock Lapis Lazuli Ore=Lapislazulierz Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Lapislazulierz ist das Erz von Lapislazuli. Es kann relativ selten in Ansammlungen in der Nähe des Weltbodens gefunden werden. @@ -202,20 +204,45 @@ Stained glass is a decorative and mostly transparent block which comes in variou Stick=Stock Sticks are a very versatile crafting material; used in countless crafting recipes.=Stöcke sind ein vielseitiges Material, sie werden in zahllosen Fertigungsrezepten gebraucht. Stone=Stein +Stripped Acacia Log=Entrindeter Akazienstamm +Stripped Acacia Wood=Entrindetes Akazienholz +Stripped Birch Log=Entrindeter Birkenstamm +Stripped Birch Wood=Entrindetes Birkenholz +Stripped Dark Oak Log=Entrindeter Schwarzeichenstamm +Stripped Dark Oak Wood=Entrindetes Schwarzeichenholz +Stripped Jungle Log=Entrindeter Dschungelbaumstamm +Stripped Jungle Wood=Entrindetes Dschungelholz +Stripped Oak Log=Entrindeter Eichenstamm +Stripped Oak Wood=Entrindetes Eichenholz +Stripped Spruce Log=Entrindeter Fichtenstamm +Stripped Spruce Wood=Entrindetes Fichtenholz Stone Bricks=Steinziegel Sugar=Zucker Sugar Canes=Zuckerrohr 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.=Zuckerrohr ist eine Pflanze, die in der Herstellung gebraucht wird. Zuckerrohr wird in der Nähe von Wasser bis zu 3 zusätzliche Blöcke wachsen lassen, wenn sie sich neben Wasser befinden und auf einem Grasblock, auf Erde, Sand, roten Sand, Podsol oder grobe Erde platziert wurden. Wird ein Zuckerrohr abgebrochen, werden alle verbundenen Zuckerrohrblöcke ebenfalls abbrechen. Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Zuckerrohr kann nur auf Zuckerrohr platziert werden und auf Blöcken, auf denen Zuckerrohr wachsen würde. Sugar comes from sugar canes and is used to make sweet foods.=Zucker kommt von Zuckerrohr und wird benutzt, um süße Lebensmittel zu machen. +The stripped trunk of an acacia tree.=Der entrindete Stamm einer Akazie. +The stripped trunk of a birch tree.=Der entrindete Stamm einer Birke. +The stripped trunk of a dark oak tree.=Der entrindete Stamm einer Schwarzeiche. +The stripped trunk of a jungle tree.=Der entrindete Stamm eines Dschungelbaums. +The stripped trunk of an oak tree.=Der entrindete Stamm einer Eiche. +The stripped trunk of a spruce tree.=Der entrindete Stamm einer Fichte. The trunk of a birch tree.=Der Baumstamm einer Birke. The trunk of a dark oak tree.=Der Baumstamm einer Schwarzeiche. The trunk of a jungle tree.=Der Baumstamm eines Dschungelbaums. The trunk of a spruce tree.=Der Baumstamm einer Fichte. The trunk of an acacia.=Der Baumstamm einer Akazie. The trunk of an oak tree.=Der Baumstamm einer Eiche. -This block consists of a couple of loose stones and can't support itself.=Diser Block besteht aus ein paar losen Steinchen und kann sich nicht selbst tragen. +The stripped wood of an acacia tree.=Das entrindete Holz einer Akazie. +The stripped wood of a birch tree.=Das entrindete Holz einer Birke. +The stripped wood of a dark oak tree.=Das entrindete Holz einer Schwarzeiche. +The stripped wood of a jungle tree.=Das entrindete Holz eines Dschungelbaums. +The stripped wood of an oak tree.=Das entrindete Holz einer Eiche. +The stripped wood of a spruce tree.=Das entrindete Holz einer Fichte. +This block consists of a couple of loose stones and can't support itself.=Dieser Block besteht aus ein paar losen Steinchen und kann sich nicht selbst tragen. This is a decorative block surrounded by the bark of a tree trunk.=Dies ist ein dekorativer Block, der von der Rinde eines Baumstamms umgeben ist. +This is a decorative block.=Dies ist ein dekorativer Block. This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Ein ganzer Block aus Schnee. Schnee von dieser Dicke wird üblicherweise in Gebieten extremer Kälte gefunden. 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.=Dies ist ein Teil eines Kaktus, der für gewöhnlich in trockenen Gebieten wächst, vorallem Wüsten. Im Laufe der Zeit werden Kakteen auf bis zu 3 Blöcke hoch auf Sand oder rotem Sand wachsen. Ein Kaktus verletzt Lebewesen, die ihn berühren, er richtet jede halbe Sekunden 1 Schaden an. Wenn ein Kaktusblock bricht, werden alle Kaktusblöcke darüber auch abbrechen. This stone contains pure gold, a rare metal.=Dieser Stein enthält pures Gold, ein seltenes Metall. @@ -255,3 +282,4 @@ Slows down movement=Verlangsamt die Fortbewegung 2×2 saplings @= large tree=2×2 Setzlinge @= großer Baum Grows on sand or dirt next to water=Wächst auf Sand oder Erde neben Wasser Stackable=Stapelbar +Needs soil and water to grow=Braucht Nährboden und Wasser zum wachsen diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr index 1e1029c0f..cf16e5bda 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.es.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.es.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=La andesita es una roca ígnea. Apple=Manzana Apples are food items which can be eaten.=Las manzanas son alimentos que se pueden comer. Barrier=Barrera -Barriers are invisble 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.=Las barreras son bloques transitables invisibles. Se utilizan para crear límites de mapas de aventura y similares. Los monstruos y los animales no aparecerán en las barreras, y las cercas no se conectan a las barreras. Otros bloques pueden construirse sobre barreras como en cualquier otro bloque. +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.=Las barreras son bloques transitables invisibles. Se utilizan para crear límites de mapas de aventura y similares. Los monstruos y los animales no aparecerán en las barreras, y las cercas no se conectan a las barreras. Otros bloques pueden construirse sobre barreras como en cualquier otro bloque. Bedrock=Lecho de roca Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=El lecho de roca es un tipo de roca muy duro. No se puede romper, destruir, recoger o mover por medios normales, a menos que esté en modo creativo. Birch Bark=Madera de abedul sin corteza @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Esmeralda Emerald Ore=Mena de esmeralda Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías. +Emeralds are used in villager trades as currency.= Flint=Pedernal Flint is a raw material.=El pedernal es una materia prima. Flowing Lava=Lava que fluye @@ -130,6 +130,8 @@ Jungle Wood=Tronco de jungla Jungle Wood Planks=Madera de jungla Jungle leaves are grown from jungle trees.=Las hojas de jungla se cultivan de los árboles de jungla. Ladder=Escalera +Lapis Lazuli=Lapislázuli +Lapis Lazuli are required for enchanting items on an enchanting table.=Los lapislázuli son necesarios para encantar objetos en una mesa de encantamiento. Lapis Lazuli Block=Bloque de lapislázuli Lapis Lazuli Ore=Mena de lapislázuli Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=El mineral de lapislázuli es el mineral de lapislázuli. Rara vez se puede encontrar en grupos, se encuentra cerca del fondo del mundo. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr index 4d97fe223..e66d8b115 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.fr.tr @@ -10,171 +10,173 @@ A block of iron is mostly a decorative block but also useful as a compact storag A cactus can only be placed on top of another cactus or any sand.=Un cactus ne peut être placé que sur un autre cactus ou du sable. A decorative and mostly transparent block.=Un bloc décoratif et surtout transparent. 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.=Un bloc d'herbe est de la terre avec une couverture d'herbe. Les blocs d'herbe sont des blocs ingénieux qui permettent la croissance de toutes sortes de plantes. Ils peuvent être transformés en terres agricoles avec une houe et transformés en chemins d'herbe avec une pelle. À la lumière, l'herbe se propage lentement sur la terre à proximité. Sous un bloc opaque ou un liquide, un bloc d'herbe peut redevenir terre. -A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Un bloc de lapis-lazuli est principalement un bloc décoratif mais également utile comme stockage compact de lapis-lazuli. +A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Un bloc de lapis-lazuli est principalement un bloc décoratif mais également utile pour stocker du lapis-lazuli. A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Une source de lave met le feu à quelques blocs d'air au-dessus lorsqu'ils sont à côté d'un bloc inflammable. 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.=Un morceau d'échelle qui vous permet de grimper verticalement. Les échelles ne peuvent être placées que sur le côté de blocs solides et non sur du verre, des feuilles, de la glace, des dalles, des pierres incandescentes ou des lanternes marines. -Acacia Bark=Écorce d'Acacia -Acacia Leaves=Feuilles d'Acacia -Acacia Sapling=Pousse d'Acacia -Acacia Wood=Bois d'Acacia -Acacia Wood Planks=Planches d'Acacia -Acacia leaves are grown from acacia trees.=Les feuilles d'acacia sont cultivées à partir d'acacias. +Acacia Bark=Bois d'acacia +Acacia Leaves=Feuilles d'acacia +Acacia Sapling=Pousse d'acacia +Acacia Wood=Bûche d'acacia +Acacia Wood Planks=Planches d'acacia +Acacia leaves are grown from acacia trees.=Les feuilles d'acacia poussent sur des acacias. Andesite=Andésite Andesite is an igneous rock.=L'andésite est une roche ignée. Apple=Pomme Apples are food items which can be eaten.=Les pommes sont des aliments qui peuvent être consommés. Barrier=Barrière invisible -Barriers are invisble 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.=Les barrières sont des blocs accessibles à pied. Ils sont utilisés pour créer des limites de cartes d'aventure et similaires. Les monstres et les animaux n'apparaissent pas sur les barrières, et les clôtures ne se connectent pas aux barrières. D'autres blocs peuvent être construits sur des barrières comme sur n'importe quel autre bloc. +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.=Les barrières sont des blocs accessibles à pied. Elles sont utilisées pour créer des limites de cartes d'aventure et autre. Les monstres et les animaux n'apparaissent pas sur les barrières, et les clôtures ne se connectent pas aux barrières. D'autres blocs peuvent être construits sur des barrières comme sur n'importe quel autre bloc. Bedrock=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.=Le bedrock est un type de roche très dur. Il ne peut pas être brisé, détruit, collecté ou déplacé par des moyens normaux, sauf en mode créatif. -Birch Bark=Écorce de Bouleau -Birch Leaves=Feuilles de Bouleau -Birch Sapling=Pousse de Bouleau -Birch Wood=Bois de Bouleau -Birch Wood Planks=Planches de Bouleau -Birch leaves are grown from birch trees.=Les feuilles de bouleau sont cultivées à partir de bouleaux. -Black Stained Glass=Verre Noir -Block of Coal=Bloc de Charbon -Block of Diamond=Bloc de Diamant -Block of Emerald=Bloc d'Emeraude -Block of Gold=Bloc d'Or -Block of Iron=Bloc de Fer -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.=Les blocs de charbon sont utiles comme stockage compact de charbon et très utiles comme combustible de four. Un bloc de charbon est aussi efficace que 10 charbon. -Blue Stained Glass=Verre Bleu -Bone Block=Bloc d'Os -Bone blocks are decorative blocks and a compact storage of bone meal.=Les blocs d'os sont des blocs décoratifs et un stockage compact de poudre d'os. +Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=La bedrock est un type de roche très dure. Elle ne peut pas être brisée, détruite, collectée ou déplacée par des moyens normaux, sauf en mode créatif. +Birch Bark=Bois de bouleau +Birch Leaves=Feuilles de bouleau +Birch Sapling=Pousse de bouleau +Birch Wood=Bûche de bouleau +Birch Wood Planks=Planches de bouleau +Birch leaves are grown from birch trees.=Les feuilles de bouleau poussent sur les bouleaux. +Black Stained Glass=Verre noir +Block of Coal=Bloc de charbon +Block of Diamond=Bloc de diamant +Block of Emerald=Bloc d'émeraude +Block of Gold=Bloc d'or +Block of Iron=Bloc de fer +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.=Les blocs de charbon sont utiles pour stocker du charbon et très utiles comme combustible de four. Un bloc de charbon est aussi efficace que 10 charbon. +Blue Stained Glass=Verre bleu +Bone Block=Bloc d'os +Bone blocks are decorative blocks and a compact storage of bone meal.=Les blocs d'os sont des blocs décoratifs et servent à stocker la poudre d'os. Bowl=Bol Bowls are mainly used to hold tasty soups.=Les bols sont principalement utilisés pour contenir de délicieuses soupes. Brick=Brique -Brick Block=Bloc de Brique -Brick blocks are a good building material for building solid houses and can take quite a punch.=Les blocs de briques sont un bon matériau de construction pour la construction de maisons solides et peuvent resite au coup. +Brick Block=Bloc de brique +Brick blocks are a good building material for building solid houses and can take quite a punch.=Les blocs de briques sont un bon matériau de construction pour la construction de maisons solides et peuvent résister aux coups. Bricks are used to craft brick blocks.=Les briques sont utilisées pour fabriquer des blocs de briques. -Brown Stained Glass=Verre Marron +Brown Stained Glass=Verre marron Cactus=Cactus -Charcoal=Charbon de Bois +Charcoal=Charbon de bois 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.=Le charbon de bois est un combustible de four alternatif créé par la cuisson du bois dans un four. Il a le même temps de combustion que le charbon et partage également bon nombre de ses recettes d'artisanat, mais il ne peut pas être utilisé pour créer des blocs de charbon. -Chiseled Stone Bricks=Pierre Sculptée -Chiseled Red Sandstone=Grès Rouge Sculptée -Chiseled Sandstone=Grès Sculptée +Chiseled Stone Bricks=Pierre sculptée +Chiseled Red Sandstone=Grès rouge sculpté +Chiseled Sandstone=Grès sculpté Chiseled red sandstone is a decorative building block.=Le grès rouge ciselé est un bloc de construction décoratif. Chiseled sandstone is a decorative building block.=Le grès ciselé est un bloc de construction décoratif. Clay=Argile -Clay Ball=Boule d'Argile +Clay Ball=Boule d'argile Clay balls are a raw material, mainly used to create bricks in the furnace.=Les boules d'argile sont une matière première, principalement utilisée pour créer des briques dans le four. Clay is a versatile kind of earth commonly found at beaches underwater.=L'argile est une terre polyvalente que l'on trouve couramment sur les plages sous-marines. Coal=Charbon -Coal Ore=Minerai de Charbon -Coarse Dirt=Terre Stérile +Coal Ore=Minerai de charbon +Coarse Dirt=Terre stérile Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=La terre stérile agit comme un sol pour certaines plantes et est similaire à la terre, mais elle ne fera jamais pousser grand chose. Cobblestone=Pierre -Cobweb=Toile d'Araignée +Cobweb=Toile d'araignée Cobwebs can be walked through, but significantly slow you down.=Les toiles d'araignée peuvent être parcourues, mais vous ralentissent considérablement. -Cracked Stone Bricks=Pierre Taillée Craquelée -Cut Red Sandstone=Grès Rouge Taillé -Cut Sandstone=Grès Taillé +Cracked Stone Bricks=Pierre taillée craquelée +Cut Red Sandstone=Grès rouge taillé +Cut Sandstone=Grès taillé Cut red sandstone is a decorative building block.=Le grès rouge taillé est un bloc de construction décoratif. Cut sandstone is a decorative building block.=Le grès taillé est un bloc de construction décoratif. -Cyan Stained Glass=Vitre Cyan -Dark Oak Bark=Écorce de Chêne Noir -Dark Oak Leaves=Feuilles de Chêne Noir -Dark Oak Sapling=Pousse de Chêne Noir -Dark Oak Wood=Bois de Chêne Noir -Dark Oak Wood Planks=Planche de Chêne Noir -Dark oak leaves are grown from dark oak trees.=Les feuilles de chêne noir sont issues de chênes noirs. -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.=Les pousses de chêne noir peuvent devenir des chênes noirs, mais seulement en groupes. Une pousse de chêne noir solitaire ne poussera pas. Un groupe de quatre pousses de chêne noir se transforme en chêne noir après un certain temps lorsqu'ils sont placés sur le sol (comme la terre) dans un carré 2×2 et exposés à la lumière. +Cyan Stained Glass=Vitre cyan +Dark Oak Bark=Bois de chêne noir +Dark Oak Leaves=Feuilles de chêne noir +Dark Oak Sapling=Pousse de chêne noir +Dark Oak Wood=Bûche de chêne noir +Dark Oak Wood Planks=Planche de chêne noir +Dark oak leaves are grown from dark oak trees.=Les feuilles de chêne noir poussent sur les chênes noirs. +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.=Les pousses de chêne noir peuvent devenir des chênes noirs, mais seulement en groupes. Une pousse de chêne noir solitaire ne poussera pas. Un groupe de quatre pousses de chêne noir se transforme en chêne noir après un certain temps lorsqu'elles sont placées sur le sol (comme la terre) dans un carré 2×2 et exposés à la lumière. Dead Bush=Arbuste mort Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=Les buissons morts sont des plantes inhabituelles que l'on trouve souvent dans les zones sèches. Ils peuvent être récoltés avec des bâtons. -Diamond=Diamamnt -Diamond Ore=Minerai de Diamant +Diamond=Diamant +Diamond Ore=Minerai de diamant Diamond ore is rare and can be found in clusters near the bottom of the world.=Le minerai de diamant est rare et peut être trouvé en filons près du fond du monde. -Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Les diamants sont des minéraux précieux et utiles pour créer le plus haut niveau d'armure et d'outils. +Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Les diamants sont des minéraux précieux et utiles pour créer des armures et outils du plus haut niveau . Diorite=Diorite Diorite is an igneous rock.=La diorite est une roche ignée. Dirt=Terre 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.=La terre agit comme un sol pour quelques plantes. Lorsqu'il est à la lumière, ce bloc peut faire pousser une couverture d'herbe ou de mycélium si ces blocs sont à proximité. -Emerald=Emeraude -Emerald Ore=Minerai d'Emeraude +Emerald=Émeraude +Emerald Ore=Minerai d'émeraude Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or. +Emeralds are used in villager trades as currency.=Les émeraudes sont utilisées pour faire des échanges avec les villageois. Flint=Silex Flint is a raw material.=Le silex est une matière première. Flowing Lava=Lave qui coule Flowing Water=Eau qui coule -Frosted Ice=Glace Givrée -Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=La glace givrée est un bloc solide de courte durée. Il fond dans une source d'eau en quelques secondes. +Frosted Ice=Glace givrée +Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=La glace givrée est un bloc solide de courte durée. Elle fond dans une source d'eau en quelques secondes. Glass=Verre -Gold Ingot=Lingot d'Or -Gold Nugget=Pépite d'Or -Gold Ore=Minerai d'Or -Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=Les pépites d'or sont de très petites pièces d'or en fusion; le but principal est de créer des lingots d'or. -Golden Apple=Pomme Dorée -Golden apples are precious food items which can be eaten.=Les pommes dorrées sont des aliments précieux qui peuvent être consommés. +Gold Ingot=Lingot d'or +Gold Nugget=Pépite d'or +Gold Ore=Minerai d'or +Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=Les pépites d'or sont de très petites pièces d'or en fusion ; le but principal est de créer des lingots d'or. +Golden Apple=Pomme dorée +Golden apples are precious food items which can be eaten.=Les pommes dorées sont des aliments précieux qui peuvent être consommés. Granite=Granite -Grass Block=Bloc d'Herbe -Grass Path=Chemin d'Herbe +Grass Block=Bloc d'herbe +Grass Path=Chemin d'herbe 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.=Les chemins d'herbe sont une variante décorative des blocs d'herbe. Leur sommet a une couleur différente et ils sont un peu plus bas que les blocs d'herbe, ce qui les rend utiles pour construire des sentiers. Les chemins d'herbe peuvent être créés avec une pelle. Un chemin d'herbe se transforme en terre quand il est en dessous d'un bloc solide. Gravel=Gravier -Green Stained Glass=Verre Vert -Grey Stained Glass=Verre Gris +Green Stained Glass=Verre vert +Grey Stained Glass=Verre gris Ice=Glace -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.=La glace est un bloc solide que l'on trouve généralement dans les régions froides. Il fond près des sources de lumière de bloc à un niveau de lumière de 12 ou plus. Lorsqu'il fond ou se casse en se reposant sur un autre bloc, il se transforme en source d'eau. +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.=La glace est un bloc solide que l'on trouve généralement dans les régions froides. Elle fond près des blocs sources de lumière à un niveau de lumière de 12 ou plus. Lorsqu'elle fond ou se casse au sommet d'un autre bloc, elle se transforme en source d'eau. In the End dimension, starting a fire on this block will create an eternal fire.=Dans la dimension End, démarrer un feu sur ce bloc créera un feu éternel. -Iron Ingot=Lingot de Fer -Iron Nugget=Pépite de Fer -Iron Ore=Minerai de Fer -Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Les pépites de fer sont de très petits morceaux de fer fondu; le but principal est de créer des lingots de fer. -Jungle Bark=Écorce d'Acajou -Jungle Leaves=Feuilles d'Acajou -Jungle Sapling=Pousse d'Acajou -Jungle Wood=Bois d'Acajou -Jungle Wood Planks=Planches d'Acajou -Jungle leaves are grown from jungle trees.=Les feuilles d'Acajou sont cultivées à partir d'arbres d'Acajou. +Iron Ingot=Lingot de fer +Iron Nugget=Pépite de fer +Iron Ore=Minerai de fer +Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Les pépites de fer sont de très petits morceaux de fer fondu ; leur principal intérêt est de fabriquer des lingots de fer. +Jungle Bark=Bois d'acajou +Jungle Leaves=Feuilles d'acajou +Jungle Sapling=Pousse d'acajou +Jungle Wood=Bûche d'acajou +Jungle Wood Planks=Planches d'acajou +Jungle leaves are grown from jungle trees.=Les feuilles d'acajou poussent sur les acajous. Ladder=Échelle -Lapis Lazuli Block=Bloc de Lapis-Lazuli -Lapis Lazuli Ore=Minerai de Lapis-Lazuli +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 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. -Light Blue Stained Glass=Verre Bleu Clair -Light Grey Stained Glass=Verre Gris Clair -Lime Stained Glass=Verre Vert Clair +Light Blue Stained Glass=Verre bleu clair +Light Grey Stained Glass=Verre gris clair +Lime Stained Glass=Verre vert clair Lit Redstone Ore=Minerai de Redstone -Magenta Stained Glass=Verre Magenta -Molten gold. It is used to craft armor, tools, and whatnot.=L'Or. Il est utilisé pour fabriquer des armures, des outils et ainsi de suite. -Molten iron. It is used to craft armor, tools, and whatnot.=Le Fer. Il est utilisé pour fabriquer des armures, des outils et ainsi de suite. -Mossy Cobblestone=Pierre Moussue -Mossy Stone Bricks=Pierre Taillée Moussue +Magenta Stained Glass=Verre magenta +Molten gold. It is used to craft armor, tools, and whatnot.=L'or. Il est utilisé pour fabriquer des armures, des outils et ainsi de suite. +Molten iron. It is used to craft armor, tools, and whatnot.=Le fer. Il est utilisé pour fabriquer des armures, des outils et ainsi de suite. +Mossy Cobblestone=Pierre moussue +Mossy Stone Bricks=Pierre taillée moussue Mycelium=Mycélium 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.=Le mycélium est un type de terre et le sol idéal pour les champignons. Contrairement à d'autres blocs de terre, il ne peut pas être transformé en terres agricoles avec une houe. À la lumière, le mycélium se répand lentement sur la terre voisine. Sous un bloc opaque ou un liquide, il finit par redevenir de la terre. -Oak Bark=Écorce de Chêne -Oak Leaves=Feuilles de Chêne -Oak Sapling=Pousse de Chêne -Oak Wood=Bois de Chêne -Oak Wood Planks=Planches de Chêne -Oak leaves are grown from oak trees.=Les feuilles de chêne sont cultivées à partir de chênes. +Oak Bark=Bois de chêne +Oak Leaves=Feuilles de chêne +Oak Sapling=Pousse de chêne +Oak Wood=Bûche de chêne +Oak Wood Planks=Planches de chêne +Oak leaves are grown from oak trees.=Les feuilles de chêne poussent sur des chênes. Obsidian=Obsidienne Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava.=L'obsidienne est un minéral extrêmement dur avec une énorme résistance à l'explosion. L'obsidienne se forme lorsque l'eau rencontre la lave. -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.=L'un des blocs les plus courants au monde, presque tout le sous-sol est en pierre. Il contient parfois des minerais. La pierre peut être créée lorsque l'eau rencontre la lave. -Orange Stained Glass=Verre Orange -Packed Ice=Glace Compactée +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.=L'un des blocs les plus courants au monde, presque tout le sous-sol est en pierre. Elle contient parfois des minerais. La pierre peut être créée lorsque l'eau rencontre la lave. +Orange Stained Glass=Verre orange +Packed Ice=Glace compactée Packed ice is a compressed form of ice. It is opaque and solid.=La glace compactée est une forme de glace comprimée. Elle est opaque et solide. Paper=Papier Paper is used to craft books and maps.=Le papier est utilisé pour créer des livres et des cartes. -Pink Stained Glass=Verre Rose +Pink Stained Glass=Verre rose Podzol=Podzol Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Le podzol est un type de terre trouvé dans les forêts de la taïga. Seules quelques plantes peuvent y survivre. -Polished Andesite=Andrésite Polie -Polished Diorite=Diorite Polie -Polished Granite=Granite Polie -Polished Stone=Roche Polie +Polished Andesite=Andésite polie +Polished Diorite=Diorite polie +Polished Granite=Granite poli +Polished Stone=Roche polie Polished andesite is a decorative building block made from andesite.=L'andésite polie est un bloc de construction décoratif en andésite. Polished diorite is a decorative building block made from diorite.=La diorite polie est un bloc de construction décoratif en diorite. -Polished granite is a decorative building block made from granite.=Le granit poli est un bloc de construction décoratif en granit. -Purple Stained Glass=Verre Violet +Polished granite is a decorative building block made from granite.=Le granite poli est un bloc de construction décoratif en granit. +Purple Stained Glass=Verre violet Realm Barrier=Barrière du royaume -Red Sand=Sable Rouge -Red Sandstone=Grès Rouge -Red Stained Glass=Verre Rouge +Red Sand=Sable rouge +Red Sandstone=Grès rouge +Red Stained Glass=Verre rouge Red sand is found in large quantities in mesa biomes.=Le sable rouge se trouve en grande quantité dans les biomes mesa. Red sandstone is compressed red sand and is a rather soft kind of stone.=Le grès rouge est du sable rouge comprimé et est une pierre plutôt tendre. Redstone Ore=Minerai de Redstone @@ -184,57 +186,82 @@ Sand is found in large quantities at beaches and deserts.=Le sable se trouve en Sandstone=Grès Sandstone is compressed sand and is a rather soft kind of stone.=Le grès est du sable comprimé et est un type de pierre plutôt tendre. Slime Block=Bloc de Slime -Slime blocks are very bouncy and prevent fall damage.=Les blocs de slime sont gonflables et empêchent les dommages de chute. -Smooth Red Sandstone=Grès Rouge Lisse -Smooth Sandstone=Grès Lisse +Slime blocks are very bouncy and prevent fall damage.=Les blocs de slime sont gonflables et empêchent les dégâts de chute. +Smooth Red Sandstone=Grès rouge lisse +Smooth Sandstone=Grès lisse Smooth red sandstone is a decorative building block.=Le grès rouge lisse est un bloc de construction décoratif. Smooth sandstone is compressed sand and is a rather soft kind of stone.=Le grès lisse est du sable comprimé et est un type de pierre plutôt tendre. Snow=Neige -Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Du charbon contenu dans la pierre, il est très commun et peut être trouvé à l'intérieur de la pierre en grappes moyennes à grandes à presque toutes les hauteurs. +Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Du charbon contenu dans la pierre, il est très commun et peut être trouvé à l'intérieur de la pierre en veines moyennes à grandes à presque toutes les hauteurs. Some iron contained in stone, it is prety common and can be found below sea level.=Du fer contenu dans la pierre, il est assez courant et se trouve sous le niveau de la mer. -Spruce Bark=Écorce de Sapin -Spruce Leaves=Feuilles de Sapin -Spruce Sapling=Pousse de Sapin -Spruce Wood=Bois de Sapin -Spruce Wood Planks=Planches de Sapin -Spruce leaves are grown from spruce trees.=Les feuilles de sapin sont cultivées à partir de sapin. +Spruce Bark=Bois de sapin +Spruce Leaves=Feuilles de sapin +Spruce Sapling=Pousse de sapin +Spruce Wood=Bûche de sapin +Spruce Wood Planks=Planches de sapin +Spruce leaves are grown from spruce trees.=Les feuilles de sapin poussent sur les sapins. Stained glass is a decorative and mostly transparent block which comes in various different colors.=Le verre est un bloc décoratif et principalement transparent qui se décline en différentes couleurs. Stick=Bâton -Sticks are a very versatile crafting material; used in countless crafting recipes.=Les bâtons sont un matériau d'artisanat très polyvalent; utilisé dans d'innombrables recettes d'artisanat. +Sticks are a very versatile crafting material; used in countless crafting recipes.=Les bâtons sont un matériau d'artisanat très polyvalent ; utilisé dans d'innombrables recettes d'artisanat. Stone=Roche -Stone Bricks=Pierre Taillée +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 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 +Stripped Oak Wood=Bois de chêne écorcé +Stripped Spruce Log=Bûche de sapin écorcée +Stripped Spruce Wood=Bois de sapin écorcé +Stone Bricks=Pierre taillée Sugar=Sucre -Sugar Canes=Canne à Sucre +Sugar Canes=Canne à sucre 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.=Les cannes à sucre sont une plante qui a certaines utilisations dans l'artisanat. Les cannes à sucre poussent lentement jusqu'à 3 blocs lorsqu'elles sont à côté de l'eau et sont placées sur un bloc d'herbe, de saleté, de sable, de sable rouge, de podzol ou de saleté grossière. Lorsqu'une canne à sucre est cassée, toutes les cannes à sucre connectées ci-dessus se brisent également. Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Les cannes à sucre ne peuvent être placées que sur d'autres cannes à sucre et sur des blocs sur lesquels elles poussent. Sugar comes from sugar canes and is used to make sweet foods.=Le sucre provient des cannes à sucre et est utilisé pour fabriquer des aliments sucrés. +The stripped trunk of an acacia tree.=Le tronc écorcé d'un acacia. +The stripped trunk of a birch tree.=Le tronc écorcé d'un bouleau. +The stripped trunk of a dark oak tree.=Le tronc écorcé d'un chêne noir. +The stripped trunk of a jungle tree.=Le tronc écorcé d'un acajou. +The stripped trunk of an oak tree.=Le tronc écorcé d'un chêne. +The stripped trunk of a spruce tree.=Le tronc écorcé d'un sapin. The trunk of a birch tree.=Le tronc d'un bouleau. The trunk of a dark oak tree.=Le tronc d'un chêne noir. The trunk of a jungle tree.=Le tronc d'un acajou. The trunk of a spruce tree.=Le tronc d'un sapin. The trunk of an acacia.=Le tronc d'un acacia The trunk of an oak tree.=Le tronc d'un chêne. -This block consists of a couple of loose stones and can't support itself.=Ce bloc se compose de quelques pierres lâches et ne peut pas se soutenir. +The stripped wood of an acacia tree.=Le bois écorcé d'un acacia. +The stripped wood of a birch tree.=Le bois écorcé d'un bouleau. +The stripped wood of a dark oak tree.=Le bois écorcé d'un chêne noir. +The stripped wood of a jungle tree.=Le bois écorcé d'un acajou. +The stripped wood of an oak tree.=Le bois écorcé d'un chêne. +The stripped wood of a spruce tree.=Le bois écorcé d'un sapin. +This block consists of a couple of loose stones and can't support itself.=Ce bloc se compose de quelques pierres instables et ne peut pas se soutenir. This is a decorative block surrounded by the bark of a tree trunk.=Il s'agit d'un bloc décoratif entouré par l'écorce d'un tronc d'arbre. +This is a decorative block.=Il s'agit d'un bloc décoratif. This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Ceci est un bloc de neige complet. La neige de cette épaisseur se trouve généralement dans les zones de froid extrême. 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.=Il s'agit d'un morceau de cactus que l'on trouve couramment dans les zones sèches, en particulier dans les déserts. Au fil du temps, les cactus pousseront jusqu'à 3 blocs de haut sur le sable ou le sable rouge. Un cactus blesse les êtres vivants qui le touchent avec des dégâts de 1 HP toutes les demi-secondes. Lorsqu'un bloc de cactus est brisé, tous les blocs de cactus connectés au-dessus se brisent également. This stone contains pure gold, a rare metal.=Cette pierre contient de l'or pur, un métal rare. Top Snow=neige -Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=La neige est une couche de neige. Il fond près de sources lumineuses autres que le soleil avec un niveau de lumière de 12 ou plus. +Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=La neige est une couche de neige. Elle fond près de sources lumineuses autres que le soleil avec un niveau de lumière de 12 ou plus. Vines=Lianes -Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Les lianes sont des blocs grimpants qui peuvent être placés sur les côtés de blocs pleins. Les lianes poussent et s'étendent lentement. +Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Les lianes sont des blocs grimpables qui peuvent être placés sur les côtés de blocs pleins. Les lianes poussent et s'étendent lentement. Void=Néant Water=Eau -Water Source=Source d'Eau +Water Source=Source d'eau 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.=L'eau est abondante dans les océans et apparaît également dans quelques sources dans le sol. Vous pouvez nager facilement dans l'eau, mais vous devez de temps en temps reprendre votre souffle. -When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=Lorsqu'il est placé sur le sol (comme la terre) et exposé à la lumière, un jeune arbre de bouleau se transforme en bouleau après un certain temps. -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.=Lorsqu'il est placé sur le sol (comme la terre) et exposé à la lumière, une pousse d'Acajou se transforme en arbre d'Acajou après un certain temps. Quand il y a 4 pousses d'Acajou dans un carré 2×2, ils deviendront un énorme arbre d'Acajou. -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.=Lorsqu'il est placé sur le sol (comme la terre) et exposé à la lumière, un pousse de sapin se transforme en sapin après un certain temps. Lorsqu'il y a 4 pousses de sapin dans un carré 2×2, elles deviendront un énorme sapin. -When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=Lorsqu'il est placé sur le sol (comme la terre) et exposé à la lumière, un pousse d'acacia se développera en un acacia après un certain temps. -When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=Lorsqu'il est placé sur le sol (comme la terre) et exposé à la lumière, une pousse de chêne se transforme en chêne après un certain temps. +When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=Lorsqu'elle est placée sur le sol (par exemple de la terre) et exposée à la lumière, une jeune pousse de bouleau se transforme en bouleau après un certain temps. +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.=Lorsqu'elle est placée sur le sol (par exemple de la terre) et exposée à la lumière, une pousse d'Acajou se transforme en arbre d'Acajou après un certain temps. Quand il y a 4 pousses d'Acajou dans un carré 2×2, elles deviendront un énorme arbre d'Acajou. +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.=Lorsqu'elle est placée sur le sol (par exemple de la terre) et exposée à la lumière, une pousse de sapin se transforme en sapin après un certain temps. Lorsqu'il y a 4 pousses de sapin dans un carré 2×2, elles deviendront un énorme sapin. +When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=Lorsqu'elle est placée sur le sol (par exemple de la terre) et exposée à la lumière, une pousse d'acacia se transforme en acacia après un certain temps. +When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=Lorsqu'elle est placée sur le sol (par exemple de la terre) et exposée à la lumière, une pousse de chêne se transforme en chêne après un certain temps. When you hold a barrier in hand, you reveal all placed barriers in a short distance around you.=Lorsque vous tenez une barrière en main, vous révélez toutes les barrières placées à une courte distance autour de vous. -White Stained Glass=Verre Blanc -Yellow Stained Glass=Verre Jaune +White Stained Glass=Verre blanc +Yellow Stained Glass=Verre jaune “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.=Le "charbon" fait référence aux morceaux de charbon obtenus en creusant du minerai de charbon qui peut être trouvé sous terre. Le charbon est votre combustible de four standard, mais il peut également être utilisé pour fabriquer des torches, des blocs de charbon et quelques autres choses. Water interacts with lava in various ways:=L'eau interagit avec la lave de différentes manières: • When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=• Lorsque l'eau est directement au-dessus ou horizontalement à côté d'une source de lave, la lave se transforme en obsidienne. @@ -244,15 +271,21 @@ Lava interacts with water various ways:=La lave interagit avec l'eau de différe • When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Lorsqu'une source de lave se trouve directement sous ou horizontalement à côté de l'eau, la lave se transforme en obsidienne. • When lava is directly above water, the water turns into stone.=• Lorsque la lave est directement au-dessus de l'eau, l'eau se transforme en pierre. Stained Glass=Verre teinté -Granite is an igneous rock.=Le granit est une roche ignée. +Granite is an igneous rock.=Le granite est une roche ignée. 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.=La neige peut être empilée et a l'un des 8 niveaux de hauteur différents. Aux niveaux 2 à 8, la neige provoque des collisions. La neige laisse tomber 2-9 boules de neige, selon sa hauteur. This block can only be placed on full solid blocks and on another top snow (which increases its height).=Ce bloc ne peut être placé que sur des blocs pleins et sur une autre neige (ce qui augmente sa hauteur). Needs soil and water to grow=A besoin de terre et d'eau pour se développer Needs soil and light to grow=A besoin de terre et de lumière pour se développer Grows on sand=Pousse sur le sable -Contact damage: @1 per half second=Dommages de contact: @1 par demi-seconde +Contact damage: @1 per half second=Dégâts de contact : @1 par demi-seconde Slows down movement=Ralentit le mouvement -2×2 saplings required=2×2 pousses requis +2×2 saplings required=2×2 pousses requises 2×2 saplings @= large tree=2×2 pousses @= grand arbre Grows on sand or dirt next to water=Pousse sur le sable ou la terre près de l'eau Stackable=Empilable +Crying Obsidian=Obsidienne pleureuse +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=L'obsidienne pleureuse est une obsidienne lumineuse qui peut être générée dans les portails en ruine. +Enchanted Golden Apple=Pomme dorée enchantée +Light=Lumière +Lights are invisible blocks. They are used to light up adventure maps and the like.=Les lumières sont des blocs invisibles. Elles sont utilisées pour éclairer les cartes d'aventure. +When you hold a light in hand, you reveal all placed lights in a short distance around you.=Lorsque vous tenez une lumière en main, vous révélez toutes les lumières placées à une courte distance autour de vous. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr new file mode 100644 index 000000000..401b02700 --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ja.tr @@ -0,0 +1,286 @@ +# textdomain: mcl_core +@1 could not survive in lava.=@1は溶岩の中で生き残ることができなかった。 +@1 died 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 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=アカシアの葉 +Acacia Sapling=アカシアの苗木 +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.=リンゴは食べられるアイテムです。 +Barrier=バリア +Barriers are invisble 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=シラカバの葉 +Birch Sapling=シラカバの苗木 +Birch Wood=シラカバの木 +Birch Wood Planks=シラカバの板材 +Birch leaves are grown from birch trees.=シラカバの葉は、シラカバの木から育ちます。 +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.=石炭ブロックは、石炭をコンパクトに保管でき、炉の燃料として非常に便利です。1個の石炭ブロックは、10個の石炭と同じ効率です。 +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.=ボウルは、主に美味しいスープを入れるために使われます。 +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=茶色ガラス +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.=粘土は海水浴中によく見つかる、汎用性の高い土の一種です。 +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.=粗い土は、一部の植物の土として機能し、土と類似してはいますが、表層を何かが覆うことがありません。 +Cobblestone=丸石 +Cobweb=クモの巣 +Cobwebs can be walked through, but significantly slow you down.=クモの巣は歩いて通過できますが、大幅にノロくなります。 +Cracked Stone Bricks=ひび割れた石レンガ +Cut Red Sandstone=溝入り赤い砂岩 +Cut Sandstone=溝入り砂岩 +Cut red sandstone is a decorative building block.=溝入り赤い砂岩は、装飾用ブロックです。 +Cut sandstone is a decorative building block.=溝入り砂岩は、装飾用ブロックです。 +Cyan Stained Glass=青緑色ガラス +Dark Oak Bark=ダークオークの樹皮 +Dark Oak Leaves=ダークオークの葉 +Dark Oak Sapling=ダークオークの苗木 +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.=ダークオークの苗木はダークオークに成長できますが、複数植えなければなりません。孤立したダークオークの苗木は成長しないのです。ダークオークの苗木を4本、正方形(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.=ダイヤモンド鉱石は希少で、ワールドの深層近くでまとまって見つかります。 +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.=土はいくつかの植物のための土壌として機能します。明るいところで近くに草や菌糸で覆われたブロックがあれば、このブロックの表層にもそれら成長させることがあります。 +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.=エメラルドは、村人との取引で通貨として使われます。 +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.=薄氷は短命の固形ブロックです。水源の中では数秒で融けてしまいます。 +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.=金のリンゴは貴重な食材で、食べられます。 +Granite=花崗岩 +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.=オフロードは、草原の装飾的なバリエーションです。上部の色が異なり、草原より少し低いので、道にうってつけです。シャベルで作れます。オフロードは、固いブロックの下にあると土になります。 +Gravel=砂利 +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.=エンドの次元では、このブロック上で火を起こすと、永続的な炎が生まれます。 +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.=ジャングルの葉は、ジャングルの木から育ちます。 +Ladder=ハシゴ +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=苔むした石レンガ +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=オークの葉 +Oak Sapling=オークの苗木 +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.=氷塊は、氷が圧縮した形態です。不透明で固形です。 +Paper=紙 +Paper is used to craft books and maps.=紙は、本や地図などのクラフトに使われます。 +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=紫色ガラス +Realm Barrier=領域障壁 +Red Sand=赤い砂 +Red Sandstone=赤い砂岩 +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.=レッドストーン鉱石は、ワールドの低層に多く見られます。それをパンチしたり、踏んだりすると光ります。 +Sand=砂 +Sand is found in large quantities at beaches and deserts.=砂は、海岸や砂漠で大量に見つかります。 +Sandstone=砂岩 +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=滑らかな赤い砂岩 +Smooth Sandstone=滑らかな砂岩 +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=トウヒの葉 +Spruce Sapling=トウヒの苗木 +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.=色ガラスは、そのほとんどが透明な装飾ブロックで、さまざまなカラーバリエーションがあります。 +Stick=棒 +Sticks are a very versatile crafting material; used in countless crafting recipes.=棒は、数え切れないほどのクラフトレシピに使用されている、非常に汎用性の高いクラフト素材です。 +Stone=石 +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 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 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.=これは1ブロックサイズの雪です。この厚さの雪は、おおむね極寒の地で見られます。 +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ブロックの高さまで成長します。サボテンはそれに触れた生物を傷つけます(1HP/0.5秒のダメージ)。サボテンのブロックが壊れると、その上につながっているすべてのサボテンのブロックも壊れます。 +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以上の光源付近で融けます。 +Vines=ツタ +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.=ジャングルの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちジャングルの木に成長します。正方形(2×2)に4本の苗木があると、巨大なジャングルの木に成長します。 +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.=トウヒの苗木は、土壌(土など)の上に置いて光を当てると、しばらくしたのちトウヒの木に成長します。正方形(2×2)に4本の苗木があると、巨大なトウヒの木に成長します。 +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.=「石炭」とは、地中の石炭鉱石を掘って得られる石炭の塊のことを指します。石炭はかまどの燃料として一般的ですが、松明や石炭ブロックなどにも利用されます。 +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.=・水が溶岩の真下にあると、水は石に変化します。 +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).=このブロックは、完全な固体ブロックの上と、別の積雪の上にしか置けません(高さが増えます)。 +Needs soil and water to grow=生育に必要なのは、土壌と水 +Needs soil and light to grow=生育に必要なのは、土壌と光 +Grows on sand=砂の上に生育 +Contact damage: @1 per half second=接触ダメージ:@1/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=スタック可能 +Crying Obsidian=泣く黒曜石 +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=泣く黒曜石は、廃墟のポータルの一部として生成可能な、発光する黒曜石です。 +Enchanted Golden Apple=エンチャントされた金のリンゴ \ No newline at end of file diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr new file mode 100644 index 000000000..669e4bc9b --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pl.tr @@ -0,0 +1,279 @@ +# textdomain: mcl_core +@1 could not survive in lava.=@1 nie przeżyła w lawie. +@1 died in lava.=@1 umarła w lawie. +@1 melted in lava.=@1 stopiła się w lawie. +@1 took a bath in a hot lava tub.=@1 wzięła gorącą kąpiel w wannie z lawą. +A block of diamond is mostly a shiny decorative block but also useful as a compact storage of diamonds.=Blok diamentu jest głównie ładnym blokiem dekoracyjnym, ale jest użyteczny również do kompaktowego przechowywania diamentów. +A block of emerald is mostly a shiny decorative block but also useful as a compact storage of emeralds.=Blok szmaragdu jest głównie ładnym blokiem dekoracyjnym, ale jest użyteczny również do kompaktowego przechowywania szmaragdów. +A block of gold is mostly a shiny decorative block but also useful as a compact storage of gold ingots.=Blok złota jest głównie ładnym blokiem dekoracyjnym, ale jest użyteczny również do kompaktowego przechowywania sztabek złota. +A block of iron is mostly a decorative block but also useful as a compact storage of iron ingots.=Blok żelaza jest głównie ładnym blokiem dekoracyjnym, ale jest użyteczny również do kompaktowego przechowywania sztabek żelaza. +A cactus can only be placed on top of another cactus or any sand.=Kaktus może być postawiony tylko na innym kaktusie lub piasku. +A decorative and mostly transparent block.=Dekoracyjny i głównie przeźroczysty blok. +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.=Blok trawy to blok ziemi z pokryciem z trawy. Bloki trawy są użytecznymi blokami pozwalającymi na wyrośnięcie różnych rodzajów roślin. Mogą zostać zamienione w pole uprawne motyką, lub w ścieżkę z trawy łopatą. Oświetlona trawa rozprzestrzenia się na pobliskie bloki. Pod nieprzezroczystym blokiem lub płynem blok trawy może zamienić się z powrotem w blok ziemi. +A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Blok lazurytu jest głównie ładnym blokiem dekoracyjnym, ale jest użyteczny również do kompaktowego przechowywania lazurytu. +A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Źródło lawy podpala bloki powietrza nad nią gdy są obok łatwopalnego bloku. +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.=Kawałek drabiny, który pozwala ci wspinać się pionowo. Drabina może być postawiona na boku stałego bloku, lecz nie na szkle, liściach, lodzie, półbloku, jasnogłazie ani na latarni morskiej. +Acacia Bark=Akacjowa kora +Acacia Leaves=Akacjowe liście +Acacia Sapling=Akacjowa sadzonka +Acacia Wood=Akacjowe drewno +Acacia Wood Planks=Akacjowe deski +Acacia leaves are grown from acacia trees.=Akacjowe liście rosną na akacjach. +Andesite=Andezyt +Andesite is an igneous rock.=Andezyt jest skałą pochodzenia wulkanicznego. +Apple=Jabłko +Apples are food items which can be eaten.=Jabłka to przedmioty które można zjeść. +Barrier=Bariera +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.=Bariery to niewidzialne bloki po których można chodzić. Są użyteczne do tworzenia ograniczeń na mapach przygodowych i im podobnych. Potwory i zwierzęta nie pojawiają się na barierach, a płoty się z nimi nie łączą. Inne bloki mogą być na nich budowane podobnie jak na innych blokach. +Bedrock=Skała macierzysta +Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Skała macierzysta jest rodzajem bardzo twardej skały. Nie może być ona zniszczona, zebrana lub przesunięta normalnymi metodami, jeśli nie jesteś w trybie kreatywnym. +Birch Bark=Brzozowa kora +Birch Leaves=Brzozowe liście +Birch Sapling=Brzozowa sadzonka +Birch Wood=Brzozowe drewno +Birch Wood Planks=Brzozowe deski +Birch leaves are grown from birch trees.=Brzozowe liście rosną na brzozach. +Black Stained Glass=Czarne szkło +Block of Coal=Blok węgla +Block of Diamond=Blok diamentu +Block of Emerald=Blok szmaragdu +Block of Gold=Blok złota +Block of Iron=Blok żelaza +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.=Bloki węgla są użyteczne do kompaktowego przechowywania diamentów i bardzo użyteczne jako paliwo do pieca. +Blue Stained Glass=Niebieskie szkło +Bone Block=Blok kości +Bone blocks are decorative blocks and a compact storage of bone meal.=Bloki kości są blokami dekoracyjnymi i są użyteczne do kompaktowego przechowywania mączki kostnej. +Bowl=Miska +Bowls are mainly used to hold tasty soups.=Miski są użyteczne do przechowywania smacznych zup. +Brick=Cegła +Brick Block=Blok cegły +Brick blocks are a good building material for building solid houses and can take quite a punch.=Bloki cegły są dobrymi materiałami na budowanie solidnych domów i trzeba się namęczyć by je zniszczyć. +Bricks are used to craft brick blocks.=Cegły są wykorzystywane do wytwarzania bloków cegieł. +Brown Stained Glass=Brązowe szkło +Cactus=Kaktus +Charcoal=Węgiel drzewny +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.=Węgiel drzewny jest alternatywnym paliwem do pieca uzyskiwanym przez wypalanie drewna w piecu. Pali się tak samo długo jak węgiel oraz może być użyty jako zamiennik w wielu recepturach, jednak nie można z niego robić bloków węgla. +Chiseled Stone Bricks=Rzeźbione kamienne cegły +Chiseled Red Sandstone=Rzeźbiony czerwony piaskowiec +Chiseled Sandstone=Rzeźbiony piaskowiec +Chiseled red sandstone is a decorative building block.=Rzeźbiony czerwony piaskowiec jest dekoracyjnym blokiem budowlanym. +Chiseled sandstone is a decorative building block.=Rzeźbiony piaskowiec jest dekoracyjnym blokiem budowlanym. +Clay=Blok gliny +Clay Ball=Glina +Clay balls are a raw material, mainly used to create bricks in the furnace.=Glina jest surowym materiałem głównie wykorzystywanym do wypalania cegieł w piecu. +Clay is a versatile kind of earth commonly found at beaches underwater.=Bloki gliny są użytecznymi blokami ziemi często występującymi na plażach pod wodą. +Coal=Węgiel +Coal Ore=Ruda węgla +Coarse Dirt=Twarda ziemia +Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=Twarda ziemia jest podłożem dla niektórych roślin i jest podobna do ziemi, jednak nie rośnie na niej trawa. +Cobblestone=Brukowiec +Cobweb=Pajęczyna +Cobwebs can be walked through, but significantly slow you down.=Przez pajęczyny można przechodzić, jednak bardzo cię spowolnią. +Cracked Stone Bricks=Popękane kamienne cegły. +Cut Red Sandstone=Przycięty czerwony piaskowiec +Cut Sandstone=Przycięty piaskowiec +Cut red sandstone is a decorative building block.=Przycięty czerwony piaskowiec jest dekoracyjnym blokiem budowlanym. +Cut sandstone is a decorative building block.=Przycięty piaskowiec jest dekoracyjnym blokiem budowlanym. +Cyan Stained Glass=Błękitne szkło +Dark Oak Bark=Ciemno-dębowa kora +Dark Oak Leaves=Ciemno-dębowe liście +Dark Oak Sapling=Ciemno-dębowa sadzonka +Dark Oak Wood=Ciemno-dębowe drewno +Dark Oak Wood Planks=Ciemno-dębowe deski +Dark oak leaves are grown from dark oak trees.=Ciemno-dębowe liście rosną na ciemnych dębach. +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.=Ciemno-dębowe sadzonki mogą wyrosnąć w ciemny dąb, ale tylko w grupach. Samotna ciemno-dębowa sadzonka nie wyrośnie. Grupa czterech ciemno-dębowych sadzonek wyrośnie w ciemny dąb po jakimś czasie, gdy będą postawiona na glebie (np. ziemi) w kwadracie 2×2, która jest oświetlona. +Dead Bush=Uschnięty krzew +Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=Uschnięte krzewy to niewyróżniające się rośliny często występujące w suchych obszarach. Mogą z nich być zebrane patyki. +Diamond=Diament +Diamond Ore=Ruda diamentu +Diamond ore is rare and can be found in clusters near the bottom of the world.=Ruda diamentu jest rzadko występującym blokiem, który można znaleźć w grupach przy dnie świata. +Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Diamenty to cenne minerały wykorzystywane do wytwarzania najwyższej jakości zbroi i narzędzi. +Diorite=Dioryt. +Diorite is an igneous rock.=Dioryt jest skałą pochodzenia wulkanicznego. +Dirt=Ziemia +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.=ziemia jest podłożem dla niektórych roślin. Gdy jest oświetlona może na niej wyrosnąć trawa bądź grzybnia, jeśli takie bloki są w pobliżu. +Emerald=Szmaragd +Emerald Ore=Ruda szmaragdu +Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach. +Emeralds are used in villager trades as currency.= +Flint=Krzemień +Flint is a raw material.=Krzemień jest surowym materiałem. +Flowing Lava=Płynąca lawa +Flowing Water=Płynąca woda +Frosted Ice=Oszroniony lód +Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=Oszroniony lód jest blokiem o krótkim życiu. Topi się w źródło wody w kilka sekund. +Glass=Szkło +Gold Ingot=Sztabka złota +Gold Nugget=Bryłka złota +Gold Ore=Ruda złota +Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=Bryłki złota są bardzo małymi kawałkami stopionego złota. Ich głównym zastosowaniem jest tworzenie sztabek złota. +Golden Apple=Złote jabłko +Golden apples are precious food items which can be eaten.=Złote jabłka są cennym jedzeniem, które można zjeść. +Granite=Granit +Grass Block=Blok trawy +Grass Path=Ścieżka trawy +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.=Ścieżki trawy są dekoracyjną wersją bloków trawy. Ich góra ma inny kolor i są nieco niższe niż bloki trawy, przez co są użyteczne do wyznaczania ścieżek. Ścieżki trawy mogą zostać stworzone łopatą. Ścieżka trawy zamienia się w ziemię gdy jest pod stałym blokiem. +Gravel=Żwir +Green Stained Glass=Zielone szkło +Grey Stained Glass=Szare szkło +Ice=Lód +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.=Lód jest stałym blokiem zwykle występującym w zimnych rejonach. Topi się w okolice źródeł światła przy poziomie oświetlenia 12 lub wyższym. Gdy się stopi bądź jest zniszczony na innym bloku zamienia się w źródło wody. +In the End dimension, starting a fire on this block will create an eternal fire.=W wymiarze Kresu rozpalenie ognia na tym bloku stworzy wieczny ogień. +Iron Ingot=Sztabka żelaza +Iron Nugget=Bryłka żelaza +Iron Ore=Ruda żelaza +Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Bryłki żelaza są bardzo małymi kawałkami stopionego żelaza. Ich głównym zastosowaniem jest tworzenie sztabek żelaza. +Jungle Bark=Tropikalna kora +Jungle Leaves=Tropikalne liście +Jungle Sapling=Tropikalna sadzonka +Jungle Wood=Tropikalne drewno +Jungle Wood Planks=Tropikalne deski +Jungle leaves are grown from jungle trees.=Tropikalne liście rosną na tropikalnych drzewach. +Ladder=Drabina +Lapis Lazuli=Lazuryt +Lapis Lazuli are required for enchanting items on an enchanting table.=Lapis Lazuli są wymagane do zaklinania przedmiotów na zaklinającym stole. +Lapis Lazuli Block=Blok lazurytu +Lapis Lazuli Ore=Ruda lazurytu +Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Ruda lazurytu jest rzadko występującym blokiem, który można znaleźć w grupach przy dnie świata. +Lava Source=Źródło lawy +Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=Lawa jest gorąca i bardzo niebezpieczna. Nie dotykaj jej, jeśli nie chcesz ucierpieć. Trudno się z niej wydostać. +Light Blue Stained Glass=Jasnoniebieskie szkło +Light Grey Stained Glass=Jasnoszare szkło +Lime Stained Glass=Jasnozielone szkło +Lit Redstone Ore=Świecąca ruda czerwienitu +Magenta Stained Glass=Karmazynowe szkło +Molten gold. It is used to craft armor, tools, and whatnot.=Stopione złoto. Wykorzystywane do wytwarzania zbroi, narzędzi i innych. +Molten iron. It is used to craft armor, tools, and whatnot.=Stopione żelazo. Wykorzystywane do wytwarzania zbroi, narzędzi i innych. +Mossy Cobblestone=Zamszony bruk +Mossy Stone Bricks=Zamszone kamienne cegły +Mycelium=Grzybnia +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.=Grzybnia jest rodzajem ziemi i idealnym podłożem dla grzybów. W przeciwieństwie do innych bloków ziemi nie może ona zostać zamieniona w pole uprawne motyką. Oświetlona grzybnia powoli rozprzestrzenia się na pobliską ziemię. Pod nieprzezroczystym blokiem bądź płynem po pewnym czasie zamieni się z powrotem w ziemię. +Oak Bark=Dębowa kora +Oak Leaves=Dębowe liście +Oak Sapling=Dębowe sadzonki +Oak Wood=Dębowe drewno +Oak Wood Planks=Dębowe deski +Oak leaves are grown from oak trees.=Dębowe liście rosną na dębach. +Obsidian=Obsydian +Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava.=Obsydian jest bardzo twardym minerałem o ogromnej odporności na wybuchy. Obsydian powstaje gdy woda styka się z lawą. +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.=Jeden z najpowszechniejszych bloków na świecie, prawie całe podziemia składają się z kamienia. Czasami zawiera rudy. Kamień może być utworzony czy woda styka się z lawą. +Orange Stained Glass=Pomarańczowe szkło +Packed Ice=Zbity lód +Packed ice is a compressed form of ice. It is opaque and solid.=Zbity lód jest skompresowaną formą lodu. Jest nieprzezroczysty i stały. +Paper=Papier +Paper is used to craft books and maps.=Papier jest wykorzystywany do wytwarzania książek i map. +Pink Stained Glass=Różowe szkło +Podzol=Bielica +Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Bielica jest typem ziemi w tajgach. Tylko niektóre rośliny są w stanie na niej przeżyć. +Polished Andesite=Wypolerowany andezyt +Polished Diorite=Wypolerowany dioryt +Polished Granite=Wypolerowany granit +Polished Stone=Wypolerowany kamień +Polished andesite is a decorative building block made from andesite.=Wypolerowany andezyt jest dekoracyjnym blokiem budowlanym tworzonym z andezytu. +Polished diorite is a decorative building block made from diorite.=Wypolerowany dioryt jest dekoracyjnym blokiem budowlanym tworzonym z diorytu. +Polished granite is a decorative building block made from granite.=Wypolerowany granit jest dekoracyjnym blokiem budowlanym tworzonym z granitu. +Purple Stained Glass=Fioletowe szkło +Realm Barrier=Bariera wymiarów +Red Sand=Czerwony piasek +Red Sandstone=Czerwony piaskowiec +Red Stained Glass=Czerwone szkło +Red sand is found in large quantities in mesa biomes.=Czerwony piasek występuje w dużych ilościach w Badlandach. +Red sandstone is compressed red sand and is a rather soft kind of stone.=Czerwony piaskowiec jest skompresowanym czerwonym piaskiem i jest miękkim rodzajem kamienia. +Redstone Ore=Ruda czerwienitu +Redstone ore is commonly found near the bottom of the world. It glows when it is punched or walked upon.=Ruda czerwienitu występuje często w okolicy dna świata. Świeci gdy się ją uderzy bądź gdy się po niej chodzi. +Sand=Piasek +Sand is found in large quantities at beaches and deserts.=Piasek występuje w dużych ilościach na plażach i pustyniach. +Sandstone=Piaskowiec +Sandstone is compressed sand and is a rather soft kind of stone.=Piaskowiec jest skompresowanym piaskiem i jest miękkim rodzajem kamienia. +Slime Block=Blok szlamu +Slime blocks are very bouncy and prevent fall damage.=Bloki szlamu są bardzo sprężyste i pomagają uniknąć obrażeń od upadku. +Smooth Red Sandstone=Gładki czerwony piaskowiec +Smooth Sandstone=Gładki piaskowiec +Smooth red sandstone is a decorative building block.=Gładki czerwony piaskowiec jest dekoracyjnym blokiem budowlanym. +Smooth sandstone is compressed sand and is a rather soft kind of stone.=Gładki piaskowiec skompresowanym piaskiem i jest miękkim rodzajem kamienia. +Snow=Śnieg +Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Trochę węgla zawartego w kamieniu. Jest bardzo częste i można to znaleźć w kamieniu w średnich i dużych grupach na niemal każdej wysokości. +Some iron contained in stone, it is prety common and can be found below sea level.=Trochę żelaza zawartego w kamieniu. Jest bardzo częste i można to znaleźć w kamieniu poniżej poziomu morza. +Spruce Bark=Świerkowa kora +Spruce Leaves=Świerkowe liście +Spruce Sapling=Świerkowa sadzonka +Spruce Wood=Świerkowe drewno +Spruce Wood Planks=Świerkowe deski +Spruce leaves are grown from spruce trees.=Świerkowe liście rosną na świerkach. +Stained glass is a decorative and mostly transparent block which comes in various different colors.=Kolorowe szkło jest dekoracyjnym, przejrzystym blokiem. Istnieją różnokolorowe warianty tego bloku. +Stick=Patyk +Sticks are a very versatile crafting material; used in countless crafting recipes.=Patyk jest wszechstronnym materiałem do wytwarzania, wykorzystywanym w niezliczonej liczbie receptur. +Stone=Kamień +Stripped Acacia Log=Okorowany pień akacji +Stripped Acacia Wood=Okorowane drewno akacji +Stripped Birch Log=Okorowany pień brzozy +Stripped Birch Wood=Okorowane drewno brzozy +Stripped Dark Oak Log=Okorowany pień ciemnego dębu +Stripped Dark Oak Wood=Okorowane drewno ciemnego dębu +Stripped Jungle Log=Okorowany pień tropikalnego drzewa +Stripped Jungle Wood=Okorowane drewno tropikalnego drzewa +Stripped Oak Log=Okorowany pień dębu +Stripped Oak Wood=Okorowane drewno dębu +Stripped Spruce Log=Okorowany pień świerku +Stripped Spruce Wood=Okorowane drewno świerku +Stone Bricks=Kamienne cegły +Sugar=Cukier +Sugar Canes=Trzcina cukrowa +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.=Trzciny cukrowe są rośliny użyteczne w wytwarzaniu. Będą one powoli rosły na wysokość 3 bloków, gdy są postawione obok wody i są postawione na bloku trawy, ziemi, piasku, czerwonego piasku, bielicy lub twardej ziemi. Gdy trzcina cukrowa jest zniszczona wszystkie połączone trzciny nad nią również się zniszczą. +Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Trzciny cukrowe mogą być posadzone tylko na innych trzcinach cukrowych i na blokach na których by wyrosły. +Sugar comes from sugar canes and is used to make sweet foods.=Cukier wytwarza się z trzciny cukrowej i wykorzystuje się go do robienia słodkich potraw. +The stripped trunk of an acacia tree.=Okorowany pień drzewa akacji. +The stripped trunk of an birch tree.=Okorowany pień drzewa brozy. +The stripped trunk of an dark oak tree.=Okorowany pień drzewa ciemnego dębu. +The stripped trunk of an jungle tree.=Okorowany pień drzewa tropikalnego. +The stripped trunk of an oak tree.=Okorowany pień drzewa dębu. +The stripped trunk of an spruce tree.=Okorowany pień drzewa świerkowego. +The trunk of a birch tree.=Pień brzozy. +The trunk of a dark oak tree.=Pień ciemnego dębu. +The trunk of a jungle tree.=Pień tropikalnego drzewa. +The trunk of a spruce tree.=Pień świerka. +The trunk of an acacia.=Pień akacji. +The trunk of an oak tree.=Pień dębu. +This block consists of a couple of loose stones and can't support itself.=Ten blok składa się z kilku luźnych kamieni i nie może się utrzymać. +This is a decorative block surrounded by the bark of a tree trunk.=Jest to dekoracyjny blok otoczony przez korę pnia. +This is a decorative block.=Jest to blok dekoracyjny. +This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=To jest pełny blok śniegu. Śnieg tej grubości występuje zwykle w ekstremalnie niskich obszarach. +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.=To jest kawałek kaktusa często występujący w suchych obszarach, zwłaszcza pustyniach. Po pewnym czasie kaktusy rosną na wysokość 3 bloków na piasku lub czerwonym piasku. Kaktus rani żywe istoty dotykające go zadając 1 HP obrażeń na pół sekundy. Gdy blok kaktusa jest zniszczony wszystkie bloki kaktusa nad nim również zostaną zniszczone. +This stone contains pure gold, a rare metal.=Ten kamień zawiera czyste złoto, rzadki metal. +Top Snow=Pokrywa śniegu +Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=Pokrywa śniegu jest warstwą śniegu. Topi się przy źródłach światła innych niż słońce o poziomie oświetlenia 12 lub wyższym. +Vines=Pnącza +Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Pnącza są blokami po których można się wspinać i które można postawić na bokach stałych pełnych bloków. +Void=Otchłań +Water=Woda +Water Source=Źródło wody +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.=Wody jest dużo w oceanach i pojawia się też w strumykach na ziemi. Możesz łatwo pływać w wodzie, ale nie zapominaj od czasu do czasu złapać oddechu. +When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=Z położonej na glebie (np. ziemi) i oświetlonej brzozowej sadzonki po pewnym czasie wyrośnie brzoza. +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.=Z położonej na glebie (np. ziemi) i oświetlonej tropikalnej sadzonki po pewnym czasie wyrośnie drzewo tropikalne. Jeśli 4 tropikalne sadzonki są posadzone w kwadracie 2×2 wyrośnie z nich duże drzewo tropikalne. +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.=Z położonej na glebie (np. ziemi) i oświetlonej świerkowej sadzonki po pewnym czasie wyrośnie świerk. Jeśli 4 tropikalne sadzonki są posadzone w kwadracie 2×2 wyrośnie z nich duży świerk. +When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=Z położonej na glebie (np. ziemi) i oświetlonej akacjowej sadzonki po pewnym czasie wyrośnie akacja. +When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=Z położonej na glebie (np. ziemi) i oświetlonej dębowej sadzonki po pewnym czasie wyrośnie dąb. +When you hold a barrier in hand, you reveal all placed barriers in a short distance around you.=Gdy w ręce trzymasz barierę będziesz w stanie dostrzec wszystkie bariery w niewielkiej odległości. +White Stained Glass=Białe szkło +Yellow Stained Glass=Żółte szkło +“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.="Węgiel" odnosi się tutaj do kawałków węgla zdobytych przez wykopanie rudy węgla występującej pod ziemią. Węgiel jest standardowym paliwem do pieca, ale może być również wykorzystany do tworzenia pochodni, bloków węgla i kilku innych rzeczy. +Water interacts with lava in various ways:=Woda wchodzi w interakcję z lawą na kilka sposobów: +• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=• Gdy woda jest bezpośrednio nad lub poziomo obok źródła lawy, lawa zamienia się w obsydian. +• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.=• Gdy płynąca woda zetknie się z lewą, z góry lub z boku, lawa zamienia się w brukowiec. +• When water is directly below lava, the water turns into stone.=Gdy woda jest bezpośrednio pod lawą, woda zamienia się w kamień. +Lava interacts with water various ways:=Lawa wchodzi w interakcję z wodą na różne sposoby: +• When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Gdy źródło lawy jest bezpośrednio pod lub poziomo obok wody, lawa zamienia się w obsydian. +• When lava is directly above water, the water turns into stone.=• Gdy lawa jest bezpośrednio nad wodą, woda zamienia się w kamień. +Stained Glass=Kolorowe szkło +Granite is an igneous rock.=Granit jest skałą pochodzenia wulkanicznego. +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.=Pokrywa śniegu może być układana w stos i ma 8 poziomów wysokości. Na poziomach 2-8 pokrywa jest przeszkodą. Z pokrywy śniegu wypada 2-9 kulek w zależności od jej wysokości. +This block can only be placed on full solid blocks and on another top snow (which increases its height).=Ten blok może być postawiony wyłącznie na pełnych stałych blokach i na innej pokrywie śniegu (co zwiększy jej wysokość). +Needs soil and water to grow=Potrzebuje gleby i wody by rosnąć +Needs soil and light to grow=Potrzebuje gleby i światła by rosnąć +Grows on sand=Rośnie na piasku +Contact damage: @1 per half second=Obrażenia dotykowe: @1 na pół sekundy +Slows down movement=Spowalnia poruszanie +2×2 saplings required=Wymagane . +2×2 saplings @= large tree=Sadzonki 2×2 @= duże drzewo. +Grows on sand or dirt next to water=Rośnie na piasku bądź ziemi obok wody. +Stackable=Możliwe grupowanie diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.pt_BR.tr b/mods/ITEMS/mcl_core/locale/mcl_core.pt_BR.tr new file mode 100644 index 000000000..e9091287d --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.pt_BR.tr @@ -0,0 +1,287 @@ +# textdomain: mcl_core +@1 could not survive in lava.=@1 não conseguiu sobreviver na lava. +@1 died in lava.=@1 morreu na lava. +@1 melted in lava.=@1 foi derretido na lava. +@1 took a bath in a hot lava tub.=@1 tomo um banho em uma banheira de lava quente. +A block of diamond is mostly a shiny decorative block but also useful as a compact storage of diamonds.=Um bloco de diamante é principalmente um bloco decorativo brilhante, mas também é útil para armazenar diamantes de forma compacta. +A block of emerald is mostly a shiny decorative block but also useful as a compact storage of emeralds.=Um bloco de esmeralda é principalmente um bloco decorativo brilhante, mas também é útil para armazenar esmeraldas de forma compacta. +A block of gold is mostly a shiny decorative block but also useful as a compact storage of gold ingots.=Um bloco de ouro é principalmente um bloco decorativo brilhante, mas também é útil para armazenar ouro de forma compacta. +A block of iron is mostly a decorative block but also useful as a compact storage of iron ingots.=Um bloco de ferro é principalmente um bloco decorativo brilhante, mas também é útil para armazenar ferro de forma compacta. +A cactus can only be placed on top of another cactus or any sand.=Um cacto só pode ser colocado em cima de outro cacto ou em qualquer areia. +A decorative and mostly transparent block.=Um bloco decorativo e na maior parte transparente. +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.=Um bloco de grama é um bloco de terra com cobertura de grama. Blocos de gramas são recursos que permitem o crescimento de qualquer tipo de planta. Eles podem se tornar terras aradas com uma enxada e em caminhos com uma pá. Sob a luz, a grama lentamente se espalha em blocos de terra próximos. Sob um bloco opaco ou um líquido, um bloco de grama pode se tornar em um bloco de terra. +A lapis lazuli block is mostly a decorative block but also useful as a compact storage of lapis lazuli.=Um bloco de lápis-lazuli é principalmente um bloco decorativo brilhante, mas também é útil para armazenar lápis-lazuli de forma compacta. +A lava source sets fire to a couple of air blocks above when they're next to a flammable block.=Uma fonte de lava incendeia alguns blocos de ar acima quando estão próximos de um bloco inflamável. +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.=Um pedaço de escada que lhe permite escalar verticalmente. Escadas só podem ser colocadas na face de um bloco sólido e naão em vidros, folhas, gelo, lajes, glowstone e nem em lanternas marinhas. +Acacia Bark=Casca de Acácia +Acacia Leaves=Folhas de Acácia +Acacia Sapling=Muda de Acácia +Acacia Wood=Madeira de Acácia +Acacia Wood Planks=Tábuas de Acácia +Acacia leaves are grown from acacia trees.=Folhas de acácia crescem a partir de árvores de acácia. +Andesite=Andesito +Andesite is an igneous rock.=Andesito é uma rocha ígnea. +Apple=Maçã +Apples are food items which can be eaten.=Maçãs são itens alimentícios que podem ser comidos. +Barrier=Barreira +Barriers are invisble 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.=Barreiras são blocos invisíveis que podem ser caminhados. Eles são usados para criar barreiras em mapas de aventura e similares. Monstros ou animais não aparecerão nas barreiras e cercas não se conectarão com elas. Outros blocos podem ser construídos sob barreiras como qualquer outro bloco. +Bedrock=Rocha-mãe +Bedrock is a very hard type of rock. It can not be broken, destroyed, collected or moved by normal means, unless in Creative Mode.=Rochas-mãe são um tipo muito duro de rochas. Elas não podem ser quebradas, destruídas, coletadas ou movidas por meios normais, a não ser no Modo Criativo. +Birch Bark=Casca de Bétula +Birch Leaves=Folhas de Bétula +Birch Sapling=Muda de Bétula +Birch Wood=Madeira de Bétula +Birch Wood Planks=Tábuas de Bétula +Birch leaves are grown from birch trees.=Folhas de bétula crescem a partir de árvores de bétula. +Black Stained Glass=Vidro Tingido de Preto +Block of Coal=Bloco de Carvão +Block of Diamond=Bloco de Diamante +Block of Emerald=Bloco de Esmeralda +Block of Gold=Bloco de Ouro +Block of Iron=Bloco de Ferro +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.=Blocos de carvão são úteis para armzenad carvão de forma compacta e muito úteis como combustível de fornalas. Um bloco de carvão é tão eficiente quanto 10 carvões. +Blue Stained Glass=Vidro Tingido de Azul +Bone Block=Bloco de Osso +Bone blocks are decorative blocks and a compact storage of bone meal.=Blocos de osso são blocos decorativos e uma forma compacta de armazenar farinha de osso. +Bowl=Tigela +Bowls are mainly used to hold tasty soups.=Tigelas são utilizadas principalmente para segurar sopas deliciosas. +Brick=Tijolo +Brick Block=Bloco de Tijolo +Brick blocks are a good building material for building solid houses and can take quite a punch.=Blocos de tijolo são bons materiais de construção para a construção de casas sólidas e que podem aguentar a porrada. +Bricks are used to craft brick blocks.=Tijolos são usados para fabricar blocos de tijolo. +Brown Stained Glass=Vidro Tingido de Marrom +Cactus=Cacto +Charcoal=Carvão Vegetal +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.=Carvão vegetal é um combustível alternativo de fornalha produzido ao cozinhar madeira em uma fornalha. Possui o mesmo tempo de queima que o carvão e também compartilha diversas receitas de fabricação, mas não pode ser usado para fabricar blocos de carvão. +Chiseled Stone Bricks=Tijolo de Rocha Cinzelado +Chiseled Red Sandstone=Arenito Vermelho Cinzelado +Chiseled Sandstone=Arenito Cinzelado +Chiseled red sandstone is a decorative building block.=Arenito vermelho cinzelado é um bloco de construção decorativo. +Chiseled sandstone is a decorative building block.=Arenito cinzelado é um bloco de construção decorativo. +Clay=Argila +Clay Ball=Bola de Argila +Clay balls are a raw material, mainly used to create bricks in the furnace.=Bolas de argila são materiais não processados, principalmente utilizados para fabricar tijolos quando cozidos. +Clay is a versatile kind of earth commonly found at beaches underwater.=Argila é um tipo de terra versátil comumente encontrado em praias e submerso. +Coal=Carvão +Coal Ore=Minério de Carvão +Coarse Dirt=Terra Infértil +Coarse dirt acts as a soil for some plants and is similar to dirt, but it will never grow a cover.=Terra infértil age como solo para algums plantas e é similar à terra, mas nunca crescerá uma cobertura. +Cobblestone=Pedregulho +Cobweb=Teia de Aranha +Cobwebs can be walked through, but significantly slow you down.=Teias de aranha podem ser atravessadas, mas reduzindo significativamente sua velocidade. +Cracked Stone Bricks=Tijolo de Rocha Rachado +Cut Red Sandstone=Arenito Vermelho Cortado +Cut Sandstone=Arenito Cortado +Cut red sandstone is a decorative building block.=Arenito vermelho cortado é um bloco de construção decorativo. +Cut sandstone is a decorative building block.=Arenito cortado é um bloco de construção decorativo. +Cyan Stained Glass=Vidro Tingido de Ciano +Dark Oak Bark=Casca de Carvalho Escuro +Dark Oak Leaves=Folhas de Carvalho Escuro +Dark Oak Sapling=Muda de Carvalho Escuro +Dark Oak Wood=Madeira de Carvalho Escuro +Dark Oak Wood Planks=Tábuas de Carvlho Escuro +Dark oak leaves are grown from dark oak trees.=Folhas de carvalho escuro crescem em árvores de carvalho escuro. +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.=Mudas de carvalho escuro podem se tornar carvalhos escuro, mas apenas em grupo. Uma muda de carvalho escuro solitária não crescerá. Um grupo de quatro mudas de carvalho escuro crescem em uma árvore de carvalho escuro após um tempo em um quadrado de 2x2 sendo expostas à luz. +Dead Bush=Arbusto Morto +Dead bushes are unremarkable plants often found in dry areas. They can be harvested for sticks.=Arbustos mortos são plantas normais comumente encontradas em áreas secas. Podem ser colhidas na forma de gravetos. +Diamond=Diamante +Diamond Ore=Minério de Diamante +Diamond ore is rare and can be found in clusters near the bottom of the world.=Minérios de diamante são raros e podem ser encontrados em aglomerados perto do fundo do mundo. +Diamonds are precious minerals and useful to create the highest tier of armor and tools.=Diamantes são minerais preciosos e úteis para criar as armaduras e ferramentas do mais alto nível. +Diorite=Diorito +Diorite is an igneous rock.=Diorito é uma rocha ígnea. +Dirt=Terra. +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.=Terra atua como solo para algumas plantas. Quando sob a luz, esse bloco pode crescer grama ou uma cobertura de micélio se tais blocos estão próximos. +Emerald=Esmeralda +Emerald Ore=Minério de Esmeralda +Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Minério de esmeralda é o minério das esmeraldas. É raro e podem ser encontrados solitários, não em aglomerados. +Emeralds are used in villager trades as currency.=Esmeraldas são utilizadas nas trocas como aldeões na forme de moeda. +Flint=Sílex +Flint is a raw material.=Sílex é um material não processado. +Flowing Lava=Lava Fluíndo +Flowing Water=Água Fluíndo +Frosted Ice=Gelo Fosco +Frosted ice is a short-lived solid block. It melts into a water source within a few seconds.=Gelo fosco é um bloco sólido de vida curta. Ele derrete em uma fonte de água após alguns segundos. +Glass=Vidro +Gold Ingot=Lingote de Ouro +Gold Nugget=Pepita de Ouro +Gold Ore=Minério de Ouro +Gold nuggets are very small pieces of molten gold; the main purpose is to create gold ingots.=Pepitas de ouro são pequenas peças de ouro fundido; sua principal finalidade é criar lingotes de ouro. +Golden Apple=Maçã Dourada +Golden apples are precious food items which can be eaten.=Maçãs douradas são alimentos preciosos que podem ser consumidos. +Granite=Granito +Grass Block=Bloco de Grama +Grass Path=Caminho de Grama +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.=Caminhos de gramas são variantes decorativas do bloco de grama. Seu topo possui diferentes cores e são um pouco mais baixos que blocos de grama, tornando-os úteis para construír trilhas. Caminhos de grama se tornam terra quando é colocado abaixo de um bloco sólido. +Gravel=Cascalho +Green Stained Glass=Vidro Tingido de Verde +Grey Stained Glass=Vidro Tingido de Cinza +Ice=Gelo +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.=Gelo é um bloco sólido normamente encontrado em áreas frias. Ele derrete quando próximo de um bloco luminoso sob um nível de luz 12 ou superior. Quando derrete ou é quebrado enquanto acima de um bloco, se torna em uma fonte de água. +In the End dimension, starting a fire on this block will create an eternal fire.=Na dimensão do End, começar um fogo nesse bloco criará um fogo eterno. +Iron Ingot=Lingote de Ferro +Iron Nugget=Pepita de Ferro +Iron Ore=Minério de Ferro +Iron nuggets are very small pieces of molten iron; the main purpose is to create iron ingots.=Pepitas de ferro são pequenas peças de ferro fundido; seu principal propósito é na criação de lingotes de ferro. +Jungle Bark=Casca da Selva +Jungle Leaves=Folhas da Selva +Jungle Sapling=Mudas da Selva +Jungle Wood=Madeira da Selva +Jungle Wood Planks=Tábuas da Selva +Jungle leaves are grown from jungle trees.=Folhas da selva crescem em árvores da selva. +Ladder=Escada +Lapis Lazuli Block=Bloco de Lápis-lazuli +Lapis Lazuli Ore=Minério de Lápis-lazuli +Lapis lazuli ore is the ore of lapis lazuli. It can be rarely found in clusters near the bottom of the world.=Minerios de lápis-lazuli são o minério que contém lápis-lazuli. Pode ser encontrado raramente em aglomerados perto do fundo do mundo. +Lava Source=Fonte de Lava +Lava is hot and rather dangerous. Don't touch it, it will hurt you a lot and it is hard to get out.=Lava é quente e um tanto quanto perigosa. Não a toque, irá te queimar muito e será dificil sair. +Light Blue Stained Glass=Vidro Tingido de Azul Claro +Light Grey Stained Glass=Vidro Tingido de Cinza Claro +Lime Stained Glass=Vidro Tingido de Lima +Lit Redstone Ore=Minério de Redstone Aceso +Magenta Stained Glass=Vidro Tingido de Magenta +Molten gold. It is used to craft armor, tools, and whatnot.=Ouro fundido. É usado para fabricar armaduras, ferramentas e o que não. +Molten iron. It is used to craft armor, tools, and whatnot.=Ferro fundido. É usado para fabricar armaduras, ferramentas e o que não. +Mossy Cobblestone=Pedregulho Musgoso +Mossy Stone Bricks=Tiolos de Rocha Musgosos +Mycelium=Micélio +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.=Micélio é um tipo de terra e é o solo ideal para cogumelos. Diferente de outros tipos de blocos de terra, ele não pode ser convertido em terra arada com uma enxada. Sob a luz, micélio lentamente se espalha sobre outros blocos de terra próximos. Sob um bloco opaco ou um líquido, eventualmente se torna terra. +Oak Bark=Casca de Carvalho +Oak Leaves=Folhas de Carvalho +Oak Sapling=Muda de Carvalho +Oak Wood=Madeira de Carvalho +Oak Wood Planks=Tábuas de Carvalho +Oak leaves are grown from oak trees.=Folhas de carvalho crescem a partir de árvores de carvalho. +Obsidian=Obsidiana +Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava.=Obsidiana é um mineral extremamente duro com uma enorme resistência a explosões. Obsidiana é formada quando a água encontra com a 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.=Um dos blocos mais comuns do mundo, o subsolo consiste quase que na integridade de rocha. Algumas vezes contém minérios. Rochas podem ser criadas quando a água entra em contato com a lava. +Orange Stained Glass=Vidro Tingido de Laranja +Packed Ice=Gelo Compactado +Packed ice is a compressed form of ice. It is opaque and solid.=Gelo compactado é uma forma comprimida de gelo. É um bloco opaco e sólido. +Paper=Papel +Paper is used to craft books and maps.=Papel é utilizado para fabricar livros e mapas. +Pink Stained Glass=Vidro Tingido de Rosa +Podzol=Podzol +Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it.=Podzol é um tpo de terra encontrado em florestas de taiga. Apenas algumas plantas conseguem sobreviver nele. +Polished Andesite=Andesito Polido +Polished Diorite=Diorito Polido +Polished Granite=Granito Polido +Polished Stone=Rocha Polida +Polished andesite is a decorative building block made from andesite.=Andesito polido é um bloco de construção decorativo feito a partir de andesito. +Polished diorite is a decorative building block made from diorite.=Diorito polido é um bloco de construção decorativo feito a partir de diorito. +Polished granite is a decorative building block made from granite.=Granito polido é um bloco de construção decorativo feito a partir de granito. +Purple Stained Glass=Vidro Tingido de Roxo +Realm Barrier=Barreira de Mundo +Red Sand=Areia Vermelha +Red Sandstone=Arenito Vermelho +Red Stained Glass=Vidro Tingido de Vermelho +Red sand is found in large quantities in mesa biomes.=Areia vermelha é encontrada em grandes quantidades nos biomes de mesa. +Red sandstone is compressed red sand and is a rather soft kind of stone.=Arenito vermelho é areia vemelha comprimida e é um tipo mais macio de rocha. +Redstone Ore=Minério de Redstone +Redstone ore is commonly found near the bottom of the world. It glows when it is punched or walked upon.=Minério de redstone é comumente encontrado próximo a superfície do mundo. +Sand=Areia +Sand is found in large quantities at beaches and deserts.=Areia é encontrada em grande quantidade em praias e desertos. +Sandstone=Arenito +Sandstone is compressed sand and is a rather soft kind of stone.=Arenito é areia comprimida e é um tipo mais macio de rocha. +Slime Block=Bloco de Slime +Slime blocks are very bouncy and prevent fall damage.=Blocos de slime são bastante saltitantes e previnem dano de queda. +Smooth Red Sandstone=Arenito Vermelho Liso +Smooth Sandstone=Arenito Liso +Smooth red sandstone is a decorative building block.=Arenito vemelho liso é um bloco de construção decorativo +Smooth sandstone is compressed sand and is a rather soft kind of stone.=Arenito liso é um bloco de construção decorativo +Snow=Neve +Some coal contained in stone, it is very common and can be found inside stone in medium to large clusters at nearly every height.=Algum carvão contigo na rocha, é bem comum e pode ser encontrado dentro de rochas em aglomerados médios a grantes a praticamente qualquer altitude. +Some iron contained in stone, it is prety common and can be found below sea level.=Algum ferro contido na rocha, é relativamente comum e pode ser encontrado abaixo do nível do mar. +Spruce Bark=Casca de Pinheiro +Spruce Leaves=Folhas de Pinheiro +Spruce Sapling=Muda de Pinheiro +Spruce Wood=Madeira de Pinheiro +Spruce Wood Planks=Tábuas de Pinheiro +Spruce leaves are grown from spruce trees.=Folhas de pinheiro crescem a partir de árvores de pinheiro. +Stained glass is a decorative and mostly transparent block which comes in various different colors.=Vidro tingido é um bloco decorativo majoritariamente transparente e que possui diferentes colorações. +Stick=Graveto +Sticks are a very versatile crafting material; used in countless crafting recipes.=Gravetos são materiais de fabricação muito versáteis; usados em inumeráveis receitas de fabricação. +Stone=Rocha +Stripped Acacia Log=Tronco de Acácia Descascado +Stripped Acacia Wood=Madeira de Acácia Descascada +Stripped Birch Log=Tronco de Bétula Descascado +Stripped Birch Wood=Madeira de Bétula Descascada +Stripped Dark Oak Log=Tronco de Carvalho Escuro Descascado +Stripped Dark Oak Wood=Madeira de Carvalho Escuro Descascada +Stripped Jungle Log=Tronco da Selva Descascado +Stripped Jungle Wood=Madeira da Selva Descascada +Stripped Oak Log=Tronco de Carvalho Descascado +Stripped Oak Wood=Madeira de Carvalho Descascada +Stripped Spruce Log=Tronco de Pinheiro Descascado +Stripped Spruce Wood=Madeira de Pinheiro Descascada +Stone Bricks=Tijolo de Rocha +Sugar=Açúcar +Sugar Canes=Cana de Açúcar +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.= +Canas de açúcar são plantas que possui alguns usos em fabricações. Canas de açúcar crescerão lentamente até 3 blocos quando estão próximas da água e são colocadas em blocos de grama, terra, areia, areia vermelha, podzol ou terra infértil. +Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow.=Canas de açúcar só podem ser colocados emcima de outras canas de açúcar ou sobre blocos em qual elas podem crescer. +Sugar comes from sugar canes and is used to make sweet foods.=Açúcar vem de canas de açúcar e é utilizado para fazer doces comidas. +The stripped trunk of an acacia tree.=O tronco descascado de uma acácia. +The stripped trunk of a birch tree.=O tronco descascado de uma bétula. +The stripped trunk of a dark oak tree.=O tronco descascado de um carvalho escuro. +The stripped trunk of a jungle tree.=O tronco descascado de uma árvore da selva. +The stripped trunk of an oak tree.=O tronco descascado de um carvalho. +The stripped trunk of a spruce tree.=O tronco descascado de um pinheiro. +The trunk of a birch tree.=O tronco de uma bétula. +The trunk of a dark oak tree.=O tronco de um carvalho escuro. +The trunk of a jungle tree.=O tronco de uma árvore da selva. +The trunk of a spruce tree.=O tronco de um pinheiro. +The trunk of an acacia.=O tronco de uma acácia. +The trunk of an oak tree.=O tronco de um carvalho. +The stripped wood of an acacia tree.=A madeira descascada de uma acácia. +The stripped wood of a birch tree.=A madeira descascada de uma bétula. +The stripped wood of a dark oak tree.=A madeira descascada de um carvalho escuro. +The stripped wood of a jungle tree.=A madeira descascada de uma árvore da selva. +The stripped wood of an oak tree.=A madeira descascada de um carvalho. +The stripped wood of a spruce tree.=A madeira descascada de um pinheiro. +This block consists of a couple of loose stones and can't support itself.=Esse bloco consiste de várias pedras soltas e não consegue se suportar. +This is a decorative block surrounded by the bark of a tree trunk.=Este é um bloco decorativo envolto das cascas de uma árvore. +This is a decorative block.=Este é um bloco decorativo. +This is a full block of snow. Snow of this thickness is usually found in areas of extreme cold.=Esse é um bloco cheio de neve. Neve dessa espessura geralmente é encontrada em áreas de frio extremo. +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.=Esse é um pedaço de cacto comumente encontrado em áreas secas, especialmente desertos. Com o passar do tempo, cactos crescerão até 3 blocos de altura em areia ou areia vermelha. Um cacto machuca seres vivos que o encostarem com o dano de 1 HP a cada meio segundo. Quando um cacto é quebrado, todo bloco de cacto conectado acima também será quebrado. +This stone contains pure gold, a rare metal.=Essa rocha contem ouro puro, um metal raro. +Top Snow=Cobertura de neve +Top snow is a layer of snow. It melts near light sources other than the sun with a light level of 12 or higher.=A cobertura de neve é uma camada de neve. Ela derrete próxima de fontes luminosas além do sol quando o nível de luz for 12 ou superior. +Vines=Vinhas +Vines are climbable blocks which can be placed on the sides of solid full-cube blocks. Vines slowly grow and spread.=Vinhas são blocos escaláveis que podem ser colocadas ao lado de blocos sólidos. Vinhas crescem lentamente e se espalham. +Void=Vazio +Water=Água +Water Source=Fonte de Água +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.=Água é abundante em oceanos e também aparece em algumas nascentes no solo. Você pode nadar facilmente na água, mas é preciso tomar fôlego de tempo em tempo. +When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time.=Quando colocada no solo (como na terra) e exposta a luz, a muda de bétula crescerá em uma árvore após algum tempo. +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.=Quando colocada no solo (como na terra) e exposta a luz, a muda da selva crescerá em uma árvore após algum tempo. Quando há 4 mudas da selva em um quadrado de 2x2, elas crescerão em uma enorme árvore da selva. +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.=Quando colocada no solo (como na terra) e exposta a luz, a muda de pinheiro crescerá em uma árvore após algum tempo. Quando há 4 mudas de pinheiro em um quadrado de 2x2, elas crescerão em um enorme pinheiro. +When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time.=Quando colocada no solo (como na terra) e exposta a luz, a muda de acácia crescerá em uma árvore após algum tempo. +When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time.=Quando colocada no solo (como na terra) e exposta a luz, a muda de carvalho rescerá em uma árvore após algum tempo. +When you hold a barrier in hand, you reveal all placed barriers in a short distance around you.=Quando você segura uma barreira na mão, lhe é revelado todas as barreiras posicionadas próximas de você. +White Stained Glass=Vidro Tingido de Branco +Yellow Stained Glass=Vidro Tingido de Amarelo +“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.="Carvão" se refere a pedaços de carvão obtidos quando escavados minérios de carvão, que podem ser encontrados no subsolo. Carvão é seu combustível de fornalha padrão, mas também pode ser usado para fazer tochas, blocos de carvão e outras coisas. +Water interacts with lava in various ways:=Água interage com a lava de várias formas: +• When water is directly above or horizontally next to a lava source, the lava turns into obsidian.=• Quando a água está diretamente acima ou horizontalmente próxima de uma fonte de lava, a lava se torna obsidiana. +• When flowing water touches flowing lava either from above or horizontally, the lava turns into cobblestone.=• Quando água fluindo toca em lava fluindo tanto por cima quanto horizontalmente, a lava se torna pedregulho. +• When water is directly below lava, the water turns into stone.=• Quando a água está diretamente abaixo da lava, a água se torna rocha. +Lava interacts with water various ways:=Lava interage com a água de várias maneiras: +• When a lava source is directly below or horizontally next to water, the lava turns into obsidian.=• Quando uma fonte de lava está diretamente abaixo ou horizontalmente perto da água, a lava se torna obsidiana. +• When lava is directly above water, the water turns into stone.=• Quando a lavaz está diretamente acima da água, a água se torna rocha. +Stained Glass=Vidro Tingido +Granite is an igneous rock.=Granito é uma rocha ígnea. +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.=Cobertura de neve pode ser empilhada e possui 8 diferentes níveis de altura. Aos níveis 2-8, a cobertura de neve é colisional. Cobertura de neve derruba 2-9 bolas de neve, dependendo de sua altura. +This block can only be placed on full solid blocks and on another top snow (which increases its height).=Esse bloco só pode ser colocado em blocos sólidos e em outras coberturas de neve (o que aumenta sua altura). +Needs soil and water to grow=Necessita de solo e água para crescer +Needs soil and light to grow=Necessita de solo e luz para crescer +Grows on sand=Cresce na areia +Contact damage: @1 per half second=Dano de contato: @1 por meio segundo +Slows down movement=Diminui a velocidade de movimento +2×2 saplings required=2x2 de mudas necessário +2×2 saplings @= large tree=2x2 de mudas @= +Grows on sand or dirt next to water=Cresce na areia ou em terra próximo a água +Stackable=Empilhável +Crying Obsidian=Obsidiana Chorona +Crying obsidian is a luminous obsidian that can generate as part of ruined portals.=Obsidiana chorona é uma obsidiana luminosa que pode ser gerada como parte de portais arruinados. +Enchanted Golden Apple=Maçã Dourada Encantada diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr index f93db7c2c..bf8ce9e4f 100644 --- a/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr +++ b/mods/ITEMS/mcl_core/locale/mcl_core.ru.tr @@ -24,7 +24,7 @@ Andesite is an igneous rock.=Андезит это камень вулканич Apple=Яблоко Apples are food items which can be eaten.=Яблоки относятся к продуктовым предметам, которые можно есть. Barrier=Барьер -Barriers are invisble 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=Кора берёзы @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald=Изумруд Emerald Ore=Изумрудная руда Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку. -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки. +Emeralds are used in villager trades as currency.= Flint=Кремень Flint is a raw material.=Кремень это необработанный материал. Flowing Lava=Текущая лава @@ -130,6 +130,8 @@ 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.=Ляпис-лазурная руда это руда ляпис-лазури. Она изредка встречается в виде скоплений вблизи дна мира. diff --git a/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr new file mode 100644 index 000000000..74f3297a1 --- /dev/null +++ b/mods/ITEMS/mcl_core/locale/mcl_core.zh_TW.tr @@ -0,0 +1,259 @@ +# textdomain: mcl_core +@1 could not survive in lava.=@1試圖在熔岩中游泳 +@1 died 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 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 Leaves=相思木葉 +Acacia Sapling=相思木樹苗 +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.=蘋果是一種可以被食用的食物 +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.=屏障是看不見但可行走的方塊。它們通常被用來創建冒險地圖的邊界。怪物和動物不會出現在屏障上,柵欄也不會連接到屏障上。其他方塊可以像在其他方塊上一樣被放置在屏障上。 +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=白樺樹葉 +Birch Sapling=白樺樹樹苗 +Birch Wood=白樺樹原木 +Birch Wood Planks=白樺樹木材 +Birch leaves are grown from birch trees.=白樺樹葉是由白樺樹樹生長出來的。 +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.=煤炭磚作為煤炭的省位存儲方式,作為熔爐燃料非常有用。一個煤炭磚的燃燒時間相當於10塊煤炭。 +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.=碗主要用來盛湯。 +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=棕色玻璃 +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.=黏土是一種多功能的土,常見於岸邊。 +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.=粗粗泥作為一些植物的土壤,與泥土相似,但它永遠不會長草。 +Cobblestone=鵝卵石 +Cobweb=蜘蛛網 +Cobwebs can be walked through, but significantly slow you down.=蜘蛛網可以穿過,但它會大大降低你的速度。 +Cracked Stone Bricks=裂紋石磚 +Cut Red Sandstone=切製紅砂岩 +Cut Sandstone=切製砂岩 +Cut red sandstone is a decorative building block.=切製紅砂岩是裝飾性的方塊。 +Cut sandstone is a decorative building block.=切製砂岩是裝飾性的方塊。 +Cyan Stained Glass=青色玻璃 +Dark Oak Bark=黑橡木樹皮 +Dark Oak Leaves=黑橡木樹葉 +Dark Oak Sapling=黑橡木樹苗 +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的形態放在土壤(如泥土)上,並暴露在光照下,一段時間後就會長成一棵黑橡樹。 +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.=鑽石礦非常稀少,可以在接近世界底部的地方找到它們。 +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.=泥土可以作为一些植物的土壤。在光照下,如果附近有草方塊或菌絲土,草或菌絲可呢會蔓延到這裏。 +Emerald=綠寶石 +Emerald Ore=綠寶石礦 +Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=綠寶石礦是綠寶石的礦石。它非常稀少,只可以單獨出現,不會成堆出現。 +Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=綠寶石本身用途不太多,但可以通過合成來得到金錠。 +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.=霜冰是一種壽命很短的固體方塊。它在幾秒鐘內就會融化,成爲水源。 +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.=金蘋果是可以吃的珍貴食品。 +Granite=花崗岩 +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.=草徑是草方塊的一種裝飾變種。它們的頂部顏色和草方塊不同,而且它們比草方塊低一些,因此它們對建造人行道很有用。草徑可以用鏟子來創造。當草徑位於不透明方塊下時,它就會變成泥土。 +Gravel=礫石 +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.=在終界,在此方塊上點火將產生永恆之火。 +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.=叢林樹葉是由叢林樹生長出來的。 +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.=青金石礦是青金石的礦石。在世界底部附近能發現成群的和稀有的青金石礦。 +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=青苔石磚 +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=橡樹葉 +Oak Sapling=橡樹樹苗 +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.=冰塊是冰的壓縮形式。它是不透明的固體方塊。 +Paper=紙 +Paper is used to craft books and maps.=紙是用來合成書和地圖的物品。 +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=紫色玻璃 +Realm Barrier=維度分割屏障 +Red Sand=紅沙 +Red Sandstone=紅砂岩 +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.=紅石礦可以在距離世界底部比較近的地方生成。它會在受到壓力或被擊打時發光。 +Sand=沙 +Sand is found in large quantities at beaches and deserts.=沙大量存在於海灘和沙漠中。 +Sandstone=砂岩 +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=平滑紅砂岩 +Smooth Sandstone=平滑砂岩 +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=杉木樹葉 +Spruce Sapling=杉木樹苗 +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.=染色玻璃是一種大多是透明的裝飾性方塊,有各種不同的顏色。 +Stick=木棒 +Sticks are a very versatile crafting material; used in countless crafting recipes.=木棒是一種非常通用的製作材料;使用它的合成配方不計其數。 +Stone=石頭 +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 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塊高。當有生物接觸它時,該生物會每半秒受到1HP的傷害。當一個仙​​人掌塊被打破時,它上面連接的所有仙人掌塊也會被打破。 +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或更高的非太陽光源附近融化。 +Vines=藤蔓 +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.=將叢林樹苗放在土壤(如泥土)上並接受光照,一段時間後就會長成叢林樹。當2×2的正方形裡有4棵叢林樹苗時,它們會長成一棵巨大的叢林樹。 +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.=將杉木樹苗放在土壤(如泥土)上並接受光照,一段時間後就會長成杉木樹。當2×2的正方形裡有4棵杉木樹苗時,它們會長成一棵巨大的杉木樹。 +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.=「煤」指的是通過挖掘地下可以找到的煤礦而得到的煤塊。煤是標準的燃料,但也可以用來製作火把、煤塊和其他一些東西。 +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.=• 當水位於熔岩下時,水就會變成石頭。 +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).=此方塊只能放在完整的不透明方塊上或另一個雪上。如果它被放置在另一個雪上,會增加其高度。 +Needs soil and water to grow=需要泥土和水來生長 +Needs soil and light to grow=需要泥土和光照來生長 +Grows on sand=在沙上生長 +Contact damage: @1 per half second=接触伤害:每半秒@1次 +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=可堆疊 diff --git a/mods/ITEMS/mcl_core/locale/template.txt b/mods/ITEMS/mcl_core/locale/template.txt index f988435a3..911746699 100644 --- a/mods/ITEMS/mcl_core/locale/template.txt +++ b/mods/ITEMS/mcl_core/locale/template.txt @@ -24,7 +24,7 @@ Andesite is an igneous rock.= Apple= Apples are food items which can be eaten.= Barrier= -Barriers are invisble 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= @@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass Emerald= Emerald Ore= Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.= -Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.= +Emeralds are used in villager trades as currency.= Flint= Flint is a raw material.= Flowing Lava= @@ -130,6 +130,8 @@ 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.= @@ -202,20 +204,45 @@ Stained glass is a decorative and mostly transparent block which comes in variou Stick= Sticks are a very versatile crafting material; used in countless crafting recipes.= Stone= +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.= 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 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.= This stone contains pure gold, a rare metal.= @@ -256,3 +283,9 @@ Slows down movement= 2×2 saplings @= large tree= 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 575c46655..45018df75 100644 --- a/mods/ITEMS/mcl_core/mod.conf +++ b/mods/ITEMS/mcl_core/mod.conf @@ -1 +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 +optional_depends = doc diff --git a/mods/ITEMS/mcl_core/nodes_base.lua b/mods/ITEMS/mcl_core/nodes_base.lua index 78e2f1495..79cd37d8e 100644 --- a/mods/ITEMS/mcl_core/nodes_base.lua +++ b/mods/ITEMS/mcl_core/nodes_base.lua @@ -1,20 +1,22 @@ -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) -- Simple solid cubic nodes, most of them are the ground materials and simple building blocks local translucent_ice = minetest.settings:get_bool("mcl_translucent_ice", false) -local ice_drawtype +local ice_drawtype, ice_texture_alpha if translucent_ice then ice_drawtype = "glasslike" + ice_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true else ice_drawtype = "normal" + ice_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false end mcl_core.fortune_drop_ore = { discrete_uniform_distribution = true, min_count = 2, max_count = 1, - get_chance = function (fortune_level) return 1 - 2 / (fortune_level + 2) end, + get_chance = function(fortune_level) return 1 - 2 / (fortune_level + 2) end, multiply = true, } @@ -26,11 +28,16 @@ minetest.register_node("mcl_core:stone", { is_ground_content = true, stack_max = 64, groups = {pickaxey=1, stone=1, building_block=1, material_stone=1}, - drop = 'mcl_core:cobble', + drop = "mcl_core:cobble", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 1.5, _mcl_silk_touch_drop = true, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if awards and awards.unlock and digger and digger:is_player() then + awards.unlock(digger:get_player_name(), "mcl:stoneAge") + end + end, }) minetest.register_node("mcl_core:stone_with_coal", { @@ -40,8 +47,8 @@ minetest.register_node("mcl_core:stone_with_coal", { tiles = {"mcl_core_coal_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=1, building_block=1, material_stone=1, xp=1}, - drop = 'mcl_core:coal_lump', + groups = {pickaxey=1, building_block=1, material_stone=1, xp=1, blast_furnace_smeltable=1}, + drop = "mcl_core:coal_lump", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, @@ -55,12 +62,13 @@ minetest.register_node("mcl_core:stone_with_iron", { tiles = {"mcl_core_iron_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=3, building_block=1, material_stone=1}, - drop = 'mcl_core:stone_with_iron', + groups = {pickaxey=3, building_block=1, material_stone=1, blast_furnace_smeltable=1}, + drop = "mcl_raw_ores:raw_iron", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) @@ -70,19 +78,23 @@ minetest.register_node("mcl_core:stone_with_gold", { tiles = {"mcl_core_gold_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1}, - drop = "mcl_core:stone_with_gold", + groups = {pickaxey=4, building_block=1, material_stone=1, blast_furnace_smeltable=1}, + drop = "mcl_raw_ores:raw_gold", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, }) local redstone_timer = 68.28 -local redstone_ore_activate = function(pos) +local function redstone_ore_activate(pos, node, puncher, pointed_thing) minetest.swap_node(pos, {name="mcl_core:stone_with_redstone_lit"}) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end minetest.register_node("mcl_core:stone_with_redstone", { description = S("Redstone Ore"), @@ -90,7 +102,7 @@ minetest.register_node("mcl_core:stone_with_redstone", { tiles = {"mcl_core_redstone_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1, xp=7}, + groups = {pickaxey=4, building_block=1, material_stone=1, xp=7, blast_furnace_smeltable=1}, drop = { items = { max_items = 1, @@ -117,9 +129,12 @@ minetest.register_node("mcl_core:stone_with_redstone", { } }) -local redstone_ore_reactivate = function(pos) +local function redstone_ore_reactivate(pos, node, puncher, pointed_thing) local t = minetest.get_node_timer(pos) t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end end -- Light the redstone ore up when it has been touched minetest.register_node("mcl_core:stone_with_redstone_lit", { @@ -130,7 +145,7 @@ minetest.register_node("mcl_core:stone_with_redstone_lit", { light_source = 9, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, not_in_creative_inventory=1, material_stone=1, xp=7}, + groups = {pickaxey=4, not_in_creative_inventory=1, material_stone=1, xp=7, blast_furnace_smeltable=1}, drop = { items = { max_items = 1, @@ -168,15 +183,15 @@ minetest.register_node("mcl_core:stone_with_lapis", { tiles = {"mcl_core_lapis_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=3, building_block=1, material_stone=1, xp=6}, + groups = {pickaxey=3, building_block=1, material_stone=1, xp=6, blast_furnace_smeltable=1}, drop = { max_items = 1, items = { - {items = {'mcl_dye:blue 8'},rarity = 5}, - {items = {'mcl_dye:blue 7'},rarity = 5}, - {items = {'mcl_dye:blue 6'},rarity = 5}, - {items = {'mcl_dye:blue 5'},rarity = 5}, - {items = {'mcl_dye:blue 4'}}, + {items = {"mcl_core:lapis 8"},rarity = 5}, + {items = {"mcl_core:lapis 7"},rarity = 5}, + {items = {"mcl_core:lapis 6"},rarity = 5}, + {items = {"mcl_core:lapis 5"},rarity = 5}, + {items = {"mcl_core:lapis 4"}}, } }, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -192,7 +207,7 @@ minetest.register_node("mcl_core:stone_with_emerald", { tiles = {"mcl_core_emerald_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1, xp=6}, + groups = {pickaxey=4, building_block=1, material_stone=1, xp=6, blast_furnace_smeltable=1}, drop = "mcl_core:emerald", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, @@ -207,7 +222,7 @@ minetest.register_node("mcl_core:stone_with_diamond", { tiles = {"mcl_core_diamond_ore.png"}, is_ground_content = true, stack_max = 64, - groups = {pickaxey=4, building_block=1, material_stone=1, xp=4}, + groups = {pickaxey=4, building_block=1, material_stone=1, xp=4, blast_furnace_smeltable=1}, drop = "mcl_core:diamond", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, @@ -354,15 +369,20 @@ minetest.register_node("mcl_core:dirt_with_grass", { _doc_items_longdesc = S("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."), _doc_items_hidden = false, paramtype2 = "color", - tiles = {"mcl_core_grass_block_top.png", { name="default_dirt.png", color="white" }}, - overlay_tiles = {"mcl_core_grass_block_top.png", "", {name="mcl_core_grass_block_side_overlay.png", tileable_vertical=false}}, + tiles = {"mcl_core_grass_block_top.png", { name="default_dirt.png", color="white" }, { name="default_dirt.png^mcl_dirt_grass_shadow.png", color="white" }}, + overlay_tiles = {"mcl_core_grass_block_top.png", "blank.png", {name="mcl_core_grass_block_side_overlay.png", tileable_vertical=false}}, palette = "mcl_core_palette_grass.png", palette_index = 0, - color = "#55aa60", + color = "#7CBD6B", is_ground_content = true, stack_max = 64, - groups = {handy=1,shovely=1,dirt=2,grass_block=1, grass_block_no_snow=1, soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, spreading_dirt_type=1, enderman_takable=1, building_block=1}, - drop = 'mcl_core:dirt', + groups = { + handy = 1, shovely = 1, dirt = 2, grass_block = 1, grass_block_no_snow = 1, + soil = 1, soil_sapling = 2, soil_sugarcane = 1, cultivatable = 2, + spreading_dirt_type = 1, enderman_takable = 1, building_block = 1, + compostability = 30, path_creation_possible = 1, grass_palette = 1 + }, + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), @@ -377,11 +397,11 @@ minetest.register_node("mcl_core:dirt_with_grass", { return mcl_core.on_snowable_construct(pos) end, _mcl_snowed = "mcl_core:dirt_with_grass_snow", - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, }) -mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_grass", nil, nil, true, S("Dirt with Snow")) +mcl_core.register_snowed_node("mcl_core:dirt_with_grass_snow", "mcl_core:dirt_with_grass", nil, nil, true, S("Dirt with Snow"), 1) minetest.register_node("mcl_core:grass_path", { tiles = {"mcl_core_grass_path_top.png", "default_dirt.png", "mcl_core_grass_path_side.png"}, @@ -389,6 +409,7 @@ minetest.register_node("mcl_core: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."), drop = "mcl_core:dirt", is_ground_content = true, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, drawtype = "nodebox", paramtype = "light", node_box = { @@ -413,33 +434,71 @@ minetest.register_node("mcl_core:mycelium", { tiles = {"mcl_core_mycelium_top.png", "default_dirt.png", {name="mcl_core_mycelium_side.png", tileable_vertical=false}}, is_ground_content = true, stack_max = 64, - groups = {handy=1,shovely=1, dirt=2,spreading_dirt_type=1, enderman_takable=1, building_block=1}, - drop = 'mcl_core:dirt', + groups = { handy = 1, shovely = 1, dirt = 2, spreading_dirt_type = 1, enderman_takable = 1, building_block = 1, soil_sapling = 2, path_creation_possible=1, mycelium=1}, + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults({ footstep = {name="default_grass_footstep", gain=0.1}, }), on_construct = mcl_core.on_snowable_construct, _mcl_snowed = "mcl_core:mycelium_snow", - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, }) mcl_core.register_snowed_node("mcl_core:mycelium_snow", "mcl_core:mycelium", nil, nil, false, S("Mycelium with Snow")) +local PARTICLE_ABM_DISTANCE = 16 + +--if minetest.settings:get("mcl_node_particles") == "full" then +minetest.register_abm({ + label = "Townaura particles", + nodenames = {"group:mycelium"}, + interval = 2, + chance = 30, + action = function(pos, node) + local player_near = false + for _,player in pairs(minetest.get_connected_players()) do + if vector.distance(player:get_pos(), pos) < PARTICLE_ABM_DISTANCE then + player_near = true + end + end + if player_near then + local apos = {x=pos.x-2, y=pos.y+0.51, z=pos.z-2} + local apos2 = {x=pos.x+2, y=pos.y+0.51, z=pos.z+2} + local acc = { x = 0, y = 0, z = 0 } + minetest.add_particlespawner({ + time = 2, + amount = 5, + minpos = apos, + maxpos = apos2, + minvel = vector.new(-3/10, 0, -3/10), + maxvel = vector.new(3/10, 10/60, 3/10), + minacc = acc, + expirationtime = 4, + collisiondetection = true, + collision_removal = true, + size = 1, + texture = "mcl_core_mycelium_particle.png", + }) + end + end, +}) +--end + minetest.register_node("mcl_core:podzol", { description = S("Podzol"), _doc_items_longdesc = S("Podzol is a type of dirt found in taiga forests. Only a few plants are able to survive on it."), tiles = {"mcl_core_dirt_podzol_top.png", "default_dirt.png", {name="mcl_core_dirt_podzol_side.png", tileable_vertical=false}}, is_ground_content = true, stack_max = 64, - groups = {handy=1,shovely=3, dirt=2,soil=1, soil_sapling=2, soil_sugarcane=1, enderman_takable=1, building_block=1}, - drop = 'mcl_core:dirt', + groups = {handy=1,shovely=3, dirt=2,soil=1, soil_sapling=2, soil_sugarcane=1, enderman_takable=1, building_block=1,path_creation_possible=1}, + drop = "mcl_core:dirt", sounds = mcl_sounds.node_sound_dirt_defaults(), on_construct = mcl_core.on_snowable_construct, _mcl_snowed = "mcl_core:podzol_snow", - _mcl_blast_resistance = 0.5, - _mcl_hardness = 0.6, + _mcl_blast_resistance = 0.8, + _mcl_hardness = 0.8, _mcl_silk_touch_drop = true, }) mcl_core.register_snowed_node("mcl_core:podzol_snow", "mcl_core:podzol", nil, nil, false, S("Podzol with Snow")) @@ -451,7 +510,7 @@ minetest.register_node("mcl_core:dirt", { tiles = {"default_dirt.png"}, is_ground_content = true, stack_max = 64, - groups = {handy=1,shovely=1, dirt=1,soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, enderman_takable=1, building_block=1}, + groups = {handy=1,shovely=1, dirt=1,soil=1, soil_sapling=2, soil_sugarcane=1, cultivatable=2, enderman_takable=1, building_block=1, path_creation_possible=1}, sounds = mcl_sounds.node_sound_dirt_defaults(), _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, @@ -463,7 +522,7 @@ minetest.register_node("mcl_core:coarse_dirt", { tiles = {"mcl_core_coarse_dirt.png"}, is_ground_content = true, stack_max = 64, - groups = {handy=1,shovely=1, dirt=3,soil=1, soil_sugarcane=1, cultivatable=1, enderman_takable=1, building_block=1}, + groups = { handy = 1,shovely = 1, dirt = 3, soil = 1, soil_sugarcane = 1, cultivatable = 1, enderman_takable = 1, building_block = 1, soil_sapling = 2, path_creation_possible=1}, sounds = mcl_sounds.node_sound_dirt_defaults(), _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, @@ -479,13 +538,11 @@ minetest.register_node("mcl_core:gravel", { drop = { max_items = 1, items = { - {items = {'mcl_core:flint'},rarity = 10}, - {items = {'mcl_core:gravel'}} + {items = {"mcl_core:flint"},rarity = 10}, + {items = {"mcl_core:gravel"}} } }, - sounds = mcl_sounds.node_sound_dirt_defaults({ - footstep = {name="default_gravel_footstep", gain=0.45}, - }), + sounds = mcl_sounds.node_sound_gravel_defaults(), _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, _mcl_silk_touch_drop = true, @@ -493,15 +550,15 @@ minetest.register_node("mcl_core:gravel", { [1] = { max_items = 1, items = { - {items = {'mcl_core:flint'},rarity = 7}, - {items = {'mcl_core:gravel'}} + {items = {"mcl_core:flint"},rarity = 7}, + {items = {"mcl_core:gravel"}} } }, [2] = { max_items = 1, items = { - {items = {'mcl_core:flint'},rarity = 4}, - {items = {'mcl_core:gravel'}} + {items = {"mcl_core:flint"},rarity = 4}, + {items = {"mcl_core:gravel"}} } }, [3] = "mcl_core:flint", @@ -543,8 +600,8 @@ minetest.register_node("mcl_core:sandstonesmooth", { stack_max = 64, groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 0.8, - _mcl_hardness = 0.8, + _mcl_blast_resistance = 6, + _mcl_hardness = 2, }) minetest.register_node("mcl_core:sandstonecarved", { @@ -568,8 +625,8 @@ minetest.register_node("mcl_core:sandstonesmooth2", { stack_max = 64, groups = {pickaxey=1, sandstone=1, normal_sandstone=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), - _mcl_blast_resistance = 0.8, - _mcl_hardness = 0.8, + _mcl_blast_resistance = 6, + _mcl_hardness = 2, }) -- red sandstone -- @@ -644,7 +701,7 @@ minetest.register_node("mcl_core:clay", { is_ground_content = true, stack_max = 64, groups = {handy=1,shovely=1, enderman_takable=1, building_block=1}, - drop = 'mcl_core:clay_lump 4', + drop = "mcl_core:clay_lump 4", sounds = mcl_sounds.node_sound_dirt_defaults(), _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, @@ -675,7 +732,7 @@ minetest.register_node("mcl_core:bedrock", { sounds = mcl_sounds.node_sound_stone_defaults(), is_ground_content = false, on_blast = function() end, - drop = '', + drop = "", _mcl_blast_resistance = 3600000, _mcl_hardness = -1, @@ -711,7 +768,7 @@ minetest.register_node("mcl_core:cobble", { tiles = {"default_cobble.png"}, is_ground_content = false, stack_max = 64, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey=1, building_block=1, material_stone=1, cobble=1}, sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 6, _mcl_hardness = 2, @@ -762,7 +819,7 @@ minetest.register_node("mcl_core:goldblock", { groups = {pickaxey=4, building_block=1}, sounds = mcl_sounds.node_sound_metal_defaults(), _mcl_blast_resistance = 6, - _mcl_hardness = 5, + _mcl_hardness = 3, }) minetest.register_node("mcl_core:diamondblock", { @@ -805,7 +862,25 @@ minetest.register_node("mcl_core:obsidian", { description = S("Obsidian"), _doc_items_longdesc = S("Obsidian is an extremely hard mineral with an enourmous blast-resistance. Obsidian is formed when water meets lava."), tiles = {"default_obsidian.png"}, - is_ground_content = true, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + stack_max = 64, + groups = {pickaxey=5, building_block=1, material_stone=1}, + _mcl_blast_resistance = 1200, + _mcl_hardness = 50, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + if awards and awards.unlock and digger and digger:is_player() then + awards.unlock(digger:get_player_name(), "mcl:obsidian") + end + end, +}) + +minetest.register_node("mcl_core:crying_obsidian", { + description = S("Crying Obsidian"), + _doc_items_longdesc = S("Crying obsidian is a luminous obsidian that can generate as part of ruined portals."), + tiles = {"default_obsidian.png^mcl_core_crying_obsidian.png"}, + is_ground_content = false, + light_source = 10, sounds = mcl_sounds.node_sound_stone_defaults(), stack_max = 64, groups = {pickaxey=5, building_block=1, material_stone=1}, @@ -820,11 +895,11 @@ minetest.register_node("mcl_core:ice", { tiles = {"default_ice.png"}, is_ground_content = true, paramtype = "light", - use_texture_alpha = translucent_ice, + use_texture_alpha = ice_texture_alpha, stack_max = 64, groups = {handy=1,pickaxey=1, slippery=3, building_block=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), node_dig_prediction = "mcl_core:water_source", after_dig_node = function(pos, oldnode) mcl_core.melt_ice(pos) @@ -842,7 +917,7 @@ minetest.register_node("mcl_core:packed_ice", { stack_max = 64, groups = {handy=1,pickaxey=1, slippery=3, building_block=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), _mcl_blast_resistance = 0.5, _mcl_hardness = 0.5, _mcl_silk_touch_drop = true, @@ -851,7 +926,7 @@ minetest.register_node("mcl_core:packed_ice", { -- Frosted Ice (4 nodes) for i=0,3 do local ice = {} - ice.increase_age = function(pos, ice_near, first_melt) + function ice.increase_age(pos, ice_near, first_melt) -- Increase age of frosted age or turn to water source if too old local nn = minetest.get_node(pos).name local age = tonumber(string.sub(nn, -1)) @@ -886,11 +961,11 @@ for i=0,3 do tiles = {"mcl_core_frosted_ice_"..i..".png"}, is_ground_content = false, paramtype = "light", - use_texture_alpha = translucent_ice, + use_texture_alpha = ice_texture_alpha, stack_max = 64, groups = {handy=1, frosted_ice=1, slippery=3, not_in_creative_inventory=1, ice=1}, drop = "", - sounds = mcl_sounds.node_sound_glass_defaults(), + sounds = mcl_sounds.node_sound_ice_defaults(), on_construct = function(pos) local timer = minetest.get_node_timer(pos) timer:start(1.5) @@ -942,7 +1017,7 @@ for i=1,8 do fixed = { -0.5, -0.5, -0.5, 0.5, -0.5 + (2*i)/16, 0.5 }, } end - local on_place = function(itemstack, placer, pointed_thing) + local function on_place(itemstack, placer, pointed_thing) -- Placement is only allowed on top of solid blocks if pointed_thing.type ~= "node" then -- no interaction possible with entities @@ -977,9 +1052,8 @@ for i=1,8 do local itemcount = itemstack:get_count() local fakestack = ItemStack(itemstring.." "..itemcount) fakestack:set_name("mcl_core:snow_"..math.min(8, (i+g))) - local success - itemstack, success = minetest.item_place(fakestack, placer, pointed_thing) - minetest.sound_play(mcl_sounds.node_sound_snow_defaults().place, {pos = below}, true) + itemstack = minetest.item_place(fakestack, placer, pointed_thing) + minetest.sound_play(mcl_sounds.node_sound_snow_defaults().place, {pos = pointed_thing.under}, true) itemstack:set_name(itemstring) return itemstack end @@ -1021,7 +1095,7 @@ for i=1,8 do mcl_core.clear_snow_dirt(npos, node) end, node_box = node_box, - groups = {shovely=1, attached_node=1,deco_block=1, dig_by_piston=1, snow_cover=1, top_snow=i}, + groups = {shovely=2, attached_node=1,deco_block=1, dig_by_piston=1, snow_cover=1, top_snow=i}, sounds = mcl_sounds.node_sound_snow_defaults(), on_construct = mcl_core.on_snow_construct, on_place = on_place, @@ -1029,7 +1103,7 @@ for i=1,8 do drop = "mcl_throwing:snowball "..(i+1), _mcl_blast_resistance = 0.1, _mcl_hardness = 0.1, - _mcl_silk_touch_drop = {"mcl_core:snow " .. (i+1)}, + _mcl_silk_touch_drop = {"mcl_core:snow " .. i}, }) end @@ -1040,13 +1114,13 @@ minetest.register_node("mcl_core:snowblock", { tiles = {"default_snow.png"}, is_ground_content = true, stack_max = 64, - groups = {shovely=1, building_block=1, snow_cover=1}, + groups = {shovely=2, building_block=1, snow_cover=1}, sounds = mcl_sounds.node_sound_snow_defaults(), on_construct = mcl_core.on_snow_construct, after_destruct = mcl_core.after_snow_destruct, drop = "mcl_throwing:snowball 4", - _mcl_blast_resistance = 0.2, - _mcl_hardness = 0.2, + _mcl_blast_resistance = 0.1, + _mcl_hardness = 0.1, _mcl_silk_touch_drop = true, }) @@ -1056,4 +1130,3 @@ if minetest.get_modpath("doc") then doc.add_entry_alias("nodes", "mcl_core:water_source", "nodes", "mcl_core:water_flowing") doc.add_entry_alias("nodes", "mcl_core:lava_source", "nodes", "mcl_core:lava_flowing") end - diff --git a/mods/ITEMS/mcl_core/nodes_cactuscane.lua b/mods/ITEMS/mcl_core/nodes_cactuscane.lua index 9c0077ea2..79b440f61 100644 --- a/mods/ITEMS/mcl_core/nodes_cactuscane.lua +++ b/mods/ITEMS/mcl_core/nodes_cactuscane.lua @@ -1,17 +1,21 @@ -- Cactus and Sugar Cane -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_node("mcl_core:cactus", { description = S("Cactus"), - _tt_help = S("Grows on sand").."\n"..minetest.colorize("#FFFF00", S("Contact damage: @1 per half second", 1)), + _tt_help = S("Grows on sand").."\n"..minetest.colorize(mcl_colors.YELLOW, S("Contact damage: @1 per half second", 1)), _doc_items_longdesc = S("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."), _doc_items_usagehelp = S("A cactus can only be placed on top of another cactus or any sand."), drawtype = "nodebox", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, tiles = {"mcl_core_cactus_top.png", "mcl_core_cactus_bottom.png", "mcl_core_cactus_side.png"}, is_ground_content = true, stack_max = 64, - groups = {handy=1, attached_node=1, plant=1, deco_block=1, dig_by_piston=1, enderman_takable=1}, + groups = { + handy = 1, attached_node = 1, deco_block = 1, dig_by_piston = 1, + plant = 1, enderman_takable = 1, compostability = 50 + }, sounds = mcl_sounds.node_sound_wood_defaults(), paramtype = "light", sunlight_propagates = true, @@ -52,7 +56,10 @@ minetest.register_node("mcl_core:reeds", { _doc_items_longdesc = S("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."), _doc_items_usagehelp = S("Sugar canes can only be placed top of other sugar canes and on top of blocks on which they would grow."), drawtype = "plantlike", - tiles = {"default_papyrus.png"}, + paramtype2 = "color", + tiles = {"mcl_core_papyrus.png"}, + palette = "mcl_core_palette_grass.png", + palette_index = 0, inventory_image = "mcl_core_reeds.png", wield_image = "mcl_core_reeds.png", paramtype = "light", @@ -75,9 +82,13 @@ minetest.register_node("mcl_core:reeds", { }, }, stack_max = 64, - groups = {dig_immediate=3, craftitem=1, deco_block=1, plant=1, non_mycelium_plant=1, dig_by_piston=1}, + groups = { + dig_immediate = 3, craftitem = 1, deco_block = 1, dig_by_piston = 1, + plant = 1, non_mycelium_plant = 1, compostability = 50, grass_palette = 1 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), node_placement_prediction = "", + drop = "mcl_core:reeds", -- to prevent color inheritation on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node) local soil_pos = {x=place_pos.x, y=place_pos.y-1, z=place_pos.z} local soil_node = minetest.get_node_or_nil(soil_pos) @@ -113,6 +124,15 @@ minetest.register_node("mcl_core:reeds", { return false end), + on_construct = function(pos) + local node = minetest.get_node(pos) + if node.param2 == 0 then + node.param2 = mcl_util.get_palette_indexes_from_pos(pos).grass_palette_index + if node.param2 ~= 0 then + minetest.set_node(pos, node) + end + end + end, _mcl_blast_resistance = 0, _mcl_hardness = 0, }) diff --git a/mods/ITEMS/mcl_core/nodes_climb.lua b/mods/ITEMS/mcl_core/nodes_climb.lua index d9ecd76d3..33a34f899 100644 --- a/mods/ITEMS/mcl_core/nodes_climb.lua +++ b/mods/ITEMS/mcl_core/nodes_climb.lua @@ -1,7 +1,7 @@ -- Climbable nodes -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) -local rotate_climbable = function(pos, node, user, mode) +local function rotate_climbable(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then local r = screwdriver.rotate.wallmounted(pos, node, mode) node.param2 = r @@ -92,11 +92,13 @@ minetest.register_node("mcl_core:vine", { _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"}, + color = "#48B518", inventory_image = "mcl_core_vine.png", wield_image = "mcl_core_vine.png", paramtype = "light", sunlight_propagates = true, - paramtype2 = "wallmounted", + paramtype2 = "colorwallmounted", + palette = "[combine:16x2:0,0=mcl_core_palette_foliage.png", walkable = false, climbable = true, buildable_to = true, @@ -104,7 +106,11 @@ minetest.register_node("mcl_core:vine", { type = "wallmounted", }, stack_max = 64, - groups = {handy=1,axey=1,shearsy=1,swordy=1, flammable=2,deco_block=1,destroy_by_lava_flow=1,dig_by_piston=1, fire_encouragement=15, fire_flammability=100}, + 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 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), drop = "", _mcl_shears_drop = true, @@ -120,7 +126,6 @@ minetest.register_node("mcl_core:vine", { local node = minetest.get_node(under) local def = minetest.registered_nodes[node.name] if not def then return itemstack end - local groups = def.groups -- Check special rightclick action of pointed node if def and def.on_rightclick then @@ -152,10 +157,24 @@ minetest.register_node("mcl_core:vine", { return itemstack end, + on_construct = function(pos) + local node = minetest.get_node(pos) + local foliage_palette_index = mcl_util.get_palette_indexes_from_pos(pos).foliage_palette_index + if node.name == "mcl_core:vine" then + local biome_param2 = foliage_palette_index + local rotation_param2 = node.param2 + local final_param2 = (biome_param2 * 8) + rotation_param2 + if node.param2 ~= final_param2 and rotation_param2 < 6 then + node.param2 = final_param2 + minetest.swap_node(pos, node) + end + end + end, + -- 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 = {x=pos.x, y=pos.y-1, z=pos.z} + 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 diff --git a/mods/ITEMS/mcl_core/nodes_glass.lua b/mods/ITEMS/mcl_core/nodes_glass.lua index 83d2c1065..8b3aea689 100644 --- a/mods/ITEMS/mcl_core/nodes_glass.lua +++ b/mods/ITEMS/mcl_core/nodes_glass.lua @@ -1,14 +1,15 @@ -- Glass nodes -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") minetest.register_node("mcl_core:glass", { description = S("Glass"), _doc_items_longdesc = S("A decorative and mostly transparent block."), - drawtype = "glasslike", + drawtype = "glasslike_framed_optional", is_ground_content = false, - tiles = {"default_glass.png"}, + tiles = {"default_glass.png", "default_glass_detail.png"}, paramtype = "light", + paramtype2 = "glasslikeliquidlevel", sunlight_propagates = true, stack_max = 64, groups = {handy=1, glass=1, building_block=1, material_glass=1}, @@ -20,7 +21,7 @@ minetest.register_node("mcl_core:glass", { }) ------------------------ --- Create Color Glass -- +-- Create Color Glass -- ------------------------ local canonical_color = "yellow" function mcl_core.add_stained_glass(desc, recipeitem, colorgroup, color) @@ -39,12 +40,13 @@ function mcl_core.add_stained_glass(desc, recipeitem, colorgroup, color) _doc_items_create_entry = create_entry, _doc_items_entry_name = entry_name, _doc_items_longdesc = longdesc, - drawtype = "glasslike", + drawtype = "glasslike_framed_optional", is_ground_content = false, - tiles = {"mcl_core_glass_"..color..".png"}, + tiles = {"mcl_core_glass_"..color..".png", "mcl_core_glass_"..color.."_detail.png"}, paramtype = "light", + paramtype2 = "glasslikeliquidlevel", sunlight_propagates = true, - use_texture_alpha = true, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, stack_max = 64, -- TODO: Add color to groups groups = {handy=1, glass=1, building_block=1, material_glass=1}, @@ -54,13 +56,13 @@ function mcl_core.add_stained_glass(desc, recipeitem, colorgroup, color) _mcl_hardness = 0.3, _mcl_silk_touch_drop = true, }) - + minetest.register_craft({ - output = 'mcl_core:glass_'..color..' 8', + output = "mcl_core:glass_"..color.." 8", recipe = { - {'mcl_core:glass','mcl_core:glass','mcl_core:glass'}, - {'mcl_core:glass',recipeitem,'mcl_core:glass'}, - {'mcl_core:glass','mcl_core:glass','mcl_core:glass'}, + {"mcl_core:glass","mcl_core:glass","mcl_core:glass"}, + {"mcl_core:glass",recipeitem,"mcl_core:glass"}, + {"mcl_core:glass","mcl_core:glass","mcl_core:glass"}, } }) diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 4769975b9..e55664432 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -1,19 +1,19 @@ -- Liquids: Water and lava -local S = minetest.get_translator("mcl_core") -local N = function(s) return s end +local S = minetest.get_translator(minetest.get_current_modname()) -local WATER_ALPHA = 179 +local vector = vector +local math = math + +--local WATER_ALPHA = 179 local WATER_VISC = 1 local LAVA_VISC = 7 local LIGHT_LAVA = minetest.LIGHT_MAX +local USE_TEXTURE_ALPHA = true -local lava_death_messages = { - N("@1 melted in lava."), - N("@1 took a bath in a hot lava tub."), - N("@1 died in lava."), - N("@1 could not survive in lava."), -} +if minetest.features.use_texture_alpha_string_modes then + USE_TEXTURE_ALPHA = "blend" +end minetest.register_node("mcl_core:water_flowing", { description = S("Flowing Water"), @@ -25,17 +25,18 @@ minetest.register_node("mcl_core:water_flowing", { { image="default_water_flowing_animated.png", backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, { image="default_water_flowing_animated.png", backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1.5} }, }, + color = "#3F76E4", sounds = mcl_sounds.node_sound_water_defaults(), is_ground_content = false, - alpha = WATER_ALPHA, + use_texture_alpha = USE_TEXTURE_ALPHA, paramtype = "light", paramtype2 = "flowingliquid", walkable = false, @@ -49,7 +50,8 @@ minetest.register_node("mcl_core:water_flowing", { liquid_alternative_source = "mcl_core:water_source", liquid_viscosity = WATER_VISC, liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + waving = 3, + post_effect_color = {a=60, r=24.7, g=46.3, b=89.4}, groups = { water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1, freezes=1, melt_around=1, dig_by_piston=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode @@ -67,21 +69,25 @@ S("• When flowing water touches flowing lava either from above or horizontally S("• When water is directly below lava, the water turns into stone."), _doc_items_hidden = false, drawtype = "liquid", + waving = 3, tiles = { - {name="default_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} + {name="default_water_source_animated.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", - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=3.0}, backface_culling = false, } }, + color = "#3F76E4", sounds = mcl_sounds.node_sound_water_defaults(), is_ground_content = false, - alpha = WATER_ALPHA, + use_texture_alpha = USE_TEXTURE_ALPHA, paramtype = "light", + paramtype2 = "color", + palette = "mcl_core_palette_water.png", walkable = false, pointable = false, diggable = false, @@ -93,12 +99,21 @@ S("• When water is directly below lava, the water turns into stone."), liquid_alternative_source = "mcl_core:water_source", liquid_viscosity = WATER_VISC, liquid_range = 7, - post_effect_color = {a=209, r=0x03, g=0x3C, b=0x5C}, + post_effect_color = {a=60, r=24.7, g=46.3, b=89.4}, stack_max = 64, - groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1}, + groups = { water=3, liquid=3, puts_out_fire=1, freezes=1, not_in_creative_inventory=1, dig_by_piston=1, water_palette=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, + on_construct = function(pos) + local node = minetest.get_node(pos) + if node.param2 == 0 then + local new_node = mcl_core.get_water_block_type(pos) + if new_node.param2 ~= 0 then + minetest.swap_node(pos, new_node) + end + end + end, }) minetest.register_node("mcl_core:lava_flowing", { @@ -140,7 +155,6 @@ minetest.register_node("mcl_core:lava_flowing", { liquid_renewable = false, liquid_range = 3, damage_per_second = 4*2, - _mcl_node_death_message = lava_death_messages, post_effect_color = {a=245, r=208, g=73, b=10}, groups = { lava=3, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15}, _mcl_blast_resistance = 100, @@ -195,22 +209,21 @@ S("• When lava is directly above water, the water turns into stone."), liquid_renewable = false, liquid_range = 3, damage_per_second = 4*2, - _mcl_node_death_message = lava_death_messages, post_effect_color = {a=245, r=208, g=73, b=10}, stack_max = 64, - groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15}, + groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, }) -local emit_lava_particle = function(pos) +local function emit_lava_particle(pos) local node = minetest.get_node(pos) if minetest.get_item_group(node.name, "lava_source") == 0 then return end local ppos = vector.add(pos, { x = math.random(-7, 7)/16, y = 0.45, z = math.random(-7, 7)/16}) - local spos = vector.add(ppos, { x = 0, y = -0.2, z = 0 }) + --local spos = vector.add(ppos, { x = 0, y = -0.2, z = 0 }) local vel = { x = math.random(-3, 3)/10, y = math.random(4, 7), z = math.random(-3, 3)/10 } local acc = { x = 0, y = -9.81, z = 0 } -- Lava droplet @@ -245,3 +258,22 @@ if minetest.settings:get("mcl_node_particles") == "full" then end, }) end + +minetest.register_on_liquid_transformed(function(pos_list, node_list) + for _, fwpos in pairs(pos_list) do + local fwnode = minetest.get_node(fwpos) + if minetest.get_item_group(fwnode, "palette_index") ~= 1 then + local pos1, pos2 = vector.offset(fwpos, -1, -1, -1), vector.offset(fwpos, 1, 1, 1) + local water = minetest.find_nodes_in_area(pos1, pos2, {"group:water_palette"}) + for _, wpos in pairs(water) do + local wnode = minetest.get_node(wpos) + local water_palette_index = mcl_util.get_palette_indexes_from_pos(wpos).water_palette_index + if wnode.param2 ~= water_palette_index then + wnode.param2 = water_palette_index + minetest.set_node(wpos, wnode) + end + end + end + end +end +) diff --git a/mods/ITEMS/mcl_core/nodes_misc.lua b/mods/ITEMS/mcl_core/nodes_misc.lua index bbfe75668..d830cc310 100644 --- a/mods/ITEMS/mcl_core/nodes_misc.lua +++ b/mods/ITEMS/mcl_core/nodes_misc.lua @@ -1,12 +1,21 @@ -- Other nodes -local S = minetest.get_translator("mcl_core") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_screwdriver = minetest.get_modpath("screwdriver") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way end -local alldirs = {{x=0,y=0,z=1}, {x=1,y=0,z=0}, {x=0,y=0,z=-1}, {x=-1,y=0,z=0}, {x=0,y=-1,z=0}, {x=0,y=1,z=0}} + +local alldirs = { + vector.new(0, 0, 1), + vector.new(1, 0, 0), + vector.new(0, 0, -1), + vector.new(-1, 0, 0), + vector.new(0, -1, 0), + vector.new(0, 1, 0), +} minetest.register_node("mcl_core:bone_block", { description = S("Bone Block"), @@ -15,7 +24,7 @@ minetest.register_node("mcl_core:bone_block", { is_ground_content = false, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey = 1, building_block = 1, material_stone = 1}, sounds = mcl_sounds.node_sound_stone_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 2, @@ -31,7 +40,7 @@ minetest.register_node("mcl_core:slimeblock", { node_box = { type = "fixed", fixed = { - {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, + {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}, {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5}, } }, @@ -39,21 +48,19 @@ minetest.register_node("mcl_core:slimeblock", { type = "regular", }, tiles = {"mcl_core_slime.png"}, - paramtype = "light", - use_texture_alpha = true, - stack_max = 64, + use_texture_alpha = "blend", -- According to Minecraft Wiki, bouncing off a slime block from a height off 255 blocks should result in a bounce height of 50 blocks -- bouncy=44 makes the player bounce up to 49.6. This value was chosen by experiment. -- bouncy=80 was chosen because it is higher than 66 (bounciness of bed) - groups = {dig_immediate=3, bouncy=80,fall_damage_add_percent=-100,deco_block=1}, + groups = {dig_immediate = 3, bouncy = 80, fall_damage_add_percent = -100, deco_block = 1}, sounds = { - dug = {name="slimenodes_dug", gain=0.6}, - place = {name="slimenodes_place", gain=0.6}, - footstep = {name="slimenodes_step", gain=0.3}, + dug = {name = "slimenodes_dug", gain = 0.6}, + place = {name = "slimenodes_place", gain = 0.6}, + footstep = {name = "slimenodes_step", gain = 0.3}, }, _mcl_blast_resistance = 0, _mcl_hardness = 0, - mvps_sticky = function (pos, node, piston_pos) + mvps_sticky = function(pos, node, piston_pos) local connected = {} for n, v in ipairs(alldirs) do local neighbor_pos = vector.add(pos, v) @@ -64,7 +71,7 @@ minetest.register_node("mcl_core:slimeblock", { neighbor_node = minetest.get_node(neighbor_pos) end local name = neighbor_node.name - if name ~= "air" and name ~= "ignore" then + if name ~= "air" and name ~= "ignore" and name ~= "mcl_honey:honey_block" and not mesecon.mvps_unsticky[name] then local piston, piston_side, piston_up, piston_down = false, false, false, false if name == "mesecons_pistons:piston_sticky_off" or name == "mesecons_pistons:piston_normal_off" then piston, piston_side = true, true @@ -73,7 +80,8 @@ minetest.register_node("mcl_core:slimeblock", { elseif name == "mesecons_pistons:piston_down_sticky_off" or name == "mesecons_pistons:piston_down_normal_off" then piston, piston_down = true, true end - if not( (piston_side and (n-1==neighbor_node.param2)) or (piston_up and (n==5)) or (piston_down and (n==6)) ) then + if not + ((piston_side and (n - 1 == neighbor_node.param2)) or (piston_up and (n == 5)) or (piston_down and (n == 6))) then if piston and piston_pos then if piston_pos.x == neighbor_pos.x and piston_pos.y == neighbor_pos.y and piston_pos.z == neighbor_pos.z then -- Loopback to the same piston! Preventing unwanted behavior: @@ -97,7 +105,6 @@ minetest.register_node("mcl_core:cobweb", { drawtype = "plantlike", paramtype2 = "degrotate", visual_scale = 1.1, - stack_max = 64, tiles = {"mcl_core_web.png"}, inventory_image = "mcl_core_web.png", paramtype = "light", @@ -108,7 +115,8 @@ minetest.register_node("mcl_core:cobweb", { liquid_renewable = false, liquid_range = 0, walkable = false, - groups = {swordy_cobweb=1,shearsy=1, fake_liquid=1, disable_jump=1, deco_block=1, dig_by_piston=1, dig_by_water=1,destroy_by_lava_flow=1,}, + groups = {swordy_cobweb = 1, shearsy_cobweb = 1, fake_liquid = 1, disable_jump = 1, deco_block = 1, dig_by_piston = 1, + dig_by_water = 1, destroy_by_lava_flow = 1,}, drop = "mcl_mobitems:string", _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), @@ -130,9 +138,9 @@ minetest.register_node("mcl_core:deadbush", { paramtype = "light", sunlight_propagates = true, walkable = false, - stack_max = 64, 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_water = 1, + destroy_by_lava_flow = 1, deco_block = 1, fire_encouragement = 60, fire_flammability = 100}, drop = { max_items = 1, items = { @@ -150,7 +158,7 @@ minetest.register_node("mcl_core:deadbush", { sounds = mcl_sounds.node_sound_leaves_defaults(), selection_box = { type = "fixed", - fixed = {-5/16, -8/16, -5/16, 5/16, 1/16, 5/16}, + fixed = {-5 / 16, -8 / 16, -5 / 16, 5 / 16, 1 / 16, 5 / 16}, }, _mcl_blast_resistance = 0, _mcl_hardness = 0, @@ -158,22 +166,21 @@ minetest.register_node("mcl_core:deadbush", { minetest.register_node("mcl_core:barrier", { description = S("Barrier"), - _doc_items_longdesc = S("Barriers are invisble 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."), + _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."), _doc_items_usagehelp = S("When you hold a barrier in hand, you reveal all placed barriers in a short distance around you."), drawtype = "airlike", paramtype = "light", inventory_image = "mcl_core_barrier.png", wield_image = "mcl_core_barrier.png", - tiles = { "blank.png" }, - stack_max = 64, + tiles = {"blank.png"}, sunlight_propagates = true, is_ground_content = false, - groups = {creative_breakable=1, not_in_creative_inventory = 1, not_solid = 1 }, - on_blast = function() end, + groups = {creative_breakable = 1, not_in_creative_inventory = 1, not_solid = 1}, + on_blast = function(pos, intensity) end, drop = "", _mcl_blast_resistance = 36000008, _mcl_hardness = -1, - after_place_node = function (pos, placer, itemstack, pointed_thing) + after_place_node = function(pos, placer, itemstack, pointed_thing) if placer == nil then return end @@ -192,11 +199,9 @@ minetest.register_node("mcl_core:barrier", { 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 + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack end local name = placer:get_player_name() @@ -213,7 +218,7 @@ minetest.register_node("mcl_core:barrier", { -- Same as barrier, but non-pointable. This node is only to be used internally to separate realms. -- It must NOT be used for anything else. -- This node only exists because Minetest does not have support for “dimensions” yet and needs to --- be removed when support for this is implemented. +-- be removed when support for this is implemented. minetest.register_node("mcl_core:realm_barrier", { description = S("Realm Barrier"), _doc_items_create_entry = false, @@ -221,27 +226,84 @@ minetest.register_node("mcl_core:realm_barrier", { paramtype = "light", inventory_image = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX", wield_image = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX", - tiles = { "blank.png" }, - stack_max = 64, + tiles = {"blank.png"}, -- To avoid players getting stuck forever between realms damage_per_second = 8, sunlight_propagates = true, is_ground_content = false, pointable = false, - groups = {not_in_creative_inventory = 1, not_solid = 1 }, - on_blast = function() end, + groups = {not_in_creative_inventory = 1, not_solid = 1}, + on_blast = function(pos, intensity) end, drop = "", _mcl_blast_resistance = 36000008, _mcl_hardness = -1, -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", - on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize("#FF0000", "You can't just place a realm barrier by hand!")) + on_place = function(itemstack, placer, pointed_thing) + if placer then + minetest.chat_send_player(placer:get_player_name(), + minetest.colorize(mcl_colors.RED, "You can't just place a realm barrier by hand!")) + end return end, }) +--- Light blocks +--- TODO: make node only pointable when wielding it + +local light_block_pattern = "^mcl_core:light_(%d+)$" + + +for i = 0, 14 do --minetest.LIGHT_MAX + minetest.register_node("mcl_core:light_" .. i, { + description = S("Light"), + _doc_items_longdesc = S("Lights are invisible blocks. They are used to light up adventure maps and the like."), + _doc_items_usagehelp = S("When you hold a light in hand, you reveal all placed lights in a short distance around you."), + drawtype = "airlike", + paramtype = "light", + walkable = false, + light_source = i, + drop = "", + buildable_to = true, + node_placement_prediction = "", + inventory_image = "mcl_core_light_" .. i .. ".png", + wield_image = "mcl_core_light_" .. i .. ".png", + sunlight_propagates = true, + is_ground_content = false, + groups = {creative_breakable = 1, not_solid = 1, light_block = i + 1}, + on_blast = function(pos, intensity) end, + on_use = function(itemstack, user, pointed_thing) + -- user:get_player_control() returns {} for non players, so we don't need user:is_player() + if pointed_thing.type == "node" and string.match(minetest.get_node(pointed_thing.under).name, light_block_pattern) and not user:get_player_control().sneak then + minetest.dig_node(pointed_thing.under) + return + end + itemstack:set_name("mcl_core:light_" .. ((i == 14) and 0 or i + 1)) + return itemstack + end, + on_place = mcl_util.bypass_buildable_to(function(node_name) + return string.match(node_name, light_block_pattern) + end), + after_place_node = function(pos, placer, itemstack, pointed_thing) + if not placer then + return + end + minetest.add_particle({ + pos = pos, + expirationtime = 1, + size = 8, + texture = "mcl_core_light_" .. i .. ".png", + glow = 14, + playername = placer:get_player_name() + }) + end, + _mcl_blast_resistance = 36000008, + _mcl_hardness = -1, + }) +end + + -- The void below the bedrock. Void damage is handled in mcl_playerplus. @@ -258,15 +320,17 @@ minetest.register_node("mcl_core:void", { buildable_to = false, inventory_image = "mcl_core_void.png", wield_image = "mcl_core_void.png", - stack_max = 64, sunlight_propagates = true, is_ground_content = false, - groups = { not_in_creative_inventory = 1 }, - on_blast = function() end, + groups = {not_in_creative_inventory = 1}, + on_blast = function(pos, intensity) end, -- Prevent placement to protect player from screwing up the world, because the node is not pointable and hard to get rid of. node_placement_prediction = "", - on_place = function(pos, placer, itemstack, pointed_thing) - minetest.chat_send_player(placer:get_player_name(), minetest.colorize("#FF0000", "You can't just place the void by hand!")) + on_place = function(itemstack, placer, pointed_thing) + if placer then + minetest.chat_send_player(placer:get_player_name(), + minetest.colorize(mcl_colors.RED, "You can't just place the void by hand!")) + end return end, drop = "", diff --git a/mods/ITEMS/mcl_core/nodes_trees.lua b/mods/ITEMS/mcl_core/nodes_trees.lua index 3a8aef8d0..beead761d 100644 --- a/mods/ITEMS/mcl_core/nodes_trees.lua +++ b/mods/ITEMS/mcl_core/nodes_trees.lua @@ -1,30 +1,76 @@ --- Tree nodes: Wood, Wooden Planks, Sapling, Leaves -local S = minetest.get_translator("mcl_core") +-- Tree nodes: Wood, Wooden Planks, Sapling, Leaves, Stripped Wood +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_screwdriver = minetest.get_modpath("screwdriver") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way end +-- Check dug/destroyed tree trunks for orphaned leaves. +-- +-- This function is meant to be called by the `after_destruct` handler of +-- treetrunk nodes. +-- +-- Whenever a trunk node is removed, all `group:leaves` nodes in a sphere +-- with radius 6 are checked. Every such node that does not have a trunk +-- node within a distance of 6 blocks and wasn't placed by a player is +-- converted into a orphan leaf node. +-- An ABM will gradually decay these nodes. +-- +-- +-- @param pos the position of the removed trunk node. +-- @param oldnode the node table of the removed trunk node. +function mcl_core.update_leaves(pos, oldnode) + local pos1, pos2 = vector.offset(pos, -6, -6, -6), vector.offset(pos, 6, 6, 6) + local lnode, lmeta + local leaves = minetest.find_nodes_in_area(pos1, pos2, "group:leaves") + for _, lpos in pairs(leaves) do + lnode = minetest.get_node(lpos) + lmeta = minetest.get_meta(lpos) + -- skip already decaying leaf nodes and player leaves + if minetest.get_item_group(lnode.name, "orphan_leaves") ~= 1 and lmeta:get_int("player_leaves") ~= 1 then + if not minetest.find_node_near(lpos, 6, "group:tree") then + local orphan_name = lnode.name .. "_orphan" + local def = minetest.registered_nodes[orphan_name] + if def then + --minetest.log("Registered: ".. orphan_name) + minetest.set_node(lpos, {name = orphan_name}) + else + --minetest.log("Not registered: ".. orphan_name) + end + end + end + end +end + +function mcl_core.make_player_leaves(pos) + local meta = minetest.get_meta(pos) + meta:set_int("player_leaves", 1) +end + -- Register tree trunk (wood) and bark -local register_tree_trunk = function(subname, description_trunk, description_bark, longdesc, tile_inner, tile_bark) - minetest.register_node("mcl_core:"..subname, { +function mcl_core.register_tree_trunk(subname, description_trunk, description_bark, longdesc, tile_inner, tile_bark, stripped_variant) + local mod = minetest.get_current_modname() + minetest.register_node(mod..":"..subname, { description = description_trunk, _doc_items_longdesc = longdesc, _doc_items_hidden = false, tiles = {tile_inner, tile_inner, tile_bark}, paramtype2 = "facedir", on_place = mcl_util.rotate_axis, + after_destruct = mcl_core.update_leaves, stack_max = 64, groups = {handy=1,axey=1, tree=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, sounds = mcl_sounds.node_sound_wood_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 2, _mcl_hardness = 2, + _mcl_stripped_variant = stripped_variant, }) - minetest.register_node("mcl_core:"..subname.."_bark", { + minetest.register_node(mod..":"..subname.."_bark", { description = description_bark, _doc_items_longdesc = S("This is a decorative block surrounded by the bark of a tree trunk."), tiles = {tile_bark}, @@ -37,19 +83,63 @@ local register_tree_trunk = function(subname, description_trunk, description_bar on_rotate = on_rotate, _mcl_blast_resistance = 2, _mcl_hardness = 2, + _mcl_stripped_variant = stripped_variant.."_bark", }) minetest.register_craft({ - output = "mcl_core:"..subname.."_bark 3", + output = mod..":"..subname.."_bark 3", recipe = { - { "mcl_core:"..subname, "mcl_core:"..subname }, - { "mcl_core:"..subname, "mcl_core:"..subname }, + { mod..":"..subname, mod..":"..subname }, + { mod..":"..subname, mod..":"..subname }, } }) end -local register_wooden_planks = function(subname, description, tiles) - minetest.register_node("mcl_core:"..subname, { +-- Register stripped trunk and stripped wood +function mcl_core.register_stripped_trunk(subname, description_stripped_trunk, description_stripped_bark, longdesc, longdesc_wood, tile_stripped_inner, tile_stripped_bark) + local mod = minetest.get_current_modname() + minetest.register_node(mod..":"..subname, { + description = description_stripped_trunk, + _doc_items_longdesc = longdesc, + _doc_items_hidden = false, + tiles = {tile_stripped_inner, tile_stripped_inner, tile_stripped_bark}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + stack_max = 64, + groups = {handy=1, axey=1, tree=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + on_rotate = on_rotate, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + }) + + minetest.register_node(mod..":"..subname.."_bark", { + description = description_stripped_bark, + _doc_items_longdesc = longdesc_wood, + tiles = {tile_stripped_bark}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + stack_max = 64, + groups = {handy=1, axey=1, bark=1, flammable=2, building_block=1, material_wood=1, fire_encouragement=5, fire_flammability=5}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + on_rotate = on_rotate, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + }) + + minetest.register_craft({ + output = mod..":"..subname.."_bark 3", + recipe = { + { mod..":"..subname, mod..":"..subname }, + { mod..":"..subname, mod..":"..subname }, + } + }) +end + +function mcl_core.register_wooden_planks(subname, description, tiles) + local mod = minetest.get_current_modname() + minetest.register_node(mod..":"..subname, { description = description, _doc_items_longdesc = doc.sub.items.temp.build, _doc_items_hidden = false, @@ -63,14 +153,11 @@ local register_wooden_planks = function(subname, description, tiles) }) end -local register_leaves = function(subname, description, longdesc, tiles, sapling, drop_apples, sapling_chances, leafdecay_distance) - local drop - if leafdecay_distance == nil then - leafdecay_distance = 4 - end +function mcl_core.register_leaves(subname, description, longdesc, tiles, color, paramtype2, palette, sapling, drop_apples, sapling_chances, foliage_palette) + local mod = minetest.get_current_modname() local apple_chances = {200, 180, 160, 120, 40} local stick_chances = {50, 45, 30, 35, 10} - + local function get_drops(fortune_level) local drop = { max_items = 1, @@ -98,17 +185,23 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling, return drop end - minetest.register_node("mcl_core:"..subname, { + local l_def = { description = description, _doc_items_longdesc = longdesc, _doc_items_hidden = false, drawtype = "allfaces_optional", waving = 2, - place_param2 = 1, -- Prevent leafdecay for placed nodes tiles = tiles, + color = color, paramtype = "light", + paramtype2 = paramtype2, + palette = palette, stack_max = 64, - groups = {handy=1,shearsy=1,swordy=1, leafdecay=leafdecay_distance, flammable=2, leaves=1, deco_block=1, dig_by_piston=1, fire_encouragement=30, fire_flammability=60}, + groups = { + handy = 1, hoey = 1, shearsy = 1, swordy = 1, dig_by_piston = 1, + flammable = 2, fire_encouragement = 30, fire_flammability = 60, + leaves = 1, deco_block = 1, compostability = 30, foliage_palette = foliage_palette + }, drop = get_drops(0), _mcl_shears_drop = true, sounds = mcl_sounds.node_sound_leaves_defaults(), @@ -116,11 +209,41 @@ local register_leaves = function(subname, description, longdesc, tiles, sapling, _mcl_hardness = 0.2, _mcl_silk_touch_drop = true, _mcl_fortune_drop = { get_drops(1), get_drops(2), get_drops(3), get_drops(4) }, - }) + on_construct = function(pos) + local node = minetest.get_node(pos) + if node.param2 == 0 then + local new_node = mcl_core.get_foliage_block_type(pos) + if new_node.param2 ~= 0 then + minetest.swap_node(pos, new_node) + end + end + end, + after_place_node = function(pos) + mcl_core.make_player_leaves(pos) -- Leaves placed by the player should always be player leaves. + end, + } + + minetest.register_node(mod .. ":" .. subname, l_def) + + local o_def = table.copy(l_def) + o_def._doc_items_create_entry = false + o_def.groups.not_in_creative_inventory = 1 + o_def.groups.orphan_leaves = 1 + o_def._mcl_shears_drop = {mod .. ":" .. subname} + o_def._mcl_silk_touch_drop = {mod .. ":" .. subname} + + minetest.register_node(mod .. ":" .. subname .. "_orphan", o_def) end -local register_sapling = function(subname, description, longdesc, tt_help, texture, selbox) - minetest.register_node("mcl_core:"..subname, { +function mcl_core.register_sapling(subname, description, longdesc, tt_help, texture, selbox) + + local mod = minetest.get_current_modname() + + if not tt_help then + tt_help = S("Needs soil and light to grow") + end + + minetest.register_node(mod..":"..subname, { description = description, _tt_help = tt_help, _doc_items_longdesc = longdesc, @@ -139,7 +262,11 @@ local register_sapling = function(subname, description, longdesc, tt_help, textu fixed = selbox }, stack_max = 64, - groups = {dig_immediate=3, plant=1,sapling=1,non_mycelium_plant=1,attached_node=1,dig_by_water=1,dig_by_piston=1,destroy_by_lava_flow=1,deco_block=1}, + groups = { + plant = 1, sapling = 1, non_mycelium_plant = 1, attached_node = 1, + deco_block = 1, dig_immediate = 3, dig_by_water = 1, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), on_construct = function(pos) local meta = minetest.get_meta(pos) @@ -149,9 +276,9 @@ local register_sapling = function(subname, description, longdesc, tt_help, textu local node_below = minetest.get_node_or_nil({x=pos.x,y=pos.y-1,z=pos.z}) if not node_below then return false end local nn = node_below.name - return ((minetest.get_item_group(nn, "grass_block") == 1) or - nn=="mcl_core:podzol" or nn=="mcl_core:podzol_snow" or - nn=="mcl_core:dirt") + return minetest.get_item_group(nn, "grass_block") == 1 or + nn == "mcl_core:podzol" or nn == "mcl_core:podzol_snow" or + nn == "mcl_core:dirt" or nn == "mcl_core:mycelium" or nn == "mcl_core:coarse_dirt" end), node_placement_prediction = "", _mcl_blast_resistance = 0, @@ -161,53 +288,55 @@ end --------------------- -register_tree_trunk("tree", S("Oak Wood"), S("Oak Bark"), S("The trunk of an oak tree."), "default_tree_top.png", "default_tree.png") -register_tree_trunk("darktree", S("Dark Oak Wood"), S("Dark Oak Bark"), S("The trunk of a dark oak tree."), "mcl_core_log_big_oak_top.png", "mcl_core_log_big_oak.png") -register_tree_trunk("acaciatree", S("Acacia Wood"), S("Acacia Bark"), S("The trunk of an acacia."), "default_acacia_tree_top.png", "default_acacia_tree.png") -register_tree_trunk("sprucetree", S("Spruce Wood"), S("Spruce Bark"), S("The trunk of a spruce tree."), "mcl_core_log_spruce_top.png", "mcl_core_log_spruce.png") -register_tree_trunk("birchtree", S("Birch Wood"), S("Birch Bark"), S("The trunk of a birch tree."), "mcl_core_log_birch_top.png", "mcl_core_log_birch.png") -register_tree_trunk("jungletree", S("Jungle Wood"), S("Jungle Bark"), S("The trunk of a jungle tree."), "default_jungletree_top.png", "default_jungletree.png") +mcl_core.register_tree_trunk("tree", S("Oak Wood"), S("Oak Bark"), S("The trunk of an oak tree."), "default_tree_top.png", "default_tree.png", "mcl_core:stripped_oak") +mcl_core.register_tree_trunk("darktree", S("Dark Oak Wood"), S("Dark Oak Bark"), S("The trunk of a dark oak tree."), "mcl_core_log_big_oak_top.png", "mcl_core_log_big_oak.png", "mcl_core:stripped_dark_oak") +mcl_core.register_tree_trunk("acaciatree", S("Acacia Wood"), S("Acacia Bark"), S("The trunk of an acacia."), "default_acacia_tree_top.png", "default_acacia_tree.png", "mcl_core:stripped_acacia") +mcl_core.register_tree_trunk("sprucetree", S("Spruce Wood"), S("Spruce Bark"), S("The trunk of a spruce tree."), "mcl_core_log_spruce_top.png", "mcl_core_log_spruce.png", "mcl_core:stripped_spruce") +mcl_core.register_tree_trunk("birchtree", S("Birch Wood"), S("Birch Bark"), S("The trunk of a birch tree."), "mcl_core_log_birch_top.png", "mcl_core_log_birch.png", "mcl_core:stripped_birch") +mcl_core.register_tree_trunk("jungletree", S("Jungle Wood"), S("Jungle Bark"), S("The trunk of a jungle tree."), "default_jungletree_top.png", "default_jungletree.png", "mcl_core:stripped_jungle") -register_wooden_planks("wood", S("Oak Wood Planks"), {"default_wood.png"}) -register_wooden_planks("darkwood", S("Dark Oak Wood Planks"), {"mcl_core_planks_big_oak.png"}) -register_wooden_planks("junglewood", S("Jungle Wood Planks"), {"default_junglewood.png"}) -register_wooden_planks("sprucewood", S("Spruce Wood Planks"), {"mcl_core_planks_spruce.png"}) -register_wooden_planks("acaciawood", S("Acacia Wood Planks"), {"default_acacia_wood.png"}) -register_wooden_planks("birchwood", S("Birch Wood Planks"), {"mcl_core_planks_birch.png"}) +mcl_core.register_stripped_trunk("stripped_oak", S("Stripped Oak Log"), S("Stripped Oak Wood"), S("The stripped trunk of an oak tree."), S("The stripped wood of an oak tree."), "mcl_core_stripped_oak_top.png", "mcl_core_stripped_oak_side.png") +mcl_core.register_stripped_trunk("stripped_acacia", S("Stripped Acacia Log"), S("Stripped Acacia Wood"), S("The stripped trunk of an acacia tree."), S("The stripped wood of an acacia tree."), "mcl_core_stripped_acacia_top.png", "mcl_core_stripped_acacia_side.png") +mcl_core.register_stripped_trunk("stripped_dark_oak", S("Stripped Dark Oak Log"), S("Stripped Dark Oak Wood"), S("The stripped trunk of a dark oak tree."), S("The stripped wood of a dark oak tree."), "mcl_core_stripped_dark_oak_top.png", "mcl_core_stripped_dark_oak_side.png") +mcl_core.register_stripped_trunk("stripped_birch", S("Stripped Birch Log"), S("Stripped Birch Wood"), S("The stripped trunk of a birch tree."), S("The stripped wood of a birch tree."), "mcl_core_stripped_birch_top.png", "mcl_core_stripped_birch_side.png") +mcl_core.register_stripped_trunk("stripped_spruce", S("Stripped Spruce Log"), S("Stripped Spruce Wood"), S("The stripped trunk of a spruce tree."), S("The stripped wood of a spruce tree."), "mcl_core_stripped_spruce_top.png", "mcl_core_stripped_spruce_side.png") +mcl_core.register_stripped_trunk("stripped_jungle", S("Stripped Jungle Log"), S("Stripped Jungle Wood"), S("The stripped trunk of a jungle tree."), S("The stripped wood of a jungle tree."),"mcl_core_stripped_jungle_top.png", "mcl_core_stripped_jungle_side.png") +mcl_core.register_wooden_planks("wood", S("Oak Wood Planks"), {"default_wood.png"}) +mcl_core.register_wooden_planks("darkwood", S("Dark Oak Wood Planks"), {"mcl_core_planks_big_oak.png"}) +mcl_core.register_wooden_planks("junglewood", S("Jungle Wood Planks"), {"default_junglewood.png"}) +mcl_core.register_wooden_planks("sprucewood", S("Spruce Wood Planks"), {"mcl_core_planks_spruce.png"}) +mcl_core.register_wooden_planks("acaciawood", S("Acacia Wood Planks"), {"default_acacia_wood.png"}) +mcl_core.register_wooden_planks("birchwood", S("Birch Wood Planks"), {"mcl_core_planks_birch.png"}) +local tt_help_sapling_large = S("Needs soil and light to grow") .. "\n" .. S("2×2 saplings = large tree") -register_sapling("sapling", S("Oak Sapling"), +mcl_core.register_sapling("sapling", S("Oak Sapling"), S("When placed on soil (such as dirt) and exposed to light, an oak sapling will grow into an oak after some time."), - S("Needs soil and light to grow"), - "default_sapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16}) -register_sapling("darksapling", S("Dark Oak Sapling"), + nil, "default_sapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16}) +mcl_core.register_sapling("darksapling", S("Dark Oak Sapling"), S("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."), S("Needs soil and light to grow") .. "\n" .. S("2×2 saplings required"), "mcl_core_sapling_big_oak.png", {-5/16, -0.5, -5/16, 5/16, 7/16, 5/16}) -register_sapling("junglesapling", S("Jungle Sapling"), +mcl_core.register_sapling("junglesapling", S("Jungle Sapling"), S("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."), - S("Needs soil and light to grow") .. "\n" .. S("2×2 saplings = large tree"), - "default_junglesapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16}) -register_sapling("acaciasapling", S("Acacia Sapling"), + tt_help_sapling_large, "default_junglesapling.png", {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16}) +mcl_core.register_sapling("acaciasapling", S("Acacia Sapling"), S("When placed on soil (such as dirt) and exposed to light, an acacia sapling will grow into an acacia after some time."), - S("Needs soil and light to grow"), - "default_acacia_sapling.png", {-5/16, -0.5, -5/16, 5/16, 4/16, 5/16}) -register_sapling("sprucesapling", S("Spruce Sapling"), + nil, "default_acacia_sapling.png", {-5/16, -0.5, -5/16, 5/16, 4/16, 5/16}) +mcl_core.register_sapling("sprucesapling", S("Spruce Sapling"), S("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."), - S("Needs soil and light to grow") .. "\n" .. S("2×2 saplings = large tree"), - "mcl_core_sapling_spruce.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16}) -register_sapling("birchsapling", S("Birch Sapling"), + tt_help_sapling_large, "mcl_core_sapling_spruce.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16}) +mcl_core.register_sapling("birchsapling", S("Birch Sapling"), S("When placed on soil (such as dirt) and exposed to light, a birch sapling will grow into a birch after some time."), - S("Needs soil and light to grow"), - "mcl_core_sapling_birch.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16}) + nil, "mcl_core_sapling_birch.png", {-4/16, -0.5, -4/16, 4/16, 0.5, 4/16}) -register_leaves("leaves", S("Oak Leaves"), S("Oak leaves are grown from oak trees."), {"default_leaves.png"}, "mcl_core:sapling", true, {20, 16, 12, 10}) -register_leaves("darkleaves", S("Dark Oak Leaves"), S("Dark oak leaves are grown from dark oak trees."), {"mcl_core_leaves_big_oak.png"}, "mcl_core:darksapling", true, {20, 16, 12, 10}) -register_leaves("jungleleaves", S("Jungle Leaves"), S("Jungle leaves are grown from jungle trees."), {"default_jungleleaves.png"}, "mcl_core:junglesapling", false, {40, 26, 32, 24, 10}) -register_leaves("acacialeaves", S("Acacia Leaves"), S("Acacia leaves are grown from acacia trees."), {"default_acacia_leaves.png"}, "mcl_core:acaciasapling", false, {20, 16, 12, 10}) -register_leaves("spruceleaves", S("Spruce Leaves"), S("Spruce leaves are grown from spruce trees."), {"mcl_core_leaves_spruce.png"}, "mcl_core:sprucesapling", false, {20, 16, 12, 10}) -register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from birch trees."), {"mcl_core_leaves_birch.png"}, "mcl_core:birchsapling", false, {20, 16, 12, 10}) +mcl_core.register_leaves("leaves", S("Oak Leaves"), S("Oak leaves are grown from oak trees."), {"default_leaves.png"}, "#48B518", "color", "mcl_core_palette_foliage.png", "mcl_core:sapling", true, {20, 16, 12, 10}, 1) +mcl_core.register_leaves("darkleaves", S("Dark Oak Leaves"), S("Dark oak leaves are grown from dark oak trees."), {"mcl_core_leaves_big_oak.png"}, "#48B518", "color", "mcl_core_palette_foliage.png", "mcl_core:darksapling", true, {20, 16, 12, 10}, 1) +mcl_core.register_leaves("jungleleaves", S("Jungle Leaves"), S("Jungle leaves are grown from jungle trees."), {"default_jungleleaves.png"}, "#48B518", "color", "mcl_core_palette_foliage.png", "mcl_core:junglesapling", false, {40, 26, 32, 24, 10}, 1) +mcl_core.register_leaves("acacialeaves", S("Acacia Leaves"), S("Acacia leaves are grown from acacia trees."), {"default_acacia_leaves.png"}, "#48B518", "color", "mcl_core_palette_foliage.png", "mcl_core:acaciasapling", false, {20, 16, 12, 10}, 1) +mcl_core.register_leaves("spruceleaves", S("Spruce Leaves"), S("Spruce leaves are grown from spruce trees."), {"mcl_core_leaves_spruce.png"}, "#619961", "none", nil, "mcl_core:sprucesapling", false, {20, 16, 12, 10}, 0) +mcl_core.register_leaves("birchleaves", S("Birch Leaves"), S("Birch leaves are grown from birch trees."), {"mcl_core_leaves_birch.png"}, "#80A755", "none", nil, "mcl_core:birchsapling", false, {20, 16, 12, 10}, 0) diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts new file mode 100644 index 000000000..fff8fddc4 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_birch_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts new file mode 100644 index 000000000..55b8dca0f Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_bush_oak_leaves_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts index c015d242d..44ac2b538 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts new file mode 100644 index 000000000..4564048d2 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts new file mode 100644 index 000000000..c604a2d9c Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_3.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts new file mode 100644 index 000000000..7ce8af2fd Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_4.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts index ba4f9fa26..eefbeb4fe 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_1.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts index df0114f6b..817ca023e 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_2.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts new file mode 100644 index 000000000..c22f49334 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_3.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts new file mode 100644 index 000000000..fa3d74567 Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_jungle_tree_huge_4.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts new file mode 100644 index 000000000..1f793f47c Binary files /dev/null and b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_classic_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts index 3308dba4a..955f70eb5 100644 Binary files a/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts and b/mods/ITEMS/mcl_core/schematics/mcl_core_oak_swamp.mts differ diff --git a/mods/ITEMS/mcl_core/textures/default_acacia_leaves.png b/mods/ITEMS/mcl_core/textures/default_acacia_leaves.png deleted file mode 100644 index a24e58f16..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_acacia_leaves.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_acacia_tree.png b/mods/ITEMS/mcl_core/textures/default_acacia_tree.png deleted file mode 100644 index 2f62228c9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_acacia_tree.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_brick.png b/mods/ITEMS/mcl_core/textures/default_brick.png deleted file mode 100644 index 785554395..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_brick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_clay.png b/mods/ITEMS/mcl_core/textures/default_clay.png deleted file mode 100644 index 63d2ff18c..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_clay.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_coal_block.png b/mods/ITEMS/mcl_core/textures/default_coal_block.png deleted file mode 100644 index cf3579499..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_coal_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_cobble.png b/mods/ITEMS/mcl_core/textures/default_cobble.png deleted file mode 100644 index 60750edaa..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_cobble.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_dirt.png b/mods/ITEMS/mcl_core/textures/default_dirt.png deleted file mode 100644 index e60fa9b3b..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_dirt.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_dry_grass.png b/mods/ITEMS/mcl_core/textures/default_dry_grass.png deleted file mode 100644 index e610678a6..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_dry_grass.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png b/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png deleted file mode 100644 index b12d06e7b..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_dry_grass_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_gravel.png b/mods/ITEMS/mcl_core/textures/default_gravel.png deleted file mode 100644 index 8108db716..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_gravel.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_ice.png b/mods/ITEMS/mcl_core/textures/default_ice.png deleted file mode 100644 index e741bccc6..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_ice.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_jungleleaves.png b/mods/ITEMS/mcl_core/textures/default_jungleleaves.png deleted file mode 100644 index d92a6e089..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_jungleleaves.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_jungletree_top.png b/mods/ITEMS/mcl_core/textures/default_jungletree_top.png deleted file mode 100644 index a2fa3a33f..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_jungletree_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_leaves.png b/mods/ITEMS/mcl_core/textures/default_leaves.png deleted file mode 100644 index 7b01275f9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_leaves.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_mossycobble.png b/mods/ITEMS/mcl_core/textures/default_mossycobble.png deleted file mode 100644 index 0cbd5a5ba..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_mossycobble.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_obsidian.png b/mods/ITEMS/mcl_core/textures/default_obsidian.png deleted file mode 100644 index a7f1d8896..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_obsidian.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_paper.png b/mods/ITEMS/mcl_core/textures/default_paper.png deleted file mode 100644 index af90416b5..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_paper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_papyrus.png b/mods/ITEMS/mcl_core/textures/default_papyrus.png deleted file mode 100644 index b6e2062ec..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_papyrus.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_sand.png b/mods/ITEMS/mcl_core/textures/default_sand.png deleted file mode 100644 index 7fc254aa2..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_sand.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_stone.png b/mods/ITEMS/mcl_core/textures/default_stone.png deleted file mode 100644 index 8831ffb9b..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_stone.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_stone_brick.png b/mods/ITEMS/mcl_core/textures/default_stone_brick.png deleted file mode 100644 index 318b91b3d..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_stone_brick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png b/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png deleted file mode 100644 index 1ad7aeb31..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_water_flowing_animated.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_water_source_animated.png b/mods/ITEMS/mcl_core/textures/default_water_source_animated.png deleted file mode 100644 index 5d4582244..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_water_source_animated.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/default_wood.png b/mods/ITEMS/mcl_core/textures/default_wood.png deleted file mode 100644 index ee97b8d8a..000000000 Binary files a/mods/ITEMS/mcl_core/textures/default_wood.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_andesite_smooth.png b/mods/ITEMS/mcl_core/textures/mcl_core_andesite_smooth.png deleted file mode 100644 index ff082af62..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_andesite_smooth.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_apple_golden.png b/mods/ITEMS/mcl_core/textures/mcl_core_apple_golden.png deleted file mode 100644 index 639afd908..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_apple_golden.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_bedrock.png b/mods/ITEMS/mcl_core/textures/mcl_core_bedrock.png deleted file mode 100644 index a96b21aca..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_bedrock.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_bone_block_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_bone_block_top.png deleted file mode 100644 index 9fc994cc3..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_bone_block_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_bottom.png b/mods/ITEMS/mcl_core/textures/mcl_core_cactus_bottom.png deleted file mode 100644 index 610a0aec5..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_cactus_side.png deleted file mode 100644 index 1a75eacdf..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_cactus_top.png deleted file mode 100644 index 988ce176f..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_cactus_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_charcoal.png b/mods/ITEMS/mcl_core/textures/mcl_core_charcoal.png deleted file mode 100644 index 9e2ae284e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_charcoal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_coarse_dirt.png b/mods/ITEMS/mcl_core/textures/mcl_core_coarse_dirt.png deleted file mode 100644 index a39ccef81..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_coarse_dirt.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_diorite.png b/mods/ITEMS/mcl_core/textures/mcl_core_diorite.png deleted file mode 100644 index 86c5a890e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_diorite.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png deleted file mode 100644 index 0d89941ff..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_top.png deleted file mode 100644 index 71bee0435..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_dirt_podzol_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_emerald_block.png b/mods/ITEMS/mcl_core/textures/mcl_core_emerald_block.png deleted file mode 100644 index c400a7bc9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_emerald_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_1.png b/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_1.png deleted file mode 100644 index fd3756ebf..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_2.png b/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_2.png deleted file mode 100644 index e90d8dd8f..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_3.png b/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_3.png deleted file mode 100644 index b6b93e88b..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_granite.png b/mods/ITEMS/mcl_core/textures/mcl_core_granite.png deleted file mode 100644 index e06aebfde..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_granite.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_side_overlay.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_side_overlay.png deleted file mode 100644 index a1cc154d9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_side_overlay.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_top.png deleted file mode 100644 index f657bb811..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_block_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_side.png deleted file mode 100644 index ac25e45c4..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_top.png deleted file mode 100644 index 22a7626a1..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_path_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png b/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png deleted file mode 100644 index 9830db7eb..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_grass_side_snowed.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_ice_packed.png b/mods/ITEMS/mcl_core/textures/mcl_core_ice_packed.png deleted file mode 100644 index 7623d45de..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_ice_packed.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_iron_nugget.png b/mods/ITEMS/mcl_core/textures/mcl_core_iron_nugget.png deleted file mode 100644 index bbb89d6a3..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_iron_nugget.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_iron_ore.png b/mods/ITEMS/mcl_core/textures/mcl_core_iron_ore.png deleted file mode 100644 index f83b8303e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_iron_ore.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_lapis_ore.png b/mods/ITEMS/mcl_core/textures/mcl_core_lapis_ore.png deleted file mode 100644 index f4bc61c8e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_lapis_ore.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_big_oak.png b/mods/ITEMS/mcl_core/textures/mcl_core_leaves_big_oak.png deleted file mode 100644 index 859d14ac8..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_big_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_birch.png b/mods/ITEMS/mcl_core/textures/mcl_core_leaves_birch.png deleted file mode 100644 index d83adabc7..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_spruce.png b/mods/ITEMS/mcl_core/textures/mcl_core_leaves_spruce.png deleted file mode 100644 index 1407ff7e3..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_leaves_spruce.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_big_oak.png b/mods/ITEMS/mcl_core/textures/mcl_core_log_big_oak.png deleted file mode 100644 index 9b7a85ce9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_log_big_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_birch.png b/mods/ITEMS/mcl_core/textures/mcl_core_log_birch.png deleted file mode 100644 index b53eb796e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_log_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_side.png b/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_side.png deleted file mode 100644 index 756a92780..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_top.png deleted file mode 100644 index 6581f19cd..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_mycelium_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_palette_grass.png b/mods/ITEMS/mcl_core/textures/mcl_core_palette_grass.png deleted file mode 100644 index 116d0cb86..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_palette_grass.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_planks_birch.png b/mods/ITEMS/mcl_core/textures/mcl_core_planks_birch.png deleted file mode 100644 index ab3ae8f7f..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_planks_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sand.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sand.png deleted file mode 100644 index 4305cffa2..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sand.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_bottom.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_bottom.png deleted file mode 100644 index f6e6ea499..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_carved.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_carved.png deleted file mode 100644 index fc8b2a09e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_carved.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_normal.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_normal.png deleted file mode 100644 index 446f35cd2..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_normal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_smooth.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_smooth.png deleted file mode 100644 index f6e6ea499..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_smooth.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_top.png deleted file mode 100644 index 807094464..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_red_sandstone_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_redstone_ore.png b/mods/ITEMS/mcl_core/textures/mcl_core_redstone_ore.png deleted file mode 100644 index f26a9cd7f..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_redstone_ore.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_bottom.png b/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_bottom.png deleted file mode 100644 index 51d4174d4..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_carved.png b/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_carved.png deleted file mode 100644 index bbe724c5e..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_carved.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_normal.png b/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_normal.png deleted file mode 100644 index 5a92d4ccc..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_normal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_smooth.png b/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_smooth.png deleted file mode 100644 index 51d4174d4..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_smooth.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_top.png b/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_top.png deleted file mode 100644 index cb3e7aa1c..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_sandstone_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_slime.png b/mods/ITEMS/mcl_core/textures/mcl_core_slime.png deleted file mode 100644 index a098a90b0..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_slime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_cracked.png b/mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_cracked.png deleted file mode 100644 index 38fcb1e8c..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_cracked.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_vine.png b/mods/ITEMS/mcl_core/textures/mcl_core_vine.png deleted file mode 100644 index 831f9d2a9..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_vine.png and /dev/null differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_web.png b/mods/ITEMS/mcl_core/textures/mcl_core_web.png deleted file mode 100644 index e2233c1b2..000000000 Binary files a/mods/ITEMS/mcl_core/textures/mcl_core_web.png and /dev/null differ diff --git a/mods/ITEMS/mcl_crafting_table/API.md b/mods/ITEMS/mcl_crafting_table/API.md new file mode 100644 index 000000000..45aa0c9ce --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/API.md @@ -0,0 +1,6 @@ +# mcl_crafting_table +Add a node which allow players to craft more complex things. + +## mcl_crafting_table.show_crafting_form(player) +Show the crafting form to a player. +Used in the node registration, but can be used by external mods. \ No newline at end of file diff --git a/mods/ITEMS/mcl_crafting_table/depends.txt b/mods/ITEMS/mcl_crafting_table/depends.txt deleted file mode 100644 index 97aafc582..000000000 --- a/mods/ITEMS/mcl_crafting_table/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_formspec -mcl_sounds diff --git a/mods/ITEMS/mcl_crafting_table/description.txt b/mods/ITEMS/mcl_crafting_table/description.txt deleted file mode 100644 index 5f2a79786..000000000 --- a/mods/ITEMS/mcl_crafting_table/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a crafting table. diff --git a/mods/ITEMS/mcl_crafting_table/init.lua b/mods/ITEMS/mcl_crafting_table/init.lua index 09c4838cd..7f6b9ccc5 100644 --- a/mods/ITEMS/mcl_crafting_table/init.lua +++ b/mods/ITEMS/mcl_crafting_table/init.lua @@ -1,57 +1,70 @@ -local S = minetest.get_translator("mcl_crafting_table") - -minetest.register_node("mcl_crafting_table:crafting_table", { - description = S("Crafting Table"), - _tt_help = S("3×3 crafting grid"), - _doc_items_longdesc = S("A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts."), - _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"}, - paramtype2 = "facedir", - groups = {handy=1,axey=1, deco_block=1, material_wood=1,flammable=-1}, - on_rightclick = function(pos, node, player, itemstack) - player:get_inventory():set_width("craft", 3) - player:get_inventory():set_size("craft", 9) - - local form = "size[9,8.75]".. - "image[4.7,1.5;1.5,1;gui_crafting_arrow.png]".. - "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[1.75,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Crafting"))).."]".. - "list[current_player;craft;1.75,0.5;3,3;]".. - mcl_formspec.get_itemslot_bg(1.75,0.5,3,3).. - "list[current_player;craftpreview;6.1,1.5;1,1;]".. - mcl_formspec.get_itemslot_bg(6.1,1.5,1,1).. - "image_button[0.75,1.5;1,1;craftguide_book.png;__mcl_craftguide;]".. - "tooltip[__mcl_craftguide;"..minetest.formspec_escape(S("Recipe book")).."]".. - "listring[current_player;main]".. - "listring[current_player;craft]" - - minetest.show_formspec(player:get_player_name(), "main", form) - end, - sounds = mcl_sounds.node_sound_wood_defaults(), - _mcl_blast_resistance = 2.5, - _mcl_hardness = 2.5, -}) - -minetest.register_craft({ - output = "mcl_crafting_table:crafting_table", - recipe = { - {"group:wood", "group:wood"}, - {"group:wood", "group:wood"} - } -}) - -minetest.register_craft({ - type = "fuel", - recipe = "mcl_crafting_table:crafting_table", - burntime = 15, -}) - -minetest.register_alias("crafting:workbench", "mcl_crafting_table:crafting_table") -minetest.register_alias("mcl_inventory:workbench", "mcl_crafting_table:crafting_table") +local S = minetest.get_translator(minetest.get_current_modname()) +local formspec_escape = minetest.formspec_escape +local show_formspec = minetest.show_formspec +local C = minetest.colorize +local text_color = "#313131" +local itemslot_bg = mcl_formspec.get_itemslot_bg + +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) + + 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]" + ) +end + +minetest.register_node("mcl_crafting_table:crafting_table", { + description = S("Crafting Table"), + _tt_help = S("3×3 crafting grid"), + _doc_items_longdesc = S("A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts."), + _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"}, + paramtype2 = "facedir", + 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) + end + end, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5, +}) + +minetest.register_craft({ + output = "mcl_crafting_table:crafting_table", + recipe = { + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"} + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_crafting_table:crafting_table", + burntime = 15, +}) + +minetest.register_alias("crafting:workbench", "mcl_crafting_table:crafting_table") +minetest.register_alias("mcl_inventory:workbench", "mcl_crafting_table:crafting_table") diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr new file mode 100644 index 000000000..03bd702b1 --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.ja.tr @@ -0,0 +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のクラフトグリッドが表示されます。 +Recipe book=レシピ本 +Crafting=クラフト +Inventory=インベントリ +3×3 crafting grid=3×3のクラフトグリッド diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pl.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pl.tr new file mode 100644 index 000000000..aed33bf6c --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_crafting_table +Crafting Table=Stół rzemieślniczy +A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Stół rzemieślniczy jest blokiem, który daje dostęp do siatki wytwarzania rozmiaru 3×3, co daje dostęp do zaawansowanego wytwarzania. +Rightclick the crafting table to access the 3×3 crafting grid.=Kliknij prawym przyciskiem na stół rzemieślniczy aby zyskać dostęp do siatki wytwarzania rozmiaru 3×3. +Recipe book=Księga receptur +Crafting=Wytwarzanie +Inventory=Ekwipunek +3×3 crafting grid=Siatka wytwarzania 3×3 diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pt_BR.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pt_BR.tr new file mode 100644 index 000000000..12c74f9e9 --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.pt_BR.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_crafting_table +Crafting Table=Bancada de Trabalho +A crafting table is a block which grants you access to a 3×3 crafting grid which allows you to perform advanced crafts.=Uma bancada de trabalho é um bloco que lhe garante acesso a uma grade de construção de 3x3 e que permite produzir coisas mais avançadas. +Rightclick the crafting table to access the 3×3 crafting grid.=Aperte com o botão direito na mesa de trabalho para acessar a grade de trabalho de 3x3. +Recipe book=Livro de receitas +Crafting=Construindo +Inventory=Inventário +3×3 crafting grid=Grade de construção 3x3 diff --git a/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.zh_TW.tr b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.zh_TW.tr new file mode 100644 index 000000000..b393d5a48 --- /dev/null +++ b/mods/ITEMS/mcl_crafting_table/locale/mcl_crafting_table.zh_TW.tr @@ -0,0 +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合成網格。 +Recipe book=合成教學 +Crafting=合成 +Inventory=物品欄 +3×3 crafting grid=3×3合成網格 diff --git a/mods/ITEMS/mcl_crafting_table/mod.conf b/mods/ITEMS/mcl_crafting_table/mod.conf index db5ab14a1..149d1c982 100644 --- a/mods/ITEMS/mcl_crafting_table/mod.conf +++ b/mods/ITEMS/mcl_crafting_table/mod.conf @@ -1 +1,3 @@ name = mcl_crafting_table +description = Adds a crafting table. +depends = mcl_init, mcl_formspec, mcl_sounds, mcl_colors diff --git a/mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_top.png b/mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_top.png deleted file mode 100644 index 5d85e5177..000000000 Binary files a/mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_crimson/README.md b/mods/ITEMS/mcl_crimson/README.md new file mode 100644 index 000000000..45c475c11 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/README.md @@ -0,0 +1,10 @@ +# Mineclone Crimson originally by debiankaios. Modified by MCL2 dev team + +Textures are from PixelPerfection other than: + +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 diff --git a/mods/ITEMS/mcl_crimson/init.lua b/mods/ITEMS/mcl_crimson/init.lua new file mode 100644 index 000000000..740f74a5b --- /dev/null +++ b/mods/ITEMS/mcl_crimson/init.lua @@ -0,0 +1,809 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +-- Warped and Crimson fungus +-- 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 function generate_warped_tree(pos) + minetest.place_schematic(pos,modpath.."/schematics/warped_fungus_1.mts","random",nil,false,"place_center_x,place_center_z") +end + +function generate_crimson_tree(pos) + minetest.place_schematic(pos,modpath.."/schematics/crimson_fungus_1.mts","random",nil,false,"place_center_x,place_center_z") +end + +function grow_vines(pos, moreontop ,vine, dir) + if dir == nil then dir = 1 end + local n + repeat + pos = vector.offset(pos,0,dir,0) + n = minetest.get_node(pos) + if n.name == "air" then + for i=0,math.max(moreontop,1) do + if minetest.get_node(pos).name == "air" then + minetest.set_node(vector.offset(pos,0,i*dir,0),{name=vine}) + end + end + break + end + until n.name ~= "air" and n.name ~= vine +end + +local nether_plants = { + ["mcl_crimson:crimson_nylium"] = { + "mcl_crimson:crimson_roots", + "mcl_crimson:crimson_fungus", + "mcl_crimson:warped_fungus", + }, + ["mcl_crimson:warped_nylium"] = { + "mcl_crimson:warped_roots", + "mcl_crimson:warped_fungus", + "mcl_crimson:twisting_vines", + "mcl_crimson:nether_sprouts", + }, +} + +local function has_nylium_neighbor(pos) + local p = minetest.find_node_near(pos,1,{"mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium"}) + if p then + return minetest.get_node(p) + end +end + +local function spread_nether_plants(pos,node) + local n = node.name + local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-5,-3,-5),vector.offset(pos,5,3,5),{n}) + table.shuffle(nn) + nn[1] = pos + for i=1,math.random(1,math.min(#nn,12)) do + local p = vector.offset(nn[i],0,1,0) + if minetest.get_node(p).name == "air" then + minetest.set_node(p,{name=nether_plants[n][math.random(#nether_plants[n])]}) + mcl_dye.add_bone_meal_particle(vector.offset(nn[i],0,1,0)) + end + end +end + +minetest.register_node("mcl_crimson:warped_fungus", { + description = S("Warped Fungus"), + _tt_help = S("Warped fungus is a mushroom found in the nether's warped forest."), + _doc_items_longdesc = S("Warped fungus is a mushroom found in the nether's warped forest."), + drawtype = "plantlike", + tiles = { "mcl_crimson_warped_fungus.png" }, + inventory_image = "mcl_crimson_warped_fungus.png", + wield_image = "mcl_crimson_warped_fungus.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1,compostability=65}, + light_source = 1, + sounds = mcl_sounds.node_sound_leaves_defaults(), + node_placement_prediction = "", + on_rightclick = function(pos, node, pointed_thing, player, itemstack) + if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + local nodepos = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) + if nodepos.name == "mcl_crimson:warped_nylium" or nodepos.name == "mcl_nether:netherrack" then + local random = math.random(1, 5) + if random == 1 then + minetest.remove_node(pos) + generate_warped_tree(pos) + end + end + end + end, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:warped_fungus", { + name = "warped fungus", + desc = S("Warped Fungus"), + image = "mcl_crimson_warped_fungus.png", +}) + +minetest.register_node("mcl_crimson:twisting_vines", { + description = S("Twisting Vines"), + drawtype = "plantlike", + tiles = { "mcl_crimson_twisting_vines_plant.png" }, + inventory_image = "mcl_crimson_twisting_vines.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + climbable = true, + buildable_to = true, + groups = {dig_immediate=3, shearsy=1, vines=1, dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, deco_block=1, compostability=50}, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then + minetest.record_protection_violation(vector.offset(pos,0,1,0), pn) + return itemstack + end + if clicker:get_wielded_item():get_name() == "mcl_crimson:twisting_vines" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, 1, "mcl_crimson:twisting_vines") + local idef = itemstack:get_definition() + local itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing) + if success then + if idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) + end + end + + elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, math.random(1, 3),"mcl_crimson:twisting_vines") + end + return itemstack + end, + on_dig = function(pos, node, digger) + local above = vector.offset(pos,0,1,0) + local abovenode = minetest.get_node(above) + minetest.node_dig(pos, node, digger) + if abovenode.name == node.name and (not mcl_core.check_vines_supported(above, abovenode)) then + minetest.registered_nodes[node.name].on_dig(above, node, digger) + end + end, + + drop = { + max_items = 1, + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 3}, + }, + }, + _mcl_shears_drop = true, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 3}, + }, + items = { + {items = {"mcl_crimson:twisting_vines"}, rarity = 1.8181818181818181}, + }, + "mcl_crimson:twisting_vines", + "mcl_crimson:twisting_vines", + }, + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.2, +}) + +minetest.register_node("mcl_crimson:weeping_vines", { + description = S("Weeping Vines"), + drawtype = "plantlike", + tiles = { "mcl_crimson_weeping_vines.png" }, + inventory_image = "mcl_crimson_weeping_vines.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + climbable = true, + buildable_to = true, + groups = {dig_immediate=3, shearsy=1, vines=1, dig_by_water=1, destroy_by_lava_flow=1, dig_by_piston=1, deco_block=1, compostability=50}, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, 0.5, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(vector.offset(pos,0,1,0), pn or "") then + minetest.record_protection_violation(vector.offset(pos,0,1,0), pn) + return itemstack + end + if clicker:get_wielded_item():get_name() == "mcl_crimson:weeping_vines" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, 1, "mcl_crimson:weeping_vines", -1) + local idef = itemstack:get_definition() + local itemstack, success = minetest.item_place_node(itemstack, placer, pointed_thing) + if success then + if idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) + end + end + + elseif clicker:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + grow_vines(pos, math.random(1, 3),"mcl_crimson:weeping_vines", -1) + end + return itemstack + end, + + on_dig = function(pos, node, digger) + 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, + drop = { + max_items = 1, + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 3}, + }, + }, + _mcl_shears_drop = true, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 3}, + }, + items = { + {items = {"mcl_crimson:weeping_vines"}, rarity = 1.8181818181818181}, + }, + "mcl_crimson:weeping_vines", + "mcl_crimson:weeping_vines", + }, + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.2, +}) + +minetest.register_node("mcl_crimson:nether_sprouts", { + description = S("Nether Sprouts"), + drawtype = "plantlike", + tiles = { "mcl_crimson_nether_sprouts.png" }, + inventory_image = "mcl_crimson_nether_sprouts.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1,shearsy=1,compostability=50}, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -4/16, -0.5, -4/16, 4/16, 0, 4/16 }, + }, + node_placement_prediction = "", + drop = "", + _mcl_shears_drop = true, + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +minetest.register_node("mcl_crimson:warped_roots", { + description = S("Warped Roots"), + drawtype = "plantlike", + tiles = { "mcl_crimson_warped_roots.png" }, + inventory_image = "mcl_crimson_warped_roots.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1,shearsy = 1,compostability=65}, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -6/16, -0.5, -6/16, 6/16, -4/16, 6/16 }, + }, + node_placement_prediction = "", + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:warped_roots", { + name = "warped roots", + desc = S("Warped Roots"), + image = "mcl_crimson_warped_roots.png", +}) + + +minetest.register_node("mcl_crimson:warped_wart_block", { + description = S("Warped Wart Block"), + tiles = {"mcl_crimson_warped_wart_block.png"}, + groups = {handy = 1, hoey = 7, swordy = 1, deco_block = 1, compostability = 85}, + _mcl_hardness = 1, + sounds = mcl_sounds.node_sound_leaves_defaults({ + footstep={name="default_dirt_footstep", gain=0.7}, + dug={name="default_dirt_footstep", gain=1.5}, + }), +}) + +minetest.register_node("mcl_crimson:shroomlight", { + description = S("Shroomlight"), + tiles = {"mcl_crimson_shroomlight.png"}, + groups = {handy = 1, hoey = 7, swordy = 1, deco_block = 1, compostability = 65}, + light_source = minetest.LIGHT_MAX, + _mcl_hardness = 1, + sounds = mcl_sounds.node_sound_leaves_defaults({ + footstep={name="default_dirt_footstep", gain=0.7}, + dug={name="default_dirt_footstep", gain=1.5}, + }), +}) + +minetest.register_node("mcl_crimson:warped_hyphae", { + description = S("Warped Hyphae"), + _doc_items_longdesc = S("The stem of a warped hyphae"), + _doc_items_hidden = false, + tiles = { + "mcl_crimson_warped_hyphae.png", + "mcl_crimson_warped_hyphae.png", + { + name = "mcl_crimson_warped_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_warped_hyphae", +}) + +minetest.register_node("mcl_crimson:warped_nylium", { + description = S("Warped Nylium"), + tiles = { + "mcl_crimson_warped_nylium.png", + "mcl_nether_netherrack.png", + "mcl_nether_netherrack.png^mcl_crimson_warped_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_warped_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_warped_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_warped_nylium_side.png", + }, + is_ground_content = true, + drop = "mcl_nether:netherrack", + groups = {pickaxey=1, building_block=1, material_stone=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_hardness = 0.4, + _mcl_blast_resistance = 0.4, + _mcl_silk_touch_drop = true, +}) + +--Stem bark, stripped stem and bark + +minetest.register_node("mcl_crimson:warped_hyphae_bark", { + description = S("Warped Hyphae Bark"), + _doc_items_longdesc = S("This is a decorative block surrounded by the bark of an hyphae."), + tiles = { + { + name = "mcl_crimson_warped_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_warped_hyphae_bark", +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_bark 3", + recipe = { + { "mcl_crimson:warped_hyphae", "mcl_crimson:warped_hyphae" }, + { "mcl_crimson:warped_hyphae", "mcl_crimson:warped_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:stripped_warped_hyphae", { + description = S("Stripped Warped Hyphae"), + _doc_items_longdesc = S("The stripped hyphae of a warped fungus"), + _doc_items_hidden = false, + tiles = {"mcl_crimson_warped_stem_stripped_top.png", "mcl_crimson_warped_stem_stripped_top.png", "mcl_crimson_warped_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:stripped_warped_hyphae_bark", { + description = S("Stripped Warped Hyphae Bark"), + _doc_items_longdesc = S("The stripped hyphae bark of a warped fungus"), + tiles = {"mcl_crimson_warped_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_craft({ + output = "mcl_crimson:stripped_warped_hyphae_bark 3", + recipe = { + { "mcl_crimson:stripped_warped_hyphae", "mcl_crimson:stripped_warped_hyphae" }, + { "mcl_crimson:stripped_warped_hyphae", "mcl_crimson:stripped_warped_hyphae" }, + }, +}) + +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}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_hardness = 2, +}) + +mcl_stairs.register_stair("warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", wood_stair_groups, false, S("Warped Stair")) +mcl_stairs.register_slab("warped_hyphae_wood", "mcl_crimson:warped_hyphae_wood", wood_slab_groups, false, S("Warped Slab")) + +minetest.register_craft({ + output = "mcl_crimson:warped_hyphae_wood 4", + recipe = { + {"mcl_crimson:warped_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_nylium 2", + recipe = { + {"mcl_crimson:warped_wart_block"}, + {"mcl_nether:netherrack"}, + }, +}) + +minetest.register_node("mcl_crimson:crimson_fungus", { + description = S("Crimson Fungus"), + _tt_help = S("Crimson fungus is a mushroom found in the nether's crimson forest."), + _doc_items_longdesc = S("Crimson fungus is a mushroom found in the nether's crimson forest."), + drawtype = "plantlike", + tiles = { "mcl_crimson_crimson_fungus.png" }, + inventory_image = "mcl_crimson_crimson_fungus.png", + wield_image = "mcl_crimson_crimson_fungus.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1,compostability=65}, + light_source = 1, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -3/16, -0.5, -3/16, 3/16, -2/16, 3/16 }, + }, + node_placement_prediction = "", + on_rightclick = function(pos, node, pointed_thing, player) + if pointed_thing:get_wielded_item():get_name() == "mcl_bone_meal:bone_meal" then + local nodepos = minetest.get_node(vector.offset(pos, 0, -1, 0)) + if nodepos.name == "mcl_crimson:crimson_nylium" or nodepos.name == "mcl_nether:netherrack" then + local random = math.random(1, 5) + if random == 1 then + minetest.remove_node(pos) + generate_crimson_tree(pos) + end + end + end + end, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_fungus", { + name = "crimson fungus", + desc = S("Crimson Fungus"), + image = "mcl_crimson_crimson_fungus.png", +}) + +minetest.register_node("mcl_crimson:crimson_roots", { + description = S("Crimson Roots"), + drawtype = "plantlike", + tiles = { "mcl_crimson_crimson_roots.png" }, + inventory_image = "mcl_crimson_crimson_roots.png", + sunlight_propagates = true, + paramtype = "light", + walkable = false, + buildable_to = true, + groups = {dig_immediate=3,vines=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,deco_block=1,shearsy = 1,compostability=65}, + sounds = mcl_sounds.node_sound_leaves_defaults(), + selection_box = { + type = "fixed", + fixed = { -6/16, -0.5, -6/16, 6/16, -4/16, 6/16 }, + }, + node_placement_prediction = "", + _mcl_silk_touch_drop = false, + _mcl_blast_resistance = 0, +}) + +mcl_flowerpots.register_potted_flower("mcl_crimson:crimson_roots", { + name = "crimson roots", + desc = S("Crimson Roots"), + image = "mcl_crimson_crimson_roots.png", +}) + +minetest.register_node("mcl_crimson:crimson_hyphae", { + description = S("Crimson Hyphae"), + _doc_items_longdesc = S("The stem of a crimson hyphae"), + _doc_items_hidden = false, + tiles = { + "mcl_crimson_crimson_hyphae.png", + "mcl_crimson_crimson_hyphae.png", + { + name = "mcl_crimson_crimson_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_crimson_hyphae", +}) + +--Stem bark, stripped stem and bark + +minetest.register_node("mcl_crimson:crimson_hyphae_bark", { + description = S("Crimson Hyphae Bark"), + _doc_items_longdesc = S("This is a decorative block surrounded by the bark of an hyphae."), + tiles = { + { + name = "mcl_crimson_crimson_hyphae_side.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0} + }, + }, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, + _mcl_stripped_variant = "mcl_crimson:stripped_crimson_hyphae_bark", +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_bark 3", + recipe = { + { "mcl_crimson:crimson_hyphae", "mcl_crimson:crimson_hyphae" }, + { "mcl_crimson:crimson_hyphae", "mcl_crimson:crimson_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:stripped_crimson_hyphae", { + description = S("Stripped Crimson Hyphae"), + _doc_items_longdesc = S("The stripped stem of a crimson hyphae"), + _doc_items_hidden = false, + tiles = {"mcl_crimson_crimson_stem_stripped_top.png", "mcl_crimson_crimson_stem_stripped_top.png", "mcl_crimson_crimson_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, tree = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:stripped_crimson_hyphae_bark", { + description = S("Stripped Crimson Hyphae Bark"), + _doc_items_longdesc = S("The stripped wood of a crimson hyphae"), + tiles = {"mcl_crimson_crimson_stem_stripped_side.png"}, + paramtype2 = "facedir", + on_place = mcl_util.rotate_axis, + groups = {handy = 1, axey = 1, bark = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 2, + _mcl_hardness = 2, +}) + +minetest.register_craft({ + output = "mcl_crimson:stripped_crimson_hyphae_bark 3", + recipe = { + { "mcl_crimson:stripped_crimson_hyphae", "mcl_crimson:stripped_crimson_hyphae" }, + { "mcl_crimson:stripped_crimson_hyphae", "mcl_crimson:stripped_crimson_hyphae" }, + }, +}) + +minetest.register_node("mcl_crimson:crimson_hyphae_wood", { + description = S("Crimson Hyphae Wood"), + tiles = {"mcl_crimson_crimson_hyphae_wood.png"}, + groups = {handy = 5, axey = 1, wood = 1, building_block = 1, material_wood = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_hardness = 2, +}) + +minetest.register_node("mcl_crimson:crimson_nylium", { + description = S("Crimson Nylium"), + tiles = { + "mcl_crimson_crimson_nylium.png", + "mcl_nether_netherrack.png", + "mcl_nether_netherrack.png^mcl_crimson_crimson_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_crimson_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_crimson_nylium_side.png", + "mcl_nether_netherrack.png^mcl_crimson_crimson_nylium_side.png", + }, + groups = {pickaxey = 1, building_block = 1, material_stone = 1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = true, + drop = "mcl_nether:netherrack", + _mcl_hardness = 0.4, + _mcl_blast_resistance = 0.4, + _mcl_silk_touch_drop = true, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_hyphae_wood 4", + recipe = { + {"mcl_crimson:crimson_hyphae"}, + }, +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_nylium 2", + recipe = { + {"mcl_nether:nether_wart"}, + {"mcl_nether:netherrack"}, + }, +}) + +mcl_stairs.register_stair("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_stair_groups, false, S("Crimson Stair")) +mcl_stairs.register_slab("crimson_hyphae_wood", "mcl_crimson:crimson_hyphae_wood", wood_slab_groups, false, S("Crimson Slab")) + +mcl_dye.register_on_bone_meal_apply(function(pt,user) + if not pt.type == "node" then return end + local node = minetest.get_node(pt.under) + if node.name == "mcl_nether:netherrack" then + local n = has_nylium_neighbor(pt.under) + if n then + minetest.set_node(pt.under,n) + end + elseif node.name == "mcl_crimson:warped_nylium" or node.name == "mcl_crimson:crimson_nylium" then + spread_nether_plants(pt.under,node) + 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}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = "mcl_crimson_crimson_door_bottom.png", + tiles_top = "mcl_crimson_crimson_door_top.png", + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_crimson:crimson_trapdoor", { + description = S("Crimson Trapdoor"), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_crimson_crimson_trapdoor.png", + tile_side = "mcl_crimson_crimson_hyphae_wood.png", + wield_image = "mcl_crimson_crimson_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "crimson_fence", + 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}, + minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_hardness, + minetest.registered_nodes["mcl_crimson:crimson_hyphae"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) + + +mcl_doors:register_door("mcl_crimson:warped_door", { + description = S("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}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = "mcl_crimson_warped_door_bottom.png", + tiles_top = "mcl_crimson_warped_door_top.png", + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_crimson:warped_trapdoor", { + description = S("Warped Trapdoor"), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_crimson_warped_trapdoor.png", + tile_side = "mcl_crimson_warped_hyphae_wood.png", + wield_image = "mcl_crimson_warped_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "warped_fence", + 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}, + minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_hardness, + minetest.registered_nodes["mcl_crimson:warped_hyphae"]._mcl_blast_resistance, + {"group:fence_wood"}, + mcl_sounds.node_sound_wood_defaults()) + +-- Door, Trapdoor, and Fence/Gate Crafting +local crimson_wood = "mcl_crimson:crimson_hyphae_wood" +local warped_wood = "mcl_crimson:warped_hyphae_wood" + +minetest.register_craft({ + output = "mcl_crimson:crimson_door 3", + recipe = { + {crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood} + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_door 3", + recipe = { + {warped_wood, warped_wood}, + {warped_wood, warped_wood}, + {warped_wood, warped_wood} + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_trapdoor 2", + recipe = { + {crimson_wood, crimson_wood, crimson_wood}, + {crimson_wood, crimson_wood, crimson_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_trapdoor 2", + recipe = { + {warped_wood, warped_wood, warped_wood}, + {warped_wood, warped_wood, warped_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_fence 3", + recipe = { + {crimson_wood, "mcl_core:stick", crimson_wood}, + {crimson_wood, "mcl_core:stick", crimson_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_fence 3", + recipe = { + {warped_wood, "mcl_core:stick", warped_wood}, + {warped_wood, "mcl_core:stick", warped_wood}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:crimson_fence_gate", + recipe = { + {"mcl_core:stick", crimson_wood, "mcl_core:stick"}, + {"mcl_core:stick", crimson_wood, "mcl_core:stick"}, + } +}) + +minetest.register_craft({ + output = "mcl_crimson:warped_fence_gate", + recipe = { + {"mcl_core:stick", warped_wood, "mcl_core:stick"}, + {"mcl_core:stick", warped_wood, "mcl_core:stick"}, + } +}) diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr new file mode 100644 index 000000000..480094dbd --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.de.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=Wirrpilz +Twisting Vines=Zwirbelranken +Nether Sprouts=Nethersprossen +Warped Roots=Wirrwurzeln +Warped Wart Block=Wirrwarzenblock +Shroomlight=Pilzlicht +Warped Hyphae=Wirrhyphe +Warped Nylium=Wirr-Nezel +Warped Checknode - only to check!=Wirr Checkblock - Nur zum checken! +Warped Hyphae Wood=Wirrhyphen Holz +Warped Stair=Wirrtreppe +Warped Slab=Wirrstufe +Double Warped Slab=Doppelte Wirrstufe +Crimson Fungus Mushroom=Karmesinpilz +Crimson Roots=Karmesinwurzeln +Crimson Hyphae=Karmesinhyphe +Crimson Hyphae Wood=Karmesinhyphenholz +Crimson Stair=Karmesintreppe +Crimson Slab=Karmesinstufe +Double Crimson Slab=Doppelte Karmesinstufe +Crimson Nylium=Karmesin-Nezel +Crimson Checknode - only to check!=Karmesin Checkblock - Nur zum checken! diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr new file mode 100644 index 000000000..16521d6a3 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.fr.tr @@ -0,0 +1,51 @@ +# textdomain: mcl_crimson + +Warped Fungus=Champignon tordu +Warped fungus is a mushroom found in the nether's warped forest.=Les champignons tordus se trouvent dans la forêt tordue du nether. +Twisting Vines=Liane tordue +Weeping Vines=Liane pleureuse +Nether Sprouts=Racines du Nether +Warped Roots=Racines tordues +Warped Wart Block=Bloc de verrues tordu +Shroomlight=Champilampe +Warped Hyphae=Tige tordue +The stem of a warped hyphae=La tige d'un champignon géant tordu +Warped Hyphae Bark=Hyphe tordue +This is a decorative block surrounded by the bark of an hyphae.=Ceci est un bloc décoratif entouré de l'écorce d'une tige +Stripped Warped Hyphae=Tige tordue dénudée +The stripped hyphae of a warped fungus=La tige dénudée d'un champignon géant tordu +Stripped Warped Hyphae Bark=Hyphe tordue dénudée +The stripped hyphae bark of a warped fungus=La tige dénudée d'un champignon géant tordu +Warped Nylium=Nylium tordu +Warped Checknode - only to check!=Bloc de vérification tordu - seulement pour vérifier ! +Warped Hyphae Wood=Planches tordues +Warped Stair=Escalier tordu +Warped Slab=Dalle tordue +Crimson Fungus=Champignon écarlate +Crimson fungus is a mushroom found in the nether's crimson forest.=Les champignons écarlates se trouvent dans la forêt écarlate du nether. +Crimson Roots=Racines écarlates +Crimson Hyphae=Tige écarlate +The stem of a crimson hyphae=La tige d'un champignon géant écarlate +Crimson Hyphae Bark=Hyphe écarlate +Stripped Crimson Hyphae=Tige écarlate dénudée +The stripped stem of a crimson hyphae=La tige dénudée d'un champignon géant écarlate +Stripped Crimson Hyphae Bark=Hyphe écarlate dénudée +The stripped wood of a crimson hyphae=La tige dénudée d'un champignon géant écarlate +Crimson Hyphae Wood=Planches écarlates +Crimson Stair=Escalier écarlate +Crimson Slab=Dalle écarlate +Double Crimson Slab=Dalle double écarlate +Crimson Nylium=Nylium écarlate +Crimson Door=Porte écarlate +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. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en bois, faites un clic droit dessus ou fournissez à sa moitié inférieure un signal redstone. +Crimson Trapdoor=Trappe écarlate +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.=es trappes en bois sont des barrières horizontales qui peuvent être ouvertes et fermées à la main ou par un signal redstone. 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. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Pour ouvrir ou fermer la trappe, faites un clic droit dessus ou envoyez-lui un signal redstone. +Crimson Fence=Barrière écarlate +Crimson Fence Gate=Portillon écarlate +Crimson Checknode - only to check!=Bloc de vérification écarlate - seulement pour vérifier ! +Warped Door=Porte tordue +Warped Trapdoor=Trappe tordue +Warped Fence=Barrière tordue +Warped Fence Gate=Portillon tordu diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr new file mode 100644 index 000000000..47251fd27 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.ja.tr @@ -0,0 +1,29 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=歪なキノコ +Twisting Vines=ねじれツタ +Nether Sprouts=ネザースプラウト +Warped Roots=歪な根 +Warped Wart Block=歪なウォートブロック +Shroomlight=シュルームライト +Warped Hyphae=歪な菌糸 +Warped Hyphae Bark=歪な菌糸の表皮 +Stripped warped hyphae=表皮を剥いだ歪な菌糸 +Stripped warped hyphae bark=剥がされた歪な菌糸の表皮 +Warped Nylium=歪なナイリウム +Warped Checknode - only to check!=歪なチェックノード - チェックのみ! +Warped Hyphae Wood=歪な菌糸の樹 +Warped Stair=歪な階段 +Warped Slab=歪なスラブ +Crimson Fungus Mushroom=真紅のキノコ +Crimson Roots=真紅の根 +Crimson Hyphae=真紅の菌糸 +Crimson Hyphae Bark=真紅の菌糸の表皮 +Stripped Crimson Hyphae=表皮を剥いだ真紅の菌糸 +Stripped Crimson Hyphae Bark=剥がされた真紅の菌糸の表皮 +Crimson Hyphae Wood=真紅の菌糸の樹 +Crimson Stair=真紅の階段 +Crimson Slab=真紅のスラブ +Double Crimson Slab=真紅の2重スラブ +Crimson Nylium=真紅のナイリウム +Crimson Checknode - only to check!=真紅のチェックノード - チェックのみ! diff --git a/mods/ITEMS/mcl_crimson/locale/mcl_crimson.pt_BR.tr b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.pt_BR.tr new file mode 100644 index 000000000..3b82e9c85 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/mcl_crimson.pt_BR.tr @@ -0,0 +1,29 @@ +# textdomain: mcl_crimson + +Warped Fungus Mushroom=Fungo Distorcido +Twisting Vines=Trepadeiras Distorcidas +Nether Sprouts=Brotos do Nether +Warped Roots=Raízes Distorcidas +Warped Wart Block=Bloco de Fungos Distorcidos +Shroomlight=Cogubrilho +Warped Hyphae=Hifas Distorcidas +Warped Hyphae Bark=Cascas de Hifas Distorcidas +Stripped warped hyphae=Hifas Distorcidas Descascadas +Stripped warped hyphae bark=Caule de Hifas Distorcidas +Warped Nylium=Nicélio Distorcido +Warped Checknode - only to check!= +Warped Hyphae Wood=Tábuas de Hifas Distorcidas +Warped Stair=Escadas Distorcidas +Warped Slab=Laje Distorcida +Crimson Fungus Mushroom=Fungo Carmesim +Crimson Roots=Raízes Carmesim +Crimson Hyphae=Hifas Carmesim +Crimson Hyphae Bark=Cascas de Hifas Carmesim +Stripped Crimson Hyphae=Hifas Carmesim Descascadas +Stripped Crimson Hyphae Bark=Caule de Hifas Carmesim +Crimson Hyphae Wood=Tábuas de Hifas Carmesim +Crimson Stair=Escadas Carmesim +Crimson Slab=Laje Carmesim +Double Crimson Slab=Laje Dupla Carmesim +Crimson Nylium=Nicélio Carmesim +Crimson Checknode - only to check!= diff --git a/mods/ITEMS/mcl_crimson/locale/template.txt b/mods/ITEMS/mcl_crimson/locale/template.txt new file mode 100644 index 000000000..f93b85577 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/locale/template.txt @@ -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= +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.= +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.= +Crimson 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.= +Crimson Fence= +Crimson Fence Gate= +Crimson Checknode - only to check!= +Warped Door= +Warped Trapdoor= +Warped Fence= +Warped Fence Gate= diff --git a/mods/ITEMS/mcl_crimson/mod.conf b/mods/ITEMS/mcl_crimson/mod.conf new file mode 100644 index 000000000..b4303cd48 --- /dev/null +++ b/mods/ITEMS/mcl_crimson/mod.conf @@ -0,0 +1,3 @@ +name = mcl_crimson +author = debiankaios, Exhale +depends = mcl_core, mcl_stairs, mobs_mc, mcl_util, mcl_dye, mcl_flowerpots diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts new file mode 100644 index 000000000..a61712fef Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_1.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts new file mode 100644 index 000000000..b509fae50 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_2.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts new file mode 100644 index 000000000..84f8fa791 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/crimson_fungus_3.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts new file mode 100644 index 000000000..487e39f1a Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_1.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts new file mode 100644 index 000000000..564731158 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_2.mts differ diff --git a/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts new file mode 100644 index 000000000..079631a20 Binary files /dev/null and b/mods/ITEMS/mcl_crimson/schematics/warped_fungus_3.mts differ diff --git a/mods/ITEMS/mcl_deepslate/README.md b/mods/ITEMS/mcl_deepslate/README.md new file mode 100644 index 000000000..398e70361 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/README.md @@ -0,0 +1,15 @@ +# Mineclone2 New Ores and Deepslate +by NO11 + +This mod adds Deepslate to the Minetest game Mineclone2, 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. + + +You can find all craft recipes for deepslate blocks here: https://minecraft.fandom.com/wiki/Deepslate_(disambiguation) +(just click on the respective block) + +Textures are from Pixel Perfection! diff --git a/mods/ITEMS/mcl_deepslate/init.lua b/mods/ITEMS/mcl_deepslate/init.lua new file mode 100644 index 000000000..a1182246a --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/init.lua @@ -0,0 +1,274 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +local copper_mod = minetest.get_modpath("mcl_copper") +local cobble = "mcl_deepslate:deepslate_cobbled" +local stick = "mcl_core:stick" + +local function spawn_silverfish(pos, oldnode, oldmetadata, digger) + if not minetest.is_creative_enabled("") then + minetest.add_entity(pos, "mobs_mc:silverfish") + end +end + +minetest.register_node("mcl_deepslate:deepslate", { + description = S("Deepslate"), + _doc_items_longdesc = S("Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone."), + _doc_items_hidden = false, + tiles = { "mcl_deepslate_top.png", "mcl_deepslate_top.png", "mcl_deepslate.png" }, + paramtype2 = "facedir", + is_ground_content = true, + on_place = mcl_util.rotate_axis, + groups = { pickaxey = 1, stone = 1, building_block = 1, material_stone = 1 }, + drop = cobble, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_rotate = screwdriver.rotate_3way, + _mcl_blast_resistance = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) + +minetest.register_node("mcl_deepslate:infested_deepslate", { + description = S("Infested Deepslate"), + _doc_items_longdesc = S("An infested block is a block from which a silverfish will pop out when it is broken. It looks identical to its normal counterpart."), + _tt_help = S("Hides a silverfish"), + tiles = { "mcl_deepslate_top.png", "mcl_deepslate_top.png", "mcl_deepslate.png" }, + is_ground_content = true, + groups = { dig_immediate = 3, spawns_silverfish = 1, deco_block = 1 }, + drop = "", + sounds = mcl_sounds.node_sound_stone_defaults(), + after_dig_node = spawn_silverfish, + _mcl_hardness = 0, + _mcl_blast_resistance = 0.5, +}) + +minetest.register_node("mcl_deepslate:tuff", { + description = S("Tuff"), + _doc_items_longdesc = S("Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y=16."), + _doc_items_hidden = false, + tiles = { "mcl_deepslate_tuff.png" }, + groups = { pickaxey = 1, deco_block = 1 }, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, + _mcl_silk_touch_drop = true, +}) + +local function register_deepslate_ore(desc, drop, cooked, pick, xp) + local item = desc:lower() + local item_string + if item == "lapis lazuli" then + item_string = "lapis" + else + item_string = item + end + local nodename = "mcl_deepslate:deepslate_with_"..item_string + minetest.register_node(nodename, { + description = S("Deepslate "..desc.." Ore"), + _doc_items_longdesc = S("Deepslate "..item.." ore is a variant of "..item.." ore that can generate in deepslate and tuff blobs."), + _doc_items_hidden = false, + tiles = { "mcl_deepslate_"..item_string.."_ore.png" }, + is_ground_content = true, + stack_max = 64, + groups = { pickaxey = pick, building_block = 1, material_stone = 1, xp = xp }, + drop = drop, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 4.5, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = mcl_core.fortune_drop_ore, + }) + + minetest.register_craft({ + type = "cooking", + output = cooked, + recipe = nodename, + cooktime = 10, + }) +end + +local lapis_drops = { + max_items = 1, items = { + { items = { "mcl_core:lapis 8" }, rarity = 5 }, + { items = { "mcl_core:lapis 7" }, rarity = 5 }, + { items = { "mcl_core:lapis 6" }, rarity = 5 }, + { items = { "mcl_core:lapis 5" }, rarity = 5 }, + { items = { "mcl_core:lapis 4" } } + } +} + +local deepslate_ores = { + { "Coal", "mcl_core:coal_lump", "mcl_core:coal_lump", 1, 1 }, + { "Iron", "mcl_raw_ores:raw_iron", "mcl_core:iron_ingot", 3, 0 }, + { "Gold", "mcl_raw_ores:raw_gold", "mcl_core:gold_ingot", 4, 0 }, + { "Emerald", "mcl_core:emerald", "mcl_core:emerald", 4, 6 }, + { "Diamond", "mcl_core:diamond", "mcl_core:diamond", 4, 4 }, + { "Lapis Lazuli", lapis_drops, "mcl_core:lapis", 3, 6 }, +} + +for _, p in pairs(deepslate_ores) do + register_deepslate_ore(p[1], p[2], p[3], p[4], p[5]) +end + +if copper_mod then + register_deepslate_ore("Copper", "mcl_copper:raw_copper", "mcl_copper:copper_ingot", 4, 4) +end + +local redstone_timer = 68.28 + +local function redstone_ore_activate(pos, node, puncher, pointed_thing) + minetest.swap_node(pos, { name = "mcl_deepslate:deepslate_with_redstone_lit" }) + local t = minetest.get_node_timer(pos) + t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end +end + +local function redstone_ore_reactivate(pos, node, puncher, pointed_thing) + local t = minetest.get_node_timer(pos) + t:start(redstone_timer) + if puncher and pointed_thing then + return minetest.node_punch(pos, node, puncher, pointed_thing) + end +end + +minetest.register_node("mcl_deepslate:deepslate_with_redstone", { + description = S("Deepslate Redstone Ore"), + _doc_items_longdesc = S("Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs."), + tiles = { "mcl_deepslate_redstone_ore.png" }, + is_ground_content = true, + groups = { pickaxey = 4, building_block = 1, material_stone = 1, xp = 7 }, + drop = { + items = { + max_items = 1, + { items = { "mesecons:redstone 4" }, rarity = 2 }, + { items = { "mesecons:redstone 5" } }, + } + }, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_punch = redstone_ore_activate, + on_walk_over = redstone_ore_activate, + _mcl_blast_resistance = 3, + _mcl_hardness = 4.5, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = { "mesecons:redstone" }, + min_count = 4, + max_count = 5, + } +}) + +minetest.register_node("mcl_deepslate:deepslate_with_redstone_lit", { + description = S("Lit Deepslate Redstone Ore"), + _doc_items_create_entry = false, + tiles = { "mcl_deepslate_redstone_ore.png" }, + paramtype = "light", + light_source = 9, + is_ground_content = true, + groups = { pickaxey = 4, not_in_creative_inventory = 1, material_stone = 1, xp = 7 }, + drop = { + items = { + max_items = 1, + { items = { "mesecons:redstone 4" }, rarity = 2 }, + { items = { "mesecons:redstone 5" } }, + } + }, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_punch = redstone_ore_reactivate, + on_walk_over = redstone_ore_reactivate, -- Uses walkover mod + on_timer = function(pos, _) + minetest.swap_node(pos, { name = "mcl_deepslate:deepslate_with_redstone" }) + end, + _mcl_blast_resistance = 3, + _mcl_hardness = 4.5, + _mcl_silk_touch_drop = { "mcl_deepslate:deepslate_with_redstone" }, + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = { "mesecons:redstone" }, + min_count = 4, + max_count = 5, + }, +}) + +local function register_deepslate_variant(item, desc, longdesc) + local texture = desc:lower():gsub("% ", "_") + local def = { + description = S(desc), + _doc_items_longdesc = S(longdesc), + _doc_items_hidden = false, + tiles = { "mcl_"..texture..".png" }, + groups = { pickaxey = 1, building_block = 1, material_stone = 1 }, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 3.5, + _mcl_silk_touch_drop = true, + } + if item == "cobbled" then + def.groups.cobble = 1 + end + minetest.register_node("mcl_deepslate:deepslate_"..item, table.copy(def)) + + if item == "bricks" or item == "tiles" then + def.description = S("Cracked "..desc) + def._doc_items_longdesc = S("Cracked "..desc:lower().." are a cracked variant.") + def.tiles = { "mcl_cracked_"..texture..".png" } + minetest.register_node("mcl_deepslate:deepslate_"..item.."_cracked", def) + 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) + end +end + +local deepslate_variants = { + { "cobbled", "Cobbled Deepslate", "Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone." }, + { "polished", "Polished Deepslate", "Polished deepslate is the stone-like polished version of deepslate." }, + { "bricks", "Deepslate Bricks", "Deepslate bricks are the brick version of deepslate." }, + { "tiles", "Deepslate Tiles", "Deepslate tiles are a decorative variant of deepslate." }, + { "chiseled", "Chiseled Deepslate", "Chiseled deepslate is the chiseled version of deepslate." }, +} + +for _, dv in pairs(deepslate_variants) do + register_deepslate_variant(dv[1], dv[2], dv[3]) +end + +for i = 1, 3 do + local s = "mcl_deepslate:deepslate_"..deepslate_variants[i][1] + minetest.register_craft({ + output = "mcl_deepslate:deepslate_"..deepslate_variants[i+1][1].." 4", + recipe = { { s, s }, { s, s } } + }) +end + +for _, p in pairs({ "bricks", "tiles" }) do + minetest.register_craft({ + type = "cooking", + output = "mcl_deepslate:deepslate_"..p.."_cracked", + recipe = "mcl_deepslate:deepslate_"..p, + cooktime = 10, + }) +end + +minetest.register_craft({ + type = "cooking", + output = "mesecons:redstone", + recipe = "mcl_deepslate:deepslate_with_redstone", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_deepslate:deepslate", + recipe = cobble, + cooktime = 10, +}) + +minetest.register_craft({ + output = "mcl_deepslate:deepslate_chiseled", + recipe = { + { "mcl_stairs:slab_deepslate_cobbled" }, + { "mcl_stairs:slab_deepslate_cobbled" }, + }, +}) diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.de.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.de.tr new file mode 100644 index 000000000..35cf86869 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.de.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.=Ein befallener Block ist ein Block, aus dem ein Silberfisch herausspringt, wenn er abgebaut wird. Er sieht genauso aus wie sein normales Gegenstück. +Chiseled deepslate is the chiseled version of deepslate.=Gemeißelter Tiefenschiefer ist die behauene Version von Tiefenschiefer. +Chiseled Deepslate=Gemeißelter Tiefenschiefer +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=Bruchtiefenschiefer funktioniert ähnlich wie Bruchstein, hat jedoch eine längere Abbauzeit. +Cobbled Deepslate Slab=Bruchtiefenschieferstufe +Cobbled Deepslate Stairs=Bruchtiefenschiefertreppe +Cobbled Deepslate Wall=Bruchtiefenschiefermauer +Cobbled Deepslate=Bruchtiefenschiefer +Cracked Deepslate Bricks=Rissige Tiefenschieferziegel +Cracked Deepslate Tiles=Rissige Tiefenschieferfliesen +Deepslate bricks are the brick version of deepslate.=Tiefenschieferziegel ist eine Variante des Tiefenschiefers. Er kann als dekorativer Block verwendet werden. +Deepslate Bricks Slab=Tiefenschieferziegelstufe +Deepslate Bricks Stairs=Tiefenschieferziegeltreppe +Deepslate Bricks Wall=Tiefenschieferziegelmauer +Deepslate Bricks=Tiefenschieferziegel +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Steinkohle ist eine Variante von Steinkohle, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Coal Ore=Tiefenschiefer-Steinkohle +Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Kupfererz ist eine Variante von Kupfererz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Copper Ore=Tiefenschiefer-Kupfererz +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Diamanterz ist eine Variante von Diamanterz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Diamond Ore=Tiefenschiefer-Diamanterz +Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Smaragderz ist eine Variante von Smaragderz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Emerald Ore=Tiefenschiefer-Smaragderz +Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Golderz ist eine Variante von Golderz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Gold Ore=Tiefenschiefer-Golderz +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Eisenerz ist eine Variante von Eisenerz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Iron Ore=Tiefenschiefer-Eisenerz +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=Tiefenschiefer ist eine Gesteinsart. Er kann als dekorativer Block verwendet und in viele Varianten weiterverarbeitet werden. +Deepslate Lapis Lazuli Ore=Tiefenschiefer-Lapislazulierz +Deepslate lapis ore is a variant of lapis ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Lapislazulierz ist eine Variante von Lapislazulierz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=Tiefenschiefer-Redstone-Erz ist eine Variante von Redstone-Erz, die in Tiefenschiefer und Tuff generiert werden kann. +Deepslate Redstone Ore=Tiefenschiefer-Redstone-Erz +Deepslate tiles are a decorative variant of deepslate.=Tiefenschieferfliesen ist eine Variante des Tiefenschiefers. Der Block kann als dekorativer Block verwendet werden. +Deepslate Tiles Slab=Tiefenschieferfliesenstufe +Deepslate Tiles Stairs=Tiefenschieferfliesentreppe +Deepslate Tiles Wall=Tiefenschieferfliesenmauer +Deepslate Tiles=Tiefenschieferfliesen +Deepslate=Tiefenschiefer +Double Cobbled Deepslate Slab=Doppelte Bruchtiefenschieferstufe +Double Deepslate Bricks Slab=Doppelte Tiefenschieferziegelstufe +Double Deepslate Tiles Slab=Doppelte Tiefenschieferfliesenstufe +Double Polished Deepslate Slab=Doppelte Polierte Tiefenschieferstufe +Hides a silverfish=Versteckt einen Silberfisch +Infested Deepslate=Befallener Tiefenschiefer +Lit Deepslate Redstone Ore=Leuchtendes Tiefschiefer-Redstone-Erz +Polished deepslate is the stone-like polished version of deepslate.=Polierter Tiefenschiefer ist eine Variante des Tiefenschiefers. Er kann als dekorativer Block verwendet werden. +Polished Deepslate Slab=Polierte Tiefenschieferstufe +Polished Deepslate Stairs=Polierte Tiefenschiefertreppe +Polished Deepslate Wall=Polierte Tiefenschiefermauer +Polished Deepslate=Polierter Tiefenschiefer +Tuff=Tuffstein +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y=16.=Der Tuffstein ist ein grauer, vulkanischer Block. diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.tr new file mode 100644 index 000000000..18fcc415b --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.fr.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.=Un bloc infesté est un bloc dont va sortir un poisson d'argent lorsqu'il sera cassé. Il a la même apparence que son équivalent normal. +Chiseled deepslate is the chiseled version of deepslate.=l'ardoise des abîmes sculptée est la version sculptée de l'ardoise des abîmes. +Chiseled Deepslate=Ardoise des abîmes sculptée +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=La pierre des abîmes est une variante de roche similaire à la pierre ou la pierre noire. +Cobbled Deepslate Slab=Dalle de pierre des abîmes +Cobbled Deepslate Stairs=Escalier de pierre des abîmes +Cobbled Deepslate Wall=Muret de pierre des abîmes +Cobbled Deepslate=Pierre des abîmes +Cracked Deepslate Bricks=Ardoise des abîmes taillée craquelée +Cracked Deepslate Tiles=Ardoise des abîmes carrelée craquelée +Deepslate bricks are the brick version of deepslate.=L'ardoise des abîmes taillée est la version brique de l'ardoise des abîmes. +Deepslate Bricks Slab=Dalle d'ardoise des abîmes taillée +Deepslate Bricks Stairs=Escalier d'ardoise des abîmes taillée +Deepslate Bricks Wall=Muret d'ardoise des abîmes taillée +Deepslate Bricks=Ardoise des abîmes taillée +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=Le minerai de charbon de l'ardoise des abîmes est une variante de minerai de charbon qui apparaît dans l'ardoise des abîmes et les filons de tuf. +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 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. +Deepslate Gold Ore=Minerai d'or de l'ardoise des abîmes +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=Le minerai de fer de l'ardoise des abîmes est une variante de minerai de fer qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Iron Ore=Minerai de fer de l'ardoise des abîmes +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=L'ardoise des abîmes est un type de roche présente dans les profondeurs de l'Overworld qui fonctionne de manière similaire à la roche classique mais en plus dur. +Deepslate Lapis Lazuli Ore=Minerai de lapis-lazuli de l'ardoise des abîmes +Deepslate lapis lazuli ore is a variant of lapis lazuli ore that can generate in deepslate and tuff blobs.=Le minerai de lapis-lazuli de l'ardoise des abîmes est une variante de minerai de lapis-lazuli qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=Le minerai de redstone de l'ardoise des abîmes est une variante de minerai de redstone qui apparaît dans l'ardoise des abîmes et les filons de tuf. +Deepslate Redstone Ore=Minerai de Redstone de l'ardoise des abîmes +Deepslate tiles are a decorative variant of deepslate.=L'ardoise des abîmes carrelée est une variante décorative de l'ardoise des abîmes. +Deepslate Tiles Slab=Dalle d'ardoise des abîmes carrelée +Deepslate Tiles Stairs=Escalier d'ardoise des abîmes carrelée +Deepslate Tiles Wall=Muret d'ardoise des abîmes carrelée +Deepslate Tiles=Ardoise des abîmes carrelée +Deepslate=Ardoise des abîmes +Double Cobbled Deepslate Slab=Dalle double de pierre des abîmes +Double Deepslate Bricks Slab=Dalle double d'ardoise des abîmes taillée +Double Deepslate Tiles Slab=Dalle double d'ardoise des abîmes carrelée +Double Polished Deepslate Slab=Dalle double d'ardoise des abîmes polie +Hides a silverfish=Cache un poisson d'argent +Infested Deepslate=Ardoise des abîmes infestée +Lit Deepslate Redstone Ore=Minerai de Redstone de l'ardoise des abîmes éclairé +Polished deepslate is the stone-like polished version of deepslate.=l'ardoise des abîmes polie est la version polie de l'ardoise des abîmes, de manière similaire à la pierre. +Polished Deepslate Slab=Dalle d'ardoise des abîmes +Polished Deepslate Stairs=Escalier d'ardoise des abîmes +Polished Deepslate Wall=Muret d'ardoise des abîmes +Polished Deepslate=Ardoise des abîmes polie +Tuff=Tuf +Tuff is an ornamental rock formed from volcanic ash, occurring in underground blobs below Y@=16.=Le tuf est une roche ornementale formée de roche volcanique, apparaissant dans des blobs souterrains sous Y@=16. diff --git a/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.tr new file mode 100644 index 000000000..bbd25ee5c --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.ja.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 ore is a variant of lapis 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=深層岩の丸石の2重スラブ +Double Deepslate Bricks Slab=深層岩レンガの2重スラブ +Double Deepslate Tiles Slab=深層岩タイルの2重スラブ +Double Polished Deepslate Slab=磨かれた深層岩の2重スラブ +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/locale/mcl_deepslate.pt_BR.tr b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.tr new file mode 100644 index 000000000..4f7c6ad24 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/mcl_deepslate.pt_BR.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.=Um bloco infestado é um bloco no qual um silverfish surgirá quando quebrado. Parece idêntico à sua contraparte normal. +Chiseled deepslate is the chiseled version of deepslate.=Ardósia cinzelada é a versão cinzelada da ardósia. +Chiseled Deepslate=Ardósia Cinzelada +Cobbled deepslate is a stone variant that functions similar to cobblestone or blackstone.=Pedregulhos de ardósia é uma variante de rocha que possui funções similares aos pedregulhos ou rochas-negra. +Cobbled Deepslate Slab=Laje de Pedregulhos de Ardósia +Cobbled Deepslate Stairs=Escadas de Pedregulhos de Ardósia +Cobbled Deepslate Wall=Muro de Pedregulhos de Ardósia +Cobbled Deepslate=Pedregulhos de Ardósia +Cracked Deepslate Bricks=Tijolos de Ardósia Rachado +Cracked Deepslate Tiles=Azulejos de Ardósia Rachado +Deepslate bricks are the brick version of deepslate.=Tijolos de ardósia são a versão em ardósia dos tijolos. +Deepslate Bricks Slab=Laje de Tijolos de Ardósia +Deepslate Bricks Stairs=Escadas de Tijolos de Ardósia +Deepslate Bricks Wall=Muro de Tijolos de Ardósia +Deepslate Bricks=Tijolos de Ardósia +Deepslate coal ore is a variant of coal ore that can generate in deepslate and tuff blobs.=Minério de carvão em ardósia é a variante do minério de carvão que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Coal Ore=Minério de Carvão em Ardósia +Deepslate copper ore is a variant of copper ore that can generate in deepslate and tuff blobs.=Minério de cobre em ardósia é a variante do minério de cobre que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Copper Ore=Minério de Cobre em Ardósia +Deepslate diamond ore is a variant of diamond ore that can generate in deepslate and tuff blobs.=Minério de diamante em ardósia é a variante do minério de diamante que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Diamond Ore=Minério de Diamante em Ardósia +Deepslate emerald ore is a variant of emerald ore that can generate in deepslate and tuff blobs.=Minério de esmeralda em ardósia é a variante do minério de esmeralda que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Emerald Ore=Minério de Esmeralda em Ardósia +Deepslate gold ore is a variant of gold ore that can generate in deepslate and tuff blobs.=Minério de ouro em ardósia é a variante do minério de ouro que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Gold Ore=Minério de Ouro em Ardósia +Deepslate iron ore is a variant of iron ore that can generate in deepslate and tuff blobs.=Minério de ferro em ardósia é a variante do minério de ferro que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Iron Ore=Minério de Ferro em Ardósia +Deepslate is a stone type found deep underground in the Overworld that functions similar to regular stone but is harder than the stone.=Ardósia é um tipo de rocha encontrado nas profundezas do subterrâneo que possui funções similares às rochas comuns, mas é mais dura que elas. +Deepslate Lapis Lazuli Ore=Minério de Lápis-lazuli em Ardósia +Deepslate lapis ore is a variant of lapis ore that can generate in deepslate and tuff blobs.=Minério de lápis-lazuli em ardósia é a variante do minério de lápis-lazuli que pode ser gerado em ardósias e bolhas de tufo. +Deepslate redstone ore is a variant of redstone ore that can generate in deepslate and tuff blobs.=Minério de redstone em ardósia é a variante do minério de redstone que pode ser gerado em ardósias e bolhas de tufo. +Deepslate Redstone Ore=Minério de Redstone em Ardósia +Deepslate tiles are a decorative variant of deepslate.=Azulejos de ardósia são variantes decorativas da ardósia. +Deepslate Tiles Slab=Laje de Azulejos de Ardósia +Deepslate Tiles Stairs=Escadas de Azulejos de Ardósia +Deepslate Tiles Wall=Muro de Azulejos de Ardósia +Deepslate Tiles=Azulejos de Ardósia +Deepslate=Ardósia +Double Cobbled Deepslate Slab=Laje Dupla de Pedregulhos de Ardósia +Double Deepslate Bricks Slab=Laje Dupla de Tijolos de Ardósia +Double Deepslate Tiles Slab=Laje Dupla de Azulejos de Ardósia +Double Polished Deepslate Slab=Laje Dupla de Ardósia Polida +Hides a silverfish=Esconde um silverfish +Infested Deepslate=Ardósia Infestada +Lit Deepslate Redstone Ore=Minério de Redstone em Ardósia Aceso +Polished deepslate is the stone-like polished version of deepslate.=Ardósia polida é a versão da rocha polida em ardósia. +Polished Deepslate Slab=Laje de Ardósia Polida +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. diff --git a/mods/ITEMS/mcl_deepslate/locale/template.txt b/mods/ITEMS/mcl_deepslate/locale/template.txt new file mode 100644 index 000000000..781eae587 --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/locale/template.txt @@ -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.= diff --git a/mods/ITEMS/mcl_deepslate/mod.conf b/mods/ITEMS/mcl_deepslate/mod.conf new file mode 100644 index 000000000..7e9a44cfc --- /dev/null +++ b/mods/ITEMS/mcl_deepslate/mod.conf @@ -0,0 +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 +optional_depends = mcl_copper diff --git a/mods/ITEMS/mcl_doors/api_doors.lua b/mods/ITEMS/mcl_doors/api_doors.lua index 07a5623f3..e392bc710 100644 --- a/mods/ITEMS/mcl_doors/api_doors.lua +++ b/mods/ITEMS/mcl_doors/api_doors.lua @@ -1,510 +1,716 @@ -local S = minetest.get_translator("mcl_doors") - --- This helper function calls on_place_node callbacks. -local function on_place_node(place_to, newnode, - placer, oldnode, itemstack, pointed_thing) - -- Run script hook - for _, callback in ipairs(minetest.registered_on_placenodes) do - -- Deep-copy pos, node and pointed_thing because callback can modify them - local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} - local newnode_copy = - {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} - local oldnode_copy = - {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} - local pointed_thing_copy = { - type = pointed_thing.type, - above = vector.new(pointed_thing.above), - under = vector.new(pointed_thing.under), - ref = pointed_thing.ref, - } - callback(place_to_copy, newnode_copy, placer, - oldnode_copy, itemstack, pointed_thing_copy) - end -end - --- Registers a door --- name: The name of the door --- def: a table with the folowing fields: --- description --- inventory_image --- groups --- tiles_bottom: the tiles of the bottom part of the door {front, side} --- tiles_top: the tiles of the bottom part of the door {front, side} --- If the following fields are not defined the default values are used --- node_box_bottom --- node_box_top --- selection_box_bottom --- selection_box_top --- only_placer_can_open: if true only the player who placed the door can --- open it --- only_redstone_can_open: if true, the door can only be opened by redstone, --- not by rightclicking it - -function mcl_doors:register_door(name, def) - def.groups.not_in_creative_inventory = 1 - def.groups.dig_by_piston = 1 - def.groups.door = 1 - def.groups.mesecon_ignore_opaque_dig = 1 - - if not def.sound_open then - def.sound_open = "doors_door_open" - end - if not def.sound_close then - def.sound_close = "doors_door_close" - end - - local box = {{-8/16, -8/16, -8/16, 8/16, 8/16, -5/16}} - - if not def.node_box_bottom then - def.node_box_bottom = box - end - if not def.node_box_top then - def.node_box_top = box - end - if not def.selection_box_bottom then - def.selection_box_bottom= box - end - if not def.selection_box_top then - def.selection_box_top = box - end - - local longdesc, usagehelp, tt_help - tt_help = def._tt_help - longdesc = def._doc_items_longdesc - if not longdesc then - if def.only_redstone_can_open then - longdesc = S("This door is a 2-block high barrier which can be opened or closed by hand or by redstone power.") - else - longdesc = S("This door is a 2-block high barrier which can only be opened by redstone power, not by hand.") - end - end - usagehelp = def._doc_items_usagehelp - if not usagehelp then - if def.only_redstone_can_open then - usagehelp = S("To open or close this door, send a redstone signal to its bottom half.") - else - usagehelp = S("To open or close this door, rightclick it or send a redstone signal to its bottom half.") - end - end - if not tt_help then - 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 - end - - local craftitem_groups = { mesecon_conductor_craftable = 1, deco_block = 1 } - if def.groups and def.groups.flammable then - craftitem_groups.flammable = def.groups.flammable - end - - minetest.register_craftitem(name, { - description = def.description, - _tt_help = tt_help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - inventory_image = def.inventory_image, - stack_max = 64, - groups = craftitem_groups, - on_place = function(itemstack, placer, pointed_thing) - if not pointed_thing.type == "node" or not placer or not placer:is_player() then - return itemstack - end - local pn = placer:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) and minetest.is_protected(pointed_thing.under, pn) then - return itemstack - end - local ptu = pointed_thing.under - local nu = minetest.get_node(ptu) - -- Pointed thing's rightclick action takes precedence, unless player holds down the sneak key - if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].on_rightclick and not placer:get_player_control().sneak then - return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack) - end - - local pt - if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].buildable_to then - pt = pointed_thing.under - else - pt = pointed_thing.above - end - local pt2 = {x=pt.x, y=pt.y, z=pt.z} - pt2.y = pt2.y+1 - local ptname = minetest.get_node(pt).name - local pt2name = minetest.get_node(pt2).name - if - (minetest.registered_nodes[ptname] and not minetest.registered_nodes[ptname].buildable_to) or - (minetest.registered_nodes[pt2name] and not minetest.registered_nodes[pt2name].buildable_to) - then - return itemstack - end - - -- get left coordinate for checking if another door is there - local pt_left = {x=pt.x, y=pt.y, z=pt.z} - local p2 = minetest.dir_to_facedir(placer:get_look_dir()) - - if p2 == 0 then - pt_left.x = pt_left.x-1 - elseif p2 == 1 then - pt_left.z = pt_left.z+1 - elseif p2 == 2 then - pt_left.x = pt_left.x+1 - elseif p2 == 3 then - pt_left.z = pt_left.z-1 - end - - local left_node = minetest.get_node(pt_left) - - -- Set door nodes - minetest.set_node(pt, {name=name.."_b_1", param2=p2}) - minetest.set_node(pt2, {name=name.."_t_1", param2=p2}) - - if def.sounds and def.sounds.place then - minetest.sound_play(def.sounds.place, {pos=pt}, true) - end - - if def.only_placer_can_open then - local meta = minetest.get_meta(pt) - meta:set_string("doors_owner", "") - meta = minetest.get_meta(pt2) - meta:set_string("doors_owner", "") - end - - local meta1 = minetest.get_meta(pt) - local meta2 = minetest.get_meta(pt2) - -- save mirror state for the correct door - if left_node.name:sub(1, #name) == name then - meta1:set_int("is_mirrored", 1) - meta2:set_int("is_mirrored", 1) - end - - -- Save open state. 1 = open. 0 = closed - meta1:set_int("is_open", 0) - meta2:set_int("is_open", 0) - - - if not minetest.is_creative_enabled(pn) then - itemstack:take_item() - end - - on_place_node(pt, minetest.get_node(pt), placer, nu, itemstack, pointed_thing) - on_place_node(pt2, minetest.get_node(pt2), placer, minetest.get_node({x=ptu.x,y=ptu.y+1,z=ptu.z}), itemstack, pointed_thing) - - return itemstack - end, - }) - - local tt = def.tiles_top - local tb = def.tiles_bottom - - local function on_open_close(pos, dir, check_name, replace, replace_dir) - local meta1 = minetest.get_meta(pos) - pos.y = pos.y+dir - local meta2 = minetest.get_meta(pos) - - -- if name of other door is not the same as check_name -> return - if not minetest.get_node(pos).name == check_name then - return - end - - -- swap directions if mirrored - local params = {3,0,1,2} - if meta1:get_int("is_open") == 0 and meta2:get_int("is_mirrored") == 0 or meta1:get_int("is_open") == 1 and meta2:get_int("is_mirrored") == 1 then - params = {1,2,3,0} - end - - local p2 = minetest.get_node(pos).param2 - local np2 = params[p2+1] - - minetest.swap_node(pos, {name=replace_dir, param2=np2}) - pos.y = pos.y-dir - minetest.swap_node(pos, {name=replace, param2=np2}) - - local door_switching_sound - if meta1:get_int("is_open") == 1 then - door_switching_sound = def.sound_close - meta1:set_int("is_open", 0) - meta2:set_int("is_open", 0) - else - door_switching_sound = def.sound_open - meta1:set_int("is_open", 1) - meta2:set_int("is_open", 1) - end - minetest.sound_play(door_switching_sound, {pos = pos, gain = 0.5, max_hear_distance = 16}, true) - end - - local function on_mesecons_signal_open(pos, node) - on_open_close(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2") - end - local function on_mesecons_signal_close(pos, node) - if not mesecon.is_powered({x=pos.x,y=pos.y+1,z=pos.z}) then - on_open_close(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1") - end - end - local function on_mesecons_signal_open_top(pos, node) - on_mesecons_signal_open({x=pos.x, y=pos.y-1, z=pos.z}, node) - end - local function on_mesecons_signal_close_top(pos, node) - if not mesecon.is_powered({x=pos.x,y=pos.y-1,z=pos.z}) then - on_mesecons_signal_close({x=pos.x, y=pos.y-1, z=pos.z}, node) - end - end - - local function check_player_priv(pos, player) - if not def.only_placer_can_open then - return true - end - local meta = minetest.get_meta(pos) - local pn = player:get_player_name() - return meta:get_string("doors_owner") == pn - end - - local on_rightclick - -- Disable on_rightclick if this is a redstone-only door - if not def.only_redstone_can_open then - on_rightclick = function(pos, node, clicker) - if check_player_priv(pos, clicker) then - on_open_close(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2") - end - end - end - - minetest.register_node(name.."_b_1", { - tiles = {"blank.png", tt[2].."^[transformFXR90", tb[2], tb[2].."^[transformFX", tb[1], tb[1].."^[transformFX"}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - is_ground_content = false, - drop = "", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = def.node_box_bottom - }, - selection_box = { - type = "fixed", - fixed = def.selection_box_bottom - }, - groups = def.groups, - _mcl_hardness = def._mcl_hardness, - _mcl_blast_resistance = def._mcl_blast_resistance, - sounds = def.sounds, - - after_destruct = function(bottom, oldnode) - minetest.add_item(bottom, name) - local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } - if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then - minetest.remove_node(top) - end - end, - - on_rightclick = on_rightclick, - - mesecons = { effector = { - action_on = on_mesecons_signal_open, - }}, - - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) - node.name = name .."_t_1" - minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node) - return true - end - return false - end, - - can_dig = check_player_priv, - }) - - if def.only_redstone_can_open then - on_rightclick = nil - else - on_rightclick = function(pos, node, clicker) - if check_player_priv(pos, clicker) then - on_open_close(pos, -1, name.."_b_1", name.."_t_2", name.."_b_2") - end - end - end - - minetest.register_node(name.."_t_1", { - tiles = {tt[2].."^[transformR90", "blank.png", tt[2], tt[2].."^[transformFX", tt[1], tt[1].."^[transformFX"}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - is_ground_content = false, - drop = "", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = def.node_box_top - }, - selection_box = { - type = "fixed", - fixed = def.selection_box_top - }, - groups = def.groups, - _mcl_hardness = def._mcl_hardness, - _mcl_blast_resistance = def._mcl_blast_resistance, - sounds = def.sounds, - - after_destruct = function(top, oldnode) - local bottom = { x = top.x, y = top.y - 1, z = top.z } - if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then - minetest.dig_node(bottom) - end - end, - - on_rightclick = on_rightclick, - - mesecons = { effector = { - action_on = on_mesecons_signal_open_top, - rules = mesecon.rules.flat, - }}, - - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) - node.name = name .."_b_1" - minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node) - return true - end - return false - end, - - can_dig = check_player_priv, - }) - - if def.only_redstone_can_open then - on_rightclick = nil - else - on_rightclick = function(pos, node, clicker) - if check_player_priv(pos, clicker) then - on_open_close(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1") - end - end - end - - minetest.register_node(name.."_b_2", { - tiles = {"blank.png", tt[2].."^[transformFXR90", tb[2].."^[transformI", tb[2].."^[transformFX", tb[1].."^[transformFX", tb[1]}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - is_ground_content = false, - drop = "", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = def.node_box_bottom - }, - selection_box = { - type = "fixed", - fixed = def.selection_box_bottom - }, - groups = def.groups, - _mcl_hardness = def._mcl_hardness, - _mcl_blast_resistance = def._mcl_blast_resistance, - sounds = def.sounds, - - after_destruct = function(bottom, oldnode) - minetest.add_item(bottom, name) - local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } - if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then - minetest.remove_node(top) - end - end, - - on_rightclick = on_rightclick, - - mesecons = { effector = { - action_off = on_mesecons_signal_close, - }}, - - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) - node.name = name .."_t_2" - minetest.set_node({x=pos.x,y=pos.y+1,z=pos.z}, node) - return true - end - return false - end, - - can_dig = check_player_priv, - }) - - if def.only_redstone_can_open then - on_rightclick = nil - else - on_rightclick = function(pos, node, clicker) - if check_player_priv(pos, clicker) then - on_open_close(pos, -1, name.."_b_2", name.."_t_1", name.."_b_1") - end - end - end - - minetest.register_node(name.."_t_2", { - tiles = {tt[2].."^[transformR90", "blank.png", tt[2].."^[transformI", tt[2].."^[transformFX", tt[1].."^[transformFX", tt[1]}, - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - is_ground_content = false, - drop = "", - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = def.node_box_top - }, - selection_box = { - type = "fixed", - fixed = def.selection_box_top - }, - groups = def.groups, - _mcl_hardness = def._mcl_hardness, - _mcl_blast_resistance = def._mcl_blast_resistance, - sounds = def.sounds, - - after_destruct = function(top, oldnode) - local bottom = { x = top.x, y = top.y - 1, z = top.z } - if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then - minetest.dig_node(bottom) - end - end, - - on_rightclick = on_rightclick, - - mesecons = { effector = { - action_off = on_mesecons_signal_close_top, - rules = mesecon.rules.flat, - }}, - - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - minetest.remove_node(pos) - node.param2 = screwdriver.rotate.facedir(pos, node, mode) - minetest.set_node(pos, node) - node.name = name .."_b_2" - minetest.set_node({x=pos.x,y=pos.y-1,z=pos.z}, node) - return true - end - return false - end, - - can_dig = check_player_priv, - }) - - -- Add entry aliases for the Help - if minetest.get_modpath("doc") then - doc.add_entry_alias("craftitems", name, "nodes", name.."_b_1") - doc.add_entry_alias("craftitems", name, "nodes", name.."_b_2") - doc.add_entry_alias("craftitems", name, "nodes", name.."_t_1") - doc.add_entry_alias("craftitems", name, "nodes", name.."_t_2") - end - -end +local S = minetest.get_translator(minetest.get_current_modname()) +local minetest_get_meta = minetest.get_meta + +-- This helper function calls on_place_node callbacks. +local function on_place_node(place_to, newnode, + placer, oldnode, itemstack, pointed_thing) + -- Run script hook + for _, callback in pairs(minetest.registered_on_placenodes) do + -- Deep-copy pos, node and pointed_thing because callback can modify them + local place_to_copy = {x = place_to.x, y = place_to.y, z = place_to.z} + local newnode_copy = + {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2} + local oldnode_copy = + {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2} + local pointed_thing_copy = { + type = pointed_thing.type, + above = vector.new(pointed_thing.above), + under = vector.new(pointed_thing.under), + ref = pointed_thing.ref, + } + callback(place_to_copy, newnode_copy, placer, + oldnode_copy, itemstack, pointed_thing_copy) + end +end + +-- Registers a door +-- name: The name of the door +-- def: a table with the folowing fields: +-- description +-- inventory_image +-- groups +-- tiles_bottom: the tiles of the bottom part of the door {front, side} +-- tiles_top: the tiles of the bottom part of the door {front, side} +-- If the following fields are not defined the default values are used +-- node_box_bottom +-- node_box_top +-- selection_box_bottom +-- selection_box_top +-- only_placer_can_open: if true only the player who placed the door can +-- open it +-- only_redstone_can_open: if true, the door can only be opened by redstone, +-- not by rightclicking it + +function mcl_doors:register_door(name, def) + def.groups.not_in_creative_inventory = 1 + def.groups.dig_by_piston = 1 + def.groups.door = 1 + def.groups.mesecon_ignore_opaque_dig = 1 + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + if not def.node_box then + def.node_box = {{-8/16, -8/16, -8/16, 8/16, 8/16, -5/16}} + end + if not def.selection_box then + def.selection_box = {{-8/16, -8/16, -8/16, 8/16, 8/16, -5/16}} + end + + local longdesc, usagehelp, tt_help + tt_help = def._tt_help + longdesc = def._doc_items_longdesc + if not longdesc then + if def.only_redstone_can_open then + longdesc = S("This door is a 2-block high barrier which can only be opened by redstone power, not by hand.") + else + longdesc = S("This door is a 2-block high barrier which can be opened or closed by hand or by redstone power.") + end + end + usagehelp = def._doc_items_usagehelp + if not usagehelp then + if def.only_redstone_can_open then + usagehelp = S("To open or close this door, send a redstone signal to its bottom half.") + else + usagehelp = S("To open or close this door, rightclick it or send a redstone signal to its bottom half.") + end + end + if not tt_help then + 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 + end + + local craftitem_groups = { mesecon_conductor_craftable = 1, deco_block = 1 } + if def.groups and def.groups.flammable then + craftitem_groups.flammable = def.groups.flammable + end + + minetest.register_craftitem(name, { + description = def.description, + _tt_help = tt_help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + inventory_image = def.inventory_image, + stack_max = 64, + groups = craftitem_groups, + on_place = function(itemstack, placer, pointed_thing) + if not pointed_thing.type == "node" or not placer or not placer:is_player() then + return itemstack + end + local pn = placer:get_player_name() + if minetest.is_protected(pointed_thing.above, pn) and minetest.is_protected(pointed_thing.under, pn) then + return itemstack + end + local ptu = pointed_thing.under + local nu = minetest.get_node(ptu) + -- Pointed thing's rightclick action takes precedence, unless player holds down the sneak key + if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].on_rightclick and not placer:get_player_control().sneak then + return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack) + end + + local pt + if minetest.registered_nodes[nu.name] and minetest.registered_nodes[nu.name].buildable_to then + pt = pointed_thing.under + else + pt = pointed_thing.above + end + local pt2 = {x=pt.x, y=pt.y, z=pt.z} + pt2.y = pt2.y+1 + local ptname = minetest.get_node(pt).name + local pt2name = minetest.get_node(pt2).name + if + (minetest.registered_nodes[ptname] and not minetest.registered_nodes[ptname].buildable_to) or + (minetest.registered_nodes[pt2name] and not minetest.registered_nodes[pt2name].buildable_to) + then + return itemstack + end + + -- get left coordinate for checking if another door is there + local pt_left = {x=pt.x, y=pt.y, z=pt.z} + local p2 = minetest.dir_to_facedir(placer:get_look_dir()) + + if p2 == 0 then + pt_left.x = pt_left.x-1 + elseif p2 == 1 then + pt_left.z = pt_left.z+1 + elseif p2 == 2 then + pt_left.x = pt_left.x+1 + elseif p2 == 3 then + pt_left.z = pt_left.z-1 + end + + local left_node = minetest.get_node(pt_left) + local mirrored = false + local door_dir = 1 + if left_node.name:sub(1, #name) == name then + mirrored = true + door_dir = 3 + p2 = left_node.param2 + end + + -- Set door nodes + minetest.set_node(pt, {name=name.."_b_"..door_dir, param2=p2}) + minetest.set_node(pt2, {name=name.."_t_"..door_dir, param2=p2}) + + if def.sounds and def.sounds.place then + minetest.sound_play(def.sounds.place, {pos=pt}, true) + end + + if def.only_placer_can_open then + local meta = minetest_get_meta(pt) + meta:set_string("doors_owner", "") + meta = minetest_get_meta(pt2) + meta:set_string("doors_owner", "") + end + + local meta1 = minetest_get_meta(pt) + local meta2 = minetest_get_meta(pt2) + -- save mirror state for the correct door + if mirrored then + meta1:set_int("is_mirrored", 1) + meta2:set_int("is_mirrored", 1) + end + + -- Save open state. 1 = open. 0 = closed + meta1:set_int("is_open", 0) + meta2:set_int("is_open", 0) + + + if not minetest.is_creative_enabled(pn) then + itemstack:take_item() + end + + on_place_node(pt, minetest.get_node(pt), placer, nu, itemstack, pointed_thing) + on_place_node(pt2, minetest.get_node(pt2), placer, minetest.get_node({x=ptu.x,y=ptu.y+1,z=ptu.z}), itemstack, pointed_thing) + + return itemstack + end, + }) + + local top_door_texture = def.tiles_top:match("(.+)%..+$") -- This removes the filename extension from the images. + local bottom_door_texture = def.tiles_bottom:match("(.+)%..+$") -- This removes the filename extension from the images. + + local texture_top = top_door_texture .. ".png" + local texture_bottom = bottom_door_texture .. ".png" + local texture_top_toppart = top_door_texture .. "_toppart.png" -- Special texture to make the top of opened doors not look weird. + local texture_bottom_bottompart = bottom_door_texture .. "_bottompart.png" -- Special texture to make the bottom of opened doors not look weird. + local texture_top_side = top_door_texture .. "_side.png" -- Special texture to make the side of opened doors not look weird. + local texture_bottom_side = bottom_door_texture .. "_side.png" -- Special texture to make the side of opened doors not look weird. + + local texture_top_mirrored = texture_top .. "^[transformFX" + local texture_bottom_mirrored = texture_bottom .. "^[transformFX" + local texture_top_toppart_mirrored = texture_top_toppart .. "^[transformFX" + local texture_bottom_bottompart_mirrored = texture_bottom_bottompart .. "^[transformFX" + local texture_top_side_mirrored = texture_top_side .. "^[transformFX" + local texture_bottom_side_mirrored = texture_bottom_side .. "^[transformFX" + + local function on_open_close(pos, dir, check_name, replace, replace_dir) + local meta1 = minetest_get_meta(pos) + pos.y = pos.y+dir + local meta2 = minetest_get_meta(pos) + + -- if name of other door is not the same as check_name -> return + if not minetest.get_node(pos).name == check_name then + return + end + + -- swap directions if mirrored + local params = {3,0,1,2} + if meta1:get_int("is_open") == 0 and meta2:get_int("is_mirrored") == 0 or meta1:get_int("is_open") == 1 and meta2:get_int("is_mirrored") == 1 then + params = {1,2,3,0} + end + + local p2 = minetest.get_node(pos).param2 + local np2 = params[p2+1] + + minetest.swap_node(pos, {name=replace_dir, param2=np2}) + pos.y = pos.y-dir + minetest.swap_node(pos, {name=replace, param2=np2}) + + local door_switching_sound + if meta1:get_int("is_open") == 1 then + door_switching_sound = def.sound_close + meta1:set_int("is_open", 0) + meta2:set_int("is_open", 0) + else + door_switching_sound = def.sound_open + meta1:set_int("is_open", 1) + meta2:set_int("is_open", 1) + end + minetest.sound_play(door_switching_sound, {pos = pos, gain = 0.5, max_hear_distance = 16}, true) + end + + local function on_mesecons_signal_open(pos, node) + local meta2 = minetest_get_meta(pos) + if meta2:get_int("is_mirrored") ~= 1 then + on_open_close(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2") + else + on_open_close(pos, 1, name.."_t_3", name.."_b_4", name.."_t_4") + end + end + + local function on_mesecons_signal_close(pos, node) + if not mesecon.is_powered({x=pos.x,y=pos.y+1,z=pos.z}) then + local meta2 = minetest_get_meta(pos) + if meta2:get_int("is_mirrored") ~= 1 then + on_open_close(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1") + else + on_open_close(pos, 1, name.."_t_4", name.."_b_3", name.."_t_3") + end + end + end + + local function on_mesecons_signal_open_top(pos, node) + on_mesecons_signal_open({x=pos.x, y=pos.y-1, z=pos.z}, node) + end + + local function on_mesecons_signal_close_top(pos, node) + if not mesecon.is_powered({x=pos.x,y=pos.y-1,z=pos.z}) then + on_mesecons_signal_close({x=pos.x, y=pos.y-1, z=pos.z}, node) + end + end + + local function check_player_priv(pos, player) + if not def.only_placer_can_open then + return true + end + local meta = minetest_get_meta(pos) + local pn = player:get_player_name() + return meta:get_string("doors_owner") == pn + end + + local on_rightclick + -- Disable on_rightclick if this is a redstone-only door + if not def.only_redstone_can_open then + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2") + end + end + end + + local template_def = { + tiles = nil, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + paramtype = "light", + paramtype2 = "facedir", + sunlight_propagates = true, + is_ground_content = false, + drop = "", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = def.node_box + }, + selection_box = { + type = "fixed", + fixed = def.selection_box + }, + groups = def.groups, + _mcl_hardness = def._mcl_hardness, + _mcl_blast_resistance = def._mcl_blast_resistance, + sounds = def.sounds, + + after_destruct = nil, + + on_rightclick = nil, + + mesecons = nil, + + on_rotate = nil, + + can_dig = check_player_priv, + } + + local _b_1_def = table.copy(template_def) + _b_1_def.tiles = {"blank.png", texture_bottom_bottompart .. "^[transformFY", texture_bottom_side, texture_bottom_side_mirrored, texture_bottom_mirrored, texture_bottom} + _b_1_def.after_destruct = function(bottom, oldnode) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + minetest.add_item(bottom, name) + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + if minetest.get_node(bottom).name ~= name.."_b_2" and minetest.get_node(top).name == name.."_t_1" then + minetest.remove_node(top) + end + end + end + _b_1_def.on_rightclick = on_rightclick + _b_1_def.mesecons = { effector = { + action_on = on_mesecons_signal_open, + }} + _b_1_def.on_rotate = function(bottom, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.name = name .."_t_1" + minetest.swap_node(top, node) + + return true + end + return false + end + + minetest.register_node(name.."_b_1", _b_1_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, -1, name.."_b_1", name.."_t_2", name.."_b_2") + end + end + end + + local _t_1_def = table.copy(template_def) + _t_1_def.tiles = {texture_top_toppart .. "^[transformFY", "blank.png", texture_top_side, texture_top_side_mirrored, texture_top_mirrored, texture_top} + _t_1_def.after_destruct = function(top, oldnode) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_2" and minetest.get_node(bottom).name == name.."_b_1" and oldnode.name == name.."_t_1" then + minetest.dig_node(bottom) + end + end + end + _t_1_def.on_rightclick = on_rightclick + _t_1_def.mesecons = { effector = { + action_on = on_mesecons_signal_open_top, + rules = mesecon.rules.flat, + }} + _t_1_def.on_rotate = function(top, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.name = name .."_b_1" + minetest.swap_node(bottom, node) + + return true + end + return false + end + + minetest.register_node(name.."_t_1", _t_1_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1") + end + end + end + + local _b_2_def = table.copy(template_def) + _b_2_def.tiles = {"blank.png", texture_bottom_bottompart_mirrored, texture_bottom_side, texture_bottom_side, texture_bottom, texture_bottom_mirrored} + _b_2_def.after_destruct = function(bottom, oldnode) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + minetest.add_item(bottom, name) + if minetest.get_node(bottom).name ~= name.."_b_1" and minetest.get_node(top).name == name.."_t_2" then + minetest.remove_node(top) + end + end + end + _b_2_def.on_rightclick = on_rightclick + _b_2_def.mesecons = { effector = { + action_off = on_mesecons_signal_close, + }} + _b_2_def.on_rotate = function(bottom, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.name = name .."_t_2" + minetest.swap_node(top, node) + + return true + end + return false + end + + minetest.register_node(name.."_b_2", _b_2_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, -1, name.."_b_2", name.."_t_1", name.."_b_1") + end + end + end + + local _t_2_def = table.copy(template_def) + _t_2_def.tiles = {texture_top_toppart_mirrored, "blank.png", texture_top_side, texture_top_side, texture_top, texture_top_mirrored} + _t_2_def.after_destruct = function(top, oldnode) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_1" and minetest.get_node(bottom).name == name.."_b_2" and oldnode.name == name.."_t_2" then + minetest.dig_node(bottom) + end + end + end + _t_2_def.on_rightclick = on_rightclick + _t_2_def.mesecons = { effector = { + action_off = on_mesecons_signal_close_top, + rules = mesecon.rules.flat, + }} + _t_2_def.on_rotate = function(top, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.name = name .."_b_2" + minetest.swap_node(bottom, node) + + return true + end + return false + end + + minetest.register_node(name.."_t_2", _t_2_def) + + if not def.only_redstone_can_open then + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, 1, name.."_t_3", name.."_b_4", name.."_t_4") + end + end + end + + local _b_3_def = table.copy(template_def) + _b_3_def.tiles = {"blank.png", texture_bottom_mirrored .. "^[transformFY", texture_bottom_side, texture_bottom_side_mirrored, texture_bottom, texture_bottom_mirrored} + _b_3_def.after_destruct = function(bottom, oldnode) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + minetest.add_item(bottom, name) + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + if minetest.get_node(bottom).name ~= name.."_b_4" and minetest.get_node(top).name == name.."_t_3" then + minetest.remove_node(top) + end + end + end + _b_3_def.on_rightclick = on_rightclick + _b_3_def.mesecons = { effector = { + action_on = on_mesecons_signal_open, + }} + _b_3_def.on_rotate = function(bottom, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.name = name .."_t_3" + minetest.swap_node(top, node) + + return true + end + return false + end + + minetest.register_node(name.."_b_3", _b_3_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, -1, name.."_b_3", name.."_t_4", name.."_b_4") + end + end + end + + local _t_3_def = table.copy(template_def) + _t_3_def.tiles = {texture_top_toppart_mirrored .. "^[transformFY", "blank.png", texture_top_side, texture_top_side_mirrored, texture_top, texture_top_mirrored} + _t_3_def.after_destruct = function(top, oldnode) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_4" and minetest.get_node(bottom).name == name.."_b_3" and oldnode.name == name.."_t_3" then + minetest.dig_node(bottom) + end + end + end + _t_3_def.on_rightclick = on_rightclick + _t_3_def.mesecons = { effector = { + action_on = on_mesecons_signal_open_top, + rules = mesecon.rules.flat, + }} + _t_3_def.on_rotate = function(top, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.name = name .."_b_3" + minetest.swap_node(bottom, node) + + return true + end + return false + end + + minetest.register_node(name.."_t_3", _t_3_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, 1, name.."_t_4", name.."_b_3", name.."_t_3") + end + end + end + + local _b_4_def = table.copy(template_def) + _b_4_def.tiles = {"blank.png", texture_bottom_bottompart, texture_bottom_side_mirrored, texture_bottom_side_mirrored, texture_bottom_mirrored, texture_bottom} + _b_4_def.after_destruct = function(bottom, oldnode) + local meta_bottom = minetest_get_meta(bottom) + if meta_bottom:get_int("rotation") == 1 then + meta_bottom:set_int("rotation", 0) + else + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + minetest.add_item(bottom, name) + if minetest.get_node(bottom).name ~= name.."_b_3" and minetest.get_node(top).name == name.."_t_4" then + minetest.remove_node(top) + end + end + end + _b_4_def.on_rightclick = on_rightclick + _b_4_def.mesecons = { effector = { + action_off = on_mesecons_signal_close, + }} + _b_4_def.on_rotate = function(bottom, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(bottom, node, mode) + minetest.swap_node(bottom, node) + + local top = {x=bottom.x,y=bottom.y+1,z=bottom.z} + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.name = name .."_t_4" + minetest.swap_node(top, node) + + return true + end + return false + end + + minetest.register_node(name.."_b_4", _b_4_def) + + if def.only_redstone_can_open then + on_rightclick = nil + else + on_rightclick = function(pos, node, clicker) + if check_player_priv(pos, clicker) then + on_open_close(pos, -1, name.."_b_4", name.."_t_3", name.."_b_3") + end + end + end + + local _t_4_def = table.copy(template_def) + _t_4_def.tiles = {texture_top_toppart, "blank.png", texture_top_side_mirrored, texture_top_side_mirrored, texture_top_mirrored, texture_top} + _t_4_def.after_destruct = function(top, oldnode) + local meta_top = minetest_get_meta(top) + if meta_top:get_int("rotation") == 1 then + meta_top:set_int("rotation", 0) + else + local bottom = { x = top.x, y = top.y - 1, z = top.z } + if minetest.get_node(top).name ~= name.."_t_3" and minetest.get_node(bottom).name == name.."_b_4" and oldnode.name == name.."_t_4" then + minetest.dig_node(bottom) + end + end + end + _t_4_def.on_rightclick = on_rightclick + _t_4_def.mesecons = { effector = { + action_off = on_mesecons_signal_close_top, + rules = mesecon.rules.flat, + }} + _t_4_def.on_rotate = function(top, node, user, mode, param2) + if mode == screwdriver.ROTATE_FACE then + local meta_top = minetest_get_meta(top) + meta_top:set_int("rotation", 1) + node.param2 = screwdriver.rotate.facedir(top, node, mode) + minetest.swap_node(top, node) + + local bottom = {x=top.x,y=top.y-1,z=top.z} + local meta_bottom = minetest_get_meta(bottom) + meta_bottom:set_int("rotation", 1) + node.name = name .."_b_4" + minetest.swap_node(bottom, node) + + return true + end + return false + end + + minetest.register_node(name.."_t_4", _t_4_def) + + + -- Add entry aliases for the Help + if minetest.get_modpath("doc") then + doc.add_entry_alias("craftitems", name, "nodes", name.."_b_1") + doc.add_entry_alias("craftitems", name, "nodes", name.."_b_2") + doc.add_entry_alias("craftitems", name, "nodes", name.."_b_3") + doc.add_entry_alias("craftitems", name, "nodes", name.."_b_4") + doc.add_entry_alias("craftitems", name, "nodes", name.."_t_1") + doc.add_entry_alias("craftitems", name, "nodes", name.."_t_2") + doc.add_entry_alias("craftitems", name, "nodes", name.."_t_3") + doc.add_entry_alias("craftitems", name, "nodes", name.."_t_4") + end +end diff --git a/mods/ITEMS/mcl_doors/api_trapdoors.lua b/mods/ITEMS/mcl_doors/api_trapdoors.lua index a7ca6cb15..5b7a0e5d0 100644 --- a/mods/ITEMS/mcl_doors/api_trapdoors.lua +++ b/mods/ITEMS/mcl_doors/api_trapdoors.lua @@ -1,231 +1,231 @@ -local S = minetest.get_translator("mcl_doors") - --- Wrapper around mintest.pointed_thing_to_face_pos. -local function get_fpos(placer, pointed_thing) - local fpos - -- Workaround: minetest.pointed_thing_to_face_pos crashes in MT 0.4.16 if - -- pointed_thing.under and pointed_thing.above are equal - -- FIXME: Remove this when MT got fixed. - if not vector.equals(pointed_thing.under, pointed_thing.above) then - -- The happy case: Everything is normal - local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing) - fpos = finepos.y % 1 - else - -- Fallback if both above and under are equal - fpos = 0 - end - return fpos -end - ----- Trapdoor ---- - -local on_rotate -if minetest.get_modpath("screwdriver") then - on_rotate = function(pos, node, user, mode, param2) - -- Flip trapdoor vertically - if mode == screwdriver.ROTATE_AXIS then - local minor = node.param2 - if node.param2 >= 20 then - minor = node.param2 - 20 - if minor == 3 then - minor = 1 - elseif minor == 1 then - minor = 3 - end - node.param2 = minor - else - if minor == 3 then - minor = 1 - elseif minor == 1 then - minor = 3 - end - node.param2 = minor - node.param2 = node.param2 + 20 - end - minetest.set_node(pos, node) - return true - end - end -end - -function mcl_doors:register_trapdoor(name, def) - local groups = table.copy(def.groups) - if groups == nil then - groups = {} - end - groups.mesecon_ignore_opaque_dig = 1 - - if not def.sound_open then - def.sound_open = "doors_door_open" - end - if not def.sound_close then - def.sound_close = "doors_door_close" - end - - local function punch(pos) - local me = minetest.get_node(pos) - 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 - 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} - end - minetest.set_node(pos, tmp_node) - end - - local on_rightclick - if not def.only_redstone_can_open then - on_rightclick = function(pos, node, clicker) - punch(pos) - end - end - - -- Default help texts - local longdesc, usagehelp, tt_help - 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.") - 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.") - 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 not tt_help then - 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 - end - - -- Closed trapdoor - - local tile_front = def.tile_front - local tile_side = def.tile_side - if not tile_side then - tile_side = tile_front - end - local tiles_closed = { - tile_front, - tile_front .. "^[transformFY", - tile_side, tile_side, - tile_side, tile_side, - } - - local groups_closed = groups - groups_closed.trapdoor = 1 - groups_closed.deco_block = 1 - minetest.register_node(name, { - description = def.description, - _tt_help = tt_help, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usagehelp, - drawtype = "nodebox", - tiles = tiles_closed, - inventory_image = def.inventory_image, - wield_image = def.wield_image, - is_ground_content = false, - paramtype = "light", - stack_max = 64, - paramtype2 = "facedir", - sunlight_propagates = true, - groups = groups_closed, - _mcl_hardness = def._mcl_hardness, - _mcl_blast_resistance = def._mcl_blast_resistance, - sounds = def.sounds, - node_box = { - type = "fixed", - fixed = { - {-8/16, -8/16, -8/16, 8/16, -5/16, 8/16},}, - }, - 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 - local param2 = 0 - - local placer_pos = placer:get_pos() - if placer_pos then - param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos)) - end - - local fpos = get_fpos(placer, pointed_thing) - - 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 - param2 = param2 + 20 - if param2 == 21 then - param2 = 23 - elseif param2 == 23 then - param2 = 21 - end - end - return minetest.item_place(itemstack, placer, pointed_thing, param2) - end, - on_rightclick = on_rightclick, - on_rotate = on_rotate, - }) - - -- Open trapdoor - - local groups_open = table.copy(groups) - - local tiles_open = { - tile_side, - tile_side .. "^[transformR180", - tile_side .. "^[transformR270", - tile_side .. "^[transformR90", - tile_front .. "^[transform46", - tile_front .. "^[transformFY", - } - - groups_open.trapdoor = 2 - groups_open.not_in_creative_inventory = 1 - minetest.register_node(name.."_open", { - drawtype = "nodebox", - tiles = tiles_open, - 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, - 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, - }) - - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", name, "nodes", name.."_open") - end - -end +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Wrapper around mintest.pointed_thing_to_face_pos. +local function get_fpos(placer, pointed_thing) + local fpos + -- Workaround: minetest.pointed_thing_to_face_pos crashes in MT 0.4.16 if + -- pointed_thing.under and pointed_thing.above are equal + -- FIXME: Remove this when MT got fixed. + if not vector.equals(pointed_thing.under, pointed_thing.above) then + -- The happy case: Everything is normal + local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing) + fpos = finepos.y % 1 + else + -- Fallback if both above and under are equal + fpos = 0 + end + return fpos +end + +---- Trapdoor ---- + +local on_rotate +if minetest.get_modpath("screwdriver") then + on_rotate = function(pos, node, user, mode, param2) + -- Flip trapdoor vertically + if mode == screwdriver.ROTATE_AXIS then + local minor = node.param2 + if node.param2 >= 20 then + minor = node.param2 - 20 + if minor == 3 then + minor = 1 + elseif minor == 1 then + minor = 3 + end + node.param2 = minor + else + if minor == 3 then + minor = 1 + elseif minor == 1 then + minor = 3 + end + node.param2 = minor + node.param2 = node.param2 + 20 + end + minetest.set_node(pos, node) + return true + end + end +end + +function mcl_doors:register_trapdoor(name, def) + local groups = table.copy(def.groups) + if groups == nil then + groups = {} + end + groups.mesecon_ignore_opaque_dig = 1 + + if not def.sound_open then + def.sound_open = "doors_door_open" + end + if not def.sound_close then + def.sound_close = "doors_door_close" + end + + local function punch(pos) + local me = minetest.get_node(pos) + 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 + 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} + end + minetest.set_node(pos, tmp_node) + end + + local on_rightclick + if not def.only_redstone_can_open then + on_rightclick = function(pos, node, clicker) + punch(pos) + end + end + + -- Default help texts + local longdesc, usagehelp, tt_help + 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.") + 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.") + 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 + + -- Closed trapdoor + + local tile_front = def.tile_front + local tile_side = def.tile_side + if not tile_side then + tile_side = tile_front + end + local tiles_closed = { + tile_front, + tile_front .. "^[transformFY", + tile_side, tile_side, + tile_side, tile_side, + } + + local groups_closed = groups + groups_closed.trapdoor = 1 + groups_closed.deco_block = 1 + minetest.register_node(name, { + description = def.description, + _tt_help = tt_help, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = usagehelp, + drawtype = "nodebox", + tiles = tiles_closed, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + inventory_image = def.inventory_image, + wield_image = def.wield_image, + is_ground_content = false, + paramtype = "light", + stack_max = 64, + paramtype2 = "facedir", + sunlight_propagates = true, + groups = groups_closed, + _mcl_hardness = def._mcl_hardness, + _mcl_blast_resistance = def._mcl_blast_resistance, + sounds = def.sounds, + node_box = { + type = "fixed", + fixed = { + {-8/16, -8/16, -8/16, 8/16, -5/16, 8/16},}, + }, + 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 + local param2 = 0 + + local placer_pos = placer:get_pos() + if placer_pos then + param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos)) + end + + local fpos = get_fpos(placer, pointed_thing) + + --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 + param2 = param2 + 20 + if param2 == 21 then + param2 = 23 + elseif param2 == 23 then + param2 = 21 + end + end + return minetest.item_place(itemstack, placer, pointed_thing, param2) + end, + on_rightclick = on_rightclick, + on_rotate = on_rotate, + }) + + -- Open trapdoor + + local groups_open = table.copy(groups) + + local tiles_open = { + tile_side, + tile_side .. "^[transformR180", + tile_side .. "^[transformR270", + tile_side .. "^[transformR90", + tile_front .. "^[transform46", + tile_front .. "^[transformFY", + } + + groups_open.trapdoor = 2 + groups_open.not_in_creative_inventory = 1 + minetest.register_node(name.."_open", { + drawtype = "nodebox", + tiles = tiles_open, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + 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, + 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, + }) + + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", name, "nodes", name.."_open") + end + +end diff --git a/mods/ITEMS/mcl_doors/depends.txt b/mods/ITEMS/mcl_doors/depends.txt deleted file mode 100644 index e2ae3cf4b..000000000 --- a/mods/ITEMS/mcl_doors/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -doc? -screwdriver? -mesecons diff --git a/mods/ITEMS/mcl_doors/init.lua b/mods/ITEMS/mcl_doors/init.lua index 9e06b513f..a39b33c5e 100644 --- a/mods/ITEMS/mcl_doors/init.lua +++ b/mods/ITEMS/mcl_doors/init.lua @@ -1,9 +1,9 @@ -mcl_doors = {} - -local this = minetest.get_current_modname() -local path = minetest.get_modpath(this) - -dofile(path.."/api_doors.lua") -- Doors API -dofile(path.."/api_trapdoors.lua") -- Trapdoors API -dofile(path.."/register.lua") -- Register builtin doors and trapdoors -dofile(path.."/alias.lua") -- Legacy aliases +mcl_doors = {} + +local this = minetest.get_current_modname() +local path = minetest.get_modpath(this) + +dofile(path.."/api_doors.lua") -- Doors API +dofile(path.."/api_trapdoors.lua") -- Trapdoors API +dofile(path.."/register.lua") -- Register builtin doors and trapdoors +dofile(path.."/alias.lua") -- Legacy aliases diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.de.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.de.tr index 03be49a68..be88513cb 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.de.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.de.tr @@ -16,9 +16,9 @@ Birch Trapdoor=Birkenfalltür Spruce Trapdoor=Fichtenfalltür Dark Oak Trapdoor=Schwarzeichenfalltür Jungle Trapdoor=Dschungelfalltür -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.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. +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.=Holzfalltüren sind horizontale Barrieren, die von Hand oder mit einem Redstone-Signal geöffnet oder geschlossen werden können. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. To open or close the trapdoor, rightclick it or send a redstone signal to it.=Um die Falltür zu öffnen oder zu schließen, rechtsklicken Sie sie oder schicken Sie ein Redstone-Signal zu ihr. Iron Trapdoor=Eisenfalltür -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.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nach dem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. +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.=Eisenfalltüren sind horizontale Barrieren, die nur mit einem Redstone-Signal geöffnet oder geschlossen werden können, nicht von Hand. Sie belegen den oberen oder unteren Teil eines Blocks, je nachdem, wie sie platziert wurden. Wenn geöffnet, können sie wie eine Leiter erklommen werden. Openable by players and redstone power=Zu öffnen von Spielern und Redstoneenergie Openable by redstone power=Zu öffnen von Redstoneenergie diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.es.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.es.tr index 1a510815b..eca8efab4 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.es.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.es.tr @@ -20,3 +20,5 @@ Wooden trapdoors are horizontal barriers which can be opened and closed by hand To open or close the trapdoor, rightclick it or send a redstone signal to it.=Para abrir o cerrar la trampilla, haga clic derecho o envíele una señal de redstone. Iron Trapdoor=Trampilla de hierro 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.=Las trampillas de hierro son barreras horizontales que solo pueden abrirse y cerrarse mediante señales de redstone, no a mano. Ocupan la parte superior o inferior de un bloque, dependiendo de cómo se hayan colocado. Cuando están abiertos, se pueden subir como una escalera. +Openable by players and redstone power=Puede ser abierta por jugadores y energía de redstone +Openable by redstone power=Puede ser abierta por energía de redstone diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr index 9d1f25d9a..c7d3ddaa1 100644 --- a/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.fr.tr @@ -1,24 +1,24 @@ # textdomain: mcl_doors 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. To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en bois, faites un clic droit dessus ou fournissez à sa moitié inférieure un signal redstone. -Oak Door=Porte en Chêne -Acacia Door=Porte en Acacia -Birch Door=Porte en Bouleau -Dark Oak Door=Porte en Chêne Noir -Jungle Door=Porte en Acajou -Spruce Door=Porte en Sapin -Iron Door=Porte en Fer +Oak Door=Porte en chêne +Acacia Door=Porte en acacia +Birch Door=Porte en bouleau +Dark Oak Door=Porte en chêne noir +Jungle Door=Porte en acajou +Spruce Door=Porte en sapin +Iron Door=Porte en fer Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=Les portes en fer sont des barrières hautes à 2 blocs qui ne peuvent être ouvertes ou fermées que par un signal redstone, mais pas à la main. To open or close an iron door, supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en fer, fournir à sa moitié inférieure un signal redstone. -Oak Trapdoor=Trappe en Chêne -Acacia Trapdoor=Trappe en Acacia -Birch Trapdoor=Trappe en Bouleau -Spruce Trapdoor=Trappe en Sapin -Dark Oak Trapdoor=Trappe en Chêne Noir -Jungle Trapdoor=Trappe en Acajou +Oak Trapdoor=Trappe en chêne +Acacia Trapdoor=Trappe en acacia +Birch Trapdoor=Trappe en bouleau +Spruce Trapdoor=Trappe en sapin +Dark Oak Trapdoor=Trappe en chêne noir +Jungle Trapdoor=Trappe en acajou 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.=Les trappes en bois sont des barrières horizontales qui peuvent être ouvertes et fermées à la main ou par un signal redstone. 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. To open or close the trapdoor, rightclick it or send a redstone signal to it.=Pour ouvrir ou fermer la trappe, faites un clic droit dessus ou envoyez-lui un signal redstone. -Iron Trapdoor=Trappe en Fer +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 diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr new file mode 100644 index 000000000..3dbdb7e5d --- /dev/null +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.ja.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_doors +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=アカシアのドア +Birch Door=シラカバのドア +Dark Oak 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.=鉄のドアは高さ2ブロックの遮蔽物で、レッドストーン信号によってのみ開閉でき、手では開けられません。 +To open or close an iron door, supply its lower half with a redstone signal.=鉄のドアを開閉するには、その下半分にレッドストーン信号を供給します。 +Oak Trapdoor=オークのトラップドア +Acacia Trapdoor=アカシアのトラップドア +Birch Trapdoor=シラカバのトラップドア +Spruce Trapdoor=トウヒのトラップドア +Dark Oak 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=レッドストーン動力によって開閉可能 diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.pl.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.pl.tr new file mode 100644 index 000000000..e26c5861a --- /dev/null +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.pl.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_doors +Wooden doors are 2-block high barriers which can be opened or closed by hand and by a redstone signal.=Drewniane drzwi są blokami o wysokości 2, które mogą być otworzone i zamknięte ręcznie bądź przez zasilenie czerwienitem. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Aby otworzyć lub zamknąć drewniane drzwi, kliknij je prawym przyciskiem bądź zasil ich dolną połowę czerwienitem. +Oak Door=Dębowe drzwi +Acacia Door=Akacjowe drzwi +Birch Door=Brzozowe drzwi +Dark Oak Door=Ciemno-dębowe drzwi +Jungle Door=Tropikalne drzwi +Spruce Door=Świerkowe drzwi +Iron Door=Żelazne drzwi +Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=Żelazne drzwi są blokami o wysokości dwa, które mogą być otwarte lub zamknięte przez zasilanie czerwienitem, ale nie ręcznie. +To open or close an iron door, supply its lower half with a redstone signal.=Aby otworzyć lub zamknąć żelazne drzwi zasil ich dolną część czerwienitem. +Oak Trapdoor=Dębowa klapa +Acacia Trapdoor=Akacjowa klapa +Birch Trapdoor=Brzozowa klapa +Spruce Trapdoor=Świerkowa klapa +Dark Oak Trapdoor=Ciemno-dębowa klapa +Jungle Trapdoor=Tropikalna klapa +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.=Drewniane klapy są poziomymi barierami, które mogą być otwarte i zamknięte ręcznie bądź przez zasilenie czerwienitem. Zajmują główną lub dolną część bloku w zależności od tego jak zostaną postawione. Gdy są otwarte można się po nich wspinać jak po drabinie. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Aby otworzyć lub zamknąć drewniane klapy, kliknij je prawym przyciskiem bądź zasil ich dolną połowę czerwienitem. +Iron Trapdoor=Żelazna klapa +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.=Żelazne klapy są poziomymi barierami, które mogą być otwarte i zamknięte tylko przez zasilenie czerwienitem, ale nie ręcznie. Zajmują główną lub dolną część bloku w zależności od tego jak zostaną postawione. Gdy są otwarte można się po nich wspinać jak po drabinie. +Openable by players and redstone power=Mogą być otworzone przez graczy i zasilanie czerwienitem +Openable by redstone power=Mogą być otworzone przez zasilanie czerwienitem diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr new file mode 100644 index 000000000..321c99e33 --- /dev/null +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.pt_BR.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_doors +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 com dois blocos de altura que podem ser abertas ou fechadas manualmente ou 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, aperte com o botão direito nela ou acione sua parte inferior com um sinal de redstone. +Oak Door=Porta de Carvalho +Acacia Door=Porta de Acácia +Birch Door=Porta de Bétula +Dark Oak Door=Porta de Carvalho Escuro +Jungle Door=Porta de Madeira da Selva +Spruce Door=Porta de Pinheiro +Iron Door=Porta de Ferro +Iron doors are 2-block high barriers which can only be opened or closed by a redstone signal, but not by hand.=Portas de ferro são barreiras com dois blocos de altura que só podem ser abertas ou fechadas com um sinal de redstone, não manualmente. +To open or close an iron door, supply its lower half with a redstone signal.=Para abrir ou fechar uma porta de ferro, acione sua metade inferior com um sinal de redstone. +Oak Trapdoor=Alçapão de Carvalho +Acacia Trapdoor=Alçapão de Acácia +Birch Trapdoor=Alçapão de Bétula +Spruce Trapdoor=Alçapão de Pinheiro +Dark Oak Trapdoor=Alçapão de Carvalho Escuro +Jungle Trapdoor=Alçapão de Madeira da Selva +Wooden trapdoors are horizontal barriers whch 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 que podem ser abertas ou fechadas manualmente ou com um sinal de redstone. Elas ocupam as partes inferiores ou superiores de um bloco, dependendo de como elas foram colocadas. Quando abertas, elas podem ser escaladas como escadas. +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 redstone power=Aberto por sinal de redstone diff --git a/mods/ITEMS/mcl_doors/locale/mcl_doors.zh_TW.tr b/mods/ITEMS/mcl_doors/locale/mcl_doors.zh_TW.tr new file mode 100644 index 000000000..62e2761d7 --- /dev/null +++ b/mods/ITEMS/mcl_doors/locale/mcl_doors.zh_TW.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_doors +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=相思木門 +Birch Door=樺木門 +Dark Oak 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.=鐵門是2格高的障礙物,能通過紅石信號打開或關閉,但不能用手。 +To open or close an iron door, supply its lower half with a redstone signal.=要打開或關閉鐵門,請在其下半部分提供紅石信號。 +Oak Trapdoor=橡木地板門 +Acacia Trapdoor=相思木地板門 +Birch Trapdoor=樺木地板門 +Spruce Trapdoor=杉木地板門 +Dark Oak 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=能通過紅石信號打開 diff --git a/mods/ITEMS/mcl_doors/mod.conf b/mods/ITEMS/mcl_doors/mod.conf index d504e8497..ed2b094a8 100644 --- a/mods/ITEMS/mcl_doors/mod.conf +++ b/mods/ITEMS/mcl_doors/mod.conf @@ -1 +1,3 @@ name = mcl_doors +depends = mcl_core, mcl_sounds, mesecons +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_doors/register.lua b/mods/ITEMS/mcl_doors/register.lua index 2ffd4b245..142bfa52e 100644 --- a/mods/ITEMS/mcl_doors/register.lua +++ b/mods/ITEMS/mcl_doors/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_doors") +local S = minetest.get_translator(minetest.get_current_modname()) --[[ Doors ]] @@ -14,8 +14,8 @@ mcl_doors:register_door("mcl_doors:wooden_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_wood_lower.png", "mcl_doors_door_wood_side_lower.png"}, - tiles_top = {"mcl_doors_door_wood_upper.png", "mcl_doors_door_wood_side_upper.png"}, + tiles_bottom = "mcl_doors_door_wood_lower.png", + tiles_top = "mcl_doors_door_wood_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -37,8 +37,8 @@ mcl_doors:register_door("mcl_doors:acacia_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_acacia_lower.png", "mcl_doors_door_acacia_side_lower.png"}, - tiles_top = {"mcl_doors_door_acacia_upper.png", "mcl_doors_door_acacia_side_upper.png"}, + tiles_bottom = "mcl_doors_door_acacia_lower.png", + tiles_top = "mcl_doors_door_acacia_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -60,8 +60,8 @@ mcl_doors:register_door("mcl_doors:birch_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_birch_lower.png", "mcl_doors_door_birch_side_lower.png"}, - tiles_top = {"mcl_doors_door_birch_upper.png", "mcl_doors_door_birch_side_upper.png"}, + tiles_bottom = "mcl_doors_door_birch_lower.png", + tiles_top = "mcl_doors_door_birch_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -83,8 +83,8 @@ mcl_doors:register_door("mcl_doors:dark_oak_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_dark_oak_lower.png", "mcl_doors_door_dark_oak_side_lower.png"}, - tiles_top = {"mcl_doors_door_dark_oak_upper.png", "mcl_doors_door_dark_oak_side_upper.png"}, + tiles_bottom = "mcl_doors_door_dark_oak_lower.png", + tiles_top = "mcl_doors_door_dark_oak_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -106,8 +106,8 @@ mcl_doors:register_door("mcl_doors:jungle_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_jungle_lower.png", "mcl_doors_door_jungle_side_lower.png"}, - tiles_top = {"mcl_doors_door_jungle_upper.png", "mcl_doors_door_jungle_side_upper.png"}, + tiles_bottom = "mcl_doors_door_jungle_lower.png", + tiles_top = "mcl_doors_door_jungle_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -129,8 +129,8 @@ mcl_doors:register_door("mcl_doors:spruce_door", { groups = {handy=1,axey=1, material_wood=1, flammable=-1}, _mcl_hardness = 3, _mcl_blast_resistance = 3, - tiles_bottom = {"mcl_doors_door_spruce_lower.png", "mcl_doors_door_spruce_side_lower.png"}, - tiles_top = {"mcl_doors_door_spruce_upper.png", "mcl_doors_door_spruce_side_upper.png"}, + tiles_bottom = "mcl_doors_door_spruce_lower.png", + tiles_top = "mcl_doors_door_spruce_upper.png", sounds = mcl_sounds.node_sound_wood_defaults(), }) @@ -183,8 +183,8 @@ mcl_doors:register_door("mcl_doors:iron_door", { groups = {pickaxey=1, mesecon_effector_on=1}, _mcl_hardness = 5, _mcl_blast_resistance = 5, - tiles_bottom = {"mcl_doors_door_iron_lower.png^[transformFX", "mcl_doors_door_iron_side_lower.png"}, - tiles_top = {"mcl_doors_door_iron_upper.png^[transformFX", "mcl_doors_door_iron_side_upper.png"}, + tiles_bottom = "mcl_doors_door_iron_lower.png", + tiles_top = "mcl_doors_door_iron_upper.png", sounds = mcl_sounds.node_sound_metal_defaults(), sound_open = "doors_steel_door_open", sound_close = "doors_steel_door_close", @@ -260,9 +260,9 @@ mcl_doors:register_trapdoor("mcl_doors:iron_trapdoor", { }) minetest.register_craft({ - output = 'mcl_doors:iron_trapdoor', + output = "mcl_doors:iron_trapdoor", recipe = { - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, } }) diff --git a/mods/ITEMS/mcl_doors/textures/doors_item_steel.png b/mods/ITEMS/mcl_doors/textures/doors_item_steel.png deleted file mode 100644 index 82a500baf..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/doors_item_steel.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/doors_item_wood.png b/mods/ITEMS/mcl_doors/textures/doors_item_wood.png deleted file mode 100644 index ca3a31862..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/doors_item_wood.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_side.png b/mods/ITEMS/mcl_doors/textures/doors_trapdoor_side.png deleted file mode 100644 index 97a5904c4..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel.png b/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel.png deleted file mode 100644 index dc8f5325c..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel_side.png b/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel_side.png deleted file mode 100644 index 109829f5b..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/doors_trapdoor_steel_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia.png deleted file mode 100644 index 11657784d..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_lower.png deleted file mode 100644 index 510c04728..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_lower.png deleted file mode 100644 index 9faa931d0..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_upper.png deleted file mode 100644 index f1c04b99e..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_upper.png deleted file mode 100644 index 7e97bb718..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_acacia_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch.png deleted file mode 100644 index 58af89e58..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_lower.png deleted file mode 100644 index 844ce3a21..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_lower.png deleted file mode 100644 index dd7310ef2..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_upper.png deleted file mode 100644 index a6805e4f6..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_upper.png deleted file mode 100644 index 3de49d6ab..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_birch_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak.png deleted file mode 100644 index 7b827cc46..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_lower.png deleted file mode 100644 index b3b7e81da..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_lower.png deleted file mode 100644 index 51f28b35e..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_upper.png deleted file mode 100644 index db254813e..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_upper.png deleted file mode 100644 index 398547b91..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_dark_oak_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_lower.png deleted file mode 100644 index 583b3e261..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_lower.png deleted file mode 100644 index 583b3e261..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_upper.png deleted file mode 100644 index a30b93003..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_upper.png deleted file mode 100644 index 093d91ce3..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_iron_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle.png deleted file mode 100644 index 29032482c..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_lower.png deleted file mode 100644 index dde5be774..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_lower.png deleted file mode 100644 index 6014b5303..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_upper.png deleted file mode 100644 index 9f01843a6..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_upper.png deleted file mode 100644 index c69c15717..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_jungle_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce.png deleted file mode 100644 index 847ec3f9b..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_lower.png deleted file mode 100644 index ebe81d620..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_lower.png deleted file mode 100644 index c46055962..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_upper.png deleted file mode 100644 index 8ca2474d4..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_upper.png deleted file mode 100644 index 9d7daaab9..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_spruce_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_lower.png deleted file mode 100644 index e69244b56..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_lower.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_lower.png deleted file mode 100644 index 6ee18505d..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_lower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_upper.png deleted file mode 100644 index abdbb0e5c..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_side_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_upper.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_upper.png deleted file mode 100644 index 4e75538c2..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_door_wood_upper.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia.png deleted file mode 100644 index 7e01900ed..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia_side.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia_side.png deleted file mode 100644 index e63f839e2..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_acacia_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch.png deleted file mode 100644 index fbd39dbcb..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch_side.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch_side.png deleted file mode 100644 index 040eaaec6..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_birch_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_dark_oak_side.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_dark_oak_side.png deleted file mode 100644 index d344c6352..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_dark_oak_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle.png deleted file mode 100644 index cf83de6a0..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle_side.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle_side.png deleted file mode 100644 index cc7cbafac..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_jungle_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce.png deleted file mode 100644 index 3c743f977..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce.png and /dev/null differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce_side.png b/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce_side.png deleted file mode 100644 index d05d717ca..000000000 Binary files a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_spruce_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_dye/API.md b/mods/ITEMS/mcl_dye/API.md new file mode 100644 index 000000000..04169f966 --- /dev/null +++ b/mods/ITEMS/mcl_dye/API.md @@ -0,0 +1,14 @@ +# mcl_dye + +# Bone meal API +Callback and particle functions. + +## mcl_dye.add_bone_meal_particle(pos, def) +Spawns standard or custom bone meal particles. +* `pos`: position, is ignored if you define def.minpos and def.maxpos +* `def`: (optional) particle definition + +## mcl_dye.register_on_bone_meal_apply(function(pointed_thing, user)) +Called when the bone meal is applied anywhere. +* `pointed_thing`: exact pointing location (see Minetest API), where the bone meal is applied +* `user`: ObjectRef of the player who aplied the bone meal, can be nil! \ No newline at end of file diff --git a/mods/ITEMS/mcl_dye/depends.txt b/mods/ITEMS/mcl_dye/depends.txt deleted file mode 100644 index 83185405e..000000000 --- a/mods/ITEMS/mcl_dye/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_flowers -mcl_mobitems -mcl_cocoas diff --git a/mods/ITEMS/mcl_dye/init.lua b/mods/ITEMS/mcl_dye/init.lua index e84e75d91..abd6ed1d9 100644 --- a/mods/ITEMS/mcl_dye/init.lua +++ b/mods/ITEMS/mcl_dye/init.lua @@ -7,17 +7,16 @@ -- Note: As this uses basecolor_*, you'd need 9 of these. -- minetest.register_craft({ -- type = "shapeless", --- output = ':item_yellow', --- recipe = {':item_no_color', 'group:basecolor_yellow'}, +-- output = ":item_yellow", +-- recipe = {":item_no_color", "group:basecolor_yellow"}, -- }) mcl_dye = {} -local S = minetest.get_translator("mcl_dye") +local S = minetest.get_translator(minetest.get_current_modname()) --- Other mods can use these for looping through available colors -mcl_dye.basecolors = {"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"} -mcl_dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "orange", "yellow", "lime", "green", "aqua", "cyan", "sky_blue", "blue", "violet", "magenta", "red_violet"} +local math = math +local string = string -- Base color groups: -- - basecolor_white @@ -59,43 +58,43 @@ mcl_dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "o -- - unicolor_medium__s50 -- - unicolor_dark__s50 --- Local stuff -local dyelocal = {} - -- This collection of colors is partly a historic thing, partly something else. -dyelocal.dyes = { - {"white", "mcl_dye_white", S("Bone Meal"), {dye=1, craftitem=1, basecolor_white=1, excolor_white=1, unicolor_white=1}}, - {"grey", "dye_grey", S("Light Grey Dye"), {dye=1, craftitem=1, basecolor_grey=1, excolor_grey=1, unicolor_grey=1}}, - {"dark_grey", "dye_dark_grey", S("Grey Dye"), {dye=1, craftitem=1, basecolor_grey=1, excolor_darkgrey=1, unicolor_darkgrey=1}}, - {"black", "mcl_dye_black", S("Ink Sac"), {dye=1, craftitem=1, basecolor_black=1, excolor_black=1, unicolor_black=1}}, - {"violet", "dye_violet", S("Purple Dye"), {dye=1, craftitem=1, basecolor_magenta=1, excolor_violet=1, unicolor_violet=1}}, - {"blue", "mcl_dye_blue", S("Lapis Lazuli"), {dye=1, craftitem=1, basecolor_blue=1, excolor_blue=1, unicolor_blue=1}}, - {"lightblue", "mcl_dye_light_blue", S("Light Blue Dye"), {dye=1, craftitem=1, basecolor_blue=1, excolor_blue=1, unicolor_light_blue=1}}, - {"cyan", "dye_cyan", S("Cyan Dye"), {dye=1, craftitem=1, basecolor_cyan=1, excolor_cyan=1, unicolor_cyan=1}}, - {"dark_green", "dye_dark_green", S("Cactus Green"),{dye=1, craftitem=1, basecolor_green=1, excolor_green=1, unicolor_dark_green=1}}, - {"green", "mcl_dye_lime", S("Lime Dye"), {dye=1, craftitem=1, basecolor_green=1, excolor_green=1, unicolor_green=1}}, - {"yellow", "dye_yellow", S("Dandelion Yellow"), {dye=1, craftitem=1, basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1}}, - {"brown", "mcl_dye_brown", S("Cocoa Beans"), {dye=1, craftitem=1, basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1}}, - {"orange", "dye_orange", S("Orange Dye"), {dye=1, craftitem=1, basecolor_orange=1, excolor_orange=1, unicolor_orange=1}}, - {"red", "dye_red", S("Rose Red"), {dye=1, craftitem=1, basecolor_red=1, excolor_red=1, unicolor_red=1}}, - {"magenta", "dye_magenta", S("Magenta Dye"), {dye=1, craftitem=1, basecolor_magenta=1, excolor_red_violet=1,unicolor_red_violet=1}}, - {"pink", "dye_pink", S("Pink Dye"), {dye=1, craftitem=1, basecolor_red=1, excolor_red=1, unicolor_light_red=1}}, +local dyes = { + {"white", S("White Dye"), {basecolor_white=1, excolor_white=1, unicolor_white=1}}, + {"grey", S("Light Grey Dye"), {basecolor_grey=1, excolor_grey=1, unicolor_grey=1}}, + {"dark_grey", S("Grey Dye"), {basecolor_grey=1, excolor_darkgrey=1, unicolor_darkgrey=1}}, + {"black", S("Black Dye"), {basecolor_black=1, excolor_black=1, unicolor_black=1}}, + {"violet", S("Purple Dye"), {basecolor_magenta=1, excolor_violet=1, unicolor_violet=1}}, + {"blue", S("Blue Dye"), {basecolor_blue=1, excolor_blue=1, unicolor_blue=1}}, + {"lightblue", S("Light Blue Dye"), {basecolor_blue=1, excolor_blue=1, unicolor_light_blue=1}}, + {"cyan", S("Cyan Dye"), {basecolor_cyan=1, excolor_cyan=1, unicolor_cyan=1}}, + {"dark_green", S("Green Dye"), {basecolor_green=1, excolor_green=1, unicolor_dark_green=1}}, + {"green", S("Lime Dye"), {basecolor_green=1, excolor_green=1, unicolor_green=1}}, + {"yellow", S("Yellow Dye"), {basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1}}, + {"brown", S("Brown Dye"), {basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1}}, + {"orange", S("Orange Dye"), {basecolor_orange=1, excolor_orange=1, unicolor_orange=1}}, + {"red", S("Red Dye"), {basecolor_red=1, excolor_red=1, unicolor_red=1}}, + {"magenta", S("Magenta Dye"), {basecolor_magenta=1, excolor_red_violet=1,unicolor_red_violet=1}}, + {"pink", S("Pink Dye"), {basecolor_red=1, excolor_red=1, unicolor_light_red=1}}, } -local mg_name = minetest.get_mapgen_setting("mg_name") +-- Other mods can use these for looping through available colors +mcl_dye.basecolors = {"white", "grey", "black", "magenta", "blue", "cyan", "green", "yellow", "orange", "red", "brown"} +mcl_dye.excolors = {"white", "grey", "darkgrey", "black", "violet", "blue", "cyan", "green", "yellow", "orange", "red", "red_violet"} -dyelocal.unicolor_to_dye_id = {} -for d=1, #dyelocal.dyes do - for k, _ in pairs(dyelocal.dyes[d][4]) do +local unicolor_to_dye_id = {} +for d = 1, #dyes do + for k, _ in pairs(dyes[d][3]) do if string.sub(k, 1, 9) == "unicolor_" then - dyelocal.unicolor_to_dye_id[k] = dyelocal.dyes[d][1] + unicolor_to_dye_id[k] = dyes[d][1] end end end --- Takes an unicolor group name (e.g. “unicolor_white”) and returns a corresponding dye name (if it exists), nil otherwise. -mcl_dye.unicolor_to_dye = function(unicolor_group) - local color = dyelocal.unicolor_to_dye_id[unicolor_group] +-- Takes an unicolor group name (e.g. “unicolor_white”) and returns a +-- corresponding dye name (if it exists), nil otherwise. +function mcl_dye.unicolor_to_dye(unicolor_group) + local color = unicolor_to_dye_id[unicolor_group] if color then return "mcl_dye:" .. color else @@ -103,30 +102,50 @@ mcl_dye.unicolor_to_dye = function(unicolor_group) end end --- Define items -for _, row in ipairs(dyelocal.dyes) do - local name = row[1] - -- White and brown dyes are defined explicitly below - if name ~= "white" and name ~= "brown" then - local img = row[2] - local description = row[3] - local groups = row[4] - local item_name = "mcl_dye:"..name - local item_image = img..".png" - minetest.register_craftitem(item_name, { - inventory_image = item_image, - description = description, - _doc_items_longdesc = S("This item is a dye which is used for dyeing and crafting."), - _doc_items_usagehelp = S("Rightclick on a sheep to dye its wool. Other things are dyed by crafting."), - groups = groups, - stack_max = 64, - }) - end +-- Define dye items. +-- +for _, row in pairs(dyes) do + local name, desc, grps = unpack(row) + minetest.register_craftitem("mcl_dye:" .. name, { + inventory_image = "mcl_dye_" .. name .. ".png", + description = desc, + _doc_items_longdesc = S("This item is a dye which is used for dyeing and crafting."), + _doc_items_usagehelp = S("Rightclick on a sheep to dye its wool. Other things are dyed by crafting."), + groups = table.update({craftitem = 1, dye = 1}, grps) + }) end --- Bone Meal +-- Bone meal code to be moved into its own mod. +-- +function mcl_dye.add_bone_meal_particle(pos, def) + if not def then + def = {} + end + minetest.add_particlespawner({ + amount = def.amount or 10, + time = def.time or 0.1, + minpos = def.minpos or vector.subtract(pos, 0.5), + maxpos = def.maxpos or vector.add(pos, 0.5), + minvel = def.minvel or vector.new(-0.01, 0.01, -0.01), + maxvel = def.maxvel or vector.new(0.01, 0.01, 0.01), + minacc = def.minacc or vector.new(0, 0, 0), + maxacc = def.maxacc or vector.new(0, 0, 0), + minexptime = def.minexptime or 1, + maxexptime = def.maxexptime or 4, + minsize = def.minsize or 0.7, + maxsize = def.maxsize or 2.4, + texture = "mcl_particles_bonemeal.png^[colorize:#00EE00:125", -- TODO: real MC color + glow = def.glow or 1, + }) +end -mcl_dye.apply_bone_meal = function(pointed_thing) +mcl_dye.bone_meal_callbacks = {} + +function mcl_dye.register_on_bone_meal_apply(func) + table.insert(mcl_dye.bone_meal_callbacks, func) +end + +local function apply_bone_meal(pointed_thing, user) -- Bone meal currently spawns all flowers found in the plains. local flowers_table_plains = { "mcl_flowers:dandelion", @@ -162,16 +181,29 @@ mcl_dye.apply_bone_meal = function(pointed_thing) local pos = pointed_thing.under local n = minetest.get_node(pos) if n.name == "" then return false end + + for _, func in pairs(mcl_dye.bone_meal_callbacks) do + if func(pointed_thing, user) then + return true + end + end + if minetest.get_item_group(n.name, "sapling") >= 1 then + mcl_dye.add_bone_meal_particle(pos) -- Saplings: 45% chance to advance growth stage - if math.random(1,100) <= 45 then - return mcl_core.grow_sapling(pos, n) + if math.random(1, 100) <= 45 then + if n.name == "mcl_cherry_blossom:cherrysapling" then + return mcl_cherry_blossom.generate_cherry_tree(pos) -- If cherry blossom sapling, run that callback instead. + else + return mcl_core.grow_sapling(pos, n) + end end elseif minetest.get_item_group(n.name, "mushroom") == 1 then + mcl_dye.add_bone_meal_particle(pos) -- Try to grow huge mushroom -- Must be on a dirt-type block - local below = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}) + local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z}) if below.name ~= "mcl_core:mycelium" and below.name ~= "mcl_core:dirt" and minetest.get_item_group(below.name, "grass_block") ~= 1 and below.name ~= "mcl_core:coarse_dirt" and below.name ~= "mcl_core:podzol" then return false end @@ -190,7 +222,7 @@ mcl_dye.apply_bone_meal = function(pointed_thing) return false end -- 40% chance - if math.random(1,100) <= 40 then + if math.random(1, 100) <= 40 then -- Check space requirements for i=1,3 do local cpos = vector.add(pos, {x=0, y=i, z=0}) @@ -216,64 +248,79 @@ mcl_dye.apply_bone_meal = function(pointed_thing) end return false -- Wheat, Potato, Carrot, Pumpkin Stem, Melon Stem: Advance by 2-5 stages - elseif string.find(n.name, "mcl_farming:wheat_") ~= nil then + elseif string.find(n.name, "mcl_farming:wheat_") then + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_wheat", pos, n, stages, true) - elseif string.find(n.name, "mcl_farming:potato_") ~= nil then + elseif string.find(n.name, "mcl_farming:potato_") then + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_potato", pos, n, stages, true) - elseif string.find(n.name, "mcl_farming:carrot_") ~= nil then + elseif string.find(n.name, "mcl_farming:carrot_") then + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_carrot", pos, n, stages, true) - elseif string.find(n.name, "mcl_farming:pumpkin_") ~= nil then + elseif string.find(n.name, "mcl_farming:pumpkin_") then + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_pumpkin_stem", pos, n, stages, true) - elseif string.find(n.name, "mcl_farming:melontige_") ~= nil then + elseif string.find(n.name, "mcl_farming:melontige_") then + mcl_dye.add_bone_meal_particle(pos) local stages = math.random(2, 5) return mcl_farming:grow_plant("plant_melon_stem", pos, n, stages, true) - - elseif string.find(n.name, "mcl_farming:beetroot_") ~= nil then + elseif string.find(n.name, "mcl_farming:beetroot_") then + mcl_dye.add_bone_meal_particle(pos) -- Beetroot: 75% chance to advance to next stage - if math.random(1,100) <= 75 then + if math.random(1, 100) <= 75 then return mcl_farming:grow_plant("plant_beetroot", pos, n, 1, true) end + elseif string.find(n.name, "mcl_farming:sweet_berry_bush_") then + mcl_dye.add_bone_meal_particle(pos) + if n.name == "mcl_farming:sweet_berry_bush_3" then + return minetest.add_item(vector.offset(pos,math.random()-0.5,math.random()-0.5,math.random()-0.5),"mcl_farming:sweet_berry") + else + return mcl_farming:grow_plant("plant_sweet_berry_bush", pos, n, 0, true) + end elseif n.name == "mcl_cocoas:cocoa_1" or n.name == "mcl_cocoas:cocoa_2" then + mcl_dye.add_bone_meal_particle(pos) -- Cocoa: Advance by 1 stage mcl_cocoas.grow(pos) return true elseif minetest.get_item_group(n.name, "grass_block") == 1 then -- Grass Block: Generate tall grass and random flowers all over the place - for i = -2, 2 do - for j = -2, 2 do - pos = pointed_thing.above - pos = {x=pos.x+i, y=pos.y, z=pos.z+j} - n = minetest.get_node(pos) - local n2 = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + for i = -7, 7 do + for j = -7, 7 do + for y = -1, 1 do + pos = vector.offset(pointed_thing.above, i, y, j) + n = minetest.get_node(pos) + local n2 = minetest.get_node(vector.offset(pos, 0, -1, 0)) - if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then - -- Randomly generate flowers, tall grass or nothing - if math.random(1,100) <= 90 then - -- 90% tall grass, 10% flower - if math.random(1,100) <= 90 then - local col = n2.param2 - minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col}) - else - local flowers_table - if mg_name == "v6" then - flowers_table = flowers_table_plains + if n.name ~= "" and n.name == "air" and (minetest.get_item_group(n2.name, "grass_block_no_snow") == 1) then + -- Randomly generate flowers, tall grass or nothing + if math.random(1, 100) <= 90 / ((math.abs(i) + math.abs(j)) / 2)then + -- 90% tall grass, 10% flower + mcl_dye.add_bone_meal_particle(pos, {amount = 4}) + if math.random(1,100) <= 90 then + local col = n2.param2 + minetest.add_node(pos, {name="mcl_flowers:tallgrass", param2=col}) else - local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome) - if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then - flowers_table = flowers_table_swampland - elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then - flowers_table = flowers_table_flower_forest - elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then + local flowers_table + if mg_name == "v6" then flowers_table = flowers_table_plains else - flowers_table = flowers_table_simple + local biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome) + if biome == "Swampland" or biome == "Swampland_shore" or biome == "Swampland_ocean" or biome == "Swampland_deep_ocean" or biome == "Swampland_underground" then + flowers_table = flowers_table_swampland + elseif biome == "FlowerForest" or biome == "FlowerForest_beach" or biome == "FlowerForest_ocean" or biome == "FlowerForest_deep_ocean" or biome == "FlowerForest_underground" then + flowers_table = flowers_table_flower_forest + elseif biome == "Plains" or biome == "Plains_beach" or biome == "Plains_ocean" or biome == "Plains_deep_ocean" or biome == "Plains_underground" or biome == "SunflowerPlains" or biome == "SunflowerPlains_ocean" or biome == "SunflowerPlains_deep_ocean" or biome == "SunflowerPlains_underground" then + flowers_table = flowers_table_plains + else + flowers_table = flowers_table_simple + end end + minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]}) end - minetest.add_node(pos, {name=flowers_table[math.random(1, #flowers_table)]}) end end end @@ -283,19 +330,24 @@ mcl_dye.apply_bone_meal = function(pointed_thing) -- Double flowers: Drop corresponding item elseif n.name == "mcl_flowers:rose_bush" or n.name == "mcl_flowers:rose_bush_top" then + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:rose_bush") return true elseif n.name == "mcl_flowers:peony" or n.name == "mcl_flowers:peony_top" then + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:peony") return true elseif n.name == "mcl_flowers:lilac" or n.name == "mcl_flowers:lilac_top" then + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:lilac") return true elseif n.name == "mcl_flowers:sunflower" or n.name == "mcl_flowers:sunflower_top" then + mcl_dye.add_bone_meal_particle(pos) minetest.add_item(pos, "mcl_flowers:sunflower") return true elseif n.name == "mcl_flowers:tallgrass" then + mcl_dye.add_bone_meal_particle(pos) -- Tall Grass: Grow into double tallgrass local toppos = { x=pos.x, y=pos.y+1, z=pos.z } local topnode = minetest.get_node(toppos) @@ -305,7 +357,18 @@ mcl_dye.apply_bone_meal = function(pointed_thing) return true end +--[[ + Here for when Bonemeal becomes an api, there's code if needed for handling applying to bamboo. + -- Handle applying bonemeal to bamboo. + elseif mcl_bamboo.is_bamboo(n.name) then + local success = mcl_bamboo.grow_bamboo(pos, true) + if success then + mcl_dye.add_bone_meal_particle(pos) + end + return success +--]] elseif n.name == "mcl_flowers:fern" then + mcl_dye.add_bone_meal_particle(pos) -- Fern: Grow into large fern local toppos = { x=pos.x, y=pos.y+1, z=pos.z } local topnode = minetest.get_node(toppos) @@ -319,15 +382,20 @@ mcl_dye.apply_bone_meal = function(pointed_thing) return false end -minetest.register_craftitem("mcl_dye:white", { - inventory_image = "mcl_dye_white.png", +mcl_dye.apply_bone_meal = apply_bone_meal + +-- Bone meal item registration. +-- +-- To be moved into its own mod. +-- +minetest.register_craftitem(":mcl_bone_meal:bone_meal", { + inventory_image = "mcl_bone_meal_bone_meal.png", description = S("Bone Meal"), _tt_help = S("Speeds up plant growth"), _doc_items_longdesc = S("Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants."), _doc_items_usagehelp = S("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."), stack_max = 64, - groups = dyelocal.dyes[1][4], - on_place = function(itemstack, user, pointed_thing) + on_place = function(itemstack, user, pointed_thing) -- 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 @@ -337,7 +405,7 @@ minetest.register_craftitem("mcl_dye:white", { end -- Use the bone meal on the ground - if(mcl_dye.apply_bone_meal(pointed_thing) and (not minetest.is_creative_enabled(user:get_player_name()))) then + if (apply_bone_meal(pointed_thing, user) and (not minetest.is_creative_enabled(user:get_player_name()))) then itemstack:take_item() end return itemstack @@ -350,63 +418,188 @@ minetest.register_craftitem("mcl_dye:white", { else pointed_thing = { above = pos, under = droppos } end - local success = mcl_dye.apply_bone_meal(pointed_thing) + local success = apply_bone_meal(pointed_thing, nil) if success then stack:take_item() end return stack end, + _dispense_into_walkable = true }) -minetest.register_craftitem("mcl_dye:brown", { - inventory_image = "mcl_dye_brown.png", - _tt_help = S("Grows at the side of jungle trees"), - _doc_items_longdesc = S("Cocoa beans are a brown dye and can be used to plant cocoas."), - _doc_items_usagehelp = S("Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa."), - description = S("Cocoa Beans"), - stack_max = 64, - groups = dyelocal.dyes[12][4], - on_place = function(itemstack, placer, pointed_thing) - return mcl_cocoas.place(itemstack, placer, pointed_thing, "mcl_cocoas:cocoa_1") - end, +minetest.register_craft({ + output = "mcl_bone_meal:bone_meal 3", + recipe = {{"mcl_mobitems:bone"}}, }) --- Dye mixing + +-- Dye creation recipes. +-- +minetest.register_craft({ + output = "mcl_dye:white", + recipe = {{"mcl_bone_meal:bone_meal"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:black", + recipe = {{"mcl_mobitems:ink_sac"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:yellow", + recipe = {{"mcl_flowers:dandelion"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:yellow 2", + recipe = {{"mcl_flowers:sunflower"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:blue", + recipe = {{"mcl_core:lapis"}}, +}) + +--[[ Uncomment when crafting blue dye back into lapis is removed. +minetest.register_craft({ + output = "mcl_dye:blue", + recipe = {{"mcl_flowers:cornflower"}}, +})]] + +minetest.register_craft({ + output = "mcl_dye:lightblue", + recipe = {{"mcl_flowers:blue_orchid"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:azure_bluet"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:oxeye_daisy"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:grey", + recipe = {{"mcl_flowers:tulip_white"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:magenta", + recipe = {{"mcl_flowers:allium"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:magenta 2", + recipe = {{"mcl_flowers:lilac"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:orange", + recipe = {{"mcl_flowers:tulip_orange"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:brown", + recipe = {{"mcl_cocoas:cocoa_beans"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:pink", + recipe = {{"mcl_flowers:tulip_pink"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:pink 2", + recipe = {{"mcl_flowers:peony"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_farming:beetroot_item"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_flowers:poppy"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red", + recipe = {{"mcl_flowers:tulip_red"}}, +}) + +minetest.register_craft({ + output = "mcl_dye:red 2", + recipe = {{"mcl_flowers:rose_bush"}}, +}) + +--[[Uncomment when crafting white dye back into bonemeal is removed +minetest.register_craft({ + output = "mcl_dye:white", + recipe = {{"mcl_flowers:lily_of_the_valley"}}, +})]] + +minetest.register_craft({ + type = "cooking", + output = "mcl_dye:dark_green", + recipe = "mcl_core:cactus", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_dye:green", + recipe = "group:sea_pickle", + cooktime = 10, +}) + +-- Dye mixing recipes. +-- minetest.register_craft({ type = "shapeless", output = "mcl_dye:dark_grey 2", recipe = {"mcl_dye:black", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:lightblue 2", recipe = {"mcl_dye:blue", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:grey 3", recipe = {"mcl_dye:black", "mcl_dye:white", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:grey 2", recipe = {"mcl_dye:dark_grey", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:green 2", recipe = {"mcl_dye:dark_green", "mcl_dye:white"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 4", recipe = {"mcl_dye:blue", "mcl_dye:white", "mcl_dye:red", "mcl_dye:red"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 3", recipe = {"mcl_dye:pink", "mcl_dye:red", "mcl_dye:blue"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:magenta 2", @@ -430,82 +623,34 @@ minetest.register_craft({ output = "mcl_dye:violet 2", recipe = {"mcl_dye:blue", "mcl_dye:red"}, }) + minetest.register_craft({ type = "shapeless", output = "mcl_dye:orange 2", recipe = {"mcl_dye:yellow", "mcl_dye:red"}, }) --- Dye creation +-- Legacy items grace conversion recipes. +-- +-- These allow for retrieval of precious items that were converted into +-- dye items after refactoring of the dyes. Should be removed again in +-- the near future. minetest.register_craft({ - output = "mcl_dye:yellow", - recipe = {{"mcl_flowers:dandelion"}}, -}) -minetest.register_craft({ - output = "mcl_dye:yellow 2", - recipe = {{"mcl_flowers:sunflower"}}, -}) -minetest.register_craft({ - output = "mcl_dye:lightblue", - recipe = {{"mcl_flowers:blue_orchid"}}, -}) -minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:azure_bluet"}}, -}) -minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:oxeye_daisy"}}, -}) -minetest.register_craft({ - output = "mcl_dye:grey", - recipe = {{"mcl_flowers:tulip_white"}}, -}) -minetest.register_craft({ - output = "mcl_dye:magenta", - recipe = {{"mcl_flowers:allium"}}, -}) -minetest.register_craft({ - output = "mcl_dye:magenta 2", - recipe = {{"mcl_flowers:lilac"}}, -}) -minetest.register_craft({ - output = "mcl_dye:orange", - recipe = {{"mcl_flowers:tulip_orange"}}, -}) -minetest.register_craft({ - output = "mcl_dye:pink", - recipe = {{"mcl_flowers:tulip_pink"}}, -}) -minetest.register_craft({ - output = "mcl_dye:pink 2", - recipe = {{"mcl_flowers:peony"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_farming:beetroot_item"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_flowers:poppy"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red", - recipe = {{"mcl_flowers:tulip_red"}}, -}) -minetest.register_craft({ - output = "mcl_dye:red 2", - recipe = {{"mcl_flowers:rose_bush"}}, -}) -minetest.register_craft({ - type = "cooking", - output = "mcl_dye:dark_green", - recipe = "mcl_core:cactus", - cooktime = 10, -}) -minetest.register_craft({ - output = "mcl_dye:white 3", - recipe = {{"mcl_mobitems:bone"}}, + output = "mcl_bone_meal:bone_meal", + recipe = {{"mcl_dye:white"}}, }) +minetest.register_craft({ + output = "mcl_mobitems:ink_sac", + recipe = {{"mcl_dye:black"}}, +}) +minetest.register_craft({ + output = "mcl_core:lapis", + recipe = {{"mcl_dye:blue"}}, +}) + +minetest.register_craft({ + output = "mcl_cocoas:cocoa_beans", + recipe = {{"mcl_dye:brown"}}, +}) diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr index 29cd4d20d..affe4cb8a 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.de.tr @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal=Knochenmehl +White Dye=Weißer Farbstoff Light Grey Dye=Hellgrauer Farbstoff Grey Dye=Grauer Farbstoff -Ink Sac=Tintenbeutel +Black Dye=Schwarzer Farbstoff Purple Dye=Violetter Farbstoff -Lapis Lazuli=Lapislazuli +Blue Dye=Blauer Farbstoff Light Blue Dye=Hellblauer Farbstoff Cyan Dye=Türkiser Farbstoff -Cactus Green=Kaktusgrün +Green Dye=Grüner Farbstoff Lime Dye=Lindgrüner Farbstoff -Dandelion Yellow=Löwenzahngelb -Cocoa Beans=Kakaobohnen +Yellow Dye=Gelber Farbstoff +Brown Dye=Brauner Farbstoff Orange Dye=Orange Farbstoff -Rose Red=Rosenrot +Red Dye=Roter Farbstoff Magenta Dye=Magenta Farbstoff Pink Dye=Rosa Farbstoff This item is a dye which is used for dyeing and crafting.=Dieser Gegenstand ist ein Farbstoff, der zum Einfärben und in der Herstellung benutzt werden kann. diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr index d20e8c96a..a829d5386 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.es.tr @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal=Harina de hueso +White Dye=Tinte blanca Light Grey Dye=Tinte gris claro Grey Dye=Tinte gris -Ink Sac=Saco de tinta +Black Dye=Tinte negro Purple Dye=Tinte púrpura -Lapis Lazuli=Lapislázuli +Blue Dye=Tinte azul Light Blue Dye=Tinte azul claro Cyan Dye=Tinte cian -Cactus Green=Tinte verde +Green Dye=Tinte verde Lime Dye=Tinte amarillo verdoso -Dandelion Yellow=Tinte amarillo -Cocoa Beans=Granos de cacao +Yellow Dye=Tinte amarillo +Brown Dye=Tinte marrón Orange Dye=Tinte naranja -Rose Red=Tinte rojo +Red Dye=Tinte rojo Magenta Dye=Tinte magenta Pink Dye=Tinte rosado This item is a dye which is used for dyeing and crafting.=Este artículo es un tinte que se utiliza para teñir y elaborar. diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr index 8d53cc73e..761511c5b 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.fr.tr @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal=Poudre d'Os +White Dye=Teinture Blanche Light Grey Dye=Teinture Gris Clair Grey Dye=Teinture Gris -Ink Sac=Poche d'Encre +Black Dye=Teinture Noire Purple Dye=Teinture Violette -Lapis Lazuli=Lapis Lazuli +Blue Dye=Teinture Bleu Light Blue Dye=Teinture Bleu Clair Cyan Dye=Teinture Cyan -Cactus Green=Cactus Vert +Green Dye=Teinture Verte Lime Dye=Teinture Vert Clair -Dandelion Yellow=Pissenlit Jaune -Cocoa Beans=Fèves de Cacao +Yellow Dye=Teinture Jaune +Brown Dye=Teinture Marron Orange Dye=Teinture Orange -Rose Red=Rose Rouge +Red Dye=Teinture Rouge Magenta Dye=Teinture Magenta Pink Dye=Teinture Rose This item is a dye which is used for dyeing and crafting.=Cet objet est un colorant utilisé pour la teinture et l'artisanat. diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr new file mode 100644 index 000000000..0d5d35da2 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.ja.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_dye +Bone Meal=骨粉 +Light Grey Dye=薄灰色の染料 +Grey Dye=灰色の染料 +Ink Sac=イカスミ +Purple Dye=紫色の染料 +Lapis Lazuli=ラピスラズリ +Light Blue Dye=空色の染料 +Cyan Dye=青緑色の染料 +Green Dye=緑色の染料 +Lime Dye=黄緑色の染料 +Yellow Dye=黄色の染料 +Cocoa Beans=カカオ豆 +Orange Dye=橙色の染料 +Red 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.=ヒツジを右クリックすると毛を染められます。それ以外のものはクラフトによって染めます。 +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.=ヒツジを右クリックすると毛が茶色に変わります。ジャングルの木の、幹の側面を右クリックすると、カカオの苗を植えることができます。 +Cocoa Beans=カカオ豆 +Grows at the side of jungle trees=ジャングルの木の側面に生育 +Speeds up plant growth=植物の生育を促進 diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr new file mode 100644 index 000000000..921983ec0 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pl.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_dye +White Dye=Biały farba +Light Grey Dye=Jasnoszara farba +Grey Dye=Szara farba +Black Dye=Czarny farba +Purple Dye=Fioletowa farba +Blue Dye=Niebieska farba +Light Blue Dye=Jasnoniebieska farba +Cyan Dye=Błękitna farba +Green Dye=Zielona farba +Lime Dye=Jasnozielona farba +Yellow Dye=Żółta farba +Brown Dye=Brązowy farba +Orange Dye=Pomarańczowa farba +Red Dye=Czerwona farba +Magenta Dye=Karmazynowa farba +Pink Dye=Różowa farba +This item is a dye which is used for dyeing and crafting.=Ten przedmiot to farba wykorzystywana to farbowania i wytwarzania. +Rightclick on a sheep to dye its wool. Other things are dyed by crafting.=Kliknij prawym na owcę aby zafarbować jej wełnę. Inne rzeczy mogą być zafarbowane przy wytwarzaniu. +Bone Meal=Mączka kostna +Bone meal is a white dye and also useful as a fertilizer to speed up the growth of many plants.=Mączka kostna to biała farba i przydatny nawóz, który przyspiesza rośnięcie wielu roślin. +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.=Kliknij prawym na owcę, aby wybielić jej wełnę. Kliknij prawym na roślinę aby przyspieszyć jej wzrost. Zważ, że nie na wszystkie rośliny to tak działa. Gdy klikniesz prawym na blok trawy, wysoka trawa wyrośnie wokół. +Cocoa beans are a brown dye and can be used to plant cocoas.=Ziarna kakaowe mogą być wykorzystane do sadzenia kakao. +Rightclick a sheep to turn its wool brown. Rightclick on the side of a jungle tree trunk (Jungle Wood) to plant a young cocoa.=Naciśnij prawym aby zafarbować wełnę owcy na brązowo. Naciśnij prawym na boku tropikalnego pnia (Tropikalne drewno) aby zasadzić młode kakao. +Cocoa Beans=Ziarna kakaowe +Grows at the side of jungle trees=Rośnie na boku tropikalnych drzew +Speeds up plant growth=Przyspiesza wzrost roślin diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr new file mode 100644 index 000000000..2b6aef9f0 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.pt_BR.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_dye +Bone Meal=Farinha de Osso +Light Grey Dye=Tintura Cinza Claro +Grey Dye=Tintura Cinza +Ink Sac=Saco de Tinta +Purple Dye=Tintura Roxa +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 +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. +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. +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. +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 +Speeds up plant growth=Acelera o crescimento de plantas diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr index e70388115..fc45a4bb4 100644 --- a/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.ru.tr @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal=Костная мука +White Dye=Белый краситель Light Grey Dye=Светло-серый краситель Grey Dye=Серый краситель -Ink Sac=Чернильный мешок +Black Dye=Чёрный краситель Purple Dye=Пурпурный краситель -Lapis Lazuli=Ляпис-лазурь +Blue Dye=голубой краситель Light Blue Dye=Светло-голубой краситель Cyan Dye=Голубой краситель -Cactus Green=Зелень кактуса +Green Dye=Зеленый краситель Lime Dye=Зелёный лаймовый краситель -Dandelion Yellow=Одуванчиковый жёлтый краситель -Cocoa Beans=Какао-бобы +Yellow Dye=Желтый краситель +Brown Dye=Коричневый краситель Orange Dye=Оранжевый краситель -Rose Red=Экстракт красной розы +Red Dye=Красный краситель Magenta Dye=Фиолетовый краситель Pink Dye=Розовый краситель This item is a dye which is used for dyeing and crafting.=Это краситель, которые используется, чтобы окрашивать и крафтить. diff --git a/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr new file mode 100644 index 000000000..86dc708e2 --- /dev/null +++ b/mods/ITEMS/mcl_dye/locale/mcl_dye.zh_TW.tr @@ -0,0 +1,25 @@ +# textdomain: mcl_dye +White Dye=白色染料 +Light Grey Dye=淺灰色染料 +Grey Dye=灰色染料 +Black Dye=黑色染料 +Purple Dye=紫色染料 +Blue Dye=藍色染料 +Light Blue Dye=淺藍色染料 +Cyan Dye=青色染料 +Green Dye=绿色染料 +Lime Dye=淺綠色染料 +Yellow Dye=黄色染料 +Brown Dye=棕色染料 +Orange Dye=橙色染料 +Red 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.=右鍵單擊綿羊以染它的毛。其他東西是通過合成染色的。 +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.=右鍵點擊一隻羊,使其羊毛變成褐色。右鍵點擊叢林木的一側,可以種植一個可可。 +Grows at the side of jungle trees=在叢林木側生長 +Speeds up plant growth=加速植物生長 diff --git a/mods/ITEMS/mcl_dye/locale/template.txt b/mods/ITEMS/mcl_dye/locale/template.txt index 94e250f06..84bac96af 100644 --- a/mods/ITEMS/mcl_dye/locale/template.txt +++ b/mods/ITEMS/mcl_dye/locale/template.txt @@ -1,18 +1,18 @@ # textdomain: mcl_dye -Bone Meal= +White Dye= Light Grey Dye= Grey Dye= -Ink Sac= +Black Dye= Purple Dye= -Lapis Lazuli= +Blue Dye= Light Blue Dye= Cyan Dye= -Cactus Green= +Green Dye= Lime Dye= -Dandelion Yellow= -Cocoa Beans= +Yellow Dye= +Brown Dye= Orange Dye= -Rose Red= +Red Dye= Magenta Dye= Pink Dye= This item is a dye which is used for dyeing and crafting.= diff --git a/mods/ITEMS/mcl_dye/mod.conf b/mods/ITEMS/mcl_dye/mod.conf index 356b16434..fe93278fc 100644 --- a/mods/ITEMS/mcl_dye/mod.conf +++ b/mods/ITEMS/mcl_dye/mod.conf @@ -1 +1,2 @@ name = mcl_dye +depends = mcl_core, mcl_flowers, mcl_mobitems, mcl_cocoas diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png b/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png deleted file mode 100644 index 95a8df4ad..000000000 Binary files a/mods/ITEMS/mcl_dye/textures/mcl_dye_black.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 75969f516..f137b4230 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_enchanting") +local S = minetest.get_translator(minetest.get_current_modname()) -- Taken from https://minecraft.gamepedia.com/Enchanting @@ -10,25 +10,6 @@ local function increase_damage(damage_group, factor) end end --- requires engine change ---[[mcl_enchanting.enchantments.aqua_affinity = { - name = S("Aqua Affinity"), - max_level = 1, - primary = {armor_head = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {}, - weight = 2, - description = S("Increases underwater mining speed."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{1, 41}}, - inv_combat_tab = true, - inv_tool_tab = false, -}]]-- - -- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented mcl_enchanting.enchantments.bane_of_arthropods = { name = S("Bane of Arthropods"), @@ -48,25 +29,6 @@ mcl_enchanting.enchantments.bane_of_arthropods = { inv_tool_tab = false, } --- implemented in mcl_armor -mcl_enchanting.enchantments.blast_protection = { - name = S("Blast Protection"), - max_level = 4, - primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {fire_protection = true, protection = true, projectile_protection = true}, - weight = 2, - description = S("Reduces explosion damage and knockback."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - -- requires missing MineClone2 feature --[[mcl_enchanting.enchantments.channeling = { name = S("Channeling"), @@ -86,25 +48,6 @@ mcl_enchanting.enchantments.blast_protection = { inv_tool_tab = false, }]]-- --- implemented in mcl_armor -mcl_enchanting.enchantments.curse_of_binding = { - name = S("Curse of Binding"), - max_level = 1, - primary = {}, - secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, - disallow = {}, - incompatible = {}, - weight = 1, - description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."), - curse = true, - on_enchant = function() end, - requires_tool = false, - treasure = true, - power_range_table = {{25, 50}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - -- implemented in mcl_death_drop mcl_enchanting.enchantments.curse_of_vanishing = { name = S("Curse of Vanishing"), @@ -124,8 +67,8 @@ mcl_enchanting.enchantments.curse_of_vanishing = { inv_tool_tab = true, } --- unimplemented ---[[mcl_enchanting.enchantments.depth_strider = { +-- implemented in mcl_playerplus +mcl_enchanting.enchantments.depth_strider = { name = S("Depth Strider"), max_level = 3, primary = {}, @@ -141,7 +84,7 @@ mcl_enchanting.enchantments.curse_of_vanishing = { power_range_table = {{10, 25}, {20, 35}, {30, 45}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- implemented via on_enchant mcl_enchanting.enchantments.efficiency = { @@ -154,16 +97,9 @@ mcl_enchanting.enchantments.efficiency = { weight = 10, description = S("Increases mining speed."), curse = false, - on_enchant = function(itemstack, level) - local tool_capabilities = itemstack:get_tool_capabilities() - local groupcaps = {} - for group, capability in pairs(tool_capabilities.groupcaps) do - local groupname = group .. "_efficiency_" .. level - capability.times = mcl_autogroup.digtimes[groupname] - groupcaps[groupname] = capability - end - tool_capabilities.groupcaps = groupcaps - itemstack:get_meta():set_tool_capabilities(tool_capabilities) + on_enchant = function() + -- Updating digging speed is handled by update_groupcaps which + -- is called from load_enchantments. end, requires_tool = false, treasure = false, @@ -172,24 +108,6 @@ mcl_enchanting.enchantments.efficiency = { inv_tool_tab = true, } --- implemented in mcl_armor -mcl_enchanting.enchantments.feather_falling = { - name = S("Feather Falling"), - max_level = 4, - primary = {armor_feet = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {}, - weight = 5, - description = S("Reduces fall damage."),curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - -- implemented in mcl_mobs and via register_on_punchplayer callback mcl_enchanting.enchantments.fire_aspect = { name = S("Fire Aspect"), @@ -215,31 +133,12 @@ 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 - 1, 1, hitter:get_player_name()) + mcl_burning.set_on_fire(player, fire_aspect_level * 4) end end end end) --- implemented in mcl_armor -mcl_enchanting.enchantments.fire_protection = { - name = S("Fire Protection"), - max_level = 4, - primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {blast_protection = true, protection = true, projectile_protection = true}, - weight = 5, - description = S("Reduces fire damage."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{10, 18}, {18, 26}, {26, 34}, {34, 42}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - mcl_enchanting.enchantments.flame = { name = S("Flame"), max_level = 1, @@ -481,8 +380,52 @@ mcl_enchanting.enchantments.mending = { inv_tool_tab = true, } --- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.multishot = { +mcl_experience.register_on_add_xp(function(player, xp) + local inv = player:get_inventory() + + local candidates = { + {list = "main", index = player:get_wield_index()}, + {list = "armor", index = 2}, + {list = "armor", index = 3}, + {list = "armor", index = 4}, + {list = "armor", index = 5}, + {list = "offhand", index = 1}, + } + + local final_candidates = {} + for _, can in ipairs(candidates) do + local stack = inv:get_stack(can.list, can.index) + local wear = stack:get_wear() + if mcl_enchanting.has_enchantment(stack, "mending") and wear > 0 then + can.stack = stack + can.wear = wear + table.insert(final_candidates, can) + end + end + + if #final_candidates > 0 then + local can = final_candidates[math.random(#final_candidates)] + local stack, list, index, wear = can.stack, can.list, can.index, can.wear + local uses = mcl_util.calculate_durability(stack) + local multiplier = 2 * 65535 / uses + local repair = xp * multiplier + local new_wear = wear - repair + + if new_wear < 0 then + xp = math.floor(-new_wear / multiplier + 0.5) + new_wear = 0 + else + xp = 0 + end + + stack:set_wear(math.floor(new_wear)) + inv:set_stack(list, index, stack) + end + + return xp +end, 0) + +mcl_enchanting.enchantments.multishot = { name = S("Multishot"), max_level = 1, primary = {crossbow = true}, @@ -498,10 +441,10 @@ mcl_enchanting.enchantments.mending = { power_range_table = {{20, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.piercing = { +mcl_enchanting.enchantments.piercing = { name = S("Piercing"), max_level = 4, primary = {crossbow = true}, @@ -517,7 +460,7 @@ mcl_enchanting.enchantments.mending = { power_range_table = {{1, 50}, {11, 50}, {21, 50}, {31, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- implemented in mcl_bows mcl_enchanting.enchantments.power = { @@ -538,44 +481,6 @@ mcl_enchanting.enchantments.power = { inv_tool_tab = false, } --- implemented in mcl_armor -mcl_enchanting.enchantments.projectile_protection = { - name = S("Projectile Protection"), - max_level = 4, - primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {blast_protection = true, fire_protection = true, protection = true}, - weight = 5, - description = S("Reduces projectile damage."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - --- implemented in mcl_armor -mcl_enchanting.enchantments.protection = { - name = S("Protection"), - max_level = 4, - primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true}, - weight = 10, - description = S("Reduces most types of damage by 4% for each level."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - -- implemented via minetest.calculate_knockback (together with the Knockback enchantment) and mcl_bows mcl_enchanting.enchantments.punch = { name = S("Punch"), @@ -596,7 +501,7 @@ mcl_enchanting.enchantments.punch = { } -- requires missing MineClone2 feature ---[[mcl_enchanting.enchantments.quick_charge = { +mcl_enchanting.enchantments.quick_charge = { name = S("Quick Charge"), max_level = 3, primary = {crossbow = true}, @@ -612,7 +517,7 @@ mcl_enchanting.enchantments.punch = { power_range_table = {{12, 50}, {32, 50}, {52, 50}}, inv_combat_tab = true, inv_tool_tab = false, -}]]-- +} -- unimplemented --[[mcl_enchanting.enchantments.respiration = { @@ -747,25 +652,6 @@ mcl_enchanting.enchantments.soul_speed = { inv_tool_tab = false, }]]-- --- implemented in mcl_armor -mcl_enchanting.enchantments.thorns = { - name = S("Thorns"), - max_level = 3, - primary = {armor_head = true}, - secondary = {armor_torso = true, armor_legs = true, armor_feet = true}, - disallow = {non_combat_armor = true}, - incompatible = {}, - weight = 1, - description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{10, 61}, {30, 71}, {50, 81}}, - inv_combat_tab = true, - inv_tool_tab = false, -} - -- for tools & weapons implemented via on_enchant; for bows implemented in mcl_bows; for armor implemented in mcl_armor and mcl_tt; for fishing rods implemented in mcl_fishing mcl_enchanting.enchantments.unbreaking = { name = S("Unbreaking"), @@ -778,12 +664,17 @@ mcl_enchanting.enchantments.unbreaking = { description = S("Increases item durability."), curse = false, on_enchant = function(itemstack, level) - local tool_capabilities = itemstack:get_tool_capabilities() - for group, capability in pairs(tool_capabilities.groupcaps) do - capability.uses = capability.uses * (1 + level) + local name = itemstack:get_name() + if not minetest.registered_tools[name].tool_capabilities then + return end + + local tool_capabilities = itemstack:get_tool_capabilities() tool_capabilities.punch_attack_uses = tool_capabilities.punch_attack_uses * (1 + level) itemstack:get_meta():set_tool_capabilities(tool_capabilities) + + -- Updating digging durability is handled by update_groupcaps + -- which is called from load_enchantments. end, requires_tool = true, treasure = false, diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index 5bb5884ce..fa6dea353 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_enchanting") +local S = minetest.get_translator(minetest.get_current_modname()) local F = minetest.formspec_escape function mcl_enchanting.is_book(itemname) @@ -6,26 +6,44 @@ function mcl_enchanting.is_book(itemname) end function mcl_enchanting.get_enchantments(itemstack) + if not itemstack then + return {} + end return minetest.deserialize(itemstack:get_meta():get_string("mcl_enchanting:enchantments")) or {} end -function mcl_enchanting.set_enchantments(itemstack, enchantments) - itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) +function mcl_enchanting.unload_enchantments(itemstack) local itemdef = itemstack:get_definition() + local meta = itemstack:get_meta() + if itemdef.tool_capabilities then + meta:set_tool_capabilities(nil) + meta:set_string("groupcaps_hash", "") + end + if meta:get_string("name") == "" then + meta:set_string("description", "") + meta:set_string("groupcaps_hash", "") + end +end + +function mcl_enchanting.load_enchantments(itemstack, enchantments) if not mcl_enchanting.is_book(itemstack:get_name()) then - if itemdef.tool_capabilities then - itemstack:get_meta():set_tool_capabilities(itemdef.tool_capabilities) - end - for enchantment, level in pairs(enchantments) do + mcl_enchanting.unload_enchantments(itemstack) + for enchantment, level in pairs(enchantments or mcl_enchanting.get_enchantments(itemstack)) do local enchantment_def = mcl_enchanting.enchantments[enchantment] if enchantment_def.on_enchant then enchantment_def.on_enchant(itemstack, level) end end + mcl_enchanting.update_groupcaps(itemstack) end tt.reload_itemstack_description(itemstack) end +function mcl_enchanting.set_enchantments(itemstack, enchantments) + itemstack:get_meta():set_string("mcl_enchanting:enchantments", minetest.serialize(enchantments)) + mcl_enchanting.load_enchantments(itemstack) +end + function mcl_enchanting.get_enchantment(itemstack, enchantment) return mcl_enchanting.get_enchantments(itemstack)[enchantment] or 0 end @@ -40,7 +58,7 @@ function mcl_enchanting.get_enchantment_description(enchantment, level) end function mcl_enchanting.get_colorized_enchantment_description(enchantment, level) - return minetest.colorize(mcl_enchanting.enchantments[enchantment].curse and "#FC5454" or "#A8A8A8", 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) @@ -56,8 +74,12 @@ function mcl_enchanting.is_enchanted(itemname) return minetest.get_item_group(itemname, "enchanted") > 0 end +function mcl_enchanting.not_enchantable_on_enchanting_table(itemname) + return mcl_enchanting.get_enchantability(itemname) == -1 +end + function mcl_enchanting.is_enchantable(itemname) - return mcl_enchanting.get_enchantability(itemname) > 0 + return mcl_enchanting.get_enchantability(itemname) > 0 or mcl_enchanting.not_enchantable_on_enchanting_table(itemname) end function mcl_enchanting.can_enchant_freshly(itemname) @@ -107,7 +129,7 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) if itemname == "" then return false, "item missing" end - local supported, primary = mcl_enchanting.item_supports_enchantment(itemstack:get_name(), enchantment) + local supported, primary = mcl_enchanting.item_supports_enchantment(itemname, enchantment) if not supported then return false, "item not supported" end @@ -116,7 +138,7 @@ function mcl_enchanting.can_enchant(itemstack, enchantment, level) end if level > enchantment_def.max_level then return false, "level too high", enchantment_def.max_level - elseif level < 1 then + elseif level < 1 then return false, "level too small", 1 end local item_enchantments = mcl_enchanting.get_enchantments(itemstack) @@ -147,7 +169,7 @@ 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 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) @@ -207,6 +229,38 @@ function mcl_enchanting.enchantments_snippet(_, _, itemstack) end end +-- Returns the after_use callback function to use when registering an enchanted +-- item. The after_use callback is used to update the tool_capabilities of +-- efficiency enchanted tools with outdated digging times. +-- +-- It does this by calling apply_efficiency to reapply the efficiency +-- enchantment. That function is written to use hash values to only update the +-- tool if neccessary. +-- +-- This is neccessary for digging times of tools to be in sync when MineClone2 +-- or mods add new hardness values. +local function get_after_use_callback(itemdef) + if itemdef.after_use then + -- If the tool already has an after_use, make sure to call that + -- one too. + return function(itemstack, user, node, digparams) + itemdef.after_use(itemstack, user, node, digparams) + mcl_enchanting.update_groupcaps(itemstack) + end + end + + -- If the tool does not have after_use, add wear to the tool as if no + -- after_use was registered. + return function(itemstack, user, node, digparams) + if not minetest.is_creative_enabled(user:get_player_name()) then + itemstack:add_wear(digparams.wear) + end + + --local enchantments = mcl_enchanting.get_enchantments(itemstack) + mcl_enchanting.update_groupcaps(itemstack) + end +end + function mcl_enchanting.initialize() local register_tool_list = {} local register_item_list = {} @@ -222,8 +276,15 @@ function mcl_enchanting.initialize() new_def.groups.not_in_creative_inventory = 1 new_def.groups.not_in_craft_guide = 1 new_def.groups.enchanted = 1 - new_def.texture = itemdef.texture or itemname:gsub("%:", "_") + + if new_def._mcl_armor_texture then + if type(new_def._mcl_armor_texture) == "string" then + new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay + end + end + new_def._mcl_enchanting_enchanted_tool = new_name + new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list if itemdef.type == "tool" then register_list = register_tool_list @@ -239,106 +300,125 @@ function mcl_enchanting.initialize() end end -function mcl_enchanting.get_possible_enchantments(itemstack, enchantment_level, treasure) - local possible_enchantments, weights, accum_weight = {}, {}, 0 - for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do - local supported, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) - if primary or treasure then - table.insert(possible_enchantments, enchantment) - accum_weight = accum_weight + enchantment_def.weight - weights[enchantment] = accum_weight - end +function mcl_enchanting.random(pr, ...) + local r = pr and pr:next(...) or math.random(...) + + if pr and not ({...})[1] then + r = r / 32767 end - return possible_enchantments, weights, accum_weight + + return r end -function mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) +function mcl_enchanting.get_random_enchantment(itemstack, treasure, weighted, exclude, pr) + local possible = {} + + for enchantment, enchantment_def in pairs(mcl_enchanting.enchantments) do + local can_enchant, _, _, primary = mcl_enchanting.can_enchant(itemstack, enchantment, 1) + + if can_enchant and (primary or treasure) and (not exclude or table.indexof(exclude, enchantment) == -1) then + local weight = weighted and enchantment_def.weight or 1 + + for i = 1, weight do + table.insert(possible, enchantment) + end + end + end + + 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) local itemname = itemstack:get_name() - if not mcl_enchanting.can_enchant_freshly(itemname) and not ignore_already_enchanted 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 + math.random(0, math.floor(enchantability / 4)) + math.random(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 * (math.random() + math.random() - 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 = {} local description + enchantment_level = enchantment_level * 2 + repeat enchantment_level = math.floor(enchantment_level / 2) + if enchantment_level == 0 then break end - local possible, weights, accum_weight = mcl_enchanting.get_possible_enchantments(itemstack, enchantment_level, treasure) - local selected_enchantment, enchantment_power - if #possible > 0 then - local r = math.random(accum_weight) - for _, enchantment in ipairs(possible) do - if weights[enchantment] >= r then - selected_enchantment = enchantment - break - end - end - local enchantment_def = mcl_enchanting.enchantments[selected_enchantment] - local power_range_table = enchantment_def.power_range_table - for i = enchantment_def.max_level, 1, -1 do - local power_range = power_range_table[i] - if enchantment_level >= power_range[1] and enchantment_level <= power_range[2] then - enchantment_power = i - break - end - end - if not description then - if not enchantment_power then - return - end - description = mcl_enchanting.get_enchantment_description(selected_enchantment, enchantment_power) - end - if enchantment_power then - enchantments[selected_enchantment] = enchantment_power - mcl_enchanting.enchant(itemstack, selected_enchantment, enchantment_power) - end - else + + local selected_enchantment = mcl_enchanting.get_random_enchantment(itemstack, treasure, true, nil, pr) + + if not selected_enchantment then break end - until not no_reduced_bonus_chance and math.random() >= (enchantment_level + 1) / 50 + + local enchantment_def = mcl_enchanting.enchantments[selected_enchantment] + local power_range_table = enchantment_def.power_range_table + + local enchantment_power + + for i = enchantment_def.max_level, 1, -1 do + local power_range = power_range_table[i] + if enchantment_level >= power_range[1] and enchantment_level <= power_range[2] then + enchantment_power = i + break + end + end + + if not description then + if not enchantment_power then + return + end + + description = mcl_enchanting.get_enchantment_description(selected_enchantment, enchantment_power) + end + + if enchantment_power then + 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 end -function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) +function mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted, pr) local enchantments + repeat - enchantments = mcl_enchanting.generate_random_enchantments(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted) + 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) +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) - mcl_enchanting.set_enchantments(itemstack, mcl_enchanting.generate_random_enchantments_reliable(itemstack, enchantment_level, treasure, no_reduced_bonus_chance, ignore_already_enchanted)) + mcl_enchanting.set_enchantments(itemstack, enchantments) + return itemstack end -function mcl_enchanting.get_randomly_enchanted_book(enchantment_level, treasure, no_reduced_bonus_chance) - return mcl_enchanting.enchant_randomly(ItemStack("mcl_books:book"), enchantment_level, treasure, no_reduced_bonus_chance, true) -end +function mcl_enchanting.enchant_uniform_randomly(stack, exclude, pr) + local enchantment = mcl_enchanting.get_random_enchantment(stack, true, false, exclude, pr) -function mcl_enchanting.get_uniform_randomly_enchanted_book(except) - except = except or except - local stack = ItemStack("mcl_enchanting:book_enchanted") - local list = {} - for enchantment in pairs(mcl_enchanting.enchantments) do - if table.indexof(except, enchantment) == -1 then - table.insert(list, enchantment) - end + if enchantment then + mcl_enchanting.enchant(stack, enchantment, mcl_enchanting.random(pr, 1, mcl_enchanting.enchantments[enchantment].max_level)) end - local index = math.random(#list) - local enchantment = list[index] - local enchantment_def = mcl_enchanting.enchantments[enchantment] - local level = math.random(enchantment_def.max_level) - mcl_enchanting.enchant(stack, enchantment, level) + return stack end @@ -377,10 +457,10 @@ function mcl_enchanting.generate_random_table_slots(itemstack, num_bookshelves) end function mcl_enchanting.get_table_slots(player, itemstack, num_bookshelves) - if not mcl_enchanting.can_enchant_freshly(itemstack:get_name()) then + 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} end - local itemname = itemstack:get_name() local meta = player:get_meta() local player_slots = minetest.deserialize(meta:get_string("mcl_enchanting:slots")) or {} local player_bookshelves_slots = player_slots[num_bookshelves] or {} @@ -434,20 +514,20 @@ function mcl_enchanting.show_enchanting_formspec(player) .. "real_coordinates[true]" .. "image[3.15,0.6;7.6,4.1;mcl_enchanting_button_background.png]" local itemstack = inv:get_stack("enchanting_item", 1) - local player_levels = mcl_experience.get_player_xp_level(player) + local player_levels = mcl_experience.get_level(player) local y = 0.65 local any_enchantment = false 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_dye:blue", 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") .. F(slot.description) .. " " .. 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 "") + .. (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 .. ";]" .. (slot and "image[0,0;1.3,1.3;mcl_enchanting_number_" .. i .. ending .. ".png]" or "") @@ -475,7 +555,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_dye:blue", count = button_pressed}) + local cost = ItemStack({name = "mcl_core:lapis", count = button_pressed}) if not inv:contains_item("enchanting_lapis", cost) then return end @@ -484,11 +564,11 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) if not slot then return end - local player_level = mcl_experience.get_player_xp_level(player) + local player_level = mcl_experience.get_level(player) if player_level < slot.level_requirement then return end - mcl_experience.set_player_xp_level(player, player_level - button_pressed) + mcl_experience.set_level(player, player_level - button_pressed) inv:remove_item("enchanting_lapis", cost) mcl_enchanting.set_enchanted_itemstring(itemstack) mcl_enchanting.set_enchantments(itemstack, slot.enchantments) @@ -496,6 +576,7 @@ function mcl_enchanting.handle_formspec_fields(player, formname, fields) 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") end end @@ -527,8 +608,13 @@ function mcl_enchanting.allow_inventory_action(player, action, inventory, invent if action == "move" then local listname = inventory_info.to_list local stack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index) - if stack:get_name() == "mcl_dye:blue" and listname ~= "enchanting_item" then - return math.min(inventory:get_stack("enchanting_lapis", 1):get_free_space(), stack:get_count()) + if stack:get_name() == "mcl_core:lapis" and listname ~= "enchanting_item" then + local count = stack:get_count() + local old_stack = inventory:get_stack("enchanting_lapis", 1) + if old_stack:get_name() ~= "" then + count = math.min(count, old_stack:get_free_space()) + end + return count elseif inventory:get_stack("enchanting_item", 1):get_count() == 0 and listname ~= "enchanting_lapis" then return 1 else @@ -545,7 +631,7 @@ function mcl_enchanting.on_inventory_action(player, action, inventory, inventory if action == "move" and inventory_info.to_list == "enchanting" then local stack = inventory:get_stack("enchanting", 1) local result_list - if stack:get_name() == "mcl_dye:blue" then + if stack:get_name() == "mcl_core:lapis" then result_list = "enchanting_lapis" stack:add_item(inventory:get_stack("enchanting_lapis", 1)) else diff --git a/mods/ITEMS/mcl_enchanting/groupcaps.lua b/mods/ITEMS/mcl_enchanting/groupcaps.lua new file mode 100644 index 000000000..2a8372772 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/groupcaps.lua @@ -0,0 +1,72 @@ +local groupcaps_cache = {} + +-- Compute a hash value. +function compute_hash(value) + return string.sub(minetest.sha1(minetest.serialize(value)), 1, 8) +end + +-- Get the groupcaps and hash for an enchanted tool. If this function is called +-- repeatedly with the same values it will return data from a cache. +-- +-- Parameters: +-- toolname - Name of the tool +-- level - The efficiency level of the tool +-- +-- Returns a table with the following two fields: +-- values - The groupcaps table +-- hash - The hash of the groupcaps table +local function get_efficiency_groupcaps(toolname, level) + local toolcache = groupcaps_cache[toolname] + local level = level + + if not toolcache then + toolcache = {} + groupcaps_cache[toolname] = toolcache + end + + local levelcache = toolcache[level] + if not levelcache then + levelcache = {} + levelcache.values = mcl_autogroup.get_groupcaps(toolname, level) + levelcache.hash = compute_hash(levelcache.values) + toolcache[level] = levelcache + end + + return levelcache +end + +-- Update groupcaps of an enchanted tool. This function will be called +-- repeatedly to make sure the digging times stored in groupcaps stays in sync +-- when the digging times of nodes can change. +-- +-- To make it more efficient it will first check a hash value to determine if +-- the tool needs to be updated. +function mcl_enchanting.update_groupcaps(itemstack) + local name = itemstack:get_name() + if not minetest.registered_tools[name] or not minetest.registered_tools[name].tool_capabilities then + return + end + + local efficiency = mcl_enchanting.get_enchantment(itemstack, "efficiency") + local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") + if unbreaking == 0 and efficiency == 0 then + return + end + + local groupcaps = get_efficiency_groupcaps(name, efficiency) + local hash = itemstack:get_meta():get_string("groupcaps_hash") + + if not hash or hash ~= groupcaps.hash then + local tool_capabilities = itemstack:get_tool_capabilities() + tool_capabilities.groupcaps = table.copy(groupcaps.values) + + -- Increase the number of uses depending on the unbreaking level + -- of the tool. + for group, capability in pairs(tool_capabilities.groupcaps) do + capability.uses = capability.uses * (1 + unbreaking) + end + + itemstack:get_meta():set_tool_capabilities(tool_capabilities) + itemstack:get_meta():set_string("groupcaps_hash", groupcaps.hash) + end +end diff --git a/mods/ITEMS/mcl_enchanting/init.lua b/mods/ITEMS/mcl_enchanting/init.lua index ab3dddbd3..9f9fbd271 100644 --- a/mods/ITEMS/mcl_enchanting/init.lua +++ b/mods/ITEMS/mcl_enchanting/init.lua @@ -1,5 +1,9 @@ -local modpath = minetest.get_modpath("mcl_enchanting") -local S = minetest.get_translator("mcl_enchanting") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + +local math = math +local vector = vector mcl_enchanting = { book_offset = vector.new(0, 0.75, 0), @@ -59,6 +63,7 @@ mcl_enchanting = { } dofile(modpath .. "/engine.lua") +dofile(modpath .. "/groupcaps.lua") dofile(modpath .. "/enchantments.lua") minetest.register_chatcommand("enchant", { @@ -121,7 +126,7 @@ minetest.register_chatcommand("forceenchant", { return false, S("Player '@1' cannot be found.", target_name) end local itemstack = target:get_wielded_item() - local can_enchant, errorstring, extra_info = mcl_enchanting.can_enchant(itemstack, enchantment, level) + local _, errorstring = mcl_enchanting.can_enchant(itemstack, enchantment, level) if errorstring == "enchantment invalid" then return false, S("There is no such enchantment '@1'.", enchantment) elseif errorstring == "item missing" then @@ -147,7 +152,7 @@ minetest.register_craftitem("mcl_enchanting:book_enchanted", { minetest.register_alias("mcl_books:book_enchanted", "mcl_enchanting:book_enchanted") -local spawn_book_entity = function(pos, respawn) +local function spawn_book_entity(pos, respawn) if respawn then -- Check if we already have a book local objs = minetest.get_objects_inside_radius(pos, 1) @@ -178,7 +183,7 @@ minetest.register_entity("mcl_enchanting:book", { collisionbox = {0, 0, 0}, pointable = false, physical = false, - textures = {"mcl_enchanting_book_entity.png"}, + textures = {"mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png", "mcl_enchanting_book_entity.png"}, static_save = false, }, _player_near = false, @@ -191,7 +196,7 @@ minetest.register_entity("mcl_enchanting:book", { local old_player_near = self._player_near local player_near = false local player - for _, obj in ipairs(minetest.get_objects_inside_radius(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset), 2.5)) do + for _, obj in pairs(minetest.get_objects_inside_radius(vector.subtract(self.object:get_pos(), mcl_enchanting.book_offset), 2.5)) do if obj:is_player() then player_near = true player = obj @@ -231,6 +236,7 @@ minetest.register_node("mcl_enchanting:table", { _doc_items_hidden = false, drawtype = "nodebox", tiles = {"mcl_enchanting_table_top.png", "mcl_enchanting_table_bottom.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png", "mcl_enchanting_table_side.png"}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, node_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 0.25, 0.5}, @@ -240,9 +246,9 @@ minetest.register_node("mcl_enchanting:table", { on_rotate = rotate, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) local player_meta = clicker:get_meta() - local table_meta = minetest.get_meta(pos) - local num_bookshelves = table_meta:get_int("mcl_enchanting:num_bookshelves") - local table_name = table_meta:get_string("name") + --local table_meta = minetest.get_meta(pos) + --local num_bookshelves = table_meta:get_int("mcl_enchanting:num_bookshelves") + local table_name = minetest.get_meta(pos):get_string("name") if table_name == "" then table_name = S("Enchant") end @@ -307,7 +313,7 @@ minetest.register_abm({ nodenames = "mcl_enchanting:table", action = function(pos) local playernames = {} - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 15)) do + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 15)) do if obj:is_player() then table.insert(playernames, obj:get_player_name()) end @@ -349,7 +355,7 @@ minetest.register_lbm({ nodenames = {"mcl_enchanting:table"}, run_at_every_load = true, action = function(pos) - spawn_book_entity(pos) + spawn_book_entity(pos, true) end, }) @@ -359,4 +365,4 @@ minetest.register_on_joinplayer(mcl_enchanting.initialize_player) minetest.register_on_player_receive_fields(mcl_enchanting.handle_formspec_fields) minetest.register_allow_player_inventory_action(mcl_enchanting.allow_inventory_action) minetest.register_on_player_inventory_action(mcl_enchanting.on_inventory_action) -table.insert(tt.registered_snippets, 1, mcl_enchanting.enchantments_snippet) +tt.register_priority_snippet(mcl_enchanting.enchantments_snippet) diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.de.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.de.tr index 68077578c..ecc08b5dc 100644 --- a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.de.tr +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.de.tr @@ -17,8 +17,8 @@ Efficiency=Effizienz Increases mining speed.=Erhöht Grabegeschwindigkeit. Feather Falling=Federfall Reduces fall damage.=Reduziert Fallschaden. -Fire Aspect=Feieraspekt -Sets target on fire.=Zündes das Ziel an. +Fire Aspect=Feueraspekt +Sets target on fire.=Zündet das Ziel an. Fire Protection=Feuerschutz Reduces fire damage.=Reduziert Feuerschaden Flame=Flamme @@ -31,7 +31,7 @@ Impaling=Aufspießen Trident deals additional damage to ocean mobs.=Dreizack richtet Zusatzschaden an Ozeanmobs an. Infinity=Unendlichkeit Shooting consumes no regular arrows.=Schüsse verbrauchen keine regulären Pfeile. -Knockback=Rückschlag. +Knockback=Rückschlag Increases knockback.=Verstärkt Rückschlag. Looting=Plünderer Increases mob loot.=Erhöht Abwürfe von Mobs. @@ -43,7 +43,7 @@ Lure=Köder Decreases time until rod catches something.=Reduziert die Zeit, bis die Angel etwas fängt. Mending=Ausbessern Repair the item while gaining XP orbs.=Gegenstand reparieren, während man Erfahrungskugeln erhält. -Multishot=Mehrschuss +Multishot=Mehrfachschuss Shoot 3 arrows at the cost of one.=3 Pfeile zum Preis von 1 schießen. Piercing=Durchbohren Arrows passes through multiple objects.=Pfeile durchdringen mehrere Objekte. @@ -74,7 +74,7 @@ Increases sweeping attack damage.=Erhöht Schwungangriffsschaden. Thorns=Dornen Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Reflektiert etwas des Schadens beim Erleiden eines Treffers, auf Kosten der Haltbarkeit. Unbreaking=Haltbarkeit -Increases item durability.=Erhöht Haldbarkeit des Gegenstands. +Increases item durability.=Erhöht Haltbarkeit des Gegenstands. Inventory=Inventar @1 Lapis Lazuli=@1 Lapislazuli @1 Enchantment Levels=@1 Verzauberungsstufen diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr new file mode 100644 index 000000000..a977e8fe6 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.es.tr @@ -0,0 +1,123 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=Las flechas atraviesan multiples enemigos. +Arrows set target on fire.=Las flechas prenderan los enemigos. +Bane of Arthropods=Perdición de los Artrópodos +Channeling=Conductividad + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canaliza los rayos de una tormenta hacia el enemigo. + +Curse of Vanishing=Maldición de Desaparición +Decreases crossbow charging time.=Disminuye el tiempo de carga de las ballestas. +Decreases time until rod catches something.=Disminuye el tiempo que tardan en picar los cebos en la pesca. +Depth Strider=Agilidad acuática +Efficiency=Eficiencia +Extends underwater breathing time.=Aumenta el tiempo de mantener la respiración. +Fire Aspect=Aspecto Ígneo +Flame=Fuego +Fortune=Fortuna +Frost Walker=Paso Helado +Impaling=Empalamiento +Increases arrow damage.=Incrementa el daño de las flechas. +Increases arrow knockback.=Incrementa el empuje de las flechas. +Increases certain block drops.=Incrementa la cantidad de objetos que sueltan los bloques. + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Incrementa el daño y ralentiza a los artrópodos. (arañas, lepismas, endermitas, etc) + +Increases damage to undead mobs.=Incrementa el daño contra no-muertos. +Increases damage.=Incrementa el daño. +Increases item durability.=Incrementa la durabilidad de una herramienta. +Increases knockback.=Incrementa el empuje. +Increases mining speed.=Incrementa la velocidad de picado. +Increases mob loot.=Incrementa el botín de los enemigos. +Increases rate of good loot (enchanting books, etc.)=Incrementa la probabilidad de encontrar tesoros. +Increases sweeping attack damage.=Incrementa el daño de efecto area. +Increases underwater movement speed.=Incrementa la velocidad de nado bajo el agua. +Increases walking speed on soul sand.=Incrementa la velocidad al caminar sobre arena de Almas. +Infinity=Infinidad +Item destroyed on death.=El objeto se destruye tras tu muerte. +Knockback=Empuje +Looting=Botín +Loyalty=Lealtad +Luck of the Sea=Suerte Marina +Lure=Atracción +Mending=Reparación +Mined blocks drop themselves.=Los bloques se minarán enteros. +Multishot=Multidisparo +Piercing=Perforación +Power=Poder +Punch=Retroceso +Quick Charge=Carga Rápida +Repair the item while gaining XP orbs.=Repara los objetos portados al recibir orbes de experiencia. +Respiration=Respiración +Riptide=Propulsión acuática +Sets target on fire.=Incencia al enemigo. +Sharpness=Filo +Shoot 3 arrows at the cost of one.=Dispara 3 flechas al precio de una. +Shooting consumes no regular arrows.=No se consumiran las flechas lanzadas. +Silk Touch=Toque de Seda +Smite=Golpeo +Soul Speed=Velocidad de Almas +Sweeping Edge=Filo Arrasador +Trident deals additional damage to ocean mobs.=Incrementa el daño del tridente sobre criaturas acuáticas. + +Trident launches player with itself when thrown. Works only in water or rain.=El tridente impulsa al portador dentro del agua o bajo la lluvia. + +Trident returns after being thrown. Higher levels reduce return time.=El tridente regresa al portador tras lanzarlo. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Congela el agua bajo tus pies y evita el daño de los bloques de magma. + +Unbreaking=Irrompibilidad + +### engine.lua ### + +@1 Enchantment Levels=Nivel de encantamiento: @1 +@1 Lapis Lazuli=@1 Lapis Lázuli +Inventory=Inventario +Level requirement: @1=Nivel requerido: @1 + +### init.lua ### + +'@1' is not a valid number='@1' no es un número válido +'@1' is not a valid number.='@1' no es un número válido + []= [] +@1 can't be combined with @2.=@1 no se puede combinar con @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.=Despues elige tu encantamiento, los niveles de experiencia y el lapis lázuli seran consumidos y el encantamiento aplicado al objeto. + +After placing your items in the slots, the enchanting options will be shown. Hover over the options to read what is available to you.=Coloca el objeto en su ranura yse mostraran los encantamientos a elegir. + +Enchant=Encantamiento +Enchant an item=Encantar objeto +Enchanted Book=Libro Encantado +Enchanting Table=Mesa de Encantamientos + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=La mesa de Encantamientos dara a tus herramientas, armas o armadura algunas habilidades magicas. Pero a coste de algo de experiencia y lapis lázuli. + +Enchanting succeded.=Encantado correctamente. +Forcefully enchant an item=Encantar objeto a la fuerza. + +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.=Coloca una herramienta, arma, armadura o libro sobre la ranura izquierda, coloca de 1 a 3 Lapis lázulis en la ranura derecha. + +Player '@1' cannot be found.=Jugador @1 no encontrado. +Rightclick the Enchanting Table to open the enchanting menu.=Clic derecho sobre la mesa de encantamientos para abrir la interfaz. +Spend experience, and lapis to enchant various items.=Experiencia y Lapis para encantar varios objetos. + +The number you have entered (@1) is too big, it must be at most @2.=@1 es muy grande, debe ser menor que @2 + +The number you have entered (@1) is too small, it must be at least @2.=@1 es muy pequeño, debe ser mayor a @2 + +The selected enchantment can't be added to the target item.=El encantamiento seleccionado no puede añadirse a ese objeto. +The target doesn't hold an item.=El jugador no sujeta un objeto. +The target item is not enchantable.=El objeto del jugador no se puede encantar. +There is no such enchantment '@1'.=@1 no es un encantamiento. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Las opciones seran aleatorias dependiendo del nivel de experiencia, los niveles de encantamiento pueden ser aumentados. + +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 los niveles de encantamientos, coloca librerias alrededor y cerca de la mesa de encantamientos. + +Usage: /enchant []=Usa: /enchant [] +Usage: /forceenchant []=Usa /forceenchant [] diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr new file mode 100644 index 000000000..80912a711 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.fr.tr @@ -0,0 +1,144 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=Les flèches traversent plusieurs objets. +Arrows set target on fire.=Les flèches mettent le feu à la cible. +Bane of Arthropods=Fléau des arthropodes +Channeling=Canalisation + +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Canalise un éclair vers une cible. Fonctionne uniquement pendant les orages et si la cible n'est pas obstruée par des blocs opaques. + +Curse of Vanishing=Malédiction de disparition +Decreases crossbow charging time.=Diminue le temps de chargement de l'arbalète. +Decreases time until rod catches something.=Diminue le temps jusqu'à ce qu'un poisson ne morde à l'hameçon. +Depth Strider=Agilité aquatique +Efficiency=Efficacité +Extends underwater breathing time.=Prolonge le temps de respiration sous l'eau. +Fire Aspect=Aura de feu +Flame=Flamme +Fortune=Fortune +Frost Walker=Semelles givrantes +Impaling=Empalement +Increases arrow damage.=Augmente les dégâts des flèches. +Increases arrow knockback.=Augmente le recul de la flèche. +Increases certain block drops.=Multiplie les objets droppés + +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Augmente les dégâts et applique la lenteur IV aux mobs arthropodes (araignées, araignées des cavernes, poissons d'argent et endermites). + +Increases damage to undead mobs.=Augmente les dégâts infligés aux monstres morts-vivants. +Increases damage.=Augmente les dégâts. +Increases item durability.=Augmente la durabilité des objets. +Increases knockback.=Augmente le recul. +Increases mining speed.=Augmente la vitesse de minage. +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. +Infinity=Infinité +Item destroyed on death.=Objet détruit à la mort. +Knockback=Recul +Looting=Butin +Loyalty=Loyauté +Luck of the Sea=Chance de la mer +Lure=Appât +Mending=Raccommodage +Mined blocks drop themselves.=Vous obtenez les blocs minés en minant. +Multishot=Tir multiple +Piercing=Perforation +Power=Puissance +Punch=Frappe +Quick Charge=Charge rapide +Repair the item while gaining XP orbs.=Réparez l'objet tout en gagnant des points d'XP. +Respiration=Apnée +Riptide=Impulsion +Sets target on fire.=Enflamme la cible. +Sharpness=Tranchant +Shoot 3 arrows at the cost of one.=Tirez 3 flèches pour le prix d'une. +Shooting consumes no regular arrows.=Le tir ne consomme pas de flèches standard. +Silk Touch=Toucher de soie +Smite=Châtiment +Soul Speed=Agilité des âmes +Sweeping Edge=Affilage +Trident deals additional damage to ocean mobs.=Le trident inflige des dégâts supplémentaires aux animaux océaniques. + +Trident launches player with itself when thrown. Works only in water or rain.=Le trident emporte le joueur avec lui-même lorsqu'il est lancé. Fonctionne uniquement sous l'eau ou sous la pluie. + +Trident returns after being thrown. Higher levels reduce return time.=Le trident revient après avoir été jeté. Des niveaux plus élevés réduisent le temps de retour. + +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Transforme l'eau sous le joueur en glace givrée et empêche les dégâts causés par les blocs de magma. + +Unbreaking=Solidité + +### engine.lua ### + +@1 Enchantment Levels=@1 Niveaux d'enchantement +@1 Lapis Lazuli=@1 Lapis Lazuli +Inventory=Inventaire +Level requirement: @1=Niveau requis : @1 + +### init.lua ### + +'@1' is not a valid number='@1' n'est pas un nombre valide +'@1' is not a valid number.='@1' n'est pas un nombre valide. + []= [] +@1 can't be combined with @2.=@1 ne peut pas être combiné avec @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.=Après avoir finalement sélectionné un enchantement ; cliquer gauche la sélection, et vous verrez à la fois les lapis-lazuli et vos niveaux d'expérience consommés. Un objet enchanté est laissé à leur 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.=Après avoir placé vos objets dans les emplacements, les options d'enchantement seront montrées. Passer au-dessus des options pour lire ce qui est disponible. + +Enchant=Enchantement +Enchant an item=Enchanter un objet +Enchanted Book=Livre enchanté +Enchanting Table=Table d'enchantement + +Enchanting Tables will let you enchant armors, tools, weapons, and books with various abilities. But, at the cost of some experience, and lapis lazuli.=La table d'enchantement vous permet d'enchanter des armures, des outils, des armes et des livres avec diverses propriétés. Mais cela coûte de l'expérience et des lapis-lazuli. + +Enchanting succeded.=L'enchantement a réussi. +Forcefully enchant an item=Enchantement forcé d'un objet + +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.=Placer un outil, armure, arme ou livre dans l'emplacement en haut à gauche, puis 1-3 Lapis-Lazuli dans l'emplacement à droite. + +Player '@1' cannot be found.=Le joueur '@1' est introuvable. +Rightclick the Enchanting Table to open the enchanting menu.=Cliquer droit la table d'enchantement pour ouvrir le menu d'enchantement. +Spend experience, and lapis to enchant various items.=Dépenser de l'expérience, et des lapis pour enchanter divers objets. + +The number you have entered (@1) is too big, it must be at most @2.=Le nombre que vous avez entré (@1) est trop grand, il doit être au plus de @2. + +The number you have entered (@1) is too small, it must be at least @2.=Le nombre que vous avez entré (@1) est trop petit, il doit être au moins de @2. + +The selected enchantment can't be added to the target item.=L'enchantement sélectionné ne peut pas être ajouté à la cible. +The target doesn't hold an item.=La cible ne contient aucun élément. +The target item is not enchantable.=L'objet cible n'est pas enchantable. +There is no such enchantment '@1'.=L'enchantement '@1' n'existe pas. + +These options are randomized, and dependent on experience level; but the enchantment strength can be increased.=Ces options sont aléatoires et dépendent du niveau d'expérience ; mais la force d'enchantement peut être augmentée. + +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.=Pour augmenter la force d'enchantement, placer des bibliothèques autour de la table d'enchantement. Cependant, vous devrez garder au moins un bloc d'air entre la table et les bibliothèques pour alimenter la table d'enchantement. + +Usage: /enchant []=Usage: /enchant [] +Usage: /forceenchant []=Usage: /forceenchant [] + + +##### not used anymore ##### + +# textdomain: mcl_enchanting +Aqua Affinity=Affinité aquatique +Increases underwater mining speed.=Augmente la vitesse de minage sous-marine. +Blast Protection=Protection contre les explosions +Reduces explosion damage and knockback.=Réduit les dégâts d'explosion et de recul. +Curse of Binding=Malédiction du lien éternel +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=L'objet ne peut pas être retiré des emplacements d'armure sauf en cas de mort, de rupture ou en mode créatif. +Feather Falling=Chute amortie +Reduces fall damage.=Reduit les dégats de chute. +Fire Protection=Protection contre le feu +Reduces fire damage.=Reduit les dégats de feu. +Projectile Protection=Protection contre les projectiles +Reduces projectile damage.=Réduit les dégâts causés par les projectiles. +Protection=Protection +Reduces most types of damage by 4% for each level.=éduit la plupart des types de dégâts de 4% pour chaque niveau. +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. +Thorns=Épines diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr new file mode 100644 index 000000000..1983ec4d4 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ja.tr @@ -0,0 +1,144 @@ +# textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.=矢が複数のオブジェクトを貫通します。 +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.=クロスボウの装填時間が短くなります。 +Decreases time until rod catches something.=釣りで獲物のかかる間隔が短くなります。 +Depth Strider=水中移動 +Efficiency=効率化 +Extends underwater breathing time.=水中での呼吸時間を延長します。 +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).=虫系のMOB(クモ、洞窟グモ、シルバーフィッシュ、エンダーマイト)に対してダメージが増加し、鈍化IVを適用します。 + +Increases damage to undead mobs.=アンデッド系のMOBへのダメージが増加します。 +Increases damage.=ダメージが増加します。 +Increases item durability.=アイテムの耐久度が向上します。 +Increases knockback.=ノックバックを強化します。 +Increases mining speed.=採掘速度が増加します。 +Increases mob loot.=MOBの戦利品が増加します。 +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.=1本分のコストで、3本の矢を同時に拡散発射します。 +Shooting consumes no regular arrows.=普通の矢は射ても消費しなくなります。 +Silk Touch=シルクタッチ +Smite=破邪 +Soul Speed=ソウルスピード +Sweeping Edge=スイープエッジ +Trident deals additional damage to ocean mobs.=トライデントは水生系のMOBに追加ダメージを与えます。 + +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=インベントリ +Level requirement: @1=必要レベル:@1 + +### init.lua ### + +'@1' is not a valid number='@1'は有効ではない数字 +'@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=エンチャントテーブル + +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.=体の外からのダメージ全般を軽減します(レベル毎に+4%)。 +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/mcl_enchanting.pl.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.pl.tr new file mode 100644 index 000000000..179702d79 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.pl.tr @@ -0,0 +1,100 @@ +# textdomain: mcl_enchanting +Aqua Affinity=Powinowactwo wodne +Increases underwater mining speed.=Przyspiesza wydobywanie pod wodą. +Bane of Arthropods=Zmora stawonogów +Increases damage and applies Slowness IV to arthropod mobs (spiders, cave spiders, silverfish and endermites).=Zwiększa obrażenia i aplikuje Spowolnienie IV stawonogom (pająkom, pająkom jaskiniowym, rybikom cukrowym i endermitom) +Blast Protection=Ochrona od wybuchów +Reduces explosion damage and knockback.=Zmniejsza obrażenia od wybuchów i odrzut. +Channeling=Przekierowanie +Channels a bolt of lightning toward a target. Works only during thunderstorms and if target is unobstructed with opaque blocks.=Przekierowuje błyskawicę w stronę celu. Działa tylko podczas burz jeśli cel nie jest zasłonięty przez nieprzezroczyste bloki. +Curse of Binding=Klątwa wiązania +Item cannot be removed from armor slots except due to death, breaking or in Creative Mode.=Przedmiotu nie można zdjąć z miejsc na zbroję inaczej niż przez śmierć, zepsucie bądź w trybie kreatywnym. +Curse of Vanishing=Klątwa znikania +Item destroyed on death.=Przedmiot niszczony przy śmierci +Depth Strider=Głębinowy wędrowiec +Increases underwater movement speed.=Zwiększa prędkość poruszania pod wodą. +Efficiency=Wydajność +Increases mining speed.=Zwiększa prędkość wydobywania zasobów. +Feather Falling=Powolne opadanie +Reduces fall damage.=Zmniejsza obrażenia od upadku. +Fire Aspect=Zaklęty ogień +Sets target on fire.=Podpala cel. +Fire Protection=Ochrona przed ogniem +Reduces fire damage.=Zmniejsza obrażenia od ognia +Flame=Płomień +Arrows set target on fire.=Strzały podpalają cel. +Fortune=Fortuna +Increases certain block drops.=Zwiększa prawdopodobieństwo wypadnięcia przedmiotów z niektórych bloków. +Frost Walker=Mroźny piechur +Turns water beneath the player into frosted ice and prevents the damage from magma blocks.=Zamienia wodę pod graczem w oszroniony lód i pozwala uniknąć obrażeń od bloków magmy. +Impaling=Przebicie +Trident deals additional damage to ocean mobs.=Trójząb zadaje dodatkowe obrażenia podwodnym stworzeniom. +Infinity=Nieskończoność +Shooting consumes no regular arrows.=Strzelanie nie zużywa zwykłych strzał. +Knockback=Odrzut +Increases knockback.=Zwiększa odrzut. +Looting=Grabież +Increases mob loot.=Zwiększa liczbę przedmiotów wypadających z mobów. +Loyalty=Lojalność +Trident returns after being thrown. Higher levels reduce return time.=Trydent wraca do gracza po rzuceniu. Większy poziom zmniejsza czas powrotu. +Luck of the Sea=Morska fortuna +Increases rate of good loot (enchanting books, etc.)=Zwiększa szansę na wypadnięcie dobrych przedmiotów (zaklętych książek itp.) +Lure=Przynęta +Decreases time until rod catches something.=Zmniejsza czas po którym coś złapie się na wędkę +Mending=Naprawa +Repair the item while gaining XP orbs.=Naprawia przedmiot podczas podnoszenia kul doświadczenia. +Multishot=Wielostrzał +Shoot 3 arrows at the cost of one.=Wystrzel 3 strzały kosztem jednej. +Piercing=Przeszycie +Arrows passes through multiple objects.=Strzała przelatuje przez wiele obiektów. +Power=Moc +Increases arrow damage.=Zwiększa obrażenia od strzał. +Projectile Protection=Ochrona przed pociskami +Reduces projectile damage.=Zmniejsza obrażenia od pocisków. +Protection=Obrona +Reduces most types of damage by 4% for each level.=Zmniejsza obrażenia większości typów o 4% za każdy poziom. +Punch=Uderzenie +Increases arrow knockback.=Zwiększa odrzut strzał. +Quick Charge=Szybkie ładowanie +Decreases crossbow charging time.=Zmniejsza czas ładowania kuszy. +Respiration=Oddychanie +Extends underwater breathing time.=Zwiększa czas na który można wstrzymać oddech pod wodą. +Riptide=Torpeda +Trident launches player with itself when thrown. Works only in water or rain.=Trydent porywa gracza ze sobą podczas rzucania. Działa tylko w wodzie lub w deszczu. +Sharpness=Ostrość +Increases damage.=Zwiększa obrażenia. +Silk Touch=Jedwabny dotyk +Mined blocks drop themselves.=Z wydobywanych bloków wypadają one same. +Smite=Pogromca nieumarłych +Increases damage to undead mobs.=Zwiększa obrażenia zadawane nieumarłym mobom. +Soul Speed=Prędkość dusz +Increases walking speed on soul sand.=Zwiększa szybkość chodzenia po piasku dusz. +Sweeping Edge=Szerokie ostrze +Increases sweeping attack damage.=Zwiększa obrażenia przy ataku z zamachu. +Thorns=Ciernie +Reflects some of the damage taken when hit, at the cost of reducing durability with each proc.=Odbija część zadanych obrażeń kosztem utraty wytrzymałości zbroi. +Unbreaking=Niezniszczalność +Increases item durability.=Zwiększa wytrzymałość przedmiotu. +Inventory=Ekwipunek +@1 Lapis Lazuli=@1 Lazurytów +@1 Enchantment Levels=@1 poziomów zaklęcia +Level requirement: @1=Wymagany poziom: @1 +Enchant an item=Zaczaruj przedmiot + []= [] +Usage: /enchant []=Użycie: /enchant [] +Player '@1' cannot be found.=Gracz '@1' nie został znaleziony. +There is no such enchantment '@1'.=Nie ma takiego zaklęcia '@1'. +The target doesn't hold an item.=Cel nie trzyma żadnego przedmiotu. +The selected enchantment can't be added to the target item.=Wybrane zaklęcie nie może zostać zaaplikowane do docelowego przedmiotu. +'@1' is not a valid number='@1' nie jest poprawną liczbą. +The number you have entered (@1) is too big, it must be at most @2.=Liczba którą wpisałaś (@1) jest zbyt duża, nie może być większa niż @2. +The number you have entered (@1) is too small, it must be at least @2.=Liczba którą wpisałaś (@1) jest zbyt mała, nie może być mniejsza niż @2. +@1 can't be combined with @2.=@1 nie może być połączone z @2. +Enchanting succeded.=Zaklinanie powiodło się. +Forcefully enchant an item=Bezwzględnie zaczaruj przedmiot. +Usage: /forceenchant []=Użycie: /forceenchant [] +The target item is not enchantable.=Docelowego przedmiotu nie można zaczarować. +'@1' is not a valid number.='@1' nie jest poprawną liczbą. +Enchanted Book=Zaklęta książka +Enchanting Table=Stół do zaklinania +Enchant=Zaczaruj diff --git a/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr new file mode 100644 index 000000000..6cd1e1db6 --- /dev/null +++ b/mods/ITEMS/mcl_enchanting/locale/mcl_enchanting.ru.tr @@ -0,0 +1,100 @@ +# 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=Бронебойность +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=Быстрая перезарядка +Decreases crossbow charging time.=Уменьшает время заряда снаряда. +Respiration=Подводное дыхание +Extends underwater breathing time.=Увеличивает время дыхания под водой. +Riptide=Тягун +Trident launches player with itself when thrown. Works only in water or rain.=Трезубец тянет игрока за собой. Работает только в воде или под дождём. +Sharpness=Острота +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.=Увеличивает прочность предмета. +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.=Выбранное зачарование не может быть добавлено к целевому предмету. +'@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' не является допустимым числом. +Enchanted Book=Зачарованная книга +Enchanting Table=Стол зачаровывания +Enchant=Зачарование diff --git a/mods/ITEMS/mcl_enchanting/locale/template.txt b/mods/ITEMS/mcl_enchanting/locale/template.txt index f186ef37b..59876dcf3 100644 --- a/mods/ITEMS/mcl_enchanting/locale/template.txt +++ b/mods/ITEMS/mcl_enchanting/locale/template.txt @@ -1,100 +1,144 @@ # textdomain: mcl_enchanting + + +### enchantments.lua ### + +Arrows passes through multiple objects.= +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.= +Decreases time until rod catches something.= +Depth Strider= +Efficiency= +Extends underwater breathing time.= +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).= + +Increases damage to undead mobs.= +Increases damage.= +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 Lapis Lazuli= +Inventory= +Level requirement: @1= + +### init.lua ### + +'@1' is not a valid number= +'@1' is not a valid number.= + []= +@1 can't be combined with @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= + +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.= + +Player '@1' cannot be found.= +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.= + +The number you have entered (@1) is too small, it must be at least @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'.= + +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.= + +Usage: /enchant []= +Usage: /forceenchant []= + + +##### not used anymore ##### + +# 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).= 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= +Curse of Binding=Malédiction du lien éternel 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= -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.= -Punch= -Increases arrow knockback.= -Quick Charge= -Decreases crossbow charging time.= -Respiration= -Extends underwater breathing time.= -Riptide= -Trident launches player with itself when thrown. Works only in water or rain.= -Sharpness= -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.= -Inventory= -@1 × Lapis Lazuli= -Enchantment levels: @1= -Level requirement: @1= -Enchant an item= - []= -Usage: /enchant []= -Player '@1' cannot be found.= -There is no such enchantment '@1'.= -The target doesn't hold an item.= -The selected enchantment can't be added to the target item.= -'@1' is not a valid number= -The number you have entered (@1) is too big, it must be at most @2.= -The number you have entered (@1) is too small, it must be at least @2.= -@1 can't be combined with @2.= -Enchanting succeded.= -Forcefully enchant an item= -Usage: /forceenchant []= -The target item is not enchantable.= -'@1' is not a valid number.= -Enchanted Book= -Enchanting Table= -Enchant= diff --git a/mods/ITEMS/mcl_enchanting/mod.conf b/mods/ITEMS/mcl_enchanting/mod.conf index ac4dad644..610492857 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 +depends = tt, walkover, mcl_sounds, mcl_colors, mcl_experience optional_depends = screwdriver author = Fleckenstein diff --git a/mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book_entity.png b/mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book_entity.png deleted file mode 100644 index fe6acf601..000000000 Binary files a/mods/ITEMS/mcl_enchanting/models/mcl_enchanting_book_entity.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_closed.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_closed.png deleted file mode 100644 index 7defcbc65..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_closed.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png deleted file mode 100644 index 5cd46d8b6..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_enchanted.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_open.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_open.png deleted file mode 100644 index 7059db5fc..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_book_open.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button.png deleted file mode 100644 index 92674cae1..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_background.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_background.png deleted file mode 100644 index a9ddf6cb2..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_background.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_hovered.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_hovered.png deleted file mode 100644 index d733e4e5e..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_hovered.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_off.png deleted file mode 100644 index 11b71696c..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_button_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_1.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_1.png deleted file mode 100644 index a5ac3f553..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_10.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_10.png deleted file mode 100644 index d002147f5..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_10.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_11.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_11.png deleted file mode 100644 index c9cd9ff5c..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_11.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_12.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_12.png deleted file mode 100644 index dc5dd1d20..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_12.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_13.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_13.png deleted file mode 100644 index 45c6d5a63..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_13.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_15.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_15.png deleted file mode 100644 index 0db3a9ea2..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_15.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_16.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_16.png deleted file mode 100644 index d10a72b75..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_16.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_17.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_17.png deleted file mode 100644 index 2b374e881..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_17.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_18.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_18.png deleted file mode 100644 index e762e350b..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_18.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_2.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_2.png deleted file mode 100644 index eb1e74fbc..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_3.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_3.png deleted file mode 100644 index e82145e5c..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_5.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_5.png deleted file mode 100644 index f0635bf2b..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_5.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_6.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_6.png deleted file mode 100644 index c93976cfb..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_6.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_7.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_7.png deleted file mode 100644 index 1e4ff0248..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_7.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_8.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_8.png deleted file mode 100644 index 2f2b86c16..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_8.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_lapis_background.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_lapis_background.png deleted file mode 100644 index 1a224f35f..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_lapis_background.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1.png deleted file mode 100644 index ecd6b1120..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1_off.png deleted file mode 100644 index 60d755e94..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_1_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2.png deleted file mode 100644 index a90100f12..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2_off.png deleted file mode 100644 index 9ba41bd55..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_2_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3.png deleted file mode 100644 index 8dd37a8b9..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3_off.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3_off.png deleted file mode 100644 index ddcc98f9b..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_number_3_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_bottom.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_bottom.png deleted file mode 100644 index ef4cc8a15..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_side.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_side.png deleted file mode 100644 index 858b9e3dc..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_top.png b/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_top.png deleted file mode 100644 index 95b45c70e..000000000 Binary files a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_table_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/building.lua b/mods/ITEMS/mcl_end/building.lua index 3dcf0671e..82f6e76e4 100644 --- a/mods/ITEMS/mcl_end/building.lua +++ b/mods/ITEMS/mcl_end/building.lua @@ -1,7 +1,8 @@ -- Building blocks and decorative nodes -local S = minetest.get_translator("mcl_end") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_screwdriver = minetest.get_modpath("screwdriver") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way @@ -28,7 +29,7 @@ minetest.register_node("mcl_end:end_bricks", { groups = {pickaxey=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 9, - _mcl_hardness = 0.8, + _mcl_hardness = 3, }) minetest.register_node("mcl_end:purpur_block", { @@ -165,11 +166,22 @@ minetest.register_node("mcl_end:dragon_egg", { selection_box = { type = "regular", }, - groups = {handy=1, falling_node = 1, deco_block = 1, not_in_creative_inventory = 1, dig_by_piston = 1 }, + groups = {handy = 1, falling_node = 1, deco_block = 1, not_in_creative_inventory = 1, dig_by_piston = 1 }, sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 9, _mcl_hardness = 3, - -- TODO: Make dragon egg teleport on punching + on_punch = function(pos, node, puncher) + if not minetest.is_protected(pos, puncher:get_player_name()) then + local max_dist = vector.new(15, 7, 15) + local positions = minetest.find_nodes_in_area(vector.subtract(pos, max_dist), vector.add(pos, max_dist), "air", false) + if #positions > 0 then + local tpos = positions[math.random(#positions)] + minetest.remove_node(pos) + minetest.set_node(tpos, node) + minetest.check_for_falling(tpos) + end + end + end, }) diff --git a/mods/ITEMS/mcl_end/chorus_plant.lua b/mods/ITEMS/mcl_end/chorus_plant.lua index 1363debf7..4dc54db18 100644 --- a/mods/ITEMS/mcl_end/chorus_plant.lua +++ b/mods/ITEMS/mcl_end/chorus_plant.lua @@ -1,7 +1,10 @@ -- Chorus plants -- This includes chorus flowers, chorus plant stem nodes and chorus fruit -local S = minetest.get_translator("mcl_end") +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math +local table = table --- Plant parts --- @@ -29,10 +32,10 @@ local no_detach = {} -- This detaches all chorus plants that are/were attached -- at start_pos. -mcl_end.detach_chorus_plant = function(start_pos, digger) +function mcl_end.detach_chorus_plant(start_pos, digger) -- This node should not call a detach function, do NOTHING local hash = minetest.hash_node_position(start_pos) - if no_detach[hash] ~= nil then + if no_detach[hash] then return end @@ -106,11 +109,11 @@ mcl_end.detach_chorus_plant = function(start_pos, digger) no_detach = {} end -mcl_end.check_detach_chorus_plant = function(pos, oldnode, oldmetadata, digger) +function mcl_end.check_detach_chorus_plant(pos, oldnode, oldmetadata, digger) mcl_end.detach_chorus_plant(pos, digger) end -mcl_end.check_blast_chorus_plant = function(pos) +function mcl_end.check_blast_chorus_plant(pos) minetest.remove_node(pos) mcl_end.detach_chorus_plant(pos) end @@ -139,7 +142,7 @@ minetest.register_node("mcl_end:chorus_flower", { node_placement_prediction = "", on_place = function(itemstack, placer, pointed_thing) local node_under = minetest.get_node(pointed_thing.under) - local node_above = minetest.get_node(pointed_thing.above) + --local node_above = minetest.get_node(pointed_thing.above) if placer and not placer:get_player_control().sneak then -- Use pointed node's on_rightclick function first, if present if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then @@ -309,7 +312,7 @@ minetest.register_node("mcl_end:chorus_plant", { }) -- Grow a complete chorus plant at pos -mcl_end.grow_chorus_plant = function(pos, node) +function mcl_end.grow_chorus_plant(pos, node, pr) local flowers = { pos } -- Plant initial flower (if it isn't there already) if not node then @@ -321,7 +324,7 @@ mcl_end.grow_chorus_plant = function(pos, node) while true do local new_flowers_list = {} for f=1, #flowers do - local new_flowers = mcl_end.grow_chorus_plant_step(flowers[f], minetest.get_node(flowers[f])) + local new_flowers = mcl_end.grow_chorus_plant_step(flowers[f], minetest.get_node(flowers[f]), pr) if #new_flowers > 0 then table.insert(new_flowers_list, new_flowers) end @@ -340,7 +343,7 @@ end -- Grow a single step of a chorus plant at pos. -- Pos must be a chorus flower. -mcl_end.grow_chorus_plant_step = function(pos, node) +function mcl_end.grow_chorus_plant_step(pos, node, pr) local new_flower_buds = {} local above = { x = pos.x, y = pos.y + 1, z = pos.z } local node_above = minetest.get_node(above) @@ -396,7 +399,7 @@ mcl_end.grow_chorus_plant_step = function(pos, node) if grow_chance then local new_flowers = {} - local r = math.random(1, 100) + local r = pr:next(1, 100) local age = node.param2 if r <= grow_chance then table.insert(new_flowers, above) @@ -404,13 +407,12 @@ mcl_end.grow_chorus_plant_step = function(pos, node) age = age + 1 local branches if branching == false then - branches = math.random(1, 4) + branches = pr:next(1, 4) elseif branching == true then - branches = math.random(0, 3) + branches = pr:next(0, 3) end - local branch_grown = false for b=1, branches do - local next_branch = math.random(1, #around) + local next_branch = pr:next(1, #around) local branch = vector.add(pos, around[next_branch]) local below_branch = vector.add(branch, {x=0,y=-1,z=0}) if minetest.get_node(below_branch).name == "air" then @@ -419,7 +421,7 @@ mcl_end.grow_chorus_plant_step = function(pos, node) end end - for _, f in ipairs(new_flowers) do + for _, f in pairs(new_flowers) do if age >= MAX_FLOWER_AGE then local nn = minetest.get_node(f).name if nn ~= "mcl_end:chorus_flower" and nn ~= "mcl_end:chorus_flower_dead" then @@ -451,13 +453,15 @@ mcl_end.grow_chorus_plant_step = function(pos, node) end --- ABM --- +local seed = minetest.get_mapgen_setting("seed") +local pr = PseudoRandom(seed) minetest.register_abm({ label = "Chorus plant growth", nodenames = { "mcl_end:chorus_flower" }, interval = 35.0, chance = 4.0, action = function(pos, node, active_object_count, active_object_count_wider) - mcl_end.grow_chorus_plant_step(pos, node) + mcl_end.grow_chorus_plant_step(pos, node, pr) end, }) @@ -470,7 +474,7 @@ minetest.register_abm({ -- * Maximum attempts: 16 -- -- Returns true on success. -local random_teleport = function(player) +local function random_teleport(player) local pos = player:get_pos() -- 16 attempts to find a suitable position for a=1, 16 do diff --git a/mods/ITEMS/mcl_end/depends.txt b/mods/ITEMS/mcl_end/depends.txt deleted file mode 100644 index 2adb4b59d..000000000 --- a/mods/ITEMS/mcl_end/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_sounds -mcl_util -doc_items -mcl_worlds -mcl_structures diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index c07ff7930..78fe658b4 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -1,4 +1,8 @@ -local S = minetest.get_translator("mcl_end") +local S = minetest.get_translator(minetest.get_current_modname()) + +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local vector = vector local explosion_strength = 6 @@ -27,9 +31,17 @@ end local function crystal_explode(self, puncher) if self._exploded then return end self._exploded = true - local strength = puncher and explosion_strength or 1 - mcl_explosions.explode(vector.add(self.object:get_pos(), {x = 0, y = 1.5, z = 0}), strength, {drop_chance = 1}, puncher) + local strength = 1 + local source + if puncher then + strength = explosion_strength + local reason = {} + mcl_damage.from_punch(reason, puncher) + mcl_damage.finish_reason(reason) + source = reason.source + end minetest.after(0, self.object.remove, self.object) + mcl_explosions.explode(vector.add(self.object:get_pos(), {x = 0, y = 1.5, z = 0}), strength, {drop_chance = 1}, self.object, source) end local function set_crystal_animation(self) @@ -37,7 +49,7 @@ local function set_crystal_animation(self) end local function spawn_crystal(pos) - local crystal = minetest.add_entity(pos, "mcl_end:crystal") + minetest.add_entity(pos, "mcl_end:crystal") if not vector.equals(pos, vector.floor(pos)) then return end if mcl_worlds.pos_to_dimension(pos) ~= "end" then return end local portal_center @@ -55,11 +67,20 @@ local function spawn_crystal(pos) crystals[i] = find_crystal(crystal_pos) if not crystals[i] then return end end + for _,o in pairs(minetest.get_objects_inside_radius(pos,64)) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:enderdragon" then return end + if not peaceful then + if o:is_player() then + awards.unlock(o:get_player_name(), "mcl:theEndAgain") + end + end + end for _, crystal in pairs(crystals) do crystal_explode(crystal) end - local dragon = minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon") - dragon:get_luaentity()._egg_spawn_pos = minetest.pos_to_string(vector.add(portal_center, {x = 0, y = 4, z = 0})) + local portal_pos = vector.add(portal_center, vector.new(0, -1, 0)) + mcl_structures.place_structure(portal_pos,mcl_structures.registered_structures["end_exit_portal"],PseudoRandom(minetest.get_mapgen_setting("seed")),-1) end minetest.register_entity("mcl_end:crystal", { @@ -70,14 +91,62 @@ minetest.register_entity("mcl_end:crystal", { collisionbox = {-1, 0.5, -1, 1, 2.5, 1}, mesh = "mcl_end_crystal.b3d", textures = {"mcl_end_crystal.png"}, - collide_with_objects = true, + collide_with_objects = false, }, on_punch = crystal_explode, on_activate = set_crystal_animation, _exploded = false, _hittable_by_projectile = true }) - + +minetest.register_entity("mcl_end:crystal_beam", { + initial_properties = { + physical = false, + visual = "cube", + visual_size = {x = 1, y = 1, z = 1}, + textures = { + "mcl_end_crystal_beam.png^[transformR90", + "mcl_end_crystal_beam.png^[transformR90", + "mcl_end_crystal_beam.png", + "mcl_end_crystal_beam.png", + "blank.png", + "blank.png", + }, + static_save = false, + }, + spin = 0, + init = function(self, dragon, crystal) + self.dragon, self.crystal = dragon, crystal + crystal:get_luaentity().beam = self.object + dragon:get_luaentity().beam = self.object + end, + on_deactivate = function(self) + if self.crystal and self.crystal:get_luaentity() then + self.crystal:get_luaentity().beam = nil + end + if self.dragon and self.dragon:get_luaentity() then + self.dragon:get_luaentity().beam = nil + end + end, + on_step = function(self, dtime) + if self.dragon and self.dragon:get_luaentity() and self.crystal and self.crystal:get_luaentity() then + self.spin = self.spin + dtime * math.pi * 2 / 4 + local dragon_pos, crystal_pos = self.dragon:get_pos(), self.crystal:get_pos() + + dragon_pos.y = dragon_pos.y + 4 + crystal_pos.y = crystal_pos.y + 2 + + self.object:set_pos(vector.divide(vector.add(dragon_pos, crystal_pos), 2)) + local rot = vector.dir_to_rotation(vector.direction(dragon_pos, crystal_pos)) + rot.z = self.spin + self.object:set_rotation(rot) + self.object:set_properties({visual_size = {x = 0.5, y = 0.5, z = vector.distance(dragon_pos, crystal_pos)}}) + else + self.object:remove() + end + end, +}) + minetest.register_craftitem("mcl_end:crystal", { inventory_image = "mcl_end_crystal_item.png", description = S("End Crystal"), @@ -85,10 +154,16 @@ minetest.register_craftitem("mcl_end:crystal", { on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type == "node" then local pos = minetest.get_pointed_thing_position(pointed_thing) - local node = minetest.get_node(pos).name + local node = minetest.get_node(pos) + local node_name = node.name + 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 if find_crystal(pos) then return itemstack end - if node == "mcl_core:obsidian" or node == "mcl_core:bedrock" then - if not minetest.is_creative_enabled(placer:get_player_name()) then + if node_name == "mcl_core:obsidian" or node_name == "mcl_core:bedrock" then + if not minetest.is_creative_enabled(placer:get_player_name()) then itemstack:take_item() end spawn_crystal(pos) @@ -110,5 +185,5 @@ minetest.register_craft({ {"mcl_core:glass", "mcl_mobitems:ghast_tear", "mcl_core:glass"}, } }) - + minetest.register_alias("mcl_end_crystal:end_crystal", "mcl_end:crystal") diff --git a/mods/ITEMS/mcl_end/eye_of_ender.lua b/mods/ITEMS/mcl_end/eye_of_ender.lua index 16f1c906b..b5adc7cb6 100644 --- a/mods/ITEMS/mcl_end/eye_of_ender.lua +++ b/mods/ITEMS/mcl_end/eye_of_ender.lua @@ -1,5 +1,5 @@ -- Eye of Ender -local S = minetest.get_translator("mcl_end") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_entity("mcl_end:ender_eye", { physical = false, @@ -29,7 +29,7 @@ minetest.register_entity("mcl_end:ender_eye", { if self._age >= 3 then -- End of life local r = math.random(1,5) - if r == 1 or minetest.is_creative_enabled("") then + if r == 1 then -- 20% chance to get destroyed completely. -- 100% if in Creative Mode self.object:remove() @@ -87,7 +87,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { end local origin = user:get_pos() origin.y = origin.y + 1.5 - local strongholds = mcl_structures.get_registered_structures("stronghold") + 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()) @@ -105,7 +105,7 @@ minetest.register_craftitem("mcl_end:ender_eye", { local closest_stronghold local lowest_dist for s=1, #strongholds do - local h_pos = table.copy(strongholds[s].pos) + local h_pos = table.copy(strongholds[s]) local h_origin = table.copy(origin) h_pos.y = 0 h_origin.y = 0 @@ -128,14 +128,14 @@ minetest.register_craftitem("mcl_end:ender_eye", { if lowest_dist <= 25 then local velocity = 4 -- Stronghold is close: Fly directly to stronghold and take Y into account. - dir = vector.normalize(vector.direction(origin, closest_stronghold.pos)) + dir = vector.normalize(vector.direction(origin, closest_stronghold)) obj:set_velocity({x=dir.x*velocity, y=dir.y*velocity, z=dir.z*velocity}) else local velocity = 12 -- Don't care about Y if stronghold is still far away. -- Fly to direction of X/Z, and always upwards so it can be seen easily. local o = {x=origin.x, y=0, z=origin.z} - local s = {x=closest_stronghold.pos.x, y=0, z=closest_stronghold.pos.z} + local s = {x=closest_stronghold.x, y=0, z=closest_stronghold.z} dir = vector.normalize(vector.direction(o, s)) obj:set_acceleration({x=dir.x*-3, y=4, z=dir.z*-3}) obj:set_velocity({x=dir.x*velocity, y=3, z=dir.z*velocity}) diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr index dc091a0f4..8e2d21e52 100644 --- a/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr +++ b/mods/ITEMS/mcl_end/locale/mcl_end.fr.tr @@ -1,27 +1,27 @@ # textdomain: mcl_end End Stone=Pierre de L'End End Stone Bricks=Brique de l'End -Purpur Block=Bloc de Purpur -Purpur Pillar=Bloc de Purpur Sculpté +Purpur Block=Bloc de purpur +Purpur Pillar=Bloc de purpur sculpté End Rod=Barre de l'End End rods are decorative light sources.=Les barres de l'End sont des sources de lumière décoratives. -Dragon Egg=Oeuf de Dragon +Dragon Egg=Oeuf de dragon A dragon egg is a decorative item which can be placed.=Un oeuf de dragon est un objet décoratif qui peut être placé. -Chorus Flower=Plante de Chorus +Chorus Flower=Plante de chorus 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.=Une fleur de chorus est la partie vivante d'une plante de chorus. Il peut devenir une grande plante de chorus, étape par étape. Quand elle grandit, elle peut finir par mourir en vieillissant. Elle meurt également lorsqu'il est incapable de grandir. 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.=Placez-la et attendez qu'elle grandisse. Elle ne peut être placée que sur le dessus de la pierre d'End, sur le dessus d'une tige de plante de chorus ou exactement sur le côté d'une tige de plante de chorus. -Dead Chorus Flower=Plante de Chorus Morte +Dead Chorus Flower=Plante de chorus morte 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.=Ceci fait partie d'une plante de chorus. Ça ne pousse pas. Les fleurs de chorus meurent de vieillesse ou lorsqu'elles ne peuvent pas pousser. Une fleur de chorus morte peut être récoltée pour obtenir une fleur de chorus fraîche qui peut repousser. -Chorus Plant Stem=Tige de Plante de Chorus +Chorus Plant Stem=Tige de plante de chorus 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.=Une tige de plante de chorus est la partie d'une plante de chorus qui maintient la plante entière ensemble. Il a besoin de pierre d'End comme sol. Les tiges sont issues de fleurs de chorus. -Chorus Fruit=Fruit de Chorus +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 Eclaté -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 End dans l'Overworld et pour activer les portails 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'oeil d'ender. Il s'élèvera et volera dans la direction horizontale du sanctuaire portail d'Ender le plus proche. Si vous êtes très proche, l'oeil 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 d'End, les yeux d'ender doivent être placés dans chaque bloc d'un cadre de portail d'End intact. -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. +Popped Chorus Fruit=Chorus éclaté +Eye of Ender=Œil 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. +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. The stem attaches itself to end stone and other chorus blocks.=La tige s'attache à la pierre d'End et à d'autres blocs de chorus. Grows on end stone=Pousse sur la pierre d'End Randomly teleports you when eaten=Vous téléporte au hasard quand il est mangé diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr b/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr new file mode 100644 index 000000000..647d3aea3 --- /dev/null +++ b/mods/ITEMS/mcl_end/locale/mcl_end.ja.tr @@ -0,0 +1,33 @@ +# textdomain: mcl_end +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.=ドラゴンの卵は、置いておくだけの装飾用アイテムです。 +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.=それを置き、成長を待ちます。置ける所は、エンドストーンかコーラスプラントの茎の上、または きっちり1本分あるコーラスプラントの茎の側面に限られます。 +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.=これはコーラスプラントの一部です。成長はしません。コーラスフラワーは、老衰や成長できなくなった場合に枯れてしまうのです。枯れたコーラスフラワーを収穫することで、再び成長できる新鮮なコーラスフラワーが得られます。 +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.=コーラスプラントの茎は、コーラスプラント全体を支えている部分です。その土壌としてエンドストーンを要します。コーラスフラワーから茎が育ちます。 +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=エンドストーンに生育 +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.=エンドクリスタルは爆発装置です。黒曜石や 岩盤の上に置けます。パンチか矢を当てると着火されます。エンドクリスタルは、エンドの出口ポータルの左右に1つずつ配置することで、エンダードラゴンを出現させることもできます。 +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.=エンドクリスタルを黒曜石や岩盤の上に置き、パンチか矢を当てると、おそらく致命的であろう大爆発を起こします。エンダードラゴンを出現させるには、エンドの出口ポータルの左右に1つずつ配置します。 diff --git a/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr b/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr new file mode 100644 index 000000000..e6526b265 --- /dev/null +++ b/mods/ITEMS/mcl_end/locale/mcl_end.pl.tr @@ -0,0 +1,33 @@ +# textdomain: mcl_end +End Stone=Kamień Kresu +End Stone Bricks=Ceglany kamień Kresu +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. +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 +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.=Kwiat refrenusu jest żywą częścią rośliny refrenusu. Może wyrosnąć w wysoką roślinę refrenusu blok po bloku. Gdy rośnie może po pewnym czasie umrzeć ze starości. Umiera również gdy nie jest w stanie rosnąć. +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.=Postaw go i poczekaj aż urośnie. Może być postawiony tylko na kamieniu Kresu, na łodydze rośliny refrenusu lub na boku dokładnie jednej łodygi rośliny refrenusu. +Dead Chorus Flower=Martwy kwiat refrenusu +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.=Jest to część rośliny refrenusu, która nie rośnie. Kwiaty refrenusu umierają ze starości lub gdy nie mogą rosnąć. Martwy kwiat refrenusu może zostać zebrany by otrzymać świeży kwiat refrenusu, który znów może urosnąć. +Chorus Plant Stem=Łodyga rośliny refrenusu +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.=Łodyga rośliny refrenusu to część rośliny która utrzymuje całą roślinę razem. Potrzebuje kamienia Kresu jako podłoża. Łodygi wyrastają z kwiatów refrenusu. +Chorus Fruit=Owoc refrenusu +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.=Owoc refrenusu jest jadalną częścią rośliny refrenusu, której naturalnym środowiskiem jest Kres. Zjedzenie go teleportuje cię na górę któregoś losowego stałego bloku w pobliżu, jeśli nie wylądowałbyś w płynie, stałym bloku lub szkodliwym bloku. Teleportacja może się nie udać jeśli nie ma, lub jest mało bloków które spełniają te warunki. +Popped Chorus Fruit=Prażony owoc refrenusu +Eye of Ender=Oko Kresu +This item is used to locate End portal shrines in the Overworld and to activate End portals.=Ten przedmiot jest wykorzystywany do znajdowaniu kapliczek portalu Kresu na Powierzchni oraz do aktywacji portali Kresu. +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.=Użyj przycisku ataku aby wypuścić oko Kresu. Podniesie się ono i poleci w poziomym kierunku najbliższej kapliczki portalu. Jeśli jesteś bardzo blisko, oko Kresu podąży bezpośrednią ścieżką do kapliczki portalu Kresu. Po kilku sekundach się zatrzymuje. Może wypaść jako przedmiot, jednak jest 20% szans, że się rozbije. +To activate an End portal, eyes of ender need to be placed into each block of an intact End portal frame.=Aby aktywować portal Kresu, w każdym bloku ramy portalu Kresu musi znajdować się 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. +The stem attaches itself to end stone and other chorus blocks.=Łodyga przytwierdza się do kamienia Kresu i innych refrenusowych bloków. +Grows on end stone=Rośnie na kamieniu Kresu +Randomly teleports you when eaten=Losowo teleportuje przy zjedzeniu +Guides the way to the mysterious End dimension=Prowadzi do tajemniczego wymiaru Kresu +End Crystal=Kryształ Kresu +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.=Kryształy kresu to wybuchowe narzędzia. Mogą być postawione na obsydianie bądź skale macierzystej. Zapal je uderzeniem bądź strzałą. Kryształy kresu mogą być również wykorzystane do przywołania smoka Kresu, jeśli ułoży się po jednym na każdym boku Portalu wyjścia z Kresu. +Explosion radius: @1=Promień wybuchu: @1 +Ignited by a punch or a hit with an arrow=Zapalane przez uderzenie lub strzałę +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.=Postaw kryształ na obsydianie lub skale macierzystej, a następnie uderz bądź strzel w niego strzałą, aby wywołać dużą, prawdopodobnie śmiertelną, eksplozję. Aby przywołać smoka Kresu postaw po jednej na każdym boku Portalu wyjścia z Kresu. diff --git a/mods/ITEMS/mcl_end/mod.conf b/mods/ITEMS/mcl_end/mod.conf new file mode 100644 index 000000000..021417e86 --- /dev/null +++ b/mods/ITEMS/mcl_end/mod.conf @@ -0,0 +1,2 @@ +name = mcl_end +depends = screwdriver, mcl_sounds, mcl_util, doc_items, mcl_worlds, mcl_structures \ No newline at end of file diff --git a/mods/ITEMS/mcl_end/models/mcl_end_crystal.png b/mods/ITEMS/mcl_end/models/mcl_end_crystal.png deleted file mode 100644 index 13e12c2ea..000000000 Binary files a/mods/ITEMS/mcl_end/models/mcl_end_crystal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower.png b/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower.png deleted file mode 100644 index 47798ba0b..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower_dead.png b/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower_dead.png deleted file mode 100644 index 88f798cd9..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_flower_dead.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_plant.png b/mods/ITEMS/mcl_end/textures/mcl_end_chorus_plant.png deleted file mode 100644 index afde6feec..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_plant.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_crystal_item.png b/mods/ITEMS/mcl_end/textures/mcl_end_crystal_item.png deleted file mode 100644 index e0eeac6a5..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_crystal_item.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_dragon_egg.png b/mods/ITEMS/mcl_end/textures/mcl_end_dragon_egg.png deleted file mode 100644 index c50d8f23d..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_dragon_egg.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_end_stone.png b/mods/ITEMS/mcl_end/textures/mcl_end_end_stone.png deleted file mode 100644 index 2254f82e7..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_end_stone.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_endframe_side.png b/mods/ITEMS/mcl_end/textures/mcl_end_endframe_side.png deleted file mode 100644 index a2370ecef..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_endframe_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar.png b/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar.png deleted file mode 100644 index 4b7efbd08..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar.png and /dev/null differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar_top.png b/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar_top.png deleted file mode 100644 index 752e77bc1..000000000 Binary files a/mods/ITEMS/mcl_end/textures/mcl_end_purpur_pillar_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/README.txt b/mods/ITEMS/mcl_farming/README.txt index 5779d7035..02cdaf93a 100644 --- a/mods/ITEMS/mcl_farming/README.txt +++ b/mods/ITEMS/mcl_farming/README.txt @@ -1,16 +1,12 @@ ===FARMING MOD for MINETEST-C55=== by PilzAdam +Modified heavily by MineClone 2 Dev Team. + Introduction: This mod adds farming to Minetest. -How to install: -Unzip the archive an place it in minetest-base-directory/mods/minetest/ -if you have a windows client or a linux run-in-place client. If you have -a linux system-wide instalation place it in ~/.minetest/mods/minetest/. -If you want to install this mod only in one world create the folder -worldmods/ in your worlddirectory. -For further information or help see: +How to install see: http://wiki.minetest.com/wiki/Installing_Mods How to use the mod: @@ -25,22 +21,8 @@ For further information or help see: http://minetest.net/forum/viewtopic.php?id=2787 License: -Sourcecode: WTFPL (see below) -Graphics: WTFPL (see below) +Sourcecode: CC-BY-SA 4 (see below) +Graphics: CC-BY-SA 4 (see below) See also: http://minetest.net/ - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - Version 2, December 2004 - - Copyright (C) 2004 Sam Hocevar - - Everyone is permitted to copy and distribute verbatim or modified - copies of this license document, and changing it is allowed as long - as the name is changed. - - DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/mods/ITEMS/mcl_farming/beetroot.lua b/mods/ITEMS/mcl_farming/beetroot.lua index 7caf5103e..3785db111 100644 --- a/mods/ITEMS/mcl_farming/beetroot.lua +++ b/mods/ITEMS/mcl_farming/beetroot.lua @@ -1,11 +1,11 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_craftitem("mcl_farming:beetroot_seeds", { description = S("Beetroot Seeds"), _tt_help = S("Grows on farmland"), _doc_items_longdesc = S("Grows into a beetroot plant. Chickens like beetroot seeds."), _doc_items_usagehelp = S("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."), - groups = { craftitem=1 }, + groups = {craftitem = 1, compostability = 30}, inventory_image = "mcl_farming_beetroot_seeds.png", wield_image = "mcl_farming_beetroot_seeds.png", on_place = function(itemstack, placer, pointed_thing) @@ -54,7 +54,7 @@ minetest.register_node("mcl_farming:beetroot_1", { selection_box = { type = "fixed", fixed = { - {-0.5, -0.5, -0.5, 0.5, -3/16, 0.5} + {-0.5, -0.5, -0.5, 0.5, -4/16, 0.5} }, }, 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}, @@ -78,7 +78,7 @@ minetest.register_node("mcl_farming:beetroot_2", { selection_box = { type = "fixed", fixed = { - {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5} + {-0.5, -0.5, -0.5, 0.5, -3/16, 0.5} }, }, 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}, @@ -102,22 +102,34 @@ minetest.register_node("mcl_farming:beetroot", { 0 seeds: 42.18% 1 seed: 14.06% 2 seeds: 18.75% - 3 seeds: 25% ]] + 3 seeds: 25% + + correction: should always drop at least 1 seed. (1-4 seeds, per the minecraft wiki) + --]] max_items = 2, items = { - { items = {"mcl_farming:beetroot_item"}, rarity = 1 }, - { items = {"mcl_farming:beetroot_seeds 3"}, rarity = 4 }, - { items = {"mcl_farming:beetroot_seeds 2"}, rarity = 4 }, - { items = {"mcl_farming:beetroot_seeds 1"}, rarity = 4 }, + {items = {"mcl_farming:beetroot_item"}}, + {items = {"mcl_farming:beetroot_seeds 4"}, rarity = 6}, + {items = {"mcl_farming:beetroot_seeds 3"}, rarity = 4}, + {items = {"mcl_farming:beetroot_seeds 2"}, rarity = 3}, + {items = {"mcl_farming:beetroot_seeds"}, rarity = 1}, }, }, + + _mcl_fortune_drop = { + discrete_uniform_distribution = true, + items = {"mcl_farming:beetroot_seeds"}, + min_count = 1, + max_count = 3, + cap = 5, + }, tiles = {"mcl_farming_beetroot_3.png"}, inventory_image = "mcl_farming_beetroot_3.png", wield_image = "mcl_farming_beetroot_3.png", selection_box = { type = "fixed", fixed = { - {-0.5, -0.5, -0.5, 0.5, 3/16, 0.5} + {-0.5, -0.5, -0.5, 0.5, -1/16, 0.5} }, }, 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,beetroot=4}, @@ -133,7 +145,7 @@ minetest.register_craftitem("mcl_farming:beetroot_item", { wield_image = "mcl_farming_beetroot.png", on_place = minetest.item_eat(1), on_secondary_use = minetest.item_eat(1), - groups = { food = 2, eatable = 1 }, + groups = {food = 2, eatable = 1, compostability = 65}, _mcl_saturation = 1.2, }) @@ -161,7 +173,10 @@ minetest.register_craft({ mcl_farming:add_plant("plant_beetroot", "mcl_farming:beetroot", {"mcl_farming:beetroot_0", "mcl_farming:beetroot_1", "mcl_farming:beetroot_2"}, 68, 3) if minetest.get_modpath("doc") then - for i=1,2 do - doc.add_entry_alias("nodes", "mcl_farming:beetroot_0", "nodes", "mcl_farming:beetroot_"..i) + for i = 1, 2 do + doc.add_entry_alias("nodes", "mcl_farming:beetroot_0", "nodes", "mcl_farming:beetroot_" .. i) end end + +minetest.register_alias("beetroot_seeds", "mcl_farming:beetroot_seeds") +minetest.register_alias("beetroot", "mcl_farming:beetroot_item") diff --git a/mods/ITEMS/mcl_farming/carrots.lua b/mods/ITEMS/mcl_farming/carrots.lua index 4599d39ee..f21285445 100644 --- a/mods/ITEMS/mcl_farming/carrots.lua +++ b/mods/ITEMS/mcl_farming/carrots.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) for i=1, 7 do local texture, sel_height @@ -6,10 +6,10 @@ for i=1, 7 do sel_height = -5/16 texture = "farming_carrot_1.png" elseif i < 5 then - sel_height = -3/16 + sel_height = -4/16 texture = "farming_carrot_2.png" else - sel_height = 2/16 + sel_height = -3/16 texture = "farming_carrot_3.png" end @@ -63,16 +63,16 @@ minetest.register_node("mcl_farming:carrot", { drop = { max_items = 1, items = { - { items = {'mcl_farming:carrot_item 4'}, rarity = 5 }, - { items = {'mcl_farming:carrot_item 3'}, rarity = 2 }, - { items = {'mcl_farming:carrot_item 2'}, rarity = 2 }, - { items = {'mcl_farming:carrot_item 1'} }, + { items = {"mcl_farming:carrot_item 4"}, rarity = 5 }, + { items = {"mcl_farming:carrot_item 3"}, rarity = 2 }, + { items = {"mcl_farming:carrot_item 2"}, rarity = 2 }, + { items = {"mcl_farming:carrot_item 1"} }, } }, selection_box = { type = "fixed", fixed = { - {-0.5, -0.5, -0.5, 0.5, 4/16, 0.5} + {-0.5, -0.5, -0.5, 0.5, -1/16, 0.5} }, }, 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}, @@ -86,17 +86,10 @@ minetest.register_craftitem("mcl_farming:carrot_item", { _doc_items_longdesc = S("Carrots can be eaten and planted. Pigs and rabbits like carrots."), _doc_items_usagehelp = S("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."), inventory_image = "farming_carrot.png", - groups = { food = 2, eatable = 3 }, + groups = {food = 2, eatable = 3, compostability = 65}, _mcl_saturation = 3.6, on_secondary_use = minetest.item_eat(3), - on_place = function(itemstack, placer, pointed_thing) - local new = mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:carrot_1") - if new ~= nil then - return new - else - return minetest.do_item_eat(3, nil, itemstack, placer, pointed_thing) - end - end, + on_place = mcl_farming:get_seed_or_eat_callback("mcl_farming:carrot_1", 3), }) minetest.register_craftitem("mcl_farming:carrot_item_gold", { @@ -112,9 +105,9 @@ minetest.register_craftitem("mcl_farming:carrot_item_gold", { minetest.register_craft({ output = "mcl_farming:carrot_item_gold", recipe = { - {'mcl_core:gold_nugget', 'mcl_core:gold_nugget', 'mcl_core:gold_nugget'}, - {'mcl_core:gold_nugget', 'mcl_farming:carrot_item', 'mcl_core:gold_nugget'}, - {'mcl_core:gold_nugget', 'mcl_core:gold_nugget', 'mcl_core:gold_nugget'}, + {"mcl_core:gold_nugget", "mcl_core:gold_nugget", "mcl_core:gold_nugget"}, + {"mcl_core:gold_nugget", "mcl_farming:carrot_item", "mcl_core:gold_nugget"}, + {"mcl_core:gold_nugget", "mcl_core:gold_nugget", "mcl_core:gold_nugget"}, } }) diff --git a/mods/ITEMS/mcl_farming/depends.txt b/mods/ITEMS/mcl_farming/depends.txt deleted file mode 100644 index 0ed4f3f58..000000000 --- a/mods/ITEMS/mcl_farming/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_core -mcl_sounds -mcl_wool -mcl_torches -mcl_weather -mcl_armor? -mobs_mc -doc? diff --git a/mods/ITEMS/mcl_farming/hoes.lua b/mods/ITEMS/mcl_farming/hoes.lua index 0a483f304..72d8f7b7a 100644 --- a/mods/ITEMS/mcl_farming/hoes.lua +++ b/mods/ITEMS/mcl_farming/hoes.lua @@ -1,255 +1,299 @@ -local S = minetest.get_translator("mcl_farming") - -local function create_soil(pos, inv) - if pos == nil then - return false - end - local node = minetest.get_node(pos) - local name = node.name - local above = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) - if minetest.get_item_group(name, "cultivatable") == 2 then - if above.name == "air" then - node.name = "mcl_farming:soil" - minetest.set_node(pos, node) - minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.5 }, true) - return true - end - elseif minetest.get_item_group(name, "cultivatable") == 1 then - if above.name == "air" then - node.name = "mcl_core:dirt" - minetest.set_node(pos, node) - minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.6 }, true) - return true - end - end - return false -end - -local hoe_on_place_function = function(wear_divisor) - return function(itemstack, user, pointed_thing) - -- Call on_rightclick if the pointed node defines it - 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 - - if minetest.is_protected(pointed_thing.under, user:get_player_name()) then - minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) - return itemstack - end - - 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) - end - return itemstack - end - end -end - -local uses = { - wood = 60, - stone = 132, - iron = 251, - gold = 33, +local S = minetest.get_translator(minetest.get_current_modname()) + +local function create_soil(pos, inv) + if pos == nil then + return false + end + local node = minetest.get_node(pos) + local name = node.name + local above = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) + if minetest.get_item_group(name, "cultivatable") == 2 then + if above.name == "air" then + node.name = "mcl_farming:soil" + minetest.set_node(pos, node) + minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.5 }, true) + return true + end + elseif minetest.get_item_group(name, "cultivatable") == 1 then + if above.name == "air" then + node.name = "mcl_core:dirt" + minetest.set_node(pos, node) + minetest.sound_play("default_dig_crumbly", { pos = pos, gain = 0.6 }, true) + return true + end + end + return false +end + +local hoe_on_place_function = function(wear_divisor) + return function(itemstack, user, pointed_thing) + -- Call on_rightclick if the pointed node defines it + 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 + + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) + return itemstack + end + + 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) + end + return itemstack + end + end +end + +local uses = { + wood = 60, + stone = 132, + iron = 251, + gold = 33, diamond = 1562, -} + netherite = 2031, +} + +local hoe_tt = S("Turns block into farmland") +local hoe_longdesc = S("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.") +local hoe_usagehelp = S("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.") + +minetest.register_tool("mcl_farming:hoe_wood", { + description = S("Wood Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.wood), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + _doc_items_hidden = false, + inventory_image = "farming_tool_woodhoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.wood), + groups = { tool=1, hoe=1, enchantability=15 }, + tool_capabilities = { + full_punch_interval = 1, + damage_groups = { fleshy = 1, }, + punch_attack_uses = uses.wood, + }, + _repair_material = "group:wood", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 2, level = 1, uses = 60 } + }, +}) + +minetest.register_craft({ + output = "mcl_farming:hoe_wood", + recipe = { + {"group:wood", "group:wood"}, + {"", "mcl_core:stick"}, + {"", "mcl_core:stick"} + } +}) +minetest.register_craft({ + output = "mcl_farming:hoe_wood", + recipe = { + {"group:wood", "group:wood"}, + {"mcl_core:stick", ""}, + {"mcl_core:stick", ""} + } +}) +minetest.register_craft({ + type = "fuel", + recipe = "mcl_farming:hoe_wood", + burntime = 10, +}) + +minetest.register_tool("mcl_farming:hoe_stone", { + description = S("Stone Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.stone), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_stonehoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.stone), + groups = { tool=1, hoe=1, enchantability=5 }, + tool_capabilities = { + full_punch_interval = 0.5, + damage_groups = { fleshy = 1, }, + punch_attack_uses = uses.stone, + }, + _repair_material = "group:cobble", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 4, level = 3, uses = 132 } + }, +}) + +minetest.register_craft({ + output = "mcl_farming:hoe_stone", + recipe = { + {"group:cobble", "group:cobble"}, + {"", "mcl_core:stick"}, + {"", "mcl_core:stick"} + } +}) +minetest.register_craft({ + output = "mcl_farming:hoe_stone", + recipe = { + {"group:cobble", "group:cobble"}, + {"mcl_core:stick", ""}, + {"mcl_core:stick", ""} + } +}) + +minetest.register_tool("mcl_farming:hoe_iron", { + description = S("Iron Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.iron), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_steelhoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.iron), + groups = { tool=1, hoe=1, enchantability=14 }, + tool_capabilities = { + -- 1/3 + full_punch_interval = 0.33333333, + damage_groups = { fleshy = 1, }, + punch_attack_uses = uses.iron, + }, + _repair_material = "mcl_core:iron_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 6, level = 4, uses = 251 } + }, +}) + +minetest.register_craft({ + output = "mcl_farming:hoe_iron", + recipe = { + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"", "mcl_core:stick"}, + {"", "mcl_core:stick"} + } +}) +minetest.register_craft({ + output = "mcl_farming:hoe_iron", + recipe = { + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:stick", ""}, + {"mcl_core:stick", ""} + } +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_core:iron_nugget", + recipe = "mcl_farming:hoe_iron", + cooktime = 10, +}) + +minetest.register_tool("mcl_farming:hoe_gold", { + description = S("Golden Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.gold), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_goldhoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.gold), + groups = { tool=1, hoe=1, enchantability=22 }, + tool_capabilities = { + full_punch_interval = 1, + damage_groups = { fleshy = 1, }, + punch_attack_uses = uses.gold, + }, + _repair_material = "mcl_core:gold_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 12, level = 2, uses = 33 } + }, +}) + +minetest.register_craft({ + output = "mcl_farming:hoe_gold", + recipe = { + {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"", "mcl_core:stick"}, + {"", "mcl_core:stick"} + } +}) +minetest.register_craft({ + output = "mcl_farming:hoe_gold", + recipe = { + {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:stick", ""}, + {"mcl_core:stick", ""} + } +}) + + + +minetest.register_craft({ + type = "cooking", + output = "mcl_core:gold_nugget", + recipe = "mcl_farming:hoe_gold", + cooktime = 10, +}) + +minetest.register_tool("mcl_farming:hoe_diamond", { + description = S("Diamond Hoe"), + _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.diamond), + _doc_items_longdesc = hoe_longdesc, + _doc_items_usagehelp = hoe_usagehelp, + inventory_image = "farming_tool_diamondhoe.png", + wield_scale = mcl_vars.tool_wield_scale, + on_place = hoe_on_place_function(uses.diamond), + groups = { tool=1, hoe=1, enchantability=10 }, + tool_capabilities = { + full_punch_interval = 0.25, + damage_groups = { fleshy = 1, }, + punch_attack_uses = uses.diamond, + }, + _repair_material = "mcl_core:diamond", + _mcl_toollike_wield = true, + _mcl_diggroups = { + hoey = { speed = 8, level = 5, uses = 1562 } + }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_farming:hoe_netherite" +}) + +minetest.register_craft({ + output = "mcl_farming:hoe_diamond", + recipe = { + {"mcl_core:diamond", "mcl_core:diamond"}, + {"", "mcl_core:stick"}, + {"", "mcl_core:stick"} + } +}) +minetest.register_craft({ + output = "mcl_farming:hoe_diamond", + recipe = { + {"mcl_core:diamond", "mcl_core:diamond"}, + {"mcl_core:stick", ""}, + {"mcl_core:stick", ""} + } +}) -local hoe_tt = S("Turns block into farmland") -local hoe_longdesc = S("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.") -local hoe_usagehelp = S("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.") - -minetest.register_tool("mcl_farming:hoe_wood", { - description = S("Wood Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.wood), +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, - _doc_items_hidden = false, - inventory_image = "farming_tool_woodhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, - on_place = hoe_on_place_function(uses.wood), - groups = { tool=1, hoe=1, enchantability=15 }, - tool_capabilities = { - full_punch_interval = 1, - damage_groups = { fleshy = 1, }, - punch_attack_uses = uses.wood, - }, - _repair_material = "group:wood", -}) - -minetest.register_craft({ - output = "mcl_farming:hoe_wood", - recipe = { - {"group:wood", "group:wood"}, - {"", "mcl_core:stick"}, - {"", "mcl_core:stick"} - } -}) -minetest.register_craft({ - output = "mcl_farming:hoe_wood", - recipe = { - {"group:wood", "group:wood"}, - {"mcl_core:stick", ""}, - {"mcl_core:stick", ""} - } -}) -minetest.register_craft({ - type = "fuel", - recipe = "mcl_farming:hoe_wood", - burntime = 10, -}) - -minetest.register_tool("mcl_farming:hoe_stone", { - description = S("Stone Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.stone), - _doc_items_longdesc = hoe_longdesc, - _doc_items_usagehelp = hoe_usagehelp, - inventory_image = "farming_tool_stonehoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, - on_place = hoe_on_place_function(uses.stone), - groups = { tool=1, hoe=1, enchantability=5 }, - tool_capabilities = { - full_punch_interval = 0.5, - damage_groups = { fleshy = 1, }, - punch_attack_uses = uses.stone, - }, - _repair_material = "mcl_core:cobblestone", -}) - -minetest.register_craft({ - output = "mcl_farming:hoe_stone", - recipe = { - {"mcl_core:cobble", "mcl_core:cobble"}, - {"", "mcl_core:stick"}, - {"", "mcl_core:stick"} - } -}) -minetest.register_craft({ - output = "mcl_farming:hoe_stone", - recipe = { - {"mcl_core:cobble", "mcl_core:cobble"}, - {"mcl_core:stick", ""}, - {"mcl_core:stick", ""} - } -}) - -minetest.register_tool("mcl_farming:hoe_iron", { - description = S("Iron Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.iron), - _doc_items_longdesc = hoe_longdesc, - _doc_items_usagehelp = hoe_usagehelp, - inventory_image = "farming_tool_steelhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, - on_place = hoe_on_place_function(uses.iron), - groups = { tool=1, hoe=1, enchantability=14 }, - tool_capabilities = { - -- 1/3 - full_punch_interval = 0.33333333, - damage_groups = { fleshy = 1, }, - punch_attack_uses = uses.iron, - }, - _repair_material = "mcl_core:iron_ingot", -}) - -minetest.register_craft({ - output = "mcl_farming:hoe_iron", - recipe = { - {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, - {"", "mcl_core:stick"}, - {"", "mcl_core:stick"} - } -}) -minetest.register_craft({ - output = "mcl_farming:hoe_iron", - recipe = { - {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, - {"mcl_core:stick", ""}, - {"mcl_core:stick", ""} - } -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_core:iron_nugget", - recipe = "mcl_farming:hoe_iron", - cooktime = 10, -}) - -minetest.register_tool("mcl_farming:hoe_gold", { - description = S("Golden Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.gold), - _doc_items_longdesc = hoe_longdesc, - _doc_items_usagehelp = hoe_usagehelp, - inventory_image = "farming_tool_goldhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, - on_place = hoe_on_place_function(uses.gold), - groups = { tool=1, hoe=1, enchantability=22 }, - tool_capabilities = { - full_punch_interval = 1, - damage_groups = { fleshy = 1, }, - punch_attack_uses = uses.gold, - }, - _repair_material = "mcl_core:gold_ingot", -}) - -minetest.register_craft({ - output = "mcl_farming:hoe_gold", - recipe = { - {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, - {"", "mcl_core:stick"}, - {"", "mcl_core:stick"} - } -}) -minetest.register_craft({ - output = "mcl_farming:hoe_gold", - recipe = { - {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, - {"mcl_core:stick", ""}, - {"mcl_core:stick", ""} - } -}) - - - -minetest.register_craft({ - type = "cooking", - output = "mcl_core:gold_nugget", - recipe = "mcl_farming:hoe_gold", - cooktime = 10, -}) - -minetest.register_tool("mcl_farming:hoe_diamond", { - description = S("Diamond Hoe"), - _tt_help = hoe_tt.."\n"..S("Uses: @1", uses.diamond), - _doc_items_longdesc = hoe_longdesc, - _doc_items_usagehelp = hoe_usagehelp, - inventory_image = "farming_tool_diamondhoe.png", - wield_scale = { x = 1.8, y = 1.8, z = 1 }, - on_place = hoe_on_place_function(uses.diamond), - groups = { tool=1, hoe=1, enchantability=10 }, + 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 = 1, }, - punch_attack_uses = uses.diamond, + 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 } }, - _repair_material = "mcl_core:diamond", -}) - -minetest.register_craft({ - output = "mcl_farming:hoe_diamond", - recipe = { - {"mcl_core:diamond", "mcl_core:diamond"}, - {"", "mcl_core:stick"}, - {"", "mcl_core:stick"} - } -}) -minetest.register_craft({ - output = "mcl_farming:hoe_diamond", - recipe = { - {"mcl_core:diamond", "mcl_core:diamond"}, - {"mcl_core:stick", ""}, - {"mcl_core:stick", ""} - } }) diff --git a/mods/ITEMS/mcl_farming/init.lua b/mods/ITEMS/mcl_farming/init.lua index adce058ee..60b10105d 100644 --- a/mods/ITEMS/mcl_farming/init.lua +++ b/mods/ITEMS/mcl_farming/init.lua @@ -27,3 +27,6 @@ dofile(minetest.get_modpath("mcl_farming").."/potatoes.lua") -- ========= BEETROOT ========= dofile(minetest.get_modpath("mcl_farming").."/beetroot.lua") + +-- ========= SWEET BERRY ========= +dofile(minetest.get_modpath("mcl_farming").."/sweet_berry.lua") diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr index 5ee1bcdfc..5b14b109b 100644 --- a/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.fr.tr @@ -1,93 +1,97 @@ # textdomain: mcl_farming -Beetroot Seeds=Graines de Betterave -Grows into a beetroot plant. Chickens like beetroot seeds.=Pousse en bettrave. Les poulets aiment les graines de betterave +Beetroot Seeds=Graines de betterave +Grows into a beetroot plant. Chickens like beetroot seeds.=Pousse en betterave. Les poulets aiment les graines de betterave. 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.=Placez les graines de betterave sur les terres agricoles (qui peuvent être créées avec une houe) pour planter un plant de betterave. Elles poussent au soleil et poussent plus vite sur les terres agricoles hydratées. Faites un clic droit sur un animal pour le nourrir de graines de betteraves. 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.=Les plants de betteraves poussent sur les terres agricoles sous le soleil en 4 étapes. Sur les terres agricoles hydratées, elles poussent un peu plus vite. Elles peuvent être récoltées à tout moment mais ne rapporteront de bénéfices qu'à maturité. -Premature Beetroot Plant=Plant de Betterave Prématurée -Premature Beetroot Plant (Stage 1)=Plant de Betterave Prématurée (Etape 1) -Premature Beetroot Plant (Stage 2)=Plant de Betterave Prématurée (Etape 2) -Premature Beetroot Plant (Stage 3)=Plant de Betterave Prématurée (Etape 3) -Mature Beetroot Plant=Betterave Mature -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.=Une betterave mature est une plante agricole prête à être récoltée pour une betterave et quelques graines de betterave. Elle ne grandira plus. +Premature Beetroot Plant=Plant de betterave prématuré +Premature Beetroot Plant (Stage 1)=Plant de betterave prématuré (étape 1) +Premature Beetroot Plant (Stage 2)=Plant de betterave prématuré (étape 2) +Premature Beetroot Plant (Stage 3)=Plant de betterave prématuré (étape 3) +Mature Beetroot Plant=Plant de betterave mature +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.=Un plant de betterave mature est une plante agricole prête à être récoltée pour une betterave et quelques graines de betterave. Elle ne grandira plus. Beetroot=Betterave Beetroots are both used as food item and a dye ingredient. Pigs like beetroots, too.=Les betteraves sont à la fois utilisées comme aliment et comme ingrédient colorant. Les porcs aiment aussi les betteraves. Hold it in your hand and right-click to eat it. Rightclick an animal to feed it.=Tenez-le dans votre main et faites un clic droit pour le manger. Faites un clic droit sur un animal pour le nourrir. -Beetroot Soup=Soupe de Betterave +Beetroot Soup=Soupe de betterave Beetroot soup is a food item.=La soupe de betterave est un aliment. -Premature Carrot Plant=Plant de Carrote Prématurée +Premature Carrot Plant=Plant de carotte prématuré 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.=Les plants de carotte sont des plantes qui poussent sur les terres agricoles sous la lumière du soleil en 8 étapes, mais seulement 4 étapes peuvent être distinguées visuellement. Sur les terres agricoles hydratées, elles poussent un peu plus vite. Ils peuvent être récoltés à tout moment mais ne rapporteront de bénéfices qu'à maturité. -Premature Carrot Plant (Stage @1)=Plant de Carrote Prématurée (Etape 1) -Mature Carrot Plant=Plant de Carotte Mature +Premature Carrot Plant (Stage @1)=Plant de carotte prématuré (étape @1) +Mature Carrot Plant=Plant de carotte mature Mature carrot plants are ready to be harvested for carrots. They won't grow any further.=Les plants de carottes matures sont prêts à être récoltés pour les carottes. Ils ne grandiront plus. -Carrot=Carrotte -Carrots can be eaten and planted. Pigs and rabbits like carrots.=Les carottes peuvent être mangées et plantées. Les cochons et les lapins comme les carottes. +Carrot=Carotte +Carrots can be eaten and planted. Pigs and rabbits like carrots.=Les carottes peuvent être mangées et plantées. Les cochons et les lapins aiment les carottes. 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.=Tenez-la dans votre main et faites un clic droit pour le manger. Placez-le au-dessus des terres agricoles pour planter la carotte. Elle pousse au soleil et pousse plus vite sur les terres agricoles hydratées. Faites un clic droit sur un animal pour le nourrir. -Golden Carrot=Carrot Dorée -A golden carrot is a precious food item which can be eaten. It is really, really filling!=Une carotte dorée est un aliment précieux qui peut être mangé. C'est vraiment, vraiment rassasiant! +Golden Carrot=Carotte dorée +A golden carrot is a precious food item which can be eaten. It is really, really filling!=Une carotte dorée est un aliment précieux qui peut être mangé. C'est vraiment, vraiment rassasiant ! 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.=Les houes sont des outils essentiels pour faire pousser des cultures. Ils sont utilisés pour créer des terres agricoles afin d'y planter des graines. Les houes peuvent également être utilisées comme armes très faibles à la rigueur. 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.=Utilisez la houe sur un bloc cultivable (en cliquant dessus avec le bouton droit) pour le transformer en terre agricole. La saleté, les blocs d'herbe et les chemins d'herbe sont des blocs cultivables. L'utilisation d'une houe sur la terre grossière la transforme en terre. -Wood Hoe=Houe en Bois -Stone Hoe=Houe en Pierre -Iron Hoe=Houe en Fer -Golden Hoe=Houe en Or -Diamond Hoe=Houe en Diamant -Melon Seeds=Graine de Pastèque +Wood Hoe=Houe en bois +Stone Hoe=Houe en pierre +Iron Hoe=Houe en fer +Golden Hoe=Houe en or +Diamond Hoe=Houe en diamant +Netherite Hoe=Houe en netherite +Melon Seeds=Graine de pastèque Grows into a melon stem which in turn grows melons. Chickens like melon seeds.=Se développe en une tige de pastèque qui à son tour forme des pastèques. Les poulets aiment les graines de pastèque. 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.=Placez les graines de pastèque sur les terres agricoles (qui peuvent être créées avec une houe) pour planter une tige de pastèque. Les tiges de pastèque poussent au soleil et se développent plus rapidement sur les terres agricoles hydratées. À maturité, la tige tentera de faire pousser une pastèque sur le côté. Faites un clic droit sur un animal pour le nourrir de graines de pastèque. Melon=Pastèque 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.=Une pastèque est un bloc qui peut être cultivé à partir de tiges de pastèque, qui à leur tour sont cultivées à partir de graines de pastèque. Elle peut être récoltée pour des tranches de pastèque. -Premature Melon Stem=Tige de Pastèque Prématurée +Premature Melon Stem=Tige de pastèque prématurée 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.=Les tiges de pastèque poussent sur les terres agricoles en 8 étapes. Sur les terres agricoles hydratées, la croissance est un peu plus rapide. Les tiges de pastèque matures sont capables de faire pousser des pastèques. -Premature Melon Stem (Stage @1)=Tige de Pastèque Prématurée (Etape @1) -Mature Melon Stem=Tige de Pastèque Mature +Premature Melon Stem (Stage @1)=Tige de pastèque prématurée (étape @1) +Mature Melon Stem=Tige de pastèque mature 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.=Une tige de pastèque mature tente de faire pousser un pastèque sur l'un de ses quatre blocs adjacents. Une pastèque ne peut pousser que sur des terres agricoles, de la terre ou un bloc d'herbe. Lorsqu'une pastèque est à côté d'une tige de pastèque, la tige de pastèque se plie immédiatement et se connecte au melon. Lorsqu'elle est connectée, une tige de pastèque ne peut pas faire pousser une autre pastèque. Dès que tous les pastèques autour de la tige ont été supprimés, elle perd la connexion et est prêt à faire pousser une autre pastèque. -Melon Slice=Tranche de Pastèque +Melon Slice=Tranche de pastèque This is a food item which can be eaten.=Il s'agit d'un aliment qui peut être mangé. -Premature Potato Plant=Plant de Pomme de Terre Prématuré +Premature Potato Plant=Plant de pomme de terre prématuré 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.=Les plants de pommes de terre sont des plants qui poussent sur les terres agricoles sous la lumière du soleil en 8 étapes, mais seulement 4 étapes peuvent être distinguées visuellement. Sur les terres agricoles hydratées, elles poussent un peu plus vite. Ils peuvent être récoltés à tout moment mais ne rapporteront de bénéfices qu'à maturité. -Premature Potato Plant (Stage @1)=Plant de pomme de terre prématuré (Etape @1) -Mature Potato Plant=Plant de Pomme de Terre Mature +Premature Potato Plant (Stage @1)=Plant de pomme de terre prématuré (étape @1) +Mature Potato Plant=Plant de pomme de terre mature Mature potato plants are ready to be harvested for potatoes. They won't grow any further.=Les plants de pommes de terre matures sont prêts à être récoltés pour les pommes de terre. Ils ne grandiront plus. Potato=Pomme de terre Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes.=Les pommes de terre sont des aliments qui peuvent être consommés, cuits au four et plantés. Des porcs comme des pommes de terre. 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.=Tenez-le dans votre main et faites un clic droit pour le manger. Placez-le au-dessus des terres agricoles pour le planter. Il pousse au soleil et pousse plus vite sur les terres agricoles hydratées. Faites un clic droit sur un animal pour le nourrir. -Baked Potato=Pomme de Terre au Four +Baked Potato=Pomme de terre au four Baked potatoes are food items which are more filling than the unbaked ones.=Les pommes de terre au four sont des aliments qui sont plus copieux que ceux non cuits. -Poisonous Potato=Pomme de Terre Toxique +Poisonous Potato=Pomme de terre toxique 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.=Cette pomme de terre n'a pas l'air trop saine. Vous pouvez le manger pour restaurer des points de faim, mais il y a 60% de chances qu'il vous empoisonne brièvement. -Pumpkin Seeds=Graines de Citrouille -Grows into a pumpkin stem which in turn grows pumpkins. Chickens like pumpkin seeds.=Pousse dans une tige de citrouille qui à son tour fait pousser des citrouilles. Les poulets aiment des graines de citrouille. +Pumpkin Seeds=Graines de citrouille +Grows into a pumpkin stem which in turn grows pumpkins. Chickens like pumpkin seeds.=Pousse en une tige de citrouille qui à son tour fait pousser des citrouilles. Les poulets aiment des graines de citrouille. 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.=Placez les graines de citrouille sur les terres agricoles (qui peuvent être créées avec une houe) pour planter une tige de citrouille. Les tiges de citrouille poussent au soleil et poussent plus vite sur les terres agricoles hydratées. À maturité, la tige tente de faire pousser une citrouille à côté d'elle. Faites un clic droit sur un animal pour le nourrir de graines de citrouille. -Premature Pumpkin Stem=Tige de Citrouille Prématurée +Premature Pumpkin Stem=Tige de citrouille prématurée 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.=Les tiges de citrouille poussent sur les terres agricoles en 8 étapes. Sur les terres agricoles hydratées, la croissance est un peu plus rapide. Les tiges de citrouille matures peuvent faire pousser des citrouilles. -Premature Pumpkin Stem (Stage @1)=Tige de Citrouille Prématurée (Etape @1) -Mature Pumpkin Stem=Tige de Citrouille Mature +Premature Pumpkin Stem (Stage @1)=Tige de citrouille prématurée (étape @1) +Mature Pumpkin Stem=Tige de citrouille mature 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.=Une tige de citrouille mature tente de faire pousser une citrouille dans l'un de ses quatre blocs adjacents. Une citrouille ne peut pousser que sur des terres agricoles, de la terre ou un bloc d'herbe. Lorsqu'une citrouille est à côté d'une tige de citrouille, la tige de citrouille se plie immédiatement et se connecte à la citrouille. Une tige de citrouille connectée ne peut pas faire pousser une autre citrouille. Dès que toutes les citrouilles autour de la tige ont été retirées, elle perd la connexion et est prête à faire pousser une autre citrouille. Faceless Pumpkin=Citrouille sans visage A faceless pumpkin is a decorative block. It can be carved with shears to obtain pumpkin seeds.=Une citrouille sans visage est un bloc décoratif. Il peut être sculpté avec une cisaille pour obtenir des graines de citrouille. Pumpkin=Citrouille A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.=Une citrouille peut être portée comme un casque. Les citrouilles poussent à partir de tiges de citrouille, qui à leur tour poussent à partir de graines de citrouille. Jack o'Lantern=Citrouille-lanterne -A jack o'lantern is a traditional Halloween decoration made from a pumpkin. It glows brightly.=Une citrouille-lanterne est une décoration traditionnelle d'Halloween à base de citrouille. Il brille de mille feux. -Pumpkin Pie=Tarte à la Citrouille +A jack o'lantern is a traditional Halloween decoration made from a pumpkin. It glows brightly.=Une citrouille-lanterne est une décoration traditionnelle d'Halloween à base de citrouille. Elle brille de mille feux. +Pumpkin Pie=Tarte à la citrouille A pumpkin pie is a tasty food item which can be eaten.=Une tarte à la citrouille est un aliment savoureux qui peut être mangé. -Farmland=Terres Agricoles +Farmland=Terres agricoles 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.=Les terres agricoles sont utilisées pour l'agriculture, une surface nécessaire pour planter des cultures. Il est créé lorsqu'une houe est utilisée sur de la terre ou un bloc similaire. Les plantes peuvent pousser sur les terres agricoles, mais lentement. Les terres agricoles deviendront des terres agricoles hydratées (sur lesquelles les plantes poussent plus rapidement) lorsqu'il pleut ou lorsqu'une source d'eau est à proximité. Ce bloc redeviendra de la terre lorsqu'un bloc solide apparaît au-dessus ou qu'un bras de piston s'étend au-dessus. -Hydrated Farmland=Terres Agricoles Hydratées +Hydrated Farmland=Terres agricoles hydratées 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.=Les terres agricoles hydratées sont utilisées dans l'agriculture, c'est là que vous pouvez planter et faire pousser certaines plantes. Il est créé lorsque les terres agricoles sont sous la pluie ou près de l'eau. Sans eau, ce bloc finira par se dessécher. Ce bloc redeviendra de la terre lorsqu'un bloc solide apparaît au-dessus ou qu'un bras de piston s'étend au-dessus. Wheat Seeds=Graines de blé Grows into a wheat plant. Chickens like wheat seeds.=Se transforme en blé. Les poulets aiment les graines de blé. -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.=Placez les graines de blé sur les terres agricoles (qui peuvent être créées avec une houe) pour planter une plante de blé. Ils poussent au soleil et poussent plus vite sur les terres agricoles hydratées. Faites un clic droit sur un animal pour le nourrir de graines de blé. -Premature Wheat Plant=Plant de Blé Prématurée -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.=Les plants de blé prématurés poussent sur les terres agricoles sous la lumière du soleil en 8 étapes. Sur les terres agricoles hydratées, ils croissent plus rapidement. Ils peuvent être récoltés à tout moment mais ne rapporteront de bénéfices qu'à maturité. -Premature Wheat Plant (Stage @1)=Plant de blé prématurée (Etape @1) -Mature Wheat Plant=Plant de Blé Maturée -Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further.=Les plants de blé matures sont prêts à être récoltés pour le blé et les graines de blé. Ils ne grandiront plus. +Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant.=Placez les graines de blé sur les terres agricoles (qui peuvent être créées avec une houe) pour planter une plante de blé. +They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds.=Ils poussent au soleil et poussent plus vite sur les terres agricoles hydratées. Faites un clic droit sur un animal pour le nourrir de graines de blé. +Premature Wheat Plant=Plant de blé Prématuré +Premature wheat plants grow on farmland under sunlight in 8 stages.=Les plants de blé prématurés poussent sur les terres agricoles sous la lumière du soleil en 8 étapes. +On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.=Sur les terres agricoles hydratées, ils croissent plus rapidement. Ils peuvent être récoltés à tout moment mais ne rapporteront de bénéfices qu'à maturité. +Premature Wheat Plant (Stage @1)=Plant de blé prématuré (étape @1) +Mature Wheat Plant=Plant de blé mature +Mature wheat plants are ready to be harvested for wheat and wheat seeds.=Les plants de blé matures sont prêts à être récoltés pour le blé et les graines de blé. +They won't grow any further.=Ils ne grandiront plus. Wheat=Blé Wheat is used in crafting. Some animals like wheat.=Le blé est utilisé dans l'artisanat. Certains animaux aiment le blé. Cookie=Cookie Bread=Pain -Hay Bale=Balle de Foin +Hay Bale=Balle de foin Hay bales are decorative blocks made from wheat.=Les balles de foin sont des blocs décoratifs en blé. 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é. @@ -96,4 +100,6 @@ Turns block into farmland=Transforme un bloc en terres agricoles 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 +Uses: @1=Utilisations : @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.ja.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.ja.tr new file mode 100644 index 000000000..d50c49911 --- /dev/null +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.ja.tr @@ -0,0 +1,99 @@ +# 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.=ビートルートの種を耕地(クワで作れる)に置いて植え、ビートルートの苗にします。日光に当たると成長し、湿った耕地ではより早く成長します。動物を右クリックすると、ビートルートの種を食べさせることができます。 +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.=成熟したビートルートの苗は、ビートルートとその種をいくつか収穫できる農作物です。これ以上は成長しません。 +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.=ビートルートスープは食料アイテムです。 +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段階だけです。湿った耕地では、やや早く成長します。収穫はいつでも可能なものの、益があるのは成熟してからです。 +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.=手に持って右クリックすると食べます。耕地に置くとニンジンを植えます。日光で育ち、湿った耕地では早く育ちます。動物を右クリックすると餌付けできます。 +Golden Carrot=金のニンジン +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.=耕せるブロックに(右クリックで)クワを使うと耕地になります。土、草原、オフロードは耕せるブロックです。粗い土にクワを使うと、土になります。 +Wood Hoe=木製のクワ +Stone Hoe=石のクワ +Iron Hoe=鉄のクワ +Golden Hoe=金のクワ +Diamond 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.=成熟したスイカの茎は、隣接する4つのブロックのいずれかでスイカを実らせようとします。実るのは、耕地、土、草原の上だけです。スイカの茎の隣にスイカがあると、茎はすぐに曲がってスイカにつながります。つながっている間は、他のスイカを実らせられません。茎の周りのスイカをすべて取り除くと、接続が切れて次のスイカが実るようになります。 +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.=手に持って右クリックすると食べます。耕地に置くとジャガイモを植えます。日光で育ち、湿った耕地では早く育ちます。動物を右クリックすると餌付けできます。 +Baked Potato=ベイクドポテト +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%あります。 +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.=カボチャの種を耕地(クワで作れる)に置いて植え、カボチャの茎にします。茎は日光で育ち、湿った耕地では早く育ちます。成熟すると、茎の隣にカボチャを実らせようとします。動物を右クリックすると、カボチャの種を食べさせることができます。 +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.=成熟したカボチャの茎は、隣接する4つのブロックのいずれかでカボチャを実らせようとします。実るのは、耕地、土、草原の上だけです。カボチャの茎の隣にカボチャがあると、茎はすぐに曲がってカボチャにつながります。つながっている間は、他のカボチャを実らせられません。茎の周りのカボチャをすべて取り除くと、接続が切れて次のカボチャが実るようになります。 +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.=パンプキンパイは、美味しくいただける食料アイテムです。 +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.=耕地とは農業に使うもので、作物の栽培に必要な地面のことです。土やそれに近いブロックの上でクワを使うとできます。たんなる耕地の上でも植物は育ちますが、そのスピードはゆるやかです。雨が降ったり、水源が近くにあったりすると、耕地は「湿った耕地」となります(植物の成長が早くなります)。上に固体ブロックが現れたり、上にピストンアームが伸びたりすると、このブロックは土に戻ります。 +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.=湿った耕地は農業に使われるもので、ここに何らかの作物を植えて育てられます。耕地が雨に降られたり水辺にある場合、これが出来上がります。水がなければ、やがて乾いてしまいます。上に固体ブロックが現れたり、上にピストンアームが伸びたりすると、このブロックは土に戻ります。 +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.=小麦の種を耕地(クワで作れる)に置いて植え、小麦の苗にします。日光に当たると成長し、湿った耕地ではより早く成長します。動物を右クリックすると、小麦の種を食べさせることができます。 +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 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.=成熟した小麦の苗からは、小麦をいくつか収穫できます。これ以上は成長しません。 +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=ブロックを耕地にする +60% chance of poisoning=60%の確率で食あたり +Surface for crops=農作物用地面 +Can become wet=潤いが得られる +Uses: @1=使用:@1 diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.pl.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.pl.tr new file mode 100644 index 000000000..3f8d0fc6c --- /dev/null +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.pl.tr @@ -0,0 +1,100 @@ + +# textdomain: mcl_farming +Beetroot Seeds=Nasiona buraka +Grows into a beetroot plant. Chickens like beetroot seeds.=Wyrasta w roślinę buraka. Kurczaki lubią nasiona buraka. +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.=Postaw nasiona buraka na polu uprawnym (możesz zaorać ziemię motyką) aby zasadzić roślinę buraka. Wyrasta ona w słońcu i rośnie szybciej na nawodnionym polu uprawnym. Kliknij prawym przyciskiem na zwierzę, aby je nakarmić nasionami buraka. +Premature Beetroot Plant (Stage 1)=Niedojrzała roślina buraka (etap 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.=Rośliny buraka są roślinami rosnącymi na oświetlonym polu uprawnym w czterech etapach. Na nawodnionym polu rosną nieco szybciej. Mogą być zebrane w dowolnym momencie ale będzie to zyskowne tylko jeśli są dojrzałe. +Premature Beetroot Plant=Niedojrzała roślina buraka +Premature Beetroot Plant (Stage 2)=Niedojrzała roślina buraka (etap 2) +Premature Beetroot Plant (Stage 3)=Niedojrzała roślina buraka (etap 3) +Mature Beetroot Plant=Dojrzała roślina buraka +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.=Dojrzała roślina buraka jest rośliną hodowlaną, która jest gotowa do zebrania w celu uzyskania buraków i nasion. Nie urośnie już więcej. +Beetroot=Burak +Beetroots are both used as food item and a dye ingredient. Pigs like beetroots, too.=Buraki są używane zarówno jako przedmioty jadalne jak i jako składniki do farb. +Hold it in your hand and right-click to eat it. Rightclick an animal to feed it.=Weź je do ręki i kliknij prawy przycisk myszy by je zjeść. +Beetroot Soup=Zupa z buraków +Beetroot soup is a food item.=Zupa z buraków to przedmiot jadalny. +Premature Carrot Plant=Niedojrzała roślina marchwi +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.=Rośliny marchwi są roślinami rosnącymi na polach uprawnych w słońcu w 8 etapach, ale tylko 4 etapy mogą być odróżnione wizualnie. Na nawodnionych polach uprawnych rosną one nieco szybciej. +Premature Carrot Plant (Stage @1)=Niedojrzała roślina marchwi (etap @1) +Mature Carrot Plant=Dojrzała roślina marchwi +Mature carrot plants are ready to be harvested for carrots. They won't grow any further.=Dojrzałe rośliny marchwi są gotowe do zebrania w celu uzyskania marchwi. +Carrot=Marchew +Carrots can be eaten and planted. Pigs and rabbits like carrots.=Marchewki mogą być zjedzone bądź zasadzone. Świnie i króliki lubią marchwie. +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.=Weź ją do ręki i kliknij prawy przycisk myszy by ją zjeść. Postaw ją na górze pola uprawnego aby ją zasadzić. Rośnie w słońcu i rośnie szybciej na nawodnionym polu. Kliknij prawym przyciskiem na zwierzę aby je nakarmić. +Golden Carrot=Złota marchew +A golden carrot is a precious food item which can be eaten. It is really, really filling!=Złota marchewka to cenny przedmiot jadalny. Jest bardzo, bardzo sycąca! +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.=Motyki są niezbędnymi narzędziami do uprawiania roślin. Są używane do tworzenia pól uprawnych na których można sadzić nasiona. Motyki mogą być również użyte jako bardzo słabe bronie w razie konieczności. +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.=Użyj motyki na bloku który można zaorać (klikając go prawym przyciskiem), aby zamienić go w pole uprawne. Ziemia, bloki trawy i ścieżki trawy są blokami, które można zaorać. Korzystanie z motyki na twardej ziemi zamienia ją w ziemię. +Wood Hoe=Drewniana motyka +Stone Hoe=Kamienna motyka +Iron Hoe=Żelazna motyka +Golden Hoe=Złota motyka +Diamond Hoe=Diamentowa motyka +Melon Seeds=Nasiona melona +Grows into a melon stem which in turn grows melons. Chickens like melon seeds.=Wyrasta z nich łodyga melona, z której z kolei wyrastają melony. Kurczaki lubią nasiona melona. +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.=Umieść nasiona melona na polu uprawnym (ziemię można zaorać motyką), aby zasadzić łodygę melona. Łodygi melona rosną w słońcu i rosną szybciej na nawodnionym polu. Gdy są dojrzałe, łodygi melona będą próbować umieścić melon na boku. Kliknij prawym na zwierzę aby nakarmić je nasionami melona. +Melon=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.=Melon jest blokiem, który wyrasta z łodygi melona, która z kolei wyrasta z nasion melona. +Premature Melon Stem=Niedojrzała łodyga melona. +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.=Łodygi melona rosną na polu uprawnym w 8 etapach. Na nawodnionym polu rosną nieco szybciej. Dojrzałe łodygi melona są w stanie tworzyć melony. +Premature Melon Stem (Stage @1)=Niedojrzała łodyga melona (etap @1) +Mature Melon Stem=Dojrzała łodyga melona +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.=Dojrzała łodyga melona próbuje stworzyć melona na jednym z czterech sąsiednich bloków. Melon może wyrosnąć tylko na polu uprawnym, ziemi lub bloku trawy. Gdy melon jest obok łodygi melona, łodyga natychmiast się zgina i łączy z melonem. Dopóki jest połączona, nie może z niej wyrosnąć inny melon. Jak tylko wszystkie melony wokół łodygi są usunięte traci ona połączenie i może z niej wyrosnąć następny melon. +Melon Slice=Kawałek melona +This is a food item which can be eaten.=Jest to przedmiot, który można zjeść. +Premature Potato Plant=Niedojrzała roślina ziemniaka +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.=Rośliny ziemniaka są roślinami rosnącymi w słońcu w 8 etapach, ale tylko 4 są rozróżnialne wizualnie. Na nawodnionym polu rosną nieco szybciej. Mogą być zebrane w dowolnym momencie, ale jest to zyskowne tylko gdy są dojrzałe. +Premature Potato Plant (Stage @1)=Niedojrzała roślina ziemniaka (Etap @1) +Mature Potato Plant=Dojrzała roślina ziemniaka +Mature potato plants are ready to be harvested for potatoes. They won't grow any further.=Dojrzałe rośliny ziemniaka są gotowe do zebrania. Nie będą już rosnąć. +Potato=Ziemniak +Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes.=Ziemniaki to przedmioty, które można zjeść, upiec w piecu i zasadzić. Świnie lubią ziemniaki. +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.=Weź je do ręki i kliknij prawy by je zjeść. Postaw je na polu uprawnym by je zasadzić. Rosną w słońcu i rosną szybciej na nawodnionym polu. Kliknij prawym na zwierzę by je nakarmić. +Baked Potato=Upieczony ziemniak +Baked potatoes are food items which are more filling than the unbaked ones.=Upieczone ziemniaki są przedmiotami jadalnymi, które są bardziej sycące niż nieupieczone ziemniaki. +Poisonous Potato=Zatruty ziemniak +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.=Ten ziemniak nie wygląda na zdrowy. Możesz go zjeść aby odzyskać punkty głodu, ale jest 60% szans, że chwilowo cię zatruje. +Pumpkin Seeds=Nasiona dyni +Grows into a pumpkin stem which in turn grows pumpkins. Chickens like pumpkin seeds.=Wyrasta z nich łodyga dyni, z której z kolei wyrastają dynie. Kurczaki lubią nasiona dyni. +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.=Postaw nasiona dyni na polu uprawnym (możesz zaorać ziemię motyką) aby zasadzić łodygę dyni. Łodygi dyni rosną w słońcu i rosną szybciej na nawodnionym polu. Gdy są dojrzałe, próbują one postawić dynię na jednym z sąsiednich pól. +Premature Pumpkin Stem=Niedojrzała łodyga dyni +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.=Łodygi dyni rosną w 8 etapach. Na nawodnionym polu rośnie nieco szybciej. Z dojrzałych łodyg dyni są w stanie wyrosnąć dynie. +Premature Pumpkin Stem (Stage @1)=Niedojrzała łodyga dyni (etap @1) +Mature Pumpkin Stem=Dojrzała łodyga dyni +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.=Dojrzała łodyga dyni próbuje postawić dynię na jednym z czterech sąsiadujących bloków. Dynia może wyrosnąć tylko na polu uprawnym, ziemi lub bloku trawy. Gdy dynia jest obok łodygi dyni, ugina się ona i łączy z dynią. Z połączonej łodygi dyni nie może wyrosnąć kolejna dynia. Jak tylko wszystkie pobliskie dynie są usunięte, traci ona połączenie i może z niej wyrosnąć następna dynia. +Faceless Pumpkin=Dynia bez twarzy +A faceless pumpkin is a decorative block. It can be carved with shears to obtain pumpkin seeds.=Dynia bez twarzy jest blokiem dekoracyjnym. Może być pokrojona nożycami aby otrzymać nasiona dyni. +Pumpkin=Dynia +A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.=Dynia może być noszona jak hełm. Dynie rosną z łodygi dyni, która z kolei rośnie z nasion dyni. +Jack o'Lantern=Świecąca dynia +A jack o'lantern is a traditional Halloween decoration made from a pumpkin. It glows brightly.=Świecąca dynia jest tradycyjną dekoracją Halloween wykonaną z dyni, która jasno świeci. +Pumpkin Pie=Ciasto z dyni +A pumpkin pie is a tasty food item which can be eaten.=Ciasto z dyni jest pysznym przedmiotem, który można zjeść. +Farmland=Pole uprawne +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.=Pole uprawne jest wykorzystywane do rolnictwa. Jest to niezbędne powierzchnia do sadzenia roślin. Jest tworzona gdy motyka jest użyta na ziemi lub podobnym bloku. Rośliny mogą rosnąć na polu uprawnym, ale powoli. Pola uprawne zamienią się w nawodnione pola uprawne (na których rośliny rosną szybciej) kiedy spadnie deszcz lub źródło wody jest w pobliżu. Ten blok zamieni się w ziemię gdy stały blok pojawi się nad nim, lub ramię tłoku będzie nad nim wysunięte. +Hydrated Farmland=Nawodnione pole uprawne +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.=Nawodnione pole uprawne jest używane w rolnictwie, do sadzenia roślin. Jest utworzone gdy na pole uprawne spadnie deszcz lub w pobliżu jest woda. Bez wody blok ten wyschnie po jakimś czasie. Ten blok zamieni się w ziemię gdy stały blok pojawi się nad nim, lub ramię tłoku będzie nad nim wysunięte. +Wheat Seeds=Nasiona zboża +Grows into a wheat plant. Chickens like wheat seeds.=Wyrasta w zboże. Kurczaki lubią nasiona zboża. +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.=Postaw nasiona zboża na polu uprawnym (możesz zaorać ziemię motyką) aby zasadzić zboże. Wyrasta ono w słońcu i rośnie szybciej na nawodnionym polu uprawnym. Kliknij prawym przyciskiem na zwierzę, aby je nakarmić. +Premature Wheat Plant=Niedojrzałe zboże +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.=Zboże rośnie w słońcu na polu uprawnym w 8 etapach. Na nawodnionym polu rośnie nieco szybciej. Może być zebrane w dowolnym momencie ale będzie to zyskowne tylko jeśli jest dojrzałe. +Premature Wheat Plant (Stage @1)=Niedojrzałe zboże (etap @1) +Mature Wheat Plant=Dojrzałe zboże +Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further.=Dojrzałe zboże jest gotowe by zostać zebrane w celu pozyskania nasion zboża. Nie urośnie ono więcej. +Wheat=Zboże +Wheat is used in crafting. Some animals like wheat.=Zboże jest używane do wytwarzania. Niektóre zwierzęta lubią zboże. +Cookie=Ciastko +Bread=Chleb +Hay Bale=Bela siana +Hay bales are decorative blocks made from wheat.=Bele siana są blokami dekoracyjnymi wytwarzanymi ze zboża. +To carve a face into the pumpkin, use the shears on the side you want to carve.=Aby wyrzeźbić twarz w dyni, użyj nożyc na boku w którym chcesz wyrzeźbić. +Use the “Place” key on an animal to try to feed it wheat.=Użyj przycisku "Umieść" na zwierzęciu, aby spróbować je nakarmić. +Grows on farmland=Rośnie na polu uprawnym +Turns block into farmland=Zamienia blok w pole uprawne +60% chance of poisoning=60% szans na zatrucie +Surface for crops=Podłoże pod uprawy +Can become wet=Może się zmoczyć +Uses: @1=Wykorzystuje: @1 diff --git a/mods/ITEMS/mcl_farming/locale/mcl_farming.zh_TW.tr b/mods/ITEMS/mcl_farming/locale/mcl_farming.zh_TW.tr new file mode 100644 index 000000000..7017f7852 --- /dev/null +++ b/mods/ITEMS/mcl_farming/locale/mcl_farming.zh_TW.tr @@ -0,0 +1,99 @@ +# 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.=將甜菜種子放在農田上(可以用鋤頭創造)種植甜菜。它們在陽光下生長,在有水分的農田上生長更快。右鍵點擊一個動物來餵牠甜菜種子。 +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.=成熟的甜菜是一種隨時可以收穫甜菜根和一些甜菜種子的植物。它不會再增長了。 +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.=甜菜根湯是一種食物。 +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個階段可以從視覺上區​​分。在水分充足的農田裡,它們生長得更快一些。它們可以在任何時候收割,但只有在成熟時才會有收益。 +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.=把它拿在手裡,右鍵點擊以吃掉它;把它放置在農田上種植它。在水分充足的農田裡,它們生長得更快一些。右鍵點擊一個動物來餵牠。 +Golden Carrot=金胡蘿蔔 +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.=在可耕地塊上使用鋤頭(通過右鍵點擊),將其變成農田。泥土、草塊和草路都是可耕地塊。在粗泥上使用鋤頭可以將其變成泥土。 +Wood Hoe=木鋤 +Stone Hoe=石鋤 +Iron Hoe=鐵鋤 +Golden Hoe=金鋤 +Diamond 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.=這是一種可以吃的食物 +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.=把它拿在手裡,點擊右鍵就可以吃掉它。把它放在農田上面來種植。它在陽光下生長,在有水分的農田上生長得更快。右鍵點擊一個動物來餵牠。 +Baked Potato=烤馬鈴薯 +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%的可能性會讓你短暫中毒。 +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.=將南瓜種子放在農田上(可以用鋤頭打造)以種植南瓜莖。南瓜莖在陽光下生長,在水分充足的農田裡生長得更快。成熟後,莖會試圖在它旁邊長出一個南瓜。右鍵點擊動物以給它餵食南瓜種子。 +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.=南瓜可以作為頭盔佩戴。南瓜由南瓜莖生長,而南瓜莖又由南瓜種子生長。 +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.=南瓜派是可以吃的美味食品。 +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.=農田用於耕作,是種植農作物的必要表面。它是在泥土類方塊上使用鋤頭時形成的。植物能夠在農田上生長,但速度很慢。當下雨或附近有水源時,農田會變成濕潤的耕地(植物在上面生長更快)。當上面出現固體方塊或活塞臂延伸到上面時,這個方塊會變回泥土。 +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.=濕潤的耕地用於耕作,這是你可以種植和生長一些植物的地方。它是在農田被雨水沖刷或靠近水的情況下形成的。如果沒有水,這個方塊最終會變乾。當上面出現固體方塊或活塞臂延伸到上面時,這個方塊會變回泥土。 +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.=將小麥種子放在農田上(可以用鋤頭製造)以種植一株小麥。它們在陽光下生長,在有水的農田裡生長得更快。右鍵點擊一個動物以給它餵食小麥種子。 +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 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.=成熟的小麥是一種隨時可以收穫小麥的植物。它不會再增長了。 +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=把方塊變成農田 +60% chance of poisoning=有60%的可能性會讓你中毒 +Surface for crops=種植農作物的表面 +Can become wet=可以變溼 +Uses: @1=使用:@1 diff --git a/mods/ITEMS/mcl_farming/locale/template.txt b/mods/ITEMS/mcl_farming/locale/template.txt index 7359fefa6..bc81acce1 100644 --- a/mods/ITEMS/mcl_farming/locale/template.txt +++ b/mods/ITEMS/mcl_farming/locale/template.txt @@ -31,6 +31,7 @@ Stone Hoe= Iron Hoe= Golden Hoe= Diamond Hoe= +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.= @@ -77,12 +78,15 @@ 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.= 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.= +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.= Premature Wheat Plant (Stage @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.= Cookie= @@ -97,3 +101,5 @@ Turns block into farmland= Surface for crops= Can become wet= Uses: @1= +Sweet Berry Bush (Stage @1)= +Sweet Berry= diff --git a/mods/ITEMS/mcl_farming/melon.lua b/mods/ITEMS/mcl_farming/melon.lua index 38b4c713c..d62288333 100644 --- a/mods/ITEMS/mcl_farming/melon.lua +++ b/mods/ITEMS/mcl_farming/melon.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) -- Seeds minetest.register_craftitem("mcl_farming:melon_seeds", { @@ -7,7 +7,7 @@ minetest.register_craftitem("mcl_farming:melon_seeds", { _doc_items_longdesc = S("Grows into a melon stem which in turn grows melons. Chickens like melon seeds."), _doc_items_usagehelp = S("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."), stack_max = 64, - groups = { craftitem=1 }, + groups = {craftitem = 1, compostability = 30}, inventory_image = "mcl_farming_melon_seeds.png", on_place = function(itemstack, placer, pointed_thing) return mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:melontige_1") @@ -21,15 +21,18 @@ local melon_base_def = { _doc_items_longdesc = S("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."), stack_max = 64, tiles = {"farming_melon_top.png", "farming_melon_top.png", "farming_melon_side.png", "farming_melon_side.png", "farming_melon_side.png", "farming_melon_side.png"}, - groups = {handy=1,axey=1, plant=1,building_block=1,enderman_takable=1,dig_by_piston=1}, + groups = { + handy = 1, axey = 1, plant = 1, building_block = 1, dig_by_piston = 1, dig_immediate_piston = 1, + enderman_takable = 1, compostability = 65 + }, drop = { max_items = 1, items = { - { items = {'mcl_farming:melon_item 7'}, rarity = 14 }, - { items = {'mcl_farming:melon_item 6'}, rarity = 10 }, - { items = {'mcl_farming:melon_item 5'}, rarity = 5 }, - { items = {'mcl_farming:melon_item 4'}, rarity = 2 }, - { items = {'mcl_farming:melon_item 3'} }, + { items = {"mcl_farming:melon_item 7"}, rarity = 14 }, + { items = {"mcl_farming:melon_item 6"}, rarity = 10 }, + { items = {"mcl_farming:melon_item 5"}, rarity = 5 }, + { items = {"mcl_farming:melon_item 4"}, rarity = 2 }, + { items = {"mcl_farming:melon_item 3"} }, } }, sounds = mcl_sounds.node_sound_wood_defaults(), @@ -134,7 +137,7 @@ minetest.register_craftitem("mcl_farming:melon_item", { inventory_image = "farming_melon.png", on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), - groups = { food = 2, eatable = 2 }, + groups = {food = 2, eatable = 2, compostability = 50}, _mcl_saturation = 1.2, }) @@ -144,11 +147,11 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mcl_farming:melon', + output = "mcl_farming:melon", recipe = { - {'mcl_farming:melon_item', 'mcl_farming:melon_item', 'mcl_farming:melon_item'}, - {'mcl_farming:melon_item', 'mcl_farming:melon_item', 'mcl_farming:melon_item'}, - {'mcl_farming:melon_item', 'mcl_farming:melon_item', 'mcl_farming:melon_item'}, + {"mcl_farming:melon_item", "mcl_farming:melon_item", "mcl_farming:melon_item"}, + {"mcl_farming:melon_item", "mcl_farming:melon_item", "mcl_farming:melon_item"}, + {"mcl_farming:melon_item", "mcl_farming:melon_item", "mcl_farming:melon_item"}, } }) diff --git a/mods/ITEMS/mcl_farming/mod.conf b/mods/ITEMS/mcl_farming/mod.conf index 4805e95db..fe4bc1564 100644 --- a/mods/ITEMS/mcl_farming/mod.conf +++ b/mods/ITEMS/mcl_farming/mod.conf @@ -1 +1,3 @@ name = mcl_farming +depends = mcl_core, mcl_sounds, mcl_wool, mcl_torches, mcl_weather, mobs_mc, mcl_colors, mcl_init +optional_depends = mcl_armor, doc diff --git a/mods/ITEMS/mcl_farming/potatoes.lua b/mods/ITEMS/mcl_farming/potatoes.lua index 871d67963..e29219fd8 100644 --- a/mods/ITEMS/mcl_farming/potatoes.lua +++ b/mods/ITEMS/mcl_farming/potatoes.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) -- Premature potato plants @@ -9,10 +9,10 @@ for i=1, 7 do selbox = { -0.5, -0.5, -0.5, 0.5, -5/16, 0.5 } elseif i < 5 then texture = "mcl_farming_potatoes_stage_1.png" - selbox = { -0.5, -0.5, -0.5, 0.5, -2/16, 0.5 } + selbox = { -0.5, -0.5, -0.5, 0.5, -4/16, 0.5 } else texture = "mcl_farming_potatoes_stage_2.png" - selbox = { -0.5, -0.5, -0.5, 0.5, 2/16, 0.5 } + selbox = { -0.5, -0.5, -0.5, 0.5, -3/16, 0.5 } end local create, name, longdesc @@ -67,17 +67,17 @@ minetest.register_node("mcl_farming:potato", { inventory_image = "mcl_farming_potatoes_stage_3.png", drop = { items = { - { items = {'mcl_farming:potato_item 1'} }, - { items = {'mcl_farming:potato_item 1'}, rarity = 2 }, - { items = {'mcl_farming:potato_item 1'}, rarity = 2 }, - { items = {'mcl_farming:potato_item 1'}, rarity = 2 }, - { items = {'mcl_farming:potato_item_poison 1'}, rarity = 50 } + { items = {"mcl_farming:potato_item 1"} }, + { items = {"mcl_farming:potato_item 1"}, rarity = 2 }, + { items = {"mcl_farming:potato_item 1"}, rarity = 2 }, + { items = {"mcl_farming:potato_item 1"}, rarity = 2 }, + { items = {"mcl_farming:potato_item_poison 1"}, rarity = 50 } } }, selection_box = { type = "fixed", fixed = { - { -0.5, -0.5, -0.5, 0.5, 1/16, 0.5 } + { -0.5, -0.5, -0.5, 0.5, -1/16, 0.5 } } }, 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}, @@ -91,18 +91,11 @@ minetest.register_craftitem("mcl_farming:potato_item", { _doc_items_longdesc = S("Potatoes are food items which can be eaten, cooked in the furnace and planted. Pigs like potatoes."), _doc_items_usagehelp = S("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."), inventory_image = "farming_potato.png", - groups = { food = 2, eatable = 1 }, + groups = {food = 2, eatable = 1, compostability = 65, smoker_cookable = 1}, _mcl_saturation = 0.6, stack_max = 64, on_secondary_use = minetest.item_eat(1), - on_place = function(itemstack, placer, pointed_thing) - local new = mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:potato_1") - if new ~= nil then - return new - else - return minetest.do_item_eat(1, nil, itemstack, placer, pointed_thing) - end - end, + on_place = mcl_farming:get_seed_or_eat_callback("mcl_farming:potato_1", 1), }) minetest.register_craftitem("mcl_farming:potato_item_baked", { @@ -112,13 +105,13 @@ minetest.register_craftitem("mcl_farming:potato_item_baked", { inventory_image = "farming_potato_baked.png", on_place = minetest.item_eat(5), on_secondary_use = minetest.item_eat(5), - groups = { food = 2, eatable = 5 }, + groups = {food = 2, eatable = 5, compostability = 85}, _mcl_saturation = 6.0, }) minetest.register_craftitem("mcl_farming:potato_item_poison", { description = S("Poisonous Potato"), - _tt_help = minetest.colorize("#FFFF00", S("60% chance of poisoning")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("60% chance of poisoning")), _doc_items_longdesc = S("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."), stack_max = 64, inventory_image = "farming_potato_poison.png", diff --git a/mods/ITEMS/mcl_farming/pumpkin.lua b/mods/ITEMS/mcl_farming/pumpkin.lua index 72b4e5412..7387a78c9 100644 --- a/mods/ITEMS/mcl_farming/pumpkin.lua +++ b/mods/ITEMS/mcl_farming/pumpkin.lua @@ -1,6 +1,7 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_screwdriver = minetest.get_modpath("screwdriver") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_simple @@ -14,7 +15,7 @@ minetest.register_craftitem("mcl_farming:pumpkin_seeds", { _doc_items_usagehelp = S("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."), stack_max = 64, inventory_image = "mcl_farming_pumpkin_seeds.png", - groups = { craftitem=1 }, + groups = {craftitem=1, compostability = 30}, on_place = function(itemstack, placer, pointed_thing) return mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:pumpkin_1") end @@ -98,37 +99,95 @@ local pumpkin_base_def = { stack_max = 64, paramtype2 = "facedir", 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, enderman_takable=1}, + groups = { + handy = 1, axey = 1, plant = 1, building_block = 1, dig_by_piston = 1, dig_immediate_piston = 1, + enderman_takable = 1, compostability = 65 + }, sounds = mcl_sounds.node_sound_wood_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 1, _mcl_hardness = 1, } -minetest.register_node("mcl_farming:pumpkin", pumpkin_base_def) local pumpkin_face_base_def = table.copy(pumpkin_base_def) pumpkin_face_base_def.description = S("Pumpkin") pumpkin_face_base_def._doc_items_longdesc = S("A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.") pumpkin_face_base_def._doc_items_usagehelp = nil pumpkin_face_base_def.tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_face.png"} +pumpkin_face_base_def.groups.armor=1 +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.groups.non_combat_armor=1 + +pumpkin_face_base_def._mcl_armor_element = "head" +pumpkin_face_base_def._mcl_armor_texture = "mcl_farming_pumpkin_face.png" + +pumpkin_face_base_def.on_construct = function(pos) + -- Attempt to spawn iron golem or snow golem + mobs_mc.check_iron_golem_summon(pos) + mobs_mc.check_snow_golem_summon(pos) +end + if minetest.get_modpath("mcl_armor") then - pumpkin_face_base_def.on_secondary_use = armor.on_armor_use + local pumpkin_hud = {} + local function add_pumpkin_hud(player) + pumpkin_hud[player] = { + pumpkin_blur = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + text = "mcl_farming_pumpkin_hud.png", + z_index = -200 + }), + --this is a fake crosshair, because hotbar and crosshair doesn't support z_index + --TODO: remove this and add correct z_index values + fake_crosshair = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = 1, y = 1}, + text = "crosshair.png", + z_index = -100 + }) + } + end + local function remove_pumpkin_hud(player) + if pumpkin_hud[player] then + player:hud_remove(pumpkin_hud[player].pumpkin_blur) + player:hud_remove(pumpkin_hud[player].fake_crosshair) + pumpkin_hud[player] = nil + end + end + + pumpkin_face_base_def.on_secondary_use = mcl_armor.equip_on_use + pumpkin_face_base_def._on_equip = add_pumpkin_hud + pumpkin_face_base_def._on_unequip = remove_pumpkin_hud + + minetest.register_on_joinplayer(function(player) + if player:get_inventory():get_stack("armor", 2):get_name() == "mcl_farming:pumpkin_face" then + add_pumpkin_hud(player) + end + end) + minetest.register_on_dieplayer(function(player) + if not minetest.settings:get_bool("mcl_keepInventory") then + remove_pumpkin_hud(player) + end + end) + minetest.register_on_leaveplayer(function(player) + pumpkin_hud[player] = nil + end) end -- Register stem growth mcl_farming:add_plant("plant_pumpkin_stem", "mcl_farming:pumpkintige_unconnect", {"mcl_farming:pumpkin_1", "mcl_farming:pumpkin_2", "mcl_farming:pumpkin_3", "mcl_farming:pumpkin_4", "mcl_farming:pumpkin_5", "mcl_farming:pumpkin_6", "mcl_farming:pumpkin_7"}, 30, 5) -- Register actual pumpkin, connected stems and stem-to-pumpkin growth -mcl_farming:add_gourd("mcl_farming:pumpkintige_unconnect", "mcl_farming:pumpkintige_linked", "mcl_farming:pumpkintige_unconnect", stem_def, stem_drop, "mcl_farming:pumpkin_face", pumpkin_face_base_def, 30, 15, "mcl_farming_pumpkin_stem_connected.png^[colorize:#FFA800:127", -function(pos) - -- Attempt to spawn iron golem or snow golem - mobs_mc.tools.check_iron_golem_summon(pos) - mobs_mc.tools.check_snow_golem_summon(pos) -end) +mcl_farming:add_gourd("mcl_farming:pumpkintige_unconnect", "mcl_farming:pumpkintige_linked", "mcl_farming:pumpkintige_unconnect", stem_def, stem_drop, "mcl_farming:pumpkin", pumpkin_base_def, 30, 15, "mcl_farming_pumpkin_stem_connected.png^[colorize:#FFA800:127") + +-- Steal function to properly disconnect a carved pumpkin +pumpkin_face_base_def.after_destruct = minetest.registered_nodes["mcl_farming:pumpkin"].after_destruct +minetest.register_node("mcl_farming:pumpkin_face", pumpkin_face_base_def) -- Jack o'Lantern minetest.register_node("mcl_farming:pumpkin_face_light", { @@ -144,8 +203,8 @@ minetest.register_node("mcl_farming:pumpkin_face_light", { sounds = mcl_sounds.node_sound_wood_defaults(), on_construct = function(pos) -- Attempt to spawn iron golem or snow golem - mobs_mc.tools.check_iron_golem_summon(pos) - mobs_mc.tools.check_snow_golem_summon(pos) + mobs_mc.check_iron_golem_summon(pos) + mobs_mc.check_snow_golem_summon(pos) end, on_rotate = on_rotate, _mcl_blast_resistance = 1, @@ -165,11 +224,6 @@ minetest.register_craft({ recipe = {{"mcl_farming:pumpkin"}} }) -minetest.register_craft({ - output = "mcl_farming:pumpkin_seeds 4", - recipe = {{"mcl_farming:pumpkin_face"}} -}) - minetest.register_craftitem("mcl_farming:pumpkin_pie", { description = S("Pumpkin Pie"), _doc_items_longdesc = S("A pumpkin pie is a tasty food item which can be eaten."), @@ -178,7 +232,7 @@ minetest.register_craftitem("mcl_farming:pumpkin_pie", { wield_image = "mcl_farming_pumpkin_pie.png", on_place = minetest.item_eat(8), on_secondary_use = minetest.item_eat(8), - groups = { food = 2, eatable = 8 }, + groups = {food = 2, eatable = 8, compostability = 100}, _mcl_saturation = 4.8, }) @@ -187,11 +241,6 @@ minetest.register_craft({ output = "mcl_farming:pumpkin_pie", recipe = {"mcl_farming:pumpkin", "mcl_core:sugar", "mcl_throwing:egg"}, }) -minetest.register_craft({ - type = "shapeless", - output = "mcl_farming:pumpkin_pie", - recipe = {"mcl_farming:pumpkin_face", "mcl_core:sugar", "mcl_throwing:egg"}, -}) if minetest.get_modpath("doc") then diff --git a/mods/ITEMS/mcl_farming/shared_functions.lua b/mods/ITEMS/mcl_farming/shared_functions.lua index 6c682f839..f597e786a 100644 --- a/mods/ITEMS/mcl_farming/shared_functions.lua +++ b/mods/ITEMS/mcl_farming/shared_functions.lua @@ -1,9 +1,15 @@ +local math = math +local tostring = tostring + +mcl_farming.plant_lists = {} + local plant_lists = {} + local plant_nodename_to_id_list = {} local function get_intervals_counter(pos, interval, chance) local meta = minetest.get_meta(pos) - local time_speed = tonumber(minetest.settings:get('time_speed') or 72) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) local current_game_time if time_speed == nil then return 1 @@ -51,18 +57,19 @@ local function get_avg_light_level(pos) end function mcl_farming:add_plant(identifier, full_grown, names, interval, chance) - plant_lists[identifier] = {} - plant_lists[identifier].full_grown = full_grown - plant_lists[identifier].names = names - plant_lists[identifier].interval = interval - plant_lists[identifier].chance = chance + mcl_farming.plant_lists[identifier] = {} + mcl_farming.plant_lists[identifier].full_grown = full_grown + mcl_farming.plant_lists[identifier].names = names + mcl_farming.plant_lists[identifier].interval = interval + mcl_farming.plant_lists[identifier].chance = chance + plant_lists = mcl_farming.plant_lists --provide local copy of plant lists (performances) minetest.register_abm({ label = string.format("Farming plant growth (%s)", identifier), nodenames = names, interval = interval, chance = chance, action = function(pos, node) - local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" + local low_speed = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z }).name ~= "mcl_farming:soil_wet" mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed) end, }) @@ -123,7 +130,7 @@ function mcl_farming:grow_plant(identifier, pos, node, stages, ignore_light, low stages = 1 end stages = stages + math.ceil(intervals_counter) - local new_node = {name = plant_info.names[step+stages]} + local new_node = { name = plant_info.names[step + stages] } if new_node.name == nil then new_node.name = plant_info.full_grown end @@ -150,15 +157,15 @@ function mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname) end end - local pos = {x=pt.above.x, y=pt.above.y-1, z=pt.above.z} + local pos = { x = pt.above.x, y = pt.above.y - 1, z = pt.above.z } local farmland = minetest.get_node(pos) - pos= {x=pt.above.x, y=pt.above.y, z=pt.above.z} + pos = { x = pt.above.x, y = pt.above.y, z = pt.above.z } local place_s = minetest.get_node(pos) - if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then - minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, {pos = pos}, true) - minetest.add_node(pos, {name=plantname, param2 = minetest.registered_nodes[plantname].place_param2}) - local intervals_counter = get_intervals_counter(pos, 1, 1) + if string.find(farmland.name, "mcl_farming:soil") and string.find(place_s.name, "air") then + minetest.sound_play(minetest.registered_nodes[plantname].sounds.place, { pos = pos }, true) + minetest.add_node(pos, { name = plantname, param2 = minetest.registered_nodes[plantname].place_param2 }) + --local intervals_counter = get_intervals_counter(pos, 1, 1) else return end @@ -172,13 +179,13 @@ end --[[ Helper function to create a gourd (e.g. melon, pumpkin), the connected stem nodes as -- full_unconnected_stem: itemstring of the full-grown but unconnceted stem node. This node must already be done +- full_unconnected_stem: itemstring of the full-grown but unconnected stem node. This node must already be done - connected_stem_basename: prefix of the itemstrings used for the 4 connected stem nodes to create - stem_itemstring: Desired itemstring of the fully-grown unconnected stem node - stem_def: Partial node definition of the fully-grown unconnected stem node. Many fields are already defined. You need to add `tiles` and `description` at minimum. Don't define on_construct without good reason - stem_drop: Drop probability table for all stem - gourd_itemstring: Desired itemstring of the full gourd node -- gourd_def: (almost) full definition of the gourd node. This function will add on_construct and after_dig_node to the definition for unconnecting any connected stems +- gourd_def: (almost) full definition of the gourd node. This function will add on_construct and after_destruct to the definition for unconnecting any connected stems - grow_interval: Will attempt to grow a gourd periodically at this interval in seconds - grow_chance: Chance of 1/grow_chance to grow a gourd next to the full unconnected stem after grow_interval has passed. Must be a natural number - connected_stem_texture: Texture of the connected stem @@ -187,7 +194,7 @@ end function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, stem_itemstring, stem_def, stem_drop, gourd_itemstring, gourd_def, grow_interval, grow_chance, connected_stem_texture, gourd_on_construct_extra) - local connected_stem_names = { + local connected_stem_names = { connected_stem_basename .. "_r", connected_stem_basename .. "_l", connected_stem_basename .. "_t", @@ -195,32 +202,32 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s } local neighbors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, } -- Connect the stem at stempos to the first neighboring gourd block. -- No-op if not a stem or no gourd block found - local try_connect_stem = function(stempos) + local function try_connect_stem(stempos) local stem = minetest.get_node(stempos) if stem.name ~= full_unconnected_stem then return false end - for n=1, #neighbors do + for n = 1, #neighbors do local offset = neighbors[n] local blockpos = vector.add(stempos, offset) local block = minetest.get_node(blockpos) if block.name == gourd_itemstring then if offset.x == 1 then - minetest.set_node(stempos, {name=connected_stem_names[1]}) + minetest.set_node(stempos, { name = connected_stem_names[1] }) elseif offset.x == -1 then - minetest.set_node(stempos, {name=connected_stem_names[2]}) + minetest.set_node(stempos, { name = connected_stem_names[2] }) elseif offset.z == 1 then - minetest.set_node(stempos, {name=connected_stem_names[3]}) + minetest.set_node(stempos, { name = connected_stem_names[3] }) elseif offset.z == -1 then - minetest.set_node(stempos, {name=connected_stem_names[4]}) + minetest.set_node(stempos, { name = connected_stem_names[4] }) end return true end @@ -228,25 +235,25 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s end -- Register gourd - if not gourd_def.after_dig_node then - gourd_def.after_dig_node = function(blockpos, oldnode, oldmetadata, user) + if not gourd_def.after_destruct then + gourd_def.after_destruct = function(blockpos, oldnode) -- Disconnect any connected stems, turning them back to normal stems - for n=1, #neighbors do + for n = 1, #neighbors do local offset = neighbors[n] local expected_stem = connected_stem_names[n] local stempos = vector.add(blockpos, offset) local stem = minetest.get_node(stempos) if stem.name == expected_stem then - minetest.add_node(stempos, {name=full_unconnected_stem}) + minetest.add_node(stempos, { name = full_unconnected_stem }) try_connect_stem(stempos) end end end end if not gourd_def.on_construct then - gourd_def.on_construct = function(blockpos) + function gourd_def.on_construct(blockpos) -- Connect all unconnected stems at full size - for n=1, #neighbors do + for n = 1, #neighbors do local stempos = vector.add(blockpos, neighbors[n]) try_connect_stem(stempos) end @@ -265,7 +272,7 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s stem_def.selection_box = { type = "fixed", fixed = { - {-0.15, -0.5, -0.15, 0.15, 0.5, 0.15} + { -0.15, -0.5, -0.15, 0.15, 0.5, 0.15 } }, } end @@ -285,14 +292,14 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s stem_def.drop = stem_drop end if stem_def.groups == nil then - stem_def.groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,} + stem_def.groups = { dig_immediate = 3, not_in_creative_inventory = 1, plant = 1, attached_node = 1, dig_by_water = 1, destroy_by_lava_flow = 1, } end if stem_def.sounds == nil then stem_def.sounds = mcl_sounds.node_sound_leaves_defaults() end if not stem_def.on_construct then - stem_def.on_construct = function(stempos) + function stem_def.on_construct(stempos) -- Connect stem to gourd (if possible) try_connect_stem(stempos) end @@ -303,48 +310,48 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s local connected_stem_tiles = { { "blank.png", --top - "blank.png", -- bottom - "blank.png", -- right - "blank.png", -- left - connected_stem_texture, -- back - connected_stem_texture.."^[transformFX90" --front + "blank.png", -- bottom + "blank.png", -- right + "blank.png", -- left + connected_stem_texture, -- back + connected_stem_texture .. "^[transformFX" --front }, { "blank.png", --top - "blank.png", -- bottom - "blank.png", -- right - "blank.png", -- left - connected_stem_texture.."^[transformFX90", --back - connected_stem_texture, -- front + "blank.png", -- bottom + "blank.png", -- right + "blank.png", -- left + connected_stem_texture .. "^[transformFX", --back + connected_stem_texture, -- front }, { "blank.png", --top - "blank.png", -- bottom - connected_stem_texture.."^[transformFX90", -- right - connected_stem_texture, -- left - "blank.png", --back - "blank.png", -- front + "blank.png", -- bottom + connected_stem_texture .. "^[transformFX", -- right + connected_stem_texture, -- left + "blank.png", --back + "blank.png", -- front }, { "blank.png", --top - "blank.png", -- bottom - connected_stem_texture, -- right - connected_stem_texture.."^[transformFX90", -- left - "blank.png", --back - "blank.png", -- front + "blank.png", -- bottom + connected_stem_texture, -- right + connected_stem_texture .. "^[transformFX", -- left + "blank.png", --back + "blank.png", -- front } } local connected_stem_nodebox = { - {-0.5, -0.5, 0, 0.5, 0.5, 0}, - {-0.5, -0.5, 0, 0.5, 0.5, 0}, - {0, -0.5, -0.5, 0, 0.5, 0.5}, - {0, -0.5, -0.5, 0, 0.5, 0.5}, + { -0.5, -0.5, 0, 0.5, 0.5, 0 }, + { -0.5, -0.5, 0, 0.5, 0.5, 0 }, + { 0, -0.5, -0.5, 0, 0.5, 0.5 }, + { 0, -0.5, -0.5, 0, 0.5, 0.5 }, } local connected_stem_selectionbox = { - {-0.1, -0.5, -0.1, 0.5, 0.2, 0.1}, - {-0.5, -0.5, -0.1, 0.1, 0.2, 0.1}, - {-0.1, -0.5, -0.1, 0.1, 0.2, 0.5}, - {-0.1, -0.5, -0.5, 0.1, 0.2, 0.1}, + { -0.1, -0.5, -0.1, 0.5, 0.2, 0.1 }, + { -0.5, -0.5, -0.1, 0.1, 0.2, 0.1 }, + { -0.1, -0.5, -0.1, 0.1, 0.2, 0.5 }, + { -0.1, -0.5, -0.5, 0.1, 0.2, 0.1 }, } - for i=1, 4 do + for i = 1, 4 do minetest.register_node(connected_stem_names[i], { _doc_items_create_entry = false, paramtype = "light", @@ -361,7 +368,8 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s fixed = connected_stem_selectionbox[i] }, tiles = connected_stem_tiles[i], - groups = {dig_immediate=3, not_in_creative_inventory=1, plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,}, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, + groups = { dig_immediate = 3, not_in_creative_inventory = 1, plant = 1, attached_node = 1, dig_by_water = 1, destroy_by_lava_flow = 1, }, sounds = mcl_sounds.node_sound_leaves_defaults(), _mcl_blast_resistance = 0, }) @@ -372,9 +380,9 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s end minetest.register_abm({ - label = "Grow gourd stem to gourd ("..full_unconnected_stem.." → "..gourd_itemstring..")", - nodenames = {full_unconnected_stem}, - neighbors = {"air"}, + label = "Grow gourd stem to gourd (" .. full_unconnected_stem .. " → " .. gourd_itemstring .. ")", + nodenames = { full_unconnected_stem }, + neighbors = { "air" }, interval = grow_interval, chance = grow_chance, action = function(stempos) @@ -382,20 +390,20 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s if light and light > 10 then -- Check the four neighbors and filter out neighbors where gourds can't grow local neighbors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, + { x = -1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = 0, z = -1 }, + { x = 0, y = 0, z = 1 }, } local floorpos, floor - for n=#neighbors, 1, -1 do + for n = #neighbors, 1, -1 do local offset = neighbors[n] local blockpos = vector.add(stempos, offset) - floorpos = { x=blockpos.x, y=blockpos.y-1, z=blockpos.z } + floorpos = vector.offset (blockpos, 0, -1,0) -- replaces { x = blockpos.x, y = blockpos.y - 1, z = blockpos.z } floor = minetest.get_node(floorpos) local block = minetest.get_node(blockpos) local soilgroup = minetest.get_item_group(floor.name, "soil") - if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name=="mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then + if not ((minetest.get_item_group(floor.name, "grass_block") == 1 or floor.name == "mcl_core:dirt" or soilgroup == 2 or soilgroup == 3) and block.name == "air") then table.remove(neighbors, n) end end @@ -408,27 +416,35 @@ function mcl_farming:add_gourd(full_unconnected_stem, connected_stem_basename, s local blockpos = vector.add(stempos, offset) local p2 if offset.x == 1 then - minetest.set_node(stempos, {name=connected_stem_names[1]}) + minetest.set_node(stempos, { name = connected_stem_names[1] }) p2 = 3 elseif offset.x == -1 then - minetest.set_node(stempos, {name=connected_stem_names[2]}) + minetest.set_node(stempos, { name = connected_stem_names[2] }) p2 = 1 elseif offset.z == 1 then - minetest.set_node(stempos, {name=connected_stem_names[3]}) + minetest.set_node(stempos, { name = connected_stem_names[3] }) p2 = 2 elseif offset.z == -1 then - minetest.set_node(stempos, {name=connected_stem_names[4]}) + minetest.set_node(stempos, { name = connected_stem_names[4] }) p2 = 0 end -- Place the gourd if gourd_def.paramtype2 == "facedir" then - minetest.add_node(blockpos, {name=gourd_itemstring, param2=p2}) + minetest.add_node(blockpos, { name = gourd_itemstring, param2 = p2 }) else - minetest.add_node(blockpos, {name=gourd_itemstring}) + minetest.add_node(blockpos, { name = gourd_itemstring }) end + -- Reset farmland, etc. to dirt when the gourd grows on top + + -- FIXED: The following 2 lines were missing, and wasn't being set (outside of the above loop that + -- finds the neighbors.) + -- FYI - don't factor this out thinking that the loop above is setting the positions correctly. + floorpos = vector.offset (blockpos, 0, -1,0) -- replaces { x = blockpos.x, y = blockpos.y - 1, z = blockpos.z } + floor = minetest.get_node(floorpos) + -- END OF FIX ------------------------------------- if minetest.get_item_group(floor.name, "dirtifies_below_solid") == 1 then - minetest.set_node(floorpos, {name = "mcl_core:dirt"}) + minetest.set_node(floorpos, { name = "mcl_core:dirt" }) end end end @@ -444,7 +460,7 @@ end function mcl_farming:stem_color(startcolor, endcolor, step, step_count) local color = {} local function get_component(startt, endd, step, step_count) - return math.floor(math.max(0, math.min(255, (startt + (((step-1)/step_count) * endd))))) + return math.floor(math.max(0, math.min(255, (startt + (((step - 1) / step_count) * endd))))) end color.r = get_component(startcolor.r, endcolor.r, step, step_count) color.g = get_component(startcolor.g, endcolor.g, step, step_count) @@ -453,17 +469,32 @@ function mcl_farming:stem_color(startcolor, endcolor, step, step_count) return colorstring end +--[[Get a callback that either eats the item or plants it. + +Used for on_place callbacks for craft items which are seeds that can also be consumed. +]] +function mcl_farming:get_seed_or_eat_callback(plantname, hp_change) + return function(itemstack, placer, pointed_thing) + local new = mcl_farming:place_seed(itemstack, placer, pointed_thing, plantname) + if new then + return new + else + return minetest.do_item_eat(hp_change, nil, itemstack, placer, pointed_thing) + end + end +end + minetest.register_lbm({ label = "Add growth for unloaded farming plants", name = "mcl_farming:growth", - nodenames = {"group:plant"}, + nodenames = { "group:plant" }, run_at_every_load = true, action = function(pos, node) local identifier = plant_nodename_to_id_list[node.name] if not identifier then return end - local low_speed = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}).name ~= "mcl_farming:soil_wet" + local low_speed = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z }).name ~= "mcl_farming:soil_wet" mcl_farming:grow_plant(identifier, pos, node, false, false, low_speed) end, }) diff --git a/mods/ITEMS/mcl_farming/soil.lua b/mods/ITEMS/mcl_farming/soil.lua index 0c0e3b832..a6721cc26 100644 --- a/mods/ITEMS/mcl_farming/soil.lua +++ b/mods/ITEMS/mcl_farming/soil.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_node("mcl_farming:soil", { tiles = {"mcl_farming_farmland_dry.png", "default_dirt.png"}, @@ -21,7 +21,7 @@ minetest.register_node("mcl_farming:soil", { end, groups = {handy=1,shovely=1, dirtifies_below_solid=1, dirtifier=1, soil=2, soil_sapling=1, deco_block=1 }, sounds = mcl_sounds.node_sound_dirt_defaults(), - _mcl_blast_resistance = 0.5, + _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) @@ -76,7 +76,7 @@ minetest.register_abm({ end -- Check an area of 9×2×9 around the node for nodename (9×9 on same level and 9×9 below) - local check_surroundings = function(pos, nodename) + local function check_surroundings(pos, nodename) local nodes = minetest.find_nodes_in_area({x=pos.x-4,y=pos.y,z=pos.z-4}, {x=pos.x+4,y=pos.y+1,z=pos.z+4}, {nodename}) return #nodes > 0 end @@ -99,7 +99,7 @@ minetest.register_abm({ -- No decay near unloaded areas since these might include water. if not check_surroundings(pos, "ignore") then if wet <= 0 then - local n_def = minetest.registered_nodes[node.name] or nil + --local n_def = minetest.registered_nodes[node.name] or nil local nn = minetest.get_node_or_nil({x=pos.x,y=pos.y+1,z=pos.z}) if not nn or not nn.name then return diff --git a/mods/ITEMS/mcl_farming/sweet_berry.lua b/mods/ITEMS/mcl_farming/sweet_berry.lua new file mode 100644 index 000000000..7dc6326a4 --- /dev/null +++ b/mods/ITEMS/mcl_farming/sweet_berry.lua @@ -0,0 +1,128 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local planton = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:coarse_dirt", "mcl_farming:soil", "mcl_farming:soil_wet", "mcl_moss:moss"} + +for i=0, 3 do + local texture = "mcl_farming_sweet_berry_bush_" .. i .. ".png" + local node_name = "mcl_farming:sweet_berry_bush_" .. i + local groups = {sweet_berry=1, 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, flammable=3, fire_encouragement=60, fire_flammability=20, compostability=30} + if i > 0 then + groups.sweet_berry_thorny = 1 + end + local drop_berries = (i >= 2) + local berries_to_drop = drop_berries and {i - 1, i} or nil + + minetest.register_node(node_name, { + drawtype = "plantlike", + tiles = {texture}, + description = S("Sweet Berry Bush (Stage @1)", i), + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "meshoptions", + place_param2 = 3, + liquid_viscosity = 15, + liquidtype = "source", + liquid_alternative_flowing = node_name, + liquid_alternative_source = node_name, + liquid_renewable = false, + liquid_range = 0, + walkable = false, + -- Dont even create a table if no berries are dropped. + drop = not drop_berries and "" or { + max_items = 1, + items = { + { items = {"mcl_farming:sweet_berry " .. berries_to_drop[1] }, rarity = 2 }, + { items = {"mcl_farming:sweet_berry " .. berries_to_drop[2] } } + } + }, + selection_box = { + type = "fixed", + fixed = {-6 / 16, -0.5, -6 / 16, 6 / 16, (-0.30 + (i*0.25)), 6 / 16}, + }, + inventory_image = texture, + wield_image = texture, + groups = groups, + sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local pn = clicker:get_player_name() + if clicker:is_player() and minetest.is_protected(pos, pn) then + minetest.record_protection_violation(pos, pn) + return itemstack + 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) + if not minetest.is_creative_enabled(pn) then + itemstack:take_item() + end + return + end + + if drop_berries then + for j=1, berries_to_drop[math.random(2)] do + minetest.add_item(pos, "mcl_farming:sweet_berry") + end + minetest.swap_node(pos, {name = "mcl_farming:sweet_berry_bush_1"}) + end + return itemstack + end, + }) + minetest.register_alias("mcl_sweet_berry:sweet_berry_bush_" .. i, node_name) +end + +minetest.register_craftitem("mcl_farming:sweet_berry", { + description = S("Sweet Berry"), + inventory_image = "mcl_farming_sweet_berry.png", + _mcl_saturation = 0.4, + groups = { food = 2, eatable = 1, compostability=30 }, + on_secondary_use = minetest.item_eat(1), + on_place = function(itemstack, placer, pointed_thing) + local pn = placer:get_player_name() + if placer:is_player() and minetest.is_protected(pointed_thing.above, pn or "") then + minetest.record_protection_violation(pointed_thing.above, pn) + return itemstack + end + if pointed_thing.type == "node" and + table.indexof(planton, minetest.get_node(pointed_thing.under).name) ~= -1 and + pointed_thing.above.y > pointed_thing.under.y and + minetest.get_node(pointed_thing.above).name == "air" then + minetest.set_node(pointed_thing.above, {name="mcl_farming:sweet_berry_bush_0"}) + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + return itemstack + end + return minetest.do_item_eat(1, nil, itemstack, placer, pointed_thing) + end, +}) +minetest.register_alias("mcl_sweet_berry:sweet_berry", "mcl_farming:sweet_berry") + +-- TODO: Find proper interval and chance values for sweet berry bushes. Current interval and chance values are copied from mcl_farming:beetroot which has similar growth stages. +mcl_farming:add_plant("plant_sweet_berry_bush", "mcl_farming:sweet_berry_bush_3", {"mcl_farming:sweet_berry_bush_0", "mcl_farming:sweet_berry_bush_1", "mcl_farming:sweet_berry_bush_2"}, 68, 3) + +local function berry_damage_check(obj) + local p = obj:get_pos() + if not p then return end + if not minetest.find_node_near(p,0.4,{"group:sweet_berry_thorny"},true) then return end + local v = obj:get_velocity() + if math.abs(v.x) < 0.1 and math.abs(v.y) < 0.1 and math.abs(v.z) < 0.1 then return end + + mcl_util.deal_damage(obj, 0.5, {type = "sweet_berry"}) +end + +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 + berry_damage_check(pl) + end + for _,ent in pairs(minetest.luaentities) do + if ent.is_mob then + berry_damage_check(ent.object) + end + end +end) diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot_4.png b/mods/ITEMS/mcl_farming/textures/farming_carrot_4.png deleted file mode 100644 index d1017eee1..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_carrot_4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_melon_side.png b/mods/ITEMS/mcl_farming/textures/farming_melon_side.png deleted file mode 100644 index 6630ce52b..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_melon_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_melon_top.png b/mods/ITEMS/mcl_farming/textures/farming_melon_top.png deleted file mode 100644 index 770871c92..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_melon_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_potato.png b/mods/ITEMS/mcl_farming/textures/farming_potato.png deleted file mode 100644 index 6614adcb2..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_potato.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_side.png b/mods/ITEMS/mcl_farming/textures/farming_pumpkin_side.png deleted file mode 100644 index 9ed67ca23..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_top.png b/mods/ITEMS/mcl_farming/textures/farming_pumpkin_top.png deleted file mode 100644 index 73d1ef540..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_diamondhoe.png b/mods/ITEMS/mcl_farming/textures/farming_tool_diamondhoe.png deleted file mode 100644 index 0adc102ac..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/farming_tool_diamondhoe.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_dry.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_dry.png deleted file mode 100644 index 4606f6fa3..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_dry.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_wet.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_wet.png deleted file mode 100644 index bad8fb002..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_farmland_wet.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_hayblock_side.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_hayblock_side.png deleted file mode 100644 index ec51c0d74..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_hayblock_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png deleted file mode 100644 index a2fd0fbf9..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face_preview.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face_preview.png deleted file mode 100644 index a151fcab6..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_face_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_seeds.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_seeds.png deleted file mode 100644 index 52c239c7f..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_seeds.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_2.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_2.png deleted file mode 100644 index 3788a40da..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_3.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_3.png deleted file mode 100644 index 889a56d63..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_4.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_4.png deleted file mode 100644 index 91bdd2b32..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_6.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_6.png deleted file mode 100644 index 6b2b23078..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_6.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_7.png b/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_7.png deleted file mode 100644 index 83d259274..000000000 Binary files a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_7.png and /dev/null differ diff --git a/mods/ITEMS/mcl_farming/wheat.lua b/mods/ITEMS/mcl_farming/wheat.lua index 9a8a9f65e..15fd98e2a 100644 --- a/mods/ITEMS/mcl_farming/wheat.lua +++ b/mods/ITEMS/mcl_farming/wheat.lua @@ -1,12 +1,13 @@ -local S = minetest.get_translator("mcl_farming") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_craftitem("mcl_farming:wheat_seeds", { -- Original Minecraft name: “Seeds” description = S("Wheat Seeds"), _tt_help = S("Grows on farmland"), _doc_items_longdesc = S("Grows into a wheat plant. Chickens like wheat seeds."), - _doc_items_usagehelp = S("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."), - groups = { craftitem=1 }, + _doc_items_usagehelp = S("Place the wheat seeds on farmland (which can be created with a hoe) to plant a wheat plant.").."\n".. + S("They grow in sunlight and grow faster on hydrated farmland. Rightclick an animal to feed it wheat seeds."), + groups = {craftitem = 1, compostability = 30}, inventory_image = "mcl_farming_wheat_seeds.png", on_place = function(itemstack, placer, pointed_thing) return mcl_farming:place_seed(itemstack, placer, pointed_thing, "mcl_farming:wheat_1") @@ -28,7 +29,8 @@ for i=1,7 do if i == 1 then create = true name = S("Premature Wheat Plant") - longdesc = S("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.") + longdesc = S("Premature wheat plants grow on farmland under sunlight in 8 stages.").."\n".. + S("On hydrated farmland, they grow faster. They can be harvested at any time but will only yield a profit when mature.") else create = false end @@ -54,7 +56,8 @@ for i=1,7 do {-0.5, -0.5, -0.5, 0.5, sel_heights[i], 0.5} }, }, - 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}, + 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, }) @@ -62,7 +65,8 @@ end minetest.register_node("mcl_farming:wheat", { description = S("Mature Wheat Plant"), - _doc_items_longdesc = S("Mature wheat plants are ready to be harvested for wheat and wheat seeds. They won't grow any further."), + _doc_items_longdesc = S("Mature wheat plants are ready to be harvested for wheat and wheat seeds.").."\n".. + S("They won't grow any further."), sunlight_propagates = true, paramtype = "light", paramtype2 = "meshoptions", @@ -75,13 +79,14 @@ minetest.register_node("mcl_farming:wheat", { drop = { max_items = 4, items = { - { items = {'mcl_farming:wheat_seeds'} }, - { items = {'mcl_farming:wheat_seeds'}, rarity = 2}, - { items = {'mcl_farming:wheat_seeds'}, rarity = 5}, - { items = {'mcl_farming:wheat_item'} } + { items = {"mcl_farming:wheat_seeds"} }, + { items = {"mcl_farming:wheat_seeds"}, rarity = 2}, + { items = {"mcl_farming:wheat_seeds"}, rarity = 5}, + { items = {"mcl_farming:wheat_item"} } } }, - 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}, + 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, }) @@ -93,20 +98,20 @@ minetest.register_craftitem("mcl_farming:wheat_item", { _doc_items_longdesc = S("Wheat is used in crafting. Some animals like wheat."), _doc_items_usagehelp = S("Use the “Place” key on an animal to try to feed it wheat."), inventory_image = "farming_wheat_harvested.png", - groups = { craftitem = 1 }, + groups = {craftitem = 1, compostability = 65}, }) minetest.register_craft({ output = "mcl_farming:bread", recipe = { - {'mcl_farming:wheat_item', 'mcl_farming:wheat_item', 'mcl_farming:wheat_item'}, + {"mcl_farming:wheat_item", "mcl_farming:wheat_item", "mcl_farming:wheat_item"}, } }) minetest.register_craft({ output = "mcl_farming:cookie 8", recipe = { - {'mcl_farming:wheat_item', 'mcl_dye:brown', 'mcl_farming:wheat_item'}, + {"mcl_farming:wheat_item", "mcl_cocoas:cocoa_beans", "mcl_farming:wheat_item"}, } }) @@ -114,7 +119,7 @@ minetest.register_craftitem("mcl_farming:cookie", { description = S("Cookie"), _doc_items_longdesc = S("This is a food item which can be eaten."), inventory_image = "farming_cookie.png", - groups = {food=2, eatable=2}, + groups = {food = 2, eatable = 2, compostability = 85}, _mcl_saturation = 0.4, on_place = minetest.item_eat(2), on_secondary_use = minetest.item_eat(2), @@ -125,13 +130,13 @@ minetest.register_craftitem("mcl_farming:bread", { description = S("Bread"), _doc_items_longdesc = S("This is a food item which can be eaten."), inventory_image = "farming_bread.png", - groups = {food=2, eatable=5}, + groups = {food = 2, eatable = 5, compostability = 85}, _mcl_saturation = 6.0, on_place = minetest.item_eat(5), on_secondary_use = minetest.item_eat(5), }) -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil +local mod_screwdriver = minetest.get_modpath("screwdriver") local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way @@ -144,9 +149,12 @@ minetest.register_node("mcl_farming:hay_block", { is_ground_content = false, stack_max = 64, paramtype2 = "facedir", - is_ground_content = false, on_place = mcl_util.rotate_axis, - groups = {handy=1, flammable=2, fire_encouragement=60, fire_flammability=20, building_block=1, fall_damage_add_percent=-80}, + groups = { + handy = 1, hoey = 1, building_block = 1, fall_damage_add_percent = -80, + flammable = 2, fire_encouragement = 60, fire_flammability = 20, + compostability = 85 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), on_rotate = on_rotate, _mcl_blast_resistance = 0.5, @@ -154,18 +162,18 @@ minetest.register_node("mcl_farming:hay_block", { }) minetest.register_craft({ - output = 'mcl_farming:hay_block', + output = "mcl_farming:hay_block", recipe = { - {'mcl_farming:wheat_item', 'mcl_farming:wheat_item', 'mcl_farming:wheat_item'}, - {'mcl_farming:wheat_item', 'mcl_farming:wheat_item', 'mcl_farming:wheat_item'}, - {'mcl_farming:wheat_item', 'mcl_farming:wheat_item', 'mcl_farming:wheat_item'}, + {"mcl_farming:wheat_item", "mcl_farming:wheat_item", "mcl_farming:wheat_item"}, + {"mcl_farming:wheat_item", "mcl_farming:wheat_item", "mcl_farming:wheat_item"}, + {"mcl_farming:wheat_item", "mcl_farming:wheat_item", "mcl_farming:wheat_item"}, } }) minetest.register_craft({ - output = 'mcl_farming:wheat_item 9', + output = "mcl_farming:wheat_item 9", recipe = { - {'mcl_farming:hay_block'}, + {"mcl_farming:hay_block"}, } }) diff --git a/mods/ITEMS/mcl_fences/depends.txt b/mods/ITEMS/mcl_fences/depends.txt deleted file mode 100644 index 217875c56..000000000 --- a/mods/ITEMS/mcl_fences/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_sounds -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_fences/init.lua b/mods/ITEMS/mcl_fences/init.lua index 650854f88..b14d103d2 100644 --- a/mods/ITEMS/mcl_fences/init.lua +++ b/mods/ITEMS/mcl_fences/init.lua @@ -1,306 +1,306 @@ -local S = minetest.get_translator("mcl_fences") - --- Node box -local p = {-2/16, -0.5, -2/16, 2/16, 0.5, 2/16} -local x1 = {-0.5, 4/16, -1/16, -2/16, 7/16, 1/16} --oben(quer) -x -local x12 = {-0.5, -2/16, -1/16, -2/16, 1/16, 1/16} --unten(quer) -x -local x2 = {2/16, 4/16, -1/16, 0.5, 7/16, 1/16} --oben(quer) x -local x22 = {2/16, -2/16, -1/16, 0.5, 1/16, 1/16} --unten(quer) x -local z1 = {-1/16, 4/16, -0.5, 1/16, 7/16, -2/16} --oben(quer) -z -local z12 = {-1/16, -2/16, -0.5, 1/16, 1/16, -2/16} --unten(quer) -z -local z2 = {-1/16, 4/16, 2/16, 1/16, 7/16, 0.5} --oben(quer) z -local z22 = {-1/16, -2/16, 2/16, 1/16, 1/16, 0.5} --unten(quer) z - --- Collision box -local cp = {-2/16, -0.5, -2/16, 2/16, 1.01, 2/16} -local cx1 = {-0.5, -0.5, -2/16, -2/16, 1.01, 2/16} --unten(quer) -x -local cx2 = {2/16, -0.5, -2/16, 0.5, 1.01, 2/16} --unten(quer) x -local cz1 = {-2/16, -0.5, -0.5, 2/16, 1.01, -2/16} --unten(quer) -z -local cz2 = {-2/16, -0.5, 2/16, 2/16, 1.01, 0.5} --unten(quer) z - -mcl_fences = {} - -mcl_fences.register_fence = function(id, fence_name, texture, groups, hardness, blast_resistance, connects_to, sounds) - local cgroups = table.copy(groups) - if cgroups == nil then cgroups = {} end - cgroups.fence = 1 - cgroups.deco_block = 1 - if connects_to == nil then - connects_to = {} - else - connects_to = table.copy(connects_to) - end - local fence_id = minetest.get_current_modname()..":"..id - table.insert(connects_to, "group:solid") - table.insert(connects_to, "group:fence_gate") - table.insert(connects_to, fence_id) - minetest.register_node(fence_id, { - description = fence_name, - _doc_items_longdesc = S("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."), - tiles = {texture}, - inventory_image = "mcl_fences_fence_mask.png^" .. texture .. "^mcl_fences_fence_mask.png^[makealpha:255,126,126", - wield_image = "mcl_fences_fence_mask.png^" .. texture .. "^mcl_fences_fence_mask.png^[makealpha:255,126,126", - paramtype = "light", - is_ground_content = false, - groups = cgroups, - stack_max = 64, - sunlight_propagates = true, - drawtype = "nodebox", - connect_sides = { "front", "back", "left", "right" }, - connects_to = connects_to, - node_box = { - type = "connected", - fixed = {p}, - connect_front = {z1,z12}, - connect_back = {z2,z22,}, - connect_left = {x1,x12}, - connect_right = {x2,x22}, - }, - collision_box = { - type = "connected", - fixed = {cp}, - connect_front = {cz1}, - connect_back = {cz2,}, - connect_left = {cx1}, - connect_right = {cx2}, - }, - sounds = sounds, - _mcl_blast_resistance = blast_resistance, - _mcl_hardness = hardness, - }) - - return fence_id -end - -mcl_fences.register_fence_gate = function(id, fence_gate_name, texture, groups, hardness, blast_resistance, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close) - local meta2 - local state2 = 0 - - local function update_gate(pos, node) - minetest.set_node(pos, node) - end - - local gate_id = minetest.get_current_modname()..":"..id.."_gate" - local open_gate_id = gate_id .. "_open" - if not sound_open then - sound_open = "doors_fencegate_open" - end - if not sound_close then - sound_close = "doors_fencegate_close" - end - if not sound_gain_open then - sound_gain_open = 0.3 - end - if not sound_gain_close then - sound_gain_close = 0.3 - end - local function punch_gate(pos, node) - meta2 = minetest.get_meta(pos) - state2 = meta2:get_int("state") - local tmp_node2 - if state2 == 1 then - state2 = 0 - minetest.sound_play(sound_close, {gain = sound_gain_close, max_hear_distance = 10, pos = pos}, true) - tmp_node2 = {name=gate_id, param1=node.param1, param2=node.param2} - else - state2 = 1 - minetest.sound_play(sound_open, {gain = sound_gain_open, max_hear_distance = 10, pos = pos}, true) - tmp_node2 = {name=open_gate_id, param1=node.param1, param2=node.param2} - end - update_gate(pos, tmp_node2) - meta2:set_int("state", state2) - end - - local on_rotate - if minetest.get_modpath("screwdriver") then - on_rotate = screwdriver.rotate_simple - end - - local cgroups = table.copy(groups) - if cgroups == nil then cgroups = {} end - cgroups.fence_gate = 1 - cgroups.deco_block = 1 - - cgroups.mesecon_ignore_opaque_dig = 1 - cgroups.mesecon_effector_on = 1 - cgroups.fence_gate = 1 - minetest.register_node(open_gate_id, { - tiles = {texture}, - paramtype = "light", - paramtype2 = "facedir", - is_ground_content = false, - sunlight_propagates = true, - walkable = false, - groups = cgroups, - drop = gate_id, - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-0.5, -3/16, -1/16, -6/16, 0.5, 1/16}, --links abschluss - {6/16, -3/16, -1/16, 0.5, 0.5, 1/16}, --rechts abschluss - {-0.5, 4/16, 1/16, -6/16, 7/16, 6/16}, --oben-links(quer) x - {-0.5, -2/16, 1/16, -6/16, 1/16, 6/16}, --unten-links(quer) x - {6/16, 4/16, 1/16, 0.5, 7/16, 0.5}, --oben-rechts(quer) x - {6/16, -2/16, 1/16, 0.5, 1/16, 0.5}, --unten-rechts(quer) x - {-0.5, -2/16, 6/16, -6/16, 7/16, 0.5}, --mitte links - {6/16, 1/16, 0.5, 0.5, 4/16, 6/16}, --mitte rechts - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -3/16, -1/16, 0.5, 0.5, 1/16}, --gate - } - }, - on_rightclick = function(pos, node, clicker) - punch_gate(pos, node) - end, - mesecons = {effector = { - action_off = (function(pos, node) - punch_gate(pos, node) - end), - }}, - on_rotate = on_rotate, - sounds = sounds, - _mcl_blast_resistance = blast_resistance, - _mcl_hardness = hardness, - }) - - local cgroups_closed = table.copy(cgroups) - cgroups_closed.mesecon_effector_on = nil - cgroups_closed.mesecon_effector_off = nil - minetest.register_node(gate_id, { - description = fence_gate_name, - _tt_help = S("Openable by players and redstone power"), - _doc_items_longdesc = S("Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates."), - _doc_items_usagehelp = S("Right-click the fence gate to open or close it."), - tiles = {texture}, - inventory_image = "mcl_fences_fence_gate_mask.png^" .. texture .. "^mcl_fences_fence_gate_mask.png^[makealpha:255,126,126", - wield_image = "mcl_fences_fence_gate_mask.png^" .. texture .. "^mcl_fences_fence_gate_mask.png^[makealpha:255,126,126", - paramtype = "light", - is_ground_content = false, - stack_max = 64, - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - groups = cgroups_closed, - drawtype = "nodebox", - node_box = { - type = "fixed", - fixed = { - {-0.5, -3/16, -1/16, -6/16, 0.5, 1/16}, --links abschluss - {6/16, -3/16, -1/16, 0.5, 0.5, 1/16}, --rechts abschluss - {-2/16, -2/16, -1/16, 0, 7/16, 1/16}, --mitte links - {0, -2/16, -1/16, 2/16, 7/16, 1/16}, --mitte rechts - {-0.5, 4/16, -1/16, -2/16, 7/16, 1/16}, --oben(quer) -z - {-0.5, -2/16, -1/16, -2/16, 1/16, 1/16}, --unten(quer) -z - {2/16, 4/16, -1/16, 0.5, 7/16, 1/16}, --oben(quer) z - {2/16, -2/16, -1/16, 0.5, 1/16, 1/16}, --unten(quer) z - } - }, - collision_box = { - type = "fixed", - fixed = { - {-0.5, -3/16, -2/16, 0.5, 1, 2/16}, --gate - } - }, - selection_box = { - type = "fixed", - fixed = { - {-0.5, -3/16, -1/16, 0.5, 0.5, 1/16}, --gate - } - }, - on_construct = function(pos) - meta2 = minetest.get_meta(pos) - meta2:set_int("state", 0) - state2 = 0 - end, - mesecons = {effector = { - action_on = (function(pos, node) - punch_gate(pos, node) - end), - }}, - on_rotate = on_rotate, - on_rightclick = function(pos, node, clicker) - punch_gate(pos, node) - end, - sounds = sounds, - _mcl_blast_resistance = blast_resistance, - _mcl_hardness = hardness, - }) - - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", gate_id, "nodes", open_gate_id) - end - - return gate_id, open_gate_id -end - -mcl_fences.register_fence_and_fence_gate = function(id, fence_name, fence_gate_name, texture_fence, groups, hardness, blast_resistance, connects_to, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close, texture_fence_gate) - if texture_fence_gate == nil then - texture_fence_gate = texture_fence - end - local fence_id = mcl_fences.register_fence(id, fence_name, texture_fence, groups, hardness, blast_resistance, connects_to, sounds) - local gate_id, open_gate_id = mcl_fences.register_fence_gate(id, fence_gate_name, texture_fence_gate, groups, hardness, blast_resistance, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close) - return fence_id, gate_id, open_gate_id -end - -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 wood_sounds = mcl_sounds.node_sound_wood_defaults() - -local woods = { - {"", S("Oak Fence"), S("Oak Fence Gate"), "mcl_fences_fence_oak.png", "mcl_fences_fence_gate_oak.png", "mcl_core:wood"}, - {"spruce", S("Spruce Fence"), S("Spruce Fence Gate"), "mcl_fences_fence_spruce.png", "mcl_fences_fence_gate_spruce.png", "mcl_core:sprucewood"}, - {"birch", S("Birch Fence"), S("Birch Fence Gate"), "mcl_fences_fence_birch.png", "mcl_fences_fence_gate_birch.png", "mcl_core:birchwood"}, - {"jungle", S("Jungle Fence"), S("Jungle Fence Gate"), "mcl_fences_fence_jungle.png", "mcl_fences_fence_gate_jungle.png", "mcl_core:junglewood"}, - {"dark_oak", S("Dark Oak Fence"), S("Dark Oak Fence Gate"), "mcl_fences_fence_big_oak.png", "mcl_fences_fence_gate_big_oak.png", "mcl_core:darkwood"}, - {"acacia", S("Acacia Fence"), S("Acacia Fence Gate"), "mcl_fences_fence_acacia.png", "mcl_fences_fence_gate_acacia.png", "mcl_core:acaciawood"}, -} - -for w=1, #woods do - local wood = woods[w] - local id, id_gate - if wood[1] == "" then - id = "fence" - id_gate = "fence_gate" - else - 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) - - minetest.register_craft({ - output = 'mcl_fences:'..id..' 3', - recipe = { - {wood[6], 'mcl_core:stick', wood[6]}, - {wood[6], 'mcl_core:stick', wood[6]}, - } - }) - minetest.register_craft({ - output = 'mcl_fences:'..id_gate, - recipe = { - {'mcl_core:stick', wood[6], 'mcl_core:stick'}, - {'mcl_core:stick', wood[6], 'mcl_core:stick'}, - } - }) -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()) - -minetest.register_craft({ - output = 'mcl_fences:nether_brick_fence 6', - recipe = { - {"mcl_nether:nether_brick", "mcl_nether:netherbrick", "mcl_nether:nether_brick"}, - {"mcl_nether:nether_brick", "mcl_nether:netherbrick", "mcl_nether:nether_brick"}, - } -}) - -minetest.register_craft({ - type = "fuel", - recipe = "group:fence_wood", - burntime = 15, -}) +local S = minetest.get_translator(minetest.get_current_modname()) + +-- Node box +local p = {-2/16, -0.5, -2/16, 2/16, 0.5, 2/16} +local x1 = {-0.5, 4/16, -1/16, -2/16, 7/16, 1/16} --oben(quer) -x +local x12 = {-0.5, -2/16, -1/16, -2/16, 1/16, 1/16} --unten(quer) -x +local x2 = {2/16, 4/16, -1/16, 0.5, 7/16, 1/16} --oben(quer) x +local x22 = {2/16, -2/16, -1/16, 0.5, 1/16, 1/16} --unten(quer) x +local z1 = {-1/16, 4/16, -0.5, 1/16, 7/16, -2/16} --oben(quer) -z +local z12 = {-1/16, -2/16, -0.5, 1/16, 1/16, -2/16} --unten(quer) -z +local z2 = {-1/16, 4/16, 2/16, 1/16, 7/16, 0.5} --oben(quer) z +local z22 = {-1/16, -2/16, 2/16, 1/16, 1/16, 0.5} --unten(quer) z + +-- Collision box +local cp = {-2/16, -0.5, -2/16, 2/16, 1.01, 2/16} +local cx1 = {-0.5, -0.5, -2/16, -2/16, 1.01, 2/16} --unten(quer) -x +local cx2 = {2/16, -0.5, -2/16, 0.5, 1.01, 2/16} --unten(quer) x +local cz1 = {-2/16, -0.5, -0.5, 2/16, 1.01, -2/16} --unten(quer) -z +local cz2 = {-2/16, -0.5, 2/16, 2/16, 1.01, 0.5} --unten(quer) z + +mcl_fences = {} + +function mcl_fences.register_fence(id, fence_name, texture, groups, hardness, blast_resistance, connects_to, sounds) + local cgroups = table.copy(groups) + if cgroups == nil then cgroups = {} end + cgroups.fence = 1 + cgroups.deco_block = 1 + if connects_to == nil then + connects_to = {} + else + connects_to = table.copy(connects_to) + end + local fence_id = minetest.get_current_modname()..":"..id + table.insert(connects_to, "group:solid") + table.insert(connects_to, "group:fence_gate") + table.insert(connects_to, fence_id) + minetest.register_node(fence_id, { + description = fence_name, + _doc_items_longdesc = S("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."), + tiles = {texture}, + inventory_image = "mcl_fences_fence_mask.png^" .. texture .. "^mcl_fences_fence_mask.png^[makealpha:255,126,126", + wield_image = "mcl_fences_fence_mask.png^" .. texture .. "^mcl_fences_fence_mask.png^[makealpha:255,126,126", + paramtype = "light", + is_ground_content = false, + groups = cgroups, + stack_max = 64, + sunlight_propagates = true, + drawtype = "nodebox", + connect_sides = { "front", "back", "left", "right" }, + connects_to = connects_to, + node_box = { + type = "connected", + fixed = {p}, + connect_front = {z1,z12}, + connect_back = {z2,z22,}, + connect_left = {x1,x12}, + connect_right = {x2,x22}, + }, + collision_box = { + type = "connected", + fixed = {cp}, + connect_front = {cz1}, + connect_back = {cz2,}, + connect_left = {cx1}, + connect_right = {cx2}, + }, + sounds = sounds, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, + }) + + return fence_id +end + +function mcl_fences.register_fence_gate(id, fence_gate_name, texture, groups, hardness, blast_resistance, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close) + local meta2 + local state2 = 0 + + local function update_gate(pos, node) + minetest.set_node(pos, node) + end + + local gate_id = minetest.get_current_modname()..":"..id.."_gate" + local open_gate_id = gate_id .. "_open" + if not sound_open then + sound_open = "doors_fencegate_open" + end + if not sound_close then + sound_close = "doors_fencegate_close" + end + if not sound_gain_open then + sound_gain_open = 0.3 + end + if not sound_gain_close then + sound_gain_close = 0.3 + end + local function punch_gate(pos, node) + meta2 = minetest.get_meta(pos) + state2 = meta2:get_int("state") + local tmp_node2 + if state2 == 1 then + state2 = 0 + minetest.sound_play(sound_close, {gain = sound_gain_close, max_hear_distance = 10, pos = pos}, true) + tmp_node2 = {name=gate_id, param1=node.param1, param2=node.param2} + else + state2 = 1 + minetest.sound_play(sound_open, {gain = sound_gain_open, max_hear_distance = 10, pos = pos}, true) + tmp_node2 = {name=open_gate_id, param1=node.param1, param2=node.param2} + end + update_gate(pos, tmp_node2) + meta2:set_int("state", state2) + end + + local on_rotate + if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.rotate_simple + end + + local cgroups = table.copy(groups) + if cgroups == nil then cgroups = {} end + cgroups.fence_gate = 1 + cgroups.deco_block = 1 + + cgroups.mesecon_ignore_opaque_dig = 1 + cgroups.mesecon_effector_on = 1 + cgroups.fence_gate = 1 + minetest.register_node(open_gate_id, { + tiles = {texture}, + paramtype = "light", + paramtype2 = "facedir", + is_ground_content = false, + sunlight_propagates = true, + walkable = false, + groups = cgroups, + drop = gate_id, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -3/16, -1/16, -6/16, 0.5, 1/16}, --links abschluss + {6/16, -3/16, -1/16, 0.5, 0.5, 1/16}, --rechts abschluss + {-0.5, 4/16, 1/16, -6/16, 7/16, 6/16}, --oben-links(quer) x + {-0.5, -2/16, 1/16, -6/16, 1/16, 6/16}, --unten-links(quer) x + {6/16, 4/16, 1/16, 0.5, 7/16, 0.5}, --oben-rechts(quer) x + {6/16, -2/16, 1/16, 0.5, 1/16, 0.5}, --unten-rechts(quer) x + {-0.5, -2/16, 6/16, -6/16, 7/16, 0.5}, --mitte links + {6/16, 1/16, 0.5, 0.5, 4/16, 6/16}, --mitte rechts + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -3/16, -1/16, 0.5, 0.5, 1/16}, --gate + } + }, + on_rightclick = function(pos, node, clicker) + punch_gate(pos, node) + end, + mesecons = {effector = { + action_off = (function(pos, node) + punch_gate(pos, node) + end), + }}, + on_rotate = on_rotate, + sounds = sounds, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, + }) + + local cgroups_closed = table.copy(cgroups) + cgroups_closed.mesecon_effector_on = nil + cgroups_closed.mesecon_effector_off = nil + minetest.register_node(gate_id, { + description = fence_gate_name, + _tt_help = S("Openable by players and redstone power"), + _doc_items_longdesc = S("Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates."), + _doc_items_usagehelp = S("Right-click the fence gate to open or close it."), + tiles = {texture}, + inventory_image = "mcl_fences_fence_gate_mask.png^" .. texture .. "^mcl_fences_fence_gate_mask.png^[makealpha:255,126,126", + wield_image = "mcl_fences_fence_gate_mask.png^" .. texture .. "^mcl_fences_fence_gate_mask.png^[makealpha:255,126,126", + paramtype = "light", + is_ground_content = false, + stack_max = 64, + paramtype2 = "facedir", + sunlight_propagates = true, + walkable = true, + groups = cgroups_closed, + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -3/16, -1/16, -6/16, 0.5, 1/16}, --links abschluss + {6/16, -3/16, -1/16, 0.5, 0.5, 1/16}, --rechts abschluss + {-2/16, -2/16, -1/16, 0, 7/16, 1/16}, --mitte links + {0, -2/16, -1/16, 2/16, 7/16, 1/16}, --mitte rechts + {-0.5, 4/16, -1/16, -2/16, 7/16, 1/16}, --oben(quer) -z + {-0.5, -2/16, -1/16, -2/16, 1/16, 1/16}, --unten(quer) -z + {2/16, 4/16, -1/16, 0.5, 7/16, 1/16}, --oben(quer) z + {2/16, -2/16, -1/16, 0.5, 1/16, 1/16}, --unten(quer) z + } + }, + collision_box = { + type = "fixed", + fixed = { + {-0.5, -3/16, -2/16, 0.5, 1, 2/16}, --gate + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.5, -3/16, -1/16, 0.5, 0.5, 1/16}, --gate + } + }, + on_construct = function(pos) + meta2 = minetest.get_meta(pos) + meta2:set_int("state", 0) + state2 = 0 + end, + mesecons = {effector = { + action_on = (function(pos, node) + punch_gate(pos, node) + end), + }}, + on_rotate = on_rotate, + on_rightclick = function(pos, node, clicker) + punch_gate(pos, node) + end, + sounds = sounds, + _mcl_blast_resistance = blast_resistance, + _mcl_hardness = hardness, + }) + + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", gate_id, "nodes", open_gate_id) + end + + return gate_id, open_gate_id +end + +function mcl_fences.register_fence_and_fence_gate(id, fence_name, fence_gate_name, texture_fence, groups, hardness, blast_resistance, connects_to, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close, texture_fence_gate) + if texture_fence_gate == nil then + texture_fence_gate = texture_fence + end + local fence_id = mcl_fences.register_fence(id, fence_name, texture_fence, groups, hardness, blast_resistance, connects_to, sounds) + local gate_id, open_gate_id = mcl_fences.register_fence_gate(id, fence_gate_name, texture_fence_gate, groups, hardness, blast_resistance, sounds, sound_open, sound_close, sound_gain_open, sound_gain_close) + return fence_id, gate_id, open_gate_id +end + +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 wood_sounds = mcl_sounds.node_sound_wood_defaults() + +local woods = { + {"", S("Oak Fence"), S("Oak Fence Gate"), "mcl_fences_fence_oak.png", "mcl_fences_fence_gate_oak.png", "mcl_core:wood"}, + {"spruce", S("Spruce Fence"), S("Spruce Fence Gate"), "mcl_fences_fence_spruce.png", "mcl_fences_fence_gate_spruce.png", "mcl_core:sprucewood"}, + {"birch", S("Birch Fence"), S("Birch Fence Gate"), "mcl_fences_fence_birch.png", "mcl_fences_fence_gate_birch.png", "mcl_core:birchwood"}, + {"jungle", S("Jungle Fence"), S("Jungle Fence Gate"), "mcl_fences_fence_jungle.png", "mcl_fences_fence_gate_jungle.png", "mcl_core:junglewood"}, + {"dark_oak", S("Dark Oak Fence"), S("Dark Oak Fence Gate"), "mcl_fences_fence_big_oak.png", "mcl_fences_fence_gate_big_oak.png", "mcl_core:darkwood"}, + {"acacia", S("Acacia Fence"), S("Acacia Fence Gate"), "mcl_fences_fence_acacia.png", "mcl_fences_fence_gate_acacia.png", "mcl_core:acaciawood"}, +} + +for w=1, #woods do + local wood = woods[w] + local id, id_gate + if wood[1] == "" then + id = "fence" + id_gate = "fence_gate" + else + 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) + + minetest.register_craft({ + output = "mcl_fences:"..id.." 3", + recipe = { + {wood[6], "mcl_core:stick", wood[6]}, + {wood[6], "mcl_core:stick", wood[6]}, + } + }) + minetest.register_craft({ + output = "mcl_fences:"..id_gate, + recipe = { + {"mcl_core:stick", wood[6], "mcl_core:stick"}, + {"mcl_core:stick", wood[6], "mcl_core:stick"}, + } + }) +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()) + +minetest.register_craft({ + output = "mcl_fences:nether_brick_fence 6", + recipe = { + {"mcl_nether:nether_brick", "mcl_nether:netherbrick", "mcl_nether:nether_brick"}, + {"mcl_nether:nether_brick", "mcl_nether:netherbrick", "mcl_nether:nether_brick"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "group:fence_wood", + burntime = 15, +}) diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.de.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.de.tr index 5a76fc59e..e4f2a5fa6 100644 --- a/mods/ITEMS/mcl_fences/locale/mcl_fences.de.tr +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.de.tr @@ -1,6 +1,6 @@ # 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.=Zäune sind Gebäude, die den Weg blockieren. Sie verbinden sich gegenseitig und anderen festen Blöcken. Man kann sie nicht mit normalen Sprüngen überspringen. -Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune werden sich gut mit Zauntoren verbinden. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Zauntore können geöffnet und geschlossen werden und können nicht übersprungen werden. Zäune lassen sich gut mit Zauntoren verbinden. Right-click the fence gate to open or close it.=Rechtsklicken Sie auf ein Zauntor, um es zu öffnen oder zu schließen. Oak Fence=Eichenzaun Oak Fence Gate=Eichenzauntor diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.es.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.es.tr index 1e8c3798a..eff541f00 100644 --- a/mods/ITEMS/mcl_fences/locale/mcl_fences.es.tr +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.es.tr @@ -1,6 +1,6 @@ # 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.=Las cercas son estructuras que bloquean el camino. Las cercas se conectarán entre sí y con los bloques sólidos. No se pueden saltar con un simple salto. -Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Las puertas de valla se pueden abrir o cerrar y no se pueden saltar. Las cercas se conectarán muy bien a las puertas de la cerca. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Las puertas de cerca se pueden abrir o cerrar y no se pueden saltar. Las cercas se conectarán muy bien a las puertas de la cerca. Right-click the fence gate to open or close it.=Haga clic derecho en la puerta de la cerca para abrirla o cerrarla. Oak Fence=Valla de roble Oak Fence Gate=Puerta de roble @@ -9,9 +9,10 @@ Spruce Fence Gate=Puerta de abeto Birch Fence=Valla de abedul Birch Fence Gate=Puerta de abedul Jungle Fence=Valla de la selva -Jungle Fence Gate=Puerta de valla de la selva +Jungle Fence Gate=Puerta de cerca de la selva Dark Oak Fence=Valla de roble oscuro Dark Oak Fence Gate=Puerta de roble oscuro Acacia Fence=Valla de acacia Acacia Fence Gate=Puerta de acacia -Nether Brick Fence=Valla de ladrillo abisal \ No newline at end of file +Nether Brick Fence=Valla de ladrillo abisal +Openable by players and redstone power=Puede ser abierta por jugadores y por señales de redstone diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.fr.tr index ccfb86d95..1044cf148 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 portillions 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 portillion pour l'ouvrir ou la fermer. +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=Portillion 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=Portillion en bois de Sapin +Spruce Fence Gate=Portillon en bois de Sapin Birch Fence=Barrière en bois de Bouleau -Birch Fence Gate=Portillion en bois de Bouleau +Birch Fence Gate=Portillon en bois de Bouleau Jungle Fence=Barrière en bois d'Acajou -Jungle Fence Gate=Portillion 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=Portillion 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=Portillion 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.ja.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.ja.tr new file mode 100644 index 000000000..80eaadaa5 --- /dev/null +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.ja.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.=フェンスは道を塞ぐ構造物です。他のフェンスや固体ブロックに隣接すると繋がります。単なるジャンプでは飛び越えられません。 +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=ジャングルのフェンスゲート +Dark Oak Fence=ダークオークのフェンス +Dark Oak Fence Gate=ダークオークのフェンスゲート +Acacia Fence=アカシアのフェンス +Acacia Fence Gate=アカシアのフェンスゲート +Nether Brick Fence=ネザーレンガのフェンス +Openable by players and redstone power=プレイヤーとレッドストーン動力によって開放可能 diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.pl.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.pl.tr new file mode 100644 index 000000000..794986b58 --- /dev/null +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.pl.tr @@ -0,0 +1,19 @@ +# 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.=Płoty są strukturami blokującymi przejścia. Nie połączą się one z innymi blokami. Nie można też nad nimi przeskoczyć pojedynczym skokiem. +Fence gates can be opened or closed and can't be jumped over. Fences will connect nicely to fence gates.=Furtki mogą być otwierane i zamykane, ale nie można ich przeskoczyć. Łączą się one ładnie z płotem. +Right-click the fence gate to open or close it.=Naciśnij prawy przycisk myszy by otworzyć lub zamknąć furtkę. +Oak Fence=Dębowy płot +Oak Fence Gate=Dębowa furtka +Spruce Fence=Świerkowy płot +Spruce Fence Gate=Świerkowa furtka +Birch Fence=Brzozowy płot +Birch Fence Gate=Brzozowa furtka +Jungle Fence=Tropikalny płot +Jungle Fence Gate=Tropikalna furtka +Dark Oak Fence=Ciemno-dębowy płot +Dark Oak Fence Gate=Ciemno-dębowa furtka +Acacia Fence=Akacjowy płot +Acacia Fence Gate=Akacjowa furtka +Nether Brick Fence=Płot z Netherowych cegieł +Openable by players and redstone power=Może być otworzony przez graczy i energię czerwienitu + diff --git a/mods/ITEMS/mcl_fences/locale/mcl_fences.zh_TW.tr b/mods/ITEMS/mcl_fences/locale/mcl_fences.zh_TW.tr new file mode 100644 index 000000000..5f360245c --- /dev/null +++ b/mods/ITEMS/mcl_fences/locale/mcl_fences.zh_TW.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.=柵欄是阻擋道路的結構。柵欄會連接到彼此和固體方塊。它們不能用簡單的跳躍方式跳過去。 +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=叢林木柵欄門 +Dark Oak Fence=黑橡木柵欄 +Dark Oak Fence Gate=黑橡木柵欄門 +Acacia Fence=相思木柵欄 +Acacia Fence Gate=相思木柵欄門 +Nether Brick Fence=地獄磚柵欄 +Openable by players and redstone power=可被紅石或玩家打開 diff --git a/mods/ITEMS/mcl_fences/mod.conf b/mods/ITEMS/mcl_fences/mod.conf index b5eafa90f..8b20dd169 100644 --- a/mods/ITEMS/mcl_fences/mod.conf +++ b/mods/ITEMS/mcl_fences/mod.conf @@ -1 +1,3 @@ name = mcl_fences +depends = mcl_core, mcl_sounds +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_acacia.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_acacia.png deleted file mode 100644 index 85dae567f..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_acacia.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_big_oak.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_big_oak.png deleted file mode 100644 index de8648e8e..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_big_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_birch.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_birch.png deleted file mode 100644 index 96121e128..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_birch.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_big_oak.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_big_oak.png deleted file mode 100644 index f7c0eccd3..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_big_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_jungle.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_jungle.png deleted file mode 100644 index dbc5684ac..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_jungle.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_mask.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_mask.png deleted file mode 100644 index dfa9b34d9..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_mask.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_nether_brick.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_nether_brick.png deleted file mode 100644 index f81609032..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_nether_brick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_oak.png b/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_oak.png deleted file mode 100644 index 6c48e53e8..000000000 Binary files a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_oak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fire/depends.txt b/mods/ITEMS/mcl_fire/depends.txt deleted file mode 100644 index 97699f211..000000000 --- a/mods/ITEMS/mcl_fire/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_worlds -mcl_sounds -mcl_particles -mcl_portals? diff --git a/mods/ITEMS/mcl_fire/fire_charge.lua b/mods/ITEMS/mcl_fire/fire_charge.lua index dcf4ddb00..4d18e44ed 100644 --- a/mods/ITEMS/mcl_fire/fire_charge.lua +++ b/mods/ITEMS/mcl_fire/fire_charge.lua @@ -1,9 +1,12 @@ -local S = minetest.get_translator("mcl_fire") +local S = minetest.get_translator(minetest.get_current_modname()) + +local get_node = minetest.get_node +local add_entity = minetest.add_entity -- Fire Charge minetest.register_craftitem("mcl_fire:fire_charge", { description = S("Fire Charge"), - _tt_help = S("Dispenser projectile").."\n"..S("Starts fires and ignites blocks"), + _tt_help = S("Dispenser projectile").."\n"..S("Starts fires and ignites blocks"), _doc_items_longdesc = S("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."), _doc_items_usagehelp = S("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."), inventory_image = "mcl_fire_fire_charge.png", @@ -11,11 +14,9 @@ minetest.register_craftitem("mcl_fire:fire_charge", { stack_max = 64, on_place = function(itemstack, user, pointed_thing) -- 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 + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack end -- Check protection @@ -26,6 +27,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", { end -- Ignite/light fire + 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 @@ -45,7 +47,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Throw fire charge local shootpos = vector.add(pos, vector.multiply(dropdir, 0.51)) - local fireball = minetest.add_entity(shootpos, "mobs_mc:blaze_fireball") + local fireball = add_entity(shootpos, "mobs_mc:blaze_fireball") local ent = fireball:get_luaentity() ent._shot_from_dispenser = true local v = ent.velocity or 1 @@ -56,7 +58,7 @@ minetest.register_craftitem("mcl_fire:fire_charge", { }) minetest.register_craft({ - type = 'shapeless', - output = 'mcl_fire:fire_charge 3', - recipe = { 'mcl_mobitems:blaze_powder', 'group:coal', 'mcl_mobitems:gunpowder' }, + type = "shapeless", + output = "mcl_fire:fire_charge 3", + recipe = { "mcl_mobitems:blaze_powder", "group:coal", "mcl_mobitems:gunpowder" }, }) diff --git a/mods/ITEMS/mcl_fire/flint_and_steel.lua b/mods/ITEMS/mcl_fire/flint_and_steel.lua index 54c2f1fac..39a4ce882 100644 --- a/mods/ITEMS/mcl_fire/flint_and_steel.lua +++ b/mods/ITEMS/mcl_fire/flint_and_steel.lua @@ -1,9 +1,11 @@ -local S = minetest.get_translator("mcl_fire") +local S = minetest.get_translator(minetest.get_current_modname()) +local get_node = minetest.get_node +local add_node = minetest.add_node -- Flint and Steel minetest.register_tool("mcl_fire:flint_and_steel", { description = S("Flint and Steel"), - _tt_help = S("Starts fires and ignites blocks"), + _tt_help = S("Starts fires and ignites blocks"), _doc_items_longdesc = S("Flint and steel is a tool to start fires and ignite blocks."), _doc_items_usagehelp = S("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."), inventory_image = "mcl_fire_flint_and_steel.png", @@ -12,11 +14,9 @@ minetest.register_tool("mcl_fire:flint_and_steel", { groups = { tool = 1, }, on_place = function(itemstack, user, pointed_thing) -- 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 + local new_stack = mcl_util.call_on_rightclick(itemstack, user, pointed_thing) + if new_stack then + return new_stack end -- Check protection local protname = user:get_player_name() @@ -33,7 +33,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { ) local used = false if pointed_thing.type == "node" then - local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name] + 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 @@ -56,7 +56,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Ignite air if dropnode.name == "air" then - minetest.add_node(droppos, {name="mcl_fire:fire"}) + add_node(droppos, {name="mcl_fire:fire"}) if not minetest.is_creative_enabled("") then stack:add_wear(65535/65) -- 65 uses end @@ -74,7 +74,7 @@ minetest.register_tool("mcl_fire:flint_and_steel", { }) minetest.register_craft({ - type = 'shapeless', - output = 'mcl_fire:flint_and_steel', - recipe = { 'mcl_core:iron_ingot', 'mcl_core:flint'}, + type = "shapeless", + output = "mcl_fire:flint_and_steel", + recipe = { "mcl_core:iron_ingot", "mcl_core:flint"}, }) diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 50303e3b2..70e0769c4 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -2,53 +2,65 @@ mcl_fire = {} -local S = minetest.get_translator("mcl_fire") -local N = function(s) return s end +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) --- inverse pyramid pattern above lava source, floor 1 of 2: -local lava_fire= -{ - { x =-1, y = 1, z =-1}, - { x =-1, y = 1, z = 0}, - { x =-1, y = 1, z = 1}, - { x = 0, y = 1, z =-1}, - { x = 0, y = 1, z = 0}, - { x = 0, y = 1, z = 1}, - { x = 1, y = 1, z =-1}, - { x = 1, y = 1, z = 0}, - { x = 1, y = 1, z = 1} -} -local alldirs= -{ - { x =-1, y = 0, z = 0}, - { x = 1, y = 0, z = 0}, - { x = 0, y =-1, z = 0}, - { x = 0, y = 1, z = 0}, - { x = 0, y = 0, z =-1}, - { x = 0, y = 0, z = 1} +local has_mcl_portals = minetest.get_modpath("mcl_portals") + +local set_node = minetest.set_node +local get_node = minetest.get_node +local add_node = minetest.add_node +local remove_node = minetest.remove_node +local swap_node = minetest.swap_node +local get_node_or_nil = minetest.get_node_or_nil + +local find_nodes_in_area = minetest.find_nodes_in_area +local find_node_near = minetest.find_node_near +local get_item_group = minetest.get_item_group + +local get_connected_players = minetest.get_connected_players + +local vector = vector +local math = math + +local adjacents = { + { x =-1, y = 0, z = 0 }, + { x = 1, y = 0, z = 0 }, + { x = 0, y = 1, z = 0 }, + { x = 0, y =-1, z = 0 }, + { x = 0, y = 0, z =-1 }, + { x = 0, y = 0, z = 1 }, } -local spawn_smoke = function(pos) - mcl_particles.add_node_particlespawner(pos, { - amount = 0.1, - time = 0, - minpos = vector.add(pos, { x = -0.45, y = -0.45, z = -0.45 }), - maxpos = vector.add(pos, { x = 0.45, y = 0.45, z = 0.45 }), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 3.0, - maxsize = 4.0, - texture = "mcl_particles_smoke_anim.png^[colorize:#000000:127", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.1, - }, - }, "high") +local function shuffle_table(t) + for i = #t, 1, -1 do + local r = math.random(i) + t[i], t[r] = t[r], t[i] + end end +shuffle_table(adjacents) + +local function has_flammable(pos) + for k,v in pairs(adjacents) do + local p=vector.add(pos,v) + local n=minetest.get_node_or_nil(p) + if n and minetest.get_item_group(n.name, "flammable") ~= 0 then + return p + end + end +end + +local smoke_pdef = { + amount = 0.009, + maxexptime = 4.0, + minvel = { x = -0.1, y = 0.3, z = -0.1 }, + maxvel = { x = 0.1, y = 1.6, z = 0.1 }, + minsize = 4.0, + maxsize = 4.5, + minrelpos = { x = -0.45, y = -0.45, z = -0.45 }, + maxrelpos = { x = 0.45, y = 0.45, z = 0.45 }, +} -- -- Items @@ -78,19 +90,8 @@ else eternal_fire_help = S("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.") end -local fire_death_messages = { - N("@1 has been cooked crisp."), - N("@1 felt the burn."), - N("@1 died in the flames."), - N("@1 died in a fire."), -} - -local fire_timer = function(pos) - minetest.get_node_timer(pos):start(math.random(3, 7)) -end - -local spawn_fire = function(pos, age) - minetest.set_node(pos, {name="mcl_fire:fire", param2 = age}) +local function spawn_fire(pos, age) + set_node(pos, {name="mcl_fire:fire", param2 = age}) minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) end @@ -116,108 +117,30 @@ minetest.register_node("mcl_fire:fire", { buildable_to = true, sunlight_propagates = true, damage_per_second = 1, - _mcl_node_death_message = fire_death_messages, groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) - if minetest.get_item_group(newnode.name, "water") ~= 0 then + if get_item_group(newnode.name, "water") ~= 0 then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) end end, - on_timer = function(pos) - local node = minetest.get_node(pos) - -- Age is a number from 0 to 15 and is increased every timer step. - -- "old" fire is more likely to be extinguished - local age = node.param2 - local flammables = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) - local below = minetest.get_node({x=pos.x, y=pos.z-1, z=pos.z}) - local below_is_flammable = minetest.get_item_group(below.name, "flammable") > 0 - -- Extinguish fire - if (not fire_enabled) and (math.random(1,3) == 1) then - minetest.remove_node(pos) - return - end - if age == 15 and not below_is_flammable then - minetest.remove_node(pos) - return - elseif age > 3 and #flammables == 0 and not below_is_flammable and math.random(1,4) == 1 then - minetest.remove_node(pos) - return - end - local age_add = 1 - -- If fire spread is disabled, we have to skip the "destructive" code - if (not fire_enabled) then - if age + age_add <= 15 then - node.param2 = age + age_add - minetest.set_node(pos, node) - end - -- Restart timer - fire_timer(pos) - return - end - -- Spawn fire to nearby flammable nodes - local is_next_to_flammable = minetest.find_node_near(pos, 2, {"group:flammable"}) ~= nil - if is_next_to_flammable and math.random(1,2) == 1 then - -- The fire we spawn copies the age of this fire. - -- This prevents fire from spreading infinitely far as the fire fire dies off - -- quicker the further it has spreaded. - local age_next = math.min(15, age + math.random(0, 1)) - -- Select random type of fire spread - local burntype = math.random(1,2) - if burntype == 1 then - -- Spawn fire in air - local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) - while #nodes > 0 do - local r = math.random(1, #nodes) - if minetest.find_node_near(nodes[r], 1, {"group:flammable"}) then - spawn_fire(nodes[r], age_next) - break - else - table.remove(nodes, r) - end - end - else - -- Burn flammable block - local nodes = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"group:flammable"}) - if #nodes > 0 then - local r = math.random(1, #nodes) - local nn = minetest.get_node(nodes[r]).name - local ndef = minetest.registered_nodes[nn] - local fgroup = minetest.get_item_group(nn, "flammable") - if ndef and ndef._on_burn then - ndef._on_burn(nodes[r]) - elseif fgroup ~= -1 then - spawn_fire(nodes[r], age_next) - end - end - end - end - -- Regular age increase - if age + age_add <= 15 then - node.param2 = age + age_add - minetest.set_node(pos, node) - end - -- Restart timer - fire_timer(pos) - end, drop = "", sounds = {}, -- Turn into eternal fire on special blocks, light Nether portal (if possible), start burning timer on_construct = function(pos) local bpos = {x=pos.x, y=pos.y-1, z=pos.z} - local under = minetest.get_node(bpos).name + local under = get_node(bpos).name local dim = mcl_worlds.pos_to_dimension(bpos) if under == "mcl_nether:magma" or under == "mcl_nether:netherrack" or (under == "mcl_core:bedrock" and dim == "end") then - minetest.swap_node(pos, {name = "mcl_fire:eternal_fire"}) + swap_node(pos, {name = "mcl_fire:eternal_fire"}) end - if minetest.get_modpath("mcl_portals") then + if has_mcl_portals then mcl_portals.light_nether_portal(pos) end - fire_timer(pos) - spawn_smoke(pos) + mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) end, on_destruct = function(pos) mcl_particles.delete_node_particlespawners(pos) @@ -247,41 +170,19 @@ minetest.register_node("mcl_fire:eternal_fire", { buildable_to = true, sunlight_propagates = true, damage_per_second = 1, - _mcl_node_death_message = fire_death_messages, groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) - if minetest.get_item_group(newnode.name, "water") ~= 0 then + if get_item_group(newnode.name, "water") ~= 0 then minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) end end, - on_timer = function(pos) - if fire_enabled then - local airs = minetest.find_nodes_in_area({x=pos.x-1, y=pos.y-1, z=pos.z-1}, {x=pos.x+1, y=pos.y+4, z=pos.z+1}, {"air"}) - while #airs > 0 do - local r = math.random(1, #airs) - if minetest.find_node_near(airs[r], 1, {"group:flammable"}) then - local node = minetest.get_node(airs[r]) - local age = node.param2 - local age_next = math.min(15, age + math.random(0, 1)) - spawn_fire(airs[r], age_next) - break - else - table.remove(airs, r) - end - end - end - -- Restart timer - fire_timer(pos) - end, -- Start burning timer and light Nether portal (if possible) on_construct = function(pos) - fire_timer(pos) - - if minetest.get_modpath("mcl_portals") then + if has_mcl_portals then --Calling directly minetest.get_modpath consumes 4x more compute time mcl_portals.light_nether_portal(pos) end - spawn_smoke(pos) + mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) end, on_destruct = function(pos) mcl_particles.delete_node_particlespawners(pos) @@ -313,7 +214,7 @@ if flame_sound then local ppos = player:get_pos() local areamin = vector.subtract(ppos, radius) local areamax = vector.add(ppos, radius) - local fpos, num = minetest.find_nodes_in_area( + local fpos, num = find_nodes_in_area( areamin, areamax, {"mcl_fire:fire", "mcl_fire:eternal_fire"} @@ -384,7 +285,7 @@ if flame_sound then end timer = 0 - local players = minetest.get_connected_players() + local players = get_connected_players() for n = 1, #players do mcl_fire.update_player_sound(players[n]) end @@ -401,6 +302,25 @@ if flame_sound then end) end +-- [...]a fire that is not adjacent to any flammable block does not spread, even to another flammable block within the normal range. +-- https://minecraft.fandom.com/wiki/Fire#Spread + +local function check_aircube(p1,p2) + local nds=minetest.find_nodes_in_area(p1,p2,{"air"}) + shuffle_table(nds) + for k,v in pairs(nds) do + if has_flammable(v) then return v end + end +end + +-- [...] a fire block can turn any air block that is adjacent to a flammable block into a fire block. This can happen at a distance of up to one block downward, one block sideways (including diagonals), and four blocks upward of the original fire block (not the block the fire is on/next to). +local function get_ignitable(pos) + return check_aircube(vector.add(pos,vector.new(-1,-1,-1)),vector.add(pos,vector.new(1,4,1))) +end +-- Fire spreads from a still lava block similarly: any air block one above and up to one block sideways (including diagonals) or two above and two blocks sideways (including diagonals) that is adjacent to a flammable block may be turned into a fire block. +local function get_ignitable_by_lava(pos) + return check_aircube(vector.add(pos,vector.new(-1,1,-1)),vector.add(pos,vector.new(1,1,1))) or check_aircube(vector.add(pos,vector.new(-2,2,-2)),vector.add(pos,vector.new(2,2,2))) or nil +end -- -- ABMs @@ -422,21 +342,7 @@ minetest.register_abm({ end, }) - -- Enable the following ABMs according to 'enable fire' setting - -local function has_flammable(pos) - local npos, node - for n, v in ipairs(alldirs) do - npos = vector.add(pos, v) - node = minetest.get_node_or_nil(npos) - if node and node.name and minetest.get_item_group(node.name, "flammable") ~= 0 then - return npos - end - end - return false -end - if not fire_enabled then -- Occasionally remove fire if fire disabled @@ -452,87 +358,118 @@ if not fire_enabled then else -- Fire enabled - -- Set fire to air nodes + -- Fire Spread minetest.register_abm({ - label = "Ignite fire by lava", - nodenames = {"group:lava"}, - neighbors = {"air"}, + label = "Ignite flame", + nodenames ={"mcl_fire:fire","mcl_fire:eternal_fire"}, interval = 7, - chance = 3, + chance = 12, catch_up = false, action = function(pos) - local i, dir, target, node, i2, f - i = math.random(1,9) - dir = lava_fire[i] - target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z} - node = minetest.get_node(target) - if not node or node.name ~= "air" then - i = ((i + math.random(0,7)) % 9) + 1 - dir = lava_fire[i] - target = {x=pos.x+dir.x, y=pos.y+dir.y, z=pos.z+dir.z} - node = minetest.get_node(target) - if not node or node.name ~= "air" then - return - end + local p = get_ignitable(pos) + if p then + spawn_fire(p) + shuffle_table(adjacents) end - i2 = math.random(1,15) - if i2 < 10 then - local dir2, target2, node2 - dir2 = lava_fire[i2] - target2 = {x=target.x+dir2.x, y=target.y+dir2.y, z=target.z+dir2.z} - node2 = minetest.get_node(target2) - if node2 and node2.name == "air" then - f = has_flammable(target2) - if f then - minetest.after(1, spawn_fire, {x=target2.x, y=target2.y, z=target2.z}) - minetest.add_particle({ - pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}), - velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.7), z=f.z-pos.z}, - expirationtime=1, size=1.5, collisiondetection=false, - glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png" - }) - return - end - end - end - f = has_flammable(target) - if f then - minetest.after(1, spawn_fire, {x=target.x, y=target.y, z=target.z}) - minetest.add_particle({ - pos = vector.new({x=pos.x, y=pos.y+0.5, z=pos.z}), - velocity={x=f.x-pos.x, y=math.max(f.y-pos.y,0.25), z=f.z-pos.z}, - expirationtime=1, size=1, collisiondetection=false, - glow=minetest.LIGHT_MAX, texture="mcl_particles_flame.png" - }) + end + }) + + --lava fire spread + minetest.register_abm({ + label = "Ignite fire by lava", + nodenames = {"mcl_core:lava_source","mcl_nether:nether_lava_source"}, + neighbors = {"group:flammable"}, + interval = 15, + chance = 9, + catch_up = false, + action = function(pos) + local p=get_ignitable_by_lava(pos) + if p then + spawn_fire(p) end end, }) + minetest.register_abm({ + label = "Remove fires", + nodenames = {"mcl_fire:fire"}, + interval = 7, + chance = 3, + catch_up = false, + action = function(pos) + local p=has_flammable(pos) + if p then + local n=minetest.get_node_or_nil(p) + if n and minetest.get_item_group(n.name, "flammable") < 1 then + minetest.remove_node(pos) + end + else + minetest.remove_node(pos) + end + end, + }) + + -- Remove flammable nodes around basic flame + minetest.register_abm({ + label = "Remove flammable nodes", + nodenames = {"mcl_fire:fire","mcl_fire:eternal_fire"}, + neighbors = {"group:flammable"}, + interval = 5, + chance = 18, + catch_up = false, + action = function(pos) + local p = has_flammable(pos) + if not p then + return + end + + local nn = minetest.get_node(p).name + local def = minetest.registered_nodes[nn] + local fgroup = minetest.get_item_group(nn, "flammable") + + if def and def._on_burn then + def._on_burn(p) + elseif fgroup ~= -1 then + spawn_fire(p) + minetest.check_for_falling(p) + end + end + }) end -- Set pointed_thing on (normal) fire. -- * pointed_thing: Pointed thing to ignite -- * player: Player who sets fire or nil if nobody -- * allow_on_fire: If false, can't ignite fire on fire (default: true) -mcl_fire.set_fire = function(pointed_thing, player, allow_on_fire) +function mcl_fire.set_fire(pointed_thing, player, allow_on_fire) local pname if player == nil then pname = "" else pname = player:get_player_name() end - local n = minetest.get_node(pointed_thing.above) - local nu = minetest.get_node(pointed_thing.under) - if allow_on_fire == false and minetest.get_item_group(nu.name, "fire") ~= 0 then - return - end + if minetest.is_protected(pointed_thing.above, pname) then minetest.record_protection_violation(pointed_thing.above, pname) return end - if n.name == "air" then - minetest.add_node(pointed_thing.above, {name="mcl_fire:fire"}) + + local n_pointed = minetest.get_node(pointed_thing.under) + if allow_on_fire == false and get_item_group(n_pointed.name, "fire") ~= 0 then + return end + + local n_fire_pos = minetest.get_node(pointed_thing.above) + if n_fire_pos.name ~= "air" then + return + end + + local n_below = minetest.get_node(vector.offset(pointed_thing.above, 0, -1, 0)) + if minetest.get_item_group(n_below.name, "water") ~= 0 then + return + end + + add_node(pointed_thing.above, {name="mcl_fire:fire"}) end minetest.register_lbm({ @@ -541,7 +478,7 @@ minetest.register_lbm({ nodenames = {"group:fire"}, run_at_every_load = true, action = function(pos, node) - spawn_smoke(pos) + mcl_particles.spawn_smoke(pos, "fire", smoke_pdef) end, }) @@ -549,5 +486,5 @@ minetest.register_alias("mcl_fire:basic_flame", "mcl_fire:fire") minetest.register_alias("fire:basic_flame", "mcl_fire:fire") minetest.register_alias("fire:permanent_flame", "mcl_fire:eternal_fire") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/flint_and_steel.lua") -dofile(minetest.get_modpath(minetest.get_current_modname()).."/fire_charge.lua") +dofile(modpath.."/flint_and_steel.lua") +dofile(modpath.."/fire_charge.lua") diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.fr.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.fr.tr index 60b6ffd0e..f585f9e02 100644 --- a/mods/ITEMS/mcl_fire/locale/mcl_fire.fr.tr +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.fr.tr @@ -1,19 +1,19 @@ # textdomain: mcl_fire -Fire Charge=Boule de Feu -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.=Les boules de feu sont principalement des projectiles qui peuvent être lancés à partir de distributeurs, ils voleront en ligne droite et éclateront en feu à l'impact. Alternativement, ils peuvent être utilisés pour allumer des incendies directement. -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.=Mettez la boule de feu dans un distributeur et alimentez-la en redstone pour la lancer. Pour allumer un feu directement, placez simplement la charge de feu sur le sol, et utiliser le. +Fire Charge=Boule de feu +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.=Les boules de feu sont principalement des projectiles qui peuvent être lancées à partir de distributeurs, elles voleront en ligne droite et éclateront en feu à l'impact. Alternativement, elles peuvent être utilisées pour allumer des incendies directement. +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.=Mettez la boule de feu dans un distributeur et alimentez-la en redstone pour la lancer. Pour allumer un feu directement, placez simplement la charge de feu sur le sol, et utiliser la. Flint and Steel=Briquet -Flint and steel is a tool to start fires and ignite blocks.=Le Briquet est uo outil pour allumer un feu ou allumer des blocs. +Flint and steel is a tool to start fires and ignite blocks.=Le briquet est un outil pour allumer un feu ou allumer des blocs. 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.=Cliquez avec le bouton droit sur la surface d'un bloc pour tenter d'allumer un feu devant lui ou d'allumer le bloc. Quelques blocs ont une réaction unique lorsqu'ils sont enflammés. 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.=Le feu est un type de bloc dommageable et destructeur mais de courte durée. Il se détruira et se propagera vers des blocs proches de produits inflammables, mais le feu disparaîtra lorsqu'il n'y aura plus rien à brûler. Il sera éteint par l'eau et la pluie à proximité. Le feu peut être détruit en toute sécurité en le frappant, mais il est blessant si vous vous tenez directement dedans. Si un feu est déclenché au-dessus d'un netherrack ou d'un bloc de magma, il se transformera immédiatement en un feu éternel. 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.=Le feu est un type de bloc éphémère mais non destructif de courte durée. Il disparaîtra en l'absence de bloc inflammable. Le feu ne détruit pas les blocs, du moins pas dans ce monde. Il sera éteint par l'eau et la pluie à proximité. Le feu peut être détruit en toute sécurité en le frappant, mais il est blessant si vous vous tenez directement dedans. Si un feu est déclenché au-dessus d'un netherrack ou d'un bloc de magma, il se transformera immédiatement en un feu éternel. 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.=Le feu éternel est un bloc endommageant qui pourrait créer plus de feu. Il créera du feu autour de lui lorsque des blocs inflammables sont à proximité. Le feu éternel peut être éteint par des coups de poing et des blocs d'eau à proximité. À part le feu (normal), le feu éternel ne s'éteint pas tout seul et continue de brûler sous la pluie. Frapper le feu éternel est sûr, mais ça fait mal si vous vous tenez à l'intérieur. 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.=Le feu éternel est un bloc dommageable. Le feu éternel peut être éteint par des coups de poing et des blocs d'eau à proximité. À part le feu (normal), le feu éternel ne s'éteint pas tout seul et continue de brûler sous la pluie. Frapper le feu éternel est sûr, mais ça fait mal si vous vous tenez à l'intérieur. -@1 has been cooked crisp.=@1 a été cuit croustillant. -@1 felt the burn.=@1 sent le brûler. +@1 has been cooked crisp.=@1 a été grillé comme une saucisse. +@1 felt the burn.=@1 sent le brûlé. @1 died in the flames.=@1 est mort dans les flammes. @1 died in a fire.=@1 est mort dans un incendie. Fire=Feu -Eternal Fire=Feu Eternel -Dispenser projectile=Distributeur de Projectile +Eternal Fire=Feu éternel +Dispenser projectile=Distributeur de projectile Starts fires and ignites blocks=Démarre les incendies et allume les blocs diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr new file mode 100644 index 000000000..5f8964b1b --- /dev/null +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.ja.tr @@ -0,0 +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.=発火弾をディスペンサーに入れ、レッドストーン動力を供給すると発射されます。直接火を着けるには、シンプルに発火弾を地面に置くだけです。なお、使い切りです。 +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は火災で死亡した。 +Fire=炎 +Eternal Fire=永続的な炎 +Dispenser projectile=ディスペンサーの発射体 +Starts fires and ignites blocks=火起こしやブロックへの着火 diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.pl.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.pl.tr new file mode 100644 index 000000000..ba55cc31e --- /dev/null +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.pl.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_fire +Fire Charge=Ładunek ognia +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.=Ładunki ognia są pociskami, którymi można strzelać z dozowników. Lecą one w linii prostej a po zderzeniu zamieniają się w ogień. +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.=Włóż ładunek ognia do dozownika i dostarcz energię z czerwienitu aby wystrzelić. Aby bezpośrednio zapalić ładunek postaw go na ziemi co go wykorzystuje. +Flint and Steel=Krzesiwo +Flint and steel is a tool to start fires and ignite blocks.=Krzesiwo jest narzędziem do rozpalania ognia i podpalania bloków. +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.=Kliknij prawym przyciskiem na powierzchni bloku, ab spróbować rozpalić na nim ogień lub go podpalić. Niektóre bloki reagują na podpalenie w specjalny sposób. +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.=Ogień jest raniącym i niszczącym, ale krótko żyjącym blokiem. Zniszczy on i będzie się rozprzestrzeniał na inne łatwopalne bloki, ale zniknie on gdy nie zostanie nic więcej do spalenia. Zostanie zgaszony przez pobliską wodę lub deszcz. Jeśli ogień jest zapalony na skale Netheru lub bloku magmy, natychmiast zamieni się on w wieczny ogień. +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.=Ogień jest raniącym, ale nie niszczącym i krótko żyjącym blokiem. Zniknie gdy w pobliżu nie będzie łatwopalnych bloków. Ogień nie niszczy bloków, przynajmniej nie w tym świecie. Może być zgaszony przez pobliską wodę i deszcz. Może być bezpiecznie zniszczony przez uderzenie go, ale jest raniący gdy stanie się wewnątrz. Jeśli ogień jest zapalony nad skałą Netheru lub bloku magmy, natychmiast zamieni się w wieczny ogień. +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.=Wieczny ogień jest niszczącym blokiem, który może tworzyć więcej ognia. Będzie on tworzył ogień wokół gdy w pobliżu są łatwopalne bloki. Wieczny ogień można ugasić uderzeniem i blokami wody. W przeciwieństwie do (zwykłego) ognia, wieczny ogień nie gasi się sam z siebie i będzie nadal płonął w deszczu. Uderzanie wiecznego ognia jest bezpieczne, ale jest raniący gdy stoi się wewnątrz. +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.=Wieczny ogień jest raniącym blokiem. Może on być zgaszony przez uderzenie i bloki wody. W przeciwieństwie do (zwykłego) ognia, wieczny ogień nie zgaśnie sam z siebie i będzie nadal płonął w deszczu. Uderzanie wiecznego ognia jest bezpieczne, ale jest raniący gdy stoi się wewnątrz. +@1 has been cooked crisp.=@1 została usmażona na chrupko. +@1 felt the burn.=@1 poczuła oparzenie. +@1 died in the flames.=@1 zginęła w płomieniach. +@1 died in a fire.=@1 zginęła w ogniu. +Fire=Ogień +Eternal Fire=Wieczny ogień +Dispenser projectile=Pocisk do dozownika +Starts fires and ignites blocks=Rozpala ogień i podpala bloki diff --git a/mods/ITEMS/mcl_fire/locale/mcl_fire.zh_TW.tr b/mods/ITEMS/mcl_fire/locale/mcl_fire.zh_TW.tr new file mode 100644 index 000000000..74394be6d --- /dev/null +++ b/mods/ITEMS/mcl_fire/locale/mcl_fire.zh_TW.tr @@ -0,0 +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.=將火藥放入發射器中,並為其提供紅石動力以發射火藥。要直接點火,只需將火藥放在地上,這樣就能用完。 +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 在火焰中昇天 +Fire=火 +Eternal Fire=永恆之火 +Dispenser projectile=發射器投射物 +Starts fires and ignites blocks=點火和點燃方塊 diff --git a/mods/ITEMS/mcl_fire/mod.conf b/mods/ITEMS/mcl_fire/mod.conf index 23de4da69..4a1d52ee2 100644 --- a/mods/ITEMS/mcl_fire/mod.conf +++ b/mods/ITEMS/mcl_fire/mod.conf @@ -1 +1,3 @@ name = mcl_fire +depends = mcl_core, mcl_worlds, mcl_sounds, mcl_particles, mcl_util +optional_depends = mcl_portals \ No newline at end of file diff --git a/mods/ITEMS/mcl_fire/textures/fire_basic_flame.png b/mods/ITEMS/mcl_fire/textures/fire_basic_flame.png deleted file mode 100644 index 5ed32ec0e..000000000 Binary files a/mods/ITEMS/mcl_fire/textures/fire_basic_flame.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fireworks/README.txt b/mods/ITEMS/mcl_fireworks/README.txt new file mode 100644 index 000000000..4cf71fc9b --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/README.txt @@ -0,0 +1,7 @@ +Firework mod for Mineclone 2 + +by NO11 and and some parts by j45 + +Sound credits: + +* mcl_firework_rocket.ogg (tnt_ignite.ogg): Own derivate work of sound by Ned Bouhalassa (CC0) created in 2005, source: diff --git a/mods/ITEMS/mcl_fireworks/crafting.lua b/mods/ITEMS/mcl_fireworks/crafting.lua new file mode 100644 index 000000000..a9e156aa6 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/crafting.lua @@ -0,0 +1,17 @@ +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_1 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_2 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_fireworks:rocket_3 3", + recipe = {"mcl_core:paper", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder", "mcl_mobitems:gunpowder"}, +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/init.lua b/mods/ITEMS/mcl_fireworks/init.lua new file mode 100644 index 000000000..cd1922580 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/init.lua @@ -0,0 +1,4 @@ +local path = minetest.get_modpath("mcl_fireworks") + +dofile(path .. "/register.lua") +dofile(path .. "/crafting.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr new file mode 100644 index 000000000..9f9098103 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.de.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=Feuerwerksrakete +Flight Duration:=Flugdauer: \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr new file mode 100644 index 000000000..e66eb06a5 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.es.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket= +Flight Duration:= \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr new file mode 100644 index 000000000..b02faa428 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=Fusée +Flight Duration:=Durée de vol : \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr new file mode 100644 index 000000000..cd6da01c4 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket=ロケット花火 +Flight Duration:=飛行時間: \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pl.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pl.tr new file mode 100644 index 000000000..d7d6db185 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.pl.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fireworks +Firework Rocket=Fajerwerkowa rakieta +Flight Duration:=Czas lotu: + diff --git a/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr new file mode 100644 index 000000000..e66eb06a5 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/mcl_fireworks.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket= +Flight Duration:= \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/locale/template.txt b/mods/ITEMS/mcl_fireworks/locale/template.txt new file mode 100644 index 000000000..e66eb06a5 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_fireworks +Firework Rocket= +Flight Duration:= \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/mod.conf b/mods/ITEMS/mcl_fireworks/mod.conf new file mode 100644 index 000000000..cf9e34e91 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/mod.conf @@ -0,0 +1,2 @@ +name = mcl_fireworks +description = Adds fun fireworks to the game which players can use. \ No newline at end of file diff --git a/mods/ITEMS/mcl_fireworks/register.lua b/mods/ITEMS/mcl_fireworks/register.lua new file mode 100644 index 000000000..23066b663 --- /dev/null +++ b/mods/ITEMS/mcl_fireworks/register.lua @@ -0,0 +1,28 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local tt_help = S("Flight Duration:") +local description = S("Firework Rocket") + +local function register_rocket(n, duration, force) + minetest.register_craftitem("mcl_fireworks:rocket_" .. n, { + description = description, + _tt_help = tt_help .. " " .. duration, + inventory_image = "mcl_fireworks_rocket.png", + stack_max = 64, + on_use = function(itemstack, user, pointed_thing) + local elytra = mcl_playerplus.elytra[user] + if elytra.active and elytra.rocketing <= 0 then + elytra.rocketing = duration + if not minetest.is_creative_enabled(user:get_player_name()) then + itemstack:take_item() + end + minetest.sound_play("mcl_fireworks_rocket", {pos = user:get_pos()}) + end + return itemstack + end, + }) +end + +register_rocket(1, 2.2, 10) +register_rocket(2, 4.5, 20) +register_rocket(3, 6, 30) diff --git a/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg b/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg new file mode 100644 index 000000000..aa232f0de Binary files /dev/null and b/mods/ITEMS/mcl_fireworks/sounds/mcl_fireworks_rocket.ogg differ diff --git a/mods/ITEMS/mcl_fishing/README.txt b/mods/ITEMS/mcl_fishing/README.txt new file mode 100644 index 000000000..b80d77936 --- /dev/null +++ b/mods/ITEMS/mcl_fishing/README.txt @@ -0,0 +1,15 @@ +License of media (sounds) +-------------------------------------- +CC0 1.0 Universal (CC0 1.0) +https://creativecommons.org/publicdomain/zero/1.0/ + +Authors of media files +----------------------- + +You're Perfect Studio (CC0) +https://opengameart.org/content/fisheefects + reel.wav, bloop.wav + +tran5ient (CC0) +https://freesound.org/people/tran5ient/sounds/190080/ + splash7.wav \ No newline at end of file diff --git a/mods/ITEMS/mcl_fishing/depends.txt b/mods/ITEMS/mcl_fishing/depends.txt deleted file mode 100644 index bbc3c6ad8..000000000 --- a/mods/ITEMS/mcl_fishing/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_loot -mcl_mobs -mcl_enchanting diff --git a/mods/ITEMS/mcl_fishing/description.txt b/mods/ITEMS/mcl_fishing/description.txt deleted file mode 100644 index 1befeab16..000000000 --- a/mods/ITEMS/mcl_fishing/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds fish and fishing poles to go fishing. diff --git a/mods/ITEMS/mcl_fishing/init.lua b/mods/ITEMS/mcl_fishing/init.lua index df76efcbd..893a376f5 100644 --- a/mods/ITEMS/mcl_fishing/init.lua +++ b/mods/ITEMS/mcl_fishing/init.lua @@ -1,11 +1,6 @@ --Fishing Rod, Bobber, and Flying Bobber mechanics and Bobber artwork by Rootyjr. -local S = minetest.get_translator("mcl_fishing") -local mod_throwing = minetest.get_modpath("mcl_throwing") - -local entity_mapping = { - ["mcl_fishing:bobber"] = "mcl_fishing:bobber_entity", -} +local S = minetest.get_translator(minetest.get_current_modname()) local bobber_ENTITY={ physical = false, @@ -43,7 +38,6 @@ local fish = function(itemstack, player, pointed_thing) local ent = nil local noent = true - local durability = 65 local unbreaking = mcl_enchanting.get_enchantment(itemstack, "unbreaking") if unbreaking > 0 then @@ -61,7 +55,6 @@ local fish = function(itemstack, player, pointed_thing) local itemname local items local itemcount = 1 - local itemwear = 0 local pr = PseudoRandom(os.time() * math.random(1, 100)) local r = pr:next(1, 100) local fish_values = {85, 84.8, 84.7, 84.5} @@ -78,8 +71,11 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_fishing:salmon_raw", weight = 25 }, { itemstring = "mcl_fishing:clownfish_raw", weight = 2 }, { itemstring = "mcl_fishing:pufferfish_raw", weight = 13 }, - } + }, + stacks_min = 1, + stacks_max = 1, }, pr) + awards.unlock(player:get_player_name(), "mcl:fishyBusiness") elseif r <= junk_value then -- Junk items = mcl_loot.get_loot({ @@ -93,23 +89,33 @@ local fish = function(itemstack, player, pointed_thing) { itemstring = "mcl_mobitems:string", weight = 5 }, { itemstring = "mcl_potions:water", weight = 10 }, { itemstring = "mcl_mobitems:bone", weight = 10 }, - { itemstring = "mcl_dye:black", weight = 1, amount_min = 10, amount_max = 10 }, + { itemstring = "mcl_mobitems:ink_sac", weight = 1, amount_min = 10, amount_max = 10 }, { itemstring = "mcl_mobitems:string", weight = 10 }, -- TODO: Tripwire Hook - } + { itemstring = "mcl_bamboo:bamboo", weight = 10 }, + }, + stacks_min = 1, + stacks_max = 1, }, pr) else -- Treasure items = mcl_loot.get_loot({ items = { - -- TODO: Enchanted Bow - { itemstring = "mcl_bows:bow", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage - { itemstack = mcl_enchanting.get_randomly_enchanted_book(30, true, true)}, - -- TODO: Enchanted Fishing Rod - { itemstring = "mcl_fishing:fishing_rod", wear_min = 49144, wear_max = 65535 }, -- 75%-100% damage + { itemstring = "mcl_bows:bow", wear_min = 49144, wear_max = 65535, func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, false, false, pr) + end }, -- 75%-100% damage + { itemstring = "mcl_books:book", func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, true, false, pr) + end }, + { itemstring = "mcl_fishing:fishing_rod", wear_min = 49144, wear_max = 65535, func = function(stack, pr) + mcl_enchanting.enchant_randomly(stack, 30, true, false, false, pr) + end }, -- 75%-100% damage { itemstring = "mcl_mobs:nametag", }, { itemstring = "mcl_mobitems:saddle", }, { itemstring = "mcl_flowers:waterlily", }, - } + { itemstring = "mcl_mobitems:nautilus_shell", }, + }, + stacks_min = 1, + stacks_max = 1, }, pr) end local item @@ -121,11 +127,14 @@ local fish = function(itemstack, player, pointed_thing) local inv = player:get_inventory() if inv:room_for_item("main", item) then inv:add_item("main", item) + if item:get_name() == "mcl_mobitems:leather" then + awards.unlock(player:get_player_name(), "mcl:killCow") + end else minetest.add_item(pos, item) end - if mcl_experience.throw_experience then - mcl_experience.throw_experience(pos, math.random(1,6)) + if mcl_experience.throw_xp then + minetest.after(0.7, mcl_experience.throw_xp, pos, math.random(1,6)) end if not minetest.is_creative_enabled(player:get_player_name()) then @@ -152,6 +161,7 @@ local fish = function(itemstack, player, pointed_thing) end --Destroy bobber. ent.object:remove() + minetest.sound_play("reel", {object=player, gain=0.1, max_hear_distance=16}, true) return itemstack end end @@ -173,7 +183,7 @@ local fish = function(itemstack, player, pointed_thing) if noent == true then local playerpos = player:get_pos() local dir = player:get_look_dir() - local obj = mcl_throwing.throw("mcl_throwing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name()) + mcl_throwing.throw("mcl_fishing:flying_bobber", {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, 15, player:get_player_name()) end end @@ -197,7 +207,7 @@ local bobber_on_step = function(self, dtime) end local wield = player:get_wielded_item() --Check if player is nearby - if self.player ~= nil and player ~= nil then + if self.player and player then --Destroy bobber if item not wielded. if ((not wield) or (minetest.get_item_group(wield:get_name(), "fishing_rod") <= 0)) then self.object:remove() @@ -233,6 +243,7 @@ local bobber_on_step = function(self, dtime) if self._oldy == nil then self.object:set_pos({x=self.object:get_pos().x,y=math.floor(self.object:get_pos().y)+.5,z=self.object:get_pos().z}) self._oldy = self.object:get_pos().y + minetest.sound_play("watersplash", {pos=epos, gain=0.25}, true) end -- reset to original position after dive. if self.object:get_pos().y > self._oldy then @@ -271,6 +282,7 @@ local bobber_on_step = function(self, dtime) self._time = self._time + dtime else -- wait time is over time to dive. + minetest.sound_play("bloop", {pos=epos, gain=0.4}, true) self._dive = true self.object:set_velocity({x=0,y=-2,z=0}) self.object:set_acceleration({x=0,y=5,z=0}) @@ -295,13 +307,54 @@ bobber_ENTITY.on_step = bobber_on_step minetest.register_entity("mcl_fishing:bobber_entity", bobber_ENTITY) +local flying_bobber_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. + visual_size = {x=0.5, y=0.5}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, + + _lastpos={}, + _thrower = nil, + objtype="fishing", +} + +-- Movement function of flying bobber +local function flying_bobber_on_step(self, dtime) + self.timer=self.timer+dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + --local player = minetest.get_player_by_name(self._thrower) + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + if (def and (def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source")) or not def then + local ent = minetest.add_entity(self._lastpos, "mcl_fishing:bobber_entity"):get_luaentity() + ent.player = self._thrower + ent.child = true + self.object:remove() + return + end + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +flying_bobber_ENTITY.on_step = flying_bobber_on_step + +minetest.register_entity("mcl_fishing:flying_bobber_entity", flying_bobber_ENTITY) + +mcl_throwing.register_throwable_object("mcl_fishing:flying_bobber", "mcl_fishing:flying_bobber_entity", 5) + -- If player leaves area, remove bobber. minetest.register_on_leaveplayer(function(player) local objs = minetest.get_objects_inside_radius(player:get_pos(), 250) - local num = 0 local ent = nil local noent = true - for n = 1, #objs do ent = objs[n]:get_luaentity() if ent then @@ -341,29 +394,30 @@ minetest.register_tool("mcl_fishing:fishing_rod", { _doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"), groups = { tool=1, fishing_rod=1, enchantability=1 }, inventory_image = "mcl_fishing_fishing_rod.png", - wield_image = "mcl_fishing_fishing_rod.png^[transformR270", + wield_image = "mcl_fishing_fishing_rod.png^[transformFY^[transformR90", wield_scale = { x = 1.5, y = 1.5, z = 1 }, stack_max = 1, on_place = fish, on_secondary_use = fish, sound = { breaks = "default_tool_breaks" }, _mcl_uses = 65, + _mcl_toollike_wield = true, }) minetest.register_craft({ output = "mcl_fishing:fishing_rod", recipe = { - {'','','mcl_core:stick'}, - {'','mcl_core:stick','mcl_mobitems:string'}, - {'mcl_core:stick','','mcl_mobitems:string'}, + {"","","mcl_core:stick"}, + {"","mcl_core:stick","mcl_mobitems:string"}, + {"mcl_core:stick","","mcl_mobitems:string"}, } }) minetest.register_craft({ output = "mcl_fishing:fishing_rod", recipe = { - {'mcl_core:stick', '', ''}, - {'mcl_mobitems:string', 'mcl_core:stick', ''}, - {'mcl_mobitems:string','','mcl_core:stick'}, + {"mcl_core:stick", "", ""}, + {"mcl_mobitems:string", "mcl_core:stick", ""}, + {"mcl_mobitems:string","","mcl_core:stick"}, } }) minetest.register_craft({ @@ -381,7 +435,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 }, + groups = { food=2, eatable = 2, smoker_cookable = 1 }, _mcl_saturation = 0.4, }) @@ -411,7 +465,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 }, + groups = { food=2, eatable = 2, smoker_cookable = 1 }, _mcl_saturation = 0.4, }) @@ -448,7 +502,7 @@ minetest.register_craftitem("mcl_fishing:clownfish_raw", { minetest.register_craftitem("mcl_fishing:pufferfish_raw", { description = S("Pufferfish"), - _tt_help = minetest.colorize("#FFFF00", S("Very poisonous")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Very poisonous")), _doc_items_longdesc = S("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)."), inventory_image = "mcl_fishing_pufferfish_raw.png", on_place = minetest.item_eat(1), diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.de.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.de.tr index 10f908593..b80c186c1 100644 --- a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.de.tr +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.de.tr @@ -7,12 +7,12 @@ Raw fish is obtained by fishing and is a food item which can be eaten safely. Co Cooked Fish=Gekochter Fisch Mmh, fish! This is a healthy food item.=Mhh, Fisch! Ein gesundes Lebensmittel. Raw Salmon=Roher Lachs -Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Lohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, der sicher verzehrt werden kann. +Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Rohen Lachs erhält man beim Angeln. Er ist ein Lebensmittel, das sicher verzehrt werden kann. Cooked Salmon=Gekochter Lachs This is a healthy food item which can be eaten.=Ein gesundes essbares Lebensmittel. Clownfish=Clownfisch -Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, der sicher verzehrt werden kann. +Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Einen Clownfisch kann man beim Angeln mit etwas Glück fangen. Er ist ein Lebensmittel, das sicher verzehrt werden kann. Pufferfish=Kugelfisch -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).=Kugelfische sind eine verbreitete Fischart, die geangelt werden können. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen. +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).=Kugelfische sind eine verbreitete Fischart, die geangelt werden kann. Sie können theoretisch gegessen werden, aber sie sind sehr schlecht für Menschen. Es gibt nur 1 Hungerpunkt und es wird Sie schwer vergiften (was Ihre Gesundheit verringert, aber nicht bis zum Tod) und Ihr Hungerpegel wird aufgrund der schweren Lebensmittelvergiftung stark ansteigen. Catches fish in water=Fängt Fische im Wasser Very poisonous=Sehr giftig diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr new file mode 100644 index 000000000..d68a8ab96 --- /dev/null +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.ja.tr @@ -0,0 +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.=ん~、サカナ! これはヘルシーな食材ですね。 +Raw Salmon=生鮭 +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.=これは食べられるヘルシーな食材です。 +Clownfish=クマノミ +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ポイントしか回復せず、過酷な毒(死なない程度にヘルスを消耗)と、深刻な食中毒(空腹感の増加)を引き起こすことになります。 +Catches fish in water=水中の魚を捕獲 +Very poisonous=猛毒 diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pl.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pl.tr new file mode 100644 index 000000000..cc35096cd --- /dev/null +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.pl.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_fishing +Fishing Rod=Wędka +Fishing rods can be used to catch fish.=Wędki są wykorzystywane do łowienia ryb. +Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?=Kliknij prawym przyciskiem aby wyrzucić spławik. Gdy zejdzie pod wodę, kliknij prawym aby go wciągnąć razem z przedmiotem. Kto wie co uda ci się złapać? +Raw Fish=Surowa ryba +Raw fish is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Surowa ryba jest możliwa do zdobycia poprzez łowienie i można go bezpiecznie zjeść. Upieczenie jej znacząco zwiększa wartości odżywcze. +Cooked Fish=Upieczona ryba +Mmh, fish! This is a healthy food item.=Mm, ryba! Jest to zdrowy i pożywny posiłek. +Raw Salmon=Surowy łosoś +Raw salmon is obtained by fishing and is a food item which can be eaten safely. Cooking it improves its nutritional value.=Surowy łosoś można zdobyć poprzez łowienie i można go bezpiecznie zjeść. Upieczenie jej znacząco zwiększa wartości odżywcze. +Cooked Salmon=Upieczony łosoś +This is a healthy food item which can be eaten.=Jest to zdrowy i pożywny posiłek. +Clownfish=Błazenek +Clownfish may be obtained by fishing (and luck) and is a food item which can be eaten safely.=Błazenek +Pufferfish=Rozdymka +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).=Rozdymki są powszechnym gatunkiem ryby, który można zdobyć poprzez łowienie. Technicznie rzecz biorąc można je zjeść, jednak są bardzo niezdrowe dla ludzi. Zjedzenie rozdymki przywraca tylko 1 punkt głodu, ale powoduje zatrucie (co zabiera twoje zdrowie, ale nie zabija) oraz zatrucie pokarmowe (co zwiększa twój głód). +Catches fish in water=Łowi ryby z wody +Very poisonous=Bardzo trujące diff --git a/mods/ITEMS/mcl_fishing/locale/mcl_fishing.zh_TW.tr b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.zh_TW.tr new file mode 100644 index 000000000..a0710f3ab --- /dev/null +++ b/mods/ITEMS/mcl_fishing/locale/mcl_fishing.zh_TW.tr @@ -0,0 +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.=嗯,魚! 這是一種健康的食品。 +Raw Salmon=生鮭魚 +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.=這是一種健康的可食用食品。 +Clownfish=熱帶魚 +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點飢餓感,而且會讓你中毒非常嚴重(非致命性地消耗你的健康),並導致嚴重的食物中毒(會增加你的飢餓感)。 +Catches fish in water=在水中取得魚 +Very poisonous=有劇毒 diff --git a/mods/ITEMS/mcl_fishing/mod.conf b/mods/ITEMS/mcl_fishing/mod.conf index 3a02c5cfc..71bde6146 100644 --- a/mods/ITEMS/mcl_fishing/mod.conf +++ b/mods/ITEMS/mcl_fishing/mod.conf @@ -1 +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 diff --git a/mods/ITEMS/mcl_fishing/sounds/bloop.ogg b/mods/ITEMS/mcl_fishing/sounds/bloop.ogg new file mode 100644 index 000000000..c724f5693 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/sounds/bloop.ogg differ diff --git a/mods/ITEMS/mcl_fishing/sounds/reel.ogg b/mods/ITEMS/mcl_fishing/sounds/reel.ogg new file mode 100644 index 000000000..2d4d0d350 Binary files /dev/null and b/mods/ITEMS/mcl_fishing/sounds/reel.ogg differ diff --git a/mods/ITEMS/mcl_fishing/sounds/watersplash.ogg b/mods/ITEMS/mcl_fishing/sounds/watersplash.ogg new file mode 100644 index 000000000..4cb6cb46b Binary files /dev/null and b/mods/ITEMS/mcl_fishing/sounds/watersplash.ogg differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png deleted file mode 100644 index 0c93fd4f9..000000000 Binary files a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_bobber.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png b/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png deleted file mode 100644 index 2fbcc7344..000000000 Binary files a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fishing_rod.png and /dev/null differ diff --git a/mods/ITEMS/mcl_fletching_table/README.md b/mods/ITEMS/mcl_fletching_table/README.md new file mode 100644 index 000000000..a30e2c1b4 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/README.md @@ -0,0 +1,19 @@ +mcl_fletching_table +------------------- +Fletching Tables, by PrairieWind + +Adds Fletching Tables to MineClone 2/5. + +License of source code +---------------------- +LGPLv2.1 + +License of media +---------------- + +fletching_table_bottom.png +fletching_table_front.png +fletching_table_side.png +fletching_table_top.png +License: CC BY-SA 4.0 +Author: MrRar diff --git a/mods/ITEMS/mcl_fletching_table/init.lua b/mods/ITEMS/mcl_fletching_table/init.lua new file mode 100644 index 000000000..7cb66f8b1 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/init.lua @@ -0,0 +1,26 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +-- Fletching Table Code. No use as of current Minecraft Updates. Basically a decor block. As of now, this is complete. +minetest.register_node("mcl_fletching_table:fletching_table", { + description = S("Fletching Table"), + _tt_help = S("A fletching table"), + _doc_items_longdesc = S("This is the fletcher villager's work station. It currently has no use beyond decoration."), + tiles = { + "fletching_table_top.png", "fletching_table_bottom.png", + "fletching_table_front.png", "fletching_table_front.png", + "fletching_table_side.png", "fletching_table_side.png" + }, + paramtype2 = "facedir", + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 + }) + +minetest.register_craft({ + output = "mcl_fletching_table:fletching_table", + recipe = { + { "mcl_core:flint", "mcl_core:flint", "" }, + { "group:wood", "group:wood", "" }, + { "group:wood", "group:wood", "" }, + } +}) \ No newline at end of file diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr new file mode 100644 index 000000000..cea6ab417 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_fletching_table +Fletching Table=Table d'Archerie +A fletching table=une table d'archerie +This is the fletcher villager's work station. It currently has no use beyond decoration.=Ceci est le poste de travail du villageois fléchier. Il n'a actuellement aucune autre utilité que la décoration. \ No newline at end of file diff --git a/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.tr b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.tr new file mode 100644 index 000000000..ecf8dd8d4 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/mcl_fletching_table.ja.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_fletching_table/locale/template.txt b/mods/ITEMS/mcl_fletching_table/locale/template.txt new file mode 100644 index 000000000..b42ea2578 --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/locale/template.txt @@ -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_fletching_table/mod.conf b/mods/ITEMS/mcl_fletching_table/mod.conf new file mode 100644 index 000000000..8b2a8ab5c --- /dev/null +++ b/mods/ITEMS/mcl_fletching_table/mod.conf @@ -0,0 +1,4 @@ +name = mcl_fletching_table +author = PrairieWind +depends = mcl_core, mcl_sounds, mcl_tools +description = Adds the fletching table villager workstation to MineClone 2/5. diff --git a/mods/ITEMS/mcl_flowerpots/depends.txt b/mods/ITEMS/mcl_flowerpots/depends.txt deleted file mode 100644 index bc1609be2..000000000 --- a/mods/ITEMS/mcl_flowerpots/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_farming -mcl_flowers -doc? diff --git a/mods/ITEMS/mcl_flowerpots/init.lua b/mods/ITEMS/mcl_flowerpots/init.lua index 3e22346f7..14350fac6 100644 --- a/mods/ITEMS/mcl_flowerpots/init.lua +++ b/mods/ITEMS/mcl_flowerpots/init.lua @@ -1,30 +1,17 @@ -local S = minetest.get_translator("mcl_flowerpots") +local S = minetest.get_translator(minetest.get_current_modname()) +local has_doc = minetest.get_modpath("doc") -local flowers = { - {"dandelion", "mcl_flowers:dandelion", S("Dandelion Flower Pot")}, - {"poppy", "mcl_flowers:poppy", S("Poppy Flower Pot")}, - {"blue_orchid", "mcl_flowers:blue_orchid", S("Blue Orchid Flower Pot")}, - {"allium", "mcl_flowers:allium", S("Allium Flower Pot")}, - {"azure_bluet", "mcl_flowers:azure_bluet", S("Azure Bluet Flower Pot")}, - {"tulip_red", "mcl_flowers:tulip_red", S("Red Tulip Flower Pot")}, - {"tulip_pink", "mcl_flowers:tulip_pink", S("Pink Tulip Flower Pot")}, - {"tulip_white", "mcl_flowers:tulip_white", S("White Tulip Flower Pot")}, - {"tulip_orange", "mcl_flowers:tulip_orange", S("Orange Tulip Flower Pot")}, - {"oxeye_daisy", "mcl_flowers:oxeye_daisy", S("Oxeye Daisy Flower Pot")}, - {"mushroom_brown", "mcl_mushrooms:mushroom_brown", S("Brown Mushroom Flower Pot")}, - {"mushroom_red", "mcl_mushrooms:mushroom_red", S("Red Mushroom Flower Pot")}, - {"sapling", "mcl_core:sapling", S("Oak Sapling Flower Pot")}, - {"acaciasapling", "mcl_core:acaciasapling", S("Acacia Sapling Flower Pot")}, - {"junglesapling", "mcl_core:junglesapling", S("Jungle Sapling Flower Pot")}, - {"darksapling", "mcl_core:darksapling", S("Dark Oak Sapling Flower Pot")}, - {"sprucesapling", "mcl_core:sprucesapling", S("Spruce Sapling Flower Pot")}, - {"birchsapling", "mcl_core:birchsapling", S("Birch Sapling Flower Pot")}, - {"deadbush", "mcl_core:deadbush", S("Dead Bush Flower Pot")}, - {"fern", "mcl_flowers:fern", S("Fern Flower Pot"), {"mcl_flowers_fern_inv.png"}}, -} +mcl_flowerpots = {} -local cubes = { - {"cactus", "mcl_core:cactus", S("Cactus Flower Pot")}, +---@type table +mcl_flowerpots.registered_pots = {} + +---@type nodebox +local pot_box = { + type = "fixed", + fixed = { + { -0.1875, -0.5, -0.1875, 0.1875, -0.125, 0.1875 }, + }, } minetest.register_node("mcl_flowerpots:flower_pot", { @@ -37,22 +24,16 @@ minetest.register_node("mcl_flowerpots:flower_pot", { tiles = { "mcl_flowerpots_flowerpot.png", }, + use_texture_alpha = "clip", visual_scale = 0.5, wield_image = "mcl_flowerpots_flowerpot_inventory.png", - wield_scale = {x=1.0, y=1.0, z=1.0}, paramtype = "light", sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, + selection_box = pot_box, + collision_box = pot_box, is_ground_content = false, inventory_image = "mcl_flowerpots_flowerpot_inventory.png", - groups = {dig_immediate=3, deco_block=1, attached_node=1, dig_by_piston=1, flower_pot=1}, + groups = { dig_immediate = 3, deco_block = 1, attached_node = 1, dig_by_piston = 1, flower_pot = 1 }, sounds = mcl_sounds.node_sound_stone_defaults(), on_rightclick = function(pos, node, clicker, itemstack) local name = clicker:get_player_name() @@ -61,142 +42,170 @@ minetest.register_node("mcl_flowerpots:flower_pot", { return end local item = clicker:get_wielded_item():get_name() - for _, row in ipairs(flowers) do - local flower = row[1] - local flower_node = row[2] - if item == flower_node then - minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..flower}) - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end - end - end - for _, row in ipairs(cubes) do - local flower = row[1] - local flower_node = row[2] - if item == flower_node then - minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..flower}) - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end + if mcl_flowerpots.registered_pots[item] then + minetest.swap_node(pos, { name = "mcl_flowerpots:flower_pot_" .. mcl_flowerpots.registered_pots[item] }) + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() end end end, }) minetest.register_craft({ - output = 'mcl_flowerpots:flower_pot', + output = "mcl_flowerpots:flower_pot", recipe = { - {'mcl_core:brick', '', 'mcl_core:brick'}, - {'', 'mcl_core:brick', ''}, - {'', '', ''}, - } -}) - -for _, row in ipairs(flowers) do -local flower = row[1] -local flower_node = row[2] -local desc = row[3] -local texture -if row[4] then - texture = row[4] -else - texture = minetest.registered_nodes[flower_node]["tiles"] -end -minetest.register_node("mcl_flowerpots:flower_pot_"..flower, { - description = desc, - _doc_items_create_entry = false, - drawtype = "mesh", - mesh = "flowerpot.obj", - tiles = { - "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0="..texture[1], - }, - visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, - paramtype = "light", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, - sounds = mcl_sounds.node_sound_stone_defaults(), - on_rightclick = function(pos, item, clicker) - local name = clicker:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, flower_node) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) - end, - drop = { - items = { - { items = { "mcl_flowerpots:flower_pot", flower_node } } - } + { "mcl_core:brick", "", "mcl_core:brick" }, + { "", "mcl_core:brick", "" }, + { "", "", "" }, }, }) --- Add entry alias for the Help -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..flower) -end + +---@param name string +---@param def {name: string, desc: string, image: string} +function mcl_flowerpots.register_potted_flower(name, def) + mcl_flowerpots.registered_pots[name] = def.name + minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, { + description = def.desc .. " " .. S("Flower Pot"), + _doc_items_create_entry = false, + drawtype = "mesh", + mesh = "flowerpot.obj", + tiles = { + "[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0=" .. def.image, + }, + use_texture_alpha = "clip", + visual_scale = 0.5, + paramtype = "light", + paramtype2 = def.paramtype2, + palette = def.palette, + sunlight_propagates = true, + selection_box = pot_box, + collision_box = pot_box, + is_ground_content = false, + groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2, grass_palette = def.grass_palette_group }, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_rightclick = function(pos, item, clicker) + local player_name = clicker:get_player_name() + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + minetest.add_item(vector.offset(pos, 0, 0.5, 0), name) + minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" }) + end, + drop = { + items = { + { items = { "mcl_flowerpots:flower_pot", name } }, + }, + }, + }) + -- Add entry alias for the Help + if has_doc then + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. name) + end end -for _, row in ipairs(cubes) do -local flower = row[1] -local flower_node = row[2] -local desc = row[3] -minetest.register_node("mcl_flowerpots:flower_pot_"..flower, { - description = desc, - _doc_items_create_entry = false, - drawtype = "mesh", - mesh = "flowerpot_with_long_cube.obj", - tiles = { - "mcl_flowerpots_"..flower..".png", - }, - visual_scale = 0.5, - wield_scale = {x=1.0, y=1.0, z=1.0}, - paramtype = "light", - sunlight_propagates = true, - selection_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - collision_box = { - type = "fixed", - fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2} - }, - is_ground_content = false, - groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2}, - sounds = mcl_sounds.node_sound_stone_defaults(), - on_rightclick = function(pos, item, clicker) - local name = "" - if clicker:is_player() then - name = clicker:get_player_name() - end - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return - end - minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, flower_node) - minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"}) - end, - drop = { - items = { - { items = { "mcl_flowerpots:flower_pot", flower_node } } - } - }, - +---@param name string +---@param def {name: string, desc: string, image: string} +function mcl_flowerpots.register_potted_cube(name, def) + mcl_flowerpots.registered_pots[name] = def.name + minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, { + description = def.desc .. " " .. S("Flower Pot"), + _doc_items_create_entry = false, + drawtype = "mesh", + mesh = "flowerpot_with_long_cube.obj", + tiles = { + def.image, + }, + use_texture_alpha = "clip", + visual_scale = 0.5, + paramtype = "light", + sunlight_propagates = true, + selection_box = pot_box, + collision_box = pot_box, + is_ground_content = false, + groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2 }, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_rightclick = function(pos, item, clicker) + local player_name = "" + if clicker:is_player() then + player_name = clicker:get_player_name() + end + if minetest.is_protected(pos, player_name) then + minetest.record_protection_violation(pos, player_name) + return + end + minetest.add_item(vector.offset(pos, 0, 0.5, 0), name) + minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" }) + end, + drop = { + items = { + { items = { "mcl_flowerpots:flower_pot", name } }, + }, + }, + }) + -- Add entry alias for the Help + if has_doc then + doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. def.name) + end +end +--forced because hard dependency to mcl_core +mcl_flowerpots.register_potted_cube("mcl_core:cactus", { + name = "cactus", + desc = S("Cactus"), + image = "mcl_flowerpots_cactus.png", }) --- Add entry alias for the Help -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..flower) -end -end +mcl_flowerpots.register_potted_flower("mcl_mushrooms:mushroom_brown", { + name = "mushroom_brown", + desc = S("Brown Mushroom"), + image = "farming_mushroom_brown.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_mushrooms:mushroom_red", { + name = "mushroom_red", + desc = S("Red Mushroom"), + image = "farming_mushroom_red.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:sapling", { + name = "sapling", + desc = S("Oak Sapling"), + image = "default_sapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:acaciasapling", { + name = "acaciasapling", + desc = S("Acacia Sapling"), + image = "default_acacia_sapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:junglesapling", { + name = "junglesapling", + desc = S("Jungle Sapling"), + image = "default_junglesapling.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:darksapling", { + name = "darksapling", + desc = S("Dark Oak Sapling"), + image = "mcl_core_sapling_big_oak.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:sprucesapling", { + name = "sprucesapling", + desc = S("Spruce Sapling"), + image = "mcl_core_sapling_spruce.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:birchsapling", { + name = "birchsapling", + desc = S("Birch Sapling"), + image = "mcl_core_sapling_birch.png", +}) + +mcl_flowerpots.register_potted_flower("mcl_core:deadbush", { + name = "deadbush", + desc = S("Dead Bush"), + image = "default_dry_shrub.png", +}) diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.de.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.de.tr index 3031e38d8..a110d5ffc 100644 --- a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.de.tr +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.de.tr @@ -1,6 +1,6 @@ # textdomain: mcl_flowerpots Dandelion Flower Pot=Blumentopf mit Löwenzahn -Poppy Floer Pot=Blumentopf mit Mohn +Poppy Flower Pot=Blumentopf mit Mohn Blue Orchid Flower Pot=Blumentopf mit blauer Orchidee Allium Flower Pot=Blumentopf mit Sternlauch Azure Bluet Flower Pot=Blumentopf mit Porzellansternchen diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.es.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.es.tr index b303194b5..fd12b1b4f 100644 --- a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.es.tr +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.es.tr @@ -1,6 +1,6 @@ # textdomain: mcl_flowerpots Dandelion Flower Pot=Maceta con diente de león -Poppy Floer Pot=Maceta con amapola +Poppy Flower Pot=Maceta con amapola Blue Orchid Flower Pot=Maceta con orquídeas azules Allium Flower Pot=Maceta con puerro Azure Bluet Flower Pot=Maceta con flor azul celeste @@ -22,4 +22,4 @@ Fern Flower Pot=Maceta con helecho Cactus Flower Pot=Maceta con cactus Flower Pot=Maceta Flower pots are decorative blocks in which flowers and other small plants can be placed.=Las macetas son bloques decorativos en los que se pueden colocar flores y otras plantas pequeñas. -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.=Simplemente coloque una planta en la maceta. Las macetas pueden contener flores pequeñas (no más de 1 bloque), árboles jóvenes, helechos, arbustos muertos, hongos y cactus. Haga clic derecho en una planta en maceta para recuperar la planta. \ No newline at end of file +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.=Simplemente coloque una planta en la maceta. Las macetas pueden contener flores pequeñas (no más de 1 bloque), árboles jóvenes, helechos, arbustos muertos, hongos y cactus. Haga clic derecho en una planta en maceta para recuperar la planta. diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr index d80497117..362b96c57 100644 --- a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.fr.tr @@ -1,26 +1,26 @@ # textdomain: mcl_flowerpots -Dandelion Flower Pot=Pissenlit en Pot -Poppy Flower Pot=Coquelicot en Pot -Blue Orchid Flower Pot=Orchidée Bleue en Pot -Allium Flower Pot=Allium en Pot -Azure Bluet Flower Pot=Houstonie Bleue en Pot -Red Tulip Flower Pot=Tulipe Rouge en Pot -Pink Tulip Flower Pot=Tulipe Rose en Pot -White Tulip Flower Pot=Tulipe Blanche en Pot -Orange Tulip Flower Pot=Tulipe Orange en Pot -Oxeye Daisy Flower Pot=Marguerite en Pot -Brown Mushroom Flower Pot=Champignon Marron en Pot -Red Mushroom Flower Pot=Champignon Rouge en Pot -Oak Sapling Flower Pot=Pousse de Chêne en Pot -Acacia Sapling Flower Pot=Pousse d'Acacia en Pot -Jungle Sapling Flower Pot=Pousse d'Acajou en Pot -Dark Oak Sapling Flower Pot=Pousse de Chêne Noir en Pot -Spruce Sapling Flower Pot=Pousse de Sapin en Pot -Birch Sapling Flower Pot=Pousse de Bouleau en Pot -Dead Bush Flower Pot=Arbuste Mort en Pot -Fern Flower Pot=Fougère en Pot -Cactus Flower Pot=Cactus en Pot -Flower Pot=Pot de Fleurs +Dandelion Flower Pot=Pissenlit en pot +Poppy Flower Pot=Coquelicot en pot +Blue Orchid Flower Pot=Orchidée bleue en pot +Allium Flower Pot=Allium en pot +Azure Bluet Flower Pot=Houstonie bleue en pot +Red Tulip Flower Pot=Tulipe rouge en pot +Pink Tulip Flower Pot=Tulipe rose en pot +White Tulip Flower Pot=Tulipe blanche en pot +Orange Tulip Flower Pot=Tulipe orange en pot +Oxeye Daisy Flower Pot=Marguerite en pot +Brown Mushroom Flower Pot=Champignon marron en pot +Red Mushroom Flower Pot=Champignon rouge en pot +Oak Sapling Flower Pot=Pousse de chêne en pot +Acacia Sapling Flower Pot=Pousse d'acacia en pot +Jungle Sapling Flower Pot=Pousse d'acajou en pot +Dark Oak Sapling Flower Pot=Pousse de chêne noir en pot +Spruce Sapling Flower Pot=Pousse de sapin en pot +Birch Sapling Flower Pot=Pousse de bouleau en pot +Dead Bush Flower Pot=Arbuste mort en pot +Fern Flower Pot=Fougère en pot +Cactus Flower Pot=Cactus en pot +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 diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr new file mode 100644 index 000000000..8e8a71b02 --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.ja.tr @@ -0,0 +1,26 @@ +# textdomain: mcl_flowerpots +Dandelion Flower Pot=鉢に植えたタンポポ +Poppy Flower Pot=鉢に植えたポピー +Blue Orchid Flower Pot=鉢に植えたヒスイラン +Allium 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=鉢に植えたフランスギク +Brown Mushroom Flower Pot=鉢に植えた茶色キノコ +Red Mushroom Flower Pot=鉢に植えた赤色キノコ +Oak Sapling Flower Pot=鉢に植えたオークの苗木 +Acacia 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=鉢に植えたシダ +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=小さな花や植物を保持可能 diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pl.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pl.tr new file mode 100644 index 000000000..4bc5e282a --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.pl.tr @@ -0,0 +1,27 @@ +# textdomain: mcl_flowerpots +Dandelion Flower Pot=Doniczka z mleczem +Poppy Flower Pot=Doniczka z makiem +Blue Orchid Flower Pot=Doniczka z niebieską orchideą +Allium Flower Pot=Doniczka z czosnkiem +Azure Bluet Flower Pot=Doniczka z houstonią błękitną +Red Tulip Flower Pot=Doniczka z czerwonym tulipanem +Pink Tulip Flower Pot=Doniczka z różowym tulipanem +White Tulip Flower Pot=Doniczka z białym tulipanem +Orange Tulip Flower Pot=Doniczka z pomarańczowym tulipanem +Oxeye Daisy Flower Pot=Doniczka ze stokrotką +Brown Mushroom Flower Pot=Doniczka z brązowym grzybem +Red Mushroom Flower Pot=Doniczka z czerwonym grzybem +Oak Sapling Flower Pot=Doniczka z sadzonką dębu +Acacia Sapling Flower Pot=Doniczka z sadzonką akacji +Jungle Sapling Flower Pot=Doniczka z tropikalną sadzonką +Dark Oak Sapling Flower Pot=Doniczka z sadzonką ciemnego dębu +Spruce Sapling Flower Pot=Doniczka z sadzonką świerku +Birch Sapling Flower Pot=Doniczka z sadzonką brzozy +Dead Bush Flower Pot=Doniczka z martwym buszem +Fern Flower Pot=Doniczka z paprocią +Cactus Flower Pot=Doniczka z kaktusem +Flower Pot=Doniczka +Flower pots are decorative blocks in which flowers and other small plants can be placed.=Doniczki są dekoracyjnymi blokami w których mogą zostać postawione kwiaty i inne małe rośliny. +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.=Po prostu umieść roślinę w doniczce. Mogę one przechowywać małe kwiaty (nie większe niż 1 blok), sadzonki, paprocie, martwe busze, grzyby i kaktusy. Kliknij prawym przyciskiem w doniczkę aby odzyskać roślinę. +Can hold a small flower or plant=Może przechowywać mały kwiat lub roślinę + diff --git a/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.zh_TW.tr b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.zh_TW.tr new file mode 100644 index 000000000..78ee96e8a --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/locale/mcl_flowerpots.zh_TW.tr @@ -0,0 +1,26 @@ +# textdomain: mcl_flowerpots +Dandelion Flower Pot=蒲公英盆栽 +Poppy Flower Pot=罌粟盆栽 +Blue Orchid Flower Pot=藍色蝴蝶蘭盆栽 +Allium 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=雛菊盆栽 +Brown Mushroom Flower Pot=棕色蘑菇盆栽 +Red Mushroom Flower Pot=紅色蘑菇盆栽 +Oak Sapling Flower Pot=橡木樹苗盆栽 +Acacia 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=蕨盆栽 +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=放置鮮花和其他小植物 diff --git a/mods/ITEMS/mcl_flowerpots/mod.conf b/mods/ITEMS/mcl_flowerpots/mod.conf new file mode 100644 index 000000000..e6a71c4da --- /dev/null +++ b/mods/ITEMS/mcl_flowerpots/mod.conf @@ -0,0 +1,3 @@ +name=mcl_flowerpots +depends=mcl_core, mcl_sounds, mcl_farming +optional_depends=doc \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/API.md b/mods/ITEMS/mcl_flowers/API.md new file mode 100644 index 000000000..f3dc87725 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/API.md @@ -0,0 +1,9 @@ +# API +Flower mod for mcl2 +# Functions +## mcl_flowers.register_simple_flower(name, desc, image, simple_selection_box) +Register a simple flower: +* name: legacity name eg: "my_super_flower" +* desc: description eg: "My Super Flower" +* image: texture +* simple_selection_box: nodebox of the flower \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/depends.txt b/mods/ITEMS/mcl_flowers/depends.txt deleted file mode 100644 index a7a7b9cd1..000000000 --- a/mods/ITEMS/mcl_flowers/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_util -mcl_sounds -screwdriver? -doc? diff --git a/mods/ITEMS/mcl_flowers/init.lua b/mods/ITEMS/mcl_flowers/init.lua index d60cb1e3b..e89d01b65 100644 --- a/mods/ITEMS/mcl_flowers/init.lua +++ b/mods/ITEMS/mcl_flowers/init.lua @@ -1,7 +1,12 @@ -local S = minetest.get_translator("mcl_flowers") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil +local mod_screwdriver = minetest.get_modpath("screwdriver") +local has_mcl_flowerpots = minetest.get_modpath("mcl_flowerpots") +mcl_flowers = {} +mcl_flowers.registered_simple_flowers = {} -- Simple flower template local smallflowerlongdesc = S("This is a small flower. Small flowers are mainly used for dye production and can also be potted.") local plant_usage_help = S("It can only be placed on a block on which it would also survive.") @@ -14,7 +19,7 @@ local get_palette_color_from_pos = function(pos) local biome_name = minetest.get_biome_name(biome) local reg_biome = minetest.registered_biomes[biome_name] if reg_biome then - index = reg_biome._mcl_palette_index + index = reg_biome._mcl_grass_palette_index end end return index @@ -46,56 +51,71 @@ local on_place_flower = mcl_util.generate_on_place_plant_function(function(pos, if (light_night and light_night >= 8) or (light_day and light_day >= minetest.LIGHT_MAX) then light_ok = true end + if itemstack:get_name() == "mcl_flowers:wither_rose" and ( minetest.get_item_group(soil_node.name, "grass_block") > 0 or soil_node.name == "mcl_core:dirt" or soil_node.name == "mcl_core:coarse_dirt" or soil_node.name == "mcl_mud:mud" or soil_node.name == "mcl_moss:moss" or soil_node.name == "mcl_nether:netherrack" or minetest.get_item_group(soil_node.name, "soul_block") > 0 ) then + return true,colorize + end local is_flower = minetest.get_item_group(itemstack:get_name(), "flower") == 1 local ok = (soil_node.name == "mcl_core:dirt" or minetest.get_item_group(soil_node.name, "grass_block") == 1 or (not is_flower and (soil_node.name == "mcl_core:coarse_dirt" or soil_node.name == "mcl_core:podzol" or soil_node.name == "mcl_core:podzol_snow"))) and light_ok return ok, colorize end) -local function add_simple_flower(name, desc, image, simple_selection_box) - minetest.register_node("mcl_flowers:"..name, { - description = desc, +function mcl_flowers.register_simple_flower(name, def) + local newname = "mcl_flowers:"..name + if not def._mcl_silk_touch_drop then def._mcl_silk_touch_drop = nil end + if not def.drop then def.drop = newname end + mcl_flowers.registered_simple_flowers[newname] = { + name=name, + desc=def.desc, + image=def.image, + simple_selection_box=def.simple_selection_box, + } + minetest.register_node(newname, { + description = def.desc, _doc_items_longdesc = smallflowerlongdesc, _doc_items_usagehelp = plant_usage_help, drawtype = "plantlike", waving = 1, - tiles = { image..".png" }, - inventory_image = image..".png", - wield_image = image..".png", + tiles = { def.image }, + inventory_image = def.image, + wield_image = def.image, sunlight_propagates = true, paramtype = "light", walkable = false, stack_max = 64, - groups = {dig_immediate=3,flammable=2,fire_encouragement=60,fire_flammability=100,plant=1,flower=1,place_flowerlike=1,non_mycelium_plant=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, + drop = def.drop, + groups = { + attached_node = 1, deco_block = 1, dig_by_piston = 1, dig_immediate = 3, + dig_by_water = 1, destroy_by_lava_flow = 1, enderman_takable = 1, + plant = 1, flower = 1, place_flowerlike = 1, non_mycelium_plant = 1, + flammable = 2, fire_encouragement = 60, fire_flammability = 100, + compostability = 65 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), node_placement_prediction = "", on_place = on_place_flower, selection_box = { type = "fixed", - fixed = simple_selection_box, + fixed = def.selection_box, }, + _mcl_silk_touch_drop = def._mcl_silk_touch_drop, }) + if def.potted and has_mcl_flowerpots then + mcl_flowerpots.register_potted_flower(newname, { + name = name, + desc = def.desc, + image = def.image, + }) + end end -add_simple_flower("poppy", S("Poppy"), "mcl_flowers_poppy", { -5/16, -0.5, -5/16, 5/16, 5/16, 5/16 }) -add_simple_flower("dandelion", S("Dandelion"), "flowers_dandelion_yellow", { -4/16, -0.5, -4/16, 4/16, 3/16, 4/16 }) -add_simple_flower("oxeye_daisy", S("Oxeye Daisy"), "mcl_flowers_oxeye_daisy", { -4/16, -0.5, -4/16, 4/16, 4/16, 4/16 }) -add_simple_flower("tulip_orange", S("Orange Tulip"), "flowers_tulip", { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }) -add_simple_flower("tulip_pink", S("Pink Tulip"), "mcl_flowers_tulip_pink", { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }) -add_simple_flower("tulip_red", S("Red Tulip"), "mcl_flowers_tulip_red", { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }) -add_simple_flower("tulip_white", S("White Tulip"), "mcl_flowers_tulip_white", { -3/16, -0.5, -3/16, 3/16, 4/16, 3/16 }) -add_simple_flower("allium", S("Allium"), "mcl_flowers_allium", { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }) -add_simple_flower("azure_bluet", S("Azure Bluet"), "mcl_flowers_azure_bluet", { -5/16, -0.5, -5/16, 5/16, 3/16, 5/16 }) -add_simple_flower("blue_orchid", S("Blue Orchid"), "mcl_flowers_blue_orchid", { -5/16, -0.5, -5/16, 5/16, 7/16, 5/16 }) - - local wheat_seed_drop = { max_items = 1, items = { { - items = {'mcl_farming:wheat_seeds'}, + items = {"mcl_farming:wheat_seeds"}, rarity = 8, }, - } + }, } local fortune_wheat_seed_drop = { @@ -132,7 +152,12 @@ local def_tallgrass = { walkable = false, buildable_to = true, is_ground_content = true, - groups = {handy=1,shearsy=1, flammable=3,fire_encouragement=60,fire_flammability=100,attached_node=1,plant=1,place_flowerlike=2,non_mycelium_plant=1,dig_by_water=1,destroy_by_lava_flow=1,deco_block=1}, + 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, + dig_by_water = 1, destroy_by_lava_flow = 1, compostability = 30, grass_palette = 1 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), drop = wheat_seed_drop, _mcl_shears_drop = true, @@ -156,19 +181,37 @@ def_fern.selection_box = { type = "fixed", fixed = { -6/16, -0.5, -6/16, 6/16, 5/16, 6/16 }, } +def_fern.groups.compostability = 65 minetest.register_node("mcl_flowers:fern", def_fern) +if has_mcl_flowerpots then + mcl_flowerpots.register_potted_flower("mcl_flowers:fern", { + name = "fern", + desc = S("Fern"), + image = "mcl_flowers_fern_inv.png", + grass_palette_group = 1 + }) +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) if not inv_img then inv_img = top_img end - local usagehelp, noncreative, create_entry, paramtype2, palette + local create_entry, paramtype2, palette if is_flower == nil then is_flower = true end - local bottom_groups = {flammable=2,fire_encouragement=60,fire_flammability=100, non_mycelium_plant=1,attached_node=1, dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1, plant=1,double_plant=1,deco_block=1,not_in_creative_inventory=noncreative} + local bottom_groups = { + attached_node = 1, deco_block = 1, + dig_by_water = 1, destroy_by_lava_flow = 1, dig_by_piston = 1, + flammable = 2, fire_encouragement = 60, fire_flammability = 100, + plant = 1, double_plant = 1, non_mycelium_plant = 1, compostability = 65, grass_palette = nil + } + if name == "double_grass" then + bottom_groups.compostability = 50 + end if is_flower then bottom_groups.flower = 1 bottom_groups.place_flowerlike = 1 @@ -181,9 +224,10 @@ local function add_large_plant(name, desc, longdesc, bottom_img, top_img, inv_im if grass_color then paramtype2 = "color" palette = "mcl_core_palette_grass.png" + bottom_groups.grass_palette = 1 end if longdesc == nil then - noncreative = 1 + bottom_groups.not_in_creative_inventory = 1 create_entry = false end -- Drop itself by default @@ -347,8 +391,8 @@ add_large_plant("sunflower", S("Sunflower"), S("A sunflower is a large plant whi 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.") -add_large_plant("double_grass", S("Double Tallgrass"), longdesc_grass, "mcl_flowers_double_plant_grass_bottom.png", "mcl_flowers_double_plant_grass_top.png", "mcl_flowers_double_plant_grass_inv.png", 6/16, 4/16, wheat_seed_drop, {"mcl_flowers:tallgrass 2"}, false, true, nil, fortune_wheat_seed_drop) -add_large_plant("double_fern", S("Large Fern"), longdesc_fern, "mcl_flowers_double_plant_fern_bottom.png", "mcl_flowers_double_plant_fern_top.png", "mcl_flowers_double_plant_fern_inv.png", 5/16, 5/16, wheat_seed_drop, {"mcl_flowers:fern 2"}, false, true, nil, fortune_wheat_seed_drop) +add_large_plant("double_grass", S("Double Tallgrass"), longdesc_grass, "mcl_flowers_double_plant_grass_bottom.png", "mcl_flowers_double_plant_grass_top.png", "mcl_flowers_double_plant_grass_inv.png", 6/16, 4/16, wheat_seed_drop, {"mcl_flowers:tallgrass 2"}, false, true, fortune_wheat_seed_drop) +add_large_plant("double_fern", S("Large Fern"), longdesc_fern, "mcl_flowers_double_plant_fern_bottom.png", "mcl_flowers_double_plant_fern_top.png", "mcl_flowers_double_plant_fern_inv.png", 5/16, 5/16, wheat_seed_drop, {"mcl_flowers:fern 2"}, false, true, fortune_wheat_seed_drop) minetest.register_abm({ label = "Pop out flowers", @@ -385,12 +429,17 @@ minetest.register_node("mcl_flowers:waterlily", { paramtype = "light", paramtype2 = "facedir", tiles = {"flowers_waterlily.png", "flowers_waterlily.png^[transformFY"}, + color = "#208030", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, inventory_image = "flowers_waterlily.png", wield_image = "flowers_waterlily.png", liquids_pointable = true, walkable = true, sunlight_propagates = true, - groups = {dig_immediate = 3, plant=1, dig_by_water = 1,destroy_by_lava_flow=1, dig_by_piston = 1, deco_block=1, dig_by_boat=1}, + groups = { + deco_block = 1, plant = 1, compostability = 65, destroy_by_lava_flow = 1, + dig_immediate = 3, dig_by_water = 1, dig_by_piston = 1, dig_by_boat = 1, + }, sounds = mcl_sounds.node_sound_leaves_defaults(), node_placement_prediction = "", node_box = { @@ -440,7 +489,6 @@ minetest.register_node("mcl_flowers:waterlily", { end end end - return itemstack end, on_rotate = on_rotate, @@ -451,31 +499,29 @@ minetest.register_alias("mcl_core:tallgrass", "mcl_flowers:tallgrass") -- mcimport support: re-adds missing double_plant tops in mcimported worlds. local mg_name = minetest.get_mapgen_setting("mg_name") -local mod_mcimport = minetest.get_modpath("mcimport") ~= nil +local mod_mcimport = minetest.get_modpath("mcimport") + local fix_doubleplants = minetest.settings:get_bool("fix_doubleplants", true) +if mod_mcimport and mg_name == "singlenode" and fix_doubleplants == true then + local flowernames = { "peony", "rose_bush", "lilac", "sunflower", "double_fern", "double_grass" } - if mod_mcimport and mg_name == "singlenode" and fix_doubleplants == true then - local flowernames = { "peony", "rose_bush", "lilac", "sunflower", "double_fern", "double_grass" } - for c=1, 6 do - local flowername = flowernames[c] - end - - minetest.register_lbm({ - label = "Add double plant tops.", - name = "mcl_flowers:double_plant_topper", - run_at_every_load = true, - nodenames = { "mcl_flowers:peony", "mcl_flowers:rose_bush", "mcl_flowers:lilac", "mcl_flowers:sunflower", "mcl_flowers:double_fern", "mcl_flowers:double_grass" }, - action = function(pos, node) - for c=1, 6 do - local flowername = flowernames[c] - local bottom = pos - local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } - if node.name == "mcl_flowers:"..flowername then - minetest.set_node(top, {name = "mcl_flowers:"..flowername.."_top"}) - end + minetest.register_lbm({ + label = "Add double plant tops.", + name = "mcl_flowers:double_plant_topper", + run_at_every_load = true, + nodenames = { "mcl_flowers:peony", "mcl_flowers:rose_bush", "mcl_flowers:lilac", "mcl_flowers:sunflower", "mcl_flowers:double_fern", "mcl_flowers:double_grass" }, + action = function(pos, node) + for c = 1, 6 do + local flowername = flowernames[c] + local bottom = pos + local top = { x = bottom.x, y = bottom.y + 1, z = bottom.z } + if node.name == "mcl_flowers:"..flowername then + minetest.set_node(top, {name = "mcl_flowers:"..flowername.."_top"}) end - end, - }) - end + end + end, + }) +end +dofile(modpath.."/register.lua") diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.de.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.de.tr index 7c4a83b88..0e1262e3c 100644 --- a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.de.tr +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.de.tr @@ -12,9 +12,9 @@ Allium=Sternlauch Azure Bluet=Porzellansternchen Blue Orchid=Blaue Orchidee Tall Grass=Hohes Gras -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.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich hohes Gras zu doppelhohem Gras verwandeln. +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.=Hohes Gras ist eine kleine Pflanze, die oft auf Wiesenflächen wächst. Es kann für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich hohes Gras zu doppelhohem Gras verwandeln. Fern=Farn -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.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl wird sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln. +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.=Farne sind kleine Pflanzen, die oft in Dschungeln und Taigas vorkommen. Sie können für Weizensamen abgeerntet werden. Mit Knochenmehl lässt sich ein Farn zu einem großen Farn, der zwei Blöcke hoch ist, verwandeln. (Top Part)=(Oberseite) Peony=Pfingstrose A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Eine Pfingstrose ist eine große Pflanze, die zwei Blöcke hoch ist. Sie wird hauptsächlich für die Farbenproduktion gebraucht. diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.fr.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.fr.tr index 1a336e2c4..c96a585f9 100644 --- a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.fr.tr +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.fr.tr @@ -11,17 +11,18 @@ White Tulip=Tulipe Blanche Allium=Allium Azure Bluet=Houstonie Bleue Blue Orchid=Orchidée Bleue +Wither Rose=Rose de Wither +Lily of the Valley=Muguet +Cornflower=Bleuet Tall Grass=Hautes herbes 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.=L'herbe haute est une petite plante qui se rencontre souvent à la surface des prairies. Il peut être récolté pour les graines de blé. En utilisant de la farine d'os, les hautes herbes peuvent être transformées en herbes hautes doubles de deux blocs de hauteur. Fern=Fougère 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.=Les fougères sont de petites plantes qui se produisent naturellement dans les jungles et les taigas. Ils peuvent être récoltés pour les graines de blé. En utilisant de la farine d'os, une fougère peut être transformée en une grande fougère haute de deux blocs. (Top Part)=(Partie supérieure) Peony=Pivoine -A peony is a large plant which occupies two blocks. It is mainly used in dye production.= -# ^^^ OLD TRANSLATION FOR ABOVE: Une pivoine est une grande plante qui occupe deux blocs. Il est principalement utilisé dans la protection des colorants. +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Une pivoine est une grande plante qui occupe deux blocs. Principalement utilisé dans la production de colorants. Rose Bush=Rosier -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.= -# ^^^ OLD TRANSLATION FOR ABOVE: Un rosier est une grande plante qui occupe deux blocs. Il n'y a pas de danger à le toucher. Les rosiers sont principalement utilisés dans la protection des colorants. +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.=Un rosier est une grande plante qui occupe deux blocs. Il n'y a rien a craindre à le toucher. Les rosiers sont principalement utilisés dans la production de teinture. Lilac=Lilas A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=Un lilas est une grande plante qui occupe deux blocs. Il est principalement utilisé dans la production de colorants. Sunflower=Tournesol diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr new file mode 100644 index 000000000..60daf85b0 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.ja.tr @@ -0,0 +1,32 @@ +# 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.=生き残るブロックにのみ配置できます。 +Poppy=ポピー +Dandelion=タンポポ +Oxeye Daisy=フランスギク +Orange Tulip=橙色のチューリップ +Pink Tulip=桃色のチューリップ +Red Tulip=赤色のチューリップ +White Tulip=白色のチューリップ +Allium=アリウム +Azure Bluet=ヒナソウ +Blue Orchid=ヒスイラン +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=シダ +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.=シダは、ジャングルやタイガに自生する小さな植物です。そこから小麦の種を収穫できることがあります。骨粉を使うことで、高さ2ブロックの、大きなシダに変えられます。 +(Top Part)=(上部) +Peony=ボタン +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=ボタンは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Rose Bush=バラの低木 +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.=バラの低木は、2ブロック分を占める大きな植物です。触っても大丈夫です。バラの低木は主に染料に使われます。 +Lilac=ライラック +A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=ライラックは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Sunflower=ヒマワリ +A sunflower is a large plant which occupies two blocks. It is mainly used in dye production.=ヒマワリは、2つのブロックを占める大きな植物です。主に染料に使われます。 +Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.=丈が倍高い草は、丈が高い草の変種であり、2ブロックを占有します。そこから小麦の種を収穫できることがあります。 +Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.=大きなシダは、シダの変種であり、2ブロックを占有します。そこから小麦の種を収穫できることがあります。 +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.=スイレンの葉は、歩くことができるペラい植物ブロックです。水源や氷、フロストアイスの上に置けます。 diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pl.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pl.tr new file mode 100644 index 000000000..828eea96a --- /dev/null +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.pl.tr @@ -0,0 +1,32 @@ +# textdomain: mcl_flowers +This is a small flower. Small flowers are mainly used for dye production and can also be potted.=To jest mały kwiat. Małe kwiaty są głównie wykorzystywane do tworzenia farb oraz do ustawiania w doniczkach. +It can only be placed on a block on which it would also survive.=Może być postawiony tylko na blokach na których jest w stanie przeżyć. +Poppy=Mak +Dandelion=Mniszek lekarski +Oxeye Daisy=Stokrotka +Orange Tulip=Pomarańczowy tulipan +Pink Tulip=Różowy tulipan +Red Tulip=Czerwony tulipan +White Tulip=Biały tulipan +Allium=Czosnek +Azure Bluet=Houstonia błękitna +Blue Orchid=Niebieska orchidea +Tall Grass=Wysoka trawa +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.=Wysoka trawa jest małą rośliną często występująca na trawiastych biomach. Mogą z nich wypaść nasiona. Używając mączki kostnej można ją zamienić w podwójnie wysoką trawę, która ma dwa bloki wysokości. +Fern=Paproć +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.=Paprocie to małe rośliny występujące naturalnie w tropikach i tajgach. Mogą z nich wypaść nasiona. Używając mączki kostnej można je zamienić w duże paprocie, które mają dwa bloki wysokości. +(Top Part)=(Górna część) +Peony=Piwonia +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=Piwonia jest dużą rośliną zajmującą dwa bloki. Jest głównie używana jako źródło farby. +Rose Bush=Krzew róży. +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.=Krzew róży jest dużą rośliną zajmującą dwa bloki. Można go dotykać. Jest głównie używana jako źródło farby. +Lilac=Bez +A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=Bez jest dużą rośliną zajmującą dwa bloki. Jest głównie używana jako źródło farby. +Sunflower=Słonecznik +A sunflower is a large plant which occupies two blocks. It is mainly used in dye production.=Słonecznik jest dużą rośliną zajmującą dwa bloki. Jest głównie używana jako źródło farby. +Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.=Podwójna wysoka trawa jest dużą rośliną zajmującą dwa bloki. Mogą z niej wypaść nasiona zboża. +Large fern is a variant of fern and occupies two blocks. It can be harvested for wheat seeds.=Duża paproć jest dużą rośliną zajmującą dwa bloki. Mogą z niej wypaść nasiona zboża. +Double Tallgrass=Podwójnie wysoka trawa +Large Fern=Duża paproć +Lily Pad=Lilia wodna +A lily pad is a flat plant block which can be walked on. They can be placed on water sources, ice and frosted ice.=Lilia wodna jest płaską rośliną po której można chodzić. Można je stawiać na źródłach wody, lodzie i oszronionym lodzie. diff --git a/mods/ITEMS/mcl_flowers/locale/mcl_flowers.zh_TW.tr b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.zh_TW.tr new file mode 100644 index 000000000..b8fb0cbe4 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/locale/mcl_flowers.zh_TW.tr @@ -0,0 +1,32 @@ +# 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.= +Poppy=罌粟 +Dandelion=蒲公英 +Oxeye Daisy=雛菊 +Orange Tulip=橙色鬱金香 +Pink Tulip=粉紅色鬱金香 +Red Tulip=紅色鬱金香 +White Tulip=白色鬱金香 +Allium=紫紅球花 +Azure Bluet=藍花美耳草 +Blue Orchid=藍色蝴蝶蘭 +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.=草是一種小植物,經常出現在草原的表面。它可以收穫小麥的種子。通過使用骨粉,高草可以變成兩塊高的芒草。 +Fern=蕨 +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.=蕨是自然存在於叢林和台地的小型植物。它們可以被收割為小麥種子。通過使用骨粉,可以把蕨變成兩塊高的高蕨。 +(Top Part)=(上部分) +Peony=牡丹花 +A peony is a large plant which occupies two blocks. It is mainly used in dye production.=牡丹花是一種大型植物,共有兩格高。它主要用於染料生產。 +Rose Bush=玫瑰叢 +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.=玫瑰叢是一種大型植物,共有兩格高。觸摸它是安全的。玫瑰叢主要用於染料生產。 +Lilac=紫丁香 +A lilac is a large plant which occupies two blocks. It is mainly used in dye production.=紫丁香是一種大型植物,共有兩格高。它主要用於染料生產。 +Sunflower=向日葵 +A sunflower is a large plant which occupies two blocks. It is mainly used in dye production.=向日葵是一種大型植物,共有兩格高。它主要用於染料生產。 +Double tallgrass a variant of tall grass and occupies two blocks. It can be harvested for wheat seeds.=芒草是草的兩格高變種。可以收割小麥種子。 +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.=荷葉是一種平坦的植物方塊,可以在上面行走。它們可以放在水源、冰面和結霜的冰面上。 diff --git a/mods/ITEMS/mcl_flowers/locale/template.txt b/mods/ITEMS/mcl_flowers/locale/template.txt index 53a6e7495..0d84093de 100644 --- a/mods/ITEMS/mcl_flowers/locale/template.txt +++ b/mods/ITEMS/mcl_flowers/locale/template.txt @@ -11,6 +11,9 @@ White Tulip= Allium= 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.= Fern= diff --git a/mods/ITEMS/mcl_flowers/mod.conf b/mods/ITEMS/mcl_flowers/mod.conf new file mode 100644 index 000000000..b309ac22e --- /dev/null +++ b/mods/ITEMS/mcl_flowers/mod.conf @@ -0,0 +1,3 @@ +name=mcl_flowers +depends=mcl_core, mcl_util, mcl_sounds +optional_depends=screwdriver, doc, mcl_flowerpots \ No newline at end of file diff --git a/mods/ITEMS/mcl_flowers/register.lua b/mods/ITEMS/mcl_flowers/register.lua new file mode 100644 index 000000000..dc0f7d9a0 --- /dev/null +++ b/mods/ITEMS/mcl_flowers/register.lua @@ -0,0 +1,80 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_flowers.register_simple_flower("poppy", { + desc = S("Poppy"), + image = "mcl_flowers_poppy.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 5/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("dandelion", { + desc = S("Dandelion"), + image = "flowers_dandelion_yellow.png", + selection_box = { -4/16, -0.5, -4/16, 4/16, 3/16, 4/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("oxeye_daisy", { + desc = S("Oxeye Daisy"), + image = "mcl_flowers_oxeye_daisy.png", + selection_box = { -4/16, -0.5, -4/16, 4/16, 4/16, 4/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_orange", { + desc = S("Orange Tulip"), + image = "flowers_tulip.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_pink", { + desc = S("Pink Tulip"), + image = "mcl_flowers_tulip_pink.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 5/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_red", { + desc = S("Red Tulip"), + image = "mcl_flowers_tulip_red.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("tulip_white", { + desc = S("White Tulip"), + image = "mcl_flowers_tulip_white.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 4/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("allium", { + desc = S("Allium"), + image = "mcl_flowers_allium.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("azure_bluet", { + desc = S("Azure Bluet"), + image = "mcl_flowers_azure_bluet.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 3/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("blue_orchid", { + desc = S("Blue Orchid"), + image = "mcl_flowers_blue_orchid.png", + selection_box = { -5/16, -0.5, -5/16, 5/16, 7/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("wither_rose", { + desc = S("Wither Rose"), + image = "mcl_flowers_wither_rose.png", + selection_box = { -3/16, -0.5, -3/16, 3/16, 6/16, 3/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("lily_of_the_valley", { + desc = S("Lily of the Valley"), + image = "mcl_flowers_lily_of_the_valley.png", + selection_box = { -5/16, -0.5, -5/16, 4/16, 5/16, 5/16 }, + potted = true, +}) +mcl_flowers.register_simple_flower("cornflower", { + desc = S("Cornflower"), + image = "mcl_flowers_cornflower.png", + selection_box = { -4/16, -0.5, -4/16, 4/16, 3/16, 4/16 }, + potted = true, +}) diff --git a/mods/ITEMS/mcl_flowers/textures/flowers_waterlily.png b/mods/ITEMS/mcl_flowers/textures/flowers_waterlily.png deleted file mode 100644 index 53b13f25b..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/flowers_waterlily.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_blue_orchid.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_blue_orchid.png deleted file mode 100644 index c5ddf11cc..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_blue_orchid.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_bottom.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_bottom.png deleted file mode 100644 index 84427db2d..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_inv.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_inv.png deleted file mode 100644 index 5bc4aa795..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_top.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_top.png deleted file mode 100644 index 5d503f85b..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_fern_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_bottom.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_bottom.png deleted file mode 100644 index fc42bb20e..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_inv.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_inv.png deleted file mode 100644 index 6f53fac56..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_top.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_top.png deleted file mode 100644 index 2dbe8aa3c..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_grass_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_rose_bottom.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_rose_bottom.png deleted file mode 100644 index 13170e669..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_rose_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_back.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_back.png deleted file mode 100644 index 3bf371775..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_back.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_bottom.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_bottom.png deleted file mode 100644 index 4f169a843..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_syringa_top.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_syringa_top.png deleted file mode 100644 index ca478a3f8..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_syringa_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern.png deleted file mode 100644 index 7850e9a81..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern_inv.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern_inv.png deleted file mode 100644 index 3041c3178..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_fern_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass.png deleted file mode 100644 index 5ab4b00f7..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass.png and /dev/null differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass_inv.png b/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass_inv.png deleted file mode 100644 index 3481b46d4..000000000 Binary files a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tallgrass_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_furnaces/depends.txt b/mods/ITEMS/mcl_furnaces/depends.txt deleted file mode 100644 index ca05945f1..000000000 --- a/mods/ITEMS/mcl_furnaces/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcl_init -mcl_formspec -mcl_core -mcl_sounds -mcl_craftguide -mcl_achievements -mcl_particles -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_furnaces/init.lua b/mods/ITEMS/mcl_furnaces/init.lua index d3877d90b..8cb8ad5a0 100644 --- a/mods/ITEMS/mcl_furnaces/init.lua +++ b/mods/ITEMS/mcl_furnaces/init.lua @@ -1,5 +1,5 @@ -local S = minetest.get_translator("mcl_furnaces") +local S = minetest.get_translator(minetest.get_current_modname()) local LIGHT_ACTIVE_FURNACE = 13 @@ -15,11 +15,11 @@ local function active_formspec(fuel_percent, item_percent) "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[current_name;src;2.75,0.5;1,1;]".. + "list[context;src;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[current_name;fuel;2.75,2.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[current_name;dst;5.75,1.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]".. @@ -29,11 +29,11 @@ local function active_formspec(fuel_percent, item_percent) -- 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[current_name;dst]".. + "listring[context;dst]".. "listring[current_player;main]".. - "listring[current_name;src]".. + "listring[context;src]".. "listring[current_player;main]".. - "listring[current_name;fuel]".. + "listring[context;fuel]".. "listring[current_player;main]" end @@ -44,11 +44,11 @@ local inactive_formspec = "size[9,8.75]".. "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[current_name;src;2.75,0.5;1,1;]".. + "list[context;src;2.75,0.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,0.5,1,1).. - "list[current_name;fuel;2.75,2.5;1,1;]".. + "list[context;fuel;2.75,2.5;1,1;]".. mcl_formspec.get_itemslot_bg(2.75,2.5,1,1).. - "list[current_name;dst;5.75,1.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]".. @@ -56,11 +56,11 @@ local inactive_formspec = "size[9,8.75]".. -- 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[current_name;dst]".. + "listring[context;dst]".. "listring[current_player;main]".. - "listring[current_name;src]".. + "listring[context;src]".. "listring[current_player;main]".. - "listring[current_name;fuel]".. + "listring[context;fuel]".. "listring[current_player;main]" local receive_fields = function(pos, formname, fields, sender) @@ -75,9 +75,9 @@ local function give_xp(pos, player) local xp = meta:get_int("xp") if xp > 0 then if player then - mcl_experience.add_experience(player, xp) + mcl_experience.add_xp(player, xp) else - mcl_experience.throw_experience(vector.add(pos, dir), xp) + mcl_experience.throw_xp(vector.add(pos, dir), xp) end meta:set_int("xp", 0) end @@ -161,6 +161,12 @@ local function on_metadata_inventory_take(pos, listname, index, stack, player) end end +local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "dst" then + give_xp(pos, player) + end +end + local function spawn_flames(pos, param2) local minrelpos, maxrelpos local dir = minetest.facedir_to_dir(param2) @@ -211,14 +217,14 @@ end local function furnace_reset_delta_time(pos) local meta = minetest.get_meta(pos) - local time_speed = tonumber(minetest.settings:get('time_speed') or 72) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) if (time_speed < 0.1) then return end local time_multiplier = 86400 / time_speed local current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier) - -- TODO: Change meta:get/set_string() to get/set_float() for 'last_gametime'. + -- TODO: Change meta:get/set_string() to get/set_float() for "last_gametime". -- In Windows *_float() works OK but under Linux it returns rounded unusable values like 449540.000000000 local last_game_time = meta:get_string("last_gametime") if last_game_time then @@ -233,7 +239,7 @@ end local function furnace_get_delta_time(pos, elapsed) local meta = minetest.get_meta(pos) - local time_speed = tonumber(minetest.settings:get('time_speed') or 72) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) local current_game_time if (time_speed < 0.1) then return meta, elapsed @@ -378,7 +384,6 @@ local function furnace_node_timer(pos, elapsed) -- Update formspec and node -- local formspec = inactive_formspec - local item_state local item_percent = 0 if cookable then item_percent = math.floor(src_time / cooked.time * 100) @@ -408,7 +413,7 @@ 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", srclist[1]:get_name()) + meta:set_string("src_item", src_item) else meta:set_string("src_item", "") end @@ -435,7 +440,10 @@ 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. 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.").."\n".. + 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 = { @@ -451,7 +459,7 @@ minetest.register_node("mcl_furnaces:furnace", { on_timer = furnace_node_timer, after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + local meta2 = meta:to_table() meta:from_table(oldmetadata) local inv = meta:get_inventory() for _, listname in ipairs({"src", "dst", "fuel"}) do @@ -461,26 +469,28 @@ minetest.register_node("mcl_furnaces:furnace", { minetest.add_item(p, stack) end end - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("formspec", inactive_formspec) local inv = meta:get_inventory() - inv:set_size('src', 1) - inv:set_size('fuel', 1) - inv:set_size('dst', 1) + inv:set_size("src", 1) + inv:set_size("fuel", 1) + inv:set_size("dst", 1) end, on_destruct = function(pos) mcl_particles.delete_node_particlespawners(pos) give_xp(pos) end, - on_metadata_inventory_move = function(pos) + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) -- Reset accumulated game time when player works with furnace: furnace_reset_delta_time(pos) minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) end, on_metadata_inventory_put = function(pos) -- Reset accumulated game time when player works with furnace: @@ -494,9 +504,7 @@ minetest.register_node("mcl_furnaces:furnace", { -- start timer function, it will helpful if player clears dst slot minetest.get_node_timer(pos):start(1.0) - if listname == "dst" then - give_xp(pos, player) - end + on_metadata_inventory_take(pos, listname, index, stack, player) end, allow_metadata_inventory_put = allow_metadata_inventory_put, @@ -552,6 +560,7 @@ minetest.register_node("mcl_furnaces:furnace_active", { allow_metadata_inventory_put = allow_metadata_inventory_put, allow_metadata_inventory_move = allow_metadata_inventory_move, allow_metadata_inventory_take = allow_metadata_inventory_take, + on_metadata_inventory_move = on_metadata_inventory_move, on_metadata_inventory_take = on_metadata_inventory_take, on_receive_fields = receive_fields, _mcl_blast_resistance = 3.5, @@ -563,9 +572,9 @@ minetest.register_node("mcl_furnaces:furnace_active", { minetest.register_craft({ output = "mcl_furnaces:furnace", 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" }, + { "group:cobble", "group:cobble", "group:cobble" }, + { "group:cobble", "", "group:cobble" }, + { "group:cobble", "group:cobble", "group:cobble" }, } }) diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.es.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.es.tr index 10378c2da..ee645231e 100644 --- a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.es.tr +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.es.tr @@ -1,8 +1,8 @@ # textdomain: mcl_furnaces Furnace=Horno -Furnaces cook or smelt several items, using a furnace fuel, into something else.=Los hornos cocinan u funden varios elementos, utilizando un combustible de horno, en otra cosa. +Furnaces cook or smelt several items, using a furnace fuel, into something else.=Los hornos cocinan o funden varios elementos, utilizando un combustible de horno, en otra cosa. 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 el horno para abrir el menú del horno. Coloque un combustible de horno en la ranura inferior y el material de origen en la ranura superior. El horno usará lentamente su combustible para fundir el artículo. El resultado se colocará en la ranura de salida en el lado derecho. -Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Use el libro de recetas para ver qué puede crear, qué puede usar como combustible y durante cuánto tiempo se quemará. +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Use el libro de recetas para ver qué puede crear, qué puede usar como combustible y durante cuánto tiempo arderá. Burning Furnace=Horno ardiente Recipe book=Libro de recetas Inventory=Inventario diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.fr.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.fr.tr index deec7981c..4db2fc103 100644 --- a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.fr.tr +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.fr.tr @@ -1,7 +1,10 @@ # textdomain: mcl_furnaces Furnace=Four Furnaces cook or smelt several items, using a furnace fuel, into something else.=Les fours cuisent ou fondent plusieurs articles, en utilisant un combustible de four, dans quelque chose d'autre. -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.=Utilisez le four pour ouvrir le menu du four. Placez un combustible de four dans la fente inférieure et le matériau source dans la fente supérieure. Le four utilisera lentement son combustible pour fondre l'article. Le résultat sera placé dans la fente de sortie du côté droit. +Use the furnace to open the furnace menu.=Utilisez le four pour ouvrir le menu du four. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Placez un combustible de four dans la fente inférieure et le matériau source dans la fente supérieure. +The furnace will slowly use its fuel to smelt the item.=Le four utilisera lentement son combustible pour fondre l'article. +The result will be placed into the output slot at the right side.=Le résultat sera placé dans la fente de sortie du côté droit. Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Utilisez le livre de recettes pour voir ce que vous pouvez cuire, ce que vous pouvez utiliser comme carburant et combien de temps il brûlera. Burning Furnace=Four Allumé Recipe book=Livre de Recette diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr new file mode 100644 index 000000000..950419915 --- /dev/null +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.ja.tr @@ -0,0 +1,9 @@ +# 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.=レシピ本を使って、何を製錬できるか、何を燃料にできるか、どれくらい燃えるかを確認しましょう。 +Burning Furnace=燻製器 燃焼中 +Recipe book=レシピ本 +Inventory=インベントリ +Uses fuel to smelt or cook items=燃料を使ってアイテムを精錬・調理 diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pl.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pl.tr new file mode 100644 index 000000000..a957155ad --- /dev/null +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.pl.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_furnaces +Furnace=Piec +Furnaces cook or smelt several items, using a furnace fuel, into something else.=Piece mogą gotować lub przetapiać niektóre przedmioty, przy użyciu paliwa, w inne przedmioty. +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.=Kliknij w piec aby otworzyć jego menu. Połóż paliwo w dolnym miejscu a materiał źródłowy w górnym. Piec będzie powoli zużywał paliwo aby przetopić przedmiot. Rezultat pojawi się w miejscu po prawej. +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Użyj książki receptur aby dowiedzieć się co możesz przetopić, co możesz użyć jako paliwa i na jak długo wystarczy. +Burning Furnace=Palący się piec +Recipe book=Książka receptur +Inventory=Ekwipunek +Uses fuel to smelt or cook items=Zużywa paliwo aby ugotować lub stopić przedmioty diff --git a/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.zh_TW.tr b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.zh_TW.tr new file mode 100644 index 000000000..447fb835c --- /dev/null +++ b/mods/ITEMS/mcl_furnaces/locale/mcl_furnaces.zh_TW.tr @@ -0,0 +1,9 @@ +# 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.=使用合成教學來查看您可以冶煉的東西,可以用作燃料的物品以及可燃燒時間。 +Burning Furnace=燃燒的熔爐 +Recipe book=合成教學 +Inventory=物品欄 +Uses fuel to smelt or cook items=使用燃料來熔煉或烹飪物品 diff --git a/mods/ITEMS/mcl_furnaces/locale/template.txt b/mods/ITEMS/mcl_furnaces/locale/template.txt index 4f88824b0..e19259437 100644 --- a/mods/ITEMS/mcl_furnaces/locale/template.txt +++ b/mods/ITEMS/mcl_furnaces/locale/template.txt @@ -1,7 +1,10 @@ # 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 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= diff --git a/mods/ITEMS/mcl_furnaces/mod.conf b/mods/ITEMS/mcl_furnaces/mod.conf index 32f1ed8e8..fe0b9c208 100644 --- a/mods/ITEMS/mcl_furnaces/mod.conf +++ b/mods/ITEMS/mcl_furnaces/mod.conf @@ -1 +1,3 @@ name = mcl_furnaces +depends = mcl_init, mcl_formspec, mcl_core, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_bottom.png b/mods/ITEMS/mcl_furnaces/textures/default_furnace_bottom.png deleted file mode 100644 index 7844072d5..000000000 Binary files a/mods/ITEMS/mcl_furnaces/textures/default_furnace_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_front_active.png b/mods/ITEMS/mcl_furnaces/textures/default_furnace_front_active.png deleted file mode 100644 index c425604d2..000000000 Binary files a/mods/ITEMS/mcl_furnaces/textures/default_furnace_front_active.png and /dev/null differ diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_side.png b/mods/ITEMS/mcl_furnaces/textures/default_furnace_side.png deleted file mode 100644 index c154414b1..000000000 Binary files a/mods/ITEMS/mcl_furnaces/textures/default_furnace_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_top.png b/mods/ITEMS/mcl_furnaces/textures/default_furnace_top.png deleted file mode 100644 index 7844072d5..000000000 Binary files a/mods/ITEMS/mcl_furnaces/textures/default_furnace_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_grindstone/init.lua b/mods/ITEMS/mcl_grindstone/init.lua new file mode 100644 index 000000000..00c373536 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/init.lua @@ -0,0 +1,343 @@ +-- Code based from mcl_anvils + +local S = minetest.get_translator(minetest.get_current_modname()) + +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 + +-- 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) + end + local new_meta = new_item:get_meta() + new_meta:set_string("name", meta:get_string("name")) + tt.reload_itemstack_description(new_item) + return new_item +end + +-- If an item has an enchanment then remove "_enchanted" from the name +local function remove_enchant_name(stack) + if mcl_enchanting.is_enchanted(stack:get_name()) then + local name = stack:get_name() + return name.sub(name, 1, -11) + else + return stack:get_name() + end +end + +-- If an input has a curse transfer it to the new item +local function transfer_curse(old_itemstack, new_itemstack) + local enchants = mcl_enchanting.get_enchantments(old_itemstack) + for enchant, level in pairs(enchants) do + if mcl_enchanting.enchantments[enchant].curse == true then + new_itemstack = mcl_enchanting.enchant(new_itemstack, enchant, level) + end + end + return new_itemstack +end + +-- Depending on an enchantment level and isn't a curse multiply xp given +local function calculate_xp(stack) + local xp = 0 + local enchants = mcl_enchanting.get_enchantments(stack) + for enchant, level in pairs(enchants) do + if level > 0 and mcl_enchanting.enchantments[enchant].curse == false then + -- Add a bit of uniform randomisation + xp = xp + math.random(7, 13) * level + end + end + return xp +end + +-- Helper function to make sure update_grindstone_slots NEVER overstacks the output slot +local function fix_stack_size(stack) + if not stack or stack == "" then return "" end + local count = stack:get_count() + local max_count = stack:get_stack_max() + + if count > max_count then + stack:set_count(max_count) + count = max_count + end + return count +end + + +-- Update the inventory slots of an grindstone node. +-- meta: Metadata of grindstone node +local function update_grindstone_slots(meta) + local inv = meta:get_inventory() + local input1 = inv:get_stack("input", 1) + local input2 = inv:get_stack("input", 2) + local meta = input1:get_meta() + + local new_output + + -- Both input slots are occupied + if (not input1:is_empty() and not input2:is_empty()) then + 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) + + -- Calculate repair + local function calculate_repair(dur1, dur2) + -- Grindstone gives a 5% bonus to durability + local new_durability = (MAX_WEAR - dur1) + (MAX_WEAR - dur2) * 1.05 + return math.max(0, math.min(MAX_WEAR, MAX_WEAR - new_durability)) + end + + -- Check if both are tools and have the same tool type + if def1.type == "tool" and def2.type == "tool" and name1 == name2 then + local new_wear = calculate_repair(input1:get_wear(), input2:get_wear()) + local new_item = create_new_item(name1, meta, new_wear) + -- Transfer curses if both items have any + new_output = transfer_curse(input1, new_item) + new_output = transfer_curse(input2, new_output) + else + new_output = "" + end + -- 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 wear = input1:get_wear() + local new_item = create_new_item(name, meta, wear) + new_output = transfer_curse(input1, new_item) + elseif input1:get_name() == "mcl_enchanting:book_enchanted" then + new_item = create_new_item("mcl_books:book", meta, nil) + new_output = transfer_curse(input1, new_item) + else + new_output = "" + end + else + 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 wear = input2:get_wear() + local new_item = create_new_item(name, meta, wear) + new_output = transfer_curse(input2, new_item) + elseif input2:get_name() == "mcl_enchanting:book_enchanted" then + new_item = create_new_item("mcl_books:book", meta, nil) + new_output = transfer_curse(input2, new_item) + else + new_output = "" + end + end + else + new_output = "" + end + + -- Set the new output slot + if new_output then + fix_stack_size(new_output) + inv:set_stack("output", 1, new_output) + end +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 + 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} + minetest.add_item(p, stack) + end + end +end + +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}, + } +} + +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."), + tiles = { + "grindstone_top.png", + "grindstone_top.png", + "grindstone_side.png", + "grindstone_side.png", + "grindstone_front.png", + "grindstone_front.png" + }, + drawtype = "nodebox", + paramtype2 = "facedir", + node_box = node_box, + selection_box = node_box, + collision_box = node_box, + sounds = mcl_sounds.node_sound_stone_defaults(), + groups = {pickaxey = 1, deco_block = 1}, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() + meta:from_table(oldmetadata) + drop_grindstone_items(pos, meta) + meta:from_table(meta2) + end, + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + elseif listname == "output" then + return 0 + else + return stack:get_count() + end + end, + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + elseif to_list == "output" then + return 0 + elseif from_list == "output" and to_list == "input" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if inv:get_stack(to_list, to_index):is_empty() then + return count + else + return 0 + end + else + return count + end + end, + on_metadata_inventory_put = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + update_grindstone_slots(meta) + end, + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + 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 + if i ~= to_index then + local istack = inv:get_stack("input", i) + istack:set_count(math.max(0, istack:get_count() - count)) + inv:set_stack("input", i, istack) + end + end + end + update_grindstone_slots(meta) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + if listname == "output" then + local xp_earnt = 0 + local inv = meta:get_inventory() + local input1 = inv:get_stack("input", 1) + local input2 = inv:get_stack("input", 2) + -- Both slots occupied? + 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() + inv:set_stack("input", 1, input1) + inv:set_stack("input", 2, input2) + else + -- If only one input item + if not input1:is_empty() then + xp_earnt = calculate_xp(input1) + input1:set_count(math.max(0, input1:get_count() - stack:get_count())) + inv:set_stack("input", 1, input1) + end + if not input2:is_empty() then + xp_earnt = calculate_xp(input2) + input2:set_count(math.max(0, input2:get_count() - stack:get_count())) + inv:set_stack("input", 2, input2) + end + end + -- Give the player xp + if mcl_experience.throw_xp and xp_earnt > 0 then + mcl_experience.throw_xp(pos, xp_earnt) + end + elseif listname == "input" then + update_grindstone_slots(meta) + end + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + 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) + 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()) + end + end, + _mcl_blast_resistance = 6, + _mcl_hardness = 2 +}) + +minetest.register_craft({ + output = "mcl_grindstone:grindstone", + recipe = { + { "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.fr.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.fr.tr new file mode 100644 index 000000000..338bae06a --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.fr.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_grindstone +Inventory=Inventaire +Repair & Disenchant=Répare & Désenchante +Grindstone=Meule +Used to disenchant/fix tools=Utilisée pour désenchanter/réparer +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.=Les meules désenchantent les outils et armures sauf si elles sont maudites, et répare deux objets du même type, c'est aussi le poste de travail du forgeron d'armes. +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=Pour utiliser la meule, cliquer droit, deux emplacements d'entrée (à gauche) et un seul emplacement de sortie. +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=Pour désenchanter un objet, placer un objet enchanté à l'entrée et récupérer l'objet désenchanté à la sortie. +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.=Pour réparer un outil vous avez besoin d'un outil du même type et matériau, placer deux objets à l'entrée et à la sortie leurs durabilités seront combinées avec un bonus de 5%. +If both items have enchantments the player will get xp from both items from the disenchant.=Si les deux objets ont des enchantements le joueur aura de l'expérience à partir des deux objets à désenchanter. +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.=Les malédictions ne peuvent pas être retirées et sont transférées à l'objet réparé, si les deux objets ont des malédictions différentes elles sont combinées. \ No newline at end of file diff --git a/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.tr b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.tr new file mode 100644 index 000000000..c0bd0a4d4 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/mcl_grindstone.ja.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.=砥石は、ツールやアーマーからエンチャントを解除(呪い以外)したり、同種の2つのアイテムで修理したりできます。これは、武器鍛冶の職場でもあります。 +To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=砥石を使うには、右クリックします。 入力スロットが2つ(左側)、出力スロットが1つです。 +To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=エンチャントを解除するには、エンチャントされたアイテムを入力スロットの1つに置き、出力から解除されたアイテムを取り出します。 +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.=道具を修理するには、同種・同素材の道具が必要です。両方のアイテムを入力スロットに入れると、出力スロットは2つのアイテムの耐久値に5%のボーナスを加えて結合します。 +If both items have enchantments the player will get xp from both items from the disenchant.=両方のアイテムにエンチャントがかかっている場合、プレイヤーは両方からエンチャント解除による経験値を得られます。 +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_grindstone/locale/template.txt b/mods/ITEMS/mcl_grindstone/locale/template.txt new file mode 100644 index 000000000..8cce10880 --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/locale/template.txt @@ -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.= +If both items have enchantments the player will get xp from both items from the disenchant.= +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_grindstone/mod.conf b/mods/ITEMS/mcl_grindstone/mod.conf new file mode 100644 index 000000000..66773c57f --- /dev/null +++ b/mods/ITEMS/mcl_grindstone/mod.conf @@ -0,0 +1,4 @@ +name = mcl_grindstone +author = TheRandomLegoBrick, ChrisPHP +depends = mcl_experience, mcl_sounds +description = Add block that disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station. diff --git a/mods/ITEMS/mcl_hamburger/init.lua b/mods/ITEMS/mcl_hamburger/init.lua new file mode 100644 index 000000000..7fbf41d31 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/init.lua @@ -0,0 +1,150 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 11/19/22 7:13 AM +--- + +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 10/23/22 4:50 AM +--- +-- LOCALIZATION + +local S = minetest.get_translator("mcl_hamburger") + +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local table = table +local DEBUG = false + +local enable_burger = minetest.settings:get_bool("mcl_enable_hamburger",true) +local use_alt = minetest.settings:get_bool("mcl_hamburger_alt_texture",false) + +local HAMBURGER_NAME = "mcl_hamburger:hamburger" + +mcl_hamburger = {} + +if DEBUG then + minetest.log("MCL_Hamburger::START.") +end + +-- call to register your hamburger. +function mcl_hamburger.register_burger_craft(cooked_meat) + minetest.register_craft({ + type = "fuel", + recipe = HAMBURGER_NAME, + burntime = 2, + }) + + minetest.register_craft({ + output = HAMBURGER_NAME, + recipe = { + { "mcl_farming:bread"}, + { cooked_meat }, -- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac. + { "mcl_farming:bread" }, + }, + }) + minetest.register_craft({ + output = HAMBURGER_NAME, + recipe = { + -- "mcl_mobitems:cooked_beef" for a reg hamburger. Grind up clowns for a Big Mac. + { "mcl_farming:bread", cooked_meat, "mcl_farming:bread"}, + }, + }) + +end + +local hamburger_def = { + description = S("A Hamburger"), + _doc_items_longdesc = S("A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten."), + _doc_items_usagehelp = S("Wield this item to pull villagers to you."), + _tt_help = S("A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy."), + inventory_image = "mcl_hamburger.png", + wield_image = "mcl_hamburger.png", + on_place = minetest.item_eat(8), + on_secondary_use = minetest.item_eat(8), + groups = { food = 2, eatable = 8 }, + _mcl_saturation = 13.8, +} + +if not enable_burger then + hamburger_def.groups.not_in_creative_inventory = 1 +end + +if use_alt == false then + minetest.register_craftitem(HAMBURGER_NAME, hamburger_def) +else + local hamburger_alt = table.copy(hamburger_def) + hamburger_alt.inventory_image = "mcl_hamburger_alt.png" + hamburger_alt.wield_image = "mcl_hamburger_alt.png" + minetest.register_craftitem(HAMBURGER_NAME, hamburger_alt) +end + +local function register_achievements() + + awards.register_achievement(HAMBURGER_NAME, { + title = S("Burger Time!"), + description = S("Craft a Hamburger."), + icon = "mcl_hamburger_alt.png", + trigger = { + type = "craft", + item = HAMBURGER_NAME, + target = 1 + }, + type = "Advancement", + group = "Overworld", + }) + +end + +local function register_doc_entry() + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("craftitems", HAMBURGER_NAME, "craftitems", HAMBURGER_NAME) + end + +end + +if enable_burger then + -- make the villagers follow the item + local villager = minetest.registered_entities["mobs_mc:villager"] + + table.insert(villager.follow, HAMBURGER_NAME) + + local original_rightclick = villager.on_rightclick + + local new_on_rightclick = function(self, clicker) + --minetest.log("In wrapper function") + + local item = clicker:get_wielded_item() + if item:get_name() == HAMBURGER_NAME then + if self.nofollow == true then + --minetest.log("Turn off nofollow") + self.nofollow = false + elseif self.nofollow == false then + --minetest.log("Turn on nofollow") + self.nofollow = true + end + else + --minetest.log("Not holding burger") + if self.nofollow == false then + --minetest.log("Turn on nofollow") + self.nofollow = true + end + original_rightclick(self, clicker) + end + --minetest.log("Finishing wrapper") + end + + villager.on_rightclick = new_on_rightclick + + mcl_hamburger.register_burger_craft("mcl_mobitems:cooked_beef") + minetest.register_alias("hamburger", HAMBURGER_NAME) + + register_achievements() + register_doc_entry() +end + diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr new file mode 100644 index 000000000..8d375dbd5 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.de.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Ein Hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Ein leckerer Hamburger, der die Dorfbewohner sicher wie eine Leine anlocken wird. Kann gegessen werden. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Ein leckerer Hamburger, der die Dorfbewohner anlocken wird. "Ich bezahle dir gerne den Dienstag, für heute einen Hamburger." - Wimpy. + +Burger Time!=Burgerzeit! +Craft a Hamburger.=Stelle einen Hamburger her. +Wield this item to pull villagers to you.=Benutze diesen Gegenstand, um Dorfbewohner zu dir zu ziehen. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr new file mode 100644 index 000000000..ad10560e4 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.es.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Una hamburguesa + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Una sabrosa hamburguesa que seguramente atraerá a los aldeanos como una pista. Se puede comer. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Una sabrosa hamburguesa que seguramente atraerá a los aldeanos. 'Con gusto te pago el martes, por una hamburguesa hoy.' - Wimpy. + +Burger Time!=¡Tiempo de hamburguesas! +Craft a Hamburger.=Elabora una hamburguesa. +Wield this item to pull villagers to you.=Utiliza este objeto para atraer a los aldeanos hacia ti. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr new file mode 100644 index 000000000..1463a69ad --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.fr.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Un hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Un hamburger savoureux qui ne manquera pas d'attirer les villageois comme une piste. Peut être mangé. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Un hamburger savoureux qui ne manquera pas d'attirer les villageois. «Je vous paierai volontiers mardi, pour un hamburger aujourd'hui.» - Wimpy. + +Burger Time!=L'heure des burgers! +Craft a Hamburger.=Fabriquez un hamburger. +Wield this item to pull villagers to you.=Maniez cet objet pour attirer les villageois vers vous. \ No newline at end of file diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr new file mode 100644 index 000000000..7cd12d735 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ja.tr @@ -0,0 +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. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=村人たちを魅了する美味しいハンバーガーです。「今日のハンバーガー代、喜んで払いますよ、火曜日に」。- へたれ(WIMPY)。 + +Burger Time!=バーガータイム! +Craft a Hamburger.=ハンバーガーをクラフトします。 +Wield this item to pull villagers to you.=このアイテムを手に持つと、村人を引き寄せられます。 diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr new file mode 100644 index 000000000..09569a2ba --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_hamburger +A Hamburger=Hamburger + +A tasty hamburger that is sure to lure villagers around like a lead. Can be eaten.=Smaczny hamburger, który zwabi wieśniaków jak trop. Można jeść. + +A tasty hamburger that is sure to lure villagers. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Smaczny hamburger, który z pewnością zwabi wieśniaków. - Chętnie zapłacę we wtorek za hamburgera dzisiaj. - Mięczak (Wimpy). + +Burger Time!=Czas na burgery! +Craft a Hamburger.=Stwórz hamburgera. +Wield this item to pull villagers to you.=Chwyć ten przedmiot, aby przyciągnąć wieśniaków do siebie. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr new file mode 100644 index 000000000..736f182a5 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.ru.tr @@ -0,0 +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. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=Вкусный гамбургер, который обязательно привлечет жителей деревни. — Я с радостью заплачу тебе во вторник за гамбургер сегодня. - Вимпи. + +Burger Time!=Время бургеров! +Craft a Hamburger.=Изготовить гамбургер. +Wield this item to pull villagers to you.=Используйте этот предмет, чтобы притягивать к себе жителей деревни. diff --git a/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr new file mode 100644 index 000000000..46f30c88e --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/mcl_hamburger.zh_TW.tr @@ -0,0 +1,16 @@ +# 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. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.=一個美味的漢堡包,一定會吸引村民。 “我很樂意在星期二付錢給你,今天就買一個漢堡包。” - 懦弱。 +Burger Time!=漢堡時間! +Craft a Hamburger.=製作一個漢堡包。 +Wield this item to pull villagers to you.=使用此物品將村民拉到你身邊。 + + + + + + + + + diff --git a/mods/ITEMS/mcl_hamburger/locale/template.txt b/mods/ITEMS/mcl_hamburger/locale/template.txt new file mode 100644 index 000000000..850ff62b0 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/locale/template.txt @@ -0,0 +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. 'I'll gladly pay you Tuesday, for a hamburger today.' - Wimpy.= + +Burger Time!= +Craft a Hamburger.= +Wield this item to pull villagers to you.= diff --git a/mods/ITEMS/mcl_hamburger/mod.conf b/mods/ITEMS/mcl_hamburger/mod.conf new file mode 100644 index 000000000..f5baca506 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/mod.conf @@ -0,0 +1,5 @@ +name = mcl_hamburger +author = Michieal +description = A cute (and easy to use) replacement for not having leashes in MC2 +depends = mcl_core, mcl_sounds, mobs_mc, mcl_mobitems, awards +optional_depends = doc diff --git a/mods/ITEMS/mcl_hamburger/readme.txt b/mods/ITEMS/mcl_hamburger/readme.txt new file mode 100644 index 000000000..e479c01b9 --- /dev/null +++ b/mods/ITEMS/mcl_hamburger/readme.txt @@ -0,0 +1,43 @@ +Tags: Hamburger +Icon set: Fugue 16px Additional Icons +Author: Yusuke Kamiyamane +License: CC Attribution 3.0 Unported +Readme file +Commercial usage: Allowed +Posted: November 22, 2011 +Icon Readme file: + +Fugue Icons + +(C) 2011 Yusuke Kamiyamane. All rights reserved. +These icons are licensed under a Creative Commons +Attribution 3.0 License. + + +If you can't or don't want to provide attribution, please +purchase a royalty-free license. + + +I'm unavailable for custom icon design work. But your +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 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 +Bally Midway. + +Information about the BurgerTime Arcade Game: + +From https://thepinballgameroom.com/product/burgertime-arcade-machine/ on the original game: +BurgerTime Arcade Machine, originally released as Hamburger in Japan, is a 1982 arcade game developed by Data East +initially for its DECO Cassette System. In the United States, Data East USA licensed BurgerTime Arcade Machine for +distribution by Bally Midway as a standard dedicated arcade game. Data East also released its own version of BurgerTime +in the United States through its DECO Cassette System. The Data East and Midway versions are distinguished by the +manufacturer’s name on the title screen and by the marquee and cabinet artworks, as the game itself is identical. diff --git a/mods/ITEMS/mcl_heads/depends.txt b/mods/ITEMS/mcl_heads/depends.txt deleted file mode 100644 index 01846722d..000000000 --- a/mods/ITEMS/mcl_heads/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_sounds -mcl_armor? -screwdriver? -doc? diff --git a/mods/ITEMS/mcl_heads/description.txt b/mods/ITEMS/mcl_heads/description.txt deleted file mode 100644 index b169ba796..000000000 --- a/mods/ITEMS/mcl_heads/description.txt +++ /dev/null @@ -1 +0,0 @@ -Small decorative head blocks. diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index a8e9f2cb5..69c26b97d 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -1,164 +1,297 @@ -local S = minetest.get_translator("mcl_heads") +local S = minetest.get_translator(minetest.get_current_modname()) +local minetest = minetest local mod_doc = minetest.get_modpath("doc") local mod_screwdriver = minetest.get_modpath("screwdriver") local equip_armor if minetest.get_modpath("mcl_armor") then - equip_armor = armor.on_armor_use + equip_armor = mcl_armor.equip_on_use end --- Heads system +mcl_heads = {} -local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) - local on_rotate_floor, on_rotate_wall - if mod_screwdriver then - on_rotate_floor = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = node.name .. "_wall" - node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end - end - on_rotate_wall = function(pos, node, user, mode, new_param2) - if mode == screwdriver.ROTATE_AXIS then - node.name = string.sub(node.name, 1, string.len(node.name)-5) - node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) - minetest.set_node(pos, node) - return true - end +-- rotations of head nodes within a quadrant (0° ≤ θ ≤ 90°) +mcl_heads.FLOOR_DEGREES = { [0]='', '22_5', '45', '67_5', } + +-- box of head nodes +mcl_heads.FLOOR_BOX = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, } + +-- floor head node nodedef template ------------------------------------------------------------------------------------ + +--- node definition template for floor mod heads +mcl_heads.deftemplate_floor = { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + armor = 1, + armor_head = 1, + non_combat_armor = 1, + non_combat_armor_head = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _mcl_armor_element = "head", + _mcl_blast_resistance = 1, + _mcl_hardness = 1, + + on_secondary_use = equip_armor, +} + +mcl_heads.deftemplate_floor_angled = { + drawtype = "mesh", + selection_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + collision_box = { + type = "fixed", + fixed = mcl_heads.FLOOR_BOX, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "facedir", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + +function mcl_heads.deftemplate_floor.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = node.name .. "_wall" + node.param2 = minetest.dir_to_wallmounted(minetest.facedir_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +function mcl_heads.deftemplate_floor.on_place(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Allow pointed node's on_rightclick callback to override place. + 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(under, node, placer, itemstack) or itemstack end end - minetest.register_node("mcl_heads:"..name, { - description = desc, - _doc_items_longdesc = longdesc, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "fixed", - fixed = { - { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - }, - groups = {handy=1, armor_head=1,non_combat_armor=1, head=1, deco_block=1, dig_by_piston=1 }, + local above = pointed_thing.above + local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} + local wdir = minetest.dir_to_wallmounted(dir) + + local itemstring = itemstack:get_name() + local placestack = ItemStack(itemstack) + + -- place wall head node (elsewhere) + if wdir ~= 0 and wdir ~= 1 then + placestack:set_name(itemstring .."_wall") + itemstack = minetest.item_place(placestack, placer, pointed_thing, wdir) + + -- place floor head node (floor and ceiling) + else + local fdir = minetest.dir_to_facedir(dir) + + -- determine the head node rotation based on player's yaw (in cw direction from North/Z+) + local yaw = placer:get_look_horizontal() + yaw = wdir == 1 and math.pi*2 - yaw or yaw + + local rotation_level = math.min(math.max(math.round((yaw / (math.pi*2)) * 16), 0), 15) + placestack:set_name(itemstring ..mcl_heads.FLOOR_DEGREES[rotation_level % 4]) + + -- determine the head node face direction based on rotation level + fdir = math.floor(rotation_level / 4) + (wdir == 1 and 0 or 20) + + itemstack = minetest.item_place(placestack, placer, pointed_thing, fdir) + end + + -- restore item from angled and wall head nodes + itemstack:set_name(itemstring) + return itemstack +end + +-- wall head node nodedef template ------------------------------------------------------------------------------------- + +--- node definition template for wall mod heads +mcl_heads.deftemplate_wall = { + drawtype = "nodebox", + node_box = { + type = "wallmounted", + wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, + wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, + wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, + }, + groups = { + handy = 1, + head = 1, + deco_block = 1, + dig_by_piston = 1, + not_in_creative_inventory = 1, + }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype = "light", + paramtype2 = "wallmounted", + stack_max = 64, + sunlight_propagates = true, + sounds = mcl_sounds.node_sound_defaults{ + footstep = {name="default_hard_footstep", gain=0.3}, + }, + is_ground_content = false, + + _doc_items_create_entry = false, + _mcl_blast_resistance = 1, + _mcl_hardness = 1, +} + +function mcl_heads.deftemplate_wall.on_rotate(pos, node, user, mode, new_param2) + if mode == screwdriver.ROTATE_AXIS then + node.name = string.sub(node.name, 1, string.len(node.name)-5) + node.param2 = minetest.dir_to_facedir(minetest.wallmounted_to_dir(node.param2)) + minetest.set_node(pos, node) + return true + end +end + +-- API functions ------------------------------------------------------------------------------------------------------- + +--- @class HeadDef +--- @field name string identifier for node +--- @field texture string armor texture for node +--- @field description string translated description +--- @field longdesc string translated doc description +--- @field range_mob string name of mob affected by range reduction +--- @field range_factor number factor of range reduction + +--- registers a head +--- @param head_def HeadDef head node definition +function mcl_heads.register_head(head_def) + local name = "mcl_heads:" ..head_def.name + + -- register the floor head node + minetest.register_node(name, table.update(table.copy(mcl_heads.deftemplate_floor), { + description = head_def.description, + _doc_items_longdesc = head_def.longdesc, + -- The head textures are based off the textures of an actual mob. tiles = { -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. -- This is required for skeleton skull and wither skeleton skull. - "[combine:16x16:-4,4="..texture, -- top - "([combine:16x16:-4,4="..texture..")^([combine:16x16:-12,4="..texture..")", -- bottom - "[combine:16x16:-12,0="..texture, -- left - "[combine:16x16:4,0="..texture, -- right - "[combine:16x16:-20,0="..texture, -- back - "[combine:16x16:-4,0="..texture, -- front + -- Note: -x coords go right per-pixel, -y coords go down per-pixel + "[combine:16x16:-36,4=" ..head_def.texture, -- top + "([combine:16x16:-36,4=" ..head_def.texture..")^([combine:16x16:-44,4="..head_def.texture..")", -- bottom + "[combine:16x16:-28,0=" ..head_def.texture, -- left + "[combine:16x16:-44,0=" ..head_def.texture, -- right + "[combine:16x16:-52,0=" ..head_def.texture, -- back + "[combine:16x16:-36,0=" ..head_def.texture, -- front }, - paramtype = "light", - stack_max = 64, - paramtype2 = "facedir", - sunlight_propagates = true, - walkable = true, - selection_box = { - type = "fixed", - fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - }, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end + _mcl_armor_mob_range_mob = head_def.range_mob, + _mcl_armor_mob_range_factor = head_def.range_factor, + _mcl_armor_texture = head_def.texture + })) - -- Call on_rightclick if the pointed node defines it - 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(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local diff = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z} - local wdir = minetest.dir_to_wallmounted(diff) - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - local idef = fakestack:get_definition() - local retval - if wdir == 0 or wdir == 1 then - return minetest.item_place(itemstack, placer, pointed_thing) - else - retval = fakestack:set_name("mcl_heads:"..name.."_wall") - end - if not retval then - return itemstack - end - - local success - itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - return itemstack - end, - on_secondary_use = equip_armor, - - on_rotate = on_rotate_floor, - - _mcl_armor_mob_range_mob = rangemob, - _mcl_armor_mob_range_factor = rangefactor, - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - minetest.register_node("mcl_heads:"..name.."_wall", { - _doc_items_create_entry = false, - drawtype = "nodebox", - is_ground_content = false, - node_box = { - type = "wallmounted", - wall_bottom = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, - wall_top = { -0.25, 0.0, -0.25, 0.25, 0.5, 0.25, }, - wall_side = { -0.5, -0.25, -0.25, 0.0, 0.25, 0.25, }, - }, - groups = {handy=1, head=1, deco_block=1, dig_by_piston=1, not_in_creative_inventory=1}, - -- The head textures are based off the textures of an actual mob. - tiles = { - { name = "[combine:16x16:-4,-4="..texture, align_style = "world" }, -- front - { name = "[combine:16x16:-20,-4="..texture, align_style = "world" }, -- back - { name = "[combine:16x16:-8,-4="..texture, align_style = "world" }, -- left - { name = "[combine:16x16:0,-4="..texture, align_style = "world" }, -- right - { name = "([combine:16x16:-4,0="..texture..")^[transformR180", align_style = "node" }, -- top - { name = "([combine:16x16:-4,8="..texture..")^([combine:16x16:-12,8="..texture..")", align_style = "node" }, -- bottom - }, - paramtype = "light", - stack_max = 64, - paramtype2 = "wallmounted", - sunlight_propagates = true, - walkable = true, - sounds = mcl_sounds.node_sound_defaults({ - footstep = {name="default_hard_footstep", gain=0.3} - }), - drop = "mcl_heads:"..name, - on_rotate = on_rotate_wall, - _mcl_blast_resistance = 1, - _mcl_hardness = 1, - }) - - if mod_doc then - doc.add_entry_alias("nodes", "mcl_heads:" .. name, "nodes", "mcl_heads:" .. name .. "_wall") + -- register the angled floor head nodes + for i, d in ipairs(mcl_heads.FLOOR_DEGREES) do + minetest.register_node(name ..d, table.update(table.copy(mcl_heads.deftemplate_floor_angled), { + mesh = "mcl_heads_floor" ..d ..".obj", + tiles = { head_def.texture }, + drop = name, + })) end + + -- register the wall head node + minetest.register_node(name .."_wall", table.update(table.copy(mcl_heads.deftemplate_wall), { + -- The head textures are based off the textures of an actual mob. + -- Note: -x coords go right per-pixel, -y coords go down per-pixel + tiles = { + { name = "[combine:16x16:-36,-4=" ..head_def.texture, align_style = "world" }, -- front + { name = "[combine:16x16:-52,-4="..head_def.texture, align_style = "world" }, -- back + { name = "[combine:16x16:-40,-4=" ..head_def.texture, align_style = "world" }, -- right + { name = "[combine:16x16:-32,-4=" ..head_def.texture, align_style = "world" }, -- left + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^[transformR180", align_style = "node" }, -- top + -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. + -- This is required for skeleton skull and wither skeleton skull. + { name = "([combine:16x16:-36,0=" ..head_def.texture ..")^([combine:16x16:-44,8=" ..head_def.texture..")", align_style = "node" }, -- bottom + }, + drop = name, + })) end --- Add heads -addhead("zombie", "mcl_heads_zombie_node.png", S("Zombie Head"), S("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%."), "mobs_mc:zombie", 0.5) -addhead("creeper", "mcl_heads_creeper_node.png", S("Creeper Head"), 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%."), "mobs_mc:creeper", 0.5) +-- initial heads ------------------------------------------------------------------------------------------------------- + +mcl_heads.register_head{ + name = "zombie", + texture = "mcl_heads_zombie.png", + description = S("Zombie Head"), + longdesc = S("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%."), + range_mob = "mobs_mc:zombie", + range_factor = 0.5, +} + +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", + range_factor = 0.5, +} + -- Original Minecraft name: “Head” -addhead("steve", "mcl_heads_steve_node.png", S("Human Head"), S("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.")) -addhead("skeleton", "mcl_heads_skeleton_node.png", S("Skeleton Skull"), S("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%."), "mobs_mc:skeleton", 0.5) -addhead("wither_skeleton", "mcl_heads_wither_skeleton_node.png", S("Wither Skeleton Skull"), S("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.")) +mcl_heads.register_head{ + name = "steve", + texture = "mcl_heads_steve.png", + description = S("Human Head"), + longdesc = S("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."), +} + +mcl_heads.register_head{ + name = "skeleton", + texture = "mcl_heads_skeleton.png", + description = S("Skeleton Skull"), + longdesc = S("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%."), + range_mob = "mobs_mc:skeleton", + range_factor = 0.5, +} + +mcl_heads.register_head{ + name = "wither_skeleton", + texture = "mcl_heads_wither_skeleton.png", + description = S("Wither Skeleton Skull"), + longdesc = S("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/mcl_heads.ja.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.ja.tr new file mode 100644 index 000000000..b3ced046c --- /dev/null +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.ja.tr @@ -0,0 +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.=人の頭は、人間(=プレイヤーキャラ)の頭部を模した小さな装飾ブロックです。遊びでヘルメットとして装着することもできますが、保護機能はありません。 +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.=ウィザースケルトンスカルは、ウィザースケルトンの頭蓋骨を模した小さな装飾ブロックです。ヘルメットとして楽しむこともできますが、保護機能はありません。 diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr new file mode 100644 index 000000000..4ed4bbbee --- /dev/null +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.pl.tr @@ -0,0 +1,11 @@ +# 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%. +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 +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%.=Głowa szkieleta jest małym blokiem dekoracyjnym i przypomina głowę szkieleta. Może być noszona jako hełm co zmniejsza obszar wykrycia przez szkielety o 50%. +Wither Skeleton Skull=Głowa witherowego szkieleta +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.=Głowa witherowego szkieleta jest małym blokiem dekoracyjnym i przypomina głowę witherowego szkieleta. Może być noszona jako hełm dla zabawy, ale nie zapewnia żadnej dodatkowej ochrony. diff --git a/mods/ITEMS/mcl_heads/locale/mcl_heads.zh_TW.tr b/mods/ITEMS/mcl_heads/locale/mcl_heads.zh_TW.tr new file mode 100644 index 000000000..3164d3831 --- /dev/null +++ b/mods/ITEMS/mcl_heads/locale/mcl_heads.zh_TW.tr @@ -0,0 +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.=玩家頭是一個小的裝飾塊,類似於玩家的頭部。它也可以作為頭盔戴著玩,但不提供任何保護。 +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.=凋零骷髏頭是一個小的裝飾塊,類似於凋零骷髏的頭部。它也可以作為頭盔戴著玩,但不提供任何保護。 diff --git a/mods/ITEMS/mcl_heads/mod.conf b/mods/ITEMS/mcl_heads/mod.conf index 0dab90077..e2fe34f63 100644 --- a/mods/ITEMS/mcl_heads/mod.conf +++ b/mods/ITEMS/mcl_heads/mod.conf @@ -1 +1,4 @@ name = mcl_heads +description = Small decorative head blocks. +depends = mcl_sounds +optional_depends = mcl_armor, screwdriver, doc diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj new file mode 100644 index 000000000..8e48015fc --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor22_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor22_5.mtl +o Cube.001 +v -0.326641 -0.500000 0.135299 +v -0.326641 0.000000 0.135299 +v -0.135299 -0.500000 -0.326641 +v -0.135299 0.000000 -0.326641 +v 0.135299 -0.500000 0.326641 +v 0.135299 0.000000 0.326641 +v 0.326641 -0.500000 -0.135299 +v 0.326641 0.000000 -0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 0.3827 +vn -0.3827 0.0000 0.9239 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj new file mode 100644 index 000000000..6300d4484 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor45.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor45.mtl +o Cube.002 +v -0.353553 -0.500000 0.000000 +v -0.353553 0.000000 0.000000 +v 0.000000 -0.500000 -0.353553 +v 0.000000 0.000000 -0.353553 +v 0.000000 -0.500000 0.353553 +v 0.000000 0.000000 0.353553 +v 0.353553 -0.500000 0.000000 +v 0.353553 0.000000 0.000000 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +vn -0.7071 0.0000 0.7071 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.002 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj new file mode 100644 index 000000000..0fe5567e3 --- /dev/null +++ b/mods/ITEMS/mcl_heads/models/mcl_heads_floor67_5.obj @@ -0,0 +1,42 @@ +# Blender v2.93.9 OBJ File: 'mcl_heads_floor_0.blend' +# www.blender.org +mtllib mcl_heads_floor67_5.mtl +o Cube.003 +v -0.326641 -0.500000 -0.135299 +v -0.326641 0.000000 -0.135299 +v 0.135299 -0.500000 -0.326641 +v 0.135299 0.000000 -0.326641 +v -0.135299 -0.500000 0.326641 +v -0.135299 0.000000 0.326641 +v 0.326641 -0.500000 0.135299 +v 0.326641 0.000000 0.135299 +vt 0.875000 0.500000 +vt 0.875000 0.750000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +vt 1.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vn -0.3827 0.0000 -0.9239 +vn 0.9239 0.0000 -0.3827 +vn 0.3827 0.0000 0.9239 +vn -0.9239 0.0000 0.3827 +vn 0.0000 -1.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Material.003 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +f 3/4/2 4/3/2 8/5/2 7/6/2 +f 7/6/3 8/5/3 6/7/3 5/8/3 +f 5/9/4 6/10/4 2/2/4 1/1/4 +f 3/11/5 7/12/5 5/13/5 1/14/5 +f 8/5/6 4/3/6 2/15/6 6/16/6 diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png deleted file mode 100644 index 99b432ac6..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_preview.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_preview.png deleted file mode 100644 index 120f0b53e..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png deleted file mode 100644 index 0af86cd6a..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_preview.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_preview.png deleted file mode 100644 index 70d6d5cab..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png deleted file mode 100644 index b85fb3d31..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png deleted file mode 100644 index 8bf839e71..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_preview.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_preview.png deleted file mode 100644 index 906eb5b93..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_steve_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png deleted file mode 100644 index 671f40547..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_preview.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_preview.png deleted file mode 100644 index dbc9b3629..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png deleted file mode 100644 index ef85701e8..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_node.png and /dev/null differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_preview.png b/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_preview.png deleted file mode 100644 index ff1e0b26c..000000000 Binary files a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie_preview.png and /dev/null differ diff --git a/mods/ITEMS/mcl_honey/init.lua b/mods/ITEMS/mcl_honey/init.lua new file mode 100644 index 000000000..a870e7c08 --- /dev/null +++ b/mods/ITEMS/mcl_honey/init.lua @@ -0,0 +1,182 @@ +--------------- +---- Honey ---- +--------------- +mcl_honey = {} + +-- Variables +local S = minetest.get_translator(minetest.get_current_modname()) +local alldirs = { { x = 0, y = 0, z = 1 }, { x = 1, y = 0, z = 0 }, { x = 0, y = 0, z = -1 }, { x = -1, y = 0, z = 0 }, { x = 0, y = -1, z = 0 }, { x = 0, y = 1, z = 0 } } + +-- Waxing Function +function mcl_honey.wax_block(pos, node, player, itemstack) + -- prevent modification of protected nodes. + if mcl_util.check_position_protection(pos, player) then + return + end + + local def = minetest.registered_nodes[node.name] + + if def and def._mcl_waxed_variant then + node.name = def._mcl_waxed_variant + else + return + end + + node.name = def._mcl_waxed_variant + minetest.set_node(pos, node) + awards.unlock(player:get_player_name(), "mcl:wax_on") + if not minetest.is_creative_enabled(player:get_player_name()) then + itemstack:take_item() + end + return itemstack +end + +-- Honeycomb +minetest.register_craftitem("mcl_honey:honeycomb", { + description = S("Honeycomb"), + _doc_items_longdesc = S("Used to craft beehives and protect copper blocks from further oxidation."), + _doc_items_usagehelp = S("Use on copper blocks to prevent further oxidation."), + inventory_image = "mcl_honey_honeycomb.png", + groups = { craftitem = 1 }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + local node = minetest.get_node(pointed_thing.under) + local pos = pointed_thing.under + + -- wax the block. This is the only viable usage of honeycomb's on_place. If it "fails" to wax, then nothing is changed. + return mcl_honey.wax_block(pos, node, placer, itemstack) + end, +}) + +minetest.register_node("mcl_honey:honeycomb_block", { + description = S("Honeycomb Block"), + _doc_items_longdesc = S("Honeycomb Block. Used as a decoration."), + tiles = { + "mcl_honey_honeycomb_block.png" + }, + groups = { handy = 1, deco_block = 1 }, + sounds = { + dig = { name = "slimenodes_dug", gain = 0.6, pitch = 1.2 }, + dug = { name = "slimenodes_dug", gain = 0.6 }, + place = { name = "slimenodes_place", gain = 0.6 }, + footstep = { name = "slimenodes_step", gain = 0.3 }, + }, + _mcl_blast_resistance = 0.6, + _mcl_hardness = 0.6, +}) + +-- Honey +minetest.register_craftitem("mcl_honey:honey_bottle", { + description = S("Honey Bottle"), + _doc_items_longdesc = S("Honey Bottle is used to craft honey blocks and to restore hunger points."), + _doc_items_usagehelp = S("Drinking will restore 6 hunger points. Can also be used to craft honey blocks."), + inventory_image = "mcl_honey_honey_bottle.png", + groups = { craftitem = 1, food = 3, eatable = 6, can_eat_when_full = 1 }, + on_place = minetest.item_eat(6, "mcl_potions:glass_bottle"), + on_secondary_use = minetest.item_eat(6, "mcl_potions:glass_bottle"), + _mcl_saturation = 1.2, + stack_max = 16, +}) + +minetest.register_node("mcl_honey:honey_block", { + description = S("Honey Block"), + _doc_items_longdesc = S("Honey Block. Used as a decoration and in redstone. Is sticky on some sides."), + tiles = { "mcl_honey_block_side.png" }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, + groups = { handy = 1, deco_block = 1, fall_damage_add_percent = -80 }, + sounds = { + dug = { name = "slimenodes_dug", gain = 0.6 }, + place = { name = "slimenodes_place", gain = 0.6 }, + footstep = { name = "slimenodes_step", gain = 0.3 }, + }, + paramtype = "light", + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + { -0.4, -0.4, -0.4, 0.4, 0.4, 0.4 }, + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + } + }, + selection_box = { + type = "regular", + }, + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + mvps_sticky = function(pos, node, piston_pos) + local connected = {} + for n, v in ipairs(alldirs) do + local neighbor_pos = vector.add(pos, v) + local neighbor_node = minetest.get_node(neighbor_pos) + if neighbor_node then + if neighbor_node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(neighbor_pos, neighbor_pos) + neighbor_node = minetest.get_node(neighbor_pos) + end + local name = neighbor_node.name + if name ~= "air" and name ~= "ignore" and name ~= "mcl_core:slimeblock" and not mesecon.mvps_unsticky[name] then + local piston, piston_side, piston_up, piston_down = false, false, false, false + if name == "mesecons_pistons:piston_sticky_off" or name == "mesecons_pistons:piston_normal_off" then + piston, piston_side = true, true + elseif name == "mesecons_pistons:piston_up_sticky_off" or name == "mesecons_pistons:piston_up_normal_off" then + piston, piston_up = true, true + elseif name == "mesecons_pistons:piston_down_sticky_off" or name == "mesecons_pistons:piston_down_normal_off" then + piston, piston_down = true, true + end + if not ((piston_side and (n - 1 == neighbor_node.param2)) or (piston_up and (n == 5)) or (piston_down and (n == 6))) then + if piston and piston_pos then + if piston_pos.x == neighbor_pos.x and piston_pos.y == neighbor_pos.y and piston_pos.z == neighbor_pos.z then + -- Loopback to the same piston! Preventing unwanted behavior: + return {}, true + end + end + table.insert(connected, neighbor_pos) + end + end + end + end + return connected, false + end, +}) + +-- Crafting +minetest.register_craft({ + output = "mcl_honey:honeycomb_block", + recipe = { + { "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + { "mcl_honey:honeycomb", "mcl_honey:honeycomb" }, + }, +}) + +minetest.register_craft({ + output = "mcl_honey:honey_block", + recipe = { + { "mcl_honey:honey_bottle", "mcl_honey:honey_bottle" }, + { "mcl_honey:honey_bottle", "mcl_honey:honey_bottle" }, + }, + replacements = { + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + }, +}) + +minetest.register_craft({ + output = "mcl_honey:honey_bottle 4", + recipe = { + { "mcl_potions:glass_bottle", "mcl_potions:glass_bottle", "mcl_honey:honey_block" }, + { "mcl_potions:glass_bottle", "mcl_potions:glass_bottle", "" }, + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_core:sugar 3", + recipe = { "mcl_honey:honey_bottle" }, + replacements = { + { "mcl_honey:honey_bottle", "mcl_potions:glass_bottle" }, + }, +}) diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr new file mode 100644 index 000000000..90382020a --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.es.tr @@ -0,0 +1,10 @@ +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 +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 +Honey Bottle=Botella de miel +Honey Bottle is used to craft honey blocks and to restore hunger points.=La botella de miel sirve para fabricar bloques de miel y para restaurar puntos de hambre. +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.=Beberla restaurará 6 puntos de hambre. También puede ser usada para fabricar bloques de miel +Honey Block=Bloque de miel +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.=Bloque de miel. Se utiliza como decoración y en redstone. Es pegajoso por algunos lados. diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.fr.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.fr.tr new file mode 100644 index 000000000..67ef904c9 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.fr.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_honey +Honeycomb=Cire +Used to craft beehives and protect copper blocks from further oxidation.=Utilisé pour fabriquer les ruches et protéger des blocs de l'oxydation. +Use on copper blocks to prevent further oxidation.=À utiliser sur les blocs de cuivre pour les protéger de l'oxydation. +Honeycomb Block=Bloc de cire +Honeycomb Block. Used as a decoration.=Bloc de cire. Utilisé en cire. +Honey Bottle=Bouteille de miel +Honey Bottle is used to craft honey blocks and to restore hunger points.=Une bouteille sert à fabriquer des bloc de miel et à restaurer des points de faim. +Drinking will restore 6 hunger points. Can also be used to craft honey blocks.=Boire ceci restaure 6 points de faim. +Honey Block=Bloc de miel +Honey Block. Used as a decoration and in redstone. Is sticky on some sides.=Bloc de miel. Utilisé comme décoration et avec la redstone. Il est collant sur certains côtés. diff --git a/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.tr b/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.tr new file mode 100644 index 000000000..c4ef54411 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/mcl_honey.ja.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_honey/locale/template.txt b/mods/ITEMS/mcl_honey/locale/template.txt new file mode 100644 index 000000000..3cdeec570 --- /dev/null +++ b/mods/ITEMS/mcl_honey/locale/template.txt @@ -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.= +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_honey/mod.conf b/mods/ITEMS/mcl_honey/mod.conf new file mode 100644 index 000000000..ff211cefa --- /dev/null +++ b/mods/ITEMS/mcl_honey/mod.conf @@ -0,0 +1,5 @@ +name = mcl_honey +author = PrairieWind +description = MineClone 2 mod that adds honey and honeycomb and the respective block versions. +depends = mesecons_mvps +optional = mcl_copper diff --git a/mods/ITEMS/mcl_hoppers/depends.txt b/mods/ITEMS/mcl_hoppers/depends.txt deleted file mode 100644 index 67a60d4df..000000000 --- a/mods/ITEMS/mcl_hoppers/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_formspec -mcl_sounds -mcl_util -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_hoppers/description.txt b/mods/ITEMS/mcl_hoppers/description.txt deleted file mode 100644 index 4430809ac..000000000 --- a/mods/ITEMS/mcl_hoppers/description.txt +++ /dev/null @@ -1 +0,0 @@ -It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed. diff --git a/mods/ITEMS/mcl_hoppers/init.lua b/mods/ITEMS/mcl_hoppers/init.lua index 52cb60874..15bc922ff 100644 --- a/mods/ITEMS/mcl_hoppers/init.lua +++ b/mods/ITEMS/mcl_hoppers/init.lua @@ -1,30 +1,48 @@ -local S = minetest.get_translator("mcl_hoppers") +local S = minetest.get_translator(minetest.get_current_modname()) +local F = minetest.formspec_escape +local C = minetest.colorize + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_hoppers", false) +local function mcl_log(message) + if LOGGING_ON then + mcl_util.mcl_log(message, "[Hoppers]", true) + end +end --[[ BEGIN OF NODE DEFINITIONS ]] -local mcl_hoppers_formspec = - "size[9,7]".. - "label[2,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Hopper"))).."]".. - "list[current_name;main;2,0.5;5,1;]".. - mcl_formspec.get_itemslot_bg(2,0.5,5,1).. - "label[0,2;"..minetest.formspec_escape(minetest.colorize("#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).. - "listring[current_name;main]".. - "listring[current_player;main]" +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), + "listring[context;main]", + "listring[current_player;main]", +}) -- 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. - tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"}, + tiles = { + "mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + }, node_box = { type = "fixed", fixed = { @@ -61,17 +79,17 @@ local def_hopper = { after_dig_node = function(pos, oldnode, oldmetadata, digger) local meta = minetest.get_meta(pos) - local meta2 = meta + 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} + 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 - meta:from_table(meta2:to_table()) + meta:from_table(meta2) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) local name = player:get_player_name() @@ -101,16 +119,16 @@ local def_hopper = { 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in mcl_hoppers 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to mcl_hoppers 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos)) end, sounds = mcl_sounds.node_sound_metal_defaults(), @@ -124,18 +142,22 @@ local def_hopper = { -- Enabled downwards hopper local def_hopper_enabled = table.copy(def_hopper) def_hopper_enabled.description = S("Hopper") -def_hopper_enabled._tt_help = S("5 inventory slots").."\n"..S("Collects items from above, moves items to container below").."\n"..S("Can be disabled with redstone power") -def_hopper_enabled._doc_items_longdesc = S("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.").."\n\n".. +def_hopper_enabled._tt_help = S("5 inventory slots") .. + "\n" .. S("Collects items from above, moves items to container below") .. "\n" .. + S("Can be disabled with redstone power") +def_hopper_enabled._doc_items_longdesc = S("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.") + .. "\n\n" .. -S("Hoppers interact with containers the following way:").."\n".. -S("• 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").."\n".. -S("• Ender chests: No interaction.").."\n".. -S("• Other containers: Normal interaction.").."\n\n".. + S("Hoppers interact with containers the following way:") .. "\n" .. + S("• 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") + .. "\n" .. + S("• Ender chests: No interaction.") .. "\n" .. + S("• Other containers: Normal interaction.") .. "\n\n" .. -S("Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.") + S("Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.") def_hopper_enabled._doc_items_usagehelp = S("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.") def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing) - local upos = pointed_thing.under + local upos = pointed_thing.under local apos = pointed_thing.above local uposnode = minetest.get_node(upos) @@ -152,7 +174,7 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing) local z = upos.z - apos.z local fake_itemstack = ItemStack(itemstack) - local newnode, param2 + local param2 if x == -1 then fake_itemstack:set_name("mcl_hoppers:hopper_side") param2 = 0 @@ -166,21 +188,22 @@ def_hopper_enabled.on_place = function(itemstack, placer, pointed_thing) fake_itemstack:set_name("mcl_hoppers:hopper_side") param2 = 1 end - local itemstack, success = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2) + local itemstack, _ = minetest.item_place_node(fake_itemstack, placer, pointed_thing, param2) itemstack:set_name("mcl_hoppers:hopper") return itemstack end def_hopper_enabled.mesecons = { effector = { action_on = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_disabled", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_disabled", param2 = node.param2}) end, }, } minetest.register_node("mcl_hoppers:hopper", def_hopper_enabled) --- Disabled downwards hopper +---Disabled downwards hopper +---@type node_definition local def_hopper_disabled = table.copy(def_hopper) def_hopper_disabled.description = S("Disabled Hopper") def_hopper_disabled.inventory_image = nil @@ -190,7 +213,7 @@ def_hopper_disabled.drop = "mcl_hoppers:hopper" def_hopper_disabled.mesecons = { effector = { action_off = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper", param2 = node.param2}) end, }, } @@ -204,15 +227,23 @@ if minetest.get_modpath("screwdriver") then on_rotate = screwdriver.rotate_simple end --- Sidewars hopper (base definition) +---Sidewars hopper (base definition) +---@type node_definition local def_hopper_side = { _doc_items_create_entry = false, drop = "mcl_hoppers:hopper", - groups = {pickaxey=1, container=2,not_in_creative_inventory=1,hopper=2}, + groups = {pickaxey = 1, container = 2, not_in_creative_inventory = 1, hopper = 2}, drawtype = "nodebox", paramtype = "light", paramtype2 = "facedir", - tiles = {"mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png", "mcl_hoppers_hopper_outside.png"}, + tiles = { + "mcl_hoppers_hopper_inside.png^mcl_hoppers_hopper_top.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + "mcl_hoppers_hopper_outside.png", + }, node_box = { type = "fixed", fixed = { @@ -252,10 +283,10 @@ local def_hopper_side = { local meta2 = meta 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} + 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 @@ -289,16 +320,16 @@ local def_hopper_side = { 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff in mcl_hoppers 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " moves stuff to mcl_hoppers 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 mcl_hoppers at "..minetest.pos_to_string(pos)) + minetest.log("action", player:get_player_name() .. + " takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos)) end, on_rotate = on_rotate, sounds = mcl_sounds.node_sound_metal_defaults(), @@ -307,23 +338,25 @@ local def_hopper_side = { _mcl_hardness = 3, } +---@type node_definition local def_hopper_side_enabled = table.copy(def_hopper_side) def_hopper_side_enabled.description = S("Side Hopper") def_hopper_side_enabled.mesecons = { effector = { action_on = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_side_disabled", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_side_disabled", param2 = node.param2}) end, }, } minetest.register_node("mcl_hoppers:hopper_side", def_hopper_side_enabled) +---@type node_definition local def_hopper_side_disabled = table.copy(def_hopper_side) def_hopper_side_disabled.description = S("Disabled Side Hopper") def_hopper_side_disabled.mesecons = { effector = { action_off = function(pos, node) - minetest.swap_node(pos, {name="mcl_hoppers:hopper_side", param2=node.param2}) + minetest.swap_node(pos, {name = "mcl_hoppers:hopper_side", param2 = node.param2}) end, }, } @@ -331,33 +364,170 @@ minetest.register_node("mcl_hoppers:hopper_side_disabled", def_hopper_side_disab --[[ END OF NODE DEFINITIONS ]] +local function hopper_pull_from_mc(mc_ent, dest_pos, inv_size) + local inv = mcl_entity_invs.load_inv(mc_ent, inv_size) + if not inv then + mcl_log("No inv") + return false + end + + local dest_meta = minetest.get_meta(dest_pos) + local dest_inv = dest_meta:get_inventory() + if not dest_inv then + mcl_log("No dest inv") + return + end + + mcl_log("inv. size: " .. mc_ent._inv_size) + for i = 1, mc_ent._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Name: [" .. tostring(stack:get_name()) .. "]") + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + + if not stack:get_name() or stack:get_name() ~= "" then + if dest_inv:room_for_item("main", stack:peek_item()) then + mcl_log("Room so unload") + dest_inv:add_item("main", stack:take_item()) + inv:set_stack("main", i, stack) + + -- Take one item and stop until next time + return + else + mcl_log("no Room") + end + + else + mcl_log("nothing there") + end + end +end + +local function hopper_push_to_mc(mc_ent, dest_pos, inv_size) + local dest_inv = mcl_entity_invs.load_inv(mc_ent, inv_size) + if not dest_inv then + mcl_log("No inv") + return false + end + + local meta = minetest.get_meta(dest_pos) + local inv = meta:get_inventory() + if not inv then + mcl_log("No dest inv") + return + end + + mcl_log("inv. size: " .. mc_ent._inv_size) + for i = 1, mc_ent._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Name: [" .. tostring(stack:get_name()) .. "]") + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + + if not stack:get_name() or stack:get_name() ~= "" then + if dest_inv:room_for_item("main", stack:peek_item()) then + mcl_log("Room so unload") + dest_inv:add_item("main", stack:take_item()) + inv:set_stack("main", i, stack) + + -- Take one item and stop until next time + return + else + mcl_log("no Room") + end + + else + mcl_log("nothing there") + end + end +end + --[[ BEGIN OF ABM DEFINITONS ]] +minetest.register_abm({ + label = "Hoppers pull from minecart hoppers", + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, + interval = 0.5, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + mcl_log("ABM for: " .. minetest.pos_to_string(pos)) + local objs = minetest.get_objects_inside_radius(pos, 3) + + if objs and #objs > 0 then + for k, v in pairs(objs) do + local entity = v:get_luaentity() + 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 + 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 + --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) + 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 + hopper_pull_from_mc(entity, pos, 27) + end + elseif (hm_pos.y == pos.y - 1) + and (hm_pos.x >= pos.x - DIST_FROM_MC and hm_pos.x <= pos.x + DIST_FROM_MC) + and (hm_pos.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 + hopper_push_to_mc(entity, pos, 27) + end + end + end + else + mcl_log("no entity") + end + end + else + mcl_log("objs missing") + end + end, +}) + -- Make hoppers suck in dropped items minetest.register_abm({ label = "Hoppers suck in dropped items", - nodenames = {"mcl_hoppers:hopper","mcl_hoppers:hopper_side"}, + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, interval = 1.0, chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) - local abovenode = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}) + local abovenode = minetest.get_node(vector.offset(pos, 0, 1, 0)) if not minetest.registered_items[abovenode.name] then return end -- Don't bother checking item enties if node above is a container (should save some CPU) - if minetest.registered_items[abovenode.name].groups.container then + if minetest.get_item_group(abovenode.name, "container") ~= 0 then return end local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - for _,object in ipairs(minetest.get_objects_inside_radius(pos, 2)) do - if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then + for _, object in pairs(minetest.get_objects_inside_radius(pos, 2)) do + if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and + not object:get_luaentity()._removed then if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then -- Item must get sucked in when the item just TOUCHES the block above the hopper -- This is the reason for the Y calculation. -- Test: Items on farmland and slabs get sucked, but items on full blocks don't local posob = object:get_pos() local posob_miny = posob.y + object:get_properties().collisionbox[2] - if math.abs(posob.x-pos.x) <= 0.5 and (posob_miny-pos.y < 1.5 and posob.y-pos.y >= 0.3) then + if math.abs(posob.x - pos.x) <= 0.5 and (posob_miny - pos.y < 1.5 and posob.y - pos.y >= 0.3) then inv:add_item("main", ItemStack(object:get_luaentity().itemstring)) object:get_luaentity().itemstring = "" object:remove() @@ -368,8 +538,14 @@ minetest.register_abm({ end, }) --- Returns true if itemstack is fuel, but not for lava bucket if destination already has one -local is_transferrable_fuel = function(itemstack, src_inventory, src_list, dst_inventory, dst_list) +---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) @@ -381,8 +557,6 @@ local is_transferrable_fuel = function(itemstack, src_inventory, src_list, dst_i end end - - minetest.register_abm({ label = "Hopper/container item exchange", nodenames = {"mcl_hoppers:hopper"}, @@ -391,18 +565,18 @@ minetest.register_abm({ chance = 1, action = function(pos, node, active_object_count, active_object_count_wider) -- Get node pos' for item transfer - local uppos = {x=pos.x,y=pos.y+1,z=pos.z} - local downpos = {x=pos.x,y=pos.y-1,z=pos.z} + 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.registered_nodes[upnode.name].groups.container + 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}) + 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 @@ -411,7 +585,6 @@ minetest.register_abm({ -- 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 - g = minetest.registered_nodes[downnode.name].groups.container mcl_util.move_item_container(pos, downpos) end, }) @@ -427,15 +600,15 @@ minetest.register_abm({ local face = minetest.get_node(pos).param2 local front = {} if face == 0 then - front = {x=pos.x-1,y=pos.y,z=pos.z} + front = vector.offset(pos, -1, 0, 0) elseif face == 1 then - front = {x=pos.x,y=pos.y,z=pos.z+1} + front = vector.offset(pos, 0, 0, 1) elseif face == 2 then - front = {x=pos.x+1,y=pos.y,z=pos.z} + front = vector.offset(pos, 1, 0, 0) elseif face == 3 then - front = {x=pos.x,y=pos.y,z=pos.z-1} + front = vector.offset(pos, 0, 0, -1) end - local above = {x=pos.x,y=pos.y+1,z=pos.z} + local above = vector.offset(pos, 0, 1, 0) local frontnode = minetest.get_node(front) if not minetest.registered_nodes[frontnode.name] then return end @@ -443,26 +616,26 @@ minetest.register_abm({ -- 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.registered_nodes[abovenode.name].groups.container + 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}) + 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.registered_nodes[frontnode.name].groups.container + 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, stack = mcl_util.get_eligible_transfer_item_slot(sinv, "main", dinv, "fuel", is_transferrable_fuel) + 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 @@ -470,13 +643,124 @@ minetest.register_abm({ end }) +if minetest.get_modpath("mcl_composters") then + minetest.register_abm({ + label = "Bonemeal extraction from composter", + nodenames = {"mcl_hoppers:hopper", "mcl_hoppers:hopper_side"}, + neighbors = {"mcl_composters:composter_ready"}, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + local uppos = vector.offset(pos, 0, 1, 0) + --local downpos = vector.offset(pos, 0, -1, 0) + + -- Get bonemeal from composter above + local upnode = minetest.get_node(uppos) + if upnode.name == "mcl_composters:composter_ready" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + minetest.swap_node(uppos, {name = "mcl_composters:composter"}) + + inv:add_item("main", "mcl_bone_meal:bone_meal") + end + end, + }) + + ---@param node node + ---@return integer? + ---@nodiscard + local function composter_level(node) + local nn = node.name + if nn == "mcl_composters:composter" then + return 0 + elseif nn == "mcl_composters:composter_1" then + return 1 + elseif nn == "mcl_composters:composter_2" then + return 2 + elseif nn == "mcl_composters:composter_3" then + return 3 + elseif nn == "mcl_composters:composter_4" then + return 4 + elseif nn == "mcl_composters:composter_5" then + return 5 + elseif nn == "mcl_composters:composter_6" then + return 6 + elseif nn == "mcl_composters:composter_7" then + return 7 + else + return nil + end + end + + for i = 1, 7 do + assert(composter_level({name = "mcl_composters:composter_" .. i}) == i) + end + + assert(composter_level({name = "mcl_composters:composter"}) == 0) + assert(composter_level({name = "mcl_composters:some_other_node"}) == nil) + + minetest.register_abm({ + label = "Add compostable items on composter", + nodenames = {"mcl_hoppers:hopper"}, + neighbors = { + "mcl_composters:composter", + "mcl_composters:composter_1", + "mcl_composters:composter_2", + "mcl_composters:composter_3", + "mcl_composters:composter_4", + "mcl_composters:composter_5", + "mcl_composters:composter_6", + "mcl_composters:composter_7", + }, + interval = 1.0, + chance = 1, + action = function(pos, node, active_object_count, active_object_count_wider) + --local uppos = vector.offset(pos, 0, 1, 0) + local downpos = vector.offset(pos, 0, -1, 0) + + local downnode = minetest.get_node(downpos) + + ---@type integer|string|nil + local level = composter_level(downnode) + + --Consume compostable items and update composter below + if level then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + for i = 1, 5 do + local stack = inv:get_stack("main", i) + local compchance = minetest.get_item_group(stack:get_name(), "compostability") + + if compchance > 0 then + stack:take_item() + inv:set_stack("main", i, stack) + + if compchance >= math.random(0, 100) then + mcl_dye.add_bone_meal_particle(vector.offset(downpos, 0, level / 8, 0)) + if level < 7 then + level = level + 1 + else + level = "ready" + end + minetest.swap_node(downpos, {name = "mcl_composters:composter_" .. level}) + end + break + end + end + end + end, + }) +end + minetest.register_craft({ output = "mcl_hoppers:hopper", recipe = { - {"mcl_core:iron_ingot","","mcl_core:iron_ingot"}, - {"mcl_core:iron_ingot","mcl_chests:chest","mcl_core:iron_ingot"}, - {"","mcl_core:iron_ingot",""}, - } + {"mcl_core:iron_ingot", "", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_chests:chest", "mcl_core:iron_ingot"}, + {"", "mcl_core:iron_ingot", ""}, + }, }) -- Add entry aliases for the Help @@ -490,7 +774,7 @@ minetest.register_alias("mcl_hoppers:hopper_item", "mcl_hoppers:hopper") minetest.register_lbm({ label = "Update hopper formspecs (0.60.0", name = "mcl_hoppers:update_formspec_0_60_0", - nodenames = { "group:hopper" }, + nodenames = {"group:hopper"}, run_at_every_load = false, action = function(pos, node) local meta = minetest.get_meta(pos) diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.fr.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.fr.tr index 40795d09c..7458ebfc1 100644 --- a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.fr.tr +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.fr.tr @@ -1,15 +1,15 @@ # textdomain: mcl_hoppers Hopper=Entonnoir -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.=Les entonoirs sont des conteneurs avec 5 emplacements d'inventaire. Ils récupèrent les objets déposés par le haut, prennent les objets d'un conteneur au-dessus et tentent de les placer dans un conteneur adjacent. Les entonnoirs peuvent aller vers le bas ou sur le côté. Les entonnoirs interagissent avec les coffres, les compte-gouttes, les distributeurs, les boites de shulker, les fours et les entonnoirs. -Hoppers interact with containers the following way:=Les entonnoirs interagissent avec les conteneurs de la manière suivante: -• 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=• Fours: les entonoires d'en haut placent les objets dans l'emplacement source. Les entonoires d'en bas prennent les éléments de la fente de sortie. Ils prennent également des objets de la fente de carburant lorsqu'ils ne peuvent pas être utilisés comme carburant. Des entonaires latérales qui pointent vers le four mettent des objets dans la fente de combustible -• Ender chests: No interaction.=• Coffres Ender: Aucune interaction. +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.=Les entonnoirs sont des conteneurs avec 5 emplacements d'inventaire. Ils récupèrent les objets déposés par le haut, prennent les objets d'un conteneur au-dessus et tentent de les placer dans un conteneur adjacent. Les entonnoirs peuvent aller vers le bas ou sur le côté. Les entonnoirs interagissent avec les coffres, les compte-gouttes, les distributeurs, les boites de shulker, les fours et les entonnoirs. +Hoppers interact with containers the following way:=Les entonnoirs interagissent avec les conteneurs de la manière suivante : +• 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=• Fours: les entonnoirs d'en haut placent les objets dans l'emplacement source. Les entonnoirs d'en bas prennent les éléments de la fente de sortie. Ils prennent également des objets de la fente de carburant lorsqu'ils ne peuvent pas être utilisés comme carburant. Des entonnoirs latérales qui pointent vers le four mettent des objets dans la fente de combustible +• Ender chests: No interaction.=• Coffres Ender : Aucune interaction. • Other containers: Normal interaction.=• Autres conteneurs: interaction normale. -Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=Les entonoires peuvent être désactivées lorsqu'elles sont alimentées en redstone. Les trémies désactivées ne déplacent pas les objets. -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.=Pour placer un entonoire verticalement, placez-la au sol ou au plafond. Pour le placer sur le côté, placez-le sur le côté d'un bloc. Utilisez l'entonoire pour accéder à son inventaire. -Disabled Hopper=Entonoir Désactivé -Side Hopper=Entonoir Latéral -Disabled Side Hopper=Entonoir Latéral Désactivé +Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=Les entonnoirs peuvent être désactivées lorsqu'ils sont alimentés en redstone. Les entonnoirs désactivés ne déplacent pas les objets. +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.=Pour placer un entonnoir verticalement, placez-le au sol ou au plafond. Pour le placer sur le côté, placez-le sur le côté d'un bloc. Utilisez l'entonnoir pour accéder à son inventaire. +Disabled Hopper=Entonnoir désactivé +Side Hopper=Entonnoir latéral +Disabled Side Hopper=Entonnoir latéral désactivé Inventory=Inventaire 5 inventory slots=5 emplacements d'inventaire Collects items from above, moves items to container below=Collecte les éléments d'en haut, déplace les éléments vers le conteneur ci-dessous diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr new file mode 100644 index 000000000..81d32f48c --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.ja.tr @@ -0,0 +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 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.=ホッパーは、レッドストーン動力を供給すると無効化できます。無効化されたホッパーは、アイテムを移動させません。 +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つのインベントリースロット +Collects items from above, moves items to container below=上からのアイテムを集め、下のコンテナに移動 +Can be disabled with redstone power=レッドストーン動力で無効化可能 diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pl.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pl.tr new file mode 100644 index 000000000..8ef70f4f0 --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.pl.tr @@ -0,0 +1,16 @@ +# textdomain: mcl_hoppers +Hopper=Lej +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.=Leje są pojemnikami z 5 miejscami ekwipunku. Zbierają upuszczone na nie z góry przedmioty, przedmioty z pojemników na nimi i próbują je umieścić w przyległych pojemnikach. Leje mogą być skierowane w dół bądź w bok. Leje wchodzą w interakcję ze skrzyniami, podajnikami, dozownikami, shulkerowymi skrzyniami, piecami i lejami. +Hoppers interact with containers the following way:=Leje wchodzą w interakcję z pojemnikami w następujący sposób: +• 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=Piece: leje nad nimi będą umieszczać przedmioty w miejsce materiału źródłowego. Leje z dołu będą brały przedmioty z miejsca wyjściowego. Będą także zabierały przedmioty z miejsca na paliwo jeśli nie można ich użyć jako paliwo. Boczne leje wskazujące na piec będą wstawiać przedmioty w miejsce na paliwo. +• Ender chests: No interaction.=Skrzynie kresu: nie wchodzą w interakcję. +• Other containers: Normal interaction.=Inne pojemniki: zwykła interakcja. +Hoppers can be disabled when supplied with redstone power. Disabled hoppers don't move items.=Leje mogą być wyłączone sygnałem z czerwienitu. +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.=Aby postawić lej pionowo postaw go na podłodze lub suficie. Aby postawić go bocznie ustaw go na boku bloku. Kliknij "Użyj" na leju by zarządzać jego ekwipunkiem. +Disabled Hopper=Wyłączony lej +Side Hopper=Boczny lej +Disabled Side Hopper=Wyłączony boczny lej +Inventory=Ekwipunek +5 inventory slots=5 miejsc w ekwipunku +Collects items from above, moves items to container below=Zbiera przedmioty z góry, umieszcza je w pojemniku pod spodem +Can be disabled with redstone power=Może być wyłączony czerwienitem diff --git a/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.zh_TW.tr b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.zh_TW.tr new file mode 100644 index 000000000..f3e8be8ab --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/locale/mcl_hoppers.zh_TW.tr @@ -0,0 +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 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.=供給紅石電源時,可以禁用漏斗。被禁用的漏斗不會移動物品。 +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個物品槽 +Collects items from above, moves items to container below=從上面收集物品,並把物品放到下面的容器中 +Can be disabled with redstone power=可被紅石電源禁用 diff --git a/mods/ITEMS/mcl_hoppers/mod.conf b/mods/ITEMS/mcl_hoppers/mod.conf new file mode 100644 index 000000000..639a5f59e --- /dev/null +++ b/mods/ITEMS/mcl_hoppers/mod.conf @@ -0,0 +1,4 @@ +name = mcl_hoppers +description = It's just a clone of Minecraft hoppers, functions nearly identical to them minus mesecons making them stop and the way they're placed. +depends = mcl_core, mcl_formspec, mcl_sounds, mcl_util, mcl_dye +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_top.png b/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_top.png deleted file mode 100644 index 918e58f5d..000000000 Binary files a/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_itemframes/README.txt b/mods/ITEMS/mcl_itemframes/README.txt index d9514a03b..c2756a1c9 100644 --- a/mods/ITEMS/mcl_itemframes/README.txt +++ b/mods/ITEMS/mcl_itemframes/README.txt @@ -1,4 +1,13 @@ -This mod is originally by Zeg9, but heavily modified for MineClone 2. +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. + +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 +included in the code / module. Model created by 22i, licensed under the GNU GPLv3 . diff --git a/mods/ITEMS/mcl_itemframes/depends.txt b/mods/ITEMS/mcl_itemframes/depends.txt deleted file mode 100644 index 0b5088e3c..000000000 --- a/mods/ITEMS/mcl_itemframes/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_core -mcl_sounds -screwdriver? diff --git a/mods/ITEMS/mcl_itemframes/init.lua b/mods/ITEMS/mcl_itemframes/init.lua index 073933fcf..1f53f8250 100644 --- a/mods/ITEMS/mcl_itemframes/init.lua +++ b/mods/ITEMS/mcl_itemframes/init.lua @@ -1,304 +1,40 @@ -local S = minetest.get_translator("mcl_itemframes") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) -local VISUAL_SIZE = 0.3 +local S = minetest.get_translator(minetest.get_current_modname()) -minetest.register_entity("mcl_itemframes:item",{ - hp_max = 1, - visual = "wielditem", - visual_size = {x=VISUAL_SIZE, y=VISUAL_SIZE}, - physical = false, - pointable = false, - textures = { "blank.png" }, - _texture = "blank.png", - _scale = 1, +-- mcl_itemframes API +dofile(modpath .. "/item_frames_API.lua") - on_activate = function(self, staticdata) - if staticdata ~= nil and staticdata ~= "" then - local data = staticdata:split(';') - if data and data[1] and data[2] then - self._nodename = data[1] - self._texture = data[2] - if data[3] then - self._scale = data[3] - else - self._scale = 1 - end - end - end - if self._texture ~= nil then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, - get_staticdata = function(self) - if self._nodename ~= nil and self._texture ~= nil then - local ret = self._nodename .. ';' .. self._texture - if self._scale ~= nil then - ret = ret .. ';' .. self._scale - end - return ret - end - return "" - end, +-- actual api initialization. +mcl_itemframes.create_base_definitions() - _update_texture = function(self) - if self._texture ~= nil then - self.object:set_properties({ - textures={self._texture}, - visual_size={x=VISUAL_SIZE/self._scale, y=VISUAL_SIZE/self._scale}, - }) - end - end, -}) +-- necessary to maintain compatibility amongst older versions. +mcl_itemframes.backwards_compatibility() +-- Define the standard frames. +mcl_itemframes.create_custom_frame("false", "item_frame", false, + "mcl_itemframes_item_frame.png", mcl_colors.WHITE, S("Can hold an item."), + S("Item Frame"), "") +mcl_itemframes.create_custom_frame("false", "glow_item_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, S("Can hold an item and glows."), + S("Glowing Item Frame"), "") -local facedir = {} -facedir[0] = {x=0,y=0,z=1} -facedir[1] = {x=1,y=0,z=0} -facedir[2] = {x=0,y=0,z=-1} -facedir[3] = {x=-1,y=0,z=0} - -local remove_item_entity = function(pos, node) - local objs = nil - if node.name == "mcl_itemframes:item_frame" then - objs = minetest.get_objects_inside_radius(pos, .5) - end - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "mcl_itemframes:item" then - obj:remove() - end - end - end -end - -local update_item_entity = function(pos, node, param2) - remove_item_entity(pos, node) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - if not param2 then - param2 = node.param2 - end - if node.name == "mcl_itemframes:item_frame" then - local posad = facedir[param2] - pos.x = pos.x + posad.x*6.5/16 - pos.y = pos.y + posad.y*6.5/16 - pos.z = pos.z + posad.z*6.5/16 - end - local e = minetest.add_entity(pos, "mcl_itemframes:item") - local lua = e:get_luaentity() - lua._nodename = node.name - local itemname = item:get_name() - if itemname == "" or itemname == nil then - lua._texture = "blank.png" - lua._scale = 1 - else - lua._texture = itemname - local def = minetest.registered_items[itemname] - if def and def.wield_scale then - lua._scale = def.wield_scale.x - else - lua._scale = 1 - end - end - lua:_update_texture() - if node.name == "mcl_itemframes:item_frame" then - local yaw = math.pi*2 - param2 * math.pi/2 - e:set_yaw(yaw) - end - end -end - -local drop_item = function(pos, node, meta, clicker) - local cname = "" - if clicker and clicker:is_player() then - cname = clicker:get_player_name() - end - if node.name == "mcl_itemframes:item_frame" and not minetest.is_creative_enabled(cname) then - local inv = meta:get_inventory() - local item = inv:get_stack("main", 1) - if not item:is_empty() then - minetest.add_item(pos, item) - end - end - meta:set_string("infotext", "") - remove_item_entity(pos, node) -end - -minetest.register_node("mcl_itemframes:item_frame",{ - description = S("Item Frame"), - _tt_help = S("Can hold an item"), - _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), - _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), - drawtype = "mesh", - is_ground_content = false, - mesh = "mcl_itemframes_itemframe1facedir.obj", - selection_box = { type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5} }, - collision_box = { type = "fixed", fixed = {-6/16, -6/16, 7/16, 6/16, 6/16, 0.5} }, - tiles = {"mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "mcl_itemframes_itemframe_background.png", "default_wood.png", "mcl_itemframes_itemframe_background.png"}, - inventory_image = "mcl_itemframes_item_frame.png", - wield_image = "mcl_itemframes_item_frame.png", - paramtype = "light", - paramtype2 = "facedir", - sunlight_propagates = true, - groups = { dig_immediate=3,deco_block=1,dig_by_piston=1,container=7,attached_node_facedir=1 }, - sounds = mcl_sounds.node_sound_defaults(), - node_placement_prediction = "", - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - return itemstack - 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_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - inv:set_size("main", 1) - end, - on_rightclick = function(pos, node, clicker, itemstack) - if not itemstack then - return - end - local pname = clicker:get_player_name() - if minetest.is_protected(pos, pname) then - minetest.record_protection_violation(pos, pname) - return - end - local meta = minetest.get_meta(pos) - drop_item(pos, node, meta, clicker) - local inv = meta:get_inventory() - if itemstack:is_empty() then - remove_item_entity(pos, node) - meta:set_string("infotext", "") - inv:set_stack("main", 1, "") - return itemstack - end - local put_itemstack = ItemStack(itemstack) - put_itemstack:set_count(1) - inv:set_stack("main", 1, put_itemstack) - update_item_entity(pos, node) - -- Add node infotext when item has been named - local imeta = itemstack:get_meta() - local iname = imeta:get_string("name") - if iname then - meta:set_string("infotext", iname) - end - - if not minetest.is_creative_enabled(clicker:get_player_name()) then - itemstack:take_item() - end - return itemstack - end, - allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return count - end - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - on_destruct = function(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - drop_item(pos, node, meta) - end, - on_rotate = function(pos, node, user, mode, param2) - if mode == screwdriver.ROTATE_FACE then - -- Rotate face - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - - local objs = nil - if node.name == "mcl_itemframes:item_frame" then - objs = minetest.get_objects_inside_radius(pos, .5) - end - if objs then - for _, obj in ipairs(objs) do - if obj and obj:get_luaentity() and obj:get_luaentity().name == "mcl_itemframes:item" then - update_item_entity(pos, node, (node.param2+1) % 4) - break - end - end - end - return - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - end, -}) - +-- Register the base frame's recipes. +-- was going to make it a specialized function, but minetest refuses to play nice. minetest.register_craft({ - output = 'mcl_itemframes:item_frame', + output = "mcl_itemframes:item_frame", recipe = { - {'mcl_core:stick', 'mcl_core:stick', 'mcl_core:stick'}, - {'mcl_core:stick', 'mcl_mobitems:leather', 'mcl_core:stick'}, - {'mcl_core:stick', 'mcl_core:stick', 'mcl_core:stick'}, + { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, + { "mcl_core:stick", "mcl_mobitems:leather", "mcl_core:stick" }, + { "mcl_core:stick", "mcl_core:stick", "mcl_core:stick" }, } }) -minetest.register_lbm({ - label = "Update legacy item frames", - name = "mcl_itemframes:update_legacy_item_frames", - nodenames = {"itemframes:frame"}, - action = function(pos, node) - -- Swap legacy node, then respawn entity - node.name = "mcl_itemframes:item_frame" - local meta = minetest.get_meta(pos) - local item = meta:get_string("item") - minetest.swap_node(pos, node) - if item ~= "" then - local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) - local inv = meta:get_inventory() - inv:set_size("main", 1) - if not itemstack:is_empty() then - inv:set_stack("main", 1, itemstack) - end - end - update_item_entity(pos, node) - end, +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, }) --- FIXME: Item entities can get destroyed by /clearobjects -minetest.register_lbm({ - label = "Respawn item frame item entities", - name = "mcl_itemframes:respawn_entities", - nodenames = {"mcl_itemframes:item_frame"}, - run_at_every_load = true, - action = function(pos, node) - update_item_entity(pos, node) - end, -}) - -minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") +mcl_itemframes.custom_register_lbm() diff --git a/mods/ITEMS/mcl_itemframes/item_frames_API.lua b/mods/ITEMS/mcl_itemframes/item_frames_API.lua new file mode 100644 index 000000000..999becf05 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_API.lua @@ -0,0 +1,889 @@ +--- +--- Generated by EmmyLua(https://github.com/EmmyLua) +--- Created by michieal. +--- DateTime: 10/26/22 1:16 AM +--- + +mcl_itemframes = {} +mcl_itemframes.item_frame_base = {} +mcl_itemframes.glow_frame_base = {} +mcl_itemframes.frames_registered = {} +mcl_itemframes.frames_registered.glowing = {} +mcl_itemframes.frames_registered.standard = {} + +-- Set to true to get all of the DEBUG messages. +mcl_itemframes.DEBUG = false + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] initialized.") +end + +local S = minetest.get_translator(minetest.get_current_modname()) +local table = table +local pairs = pairs + +if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] API initialized.") +end + +local VISUAL_SIZE = 0.3 +local facedir = {} +local pi = math.pi + +local glow_amount = 6 -- LIGHT_MAX is 15, but the items aren't supposed to be a light source. +local frame_item_base = {} +local map_item_base = {} + +local TIMER_INTERVAL = 40.0 + +-- Time to Fleckenstein! (it just sounds cool lol) + +--- self: the object to roll. +local function update_roll(self, pos) + + -- get the entity's metadata. + local meta = minetest.get_meta(pos) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local current_roll = meta:get_int("roll", 0) + local new_roll = current_roll + 1 + + if new_roll == 8 then + new_roll = 0 + end + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + rot.z = Radians + + self:set_rotation(rot) + +end + +--- self: the object to roll. +--- faceDeg: 0-7, inclusive. +local function set_roll(self, faceDeg) + -- get the entity's metadata. + local meta = minetest.get_meta(self:get_pos()) + + -- using an integer, as it's the number of 45 degree turns. ie, 0 to 7 + local new_roll = faceDeg + + if new_roll >= 8 then + new_roll = 7 + end + if new_roll <= 0 then + new_roll = 0 + end + + meta:set_int("roll", new_roll) + + local new_roll_deg = new_roll * 45 + + -- * `get_rotation()`: returns the rotation, a vector (radians) + local rot = self:get_rotation() + local Radians = 0 + + -- Radians = Degrees * (pi / 180) degrees to radian formula + -- Radian quick chart + -- One full revolution is equal to 2π rad (or) 360°. + -- 1° = 0.017453 radians and 1 rad = 57.2958°. + -- To convert an angle from degrees to radians, we multiply it by π/180°. + -- To convert an angle from radians to degrees, we multiply it by 180°/π. + + Radians = new_roll_deg * (pi / 180) + + rot.z = Radians + + self:set_rotation(rot) +end + +local function update_map_texture (self, staticdata) + self.id = staticdata + local result = true + result = mcl_maps.load_map(self.id, function(texture) + -- will not crash even if self.object is invalid by now + -- update... quite possibly will screw up with each version of Minetest. >.< + if not texture then + minetest.log("error", "Failed to load the map texture using mcl_maps.") + end + + self.object:set_properties({ textures = { texture } }) + end) + if result ~= nil and result == false then + minetest.log("error", "[mcl_itemframes] Error setting up Map Item.") + end + +end + +local remove_item_entity = function(pos, node) + + local name_found = false + local found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + if mcl_itemframes.DEBUG then + minetest.log("action", "mcl_itemframes] remove_item_entity: " .. found_name_to_use .. "'s displayed item.") + end + + -- node.name == "mcl_itemframes:item_frame" or node.name == "mcl_itemframes:glow_item_frame" or + if node.name == found_name_to_use then + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do + local entity = obj:get_luaentity() + if entity then + -- remove old entities + if entity.name == "mcl_itemframes:item" or entity.name == "mcl_itemframes:glow_item" or entity.name == "mcl_itemframes:map" or entity.name == "mcl_itemframes:glow_map" then + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + if not item:is_empty() then + if (node.name == found_name_to_use) then + minetest.add_item(pos, item) + end + meta:set_string("infotext", "") + end + obj:remove() + end + if entity.name == found_name_to_use .. "_item" or entity.name == found_name_to_use .. "_map" then + if mcl_itemframes.DEBUG then + minetest.log("action", "mcl_itemframes] remove_item_entity: " .. entity.name .. "-- the item.") + end + obj:remove() + end + end + end + end +end + +mcl_itemframes.update_item_entity = function(pos, node, param2) + + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nPosition: " .. dump(pos) .. "\nNode: " .. dump(node)) + end + + remove_item_entity(pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + + local name_found = false + local found_name_to_use = "" + local has_glow = false + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + has_glow = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + has_glow = false + found_name_to_use = v + break + end + end + end + + if name_found == false then + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nFailed to find registered node:\nNode name - " .. node.name) + minetest.log("error", "[mcl_itemframes] Update_Generic_Item:\nRegistry definition:" .. dump(mcl_itemframes.frames_registered)) + return + end + + if not item:is_empty() then + -- update existing items placed. + if not param2 then + param2 = node.param2 + end + local pos_adj = facedir[param2] + + if node.name == found_name_to_use then + pos.x = pos.x + pos_adj.x * 6.5 / 16 + pos.y = pos.y + pos_adj.y * 6.5 / 16 + pos.z = pos.z + pos_adj.z * 6.5 / 16 + + if mcl_itemframes.DEBUG then + minetest.log("[mcl_itemframes] Update_Generic_Item:\nFound Name in Registry: " .. found_name_to_use) + end + end + local yaw = pi * 2 - param2 * pi / 2 + local map_id = item:get_meta():get_string("mcl_maps:id") + local map_id_entity = {} + local map_id_lua = {} + + local timer = minetest.get_node_timer(pos) + if map_id == "" then + -- handle regular items placed into custom frame. + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item:\nAdding entity: " .. node.name .. "_item") + end + + if node.name == found_name_to_use then + map_id_entity = minetest.add_entity(pos, node.name .. "_item") + else + local debug_string = "[mcl_itemframes] Update_Generic_Item:\nCouldn't find node name in registry: " + minetest.log("error", debug_string .. found_name_to_use "\nregistry: " .. dump(mcl_itemframes.frames_registered)) + return + end + + map_id_lua = map_id_entity:get_luaentity() + map_id_lua._nodename = node.name + + local itemname = item:get_name() + if itemname == "" or itemname == nil then + map_id_lua._texture = "blank.png" + map_id_lua._scale = 1 + + -- set up glow, as this is the default/initial clause on placement. + if has_glow then + map_id_lua.glow = glow_amount + end + + -- if there's nothing to display, then kill the timer. + if timer:is_started() == true then + timer:stop() + end + else + map_id_lua._texture = itemname + local def = minetest.registered_items[itemname] + map_id_lua._scale = def and def.wield_scale and def.wield_scale.x or 1 + + -- fix for /ClearObjects + if minetest.get_item_group(itemname, "clock") == 0 then + -- Do timer related stuff - but only if there is something to display... and it's not a clock. + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + end + + end + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: item's name: " .. itemname) + end + map_id_lua:_update_texture() + if node.name == found_name_to_use then + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Display Item's yaw. " .. node.name) + end + else + -- handle map items placed into custom frame. + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] Update_Generic_Item: Placing map in a " .. found_name_to_use .. " frame.") + end + + if node.name == found_name_to_use then + map_id_entity = minetest.add_entity(pos, found_name_to_use .. "_map", map_id) + map_id_entity:set_yaw(yaw) + else + minetest.log("error", "[mcl_itemframes] Update_Generic_Item: Failed to set Map Item in " .. found_name_to_use .. "'s frame.") + end + + -- give maps a refresh timer. + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + + end + + -- finally, set the rotation (roll) of the displayed object. + local roll = meta:get_int("roll", 0) + set_roll(map_id_entity, roll) + end + +end + +function mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + local name_found = false + local found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + local cname = "" + if clicker and clicker:is_player() then + cname = clicker:get_player_name() + end + if not minetest.is_creative_enabled(cname) then + if (node.name == found_name_to_use) then + local inv = meta:get_inventory() + local item = inv:get_stack("main", 1) + if not item:is_empty() then + minetest.add_item(pos, item) + end + end + end + + meta:set_string("infotext", "") + remove_item_entity(pos, node) + +end + +--- reworked to set up the base item definitions. +function mcl_itemframes.create_base_item_entity() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_item_entity.") + end + + --"mcl_itemframes:item", + frame_item_base = { + hp_max = 1, + visual = "wielditem", + visual_size = { x = VISUAL_SIZE, y = VISUAL_SIZE }, + physical = false, + pointable = false, + textures = { "blank.png" }, + _texture = "blank.png", + _scale = 1, + groups = { immortal = 1, }, + on_activate = function(self, staticdata) + if staticdata and staticdata ~= "" then + local data = staticdata:split(";") + if data and data[1] and data[2] then + self._nodename = data[1] + self._texture = data[2] + if data[3] then + self._scale = data[3] + else + self._scale = 1 + end + end + end + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + get_staticdata = function(self) + if self._nodename and self._texture then + local ret = self._nodename .. ";" .. self._texture + if self._scale then + ret = ret .. ";" .. self._scale + end + return ret + end + return "" + end, + on_punch = function() return true end, + _update_texture = function(self) + if self._texture then + self.object:set_properties({ + textures = { self._texture }, + visual_size = { x = VISUAL_SIZE / self._scale, y = VISUAL_SIZE / self._scale }, + }) + end + end, + } + -- "mcl_itemframes:map", + map_item_base = { + initial_properties = { + visual = "upright_sprite", + visual_size = { x = 1, y = 1 }, + pointable = false, + physical = false, + collide_with_objects = false, + textures = { "blank.png" }, + }, + on_activate = function(self, staticdata) + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] map_item:on_activate.") + end + update_map_texture(self, staticdata) + end, + + get_staticdata = function(self) + return self.id + end, + } + +end + +function mcl_itemframes.create_custom_items(name, has_glow) + local custom_frame_item = table.copy(frame_item_base) + local custom_frame_map_item = table.copy(map_item_base) + if has_glow then + custom_frame_map_item.glow = glow_amount + custom_frame_item.glow = glow_amount + if mcl_itemframes.DEBUG then + minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_item") + minetest.log("action", "[mcl_itemframes] create_custom_item_entity: glow name: " .. name .. "_map\n") + end + else + if mcl_itemframes.DEBUG then + minetest.log("action", "\n[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_item") + minetest.log("action", "[mcl_itemframes] create_custom_item_entity: name: " .. name .. "_map\n") + end + end + minetest.register_entity(":" .. name .. "_item", custom_frame_item) + minetest.register_entity(":" .. name .. "_map", custom_frame_map_item) +end + +function mcl_itemframes.update_frame_registry(modname, name, has_glow) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + local frame = name -- should only be called within the create_frames functions. + if has_glow == true then + table.insert(mcl_itemframes.frames_registered.glowing, frame) + else + table.insert(mcl_itemframes.frames_registered.standard, frame) + end + +end + +--- name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: +--- "glow_item_frame" creates a node named ":mcl_itemframes:glow_item_frame". +function mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, description, inv_wield_image) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + if name == nil then + name = "" + end + + if name == "" then + minetest.log("error", "attempted to create an item frame WITHOUT a name!") + return + end + + if has_glow == nil or has_glow == "" then + has_glow = false + end + + if tiles == nil or tiles == "" then + minetest.log("error", "No textures passed to Create_Custom_Frame!! Exiting frame creation.") + return + end + + local working_name = "mcl_itemframes:" .. name + + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_custom_frame: " .. working_name) + minetest.log("action", "[mcl_itemframes] create_custom_frame - calling create_custom_items " .. working_name) + end + + -- make any special frame items. + mcl_itemframes.create_custom_items(working_name, has_glow) + + local custom_itemframe_definition = {} + + if has_glow == false then + custom_itemframe_definition = table.copy(mcl_itemframes.item_frame_base) + else + custom_itemframe_definition = table.copy(mcl_itemframes.glow_frame_base) + end + + if inv_wield_image ~= nil and inv_wield_image ~= "" then + custom_itemframe_definition.glow_frame_base.inventory_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition.glow_frame_base.wield_image = { "(" .. inv_wield_image .. "^[multiply:" .. color .. ")" } + end + + custom_itemframe_definition.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + custom_itemframe_definition._tt_help = ttframe + custom_itemframe_definition.description = description + + minetest.register_node(":" .. working_name, custom_itemframe_definition) + + mcl_itemframes.update_frame_registry(modname, working_name, has_glow) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_itemframes:item_frame", "nodes", working_name) + end + +end + +function mcl_itemframes.custom_register_lbm() + + local registered_frame_nodenames = {} + + for i = 0, #mcl_itemframes.frames_registered.glowing do + table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.glowing[i]) + end + + for i = 0, #mcl_itemframes.frames_registered.standard do + table.insert(registered_frame_nodenames, mcl_itemframes.frames_registered.standard[i]) + end + + minetest.register_lbm({ + label = "Respawn item frame item entities", + name = "mcl_itemframes:respawn_entities", + nodenames = registered_frame_nodenames, + run_at_every_load = true, + action = function(pos, node) + mcl_itemframes.update_item_entity(pos, node) + end, + }) + +end + +local function register_frame_achievements() + + awards.register_achievement("mcl_itemframes:glowframe", { + title = S("Glow and Behold!"), + description = S("Craft a glow item frame."), + icon = "mcl_itemframes_glow_item_frame.png", + trigger = { + type = "craft", + item = "mcl_itemframes:glow_item_frame", + target = 1 + }, + type = "Advancement", + group = "Overworld", + }) + +end + +function mcl_itemframes.create_base_definitions() + if mcl_itemframes.DEBUG then + minetest.log("action", "[mcl_itemframes] create_base_definitions.") + end + + -- set up the facedir information. + facedir[0] = { x = 0, y = 0, z = 1 } + facedir[1] = { x = 1, y = 0, z = 0 } + facedir[2] = { x = 0, y = 0, z = -1 } + facedir[3] = { x = -1, y = 0, z = 0 } + + mcl_itemframes.item_frame_base = { + description = S("Item Frame"), + name = "mcl_itemframes:item_frame", + _tt_help = S("Can hold an item."), + _doc_items_longdesc = S("Item frames are decorative blocks in which items can be placed."), + _doc_items_usagehelp = S("Just place any item on the item frame. Use the item frame again to retrieve the item."), + drawtype = "mesh", + is_ground_content = false, + mesh = "mcl_itemframes_itemframe1facedir.obj", + selection_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + collision_box = { type = "fixed", fixed = { -6 / 16, -6 / 16, 7 / 16, 6 / 16, 6 / 16, 0.5 } }, + tiles = { "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "mcl_itemframes_item_frame_back.png", "default_wood.png", "mcl_itemframes_item_frame_back.png" }, + inventory_image = "mcl_itemframes_item_frame.png", + wield_image = "mcl_itemframes_item_frame.png", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + 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. + sounds = mcl_sounds.node_sound_defaults(), + node_placement_prediction = "", + + on_timer = function(pos) + local inv = minetest.get_meta(pos):get_inventory() + local stack = inv:get_stack("main", 1) + local itemname = stack:get_name() + local node = {} + if minetest.get_item_group(itemname, "clock") > 0 then + local new_name = "mcl_clock:clock_" .. (mcl_worlds.clock_works(pos) and mcl_clock.old_time or mcl_clock.random_frame) + if itemname ~= new_name then + stack:set_name(new_name) + inv:set_stack("main", 1, stack) + node = minetest.get_node(pos) + mcl_itemframes.update_item_entity(pos, node, node.param2) + end + minetest.get_node_timer(pos):start(1.0) + else + node = minetest.get_node(pos) + mcl_itemframes.update_item_entity(pos, node, node.param2) + end + end, + + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local dir = vector.subtract(pointed_thing.under, pointed_thing.above) + local wdir = minetest.dir_to_wallmounted(dir) + + -- remove bottom and top of objects. + if wdir == 0 or wdir == 1 then + return itemstack + 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_construct = function(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + inv:set_size("main", 1) + end, + + on_rightclick = function(pos, node, clicker, itemstack) + if not itemstack then + return + end + local pname = clicker:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + return + end + local meta = minetest.get_meta(pos) + mcl_itemframes.drop_generic_item(pos, node, meta, clicker) + + local inv = meta:get_inventory() + if itemstack:is_empty() then + remove_item_entity(pos, node) + meta:set_string("infotext", "") + inv:set_stack("main", 1, "") + return itemstack + end + local put_itemstack = ItemStack(itemstack) + put_itemstack:set_count(1) + local itemname = put_itemstack:get_name() + if minetest.get_item_group(itemname, "compass") > 0 then + put_itemstack:set_name(mcl_compass.get_compass_itemname(pos, minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2)), put_itemstack)) + end + if minetest.get_item_group(itemname, "clock") > 0 then + minetest.get_node_timer(pos):start(1.0) + end + + inv:set_stack("main", 1, put_itemstack) + mcl_itemframes.update_item_entity(pos, node) + + -- Add node infotext when item has been named + local imeta = itemstack:get_meta() + local iname = imeta:get_string("name") + if iname then + meta:set_string("infotext", iname) + end + + if not minetest.is_creative_enabled(clicker:get_player_name()) then + itemstack:take_item() + end + return itemstack + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return count + end + end, + + allow_metadata_inventory_take = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + allow_metadata_inventory_put = function(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + else + return stack:get_count() + end + end, + + on_destruct = function(pos) + local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + mcl_itemframes.drop_generic_item(pos, node, meta) + + end, + + on_rotate = function(pos, node, user, mode, param2) + --local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + local objs = nil + local name_found = false + local found_name_to_use = "" + name_found = false + found_name_to_use = "" + + for k, v in pairs(mcl_itemframes.frames_registered.glowing) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + + -- try to cut down on excess looping, if possible. + if name_found == false then + for k, v in pairs(mcl_itemframes.frames_registered.standard) do + if node.name == v then + name_found = true + found_name_to_use = v + break + end + end + end + + if node.name == found_name_to_use then + objs = minetest.get_objects_inside_radius(pos, 0.5) + else + return -- short circuit if it's somehow not the right thing. + end + + if objs then + if mode == screwdriver.ROTATE_FACE or mode == screwdriver.ROTATE_AXIS then + for _, obj in ipairs(objs) do + if obj and obj:get_luaentity() then + local obj_name = obj:get_luaentity().name + if obj_name == found_name_to_use .. "_item" then + if mode == screwdriver.ROTATE_AXIS then + update_roll(obj, pos) + end + break + end + end + end + return false + end + end + end, + } + + -- make the base items for the base frames. + mcl_itemframes.create_base_item_entity() + + -- minetest.register_node("mcl_itemframes:item_frame", mcl_itemframes.item_frame_base) + + -- make glow frame from the base item_frame. + mcl_itemframes.glow_frame_base = table.copy(mcl_itemframes.item_frame_base) + mcl_itemframes.glow_frame_base.description = S("Glowing Item Frame") + mcl_itemframes.glow_frame_base._tt_help = S("Can hold an item and glows.") + mcl_itemframes.glow_frame_base.longdesc = S("Glowing item frames are decorative blocks in which items can be placed and made to glow.") + mcl_itemframes.glow_frame_base.tiles = { "mcl_itemframes_glow_item_frame.png" } + mcl_itemframes.glow_frame_base.inventory_image = "mcl_itemframes_glow_item_frame.png" + mcl_itemframes.glow_frame_base.wield_image = "mcl_itemframes_glow_item_frame.png" + mcl_itemframes.glow_frame_base.mesh = "mcl_itemframes_glow_item_frame.obj" + mcl_itemframes.glow_frame_base.glow = 1 --make the glow frames have some glow at night, but not enough to be a light source. + + -- set up the achievement for glow frames. + register_frame_achievements() + +end + +-- for compatibility: +function mcl_itemframes.backwards_compatibility () + minetest.register_lbm({ + label = "Update legacy item frames", + name = "mcl_itemframes:update_legacy_item_frames", + nodenames = { "itemframes:frame" }, + action = function(pos, node) + -- Swap legacy node, then respawn entity + node.name = "mcl_itemframes:item_frame" + local meta = minetest.get_meta(pos) + local item = meta:get_string("item") + minetest.swap_node(pos, node) + if item ~= "" then + local itemstack = ItemStack(minetest.deserialize(meta:get_string("itemdata"))) + local inv = meta:get_inventory() + inv:set_size("main", 1) + if not itemstack:is_empty() then + inv:set_stack("main", 1, itemstack) + end + end + mcl_itemframes.update_item_entity(pos, node) + end, + }) + minetest.register_alias("itemframes:frame", "mcl_itemframes:item_frame") + + -- adds backwards compatibility + minetest.register_alias("mcl_itemframes:item", "mcl_itemframes:item_frame_item") + minetest.register_alias("mcl_itemframes:map", "mcl_itemframes:item_frame_map") + minetest.register_alias("mcl_itemframes:glow_item", "mcl_itemframes:glow_item_frame_item") + minetest.register_alias("mcl_itemframes:glow_map", "mcl_itemframes:glow_item_frame_map") + + minetest.register_entity("mcl_itemframes:item", frame_item_base) + minetest.register_entity("mcl_itemframes:map", map_item_base) + minetest.register_entity("mcl_itemframes:glow_item", frame_item_base) + minetest.register_entity("mcl_itemframes:glow_map", map_item_base) + +end diff --git a/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt new file mode 100644 index 000000000..7510b15b5 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/item_frames_api_doc.txt @@ -0,0 +1,36 @@ +The item frames use case is a very specific one, but... in the event that there is need for a new item frame then that +is where this api will shine. + +As long as the api has been initialized (which it does in its own init.lua) then you really only need to call one +function. That function being mcl_itemframes.create_custom_frame(modname, name, has_glow, tiles, color, ttframe, +description, inv_wield_image). Note: unlike the Signs API, this API does not automatically create the recipe for you. + +Here's an explanation of create_custom_frame and an example of using it. + +This function is responsible for creating each frame, and handling the creation of its underlying entities. + +Parameters: +* modname: Used to make sure that a specific module is installed before running the code contained within. Set to "" or + false, if there's not a mod to check for. +* name: The name used to distinguish the item frame. Prepends "mcl_itemframes:" to the name. Example usage: + "glow_item_frame" creates a node named "mcl_itemframes:glow_item_frame". +* has_glow: Does the frame cause the item within to glow? true / false. +* tiles: The image files used for the item frame's object texturing. +* color: Colorizes the frame / wield / inventory image to a specific color. Use White (#FFFFFF) to ignore. +* ttframe: The tooltip to show for the frame. +* description: The frame's description. +* inv_wield_image: Optionally the image to use as the inventory and the wield image. Colorized. set to "" or nil to use + the default frame / glow frame images. Note: must be set if you want the inventory / wield image to be colored. + +example: +-- Register the Glow Frame +mcl_itemframes.create_custom_frame("false", "glow_item_frame", true, + "mcl_itemframes_glow_item_frame.png", mcl_colors.WHITE, "Glowing Item Frame", + "Can hold an item and glows.","") + +-- Register the Glow Frame's recipe +minetest.register_craft({ + type = "shapeless", + output = 'mcl_itemframes:glow_item_frame', + recipe = { 'mcl_mobitems:glow_ink_sac', 'mcl_itemframes:item_frame' }, +}) diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr index 07d7812f6..b9bf40e1a 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.de.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Rahmen -Item frames are decorative blocks in which items can be placed.=Rahmen sind dekorative Blöcke, in denen man Gegenstände platzieren kann. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand in den Rahmen. Benutzen Sie den Rahmen erneut, um den Gegenstand zurück zu erhalten. -Can hold an item=Kann einen Gegenstand halten +Item Frame=Artikel Rahmen +Item frames are decorative blocks in which items can be placed.=Artikelrahmen sind dekorative Blöcke, in denen Artikel platziert werden können. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Platzieren Sie einfach einen beliebigen Gegenstand auf dem Gegenstandsrahmen. Verwenden Sie den Artikelrahmen erneut, um den Artikel abzurufen. +Can hold an item.=Kann einen Gegenstand halten. +Glowing Item Frame=Leuchtender Gegenstandsrahmen +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Leuchtende Gegenstandsrahmen sind dekorative Blöcke, in denen Gegenstände platziert und zum Leuchten gebracht werden können. +Can hold an item and glows.=Kann einen Gegenstand halten und leuchtet. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr index 0803234b0..d5c3aed71 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.es.tr @@ -1,5 +1,8 @@ # textdomain: mcl_itemframes -Item Frame=Marco +Item Frame=Cuadro de artículo Item frames are decorative blocks in which items can be placed.=Los marcos de elementos son bloques decorativos en los que se pueden colocar elementos. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier artículo en el marco del artículo. Use el marco del artículo nuevamente para recuperar el artículo. - +Just place any item on the item frame. Use the item frame again to retrieve the item.=Simplemente coloque cualquier elemento en el marco del elemento. Use el marco del elemento nuevamente para recuperar el elemento. +Can hold an item.=Puede contener un artículo. +Glowing Item Frame=Marco de artículo brillante +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Los marcos de elementos brillantes son bloques decorativos en los que se pueden colocar elementos y hacer que brillen. +Can hold an item and glows.=Puede sostener un artículo y brilla. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr index 180c5555f..7ff510cb2 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.fr.tr @@ -1,5 +1,10 @@ # textdomain: mcl_itemframes -Item Frame=Cadre -Item frames are decorative blocks in which items can be placed.=Les cadres sont des blocs décoratifs dans lesquels les objets peuvent être placés. -Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel objet sur le cadre. Utilisez à nouveau le cadre décoré pour récupérer l'élément. -Can hold an item=Peut contenir un objet +Item Frame=Cadre de l'article +Item frames are decorative blocks in which items can be placed.=Les cadres d'objets sont des blocs décoratifs dans lesquels des objets peuvent être placés. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Placez simplement n'importe quel élément sur le cadre de l'élément. Utilisez à nouveau le cadre de l'objet pour récupérer l'objet. +Can hold an item.=Peut contenir un objet +Glowing Item Frame=Cadre d'objet lumineux +Glowing item frames are decorative blocks in which items can be placed.=Les cadres d'objets lumineux sont des blocs décoratifs dans lesquels des objets peuvent être placés. +Can hold an item and glows.=Peut contenir un objet et brille +Glow and Behold!=Une idée brillante ! +Craft a glow item frame.=Fabriquez un cadre brillant. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr new file mode 100644 index 000000000..daf21337f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ja.tr @@ -0,0 +1,8 @@ +# 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=アイテムを保持可能 +Glow Item Frame=発光するアイテムフレーム +Glow item frames are decorative blocks in which items can be placed.=発光するアイテムフレームは、アイテムを配置することができる装飾ブロックです。 +Can hold an item and glows=アイテムを保持でき、発光する \ No newline at end of file diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr new file mode 100644 index 000000000..87b83c27d --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.pl.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_itemframes +Item Frame=Ramka na przedmiot +Item frames are decorative blocks in which items can be placed.=Ramki na przedmiot to dekoracyjne bloki w których można umieszczać przedmioty. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Umieść dowolny przedmiot w ramce. Użyj ramki ponownie aby odzyskać przedmiot. +Can hold an item=Może przetrzymywać przedmiot +Item Frame=Rama przedmiotu +Item frames are decorative blocks in which items can be placed.=Ramki na przedmioty to klocki ozdobne, w których można umieszczać przedmioty. +Just place any item on the item frame. Use the item frame again to retrieve the item.=Wystarczy umieścić dowolny przedmiot na ramie przedmiotu. Użyj ponownie ramki elementu, aby pobrać element. +Can hold an item.=Może pomieścić przedmiot. +Glowing Item Frame=Świecąca ramka na przedmiot +Glowing item frames are decorative blocks in which items can be placed and made to glow.=Świecące ramki na przedmioty to ozdobne bloki, w których można umieścić przedmioty i sprawić, by świeciły. +Can hold an item and glows.=Może trzymać przedmiot i świeci. diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr index 7d3d90cc4..73320ce14 100644 --- a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.ru.tr @@ -1,5 +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=Может хранить предмет +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 diff --git a/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.zh_TW.tr b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.zh_TW.tr new file mode 100644 index 000000000..d45c14d74 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/locale/mcl_itemframes.zh_TW.tr @@ -0,0 +1,5 @@ +# 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=可以展示物品 diff --git a/mods/ITEMS/mcl_itemframes/locale/template.txt b/mods/ITEMS/mcl_itemframes/locale/template.txt index bacbfaa69..bd5ff6f29 100644 --- a/mods/ITEMS/mcl_itemframes/locale/template.txt +++ b/mods/ITEMS/mcl_itemframes/locale/template.txt @@ -2,4 +2,9 @@ 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= +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.= diff --git a/mods/ITEMS/mcl_itemframes/mod.conf b/mods/ITEMS/mcl_itemframes/mod.conf new file mode 100644 index 000000000..f9421e657 --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/mod.conf @@ -0,0 +1,2 @@ +name = mcl_itemframes +depends = mcl_core, mcl_sounds, mcl_compass, mcl_maps, screwdriver diff --git a/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj new file mode 100644 index 000000000..d0a5b0c5f --- /dev/null +++ b/mods/ITEMS/mcl_itemframes/models/mcl_itemframes_glow_item_frame.obj @@ -0,0 +1,156 @@ +# Blender v2.76 (sub 0) OBJ File: 'itemframe1facedir.blend' +# www.blender.org +mtllib itemframe1facedir.mtl +o right.frame_Cube.005 +v -0.313413 -0.313413 0.435326 +v -0.313413 0.313413 0.435326 +v -0.313413 -0.313413 0.498008 +v -0.313413 0.313413 0.498008 +v -0.376095 -0.313413 0.435326 +v -0.376095 0.313413 0.435326 +v -0.376095 -0.313413 0.498008 +v -0.376095 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 2/1/1 4/2/1 3/3/1 1/4/1 +f 4/1/2 8/2/2 7/3/2 3/4/2 +f 8/5/3 6/6/3 5/7/3 7/8/3 +f 6/1/4 2/2/4 1/3/4 5/4/4 +f 1/9/5 3/10/5 7/11/5 5/12/5 +f 6/9/6 8/10/6 4/11/6 2/12/6 +o left.frame_Cube.004 +v 0.376095 -0.313413 0.435326 +v 0.376095 0.313413 0.435326 +v 0.376095 -0.313413 0.498008 +v 0.376095 0.313413 0.498008 +v 0.313413 -0.313413 0.435326 +v 0.313413 0.313413 0.435326 +v 0.313413 -0.313413 0.498008 +v 0.313413 0.313413 0.498008 +vt 0.875000 0.812500 +vt 0.812500 0.812500 +vt 0.812500 0.187500 +vt 0.875000 0.187500 +vt 1.000000 0.812500 +vt 0.937500 0.812500 +vt 0.937500 0.187500 +vt 1.000000 0.187500 +vt -0.000000 0.937500 +vt 0.062500 0.937500 +vt 0.062500 1.000000 +vt -0.000000 1.000000 +vn 1.000000 0.000000 -0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn 0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 -0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 10/13/7 12/14/7 11/15/7 9/16/7 +f 12/13/8 16/14/8 15/15/8 11/16/8 +f 16/17/9 14/18/9 13/19/9 15/20/9 +f 14/13/10 10/14/10 9/15/10 13/16/10 +f 9/21/11 11/22/11 15/23/11 13/24/11 +f 14/21/12 16/22/12 12/23/12 10/24/12 +o lower.frame_Cube.003 +v 0.376095 -0.376095 0.435326 +v 0.376095 -0.313413 0.435326 +v 0.376095 -0.376095 0.498008 +v 0.376095 -0.313413 0.498008 +v -0.376095 -0.376095 0.435326 +v -0.376095 -0.313413 0.435326 +v -0.376095 -0.376095 0.498008 +v -0.376095 -0.313413 0.498008 +vt 0.187500 0.187500 +vt 0.125000 0.187500 +vt 0.125000 0.125000 +vt 0.187500 0.125000 +vt 0.875000 0.187500 +vt 0.875000 0.125000 +vt 0.812500 0.187500 +vt 0.812500 0.125000 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 18/25/13 20/26/13 19/27/13 17/28/13 +f 20/29/14 24/26/14 23/27/14 19/30/14 +f 24/29/15 22/31/15 21/32/15 23/30/15 +f 22/29/16 18/26/16 17/27/16 21/30/16 +f 17/33/17 19/34/17 23/35/17 21/36/17 +f 22/30/18 24/29/18 20/26/18 18/27/18 +o upper.frame_Cube.002 +v 0.376095 0.313413 0.435326 +v 0.376095 0.376095 0.435326 +v 0.376095 0.313413 0.498008 +v 0.376095 0.376095 0.498008 +v -0.376095 0.313413 0.435326 +v -0.376095 0.376095 0.435326 +v -0.376095 0.313413 0.498008 +v -0.376095 0.376095 0.498008 +vt 0.187500 0.875000 +vt 0.125000 0.875000 +vt 0.125000 0.812500 +vt 0.187500 0.812500 +vt 0.875000 0.875000 +vt 0.875000 0.812500 +vt 0.812500 0.875000 +vt 0.812500 0.812500 +vt 0.875000 0.937500 +vt 0.875000 1.000000 +vt 0.125000 1.000000 +vt 0.125000 0.937500 +vn 1.000000 0.000000 0.000000 +vn 0.000000 0.000000 1.000000 +vn -1.000000 0.000000 0.000000 +vn -0.000000 0.000000 -1.000000 +vn 0.000000 -1.000000 0.000000 +vn 0.000000 1.000000 0.000000 +usemtl None +s off +f 26/37/19 28/38/19 27/39/19 25/40/19 +f 28/41/20 32/38/20 31/39/20 27/42/20 +f 32/41/21 30/43/21 29/44/21 31/42/21 +f 30/41/22 26/38/22 25/39/22 29/42/22 +f 25/45/23 27/46/23 31/47/23 29/48/23 +f 30/48/24 32/38/24 28/41/24 26/45/24 +o background_Plane +v 0.313413 -0.313413 0.466667 +v -0.313413 -0.313413 0.466667 +v 0.313413 0.313413 0.466667 +v -0.313413 0.313413 0.466667 +vt 0.187500 0.187500 +vt 0.812500 0.187500 +vt 0.812500 0.812500 +vt 0.187500 0.812500 +vn -0.000000 0.000000 -1.000000 +usemtl None +s off +f 33/49/25 34/50/25 36/51/25 35/52/25 diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_item_frame.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_item_frame.png deleted file mode 100644 index 274749919..000000000 Binary files a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_item_frame.png and /dev/null differ diff --git a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_itemframe_background.png b/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_itemframe_background.png deleted file mode 100644 index d48cf26c5..000000000 Binary files a/mods/ITEMS/mcl_itemframes/textures/mcl_itemframes_itemframe_background.png and /dev/null differ diff --git a/mods/ITEMS/mcl_jukebox/API.md b/mods/ITEMS/mcl_jukebox/API.md new file mode 100644 index 000000000..85900ede0 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/API.md @@ -0,0 +1,18 @@ +# mcl_jukebox + +## mcl_jukebox.register_record(title, author, identifier, image, sound) + +* title: title of the track +* author: author of the track +* identifier: short string used in the item registration +* image: the texture of the track +* sound: sound file of the track + +## mcl_jukebox.registered_records + +Table indexed by item name containing: +* title: title of the track +* author: author of the track +* identifier: short string used in the item registration +* image: the texture of the track +* sound: sound file of the track \ No newline at end of file diff --git a/mods/ITEMS/mcl_jukebox/README.md b/mods/ITEMS/mcl_jukebox/README.md index bc261270a..6376362bb 100644 --- a/mods/ITEMS/mcl_jukebox/README.md +++ b/mods/ITEMS/mcl_jukebox/README.md @@ -10,7 +10,7 @@ to play. And that's it! `mcl_jukebox_track_2.ogg`: “The Energetic Rat (Jordach's Mix)” by SoundHelix (CC0) `mcl_jukebox_track_3.ogg`: “Eastern Feeling” by Jordach (CC0) `mcl_jukebox_track_4.ogg`: “Minetest” by Jordach (CC0) -`mcl_jukebox_track_5.ogg`: “Credit Roll (Jordach's HD Mix)” by Junichi Masuda (CC0) +`mcl_jukebox_track_5.ogg`: "Soaring over the sea" by mactonite http://ccmixter.org/files/mactonite/65379 (CC-BY) `mcl_jukebox_track_6.ogg`: “Winter Feeling" by Tom Peter (CC BY-SA 3.0) `mcl_jukebox_track_7.ogg`: “Synthgroove (Jordach's Mix)” by HeroOfTheWinds (CC0) `mcl_jukebox_track_8.ogg`: “The Clueless Frog (Jordach's Mix)” by SoundHelix (CC0) diff --git a/mods/ITEMS/mcl_jukebox/depends.txt b/mods/ITEMS/mcl_jukebox/depends.txt deleted file mode 100644 index 97bf51069..000000000 --- a/mods/ITEMS/mcl_jukebox/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -mcl_sounds diff --git a/mods/ITEMS/mcl_jukebox/description.txt b/mods/ITEMS/mcl_jukebox/description.txt deleted file mode 100644 index 143812e1d..000000000 --- a/mods/ITEMS/mcl_jukebox/description.txt +++ /dev/null @@ -1 +0,0 @@ -Jukebox and music discs are used to play background music on a per-player basis. diff --git a/mods/ITEMS/mcl_jukebox/init.lua b/mods/ITEMS/mcl_jukebox/init.lua index db9f25312..d817bdac7 100644 --- a/mods/ITEMS/mcl_jukebox/init.lua +++ b/mods/ITEMS/mcl_jukebox/init.lua @@ -1,4 +1,10 @@ -local S = minetest.get_translator("mcl_jukebox") +local S = minetest.get_translator(minetest.get_current_modname()) +local C = minetest.colorize + +local math = math + +mcl_jukebox = {} +mcl_jukebox.registered_records = {} -- Player name-indexed table containing the currently heard track local active_tracks = {} @@ -10,47 +16,30 @@ local active_huds = {} -- Used to make sure that minetest.after only applies to the latest HUD change event local hud_sequence_numbers = {} --- List of music -local recorddata = { - -- { title, author, identifier } - { "The Evil Sister (Jordach's Mix)", "SoundHelix", "13" } , - { "The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait" }, - { "Eastern Feeling", "Jordach", "blocks"}, - { "Minetest", "Jordach", "far" }, - { "Credit Roll (Jordach's HD Mix)", "Junichi Masuda", "chirp" }, - { "Winter Feeling", "Tom Peter", "strad" }, - { "Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi" }, - { "The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall" }, -} -local records = #recorddata - -for r=1, records do - local doc = false - local entryname, longdesc, usagehelp - if r == 1 then - doc = true - entryname = S("Music Disc") - longdesc = S("A music disc holds a single music track which can be used in a jukebox to play music.") - usagehelp = S("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.") - end - minetest.register_craftitem("mcl_jukebox:record_"..r, { +function mcl_jukebox.register_record(title, author, identifier, image, sound) + mcl_jukebox.registered_records["mcl_jukebox:record_"..identifier] = {title, author, identifier, image, sound} + local entryname = S("Music Disc") + local longdesc = S("A music disc holds a single music track which can be used in a jukebox to play music.") + local usagehelp = S("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.") + minetest.register_craftitem(":mcl_jukebox:record_"..identifier, { description = - core.colorize("#55FFFF", S("Music Disc")) .. "\n" .. - core.colorize("#989898", S("@1—@2", recorddata[r][2], recorddata[r][1])), - _doc_items_create_entry = doc, + C(mcl_colors.AQUA, S("Music Disc")) .. "\n" .. + C(mcl_colors.GRAY, S("@1—@2", author, title)), + _doc_items_create_entry = true, _doc_items_entry_name = entryname, _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - inventory_image = "mcl_jukebox_record_"..recorddata[r][3]..".png", + --inventory_image = "mcl_jukebox_record_"..recorddata[r][3]..".png", + inventory_image = image, stack_max = 1, - groups = { music_record = r }, + groups = { music_record = 1 }, }) end -local function now_playing(player, track_id) +local function now_playing(player, name) local playername = player:get_player_name() local hud = active_huds[playername] - local text = S("Now playing: @1—@2", recorddata[track_id][2], recorddata[track_id][1]) + local text = S("Now playing: @1—@2", mcl_jukebox.registered_records[name][2], mcl_jukebox.registered_records[name][1]) if not hud_sequence_numbers[playername] then hud_sequence_numbers[playername] = 1 @@ -59,7 +48,7 @@ local function now_playing(player, track_id) end local id - if hud ~= nil then + if hud then id = hud player:hud_change(id, "text", text) else @@ -81,12 +70,11 @@ local function now_playing(player, track_id) if not player or not player:is_player() or not active_huds[playername] or not hud_sequence_numbers[playername] or seq ~= hud_sequence_numbers[playername] then return end - if id ~= nil and id == active_huds[playername] then + if id and id == active_huds[playername] then player:hud_remove(active_huds[playername]) active_huds[playername] = nil end end, {playername, id, hud_sequence_numbers[playername]}) - end minetest.register_on_leaveplayer(function(player) @@ -97,27 +85,29 @@ end) -- Jukebox crafting minetest.register_craft({ - output = 'mcl_jukebox:jukebox', + output = "mcl_jukebox:jukebox", recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'group:wood', 'mcl_core:diamond', 'group:wood'}, - {'group:wood', 'group:wood', 'group:wood'}, + {"group:wood", "group:wood", "group:wood"}, + {"group:wood", "mcl_core:diamond", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, } }) -local play_record = function(pos, itemstack, player) - local record_id = minetest.get_item_group(itemstack:get_name(), "music_record") - if record_id ~= 0 then +local function play_record(pos, itemstack, player) + local item_name = itemstack:get_name() + -- ensure the jukebox uses the new record names for old records + local name = minetest.registered_aliases[item_name] or item_name + if mcl_jukebox.registered_records[name] then local cname = player:get_player_name() - if active_tracks[cname] ~= nil then + if active_tracks[cname] then minetest.sound_stop(active_tracks[cname]) active_tracks[cname] = nil end - active_tracks[cname] = minetest.sound_play("mcl_jukebox_track_"..record_id, { + active_tracks[cname] = minetest.sound_play(mcl_jukebox.registered_records[name][5], { to_player = cname, gain = 1, }) - now_playing(player, record_id) + now_playing(player, name) return true end return false @@ -149,7 +139,7 @@ minetest.register_node("mcl_jukebox:jukebox", { local inv = meta:get_inventory() if not inv:is_empty("main") then -- Jukebox contains a disc: Stop music and remove disc - if active_tracks[cname] ~= nil then + if active_tracks[cname] then minetest.sound_stop(active_tracks[cname]) end local lx = pos.x @@ -160,11 +150,11 @@ minetest.register_node("mcl_jukebox:jukebox", { -- Rotate record to match with “slot” texture dropped_item:set_yaw(math.pi/2) inv:set_stack("main", 1, "") - if active_tracks[cname] ~= nil then + if active_tracks[cname] then minetest.sound_stop(active_tracks[cname]) active_tracks[cname] = nil end - if active_huds[cname] ~= nil then + if active_huds[cname] then clicker:hud_remove(active_huds[cname]) active_huds[cname] = nil end @@ -219,11 +209,11 @@ minetest.register_node("mcl_jukebox:jukebox", { local dropped_item = minetest.add_item(p, stack) -- Rotate record to match with “slot” texture dropped_item:set_yaw(math.pi/2) - if active_tracks[name] ~= nil then + if active_tracks[name] then minetest.sound_stop(active_tracks[name]) active_tracks[name] = nil end - if active_huds[name] ~= nil then + if active_huds[name] then digger:hud_remove(active_huds[name]) active_huds[name] = nil end @@ -239,3 +229,22 @@ minetest.register_craft({ recipe = "mcl_jukebox:jukebox", burntime = 15, }) + +mcl_jukebox.register_record("The Evil Sister (Jordach's Mix)", "SoundHelix", "13", "mcl_jukebox_record_13.png", "mcl_jukebox_track_1") +mcl_jukebox.register_record("The Energetic Rat (Jordach's Mix)", "SoundHelix", "wait", "mcl_jukebox_record_wait.png", "mcl_jukebox_track_2") +mcl_jukebox.register_record("Eastern Feeling", "Jordach", "blocks", "mcl_jukebox_record_blocks.png", "mcl_jukebox_track_3") +mcl_jukebox.register_record("Minetest", "Jordach", "far", "mcl_jukebox_record_far.png", "mcl_jukebox_track_4") +mcl_jukebox.register_record("Soaring over the sea", "mactonite", "chirp", "mcl_jukebox_record_chirp.png", "mcl_jukebox_track_5") +mcl_jukebox.register_record("Winter Feeling", "Tom Peter", "strad", "mcl_jukebox_record_strad.png", "mcl_jukebox_track_6") +mcl_jukebox.register_record("Synthgroove (Jordach's Mix)", "HeroOfTheWinds", "mellohi", "mcl_jukebox_record_mellohi.png", "mcl_jukebox_track_7") +mcl_jukebox.register_record("The Clueless Frog (Jordach's Mix)", "SoundHelix", "mall", "mcl_jukebox_record_mall.png", "mcl_jukebox_track_8") + +--add backward compatibility +minetest.register_alias("mcl_jukebox:record_1", "mcl_jukebox:record_13") +minetest.register_alias("mcl_jukebox:record_2", "mcl_jukebox:record_wait") +minetest.register_alias("mcl_jukebox:record_3", "mcl_jukebox:record_blocks") +minetest.register_alias("mcl_jukebox:record_4", "mcl_jukebox:record_far") +minetest.register_alias("mcl_jukebox:record_5", "mcl_jukebox:record_chirp") +minetest.register_alias("mcl_jukebox:record_6", "mcl_jukebox:record_strad") +minetest.register_alias("mcl_jukebox:record_7", "mcl_jukebox:record_mellohi") +minetest.register_alias("mcl_jukebox:record_8", "mcl_jukebox:record_mall") \ No newline at end of file diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr new file mode 100644 index 000000000..7f62b5625 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.ja.tr @@ -0,0 +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.=音楽ディスクには1曲の音楽が収録されており、ジュークボックスで音楽を再生するのに使用できます。 +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.=空のジュークボックスに音楽ディスクを入れると、音楽が再生されます。すでに音楽ディスクが入っている場合は、まずその音楽ディスクを取り出します。音楽は自分だけが聴くことができ、他のプレーヤーは聴くことができません。 +Now playing: @1—@2=再生中: @1—@2 +Uses music discs to play music=音楽再生に音楽ディスクを使用 diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pl.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pl.tr new file mode 100644 index 000000000..a0c2eccd5 --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.pl.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_jukebox +Music Disc=Płyta z muzyką +A music disc holds a single music track which can be used in a jukebox to play music.=Płyta z muzyką zawiera ścieżkę muzyczną, którą można użyć na szafie grającej aby włączyć muzykę. +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.=Włóż płyty z muzyką do pustej szafy grającej aby włączyć muzykę. Kliknij użycie na szafie grającej ponownie, aby odzyskać płytę. Muzyka jest słyszalna tylko przez ciebie, nie przez innych graczy. +Music Disc=Płyta z muzyką +@1—@2=@1-@2 +Jukebox=Szafa grająca +Jukeboxes play music when they're supplied with a music disc.=Szafa grająca gra muzykę, gdy ma w sobie płytę z muzyką. +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.=Włóż płytę z muzyką do szafy grającej aby muzyka zaczęła grać. Jeśli w szafie grającej jest już płyta odzyskasz najpierw tę muzykę. Muzyka będzie słyszalna tylko przez ciebie, nie przez innych graczy. +Now playing: @1—@2=Aktualna muzyka: @1—@2 +Uses music discs to play music=Używa płyt z muzyką by odtwarzać muzykę diff --git a/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.zh_TW.tr b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.zh_TW.tr new file mode 100644 index 000000000..ba48ae9de --- /dev/null +++ b/mods/ITEMS/mcl_jukebox/locale/mcl_jukebox.zh_TW.tr @@ -0,0 +1,10 @@ +# 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.=將唱片放入空的唱片機中播放音樂。再次使用唱片機取出唱片。音樂只能由您自己聽,而不能由其他玩家聽。 +@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.=將音樂光盤放入空的點唱機,插入音樂光盤並播放音樂。如果點唱機已經有一張音樂光盤,你要先取回這張音樂光盤。音樂只能被你聽到,不能被其他玩家聽到。 +Now playing: @1—@2=正在播放:@1—@2 +Uses music discs to play music=使用唱片播放音樂 diff --git a/mods/ITEMS/mcl_jukebox/mod.conf b/mods/ITEMS/mcl_jukebox/mod.conf index ec39a7be9..9046ff7d3 100644 --- a/mods/ITEMS/mcl_jukebox/mod.conf +++ b/mods/ITEMS/mcl_jukebox/mod.conf @@ -1 +1,3 @@ name = mcl_jukebox +description = Jukebox and music discs are used to play background music on a per-player basis. +depends = mcl_core, mcl_sounds, mcl_colors diff --git a/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg b/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg index dcad499d9..0a635207c 100644 Binary files a/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg and b/mods/ITEMS/mcl_jukebox/sounds/mcl_jukebox_track_5.ogg differ diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_top.png b/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_top.png deleted file mode 100644 index 66c3332e6..000000000 Binary files a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_lanterns/init.lua b/mods/ITEMS/mcl_lanterns/init.lua new file mode 100644 index 000000000..5be325e48 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/init.lua @@ -0,0 +1,292 @@ +local S = minetest.get_translator("mcl_lanterns") +local modpath = minetest.get_modpath("mcl_lanterns") + +mcl_lanterns = {} + +--[[ +TODO: +- add lantern specific sounds +- remove the hack arround walmounted nodes +]] + +local allowed_non_solid_nodes_floor = { + "mcl_core:ice", + "mcl_nether:soul_sand", + "mcl_mobspawners:spawner", + "mcl_core:barrier", + "mcl_end:chorus_flower", + "mcl_end:chorus_flower_dead", + "mcl_end:end_rod", + "mcl_end:dragon_egg", + "mcl_portals:end_portal_frame_eye", + "mcl_lanterns:chain" +} +-- The function below allows nodes that call it to be included in the 'allowed floor placement' list above. This lets lanterns be placed on top of said nodes. Most useful for modded in nodes. +function mcl_lanterns.add_allowed_non_solid_nodes_floor (node_name) + table.insert (allowed_non_solid_nodes_floor, node_name) +end + +local allowed_non_solid_groups_floor = {"anvil", "wall", "glass", "fence", "fence_gate", "pane"} + +local allowed_non_solid_nodes_ceiling = { + "mcl_core:ice", + "mcl_nether:soul_sand", + "mcl_mobspawners:spawner", + "mcl_core:barrier", + "mcl_end:chorus_flower", + "mcl_end:chorus_flower_dead", + "mcl_end:end_rod", + "mcl_core:grass_path", + "mcl_lanterns:chain" +} +-- The function below allows nodes that call it to be included in the 'allowed ceiling placement' list above. This lets lanterns be placed below said nodes. Most useful for modded in nodes. +function mcl_lanterns.add_allowed_non_solid_nodes_ceiling (node_name) + table.insert (allowed_non_solid_nodes_ceiling, node_name) +end + +local allowed_non_solid_groups_ceiling = {"anvil", "wall", "glass", "fence", "fence_gate", "soil", "pane", "end_portal_frame"} + +local function check_placement(node, wdir) + local nn = node.name + local def = minetest.registered_nodes[nn] + + if not def then + return false + else + --wdir: + --0: ceiling + --1: floor + if wdir == 0 then + if def.groups.solid or def.groups.opaque then + return true + else + for _,i in ipairs(allowed_non_solid_nodes_ceiling) do + if nn == i then + return true + end + end + for _,j in ipairs(allowed_non_solid_groups_ceiling) do + if def.groups[j] then + return true + end + end + return false + end + else --assuming wdir == 1 + if def.groups.solid or def.groups.opaque then + return true + else + for _,i in ipairs(allowed_non_solid_nodes_floor) do + if nn == i then + return true + end + end + for _,j in ipairs(allowed_non_solid_groups_floor) do + if def.groups[j] then + return true + end + end + return false + end + end + end +end + +function mcl_lanterns.register_lantern(name, def) + local itemstring_floor = "mcl_lanterns:"..name.."_floor" + local itemstring_ceiling = "mcl_lanterns:"..name.."_ceiling" + + local sounds = mcl_sounds.node_sound_metal_defaults() + + minetest.register_node(":"..itemstring_floor, { + description = def.description, + _doc_items_longdesc = def.longdesc, + drawtype = "mesh", + mesh = "mcl_lanterns_lantern_floor.obj", + inventory_image = def.texture_inv, + wield_image = def.texture_inv, + tiles = { + { + name = def.texture, + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + } + }, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "wallmounted", + place_param2 = 1, + node_placement_prediction = "", + sunlight_propagates = true, + light_source = def.light_level, + groups = {pickaxey = 1, attached_node = 1, deco_block = 1, lantern = 1}, + selection_box = { + type = "fixed", + fixed = { + {-0.1875, -0.5, -0.1875, 0.1875, -0.0625, 0.1875}, + {-0.125, -0.0625, -0.125, 0.125, 0.0625, 0.125}, + {-0.0625, -0.5, -0.0625, 0.0625, 0.1875, 0.0625}, + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.1875, -0.5, -0.1875, 0.1875, -0.0625, 0.1875}, + {-0.125, -0.0625, -0.125, 0.125, 0.0625, 0.125}, + {-0.0625, -0.5, -0.0625, 0.0625, 0.1875, 0.0625}, + }, + }, + sounds = sounds, + on_place = function(itemstack, placer, pointed_thing) + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack + end + + local under = pointed_thing.under + local above = pointed_thing.above + local node = minetest.get_node(under) + + local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above)) + local fakestack = itemstack + + if check_placement(node, wdir) == false then + return itemstack + end + + if wdir == 0 then + fakestack:set_name(itemstring_ceiling) + elseif wdir == 1 then + fakestack:set_name(itemstring_floor) + end + + local success + itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name(itemstring_floor) + + if success then + minetest.sound_play(sounds.place, {pos = under, gain = 1}, true) + end + + return itemstack + end, + on_rotate = false, + _mcl_hardness = 3.5, + _mcl_blast_resistance = 3.5, + }) + + minetest.register_node(":"..itemstring_ceiling, { + description = def.description, + _doc_items_create_entry = false, + drawtype = "mesh", + mesh = "mcl_lanterns_lantern_ceiling.obj", + tiles = { + { + name = def.texture, + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + } + }, + use_texture_alpha = "clip", + paramtype = "light", + paramtype2 = "wallmounted", + place_param2 = 0, + node_placement_prediction = "", + sunlight_propagates = true, + light_source = def.light_level, + groups = {pickaxey = 1, attached_node = 1, deco_block = 1, lantern = 1, not_in_creative_inventory = 1}, + drop = itemstring_floor, + selection_box = { + type = "fixed", + fixed = { + {-0.1875, 0, -0.1875, 0.1875, 0.4375, 0.1875}, + {-0.125, -0.125, -0.125, 0.125, 0, 0.125}, + {-0.0625, -0.5, -0.0625, 0.0625, -0.125, 0.0625}, + }, + }, + collision_box = { + type = "fixed", + fixed = { + {-0.1875, 0, -0.1875, 0.1875, 0.4375, 0.1875}, + {-0.125, -0.125, -0.125, 0.125, 0, 0.125}, + {-0.0625, -0.5, -0.0625, 0.0625, -0.125, 0.0625}, + }, + }, + sounds = sounds, + on_rotate = false, + _mcl_hardness = 3.5, + _mcl_blast_resistance = 3.5, + }) +end + +minetest.register_node("mcl_lanterns:chain", { + description = S("Chain"), + _doc_items_longdesc = S("Chains are metallic decoration blocks."), + inventory_image = "mcl_lanterns_chain_inv.png", + tiles = {"mcl_lanterns_chain.png"}, + drawtype = "mesh", + paramtype = "light", + paramtype2 = "facedir", + use_texture_alpha = "clip", + mesh = "mcl_lanterns_chain.obj", + is_ground_content = false, + sunlight_propagates = true, + collision_box = { + type = "fixed", + fixed = { + {-0.0625, -0.5, -0.0625, 0.0625, 0.5, 0.0625}, + } + }, + selection_box = { + type = "fixed", + fixed = { + {-0.0625, -0.5, -0.0625, 0.0625, 0.5, 0.0625}, + } + }, + groups = {pickaxey = 1, deco_block = 1}, + sounds = mcl_sounds.node_sound_metal_defaults(), + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local p0 = pointed_thing.under + local p1 = pointed_thing.above + local param2 = 0 + + local placer_pos = placer:get_pos() + if placer_pos then + local dir = { + x = p1.x - placer_pos.x, + y = p1.y - placer_pos.y, + z = p1.z - placer_pos.z + } + param2 = minetest.dir_to_facedir(dir) + end + + if p0.y - 1 == p1.y then + param2 = 20 + elseif p0.x - 1 == p1.x then + param2 = 16 + elseif p0.x + 1 == p1.x then + param2 = 12 + elseif p0.z - 1 == p1.z then + param2 = 8 + elseif p0.z + 1 == p1.z then + param2 = 4 + end + + return minetest.item_place(itemstack, placer, pointed_thing, param2) + end, + _mcl_blast_resistance = 6, + _mcl_hardness = 5, +}) + +minetest.register_craft({ + output = "mcl_lanterns:chain", + recipe = { + {"mcl_core:iron_nugget"}, + {"mcl_core:iron_ingot"}, + {"mcl_core:iron_nugget"}, + }, +}) + +dofile(modpath.."/register.lua") diff --git a/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.fr.tr b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.fr.tr new file mode 100644 index 000000000..b28822b75 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.fr.tr @@ -0,0 +1,6 @@ +# textdomain: mcl_lanterns +Lantern=Lanterne +Soul Lantern=Lanterne des âmes +Lanterns are light sources which can be placed on the top or the bottom of most blocks.=Les lanternes sont des blocs lumineux qui peuvent être placés au dessus ou en dessous de la plupart des blocs. +Chain=Chaîne +Chains are metallic decoration blocks.=La chaîne est un bloc de décoration métalique. \ No newline at end of file diff --git a/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.tr b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.tr new file mode 100644 index 000000000..2d403d9d9 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/mcl_lanterns.ja.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_lanterns/locale/template.txt b/mods/ITEMS/mcl_lanterns/locale/template.txt new file mode 100644 index 000000000..545118b54 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/locale/template.txt @@ -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_lanterns/mod.conf b/mods/ITEMS/mcl_lanterns/mod.conf new file mode 100644 index 000000000..746ffcb15 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/mod.conf @@ -0,0 +1,6 @@ +name = mcl_lanterns +description = Add lanterns and chains to MineClone2 +depends = mcl_sounds +optional_depends = +author = AFCMS +title = MineClone2 Lanterns \ No newline at end of file diff --git a/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_chain.obj b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_chain.obj new file mode 100644 index 000000000..94a7b8971 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_chain.obj @@ -0,0 +1,24 @@ +# Blender v3.0.1 OBJ File: 'chain.blend' +# www.blender.org +o Plane +v 0.066291 0.500000 0.066291 +v 0.066291 -0.500000 0.066291 +v -0.066291 0.500000 -0.066291 +v -0.066291 -0.500000 -0.066291 +v -0.066291 0.500000 0.066291 +v -0.066291 -0.500000 0.066291 +v 0.066291 0.500000 -0.066291 +v 0.066291 -0.500000 -0.066291 +vt -0.000000 1.000000 +vt 0.000000 -0.000000 +vt 0.187500 0.000000 +vt 0.187500 1.000000 +vt 0.187500 1.000000 +vt 0.187500 -0.000000 +vt 0.375000 -0.000000 +vt 0.375000 1.000000 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +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 diff --git a/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_ceiling.obj b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_ceiling.obj new file mode 100644 index 000000000..7079aa7cb --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_ceiling.obj @@ -0,0 +1,104 @@ +# Blender v3.0.1 OBJ File: 'lantern.blend' +# www.blender.org +o Lantern_Ceiling +v 0.187500 -0.000000 0.187500 +v 0.187500 0.437500 0.187500 +v 0.187500 0.000000 -0.187500 +v 0.187500 0.437500 -0.187500 +v -0.187500 -0.000000 0.187500 +v -0.187500 0.437500 0.187500 +v -0.187500 0.000000 -0.187500 +v -0.187500 0.437500 -0.187500 +v 0.125000 -0.125000 0.125000 +v 0.125000 -0.000000 0.125000 +v 0.125000 -0.125000 -0.125000 +v 0.125000 0.000000 -0.125000 +v -0.125000 -0.125000 0.125000 +v -0.125000 -0.000000 0.125000 +v -0.125000 -0.125000 -0.125000 +v -0.125000 0.000000 -0.125000 +v 0.066291 -0.500000 -0.066291 +v 0.066291 -0.125000 -0.066291 +v -0.066291 -0.500000 0.066291 +v -0.066291 -0.125000 0.066291 +v -0.066291 -0.500000 -0.066291 +v -0.066291 -0.125000 -0.066291 +v 0.066291 -0.500000 0.066291 +v 0.066291 -0.125000 0.066291 +vt 0.000000 0.062500 +vt 0.375000 0.062500 +vt 0.375000 0.437500 +vt 0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt -0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt 0.000000 0.437500 +vt 0.000000 0.062500 +vt 0.375000 0.062500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt 0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt -0.000000 0.437500 +vt 0.062500 0.125000 +vt 0.312500 0.125000 +vt 0.312500 0.375000 +vt 0.062500 0.375000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.687500 0.625000 +vt 0.687500 0.250000 +vt 0.875000 0.250000 +vt 0.875000 0.625000 +vt 0.687500 1.000000 +vt 0.687500 0.625000 +vt 0.875000 0.625000 +vt 0.875000 1.000000 +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 +vn 0.7071 -0.0000 0.7071 +vn 0.7071 0.0000 -0.7071 +s off +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/5/4 8/8/4 +f 2/15/5 1/16/5 3/17/5 4/18/5 +f 6/19/6 5/20/6 1/21/6 2/22/6 +f 9/23/1 13/24/1 15/25/1 11/26/1 +f 12/27/2 11/28/2 15/29/2 16/30/2 +f 16/31/3 15/32/3 13/33/3 14/34/3 +f 14/35/4 10/36/4 12/37/4 16/38/4 +f 10/39/5 9/40/5 11/41/5 12/42/5 +f 14/43/6 13/44/6 9/45/6 10/46/6 +f 17/47/7 18/48/7 20/49/7 19/50/7 +f 21/51/8 22/52/8 24/53/8 23/54/8 diff --git a/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_floor.obj b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_floor.obj new file mode 100644 index 000000000..c90ece680 --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/models/mcl_lanterns_lantern_floor.obj @@ -0,0 +1,104 @@ +# Blender v3.0.1 OBJ File: 'lantern.blend' +# www.blender.org +o Lantern_Floor +v 0.187500 -0.062500 -0.187500 +v 0.187500 -0.500000 -0.187500 +v 0.187500 -0.062500 0.187500 +v 0.187500 -0.500000 0.187500 +v -0.187500 -0.062500 -0.187500 +v -0.187500 -0.500000 -0.187500 +v -0.187500 -0.062500 0.187500 +v -0.187500 -0.500000 0.187500 +v 0.125000 0.062500 -0.125000 +v 0.125000 -0.062500 -0.125000 +v 0.125000 0.062500 0.125000 +v 0.125000 -0.062500 0.125000 +v -0.125000 0.062500 -0.125000 +v -0.125000 -0.062500 -0.125000 +v -0.125000 0.062500 0.125000 +v -0.125000 -0.062500 0.125000 +v 0.066291 0.187500 0.066291 +v 0.066291 0.062500 0.066291 +v -0.066291 0.187500 -0.066291 +v -0.066291 0.062500 -0.066291 +v -0.066291 0.187500 0.066291 +v -0.066291 0.062500 0.066291 +v 0.066291 0.187500 -0.066291 +v 0.066291 0.062500 -0.066291 +vt 0.000000 0.062500 +vt 0.375000 0.062500 +vt 0.375000 0.437500 +vt 0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt -0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt 0.000000 0.437500 +vt 0.000000 0.062500 +vt 0.375000 0.062500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt 0.000000 0.437500 +vt 0.375000 0.437500 +vt 0.375000 0.875000 +vt -0.000000 0.875000 +vt -0.000000 0.437500 +vt 0.062500 0.125000 +vt 0.312500 0.125000 +vt 0.312500 0.375000 +vt 0.062500 0.375000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.500000 0.770833 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.312500 0.875000 +vt 0.312500 1.000000 +vt 0.062500 1.000000 +vt 0.062500 0.875000 +vt 0.687500 0.937500 +vt 0.687500 0.812500 +vt 0.875000 0.812500 +vt 0.875000 0.937500 +vt 0.687500 0.937500 +vt 0.687500 0.812500 +vt 0.875000 0.812500 +vt 0.875000 0.937500 +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 +vn 0.7071 0.0000 -0.7071 +vn 0.7071 0.0000 0.7071 +s off +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/5/4 8/8/4 +f 2/15/5 1/16/5 3/17/5 4/18/5 +f 6/19/6 5/20/6 1/21/6 2/22/6 +f 9/23/1 13/24/1 15/25/1 11/26/1 +f 12/27/2 11/28/2 15/29/2 16/30/2 +f 16/31/3 15/32/3 13/33/3 14/34/3 +f 14/35/4 10/36/4 12/37/4 16/38/4 +f 10/39/5 9/40/5 11/41/5 12/42/5 +f 14/43/6 13/44/6 9/45/6 10/46/6 +f 17/47/7 18/48/7 20/49/7 19/50/7 +f 21/51/8 22/52/8 24/53/8 23/54/8 diff --git a/mods/ITEMS/mcl_lanterns/register.lua b/mods/ITEMS/mcl_lanterns/register.lua new file mode 100644 index 000000000..86305052b --- /dev/null +++ b/mods/ITEMS/mcl_lanterns/register.lua @@ -0,0 +1,35 @@ +local S = minetest.get_translator("mcl_lanterns") + +mcl_lanterns.register_lantern("lantern", { + description = S("Lantern"), + longdesc = S("Lanterns are light sources which can be placed on the top or the bottom of most blocks."), + texture = "mcl_lanterns_lantern.png", + texture_inv = "mcl_lanterns_lantern_inv.png", + light_level = 14, +}) + +mcl_lanterns.register_lantern("soul_lantern", { + description = S("Soul Lantern"), + longdesc = S("Lanterns are light sources which can be placed on the top or the bottom of most blocks."), + texture = "mcl_lanterns_soul_lantern.png", + texture_inv = "mcl_lanterns_soul_lantern_inv.png", + light_level = 10, +}) + +minetest.register_craft({ + output = "mcl_lanterns:lantern_floor", + recipe = { + {"mcl_core:iron_nugget", "mcl_core:iron_nugget", "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_torches:torch" , "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_core:iron_nugget", "mcl_core:iron_nugget"}, + }, +}) + +minetest.register_craft({ + output = "mcl_lanterns:soul_lantern_floor", + recipe = { + {"mcl_core:iron_nugget", "mcl_core:iron_nugget" , "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_blackstone:soul_torch" , "mcl_core:iron_nugget"}, + {"mcl_core:iron_nugget", "mcl_core:iron_nugget" , "mcl_core:iron_nugget"}, + }, +}) diff --git a/mods/ITEMS/mcl_lectern/License.txt b/mods/ITEMS/mcl_lectern/License.txt new file mode 100644 index 000000000..36caec951 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/License.txt @@ -0,0 +1,226 @@ + +GNU GENERAL PUBLIC LICENSE + +Version 3, 29 June 2007 + +Copyright © 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/ITEMS/mcl_lectern/README.txt b/mods/ITEMS/mcl_lectern/README.txt new file mode 100644 index 000000000..8afe7108e --- /dev/null +++ b/mods/ITEMS/mcl_lectern/README.txt @@ -0,0 +1,15 @@ + +--- +# Mineclone2-Lectern +--- +A ground up creation of a lectern to be used in MineClone 2. Requires Minetest and Mineclone2. +--- + +Created by Michieal (FaerRaven) @ DateTime: 01/07/2023 (07JAN2023) + +* Made for MineClone 2 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) +* License for Code: GPL3 +* License for Media: CC-BY-SA 4 diff --git a/mods/ITEMS/mcl_lectern/init.lua b/mods/ITEMS/mcl_lectern/init.lua new file mode 100644 index 000000000..98366b7b8 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/init.lua @@ -0,0 +1,140 @@ +-- Made for MineClone 2 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) +-- License for Code: GPL3 +-- License for Media: CC-BY-SA 4 +-- Copyright (C) 2023, Michieal. See: License.txt. + +-- LOCALS +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local node_sound = mcl_sounds.node_sound_wood_defaults() +local pi = 3.1415926 + +local lectern_def = { + description = S("Lectern"), + _tt_help = S("Lecterns not only look good, but are job site blocks for Librarians."), + _doc_items_longdesc = S("Lecterns not only look good, but are job site blocks for Librarians."), + _doc_items_usagehelp = S("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'."), + sounds = node_sound, + paramtype = "light", + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, + paramtype2 = "facedir", + drawtype = "mesh", + -- visual_scale = 1.0, -- Default is 1.0. + mesh = "mcl_lectern_lectern.obj", + tiles = {"mcl_lectern_lectern.png", }, + groups = {handy = 1, axey = 1, flammable = 2, fire_encouragement = 5, fire_flammability = 5, solid = 1}, + drops = "mcl_lectern:lectern", + sunlight_propagates = true, + walkable = true, + is_ground_content = false, + node_placement_prediction = "", + _mcl_blast_resistance = 3, + _mcl_hardness = 2, + selection_box = { + type = "fixed", + fixed = { + -- L, T, Ba, R, Bo, F. + {-0.32, 0.46, -0.32, 0.32, 0.175, 0.32}, + {-0.18, 0.175, -0.055, 0.18, -0.37, 0.21}, + {-0.32, -0.37, -0.32, 0.32, -0.5, 0.32}, + } + }, + collision_box = { + type = "fixed", + fixed = { + -- L, T, Ba, R, Bo, F. + {-0.32, 0.46, -0.32, 0.32, 0.175, 0.32}, + {-0.18, 0.175, -0.055, 0.18, -0.37, 0.21}, + {-0.32, -0.37, -0.32, 0.32, -0.5, 0.32}, + } + }, + + on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + local pos = under + local pname = placer:get_player_name() + if minetest.is_protected(pos, pname) then + minetest.record_protection_violation(pos, pname) + 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 + local dir = vector.subtract(under, above) + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + if wdir == 0 then + return itemstack + -- IE., no Hanging Lecterns for you! + end + if wdir == 1 then + -- (only make standing nodes...) + -- Determine the rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Convert to 16 dir. + local rotation_level = math.round((yaw / (pi * 2)) * 16) + + -- put the rotation level within bounds. + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + fdir = math.floor(rotation_level / 4) -- collapse that to 4 dir. + local lectern_node = ItemStack(itemstack) + -- Place the node! + local _, success = minetest.item_place_node(lectern_node, placer, pointed_thing, fdir) + + -- Add placement sound. + local idef = lectern_node:get_definition() + if success then + if idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=above, gain=1}, true) + end + end + + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + end + return itemstack + end, +} + +minetest.register_node("mcl_lectern:lectern", lectern_def) +mcl_wip.register_wip_item("mcl_lectern:lectern") + +-- April Fools setup +local date = os.date("*t") +if (date.month == 4 and date.day == 1) then + minetest.override_item("mcl_lectern:lectern", {waving = 2}) +else + minetest.override_item("mcl_lectern:lectern", {waving = 0}) +end + +minetest.register_craft({ + output = "mcl_lectern:lectern", + recipe = { + {"group:wood_slab", "group:wood_slab", "group:wood_slab"}, + {"", "mcl_books:bookshelf", ""}, + {"", "group:wood_slab", ""}, + } +}) + +-- Base Aliases. +minetest.register_alias("lectern", "mcl_lectern:lectern") diff --git a/mods/ITEMS/mcl_lectern/locale/mcl_lectern.fr.tr b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.fr.tr new file mode 100644 index 000000000..c068052e1 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/locale/mcl_lectern.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_lectern +Lectern=Pupitre +Lecterns not only look good, but are job site blocks for Librarians.=Les pupitres ne sont pas seulement décoratifs, ils sont aussi le poste de travail des Bibliothécaires. +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'.=Placer le Pupitre sur un bloc solide pour de meilleurs résultats. Il peut attirer les villageois, donc il vaut mieux le placer en dehors de chez vous. diff --git a/mods/ITEMS/mcl_lectern/locale/template.txt b/mods/ITEMS/mcl_lectern/locale/template.txt new file mode 100644 index 000000000..b3232a93b --- /dev/null +++ b/mods/ITEMS/mcl_lectern/locale/template.txt @@ -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_lectern/mod.conf b/mods/ITEMS/mcl_lectern/mod.conf new file mode 100644 index 000000000..93cc24041 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/mod.conf @@ -0,0 +1,3 @@ +name = mcl_lectern +depends = mcl_core, mcl_sounds, mcl_tools +author = Michieal \ No newline at end of file diff --git a/mods/ITEMS/mcl_lectern/models/mcl_lectern_lectern.obj b/mods/ITEMS/mcl_lectern/models/mcl_lectern_lectern.obj new file mode 100644 index 000000000..94e1db8e1 --- /dev/null +++ b/mods/ITEMS/mcl_lectern/models/mcl_lectern_lectern.obj @@ -0,0 +1,223 @@ +# Blender 3.5.0 Alpha +# www.blender.org +mtllib mcl_lectern_lectern.mtl +o Lectern_Cube.012 +v 0.179604 0.312500 -0.062500 +v -0.179604 0.312500 -0.062500 +v 0.179604 0.363193 0.205629 +v -0.179604 0.363193 0.205629 +v 0.179604 -0.375000 -0.062500 +v -0.179604 -0.375000 -0.062500 +v 0.179604 -0.375000 0.205629 +v -0.179604 -0.375000 0.205629 +v 0.311850 -0.500000 0.312500 +v 0.311850 -0.375000 0.312500 +v -0.311649 -0.500000 0.312500 +v -0.311649 -0.375000 0.312500 +v 0.311850 -0.500000 -0.312500 +v 0.311850 -0.375000 -0.312500 +v -0.311649 -0.500000 -0.312500 +v -0.311649 -0.375000 -0.312500 +v 0.312500 0.186356 -0.272278 +v 0.312500 0.245087 -0.293654 +v 0.312500 0.400118 0.315030 +v 0.312500 0.458849 0.293654 +v -0.312500 0.186356 -0.272278 +v -0.312500 0.245087 -0.293654 +v -0.312500 0.400118 0.315030 +v -0.312500 0.458849 0.293654 +v 0.312500 0.207732 -0.213547 +v 0.312500 0.266463 -0.234923 +v -0.312500 0.207732 -0.213547 +v -0.312500 0.266463 -0.234923 +v -0.312500 0.325194 -0.256299 +v -0.312500 0.303817 -0.315030 +v 0.312500 0.303817 -0.315030 +v 0.312500 0.325194 -0.256299 +v 0.151506 0.084133 0.146440 +v -0.157381 0.084133 0.146440 +v -0.157381 -0.203113 0.146441 +v 0.151506 -0.203113 0.146441 +v 0.151523 0.084130 -0.062500 +v -0.157397 0.084130 -0.062500 +v 0.151523 -0.203120 -0.062500 +v -0.157397 -0.203120 -0.062500 +v 0.151768 0.044855 0.077978 +v 0.064092 -0.203638 0.077978 +v 0.151797 0.044842 -0.062023 +v 0.064120 -0.203654 -0.062023 +v 0.028419 -0.191051 0.077979 +v 0.116095 0.057441 0.077979 +v 0.116124 0.057428 -0.062022 +v 0.028447 -0.191068 -0.062022 +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 +vn -0.0000 0.3420 0.9397 +vn -0.0000 -0.3420 -0.9397 +vn -0.0000 -0.9397 0.3420 +vn -0.0000 0.9397 -0.3420 +vn -0.0000 -1.0000 -0.0000 +vn -1.0000 -0.0000 -0.0001 +vn 1.0000 -0.0000 -0.0001 +vn 0.9430 -0.3327 0.0002 +vn -0.9430 0.3327 -0.0002 +vn 0.3327 0.9430 -0.0000 +vn -0.3327 -0.9430 -0.0000 +vt 0.000000 0.000000 +vt 0.343750 -0.000000 +vt 0.312500 0.000000 +vt -0.000000 -0.000000 +vt 0.312500 0.000000 +vt 0.000000 0.000000 +vt 0.312500 0.000000 +vt 0.000000 0.000000 +vt 0.000000 0.437500 +vt 0.343750 0.625000 +vt 0.312500 0.437500 +vt -0.000000 0.625000 +vt 0.312500 0.437500 +vt 0.000000 0.437500 +vt 0.312500 0.437500 +vt 0.000000 0.437500 +vt 0.312500 0.593750 +vt 0.000000 0.593750 +vt 0.312500 0.656250 +vt 0.000000 0.656250 +vt 1.000000 1.000000 +vt 0.000000 0.593750 +vt 0.312500 0.593750 +vt 0.000000 0.656250 +vt 0.312500 0.656250 +vt 1.000000 0.437500 +vt 0.000000 0.593750 +vt 0.312500 0.593750 +vt 0.000000 0.656250 +vt 0.312500 0.656250 +vt 0.437500 1.000000 +vt 0.000000 0.593750 +vt 0.312500 0.593750 +vt 0.000000 0.656250 +vt 0.312500 0.656250 +vt 0.437500 0.437500 +vt 0.125000 1.000000 +vt 0.125000 0.687500 +vt 0.062500 0.687500 +vt 0.187500 1.000000 +vt 0.125000 1.000000 +vt 0.312500 1.000000 +vt 0.437500 1.000000 +vt 0.062500 1.000000 +vt 0.250000 1.000000 +vt 1.000000 1.000000 +vt 0.125000 0.687500 +vt 0.062500 0.687500 +vt 0.187500 0.687500 +vt 0.312500 0.687500 +vt 0.437500 0.437500 +vt 0.125000 1.000000 +vt 0.250000 0.687500 +vt 1.000000 0.437500 +vt 0.062500 1.000000 +vt 1.000000 1.000000 +vt 0.062500 1.000000 +vt 0.125000 0.718750 +vt 0.437500 1.000000 +vt 0.062500 0.718750 +vt 1.000000 0.437500 +vt 0.062500 0.687500 +vt 0.125000 0.718750 +vt 0.437500 0.437500 +vt 0.062500 0.718750 +vt 0.437500 0.687500 +vt -0.000000 0.718750 +vt 0.375000 0.687500 +vt -0.000000 0.687500 +vt 0.312500 0.687500 +vt 0.250000 0.687500 +vt 0.312500 1.000000 +vt -0.000000 0.687500 +vt 0.250000 1.000000 +vt 0.375000 1.000000 +vt -0.000000 0.718750 +vt 0.687500 0.375000 +vt 0.312500 0.375000 +vt 0.687500 0.375000 +vt 0.312500 0.000000 +vt 0.312500 0.375000 +vt 0.687500 0.000000 +vt 0.687500 0.375000 +vt 0.312500 0.375000 +vt 0.312500 0.218750 +vt 0.687500 -0.000000 +vt 0.031250 0.218750 +vt 0.312500 -0.000000 +vt 0.687500 -0.000000 +vt 0.312500 0.468750 +vt 0.687500 -0.000000 +vt 0.312500 -0.000000 +vt 0.031250 0.468750 +vt 0.312500 -0.000000 +vt 0.937500 -0.000000 +vt 0.937500 0.437500 +vt 0.937500 0.437500 +vt 1.000000 0.437500 +vt 0.687500 0.000000 +vt 0.937500 0.218750 +vt 0.750000 0.000000 +vt 0.687500 0.437500 +vt 0.750000 0.437500 +vt 1.000000 0.218750 +vt 0.937500 0.000000 +vt 1.000000 0.437500 +vt 0.937500 0.437500 +vt 0.937500 0.437500 +vt 1.000000 -0.000000 +vt 1.000000 0.437500 +vt 0.687500 0.437500 +vt 1.000000 0.218750 +vt 0.687500 0.000000 +vt 0.687500 0.000000 +vt 0.687500 0.437500 +vt 0.937500 0.218750 +s 0 +usemtl Material +f 1/1/1 3/5/1 7/13/1 5/9/1 +f 3/6/2 4/7/2 8/15/2 7/14/2 +f 9/17/2 10/19/2 12/24/2 11/22/2 +f 36/82/3 35/80/3 34/78/3 33/77/3 +f 8/16/4 4/8/4 2/3/4 6/11/4 +f 11/23/4 12/25/4 16/34/4 15/32/4 +f 15/33/3 16/35/3 14/29/3 13/27/3 +f 13/28/1 14/30/1 10/20/1 9/18/1 +f 16/36/5 12/26/5 10/21/5 14/31/5 +f 25/58/1 26/60/1 20/44/1 19/41/1 +f 19/42/6 20/45/6 24/53/6 23/50/6 +f 27/63/4 28/65/4 22/48/4 21/47/4 +f 21/47/7 22/49/7 18/40/7 17/37/7 +f 22/48/4 28/65/4 29/67/4 30/69/4 +f 25/56/8 19/43/8 23/51/8 27/61/8 +f 17/37/8 25/57/8 27/62/8 21/47/8 +f 24/54/9 20/46/9 26/59/9 28/64/9 +f 23/52/4 24/55/4 28/65/4 27/63/4 +f 17/38/1 18/39/1 26/60/1 25/58/1 +f 29/68/9 32/75/9 31/72/9 30/70/9 +f 28/66/6 26/59/6 32/75/6 29/68/6 +f 26/60/1 18/39/1 31/73/1 32/76/1 +f 18/40/7 22/49/7 30/71/7 31/74/7 +f 37/85/3 38/87/3 2/4/3 1/2/3 +f 39/90/3 37/85/3 1/2/3 5/10/3 +f 40/93/3 39/90/3 5/10/3 6/12/3 +f 38/87/3 40/93/3 6/12/3 2/4/3 +f 33/77/10 34/78/10 38/88/10 37/86/10 +f 35/81/5 36/83/5 39/91/5 40/94/5 +f 36/84/11 33/77/11 37/86/11 39/92/11 +f 34/79/12 35/81/12 40/94/12 38/89/12 +f 44/102/13 43/99/13 41/95/13 42/97/13 +f 45/105/14 46/108/14 47/111/14 48/114/14 +f 41/95/2 46/109/2 45/106/2 42/97/2 +f 43/100/15 47/112/15 46/110/15 41/96/15 +f 44/103/3 48/115/3 47/113/3 43/101/3 +f 42/98/16 45/107/16 48/116/16 44/104/16 diff --git a/mods/ITEMS/mcl_lightning_rods/init.lua b/mods/ITEMS/mcl_lightning_rods/init.lua new file mode 100644 index 000000000..3cd2dc1dc --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/init.lua @@ -0,0 +1,118 @@ +local S = minetest.get_translator("mcl_lightning_rods") + +---@type nodebox +local cbox = { + type = "fixed", + fixed = { + { -0.0625, -0.5, -0.0625, 0.0625, 0.25, 0.0625 }, + { -0.125, 0.25, -0.125, 0.125, 0.5, 0.125 }, + }, +} + +---@type node_definition +local rod_def = { + description = S("Lightning Rod"), + _doc_items_longdesc = S("A block that attracts lightning"), + tiles = { "mcl_lightning_rods_rod.png" }, + drawtype = "mesh", + mesh = "mcl_lightning_rods_rod.obj", + is_ground_content = false, + paramtype = "light", + paramtype2 = "facedir", + use_texture_alpha = "opaque", + groups = { pickaxey = 2, attracts_lightning = 1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + selection_box = cbox, + collision_box = cbox, + node_placement_prediction = "", + mesecons = { + receptor = { + state = mesecon.state.off, + rules = mesecon.rules.alldirs, + }, + }, + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + end + + local p0 = pointed_thing.under + local p1 = pointed_thing.above + local param2 = 0 + + local placer_pos = placer:get_pos() + if placer_pos then + param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos)) + end + + if p0.y - 1 == p1.y then + param2 = 20 + elseif p0.x - 1 == p1.x then + param2 = 16 + elseif p0.x + 1 == p1.x then + param2 = 12 + elseif p0.z - 1 == p1.z then + param2 = 8 + elseif p0.z + 1 == p1.z then + param2 = 4 + end + + return minetest.item_place(itemstack, placer, pointed_thing, param2) + end, + + _mcl_blast_resistance = 0, +} + +minetest.register_node("mcl_lightning_rods:rod", rod_def) + +local rod_def_a = table.copy(rod_def) + +rod_def_a.tiles = { "mcl_lightning_rods_rod.png^[brighten" } + +rod_def_a.groups.not_in_creative_inventory = 1 + +rod_def_a.mesecons = { + receptor = { + state = mesecon.state.on, + rules = mesecon.rules.alldirs, + }, +} + +rod_def_a.on_timer = function(pos, elapsed) + local node = minetest.get_node(pos) + + if node.name == "mcl_lightning_rods:rod_powered" then --has not been dug + minetest.set_node(pos, { name = "mcl_lightning_rods:rod", param2 = node.param2 }) + mesecon.receptor_off(pos, mesecon.rules.alldirs) + end + + return false +end + +minetest.register_node("mcl_lightning_rods:rod_powered", rod_def_a) + + +lightning.register_on_strike(function(pos, pos2, objects) + local lr = minetest.find_node_near(pos, 128, { "group:attracts_lightning" }, true) + + if lr then + local node = minetest.get_node(lr) + + if node.name == "mcl_lightning_rods:rod" then + minetest.set_node(lr, { name = "mcl_lightning_rods:rod_powered", param2 = node.param2 }) + mesecon.receptor_on(lr, mesecon.rules.alldirs) + minetest.get_node_timer(lr):start(0.4) + end + end + + return lr, nil +end) + +minetest.register_craft({ + output = "mcl_lightning_rods:rod", + recipe = { + { "", "mcl_copper:copper_ingot", "" }, + { "", "mcl_copper:copper_ingot", "" }, + { "", "mcl_copper:copper_ingot", "" }, + }, +}) diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr new file mode 100644 index 000000000..8f99047f6 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_lightning_rods +Lightning Rod=Paratonnerre +A block that attracts lightning=Un bloc qui attire la foudre \ No newline at end of file diff --git a/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.tr b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.tr new file mode 100644 index 000000000..33376bf98 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/mcl_lightning_rods.ja.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_lightning_rods/locale/template.txt b/mods/ITEMS/mcl_lightning_rods/locale/template.txt new file mode 100644 index 000000000..5b2bbbcd2 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/locale/template.txt @@ -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_lightning_rods/mod.conf b/mods/ITEMS/mcl_lightning_rods/mod.conf new file mode 100644 index 000000000..dd30d7aa7 --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/mod.conf @@ -0,0 +1,3 @@ +name = mcl_lightning_rods +author = cora +depends = mcl_sounds, lightning, mesecons diff --git a/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj b/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj new file mode 100644 index 000000000..7870fc5bd --- /dev/null +++ b/mods/ITEMS/mcl_lightning_rods/models/mcl_lightning_rods_rod.obj @@ -0,0 +1,90 @@ +# Blender 3.3.1 +# www.blender.org +o Cube +v -0.062500 -0.500000 0.062500 +v -0.062500 0.250000 0.062500 +v -0.062500 -0.500000 -0.062500 +v -0.062500 0.250000 -0.062500 +v 0.062500 -0.500000 0.062500 +v 0.062500 0.250000 0.062500 +v 0.062500 -0.500000 -0.062500 +v 0.062500 0.250000 -0.062500 +v -0.125000 0.250000 0.125000 +v -0.125000 0.250000 -0.125000 +v 0.125000 0.250000 -0.125000 +v 0.125000 0.250000 0.125000 +v -0.125000 0.500000 0.125000 +v -0.125000 0.500000 -0.125000 +v 0.125000 0.500000 -0.125000 +v 0.125000 0.500000 0.125000 +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.000000 0.750000 +vt 0.125000 0.750000 +vt 0.062500 0.937500 +vt 0.000000 0.000000 +vt 0.125000 0.000000 +vt 0.187500 0.812500 +vt 0.062500 0.937500 +vt 0.125000 0.750000 +vt -0.000000 0.750000 +vt 0.062500 0.812500 +vt 0.125000 0.000000 +vt 0.000000 -0.000000 +vt 0.062500 0.812500 +vt 0.187500 0.937500 +vt 0.125000 0.750000 +vt -0.000000 0.750000 +vt 0.187500 0.937500 +vt 0.125000 -0.000000 +vt 0.000000 -0.000000 +vt 0.062500 0.812500 +vt 0.187500 0.937500 +vt 0.125000 0.750000 +vt 0.000000 0.750000 +vt 0.187500 0.812500 +vt 0.125000 -0.000000 +vt -0.000000 0.000000 +vt 0.187500 0.812500 +vt 0.062500 0.937500 +vt 0.000000 1.000000 +vt 0.250000 0.750000 +vt -0.000000 0.750000 +vt 0.250025 0.999950 +vt -0.000000 0.750000 +vt 0.250000 0.750000 +vt 0.250000 0.750000 +vt 0.000000 1.000000 +vt -0.000000 0.750000 +vt 0.000000 0.750000 +vt 0.250000 1.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt -0.000000 1.000000 +vt 0.250000 0.750000 +vt 0.000100 0.999900 +vt 0.250000 1.000000 +vt 0.250000 1.000000 +vt 0.000000 0.750000 +vt 0.000100 0.999900 +vt 0.000000 1.000000 +vt 0.250000 1.000000 +s 0 +f 1/1/1 2/4/1 4/11/1 3/8/1 +f 3/9/2 4/12/2 8/25/2 7/22/2 +f 7/23/3 8/26/3 6/18/3 5/15/3 +f 5/16/4 6/19/4 2/5/4 1/2/4 +f 3/10/5 7/24/5 5/17/5 1/3/5 +f 8/27/5 4/13/5 10/33/5 11/35/5 +f 12/38/3 11/35/3 15/46/3 16/49/3 +f 6/20/5 8/28/5 11/36/5 12/38/5 +f 4/14/5 2/6/5 9/30/5 10/32/5 +f 2/7/5 6/21/5 12/39/5 9/29/5 +f 15/47/6 14/43/6 13/41/6 16/49/6 +f 10/33/1 9/30/1 13/41/1 14/44/1 +f 9/31/4 12/40/4 16/50/4 13/42/4 +f 11/37/2 10/34/2 14/45/2 15/48/2 diff --git a/mods/ITEMS/mcl_loom/README.md b/mods/ITEMS/mcl_loom/README.md new file mode 100644 index 000000000..e91bad8fd --- /dev/null +++ b/mods/ITEMS/mcl_loom/README.md @@ -0,0 +1,19 @@ +mcl_loom +-------- +Looms, by PrairieWind + +Adds Looms to MineClone 2/5. Used to add patterns to banners. + +License of source code +---------------------- +LGPLv2.1 + +License of media +---------------- + +loom_bottom.png +loom_front.png +loom_side.png +loom_top.png +License: CC BY-SA 4.0 +Author: MrRar diff --git a/mods/ITEMS/mcl_loom/init.lua b/mods/ITEMS/mcl_loom/init.lua new file mode 100644 index 000000000..5475980bd --- /dev/null +++ b/mods/ITEMS/mcl_loom/init.lua @@ -0,0 +1,28 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +-- Loom Code. Used to craft banner designs easier. Still needs a GUI. https://minecraft.fandom.com/wiki/Loom + +minetest.register_node("mcl_loom:loom", { + description = S("Loom"), + _tt_help = S("Used to create banner designs"), + _doc_items_longdesc = S("This is the shepherd villager's work station. It is used to create banner designs."), + tiles = { + "loom_top.png", "loom_bottom.png", + "loom_side.png", "loom_side.png", + "loom_side.png", "loom_front.png" + }, + paramtype2 = "facedir", + groups = { axey = 2, handy = 1, deco_block = 1, material_wood = 1, flammable = 1 }, + sounds = mcl_sounds.node_sound_wood_defaults(), + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 +}) + + +minetest.register_craft({ + output = "mcl_loom:loom", + recipe = { + { "", "", "" }, + { "mcl_mobitems:string", "mcl_mobitems:string", "" }, + { "group:wood", "group:wood", "" }, + } +}) diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr new file mode 100644 index 000000000..410099428 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_loom +Loom=Métier à tisser +Used to create banner designs=Utilisé pour créer des motifs de bannières +This is the shepherd villager's work station. It is used to create banner designs.=Ceci est le poste de travail du villageois berger. Il est utilisé pour créer des motifs de bannière. \ No newline at end of file diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr new file mode 100644 index 000000000..8e5e8b076 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.ja.tr @@ -0,0 +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.=羊飼いの村人の職場です。旗のデザイン作成に使用します。 diff --git a/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr new file mode 100644 index 000000000..2442f76d5 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/mcl_loom.ru.tr @@ -0,0 +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.=Это рабочее место пастуха. Позволяет создавать узоры на флаге diff --git a/mods/ITEMS/mcl_loom/locale/template.txt b/mods/ITEMS/mcl_loom/locale/template.txt new file mode 100644 index 000000000..31905ea02 --- /dev/null +++ b/mods/ITEMS/mcl_loom/locale/template.txt @@ -0,0 +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.= diff --git a/mods/ITEMS/mcl_loom/mod.conf b/mods/ITEMS/mcl_loom/mod.conf new file mode 100644 index 000000000..e316b201a --- /dev/null +++ b/mods/ITEMS/mcl_loom/mod.conf @@ -0,0 +1,4 @@ +name = mcl_loom +author = PrairieWind +depends = mcl_core, mcl_sounds, mcl_tools +description = Adds the loom villager workstation to MineClone 2/5. Used to add patterns to banners. \ No newline at end of file diff --git a/mods/ITEMS/mcl_mangrove/init.lua b/mods/ITEMS/mcl_mangrove/init.lua new file mode 100644 index 000000000..ae80ba4b3 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/init.lua @@ -0,0 +1,469 @@ +local S = minetest.get_translator("mcl_mangrove") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local propagule_allowed_nodes = { + "mcl_core:dirt", + "mcl_core:coarse_dirt", + "mcl_core:dirt_with_grass", + "mcl_core:podzol", + "mcl_core:mycelium", + "mcl_lush_caves:rooted_dirt", + "mcl_lush_caves:moss", + "mcl_farming:soil", + "mcl_farming:soil_wet", + "mcl_core:clay", + "mcl_mud:mud", +} +local propagule_water_nodes = {"mcl_mud:mud","mcl_core:dirt","mcl_core:coarse_dirt","mcl_core:clay"} + --"mcl_lush_caves:moss","mcl_lush_caves:rooted_dirt + +mcl_core.register_tree_trunk("mangrove_tree", S("Mangrove Wood"), S("Mangrove Bark"), + S("The trunk of a Mangrove tree."), + "mcl_mangrove_log_top.png", "mcl_mangrove_log.png", "mcl_mangrove:mangrove_stripped") + +mcl_core.register_wooden_planks("mangrove_wood", S("Mangrove Wood Planks"), {"mcl_mangrove_planks.png"}) + +mcl_core.register_leaves("mangroveleaves", S("Mangrove Leaves"), S("Mangrove leaves are grown from mangrove trees."), + {"mcl_mangrove_leaves.png"}, "#48B518", "color", "mcl_core_palette_foliage.png", "mcl_mangrove:propagule", true, {20, 16, 12, 10}, 1) + +mcl_core.register_stripped_trunk("mangrove_stripped", S("Stripped Mangrove Log"), S("Stripped Mangrove Wood"), + S("The stripped wood of a Mangrove tree"), S("The stripped bark of a Mangrove tree"), + "mcl_stripped_mangrove_log_top.png", "mcl_stripped_mangrove_log_side.png") + +minetest.register_alias("mcl_mangrove:mangrove_stripped_trunk", "mcl_mangrove:mangrove_stripped") + +minetest.register_node("mcl_mangrove:mangrove_roots", { + description = S("Mangrove Roots"), + _doc_items_longdesc = S("Mangrove roots are decorative blocks that form as part of mangrove trees."), + _doc_items_hidden = false, + waving = 0, + place_param2 = 1, -- Prevent leafdecay for placed nodes + tiles = { + "mcl_mangrove_roots_top.png", + "mcl_mangrove_roots_side.png", + "mcl_mangrove_roots_side.png", + }, + paramtype = "light", + drawtype = "allfaces_optional", + groups = { + handy = 1, hoey = 1, shearsy = 1, axey = 1, swordy = 1, dig_by_piston = 0, + flammable = 10, fire_encouragement = 30, fire_flammability = 60, + deco_block = 1, compostability = 30 + }, + drop = "mcl_mangrove:mangrove_roots", + _mcl_shears_drop = true, + sounds = mcl_sounds.node_sound_leaves_defaults(), + _mcl_blast_resistance = 0.7, + _mcl_hardness = 0.7, + _mcl_silk_touch_drop = true, + _mcl_fortune_drop = { "mcl_mangrove:mangrove_roots 1", "mcl_mangrove:mangrove_roots 2", "mcl_mangrove:mangrove_roots 3", "mcl_mangrove:mangrove_roots 4" }, +}) + +minetest.register_node("mcl_mangrove:propagule", { + description = S("Mangrove Propagule"), + _tt_help = S("Needs soil and light to grow"), + _doc_items_longdesc = S("When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time."), + _doc_items_hidden = false, + drawtype = "plantlike", + waving = 1, + visual_scale = 1.0, + tiles = {"mcl_mangrove_propagule_item.png"}, + inventory_image = "mcl_mangrove_propagule_item.png", + wield_image = "mcl_mangrove_propagule_item.png", + paramtype = "light", + sunlight_propagates = true, + walkable = false, + selection_box = { + type = "fixed", + fixed = {-5/16, -0.5, -5/16, 5/16, 0.5, 5/16} + }, + groups = { + plant = 1, sapling = 1, non_mycelium_plant = 1, attached_node = 1, + deco_block = 1, dig_immediate = 3, dig_by_water = 0, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + sounds = mcl_sounds.node_sound_leaves_defaults(), + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_int("stage", 0) + end, + node_placement_prediction = "", + _mcl_blast_resistance = 0, + _mcl_hardness = 0, + on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node,stack) + local under = vector.offset(place_pos,0,-1,0) + local snn = minetest.get_node_or_nil(under).name + if not snn then return false end + if table.indexof(propagule_allowed_nodes,snn) ~= -1 then + local n = minetest.get_node(place_pos) + if minetest.get_item_group(n.name,"water") > 0 and table.indexof(propagule_water_nodes,snn) ~= -1 then + minetest.set_node(under,{name="mcl_mangrove:propagule_"..snn:split(":")[2]}) + stack:take_item() + return stack + end + return true + end + end) +}) + +minetest.register_node("mcl_mangrove:hanging_propagule_1", { + description = S("Hanging Propagule"), + _tt_help = S("Grows on Mangrove leaves"), + _doc_items_longdesc = "", + _doc_items_usagehelp = "", + groups = { + plant = 1, not_in_creative_inventory=1, non_mycelium_plant = 1, + deco_block = 1, dig_immediate = 3, dig_by_water = 0, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + paramtype = "light", + paramtype2 = "", + on_rotate = false, + walkable = false, + drop = "mcl_mangrove:propagule", + use_texture_alpha = "clip", + drawtype = 'mesh', + mesh = 'propagule_hanging.obj', + selection_box = { + type = "fixed", + fixed = { + {-0.125, -0.5, -0.125, 0.125, 0.5, 0.125}, -- Base + }, + }, + tiles = {"mcl_mangrove_propagule_hanging.png"}, + inventory_image = "mcl_mangrove_propagule.png", + wield_image = "mcl_mangrove_propagule.png", +}) +local propagule_rooted_nodes = {} +for _,root in pairs(propagule_water_nodes) do + local r = root:split(":")[2] + local def = minetest.registered_nodes[root] + local tx = def.tiles + local n = "mcl_mangrove:propagule_"..r + table.insert(propagule_rooted_nodes,n) + minetest.register_node(n, { + drawtype = "plantlike_rooted", + paramtype = "light", + place_param2 = 1, + tiles = tx, + special_tiles = { { name = "mcl_mangrove_propagule_item.png" } }, + inventory_image = "mcl_mangrove_propagule_item.png", + wield_image = "mcl_mangrove_propagule.png", + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.5, -0.5, 0.5, 1.0, 0.5 }, + } + }, + groups = { + plant = 1, sapling = 1, non_mycelium_plant = 1, attached_node = 1,not_in_creative_inventory=1, + deco_block = 1, dig_immediate = 3, dig_by_piston = 1, + destroy_by_lava_flow = 1, compostability = 30 + }, + sounds = mcl_sounds.node_sound_leaves_defaults(), + drop = "mcl_mangrove:propagule", + node_placement_prediction = "", + node_dig_prediction = "", + after_dig_node = function(pos) + minetest.set_node(pos, {name=root}) + end, + _mcl_hardness = 0, + _mcl_blast_resistance = 0, + _mcl_silk_touch_drop = true, + }) + +end + + +mcl_flowerpots.register_potted_flower("mcl_mangrove:propagule", { + name = "propagule", + desc = S("Mangrove Propagule"), + image = "mcl_mangrove_propagule.png", +}) + +local water_tex = "default_water_source_animated.png^[verticalframe:16:0^[multiply:#3F76E4" + +local wlroots = { + description = S("water logged mangrove roots"), + _doc_items_entry_name = S("water logged mangrove roots"), + _doc_items_longdesc = + S("Mangrove roots are decorative blocks that form as part of mangrove trees.").."\n\n".. + S("Mangrove roots, despite being a full block, can be waterlogged and do not flow water out").."\n\n".. + 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}} + }, + special_tiles = { + -- New-style water source material (mostly unused) + { + name="default_water_source_animated.png", + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, + backface_culling = false, + } + }, + overlay_tiles = { + "mcl_mangrove_roots_top.png", + "mcl_mangrove_roots_side.png", + "mcl_mangrove_roots_side.png", + }, + sounds = mcl_sounds.node_sound_water_defaults(), + drawtype = "allfaces_optional", + use_texture_alpha = "blend", + is_ground_content = false, + paramtype = "light", + walkable = true, + pointable = true, + diggable = true, + buildable_to = false, + 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 }, + _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) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + minetest.set_node(pos, {name="mcl_mangrove:mangrove_roots"}) + end + end, + after_dig_node = function(pos) + local node = minetest.get_node(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if minetest.get_item_group(node.name, "water") == 0 and dim ~= "nether" then + minetest.set_node(pos, {name="mcl_core:water_source"}) + else + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end + end, +} +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" +rwlroots.tiles = { + "("..water_tex..")^mcl_mangrove_roots_top.png", + "("..water_tex..")^mcl_mangrove_roots_side.png", + "("..water_tex..")^mcl_mangrove_roots_side.png", +} +rwlroots.after_dig_node = function(pos) + local node = minetest.get_node(pos) + local dim = mcl_worlds.pos_to_dimension(pos) + if minetest.get_item_group(node.name, "water") == 0 and dim ~= "nether" then + minetest.set_node(pos, {name="mclx_core:river_water_source"}) + else + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + end +end + +minetest.register_node("mcl_mangrove:water_logged_roots", wlroots) +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"), + _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", + "mcl_mud.png^mcl_mangrove_roots_side.png", + "mcl_mud.png^mcl_mangrove_roots_side.png", + }, + is_ground_content = true, + groups = {handy = 1, shovely = 1, axey = 1, building_block = 1}, + sounds = mcl_sounds.node_sound_sand_defaults(), + _mcl_blast_resistance = 0.7, + _mcl_hardness = 0.7, +}) + +mcl_doors:register_door("mcl_mangrove:mangrove_door", { + description = S("Mangrove 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_mangrove_doors.png", + groups = {handy=1,axey=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + tiles_bottom = "mcl_mangrove_door_bottom.png", + tiles_top = "mcl_mangrove_door_top.png", + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_doors:register_trapdoor("mcl_mangrove:mangrove_trapdoor", { + description = S("Mangrove Trapdoor"), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = S("To open or close the trapdoor, rightclick it or send a redstone signal to it."), + tile_front = "mcl_mangrove_trapdoor.png", + tile_side = "mcl_mangrove_planks.png", + wield_image = "mcl_mangrove_trapdoor.png", + groups = {handy=1,axey=1, mesecon_effector_on=1, material_wood=1, flammable=-1}, + _mcl_hardness = 3, + _mcl_blast_resistance = 3, + sounds = mcl_sounds.node_sound_wood_defaults(), +}) + +mcl_fences.register_fence_and_fence_gate( + "mangrove_wood_fence", + S("Mangrove Wood Fence"), + S("Mangrove Wood Fence Gate"), + "mcl_mangrove_fence.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(), "mcl_mangrove_mangrove_wood_fence_gate_open", "mcl_mangrove_mangrove_wood_fence_gate_close", 1, 1, + "mcl_mangrove_fence_gate.png") + +mcl_stairs.register_stair("mangrove_wood", "mcl_mangrove:mangrove_wood", + {handy=1,axey=1, flammable=3,wood_stairs=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_mangrove_planks.png"}, + S("Mangrove Wood Stairs"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + "woodlike") + +mcl_stairs.register_slab("mangrove_wood", "mcl_mangrove:mangrove_wood", + {handy=1,axey=1, flammable=3,wood_slab=1, material_wood=1, fire_encouragement=5, fire_flammability=20}, + {"mcl_mangrove_planks.png"}, + S("Mangrove Wood Slab"), + mcl_sounds.node_sound_wood_defaults(), 3, 2, + S("Double Mangrove Wood Slab")) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_tree_bark 3", + recipe = { + { "mcl_mangrove:mangrove_tree", "mcl_mangrove:mangrove_tree" }, + { "mcl_mangrove:mangrove_tree", "mcl_mangrove:mangrove_tree" }, + } +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_mud_roots", + recipe = { + {"mcl_mangrove:mangrove_roots", "mcl_mud:mud",}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mangrove:mangrove_door", + burntime = 15, +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_door 3", + recipe = { + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_mangrove:mangrove_wood"}, + } +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_trapdoor 2", + recipe = { + {"mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood","mcl_mangrove:mangrove_wood"}, + } +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mangrove:mangrove_trapdoor", + burntime = 15, +}) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood_fence_gate", + recipe = { + {"mcl_core:stick", "mcl_mangrove:mangrove_wood", "mcl_core:stick"}, + {"mcl_core:stick", "mcl_mangrove:mangrove_wood", "mcl_core:stick"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood_fence 3", + recipe = { + {"mcl_mangrove:mangrove_wood", "mcl_core:stick", "mcl_mangrove:mangrove_wood"}, + {"mcl_mangrove:mangrove_wood", "mcl_core:stick", "mcl_mangrove:mangrove_wood"}, + } + }) + +minetest.register_craft({ + output = "mcl_mangrove:mangrove_wood 4", + recipe = { + {"mcl_mangrove:mangrove_tree"}, + } + }) + +minetest.register_craft({ + type = "fuel", + recipe = "group:fence_wood", + burntime = 15, +}) + +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +minetest.register_abm({ + label = "Waterlog mangrove roots", + nodenames = {"mcl_mangrove:mangrove_roots"}, + neighbors = {"group:water"}, + interval = 5, + chance = 5, + action = function(pos,value) + for _,v in pairs(adjacents) do + local n = minetest.get_node(vector.add(pos,v)).name + if minetest.get_item_group(n,"water") > 0 then + if n:find("river") then + minetest.swap_node(pos,{name="mcl_mangrove:river_water_logged_roots"}) + return + else + minetest.swap_node(pos,{name="mcl_mangrove:water_logged_roots"}) + return + end + end + end + end +}) + +local abm_nodes = table.copy(propagule_rooted_nodes) +table.insert(abm_nodes,"mcl_mangrove:propagule") +minetest.register_abm({ + label = "Mangrove_tree_growth", + nodenames = abm_nodes, + interval = 30, + chance = 5, + action = function(pos,node) + local pr = PseudoRandom(pos.x+pos.y+pos.z) + local r = pr:next(1,5) + local path = modpath .."/schematics/mcl_mangrove_tree_"..tostring(r)..".mts" + local w = 5 + local h = 10 + local fp = true + pos.y = pos.y - 1 + if table.indexof(propagule_rooted_nodes,node.name) ~= -1 then + local nn = minetest.find_nodes_in_area(vector.offset(pos,0,-1,0),vector.offset(pos,0,h,0),{"group:water","air"}) + if #nn >= h then + minetest.place_schematic(pos, path, "random", function() + mcl_core.update_sapling_foliage_colors(pos) + local nnv = minetest.find_nodes_in_area(vector.offset(pos,-5,-1,-5),vector.offset(pos,5,h/2,5),{"mcl_core:vine"}) + minetest.bulk_set_node(nnv,{"air"}) + end, true, "place_center_x, place_center_z") + end + return + end + if r > 3 then h = 18 end + if mcl_core.check_growth_width(pos,w,h) then + minetest.place_schematic(pos, path, "random", nil, true, "place_center_x, place_center_z") + mcl_core.update_sapling_foliage_colors(pos) + end + end, +}) diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr new file mode 100644 index 000000000..4d1590dbd --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.fr.tr @@ -0,0 +1,36 @@ +# textdomain: mcl_mangrove +Mangrove Wood=Bûche de palétuvier +The trunk of a Mangrove tree.=Le tronc d'un palétuvier. +Mangrove Bark=Bois de palétuvier +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 +The stripped wood of a Mangrove tree=La bûche écorcée d'un palétuvier +Stripped Mangrove Bark=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. +Mangrove Propagule=Propagule de palétuvier +Needs soil and light to grow=A besoin de terre et de lumière pour pousser +When placed on soil (such as dirt) and exposed to light, an propagule will grow into an mangrove after some time.=Lorsque placé sur la terre et exposée à la lumière, une propagule pousera en palétuvier après un certain temps. +Hanging Propagule=Propagule suspendue +Grows on Mangrove leaves=Pousse sur les feuilles de palétuvier +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 +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. +To open or close a wooden door, rightclick it or supply its lower half with a redstone signal.=Pour ouvrir ou fermer une porte en bois, faites un clic droit dessus ou fournissez à sa moitié inférieure un signal redstone. +Mangrove Trapdoor=Trappe en palétuvier +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.=Les trappes de bois sont des barrières horizontales qui peuvent être ouvertes et fermées à la main ou avec un signal redstone. Elles occupent la partie haut ou bas d'un bloc, selon la manière dont elles ont été placées. +To open or close the trapdoor, rightclick it or send a redstone signal to it.=Pour ouvrir et fermer la trappe, faire un clic droit ou lui envoyer un signal redstone. +Mangrove Wood Fence=Barrière de palétuvier +Mangrove Wood Fence Gate=Portillon de palétuvier +Mangrove Wood Stairs=Escalier en bois de palétuvier +Mangrove Wood Slab=Dalle en bois de palétuvier +Double Mangrove Wood Slab=Double Dalle en bois de palétuvier diff --git a/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.tr new file mode 100644 index 000000000..6df59f6fb --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/mcl_mangrove.ja.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 Wood=樹皮を剥いだマングローブの木 +The stripped wood of a Mangrove tree=剥き身となったマングローブの木 +Stripped Mangrove Bark=剥がされたマングローブの樹皮 +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.=泥に塗れたマングローブの根は、マングローブの沼地から1ブロックの場所にあります。 +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=マングローブの2重スラブ diff --git a/mods/ITEMS/mcl_mangrove/locale/template.txt b/mods/ITEMS/mcl_mangrove/locale/template.txt new file mode 100644 index 000000000..3de2b9ced --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/locale/template.txt @@ -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 Wood= +The stripped wood of a Mangrove tree= +Stripped Mangrove Bark= +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.= +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/mod.conf b/mods/ITEMS/mcl_mangrove/mod.conf new file mode 100644 index 000000000..cdc9a6a1c --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/mod.conf @@ -0,0 +1,3 @@ +name = mcl_mangrove +author = thunder1035 +depends = mcl_core, mcl_doors, mcl_stairs, mcl_walls, mclx_fences, mcl_boats, mcl_flowerpots, mcl_mud, mcl_util, mcl_worlds diff --git a/mods/ITEMS/mcl_mangrove/models/propagule.obj b/mods/ITEMS/mcl_mangrove/models/propagule.obj new file mode 100644 index 000000000..598573020 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/models/propagule.obj @@ -0,0 +1,73 @@ +# Blender v3.1.2 OBJ File: 'propagule.blend' +# www.blender.org +mtllib propagule.mtl +o Plane +v 0.500000 0.499931 0.499931 +v 0.500000 -0.499931 0.499931 +v 0.500000 0.499931 -0.499931 +v 0.500000 -0.499931 -0.499931 +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 +v -0.347329 1.500000 0.359670 +v 0.347329 1.500000 -0.359670 +v 0.347329 0.500000 -0.359670 +v -0.347329 0.500000 0.359670 +v -0.359670 1.500000 -0.347329 +v 0.359670 1.500000 0.347329 +v 0.359670 0.500000 0.347329 +v -0.359670 0.500000 -0.347329 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499987 +vt 0.000000 0.499987 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 0.000000 +vt 1.000000 0.000000 +vt 1.000000 0.499868 +vt 0.000000 0.499868 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.499985 +vt 0.000000 0.499985 +vt 0.000000 1.000000 +vt 1.000000 1.000000 +vt 1.000000 0.499985 +vt 0.000000 0.499985 +vn 1.0000 0.0000 0.0000 +vn -0.5774 0.5774 0.5774 +vn 0.0000 0.7071 0.7071 +vn 0.0000 0.7071 -0.7071 +vn -0.5774 0.5774 -0.5774 +vn -0.7071 0.0000 -0.7071 +vn -0.7071 -0.0000 0.7071 +vn 0.0000 0.0000 -1.0000 +vn -0.0000 -0.0000 1.0000 +vn -0.7193 0.0000 -0.6947 +vn 0.6947 0.0000 -0.7193 +usemtl default_dirt.png.001 +s off +f 1/1/1 2/2/1 4/3/1 3/4/1 +s 1 +f 5/5/2 6/6/3 7/7/4 8/8/5 +f 9/9/6 10/10/7 5/11/2 8/8/5 +f 11/12/8 9/13/6 8/14/5 7/15/4 +f 10/16/7 12/17/9 6/18/3 5/19/2 +usemtl mcl_mangrove_propagule.png.001 +f 13/20/10 14/21/10 15/22/10 16/23/10 +f 17/24/11 18/25/11 19/26/11 20/27/11 diff --git a/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj b/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj new file mode 100644 index 000000000..0a8be50d0 --- /dev/null +++ b/mods/ITEMS/mcl_mangrove/models/propagule_hanging.obj @@ -0,0 +1,975 @@ +# Blender v3.1.2 OBJ File: 'propagule_hanging.blend' +# www.blender.org +mtllib propagule_hanging.mtl +o plant +v 0.000000 0.470112 0.000000 +v 0.000000 -0.529888 0.000000 +v 0.000000 -0.529888 0.000000 +v 0.000000 0.470112 0.000000 +v 0.000000 -0.029888 0.000000 +v 0.000000 -0.029888 0.000000 +v 0.000000 -0.279888 0.000000 +v 0.000000 0.220112 0.000000 +v 0.000000 -0.279888 0.000000 +v 0.000000 0.220112 0.000000 +v -0.086832 0.470112 0.089918 +v 0.086832 -0.529888 -0.089917 +v 0.089917 -0.529888 0.086832 +v -0.089918 0.470112 -0.086832 +v 0.000000 -0.404888 0.000000 +v 0.000000 0.095112 0.000000 +v 0.089917 -0.029888 0.086832 +v 0.000000 -0.404888 0.000000 +v 0.000000 0.095112 0.000000 +v 0.086832 -0.029888 -0.089917 +v 0.086832 0.470112 -0.089917 +v -0.086832 -0.529888 0.089917 +v -0.089917 -0.529888 -0.086832 +v 0.089917 0.470112 0.086832 +v 0.000000 -0.154888 0.000000 +v 0.000000 0.345112 0.000000 +v -0.089917 -0.029888 -0.086832 +v 0.000000 -0.154888 0.000000 +v 0.000000 0.345112 0.000000 +v -0.086832 -0.029888 0.089918 +v 0.086832 0.220112 -0.089917 +v -0.086832 0.220112 0.089918 +v -0.086832 -0.279888 0.089917 +v 0.089917 0.220112 0.086832 +v -0.089918 0.220112 -0.086832 +v -0.089917 -0.279888 -0.086832 +v 0.089917 -0.279888 0.086832 +v 0.086832 -0.279888 -0.089917 +v 0.086832 -0.154888 -0.089917 +v 0.086832 -0.404888 -0.089917 +v 0.089917 -0.154888 0.086832 +v 0.089917 -0.404888 0.086832 +v -0.089917 -0.154888 -0.086832 +v -0.089918 0.345112 -0.086832 +v 0.089917 0.345112 0.086832 +v 0.089917 0.095112 0.086832 +v -0.086832 -0.154888 0.089918 +v -0.086832 0.345112 0.089918 +v 0.086832 0.345112 -0.089917 +v 0.086832 0.095112 -0.089917 +v -0.086832 0.095112 0.089918 +v -0.086832 -0.404888 0.089917 +v -0.089917 0.095112 -0.086832 +v -0.089917 -0.404888 -0.086832 +v -0.043416 0.470112 0.044959 +v 0.043416 -0.529888 -0.044959 +v 0.044959 -0.529888 0.043416 +v -0.044959 0.470112 -0.043416 +v 0.000000 -0.467388 0.000000 +v 0.000000 0.032612 0.000000 +v 0.044959 -0.029888 0.043416 +v 0.000000 -0.467388 0.000000 +v 0.000000 0.032612 0.000000 +v 0.043416 -0.029888 -0.044959 +v 0.000000 -0.217388 0.000000 +v 0.000000 0.282612 0.000000 +v 0.000000 -0.217388 0.000000 +v 0.000000 0.282612 0.000000 +v 0.043416 0.220112 -0.044959 +v 0.044959 0.220112 0.043416 +v 0.044959 -0.279888 0.043416 +v 0.043416 -0.279888 -0.044959 +v 0.000000 -0.342388 0.000000 +v 0.000000 0.157612 0.000000 +v 0.000000 -0.342388 0.000000 +v 0.000000 0.157612 0.000000 +v 0.043416 0.470112 -0.044959 +v -0.043416 -0.529888 0.044959 +v -0.044959 -0.529888 -0.043416 +v 0.044959 0.470112 0.043416 +v 0.000000 -0.092388 0.000000 +v 0.000000 0.407612 0.000000 +v -0.044959 -0.029888 -0.043416 +v 0.000000 -0.092388 0.000000 +v 0.000000 0.407612 0.000000 +v -0.043416 -0.029888 0.044959 +v -0.043416 0.220112 0.044959 +v -0.043416 -0.279888 0.044959 +v -0.044959 0.220112 -0.043416 +v -0.044959 -0.279888 -0.043416 +v 0.086832 -0.217388 -0.089917 +v 0.086832 -0.092388 -0.089917 +v 0.043416 -0.154888 -0.044959 +v 0.086832 -0.467388 -0.089917 +v 0.086832 -0.342388 -0.089917 +v 0.043416 -0.404888 -0.044959 +v 0.089917 -0.217388 0.086832 +v 0.089917 -0.092388 0.086832 +v 0.044959 -0.154888 0.043416 +v 0.089917 -0.467388 0.086832 +v 0.089917 -0.342388 0.086832 +v 0.044959 -0.404888 0.043416 +v -0.089917 -0.217388 -0.086832 +v -0.089917 -0.092388 -0.086832 +v -0.044959 -0.154888 -0.043416 +v -0.089918 0.282612 -0.086832 +v -0.089918 0.407612 -0.086832 +v -0.044959 0.345112 -0.043416 +v 0.089917 0.282612 0.086832 +v 0.089917 0.407612 0.086832 +v 0.044959 0.345112 0.043416 +v 0.089917 0.032612 0.086832 +v 0.089917 0.157612 0.086832 +v 0.044959 0.095112 0.043416 +v -0.086832 -0.217388 0.089917 +v -0.086832 -0.092388 0.089918 +v -0.043416 -0.154888 0.044959 +v -0.086832 0.282612 0.089918 +v -0.086832 0.407612 0.089918 +v -0.043416 0.345112 0.044959 +v 0.086832 0.282612 -0.089917 +v 0.086832 0.407612 -0.089917 +v 0.043416 0.345112 -0.044959 +v 0.086832 0.032612 -0.089917 +v 0.086832 0.157612 -0.089917 +v 0.043416 0.095112 -0.044959 +v -0.086832 0.032612 0.089918 +v -0.086832 0.157612 0.089918 +v -0.043416 0.095112 0.044959 +v -0.086832 -0.467388 0.089917 +v -0.086832 -0.342388 0.089917 +v -0.043416 -0.404888 0.044959 +v -0.089917 0.032612 -0.086832 +v -0.089917 0.157612 -0.086832 +v -0.044959 0.095112 -0.043416 +v -0.089917 -0.467388 -0.086832 +v -0.089917 -0.342388 -0.086832 +v -0.044959 -0.404888 -0.043416 +v -0.044959 -0.342388 -0.043416 +v -0.044959 0.157612 -0.043416 +v -0.043416 -0.342388 0.044959 +v -0.043416 0.157612 0.044959 +v 0.043416 0.157612 -0.044959 +v 0.043416 0.032612 -0.044959 +v 0.043416 0.407612 -0.044959 +v 0.043416 0.282612 -0.044959 +v -0.043416 0.407612 0.044959 +v -0.043416 -0.092388 0.044959 +v 0.044959 0.157612 0.043416 +v 0.044959 0.032612 0.043416 +v 0.044959 0.407612 0.043416 +v 0.044959 0.282612 0.043416 +v -0.044959 0.407612 -0.043416 +v -0.044959 -0.092388 -0.043416 +v 0.044959 -0.342388 0.043416 +v 0.044959 -0.467388 0.043416 +v 0.044959 -0.092388 0.043416 +v 0.044959 -0.217388 0.043416 +v 0.043416 -0.342388 -0.044959 +v 0.043416 -0.467388 -0.044959 +v 0.043416 -0.092388 -0.044959 +v 0.043416 -0.217388 -0.044959 +v -0.044959 -0.217388 -0.043416 +v -0.044959 0.282612 -0.043416 +v -0.043416 -0.217388 0.044959 +v -0.043416 0.282612 0.044959 +v -0.043416 0.032612 0.044959 +v -0.043416 -0.467388 0.044959 +v -0.044959 0.032612 -0.043416 +v -0.044959 -0.467388 -0.043416 +vt 0.218362 0.406348 +vt 0.250401 0.406348 +vt 0.250401 0.376797 +vt 0.218362 0.376797 +vt 0.218362 0.657596 +vt 0.250401 0.657596 +vt 0.250401 0.626276 +vt 0.218362 0.626276 +vt 0.218362 0.406348 +vt 0.250401 0.406348 +vt 0.250401 0.376797 +vt 0.218362 0.376797 +vt 0.218362 0.657596 +vt 0.250401 0.657596 +vt 0.250401 0.626276 +vt 0.218362 0.626276 +vt 0.218362 0.784719 +vt 0.250401 0.784719 +vt 0.250401 0.751554 +vt 0.218362 0.751554 +vt 0.218362 0.532933 +vt 0.250401 0.532933 +vt 0.250401 0.502229 +vt 0.218362 0.502229 +vt 0.218362 0.784719 +vt 0.250401 0.784719 +vt 0.250401 0.751554 +vt 0.218362 0.751554 +vt 0.218362 0.532933 +vt 0.250401 0.532933 +vt 0.250401 0.502229 +vt 0.218362 0.502229 +vt 0.282961 0.532934 +vt 0.315521 0.532934 +vt 0.315521 0.502229 +vt 0.282961 0.502229 +vt 0.282961 0.594957 +vt 0.315521 0.594957 +vt 0.315521 0.563638 +vt 0.282961 0.563638 +vt 0.282961 0.406348 +vt 0.315521 0.406348 +vt 0.315521 0.376797 +vt 0.282961 0.376797 +vt 0.282961 0.469065 +vt 0.315521 0.469065 +vt 0.315521 0.435900 +vt 0.282961 0.435900 +vt 0.282961 0.532934 +vt 0.315521 0.532934 +vt 0.315521 0.502229 +vt 0.282961 0.502229 +vt 0.282961 0.594957 +vt 0.315521 0.594957 +vt 0.315521 0.563638 +vt 0.282961 0.563638 +vt 0.282961 0.406348 +vt 0.315521 0.406348 +vt 0.315521 0.376797 +vt 0.282961 0.376797 +vt 0.282961 0.469065 +vt 0.315521 0.469065 +vt 0.315521 0.435900 +vt 0.282961 0.435900 +vt 0.218362 0.594957 +vt 0.250401 0.594957 +vt 0.250401 0.563638 +vt 0.218362 0.563638 +vt 0.466901 0.935330 +vt 0.498940 0.935330 +vt 0.498940 0.875712 +vt 0.466901 0.875712 +vt 0.282961 0.784719 +vt 0.315521 0.784719 +vt 0.315521 0.751554 +vt 0.282961 0.751554 +vt 0.531500 0.935330 +vt 0.564060 0.935330 +vt 0.564060 0.875712 +vt 0.531500 0.875712 +vt 0.282961 0.657596 +vt 0.315521 0.657596 +vt 0.315521 0.626276 +vt 0.282961 0.626276 +vt 0.282961 0.720234 +vt 0.315521 0.720234 +vt 0.315521 0.688915 +vt 0.282961 0.688915 +vt 0.218362 0.594957 +vt 0.250401 0.594957 +vt 0.250401 0.563638 +vt 0.218362 0.563638 +vt 0.466901 0.935330 +vt 0.498940 0.935330 +vt 0.498940 0.875712 +vt 0.466901 0.875712 +vt 0.282961 0.784719 +vt 0.315521 0.784719 +vt 0.315521 0.751554 +vt 0.282961 0.751554 +vt 0.531500 0.935330 +vt 0.564060 0.935330 +vt 0.564060 0.875712 +vt 0.531500 0.875712 +vt 0.282961 0.657596 +vt 0.315521 0.657596 +vt 0.315521 0.626276 +vt 0.282961 0.626276 +vt 0.282961 0.720234 +vt 0.315521 0.720234 +vt 0.315521 0.688915 +vt 0.282961 0.688915 +vt 0.218362 0.720234 +vt 0.250401 0.720234 +vt 0.250401 0.688915 +vt 0.218362 0.688915 +vt 0.218362 0.469064 +vt 0.250401 0.469064 +vt 0.250401 0.435900 +vt 0.218362 0.435900 +vt 0.218362 0.720234 +vt 0.250401 0.720234 +vt 0.250401 0.688915 +vt 0.218362 0.688915 +vt 0.218362 0.469064 +vt 0.250401 0.469064 +vt 0.250401 0.435900 +vt 0.218362 0.435900 +vt 0.186322 0.469064 +vt 0.186322 0.435900 +vt 0.186322 0.502229 +vt 0.186322 0.720234 +vt 0.186322 0.688915 +vt 0.186322 0.751554 +vt 0.186322 0.469064 +vt 0.186322 0.435900 +vt 0.186322 0.502229 +vt 0.186322 0.720234 +vt 0.186322 0.688915 +vt 0.186322 0.751554 +vt 0.498940 0.998640 +vt 0.531500 0.998640 +vt 0.564060 0.998640 +vt 0.250401 0.817883 +vt 0.282961 0.817883 +vt 0.315521 0.817883 +vt 0.434861 0.935330 +vt 0.434861 0.875712 +vt 0.434861 0.998640 +vt 0.466901 0.998640 +vt 0.186322 0.594957 +vt 0.186322 0.563638 +vt 0.186322 0.626276 +vt 0.498940 0.998640 +vt 0.531500 0.998640 +vt 0.564060 0.998640 +vt 0.250401 0.817883 +vt 0.282961 0.817883 +vt 0.315521 0.817883 +vt 0.434861 0.935330 +vt 0.434861 0.875712 +vt 0.434861 0.998640 +vt 0.466901 0.998640 +vt 0.186322 0.594957 +vt 0.186322 0.563638 +vt 0.186322 0.626276 +vt 0.186322 0.532933 +vt 0.186322 0.784719 +vt 0.186322 0.817883 +vt 0.218362 0.817883 +vt 0.186322 0.532933 +vt 0.186322 0.784719 +vt 0.186322 0.817883 +vt 0.218362 0.817883 +vt 0.186322 0.657596 +vt 0.186322 0.406348 +vt 0.186322 0.376797 +vt 0.186322 0.657596 +vt 0.186322 0.406348 +vt 0.186322 0.376797 +vn 0.6947 0.0000 -0.7193 +vn -0.7193 0.0000 -0.6947 +usemtl mcl_flowers_tallgrass.png +s 1 +f 170/1/1 59/2/1 3/3/1 79/4/1 +f 169/5/1 60/6/1 5/7/1 83/8/1 +f 168/9/2 62/10/2 2/11/2 78/12/2 +f 167/13/2 63/14/2 6/15/2 86/16/2 +f 166/17/2 68/18/2 10/19/2 87/20/2 +f 165/21/2 67/22/2 9/23/2 88/24/2 +f 164/25/1 66/26/1 8/27/1 89/28/1 +f 163/29/1 65/30/1 7/31/1 90/32/1 +f 162/33/2 91/34/2 38/35/2 72/36/2 +f 161/37/2 92/38/2 39/39/2 93/40/2 +f 160/41/2 94/42/2 12/43/2 56/44/2 +f 159/45/2 95/46/2 40/47/2 96/48/2 +f 158/49/1 97/50/1 37/51/1 71/52/1 +f 157/53/1 98/54/1 41/55/1 99/56/1 +f 156/57/1 100/58/1 13/59/1 57/60/1 +f 155/61/1 101/62/1 42/63/1 102/64/1 +f 154/65/1 81/66/1 25/67/1 105/68/1 +f 153/69/1 82/70/1 26/71/1 108/72/1 +f 152/73/1 109/74/1 34/75/1 70/76/1 +f 151/77/1 110/78/1 45/79/1 111/80/1 +f 150/81/1 112/82/1 17/83/1 61/84/1 +f 149/85/1 113/86/1 46/87/1 114/88/1 +f 148/89/2 84/90/2 28/91/2 117/92/2 +f 147/93/2 85/94/2 29/95/2 120/96/2 +f 146/97/2 121/98/2 31/99/2 69/100/2 +f 145/101/2 122/102/2 49/103/2 123/104/2 +f 144/105/2 124/106/2 20/107/2 64/108/2 +f 143/109/2 125/110/2 50/111/2 126/112/2 +f 142/113/2 76/114/2 19/115/2 129/116/2 +f 141/117/2 75/118/2 18/119/2 132/120/2 +f 140/121/1 74/122/1 16/123/1 135/124/1 +f 139/125/1 73/126/1 15/127/1 138/128/1 +f 137/129/1 139/125/1 138/128/1 54/130/1 +f 36/131/1 90/32/1 139/125/1 137/129/1 +f 90/32/1 7/31/1 73/126/1 139/125/1 +f 134/132/1 140/121/1 135/124/1 53/133/1 +f 35/134/1 89/28/1 140/121/1 134/132/1 +f 89/28/1 8/27/1 74/122/1 140/121/1 +f 131/135/2 141/117/2 132/120/2 52/136/2 +f 33/137/2 88/24/2 141/117/2 131/135/2 +f 88/24/2 9/23/2 75/118/2 141/117/2 +f 128/138/2 142/113/2 129/116/2 51/139/2 +f 32/140/2 87/20/2 142/113/2 128/138/2 +f 87/20/2 10/19/2 76/114/2 142/113/2 +f 76/114/2 143/109/2 126/112/2 19/115/2 +f 10/19/2 69/100/2 143/109/2 76/114/2 +f 69/100/2 31/99/2 125/110/2 143/109/2 +f 63/14/2 144/105/2 64/108/2 6/15/2 +f 19/115/2 126/112/2 144/105/2 63/14/2 +f 126/112/2 50/111/2 124/106/2 144/105/2 +f 85/94/2 145/101/2 123/104/2 29/95/2 +f 1/141/2 77/142/2 145/101/2 85/94/2 +f 77/142/2 21/143/2 122/102/2 145/101/2 +f 68/18/2 146/97/2 69/100/2 10/19/2 +f 29/144/2 123/145/2 146/97/2 68/18/2 +f 123/145/2 49/146/2 121/98/2 146/97/2 +f 119/147/2 147/93/2 120/96/2 48/148/2 +f 11/149/2 55/150/2 147/93/2 119/147/2 +f 55/150/2 1/141/2 85/94/2 147/93/2 +f 116/151/2 148/89/2 117/92/2 47/152/2 +f 30/153/2 86/16/2 148/89/2 116/151/2 +f 86/16/2 6/15/2 84/90/2 148/89/2 +f 74/122/1 149/85/1 114/88/1 16/123/1 +f 8/27/1 70/76/1 149/85/1 74/122/1 +f 70/76/1 34/75/1 113/86/1 149/85/1 +f 60/6/1 150/81/1 61/84/1 5/7/1 +f 16/123/1 114/88/1 150/81/1 60/6/1 +f 114/88/1 46/87/1 112/82/1 150/81/1 +f 82/70/1 151/77/1 111/80/1 26/71/1 +f 4/154/1 80/155/1 151/77/1 82/70/1 +f 80/155/1 24/156/1 110/78/1 151/77/1 +f 66/26/1 152/73/1 70/76/1 8/27/1 +f 26/157/1 111/158/1 152/73/1 66/26/1 +f 111/158/1 45/159/1 109/74/1 152/73/1 +f 107/160/1 153/69/1 108/72/1 44/161/1 +f 14/162/1 58/163/1 153/69/1 107/160/1 +f 58/163/1 4/154/1 82/70/1 153/69/1 +f 104/164/1 154/65/1 105/68/1 43/165/1 +f 27/166/1 83/8/1 154/65/1 104/164/1 +f 83/8/1 5/7/1 81/66/1 154/65/1 +f 73/126/1 155/61/1 102/64/1 15/127/1 +f 7/31/1 71/52/1 155/61/1 73/126/1 +f 71/52/1 37/51/1 101/62/1 155/61/1 +f 59/2/1 156/57/1 57/60/1 3/3/1 +f 15/127/1 102/64/1 156/57/1 59/2/1 +f 102/64/1 42/63/1 100/58/1 156/57/1 +f 81/66/1 157/53/1 99/56/1 25/67/1 +f 5/7/1 61/84/1 157/53/1 81/66/1 +f 61/84/1 17/83/1 98/54/1 157/53/1 +f 65/30/1 158/49/1 71/52/1 7/31/1 +f 25/67/1 99/56/1 158/49/1 65/30/1 +f 99/56/1 41/55/1 97/50/1 158/49/1 +f 75/118/2 159/45/2 96/48/2 18/119/2 +f 9/23/2 72/36/2 159/45/2 75/118/2 +f 72/36/2 38/35/2 95/46/2 159/45/2 +f 62/10/2 160/41/2 56/44/2 2/11/2 +f 18/119/2 96/48/2 160/41/2 62/10/2 +f 96/48/2 40/47/2 94/42/2 160/41/2 +f 84/90/2 161/37/2 93/40/2 28/91/2 +f 6/15/2 64/108/2 161/37/2 84/90/2 +f 64/108/2 20/107/2 92/38/2 161/37/2 +f 67/22/2 162/33/2 72/36/2 9/23/2 +f 28/91/2 93/40/2 162/33/2 67/22/2 +f 93/40/2 39/39/2 91/34/2 162/33/2 +f 103/167/1 163/29/1 90/32/1 36/131/1 +f 43/165/1 105/68/1 163/29/1 103/167/1 +f 105/68/1 25/67/1 65/30/1 163/29/1 +f 106/168/1 164/25/1 89/28/1 35/134/1 +f 44/169/1 108/170/1 164/25/1 106/168/1 +f 108/170/1 26/157/1 66/26/1 164/25/1 +f 115/171/2 165/21/2 88/24/2 33/137/2 +f 47/152/2 117/92/2 165/21/2 115/171/2 +f 117/92/2 28/91/2 67/22/2 165/21/2 +f 118/172/2 166/17/2 87/20/2 32/140/2 +f 48/173/2 120/174/2 166/17/2 118/172/2 +f 120/174/2 29/144/2 68/18/2 166/17/2 +f 127/175/2 167/13/2 86/16/2 30/153/2 +f 51/139/2 129/116/2 167/13/2 127/175/2 +f 129/116/2 19/115/2 63/14/2 167/13/2 +f 130/176/2 168/9/2 78/12/2 22/177/2 +f 52/136/2 132/120/2 168/9/2 130/176/2 +f 132/120/2 18/119/2 62/10/2 168/9/2 +f 133/178/1 169/5/1 83/8/1 27/166/1 +f 53/133/1 135/124/1 169/5/1 133/178/1 +f 135/124/1 16/123/1 60/6/1 169/5/1 +f 136/179/1 170/1/1 79/4/1 23/180/1 +f 54/130/1 138/128/1 170/1/1 136/179/1 +f 138/128/1 15/127/1 59/2/1 170/1/1 +o plant_test +v -0.000842 0.420173 0.000152 +v -0.000842 0.420173 0.000152 +v 0.190595 0.340629 0.003494 +v 0.002500 0.340629 -0.191284 +v -0.192278 0.340629 -0.003189 +v -0.004183 0.340629 0.191589 +v 0.094876 0.380401 0.001823 +v 0.193936 0.340629 -0.187943 +v 0.187253 0.340629 0.194930 +v 0.000829 0.380401 -0.095566 +v -0.188937 0.340629 -0.194626 +v 0.193936 0.340629 -0.187943 +v -0.096560 0.380401 -0.001519 +v -0.195620 0.340629 0.188247 +v -0.188937 0.340629 -0.194626 +v -0.002513 0.380401 0.095870 +v 0.187253 0.340629 0.194930 +v -0.195620 0.340629 0.188247 +v 0.188924 0.380401 0.099212 +v -0.099901 0.380401 0.189918 +v -0.190607 0.380401 -0.098907 +v 0.098218 0.380401 -0.189613 +v 0.091535 0.380401 0.193259 +v 0.192265 0.380401 -0.092225 +v -0.093219 0.380401 -0.192955 +v -0.193949 0.380401 0.092529 +vt 0.373047 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.373047 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.312500 0.821932 +vt 0.500000 0.821932 +vt 0.500000 0.691073 +vt 0.312500 0.691073 +vt 0.701172 0.821932 +vt 0.701172 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vt 0.623047 0.821932 +vt 0.623047 0.691073 +vn 0.0067 -0.9235 -0.3836 +vn 0.3836 -0.9235 0.0067 +vn -0.0067 -0.9235 0.3836 +vn -0.3836 -0.9235 -0.0067 +usemtl mcl_ocean_bubble_coral_fan.png +s 1 +f 187/181/3 176/182/3 186/183/3 189/184/3 +f 184/185/4 175/186/4 183/187/4 190/188/4 +f 181/189/5 174/190/5 180/191/5 191/192/5 +f 178/193/6 173/194/6 177/195/6 192/196/6 +f 173/194/6 179/197/6 193/198/6 177/195/6 +f 174/190/5 182/199/5 194/200/5 180/191/5 +f 175/186/4 185/201/4 195/202/4 183/187/4 +f 176/182/3 188/203/3 196/204/3 186/183/3 +l 177 171 +l 180 172 +l 183 171 +l 186 172 +o Cube +v -0.093808 0.196026 0.093233 +v -0.093808 0.390929 0.093233 +v -0.093808 0.196026 -0.093233 +v -0.093808 0.390929 -0.093233 +v 0.093808 0.196026 0.093233 +v 0.093808 0.390929 0.093233 +v 0.093808 0.196026 -0.093233 +v 0.093808 0.390929 -0.093233 +v -0.093808 0.196026 0.000000 +v -0.093808 0.290470 0.093233 +v -0.093808 0.390929 0.000000 +v -0.093808 0.290470 -0.093233 +v -0.000000 0.196026 -0.093233 +v -0.000000 0.390929 -0.093233 +v 0.093808 0.290470 -0.093233 +v 0.093808 0.196026 0.000000 +v 0.093808 0.390929 0.000000 +v 0.093808 0.290470 0.093233 +v -0.000000 0.196026 0.093233 +v -0.000000 0.390929 0.093233 +v -0.000000 0.390929 0.000000 +v -0.000000 0.196026 0.000000 +v -0.000000 0.290470 0.093233 +v 0.093808 0.290470 0.000000 +v -0.000000 0.290470 -0.093233 +v -0.093808 0.290470 0.000000 +v -0.093808 0.196026 0.092775 +v -0.093808 0.290971 0.093233 +v -0.093808 0.390929 -0.092775 +v -0.093808 0.197014 -0.093233 +v -0.092974 0.196026 -0.093233 +v 0.092974 0.390929 -0.093233 +v 0.093808 0.197014 -0.093233 +v 0.093808 0.196026 -0.092775 +v 0.093808 0.390929 0.092775 +v 0.093808 0.197014 0.093233 +v 0.092974 0.196026 0.093233 +v -0.092974 0.390929 0.093233 +v -0.093808 0.196026 -0.092775 +v -0.093808 0.197014 0.093233 +v -0.093808 0.390929 0.092775 +v -0.093808 0.290971 -0.093233 +v 0.092974 0.196026 -0.093233 +v -0.092974 0.390929 -0.093233 +v 0.093808 0.290971 -0.093233 +v 0.093808 0.196026 0.092775 +v 0.093808 0.390929 -0.092775 +v 0.093808 0.290971 0.093233 +v -0.092974 0.196026 0.093233 +v 0.092974 0.390929 0.093233 +v -0.000000 0.390929 0.092775 +v -0.000000 0.390929 -0.092775 +v 0.092974 0.390929 0.000000 +v -0.092974 0.390929 0.000000 +v -0.000000 0.196026 0.092775 +v -0.000000 0.196026 -0.092775 +v -0.092974 0.196026 0.000000 +v 0.092974 0.196026 0.000000 +v -0.092974 0.290470 0.093233 +v 0.092974 0.290470 0.093233 +v -0.000000 0.197014 0.093233 +v -0.000000 0.290971 0.093233 +v 0.093808 0.290470 0.092775 +v 0.093808 0.290470 -0.092775 +v 0.093808 0.197014 0.000000 +v 0.093808 0.290971 0.000000 +v 0.092974 0.290470 -0.093233 +v -0.092974 0.290470 -0.093233 +v -0.000000 0.197014 -0.093233 +v -0.000000 0.290971 -0.093233 +v -0.093808 0.290470 -0.092775 +v -0.093808 0.290470 0.092775 +v -0.093808 0.197014 0.000000 +v -0.093808 0.290971 0.000000 +v -0.093808 0.290971 0.092775 +v -0.093808 0.197014 0.092775 +v -0.093808 0.197014 -0.092775 +v -0.092974 0.290971 -0.093233 +v -0.092974 0.197014 -0.093233 +v 0.092974 0.197014 -0.093233 +v 0.093808 0.290971 -0.092775 +v 0.093808 0.197014 -0.092775 +v 0.093808 0.197014 0.092775 +v 0.092974 0.290971 0.093233 +v 0.092974 0.197014 0.093233 +v -0.092974 0.197014 0.093233 +v 0.092974 0.196026 -0.092775 +v -0.092974 0.196026 -0.092775 +v -0.092974 0.196026 0.092775 +v -0.092974 0.390929 -0.092775 +v 0.092974 0.390929 -0.092775 +v 0.092974 0.390929 0.092775 +v -0.092974 0.390929 0.092775 +v 0.092974 0.196026 0.092775 +v -0.092974 0.290971 0.093233 +v 0.093808 0.290971 0.092775 +v 0.092974 0.290971 -0.093233 +v -0.093808 0.290971 -0.092775 +vt 0.502042 0.373047 +vt 0.564542 0.373047 +vt 0.564542 0.435547 +vt 0.502042 0.435547 +vt 0.502042 0.437500 +vt 0.564542 0.437500 +vt 0.564542 0.500000 +vt 0.502042 0.500000 +vt 0.502042 0.687500 +vt 0.564542 0.687500 +vt 0.564542 0.750000 +vt 0.502042 0.750000 +vt 0.066619 0.765683 +vt 0.129119 0.765683 +vt 0.129119 0.879860 +vt 0.066619 0.879860 +vt 0.436154 0.687500 +vt 0.436520 0.687500 +vt 0.436520 0.750000 +vt 0.436154 0.750000 +vt 0.000020 0.937269 +vt 0.124039 0.937269 +vt 0.124039 0.999769 +vt 0.000020 0.999769 +vt 0.000020 0.937269 +vt 0.124039 0.937269 +vt 0.124039 0.999769 +vt 0.000020 0.999769 +vt 0.000957 0.875000 +vt 0.124977 0.875000 +vt 0.124977 0.937500 +vt 0.000957 0.937500 +vt 0.000020 0.812269 +vt 0.124039 0.812269 +vt 0.124039 0.874769 +vt 0.000020 0.874769 +vt 0.000596 0.374981 +vt 0.124500 0.374981 +vt 0.124500 0.437481 +vt 0.000596 0.437481 +vt 0.000577 0.250031 +vt 0.126692 0.250031 +vt 0.126692 0.376511 +vt 0.000577 0.376511 +vt 0.436154 0.562500 +vt 0.436520 0.562500 +vt 0.436520 0.625000 +vt 0.436154 0.625000 +vt 0.063596 0.765683 +vt 0.064577 0.765683 +vt 0.064577 0.879860 +vt 0.063596 0.879860 +vt 0.065922 0.760824 +vt 0.066902 0.760824 +vt 0.066902 0.823324 +vt 0.065922 0.823324 +vt 0.066496 0.688477 +vt 0.128996 0.688477 +vt 0.128996 0.815430 +vt 0.066496 0.815430 +vt 0.499020 0.687500 +vt 0.500000 0.687500 +vt 0.500000 0.750000 +vt 0.499020 0.750000 +vt 0.065922 0.687500 +vt 0.066902 0.687500 +vt 0.066902 0.750000 +vt 0.065922 0.750000 +vt 0.064542 0.687500 +vt 0.127042 0.687500 +vt 0.127042 0.812500 +vt 0.064542 0.812500 +vt 0.499020 0.437500 +vt 0.500000 0.437500 +vt 0.500000 0.500000 +vt 0.499020 0.500000 +vt 0.065426 0.740234 +vt 0.066406 0.740234 +vt 0.066406 0.802734 +vt 0.065426 0.802734 +vt 0.066496 0.689453 +vt 0.128996 0.689453 +vt 0.128996 0.814453 +vt 0.066496 0.814453 +vt 0.499020 0.373047 +vt 0.500000 0.373047 +vt 0.500000 0.435547 +vt 0.499020 0.435547 +vt 0.065922 0.690000 +vt 0.066902 0.690000 +vt 0.066902 0.752500 +vt 0.065922 0.752500 +vt 0.064542 0.690000 +vt 0.127042 0.690000 +vt 0.127042 0.815000 +vt 0.064542 0.815000 +vt 0.068945 0.690000 +vt 0.068945 0.752500 +vt 0.500000 0.308594 +vt 0.502042 0.308594 +vt 0.502042 0.371094 +vt 0.500000 0.371094 +vt 0.564542 0.308594 +vt 0.564542 0.371094 +vt -0.000980 0.690000 +vt 0.061520 0.690000 +vt 0.061520 0.815000 +vt -0.000980 0.815000 +vt 0.436520 0.308594 +vt 0.499020 0.308594 +vt 0.499020 0.371094 +vt 0.436520 0.371094 +vt 0.436520 0.373047 +vt 0.436520 0.435547 +vt 0.061520 0.877500 +vt -0.000980 0.877500 +vt 0.066902 0.815000 +vt 0.065922 0.815000 +vt 0.068449 0.740234 +vt 0.068449 0.802734 +vt 0.502042 0.312500 +vt 0.500000 0.312500 +vt 0.502042 0.689453 +vt 0.564542 0.689453 +vt 0.564542 0.751953 +vt 0.502042 0.751953 +vt 0.000973 0.689453 +vt 0.063473 0.689453 +vt 0.063473 0.814453 +vt 0.000973 0.814453 +vt 0.436520 0.689453 +vt 0.499020 0.689453 +vt 0.499020 0.751953 +vt 0.436520 0.751953 +vt 0.499020 0.312500 +vt 0.436520 0.437500 +vt 0.436520 0.500000 +vt 0.063473 0.876953 +vt 0.000973 0.876953 +vt 0.066406 0.865234 +vt 0.065426 0.865234 +vt 0.068945 0.687500 +vt 0.068945 0.750000 +vt 0.502042 0.562500 +vt 0.500000 0.562500 +vt 0.564542 0.562500 +vt -0.000980 0.687500 +vt 0.061520 0.687500 +vt 0.061520 0.812500 +vt -0.000980 0.812500 +vt 0.499020 0.562500 +vt 0.061520 0.875000 +vt -0.000980 0.875000 +vt 0.066902 0.812500 +vt 0.065922 0.812500 +vt 0.068945 0.760824 +vt 0.068945 0.823324 +vt 0.502042 0.812500 +vt 0.500000 0.812500 +vt 0.564542 0.812500 +vt 0.000973 0.688477 +vt 0.063473 0.688477 +vt 0.063473 0.815430 +vt 0.000973 0.815430 +vt 0.499020 0.812500 +vt 0.436520 0.812500 +vt 0.001096 0.765683 +vt 0.001096 0.879860 +vt 0.063473 0.879883 +vt 0.000973 0.879883 +vt 0.000577 0.250031 +vt 0.000577 0.376511 +vt 0.499769 0.500000 +vt 0.436154 0.500000 +vt 0.499769 0.562500 +vt 0.124500 0.249981 +vt 0.000596 0.312481 +vt 0.124500 0.312481 +vt 0.499769 0.500000 +vt 0.436154 0.500000 +vt 0.436154 0.562500 +vt 0.499769 0.562500 +vt 0.124500 0.374981 +vt 0.124500 0.437481 +vt 0.126692 0.439011 +vt 0.000577 0.439011 +vt 0.000957 0.875000 +vt 0.000957 0.937500 +vt 0.564430 0.500000 +vt 0.501930 0.500000 +vt 0.501930 0.562500 +vt 0.564430 0.562500 +vt 0.564430 0.500000 +vt 0.564430 0.562500 +vt 0.501930 0.562500 +vt 0.501930 0.625000 +vt 0.564542 0.625000 +vt 0.501930 0.500000 +vt 0.501930 0.687500 +vt 0.501930 0.750000 +vt 0.124977 1.000000 +vt 0.000957 1.000000 +vt 0.000957 1.000000 +vt 0.000596 0.374981 +vt 0.000596 0.437481 +vt 0.000577 0.439011 +vt 0.128996 0.879883 +vt 0.066496 0.879883 +vt 0.068945 0.812500 +vt 0.127042 0.875000 +vt 0.064542 0.875000 +vt 0.068449 0.865234 +vt 0.128996 0.876953 +vt 0.066496 0.876953 +vt 0.068945 0.815000 +vt 0.127042 0.877500 +vt 0.064542 0.877500 +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 +usemtl Material +s off +f 294/205/7 225/206/7 200/207/7 238/208/7 +f 293/209/8 228/210/8 204/211/8 241/212/8 +f 292/213/9 231/214/9 202/215/9 244/216/9 +f 291/217/10 234/218/10 198/219/10 224/220/10 +f 290/221/11 242/222/11 201/223/11 233/224/11 +f 289/225/12 237/226/12 198/227/12 234/228/12 +f 288/229/12 247/230/12 216/231/12 246/232/12 +f 287/233/12 248/234/12 217/235/12 249/236/12 +f 286/237/12 225/238/12 207/239/12 250/240/12 +f 285/241/11 251/242/11 215/243/11 245/244/11 +f 284/245/11 252/246/11 218/247/11 253/248/11 +f 283/249/11 230/250/11 212/251/11 254/252/11 +f 282/253/10 255/254/10 206/255/10 236/256/10 +f 281/257/10 256/258/10 219/259/10 257/260/10 +f 280/261/10 246/262/10 216/263/10 258/264/10 +f 279/265/9 259/266/9 214/267/9 232/268/9 +f 278/269/9 260/270/9 220/271/9 261/272/9 +f 277/273/9 243/274/9 213/275/9 262/276/9 +f 276/277/8 263/278/8 211/279/8 229/280/8 +f 275/281/8 264/282/8 221/283/8 265/284/8 +f 274/285/8 240/286/8 210/287/8 266/288/8 +f 273/289/7 267/290/7 208/291/7 226/292/7 +f 272/293/7 268/294/7 222/295/7 269/296/7 +f 271/297/7 237/298/7 207/299/7 270/300/7 +f 268/294/7 271/301/7 270/302/7 222/295/7 +f 206/303/7 224/304/7 271/305/7 268/306/7 +f 224/304/7 198/307/7 237/308/7 271/305/7 +f 223/309/7 272/310/7 269/311/7 205/312/7 +f 197/313/7 236/314/7 272/315/7 223/316/7 +f 236/314/7 206/303/7 268/306/7 272/315/7 +f 235/317/7 273/289/7 226/292/7 199/318/7 +f 205/312/7 269/311/7 273/319/7 235/320/7 +f 269/296/7 222/295/7 267/321/7 273/322/7 +f 264/282/8 274/323/8 266/324/8 221/283/8 +f 208/291/8 238/208/8 274/325/8 264/326/8 +f 238/327/8 200/328/8 240/329/8 274/330/8 +f 227/331/8 275/332/8 265/333/8 209/334/8 +f 199/335/8 226/336/8 275/337/8 227/338/8 +f 226/292/8 208/291/8 264/326/8 275/339/8 +f 239/340/8 276/277/8 229/280/8 203/341/8 +f 209/334/8 265/333/8 276/342/8 239/343/8 +f 265/284/8 221/283/8 263/344/8 276/345/8 +f 260/270/9 277/346/9 262/347/9 220/271/9 +f 211/279/9 241/212/9 277/348/9 260/349/9 +f 241/212/9 204/211/9 243/350/9 277/348/9 +f 230/351/9 278/352/9 261/353/9 212/354/9 +f 203/341/9 229/280/9 278/355/9 230/250/9 +f 229/280/9 211/279/9 260/349/9 278/355/9 +f 242/222/9 279/265/9 232/268/9 201/223/9 +f 212/354/9 261/353/9 279/356/9 242/357/9 +f 261/272/9 220/271/9 259/358/9 279/359/9 +f 256/258/10 280/360/10 258/361/10 219/259/10 +f 214/267/10 244/216/10 280/362/10 256/363/10 +f 244/216/10 202/215/10 246/364/10 280/362/10 +f 233/365/10 281/366/10 257/367/10 215/368/10 +f 201/223/10 232/268/10 281/369/10 233/370/10 +f 232/268/10 214/267/10 256/363/10 281/369/10 +f 245/371/10 282/253/10 236/256/10 197/372/10 +f 215/368/10 257/367/10 282/373/10 245/374/10 +f 257/260/10 219/259/10 255/254/10 282/253/10 +f 252/246/11 283/375/11 254/376/11 218/247/11 +f 209/377/11 239/378/11 283/249/11 252/379/11 +f 239/378/11 203/341/11 230/250/11 283/249/11 +f 235/380/11 284/245/11 253/381/11 205/382/11 +f 199/383/11 227/384/11 284/385/11 235/386/11 +f 227/384/11 209/377/11 252/379/11 284/385/11 +f 223/387/11 285/241/11 245/244/11 197/388/11 +f 205/382/11 253/381/11 285/241/11 223/387/11 +f 253/248/11 218/247/11 251/389/11 285/390/11 +f 248/234/12 286/391/12 250/392/12 217/235/12 +f 210/393/12 240/394/12 286/395/12 248/396/12 +f 240/394/12 200/397/12 225/398/12 286/395/12 +f 243/350/12 287/399/12 249/400/12 213/401/12 +f 204/211/12 228/402/12 287/399/12 243/350/12 +f 228/402/12 210/393/12 248/396/12 287/399/12 +f 231/214/12 288/403/12 246/404/12 202/215/12 +f 213/401/12 249/400/12 288/403/12 231/214/12 +f 249/236/12 217/235/12 247/405/12 288/406/12 +f 247/230/12 289/225/12 234/228/12 216/231/12 +f 217/235/12 250/392/12 289/407/12 247/405/12 +f 250/240/12 207/239/12 237/226/12 289/225/12 +f 251/242/11 290/408/11 233/409/11 215/243/11 +f 218/247/11 254/376/11 290/410/11 251/389/11 +f 254/252/11 212/251/11 242/222/11 290/221/11 +f 255/254/10 291/217/10 224/220/10 206/255/10 +f 219/259/10 258/361/10 291/217/10 255/254/10 +f 258/264/10 216/263/10 234/411/10 291/412/10 +f 259/266/9 292/213/9 244/216/9 214/267/9 +f 220/271/9 262/347/9 292/413/9 259/358/9 +f 262/276/9 213/275/9 231/414/9 292/415/9 +f 263/278/8 293/209/8 241/212/8 211/279/8 +f 221/283/8 266/324/8 293/416/8 263/344/8 +f 266/288/8 210/287/8 228/417/8 293/418/8 +f 267/290/7 294/205/7 238/208/7 208/291/7 +f 222/295/7 270/302/7 294/419/7 267/321/7 +f 270/300/7 207/299/7 225/420/7 294/421/7 diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts new file mode 100644 index 000000000..630117463 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_bee_nest.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts new file mode 100644 index 000000000..68e66e425 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_1.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts new file mode 100644 index 000000000..5307d7d32 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_2.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts new file mode 100644 index 000000000..96e3f0e66 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_3.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts new file mode 100644 index 000000000..46f3e3b59 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_4.mts differ diff --git a/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts new file mode 100644 index 000000000..35e3ed120 Binary files /dev/null and b/mods/ITEMS/mcl_mangrove/schematics/mcl_mangrove_tree_5.mts differ diff --git a/mods/ITEMS/mcl_maps/colors.json b/mods/ITEMS/mcl_maps/colors.json new file mode 100644 index 000000000..4929a2f66 --- /dev/null +++ b/mods/ITEMS/mcl_maps/colors.json @@ -0,0 +1,10207 @@ +{ + "player.png": [ + 123, + 74, + 62 + ], + "player_back.png": [ + 114, + 68, + 56 + ], + "mcl_skins_button.png": [ + 121, + 95, + 85 + ], + "mcl_skins_character_1.png": [ + 93, + 90, + 77 + ], + "mcl_hunger_bar_saturation.png": [ + 255, + 255, + 0 + ], + "hbhunger_bar_health_poison.png": [ + 148, + 120, + 24 + ], + "mcl_hunger_bar_exhaustion.png": [ + 255, + 255, + 255 + ], + "mcl_hunger_icon_exhaustion.png": [ + 213, + 213, + 213 + ], + "mcl_hunger_bgicon_exhaustion.png": [ + 25, + 25, + 26 + ], + "mcl_hunger_icon_foodpoison.png": [ + 109, + 106, + 40 + ], + "mcl_hunger_bgicon_saturation.png": [ + 24, + 24, + 26 + ], + "hbhunger_bar.png": [ + 200, + 103, + 0 + ], + "hbhunger_bgicon.png": [ + 24, + 24, + 26 + ], + "hbhunger_icon_health_poison.png": [ + 69, + 98, + 45 + ], + "mcl_hunger_bar_foodpoison.png": [ + 116, + 132, + 88 + ], + "hbhunger_icon.png": [ + 175, + 132, + 97 + ], + "mcl_hunger_icon_saturation.png": [ + 157, + 140, + 64 + ], + "mcl_playerplus_end_sky.png": [ + 14, + 14, + 14 + ], + "mobs_mc_llama_decor_purple.png": [ + 108, + 72, + 115 + ], + "mobs_mc_spawn_icon_illusioner.png": [ + 98, + 111, + 155 + ], + "mobs_mc_llama_gray.png": [ + 195, + 188, + 175 + ], + "mobs_mc_spawn_icon_zombie.png": [ + 64, + 136, + 112 + ], + "mobs_mc_llama_decor_blue.png": [ + 117, + 121, + 156 + ], + "mobs_mc_spawn_icon_skeleton.png": [ + 146, + 146, + 146 + ], + "mobs_mc_shulker_blue.png": [ + 89, + 100, + 126 + ], + "mobs_mc_shulker_black.png": [ + 78, + 75, + 76 + ], + "mobs_mc_wolf_collar.png": [ + 186, + 186, + 186 + ], + "mobs_mc_spawn_icon_bat.png": [ + 130, + 63, + 13 + ], + "mobs_mc_villager_weaponsmith.png": [ + 75, + 74, + 62 + ], + "mobs_mc_parrot_green.png": [ + 47, + 208, + 62 + ], + "mobs_mc_llama_decor_magenta.png": [ + 186, + 84, + 131 + ], + "mobs_mc_rabbit_black.png": [ + 73, + 64, + 61 + ], + "mobs_mc_vindicator.png": [ + 56, + 56, + 57 + ], + "mobs_mc_polarbear.png": [ + 233, + 220, + 208 + ], + "mobs_mc_magmacube.png": [ + 83, + 40, + 27 + ], + "mobs_mc_chicken.png": [ + 198, + 182, + 176 + ], + "mobs_mc_villager_toolsmith.png": [ + 78, + 76, + 64 + ], + "mobs_mc_ghast_firing.png": [ + 198, + 198, + 198 + ], + "mobs_mc_spawn_icon_zombie_pigman.png": [ + 202, + 160, + 135 + ], + "mobs_mc_husk.png": [ + 98, + 95, + 76 + ], + "mobs_mc_villager_librarian.png": [ + 167, + 161, + 151 + ], + "mobs_mc_villager_priest.png": [ + 119, + 112, + 98 + ], + "mobs_mc_villager_fletcher.png": [ + 84, + 86, + 52 + ], + "mobs_mc_villager_smith.png": [ + 76, + 76, + 63 + ], + "mobs_mc_spawn_icon_dragon.png": [ + 98, + 47, + 89 + ], + "mobs_mc_spawn_icon_donkey.png": [ + 152, + 132, + 100 + ], + "mobs_mc_squid.png": [ + 37, + 52, + 68 + ], + "mobs_mc_villager_farmer.png": [ + 94, + 87, + 70 + ], + "mobs_mc_spawn_icon_horse_skeleton.png": [ + 245, + 204, + 202 + ], + "mobs_mc_villager_sheperd.png": [ + 97, + 98, + 66 + ], + "mobs_mc_horse_markings_blackdots.png": [ + 24, + 22, + 22 + ], + "mobs_mc_zombie_farmer.png": [ + 119, + 99, + 85 + ], + "mobs_mc_spawn_icon_vex.png": [ + 145, + 185, + 185 + ], + "mobs_mc_villager_armorer.png": [ + 86, + 87, + 55 + ], + "mobs_mc_parrot_blue.png": [ + 43, + 58, + 148 + ], + "mobs_mc_spider_eyes.png": [ + 174, + 48, + 48 + ], + "mobs_mc_zombie.png": [ + 78, + 110, + 105 + ], + "mobs_mc_llama_decor_light_blue.png": [ + 116, + 200, + 250 + ], + "mobs_mc_zombie_priest.png": [ + 120, + 104, + 110 + ], + "mobs_mc_llama_decor_black.png": [ + 12, + 8, + 24 + ], + "mobs_mc_horse_white.png": [ + 190, + 173, + 154 + ], + "mobs_mc_spawn_icon_vindicator.png": [ + 102, + 103, + 104 + ], + "mobs_mc_silverfish.png": [ + 179, + 164, + 144 + ], + "mobs_mc_llama_decor_gray.png": [ + 110, + 110, + 110 + ], + "mobs_mc_spawn_icon_guardian.png": [ + 119, + 156, + 148 + ], + "mobs_mc_creeper.png": [ + 98, + 107, + 71 + ], + "mobs_mc_shulker_purple.png": [ + 135, + 87, + 99 + ], + "mobs_mc_spawn_icon_rabbit.png": [ + 156, + 126, + 84 + ], + "mobs_mc_sheep.png": [ + 182, + 161, + 149 + ], + "mobs_mc_parrot_grey.png": [ + 33, + 178, + 173 + ], + "mobs_mc_wolf_icon_sit.png": [ + 8, + 88, + 116 + ], + "mobs_mc_gold_horse_armor.png": [ + 140, + 106, + 67 + ], + "mobs_mc_spawn_icon_witch.png": [ + 98, + 85, + 68 + ], + "mobs_mc_shulker_green.png": [ + 89, + 122, + 84 + ], + "mobs_mc_bat.png": [ + 87, + 63, + 54 + ], + "mobs_mc_villager_cartographer.png": [ + 164, + 157, + 145 + ], + "mobs_mc_horse_chestnut.png": [ + 126, + 78, + 58 + ], + "mobs_mc_shulker_yellow.png": [ + 175, + 128, + 69 + ], + "mobs_mc_spawn_icon_creeper.png": [ + 115, + 125, + 53 + ], + "mobs_mc_slime.png": [ + 63, + 133, + 78 + ], + "mobs_mc_evoker.png": [ + 44, + 48, + 43 + ], + "mobs_mc_horse_skeleton.png": [ + 163, + 156, + 141 + ], + "mobs_mc_spawn_icon_blaze.png": [ + 142, + 76, + 49 + ], + "mobs_mc_shulker_light_blue.png": [ + 114, + 140, + 158 + ], + "mobs_mc_shulker_gray.png": [ + 106, + 104, + 109 + ], + "mobs_mc_horse_darkbrown.png": [ + 69, + 47, + 34 + ], + "mobs_mc_stray_overlay.png": [ + 63, + 59, + 65 + ], + "mobs_mc_arrow_particle.png": [ + 218, + 171, + 136 + ], + "mobs_mc_spawn_icon_cat.png": [ + 120, + 66, + 10 + ], + "mobs_mc_stray.png": [ + 155, + 157, + 161 + ], + "mobs_mc_villager_nitwit.png": [ + 91, + 93, + 60 + ], + "mobs_mc_trading_formspec_bg.png": [ + 157, + 157, + 157 + ], + "mobs_mc_spawn_icon_villager.png": [ + 134, + 124, + 81 + ], + "mobs_mc_pig.png": [ + 228, + 175, + 165 + ], + "mobs_mc_spawn_icon_mooshroom.png": [ + 160, + 56, + 55 + ], + "mobs_mc_wolf_angry.png": [ + 187, + 179, + 176 + ], + "mobs_mc_cat_black.png": [ + 206, + 181, + 154 + ], + "mobs_mc_vex_charging.png": [ + 142, + 153, + 153 + ], + "mobs_mc_llama.png": [ + 207, + 189, + 155 + ], + "mobs_mc_mushroom_brown.png": [ + 122, + 81, + 58 + ], + "mobs_mc_spawn_icon_shulker.png": [ + 170, + 117, + 130 + ], + "mobs_mc_wither_half_health.png": [ + 7, + 58, + 91 + ], + "mobs_mc_spawn_icon_guardian_elder.png": [ + 174, + 140, + 113 + ], + "mobs_mc_enderman_eyes.png": [ + 184, + 211, + 242 + ], + "mobs_mc_horse_creamy.png": [ + 146, + 111, + 75 + ], + "mobs_mc_spawn_icon_zombie_villager.png": [ + 95, + 110, + 68 + ], + "mobs_mc_vex.png": [ + 128, + 162, + 162 + ], + "mobs_mc_iron_golem.png": [ + 47, + 44, + 44 + ], + "mobs_mc_cat_ocelot.png": [ + 163, + 111, + 52 + ], + "mobs_mc_llama_decor_green.png": [ + 51, + 84, + 27 + ], + "mobs_mc_cow.png": [ + 94, + 68, + 55 + ], + "mobs_mc_llama_decor_brown.png": [ + 85, + 58, + 46 + ], + "mobs_mc_villager_butcher.png": [ + 95, + 92, + 79 + ], + "mobs_mc_parrot_yellow_blue.png": [ + 98, + 187, + 205 + ], + "mobs_mc_zombie_pigman.png": [ + 164, + 129, + 117 + ], + "mobs_mc_spawn_icon_wolf.png": [ + 231, + 218, + 207 + ], + "mobs_mc_zombie_villager.png": [ + 112, + 108, + 90 + ], + "mobs_mc_sheep_fur.png": [ + 203, + 186, + 174 + ], + "mobs_mc_spawn_icon_horse_zombie.png": [ + 129, + 143, + 66 + ], + "mobs_mc_blaze.png": [ + 84, + 63, + 50 + ], + "mobs_mc_rabbit_salt.png": [ + 122, + 99, + 87 + ], + "mobs_mc_rabbit_white_splotched.png": [ + 146, + 139, + 135 + ], + "mobs_mc_horse_brown.png": [ + 115, + 84, + 61 + ], + "mobs_mc_ghast.png": [ + 199, + 199, + 199 + ], + "mobs_mc_horse_markings_white.png": [ + 165, + 149, + 132 + ], + "mobs_mc_horse_markings_whitefield.png": [ + 193, + 178, + 162 + ], + "mobs_mc_spawn_icon_endermite.png": [ + 138, + 67, + 74 + ], + "mobs_mc_shulker_magenta.png": [ + 143, + 97, + 130 + ], + "mobs_mc_snowman.png": [ + 211, + 217, + 221 + ], + "mobs_mc_zombie_smith.png": [ + 71, + 59, + 54 + ], + "mobs_mc_spawn_icon_squid.png": [ + 55, + 58, + 103 + ], + "mobs_mc_dragon_fireball.png": [ + 89, + 66, + 79 + ], + "mobs_mc_diamond_horse_armor.png": [ + 67, + 95, + 112 + ], + "mobs_mc_rabbit_toast.png": [ + 130, + 123, + 119 + ], + "mobs_mc_llama_white.png": [ + 207, + 199, + 184 + ], + "mobs_mc_llama_creamy.png": [ + 208, + 190, + 155 + ], + "mobs_mc_pig_saddle.png": [ + 82, + 63, + 45 + ], + "mobs_mc_spawn_icon_cave_spider.png": [ + 23, + 43, + 57 + ], + "mobs_mc_shulker_silver.png": [ + 140, + 138, + 143 + ], + "mobs_mc_trading_formspec_disabled.png": [ + 193, + 26, + 26 + ], + "mobs_mc_spider.png": [ + 41, + 38, + 37 + ], + "mobs_mc_wither.png": [ + 33, + 33, + 33 + ], + "mobs_mc_llama_decor_white.png": [ + 231, + 231, + 231 + ], + "mobs_mc_witch.png": [ + 80, + 74, + 67 + ], + "mobs_mc_wolf_icon_roam.png": [ + 6, + 124, + 36 + ], + "mobs_mc_illusionist.png": [ + 56, + 68, + 114 + ], + "mobs_mc_endermite.png": [ + 55, + 20, + 65 + ], + "mobs_mc_spawn_icon_witherskeleton.png": [ + 71, + 71, + 71 + ], + "mobs_mc_llama_decor_light_gray.png": [ + 201, + 201, + 201 + ], + "mobs_mc_llama_decor_cyan.png": [ + 20, + 157, + 160 + ], + "mobs_mc_skeleton.png": [ + 124, + 124, + 124 + ], + "mobs_mc_spawn_icon_llama.png": [ + 230, + 221, + 178 + ], + "mobs_mc_spawn_icon_chicken.png": [ + 170, + 160, + 156 + ], + "mobs_mc_shulker_pink.png": [ + 173, + 127, + 160 + ], + "mobs_mc_spawn_icon_spider.png": [ + 53, + 43, + 43 + ], + "mobs_mc_shulker_red.png": [ + 146, + 77, + 71 + ], + "mobs_mc_shulker_white.png": [ + 184, + 181, + 186 + ], + "mobs_mc_spawn_icon_magmacube.png": [ + 52, + 33, + 23 + ], + "mobs_mc_spawn_icon_ghast.png": [ + 212, + 212, + 212 + ], + "mobs_mc_rabbit_brown.png": [ + 112, + 86, + 73 + ], + "mobs_mc_spawn_icon_pig.png": [ + 242, + 200, + 188 + ], + "mobs_mc_spawn_icon_horse.png": [ + 44, + 36, + 25 + ], + "mobs_mc_cat_siamese.png": [ + 161, + 144, + 133 + ], + "mobs_mc_mushroom_red.png": [ + 176, + 51, + 49 + ], + "mobs_mc_shulker_brown.png": [ + 94, + 81, + 70 + ], + "mobs_mc_villager_leatherworker.png": [ + 96, + 93, + 58 + ], + "mobs_mc_guardian.png": [ + 78, + 116, + 130 + ], + "mobs_mc_creeper_charge.png": [ + 121, + 219, + 255 + ], + "mobs_mc_villager.png": [ + 88, + 91, + 55 + ], + "mobs_mc_llama_decor_lime.png": [ + 170, + 214, + 67 + ], + "mobs_mc_llama_brown.png": [ + 136, + 97, + 52 + ], + "mobs_mc_enderman_cactus_background.png": [ + 44, + 71, + 27 + ], + "mobs_mc_parrot_red_blue.png": [ + 171, + 70, + 37 + ], + "mobs_mc_spawn_icon_husk.png": [ + 174, + 174, + 128 + ], + "mobs_mc_rabbit_gold.png": [ + 151, + 130, + 96 + ], + "mobs_mc_spawn_icon_evoker.png": [ + 92, + 103, + 86 + ], + "mobs_mc_iron_horse_armor.png": [ + 133, + 119, + 114 + ], + "mobs_mc_llama_decor_red.png": [ + 215, + 58, + 50 + ], + "mobs_mc_enderman.png": [ + 3, + 10, + 10 + ], + "mobs_mc_mooshroom_brown.png": [ + 93, + 50, + 28 + ], + "mobs_mc_llama_decor_pink.png": [ + 207, + 140, + 182 + ], + "mobs_mc_enderman_block.png": [ + 46, + 42, + 38 + ], + "mobs_mc_mooshroom.png": [ + 90, + 42, + 41 + ], + "mobs_mc_cat_red.png": [ + 221, + 163, + 120 + ], + "mobs_mc_shulkerbullet.png": [ + 216, + 190, + 153 + ], + "mobs_mc_horse_markings_whitedots.png": [ + 230, + 220, + 207 + ], + "mobs_mc_mule.png": [ + 108, + 75, + 51 + ], + "mobs_mc_spawn_icon_iron_golem.png": [ + 122, + 72, + 41 + ], + "mobs_mc_zombie_butcher.png": [ + 107, + 98, + 87 + ], + "mobs_mc_llama_decor_yellow.png": [ + 218, + 187, + 8 + ], + "mobs_mc_wolf_tame.png": [ + 179, + 159, + 154 + ], + "mobs_mc_horse_gray.png": [ + 78, + 68, + 62 + ], + "mobs_mc_shulker_lime.png": [ + 106, + 132, + 88 + ], + "mobs_mc_rabbit_caerbannog.png": [ + 186, + 179, + 174 + ], + "mobs_mc_zombie_librarian.png": [ + 106, + 104, + 104 + ], + "mobs_mc_spawn_icon_silverfish.png": [ + 199, + 168, + 128 + ], + "mobs_mc_spawn_icon_stray.png": [ + 118, + 116, + 118 + ], + "mobs_mc_spawn_icon_polarbear.png": [ + 237, + 235, + 212 + ], + "mobs_mc_guardian_elder.png": [ + 141, + 141, + 125 + ], + "mobs_mc_spawn_icon_slime.png": [ + 76, + 130, + 33 + ], + "mobs_mc_cave_spider.png": [ + 14, + 28, + 38 + ], + "mobs_mc_spawn_icon_cow.png": [ + 162, + 118, + 72 + ], + "mobs_mc_wolf.png": [ + 182, + 165, + 159 + ], + "mobs_mc_wither_skeleton.png": [ + 50, + 50, + 50 + ], + "mobs_mc_endergolem.png": [ + 135, + 87, + 99 + ], + "mobs_mc_spawn_icon_mule.png": [ + 115, + 82, + 47 + ], + "mobs_mc_llama_decor_orange.png": [ + 151, + 80, + 27 + ], + "mobs_chicken_egg.png": [ + 199, + 157, + 106 + ], + "mobs_mc_rabbit_white.png": [ + 161, + 153, + 149 + ], + "mobs_mc_horse_black.png": [ + 49, + 42, + 39 + ], + "mobs_mc_dragon.png": [ + 79, + 54, + 67 + ], + "mobs_mc_villager_fisherman.png": [ + 98, + 92, + 58 + ], + "mobs_mc_spawn_icon_parrot.png": [ + 202, + 100, + 54 + ], + "mobs_mc_spawn_icon_snowman.png": [ + 216, + 173, + 147 + ], + "mobs_mc_donkey.png": [ + 91, + 78, + 68 + ], + "mobs_mc_shulker_cyan.png": [ + 89, + 114, + 128 + ], + "mobs_mc_spawn_icon_sheep.png": [ + 209, + 185, + 175 + ], + "mobs_mc_TEMP_wither_projectile.png": [ + 69, + 69, + 69 + ], + "mobs_mc_spawn_icon_enderman.png": [ + 63, + 82, + 87 + ], + "mobs_mc_shulker_orange.png": [ + 156, + 90, + 67 + ], + "mobs_mc_empty.png": [ + 255, + 255, + 255 + ], + "mobs_mc_spawn_icon_wither.png": [ + 102, + 102, + 102 + ], + "mcl_boats_spruce_boat.png": [ + 72, + 61, + 51 + ], + "mcl_boats_jungle_boat.png": [ + 102, + 73, + 58 + ], + "mcl_boats_texture_birch_boat.png": [ + 131, + 105, + 83 + ], + "mcl_boats_texture_oak_boat.png": [ + 103, + 82, + 65 + ], + "mcl_boats_birch_boat.png": [ + 120, + 95, + 78 + ], + "mcl_boats_texture_jungle_boat.png": [ + 109, + 78, + 60 + ], + "mcl_boats_oak_boat.png": [ + 93, + 76, + 62 + ], + "mcl_boats_texture_acacia_boat.png": [ + 136, + 90, + 64 + ], + "mcl_boats_obsidian_boat.png": [ + 17, + 15, + 27 + ], + "mcl_boats_texture_obsidian_boat.png": [ + 13, + 10, + 26 + ], + "mcl_boats_texture_dark_oak_boat.png": [ + 89, + 76, + 64 + ], + "mcl_boats_texture_spruce_boat.png": [ + 74, + 61, + 50 + ], + "mcl_boats_acacia_boat.png": [ + 124, + 82, + 59 + ], + "mcl_boats_dark_oak_boat.png": [ + 89, + 76, + 64 + ], + "mobs_nametag.png": [ + 138, + 114, + 89 + ], + "mobs_blood.png": [ + 27, + 27, + 29 + ], + "mcl_minecarts_rail_golden_curved_powered.png": [ + 89, + 71, + 57 + ], + "mcl_minecarts_rail_golden_crossing.png": [ + 83, + 70, + 55 + ], + "mcl_minecarts_rail_detector_curved_powered.png": [ + 81, + 68, + 64 + ], + "mcl_minecarts_rail_golden_t_junction_powered.png": [ + 82, + 69, + 59 + ], + "mcl_minecarts_rail_golden_t_junction.png": [ + 80, + 70, + 59 + ], + "mcl_minecarts_rail_detector.png": [ + 85, + 74, + 67 + ], + "mcl_minecarts_rail_detector_crossing.png": [ + 77, + 69, + 65 + ], + "default_rail_t_junction.png": [ + 79, + 68, + 61 + ], + "mcl_minecarts_rail_activator_crossing_powered.png": [ + 72, + 55, + 51 + ], + "mcl_minecarts_minecart_hopper.png": [ + 45, + 45, + 45 + ], + "mcl_minecarts_minecart_furnace.png": [ + 66, + 65, + 64 + ], + "mcl_minecarts_minecart_command_block.png": [ + 64, + 62, + 61 + ], + "mcl_minecarts_rail_golden.png": [ + 92, + 77, + 60 + ], + "mcl_minecarts_rail_activator_t_junction_powered.png": [ + 76, + 61, + 55 + ], + "default_rail_curved.png": [ + 76, + 67, + 60 + ], + "mcl_minecarts_rail_activator_t_junction.png": [ + 72, + 62, + 56 + ], + "mcl_minecarts_rail_golden_crossing_powered.png": [ + 86, + 70, + 54 + ], + "mcl_minecarts_rail_detector_crossing_powered.png": [ + 78, + 68, + 64 + ], + "mcl_minecarts_rail_detector_curved.png": [ + 77, + 70, + 66 + ], + "default_rail_crossing.png": [ + 79, + 68, + 59 + ], + "mcl_minecarts_rail_detector_t_junction.png": [ + 74, + 66, + 61 + ], + "mcl_minecarts_minecart.png": [ + 72, + 60, + 51 + ], + "mcl_minecarts_rail_golden_curved.png": [ + 85, + 73, + 58 + ], + "mcl_minecarts_rail_activator.png": [ + 78, + 64, + 56 + ], + "mcl_minecarts_rail_activator_powered.png": [ + 86, + 62, + 54 + ], + "mcl_minecarts_rail_detector_t_junction_powered.png": [ + 76, + 66, + 61 + ], + "mcl_minecarts_minecart_normal.png": [ + 47, + 45, + 43 + ], + "mcl_minecarts_minecart_tnt.png": [ + 75, + 52, + 52 + ], + "mcl_minecarts_rail_detector_powered.png": [ + 87, + 74, + 67 + ], + "mcl_minecarts_rail_golden_powered.png": [ + 94, + 77, + 60 + ], + "mcl_minecarts_rail_activator_crossing.png": [ + 65, + 56, + 52 + ], + "default_rail.png": [ + 83, + 70, + 61 + ], + "mcl_minecarts_rail_activator_curved_powered.png": [ + 75, + 55, + 52 + ], + "mcl_minecarts_rail_activator_curved.png": [ + 66, + 56, + 53 + ], + "mcl_minecarts_minecart_chest.png": [ + 51, + 48, + 46 + ], + "mcl_paintings_paintings.png": [ + 104, + 99, + 89 + ], + "mcl_paintings_painting.png": [ + 139, + 133, + 119 + ], + "mcl_particles_totem4.png": [ + 255, + 255, + 255 + ], + "mcl_particles_lava.png": [ + 250, + 150, + 64 + ], + "mcl_particles_bonemeal.png": [ + 185, + 185, + 185 + ], + "mcl_particles_instant_effect.png": [ + 160, + 160, + 160 + ], + "mcl_particles_note.png": [ + 41, + 40, + 39 + ], + "mcl_particles_bubble.png": [ + 147, + 174, + 195 + ], + "mcl_particles_sponge1.png": [ + 241, + 238, + 226 + ], + "mcl_particles_smoke_anim.png": [ + 172, + 172, + 172 + ], + "mcl_particles_crit.png": [ + 165, + 165, + 165 + ], + "mcl_particles_totem2.png": [ + 255, + 255, + 255 + ], + "mcl_particles_mob_death.png": [ + 198, + 198, + 198 + ], + "mcl_particles_droplet_bottle.png": [ + 203, + 203, + 203 + ], + "mcl_particles_sponge4.png": [ + 241, + 238, + 226 + ], + "mcl_particles_effect.png": [ + 184, + 184, + 184 + ], + "mcl_particles_teleport.png": [ + 86, + 22, + 128 + ], + "mcl_particles_sponge5.png": [ + 241, + 238, + 226 + ], + "mcl_particles_flame.png": [ + 244, + 149, + 63 + ], + "mcl_particles_sponge3.png": [ + 241, + 238, + 226 + ], + "mcl_particles_sponge2.png": [ + 241, + 238, + 226 + ], + "mcl_particles_totem1.png": [ + 255, + 255, + 255 + ], + "mcl_particles_smoke.png": [ + 174, + 174, + 174 + ], + "mcl_particles_totem3.png": [ + 255, + 255, + 255 + ], + "lightning_lightning_2.png": [ + 255, + 255, + 255 + ], + "lightning_lightning_3.png": [ + 217, + 217, + 217 + ], + "lightning_lightning_1.png": [ + 223, + 223, + 223 + ], + "weather_pack_rain_raindrop_2.png": [ + 33, + 79, + 142 + ], + "weather_pack_rain_raindrop_3.png": [ + 59, + 88, + 128 + ], + "mcl_particles_nether_dust3.png": [ + 143, + 105, + 102 + ], + "weather_pack_rain_raindrop_1.png": [ + 97, + 137, + 179 + ], + "mcl_particles_nether_dust1.png": [ + 143, + 105, + 102 + ], + "weather_pack_snow_snowflake1.png": [ + 255, + 255, + 255 + ], + "mcl_particles_nether_dust2.png": [ + 143, + 105, + 102 + ], + "weather_pack_snow_snowflake2.png": [ + 255, + 255, + 255 + ], + "mcl_moon_moon_phases.png": [ + 80, + 106, + 141 + ], + "hbarmor_bgicon.png": [ + 27, + 27, + 29 + ], + "hbarmor_bar.png": [ + 175, + 172, + 165 + ], + "hbarmor_icon.png": [ + 135, + 131, + 126 + ], + "mcl_base_textures_background9.png": [ + 179, + 179, + 179 + ], + "object_crosshair.png": [ + 255, + 255, + 255 + ], + "bubble.png": [ + 69, + 138, + 194 + ], + "crosshair.png": [ + 255, + 255, + 255 + ], + "heart.png": [ + 137, + 47, + 40 + ], + "mcl_base_textures_background.png": [ + 179, + 179, + 179 + ], + "crack_anylength.png": [ + 93, + 93, + 93 + ], + "mcl_base_textures_button9_pressed.png": [ + 162, + 162, + 162 + ], + "mcl_base_textures_button9.png": [ + 162, + 162, + 162 + ], + "smoke_puff.png": [ + 255, + 255, + 255 + ], + "credits_bg.png": [ + 94, + 72, + 60 + ], + "mineclone2_logo.png": [ + 75, + 74, + 69 + ], + "mineclone2_icon.png": [ + 58, + 74, + 44 + ], + "awards_template.png": [ + 134, + 134, + 134 + ], + "awards_bg_mining.png": [ + 73, + 68, + 51 + ], + "awards_progress_gray.png": [ + 157, + 157, + 157 + ], + "awards_ui_icon.png": [ + 190, + 34, + 34 + ], + "awards_unknown.png": [ + 134, + 134, + 134 + ], + "awards_progress_green.png": [ + 0, + 155, + 74 + ], + "awards_bg_default.png": [ + 38, + 38, + 38 + ], + "hudbars_bar_breath.png": [ + 159, + 161, + 255 + ], + "hudbars_icon_health.png": [ + 137, + 47, + 40 + ], + "hudbars_bar_health.png": [ + 168, + 55, + 47 + ], + "hudbars_bgicon_breath.png": [ + 0, + 0, + 0 + ], + "hudbars_bgicon_health.png": [ + 27, + 27, + 29 + ], + "hudbars_icon_breath.png": [ + 69, + 138, + 194 + ], + "hudbars_bar_background.png": [ + 71, + 71, + 71 + ], + "mcl_achievements_button.png": [ + 158, + 152, + 67 + ], + "mcl_inventory_hotbar.png": [ + 81, + 81, + 85 + ], + "crafting_inventory_creative_survival.png": [ + 195, + 195, + 195 + ], + "crafting_creative_bg_dark.png": [ + 157, + 157, + 157 + ], + "mcl_inventory_empty_armor_slot_shield.png": [ + 25, + 32, + 34 + ], + "crafting_formspec_bg.png": [ + 9, + 9, + 9 + ], + "mcl_inventory_empty_armor_slot_helmet.png": [ + 25, + 32, + 34 + ], + "mcl_inventory_hotbar_selected.png": [ + 113, + 85, + 40 + ], + "crafting_creative_inactive_down.png": [ + 151, + 151, + 151 + ], + "crafting_creative_active_down.png": [ + 196, + 196, + 196 + ], + "crafting_creative_prev.png": [ + 254, + 254, + 254 + ], + "crafting_creative_marker.png": [ + 0, + 0, + 0 + ], + "mcl_inventory_button9_pressed.png": [ + 162, + 162, + 162 + ], + "crafting_creative_active.png": [ + 202, + 202, + 202 + ], + "mcl_inventory_button9.png": [ + 162, + 162, + 162 + ], + "mcl_inventory_empty_armor_slot_chestplate.png": [ + 0, + 0, + 0 + ], + "mcl_inventory_empty_armor_slot_boots.png": [ + 0, + 0, + 0 + ], + "crafting_creative_bg.png": [ + 207, + 207, + 207 + ], + "crafting_creative_inactive.png": [ + 157, + 157, + 157 + ], + "crafting_creative_next.png": [ + 254, + 254, + 254 + ], + "mcl_inventory_empty_armor_slot_leggings.png": [ + 25, + 32, + 34 + ], + "crafting_inventory_creative.png": [ + 206, + 206, + 206 + ], + "crafting_creative_trash.png": [ + 144, + 113, + 113 + ], + "mcl_formspec_itemslot.png": [ + 157, + 157, + 157 + ], + "mcl_wear_bar.png": [ + 255, + 255, + 255 + ], + "mcl_offhand_slot.png": [ + 92, + 92, + 94 + ], + "mcl_experience_bottle.png": [ + 136, + 174, + 169 + ], + "mcl_experience_bar.png": [ + 74, + 102, + 70 + ], + "mcl_experience_orb.png": [ + 93, + 174, + 0 + ], + "mcl_experience_bar_background.png": [ + 49, + 46, + 45 + ], + "mcl_bossbars_empty.png": [ + 255, + 255, + 255 + ], + "mcl_bossbars.png": [ + 76, + 68, + 75 + ], + "blast_furnace_front_on.png": [ + 98, + 88, + 83 + ], + "blast_furnace_top.png": [ + 126, + 115, + 110 + ], + "blast_furnace_side.png": [ + 99, + 92, + 89 + ], + "blast_furnace_front.png": [ + 93, + 88, + 85 + ], + "mcl_itemframes_item_frame.png": [ + 123, + 90, + 63 + ], + "mcl_itemframes_itemframe_background.png": [ + 136, + 104, + 75 + ], + "mcl_banners_stripe_middle.png": [ + 255, + 255, + 255 + ], + "mcl_banners_skull.png": [ + 255, + 255, + 255 + ], + "mcl_banners_bricks.png": [ + 255, + 255, + 255 + ], + "mcl_banners_square_bottom_left.png": [ + 255, + 255, + 255 + ], + "mcl_banners_gradient.png": [ + 254, + 254, + 254 + ], + "mcl_banners_cross.png": [ + 255, + 255, + 255 + ], + "mcl_banners_gradient_up.png": [ + 254, + 254, + 254 + ], + "mcl_banners_item_overlay.png": [ + 240, + 240, + 240 + ], + "mcl_banners_stripe_downright.png": [ + 255, + 255, + 255 + ], + "mcl_banners_stripe_downleft.png": [ + 255, + 255, + 255 + ], + "mcl_banners_fallback_wood.png": [ + 102, + 88, + 74 + ], + "mcl_banners_base_inverted.png": [ + 255, + 255, + 255 + ], + "mcl_banners_triangles_top.png": [ + 255, + 255, + 255 + ], + "mcl_banners_banner_base.png": [ + 215, + 206, + 193 + ], + "mcl_banners_curly_border.png": [ + 254, + 254, + 254 + ], + "mcl_banners_thing.png": [ + 253, + 253, + 253 + ], + "mcl_banners_small_stripes.png": [ + 255, + 255, + 255 + ], + "mcl_banners_triangle_bottom.png": [ + 254, + 254, + 254 + ], + "mcl_banners_stripe_right.png": [ + 255, + 255, + 255 + ], + "mcl_banners_straight_cross.png": [ + 255, + 255, + 255 + ], + "mcl_banners_triangle_top.png": [ + 255, + 255, + 255 + ], + "mcl_banners_border.png": [ + 255, + 255, + 255 + ], + "mcl_banners_diagonal_left.png": [ + 255, + 255, + 255 + ], + "mcl_banners_diagonal_right.png": [ + 255, + 255, + 255 + ], + "mcl_banners_base.png": [ + 255, + 255, + 255 + ], + "mcl_banners_half_vertical.png": [ + 255, + 255, + 255 + ], + "mcl_banners_circle.png": [ + 254, + 254, + 254 + ], + "mcl_banners_triangles_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_banners_item_base.png": [ + 103, + 89, + 75 + ], + "mcl_banners_stripe_left.png": [ + 255, + 255, + 255 + ], + "mcl_banners_rhombus.png": [ + 255, + 255, + 255 + ], + "mcl_banners_creeper.png": [ + 255, + 255, + 255 + ], + "mcl_banners_flower.png": [ + 254, + 254, + 254 + ], + "mcl_banners_stripe_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_banners_half_horizontal.png": [ + 255, + 255, + 255 + ], + "mcl_banners_half_horizontal_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_banners_square_top_left.png": [ + 255, + 255, + 255 + ], + "mcl_banners_square_top_right.png": [ + 255, + 255, + 255 + ], + "mcl_banners_stripe_center.png": [ + 255, + 255, + 255 + ], + "mcl_banners_diagonal_up_left.png": [ + 255, + 255, + 255 + ], + "mcl_banners_stripe_top.png": [ + 255, + 255, + 255 + ], + "mcl_banners_diagonal_up_right.png": [ + 255, + 255, + 255 + ], + "mcl_banners_square_bottom_right.png": [ + 255, + 255, + 255 + ], + "mcl_banners_half_vertical_right.png": [ + 255, + 255, + 255 + ], + "mcl_doors_trapdoor_dark_oak.png": [ + 81, + 68, + 56 + ], + "mcl_doors_trapdoor_acacia_side.png": [ + 154, + 102, + 71 + ], + "doors_trapdoor_steel_side.png": [ + 149, + 140, + 140 + ], + "mcl_doors_door_jungle_side_upper.png": [ + 109, + 75, + 57 + ], + "mcl_doors_door_dark_oak_side_lower.png": [ + 103, + 90, + 75 + ], + "mcl_doors_door_iron_lower.png": [ + 157, + 152, + 151 + ], + "mcl_doors_door_acacia_upper.png": [ + 152, + 100, + 69 + ], + "mcl_doors_door_jungle_side_lower.png": [ + 107, + 72, + 55 + ], + "mcl_doors_door_wood_lower.png": [ + 89, + 70, + 55 + ], + "doors_trapdoor_steel.png": [ + 149, + 140, + 140 + ], + "mcl_doors_door_iron_side_upper.png": [ + 155, + 149, + 148 + ], + "mcl_doors_door_acacia_side_upper.png": [ + 133, + 80, + 53 + ], + "mcl_doors_door_jungle.png": [ + 116, + 83, + 62 + ], + "mcl_doors_door_iron_side_lower.png": [ + 157, + 152, + 151 + ], + "mcl_doors_door_birch_upper.png": [ + 179, + 158, + 139 + ], + "mcl_doors_trapdoor_spruce_side.png": [ + 73, + 59, + 47 + ], + "mcl_doors_door_iron_upper.png": [ + 155, + 149, + 148 + ], + "mcl_doors_door_spruce_side_lower.png": [ + 92, + 79, + 68 + ], + "mcl_doors_trapdoor_spruce.png": [ + 71, + 57, + 46 + ], + "mcl_doors_trapdoor_birch_side.png": [ + 147, + 116, + 89 + ], + "doors_trapdoor_side.png": [ + 113, + 86, + 67 + ], + "mcl_doors_door_acacia_lower.png": [ + 153, + 101, + 70 + ], + "mcl_doors_door_dark_oak_side_upper.png": [ + 102, + 89, + 75 + ], + "mcl_doors_door_acacia_side_lower.png": [ + 131, + 78, + 51 + ], + "mcl_doors_door_wood_upper.png": [ + 92, + 72, + 57 + ], + "mcl_doors_trapdoor_birch.png": [ + 173, + 151, + 132 + ], + "mcl_doors_door_dark_oak_upper.png": [ + 83, + 71, + 59 + ], + "mcl_doors_door_acacia.png": [ + 148, + 98, + 67 + ], + "mcl_doors_door_spruce.png": [ + 67, + 56, + 47 + ], + "mcl_doors_door_spruce_lower.png": [ + 71, + 58, + 48 + ], + "mcl_doors_door_birch_side_upper.png": [ + 153, + 121, + 94 + ], + "mcl_doors_trapdoor_dark_oak_side.png": [ + 85, + 72, + 60 + ], + "mcl_doors_door_wood_side_upper.png": [ + 84, + 65, + 51 + ], + "mcl_doors_door_birch.png": [ + 172, + 147, + 124 + ], + "mcl_doors_door_birch_lower.png": [ + 165, + 140, + 119 + ], + "mcl_doors_trapdoor_jungle.png": [ + 103, + 70, + 52 + ], + "doors_item_steel.png": [ + 148, + 144, + 143 + ], + "doors_trapdoor.png": [ + 98, + 75, + 59 + ], + "mcl_doors_door_jungle_lower.png": [ + 116, + 82, + 61 + ], + "doors_item_wood.png": [ + 88, + 67, + 53 + ], + "mcl_doors_door_jungle_upper.png": [ + 113, + 79, + 59 + ], + "mcl_doors_door_spruce_upper.png": [ + 71, + 58, + 47 + ], + "mcl_doors_door_dark_oak_lower.png": [ + 84, + 71, + 59 + ], + "mcl_doors_door_dark_oak.png": [ + 82, + 69, + 57 + ], + "mcl_doors_door_wood_side_lower.png": [ + 132, + 102, + 81 + ], + "mcl_doors_trapdoor_jungle_side.png": [ + 121, + 87, + 62 + ], + "mcl_doors_door_spruce_side_upper.png": [ + 92, + 79, + 68 + ], + "mcl_doors_door_birch_side_lower.png": [ + 152, + 119, + 92 + ], + "mcl_doors_trapdoor_acacia.png": [ + 148, + 96, + 66 + ], + "mcl_fishing_clownfish_raw.png": [ + 205, + 127, + 81 + ], + "mcl_fishing_fish_raw.png": [ + 70, + 112, + 154 + ], + "mcl_fishing_salmon_raw.png": [ + 112, + 105, + 102 + ], + "mcl_fishing_fish_cooked.png": [ + 93, + 84, + 94 + ], + "mcl_fishing_bobber.png": [ + 171, + 117, + 119 + ], + "mcl_fishing_pufferfish_raw.png": [ + 219, + 165, + 77 + ], + "mcl_fishing_fishing_rod.png": [ + 134, + 116, + 103 + ], + "mcl_fishing_salmon_cooked.png": [ + 97, + 91, + 89 + ], + "mcl_barrels_barrel_top_open.png": [ + 58, + 43, + 35 + ], + "mcl_barrels_barrel_bottom.png": [ + 78, + 61, + 47 + ], + "mcl_barrels_barrel_side.png": [ + 70, + 57, + 47 + ], + "mcl_barrels_barrel_top.png": [ + 79, + 61, + 48 + ], + "mcl_stairs_diorite_smooth_slab.png": [ + 156, + 153, + 151 + ], + "mcl_stairs_iron_block_slab.png": [ + 166, + 159, + 159 + ], + "mcl_stairs_andesite_smooth_slab.png": [ + 106, + 113, + 108 + ], + "mcl_stairs_gold_block_slab.png": [ + 191, + 146, + 56 + ], + "mcl_stairs_granite_smooth_slab.png": [ + 150, + 121, + 109 + ], + "mcl_stairs_lapis_block_slab.png": [ + 49, + 89, + 158 + ], + "lantern_top.png": [ + 65, + 66, + 70 + ], + "mcl_blackstone_basalt_smooth.png": [ + 87, + 86, + 86 + ], + "mcl_blackstone_basalt_top_polished.png": [ + 77, + 76, + 76 + ], + "mcl_backstone_quartz_bricks.png": [ + 189, + 184, + 181 + ], + "soul_fire_basic_flame_animated.png": [ + 75, + 161, + 161 + ], + "mcl_blackstone_basalt_side_polished.png": [ + 64, + 63, + 63 + ], + "soul_torch_on_floor_animated.png": [ + 94, + 96, + 84 + ], + "mcl_blackstone_chiseled_polished.png": [ + 40, + 38, + 43 + ], + "lantern_bottom.png": [ + 78, + 138, + 137 + ], + "lantern.png": [ + 69, + 121, + 121 + ], + "soul_mcl_burning_hud_flame_animated.png": [ + 75, + 161, + 161 + ], + "mcl_blackstone_basalt_side.png": [ + 60, + 59, + 59 + ], + "mcl_blackstone_basalt_top.png": [ + 68, + 68, + 68 + ], + "mcl_blackstone_polished.png": [ + 43, + 41, + 46 + ], + "mcl_blackstone_polished_bricks.png": [ + 41, + 38, + 43 + ], + "mcl_blackstone_soul_soil.png": [ + 91, + 71, + 52 + ], + "soul_mcl_burning_entity_flame_animated.png": [ + 75, + 161, + 161 + ], + "mcl_blackstone_chain.png": [ + 33, + 33, + 33 + ], + "soul_fire_basic_flame.png": [ + 76, + 164, + 164 + ], + "mcl_blackstone.png": [ + 30, + 29, + 31 + ], + "soul_torch_on_floor.png": [ + 92, + 94, + 83 + ], + "mcl_nether_nether_wart_block_blue.png": [ + 72, + 95, + 175 + ], + "mcl_blackstone_gilded_side.png": [ + 184, + 140, + 50 + ], + "mcl_fireworks_rocket.png": [ + 155, + 84, + 71 + ], + "mcl_bows_arrow_inv.png": [ + 144, + 129, + 121 + ], + "mcl_bows_crossbow_0.png": [ + 95, + 77, + 61 + ], + "mcl_bows_rocket.png": [ + 188, + 86, + 83 + ], + "mcl_bows_firework_white.png": [ + 222, + 222, + 222 + ], + "mcl_bows_firework_green.png": [ + 156, + 238, + 141 + ], + "mcl_bows_firework_blue.png": [ + 141, + 174, + 238 + ], + "mcl_bows_firework_red.png": [ + 238, + 141, + 141 + ], + "mcl_bows_arrow_overlay.png": [ + 184, + 181, + 175 + ], + "mcl_bows_bow_1.png": [ + 112, + 95, + 79 + ], + "mcl_bows_bow_0.png": [ + 111, + 94, + 79 + ], + "mcl_bows_crossbow_2.png": [ + 100, + 82, + 66 + ], + "mcl_bows_bow_2.png": [ + 115, + 98, + 82 + ], + "mcl_bows_rocket_particle.png": [ + 215, + 215, + 215 + ], + "mcl_bows_crossbow_3.png": [ + 103, + 87, + 73 + ], + "mcl_bows_bow.png": [ + 114, + 95, + 78 + ], + "mcl_bows_arrow.png": [ + 133, + 116, + 108 + ], + "mcl_bows_crossbow.png": [ + 94, + 76, + 60 + ], + "mcl_bows_crossbow_1.png": [ + 97, + 79, + 62 + ], + "mcl_bows_arrow_front.png": [ + 178, + 175, + 168 + ], + "mcl_bows_arrow_back.png": [ + 218, + 216, + 213 + ], + "mcl_bows_firework_yellow.png": [ + 238, + 218, + 141 + ], + "mcl_ocean_dead_bubble_coral.png": [ + 118, + 108, + 126 + ], + "mcl_ocean_tube_coral.png": [ + 57, + 88, + 209 + ], + "mcl_ocean_sea_pickle_2_anim.png": [ + 95, + 122, + 51 + ], + "mcl_ocean_dead_horn_coral_fan.png": [ + 150, + 143, + 123 + ], + "mcl_ocean_dead_bubble_coral_block.png": [ + 114, + 105, + 122 + ], + "mcl_ocean_sea_pickle_3_off.png": [ + 68, + 99, + 36 + ], + "mcl_ocean_dead_horn_coral_block.png": [ + 152, + 146, + 125 + ], + "mcl_ocean_bubble_coral_block.png": [ + 143, + 76, + 195 + ], + "mcl_ocean_horn_coral.png": [ + 233, + 195, + 69 + ], + "mcl_ocean_dead_tube_coral_block.png": [ + 99, + 104, + 127 + ], + "mcl_ocean_sea_pickle_item.png": [ + 93, + 120, + 50 + ], + "mcl_ocean_kelp_item.png": [ + 42, + 105, + 55 + ], + "mcl_ocean_dried_kelp_side.png": [ + 71, + 80, + 67 + ], + "mcl_ocean_dead_tube_coral.png": [ + 99, + 105, + 128 + ], + "mcl_ocean_fire_coral_block.png": [ + 198, + 74, + 62 + ], + "mcl_ocean_bubble_coral.png": [ + 149, + 77, + 200 + ], + "mcl_ocean_prismarine_bricks.png": [ + 104, + 112, + 115 + ], + "mcl_ocean_brain_coral.png": [ + 206, + 87, + 153 + ], + "mcl_ocean_dried_kelp_top.png": [ + 56, + 71, + 57 + ], + "mcl_ocean_brain_coral_block.png": [ + 200, + 85, + 148 + ], + "mcl_ocean_prismarine_dark.png": [ + 77, + 89, + 97 + ], + "mcl_ocean_dead_fire_coral_block.png": [ + 127, + 102, + 100 + ], + "mcl_ocean_prismarine_shard.png": [ + 122, + 144, + 135 + ], + "mcl_ocean_sea_pickle_2_off.png": [ + 70, + 100, + 36 + ], + "mcl_ocean_sea_pickle_4_anim.png": [ + 85, + 113, + 46 + ], + "mcl_ocean_dead_brain_coral.png": [ + 134, + 117, + 127 + ], + "mcl_ocean_tube_coral_fan.png": [ + 59, + 85, + 203 + ], + "mcl_ocean_sea_pickle_4_off.png": [ + 68, + 98, + 36 + ], + "mcl_ocean_sea_pickle_1_anim.png": [ + 106, + 132, + 57 + ], + "mcl_ocean_fire_coral.png": [ + 208, + 78, + 65 + ], + "mcl_ocean_sea_pickle_3_anim.png": [ + 89, + 116, + 48 + ], + "mcl_ocean_dead_fire_coral_fan.png": [ + 140, + 113, + 110 + ], + "mcl_ocean_prismarine_crystals.png": [ + 182, + 193, + 190 + ], + "mcl_ocean_prismarine_anim.png": [ + 104, + 123, + 122 + ], + "mcl_ocean_horn_coral_fan.png": [ + 230, + 189, + 68 + ], + "mcl_ocean_dead_tube_coral_fan.png": [ + 98, + 103, + 125 + ], + "mcl_ocean_sea_pickle_1_off.png": [ + 72, + 103, + 37 + ], + "mcl_ocean_dead_horn_coral.png": [ + 154, + 148, + 127 + ], + "mcl_ocean_dead_fire_coral.png": [ + 133, + 107, + 105 + ], + "mcl_ocean_bubble_coral_fan.png": [ + 141, + 75, + 192 + ], + "mcl_ocean_horn_coral_block.png": [ + 232, + 193, + 69 + ], + "mcl_ocean_brain_coral_fan.png": [ + 206, + 87, + 154 + ], + "mcl_ocean_sea_lantern.png": [ + 133, + 144, + 145 + ], + "mcl_ocean_seagrass.png": [ + 48, + 125, + 60 + ], + "mcl_ocean_dead_brain_coral_fan.png": [ + 134, + 117, + 127 + ], + "mcl_ocean_dried_kelp.png": [ + 36, + 57, + 40 + ], + "mcl_ocean_dead_bubble_coral_fan.png": [ + 113, + 104, + 120 + ], + "mcl_ocean_dried_kelp_bottom.png": [ + 56, + 71, + 57 + ], + "mcl_ocean_kelp_plant.png": [ + 42, + 105, + 55 + ], + "mcl_ocean_tube_coral_block.png": [ + 58, + 88, + 207 + ], + "mcl_ocean_dead_brain_coral_block.png": [ + 130, + 114, + 123 + ], + "mcl_ocean_fire_coral_fan.png": [ + 205, + 77, + 64 + ], + "mcl_portals_endframe_bottom.png": [ + 109, + 99, + 87 + ], + "mcl_portals_particle3.png": [ + 146, + 0, + 201 + ], + "mcl_portals_particle2.png": [ + 146, + 0, + 201 + ], + "mcl_portals_endframe_top.png": [ + 95, + 85, + 74 + ], + "mcl_portals_particle4.png": [ + 146, + 0, + 201 + ], + "mcl_portals_endframe_eye.png": [ + 135, + 36, + 18 + ], + "mcl_portals_end_portal.png": [ + 14, + 14, + 14 + ], + "mcl_particles_nether_portal.png": [ + 206, + 0, + 206 + ], + "mcl_portals_particle5.png": [ + 189, + 11, + 213 + ], + "mcl_portals_endframe_side.png": [ + 110, + 99, + 86 + ], + "mcl_portals_particle1.png": [ + 173, + 28, + 229 + ], + "mcl_portals_portal.png": [ + 74, + 24, + 172 + ], + "mcl_particles_nether_portal_t.png": [ + 159, + 0, + 223 + ], + "cake_side.png": [ + 201, + 170, + 155 + ], + "cake_inner.png": [ + 185, + 129, + 99 + ], + "cake_bottom.png": [ + 160, + 86, + 51 + ], + "cake_top.png": [ + 241, + 228, + 226 + ], + "cake.png": [ + 216, + 187, + 176 + ], + "mcl_cocoas_cocoa_top_stage_2.png": [ + 138, + 68, + 52 + ], + "mcl_cocoas_cocoa_stage_1.png": [ + 172, + 121, + 69 + ], + "mcl_cocoas_cocoa_stage_2.png": [ + 132, + 65, + 50 + ], + "mcl_cocoas_cocoa_stage_0.png": [ + 65, + 77, + 39 + ], + "mcl_fences_fence_red_nether_brick.png": [ + 68, + 17, + 0 + ], + "mcl_fences_fence_gate_red_nether_brick.png": [ + 64, + 15, + 0 + ], + "mcl_fences_fence_gate_nether_brick.png": [ + 50, + 25, + 26 + ], + "mcl_mobitems_spider_eye.png": [ + 154, + 69, + 60 + ], + "mcl_mobitems_leather.png": [ + 105, + 75, + 45 + ], + "mcl_mobitems_feather.png": [ + 206, + 185, + 183 + ], + "mcl_mobitems_string.png": [ + 202, + 186, + 166 + ], + "mcl_mobitems_rabbit_foot.png": [ + 124, + 107, + 97 + ], + "mcl_mobitems_saddle.png": [ + 93, + 72, + 50 + ], + "mcl_mobitems_bone.png": [ + 182, + 162, + 139 + ], + "mcl_mobitems_horse_armor_iron.png": [ + 134, + 123, + 118 + ], + "mcl_mobitems_shulker_shell.png": [ + 118, + 68, + 83 + ], + "mcl_mobitems_blaze_rod.png": [ + 143, + 64, + 28 + ], + "mcl_mobitems_beef_raw.png": [ + 147, + 63, + 54 + ], + "mcl_mobitems_rabbit_stew.png": [ + 127, + 98, + 79 + ], + "mcl_mobitems_rotten_flesh.png": [ + 110, + 68, + 45 + ], + "mcl_mobitems_horse_armor_diamond.png": [ + 78, + 110, + 129 + ], + "mcl_mobitems_chicken_raw.png": [ + 217, + 178, + 149 + ], + "mcl_mobitems_ghast_tear.png": [ + 148, + 160, + 166 + ], + "mcl_mobitems_porkchop_raw.png": [ + 160, + 72, + 69 + ], + "mcl_mobitems_horse_armor_gold.png": [ + 143, + 110, + 59 + ], + "mcl_mobitems_rabbit_hide.png": [ + 108, + 85, + 73 + ], + "mcl_mobitems_slimeball.png": [ + 75, + 134, + 82 + ], + "mcl_mobitems_magma_cream.png": [ + 102, + 54, + 34 + ], + "default_gunpowder.png": [ + 48, + 41, + 36 + ], + "mcl_mobitems_chicken_cooked.png": [ + 187, + 145, + 106 + ], + "mcl_mobitems_beef_cooked.png": [ + 112, + 70, + 49 + ], + "mcl_mobitems_rabbit_cooked.png": [ + 188, + 155, + 131 + ], + "mcl_mobitems_blaze_powder.png": [ + 86, + 50, + 34 + ], + "mcl_mobitems_rabbit_raw.png": [ + 217, + 177, + 157 + ], + "mcl_mobitems_carrot_on_a_stick.png": [ + 133, + 113, + 93 + ], + "mcl_mobitems_mutton_cooked.png": [ + 144, + 104, + 77 + ], + "mcl_mobitems_nether_star.png": [ + 234, + 189, + 123 + ], + "mcl_mobitems_porkchop_cooked.png": [ + 116, + 72, + 48 + ], + "mcl_mobitems_mutton_raw.png": [ + 175, + 77, + 77 + ], + "mcl_mobitems_bucket_milk.png": [ + 180, + 175, + 166 + ], + "mcl_farming_wheat_stage_0.png": [ + 53, + 101, + 46 + ], + "farming_carrot.png": [ + 147, + 106, + 63 + ], + "farming_potato_poison.png": [ + 121, + 93, + 55 + ], + "mcl_farming_pumpkin_hud.png": [ + 0, + 0, + 0 + ], + "farming_cookie.png": [ + 144, + 100, + 61 + ], + "mcl_farming_melon_seeds.png": [ + 100, + 72, + 61 + ], + "mcl_farming_potatoes_stage_1.png": [ + 69, + 113, + 61 + ], + "mcl_farming_melon_stem_disconnected.png": [ + 96, + 96, + 96 + ], + "farming_carrot_4.png": [ + 93, + 105, + 58 + ], + "mcl_farming_wheat_stage_5.png": [ + 101, + 142, + 66 + ], + "farming_tool_woodhoe.png": [ + 120, + 101, + 86 + ], + "mcl_farming_potatoes_stage_0.png": [ + 73, + 119, + 65 + ], + "farming_carrot_1.png": [ + 75, + 112, + 61 + ], + "farming_carrot_3.png": [ + 70, + 107, + 57 + ], + "farming_melon.png": [ + 153, + 84, + 62 + ], + "mcl_farming_pumpkin_seeds.png": [ + 132, + 120, + 87 + ], + "farming_wheat_harvested.png": [ + 178, + 134, + 80 + ], + "farming_pumpkin_side.png": [ + 186, + 100, + 42 + ], + "mcl_farming_pumpkin_face.png": [ + 181, + 94, + 40 + ], + "mcl_farming_wheat_stage_4.png": [ + 86, + 129, + 65 + ], + "mcl_farming_farmland_wet.png": [ + 69, + 55, + 46 + ], + "mcl_farming_beetroot_0.png": [ + 56, + 122, + 75 + ], + "mcl_farming_pumpkin_stem_connected.png": [ + 94, + 94, + 94 + ], + "mcl_farming_farmland_dry.png": [ + 101, + 80, + 68 + ], + "farming_tool_diamondhoe.png": [ + 101, + 104, + 104 + ], + "mcl_farming_beetroot_1.png": [ + 54, + 118, + 72 + ], + "mcl_farming_beetroot_2.png": [ + 54, + 119, + 73 + ], + "mcl_farming_wheat_stage_7.png": [ + 165, + 116, + 75 + ], + "mcl_farming_beetroot.png": [ + 113, + 69, + 66 + ], + "mcl_farming_wheat_stage_6.png": [ + 145, + 145, + 69 + ], + "mcl_farming_wheat_stage_3.png": [ + 64, + 113, + 52 + ], + "mcl_farming_pumpkin_stem_disconnected.png": [ + 96, + 96, + 96 + ], + "mcl_farming_hayblock_top.png": [ + 154, + 116, + 81 + ], + "farming_pumpkin_face_light.png": [ + 189, + 100, + 45 + ], + "farming_potato_baked.png": [ + 118, + 84, + 45 + ], + "farming_melon_side.png": [ + 68, + 95, + 37 + ], + "farming_potato.png": [ + 107, + 74, + 39 + ], + "mcl_farming_wheat_stage_1.png": [ + 49, + 97, + 45 + ], + "farming_pumpkin_top.png": [ + 172, + 87, + 40 + ], + "farming_bread.png": [ + 177, + 133, + 94 + ], + "mcl_farming_beetroot_soup.png": [ + 120, + 70, + 63 + ], + "farming_melon_top.png": [ + 58, + 80, + 33 + ], + "mcl_farming_potatoes_stage_3.png": [ + 82, + 106, + 57 + ], + "farming_tool_stonehoe.png": [ + 133, + 122, + 111 + ], + "mcl_farming_beetroot_seeds.png": [ + 107, + 104, + 88 + ], + "farming_tool_goldhoe.png": [ + 162, + 131, + 70 + ], + "farming_carrot_gold.png": [ + 140, + 122, + 48 + ], + "farming_carrot_2.png": [ + 72, + 108, + 58 + ], + "farming_pumpkin_face.png": [ + 161, + 79, + 37 + ], + "mcl_farming_melon_stem_connected.png": [ + 94, + 94, + 94 + ], + "mcl_farming_pumpkin_pie.png": [ + 172, + 98, + 45 + ], + "mcl_farming_wheat_stage_2.png": [ + 49, + 97, + 45 + ], + "farming_tool_steelhoe.png": [ + 123, + 112, + 102 + ], + "mcl_farming_potatoes_stage_2.png": [ + 72, + 116, + 62 + ], + "mcl_farming_beetroot_3.png": [ + 73, + 105, + 71 + ], + "mcl_farming_wheat_seeds.png": [ + 102, + 87, + 55 + ], + "mcl_farming_hayblock_side.png": [ + 135, + 99, + 71 + ], + "mcl_raw_ores_raw_iron_block.png": [ + 194, + 172, + 156 + ], + "mcl_raw_ores_raw_gold_block.png": [ + 208, + 166, + 77 + ], + "mcl_raw_ores_raw_gold.png": [ + 195, + 152, + 64 + ], + "mcl_raw_ores_raw_iron.png": [ + 182, + 160, + 145 + ], + "mcl_end_purpur_block.png": [ + 161, + 111, + 175 + ], + "mcl_end_chorus_flower_dead.png": [ + 82, + 79, + 118 + ], + "mcl_end_end_stone.png": [ + 221, + 214, + 130 + ], + "mcl_end_endframe_side.png": [ + 110, + 99, + 86 + ], + "mcl_end_purpur_pillar.png": [ + 157, + 108, + 171 + ], + "mcl_end_chorus_fruit.png": [ + 87, + 89, + 121 + ], + "mcl_end_endframe_eye.png": [ + 135, + 36, + 18 + ], + "mcl_end_chorus_fruit_popped.png": [ + 70, + 67, + 110 + ], + "mcl_end_end_rod_top.png": [ + 123, + 75, + 97 + ], + "mcl_end_endframe_top.png": [ + 95, + 85, + 74 + ], + "mcl_end_purpur_pillar_top.png": [ + 159, + 110, + 173 + ], + "mcl_end_chorus_flower.png": [ + 92, + 92, + 125 + ], + "mcl_end_crystal_item.png": [ + 170, + 140, + 162 + ], + "mcl_end_end_bricks.png": [ + 194, + 187, + 123 + ], + "mcl_end_dragon_egg.png": [ + 55, + 34, + 32 + ], + "mcl_end_ender_eye.png": [ + 130, + 33, + 17 + ], + "mcl_end_chorus_plant.png": [ + 78, + 73, + 115 + ], + "mcl_end_end_rod_bottom.png": [ + 122, + 74, + 96 + ], + "mcl_end_crystal_beam.png": [ + 195, + 81, + 183 + ], + "mcl_end_end_rod_side.png": [ + 242, + 202, + 177 + ], + "mcl_cracked_deepslate_tiles.png": [ + 47, + 46, + 46 + ], + "mcl_cracked_deepslate_bricks.png": [ + 60, + 58, + 58 + ], + "mcl_deepslate_iron_ore.png": [ + 88, + 82, + 79 + ], + "mcl_deepslate_bricks.png": [ + 62, + 61, + 60 + ], + "mcl_deepslate_tuff.png": [ + 98, + 81, + 69 + ], + "mcl_deepslate_gold_ore.png": [ + 87, + 78, + 64 + ], + "mcl_chiseled_deepslate.png": [ + 44, + 43, + 43 + ], + "mcl_deepslate_diamond_ore.png": [ + 74, + 92, + 100 + ], + "mcl_deepslate_lapis_ore.png": [ + 63, + 74, + 90 + ], + "mcl_cobbled_deepslate.png": [ + 78, + 76, + 75 + ], + "mcl_deepslate_tiles.png": [ + 49, + 47, + 47 + ], + "mcl_deepslate.png": [ + 70, + 68, + 67 + ], + "mcl_deepslate_redstone_ore.png": [ + 89, + 61, + 60 + ], + "mcl_deepslate_emerald_ore.png": [ + 63, + 81, + 71 + ], + "mcl_deepslate_top.png": [ + 75, + 73, + 72 + ], + "mcl_polished_deepslate.png": [ + 68, + 66, + 66 + ], + "mcl_deepslate_copper_ore.png": [ + 82, + 70, + 67 + ], + "mcl_deepslate_coal_ore.png": [ + 63, + 60, + 59 + ], + "mcl_clock_clock_18.png": [ + 152, + 123, + 81 + ], + "mcl_clock_clock_03.png": [ + 160, + 129, + 88 + ], + "mcl_clock_clock_49.png": [ + 155, + 122, + 79 + ], + "mcl_clock_clock_34.png": [ + 140, + 115, + 76 + ], + "mcl_clock_clock_01.png": [ + 161, + 129, + 88 + ], + "mcl_clock_clock_32.png": [ + 141, + 116, + 77 + ], + "mcl_clock_clock_27.png": [ + 142, + 117, + 78 + ], + "mcl_clock_clock_42.png": [ + 147, + 119, + 79 + ], + "mcl_clock_clock_25.png": [ + 145, + 119, + 78 + ], + "mcl_clock_clock_56.png": [ + 160, + 126, + 81 + ], + "mcl_clock_clock_22.png": [ + 146, + 119, + 79 + ], + "mcl_clock_clock_31.png": [ + 141, + 116, + 76 + ], + "mcl_clock_clock_57.png": [ + 161, + 127, + 83 + ], + "mcl_clock_clock_58.png": [ + 157, + 127, + 86 + ], + "mcl_clock_clock_39.png": [ + 146, + 119, + 79 + ], + "mcl_clock_clock_59.png": [ + 160, + 128, + 86 + ], + "mcl_clock_clock_16.png": [ + 157, + 125, + 80 + ], + "mcl_clock_clock_38.png": [ + 141, + 117, + 78 + ], + "mcl_clock_clock_53.png": [ + 158, + 124, + 80 + ], + "mcl_clock_clock_43.png": [ + 149, + 121, + 80 + ], + "mcl_clock_clock_09.png": [ + 161, + 127, + 81 + ], + "mcl_clock_clock_33.png": [ + 141, + 116, + 76 + ], + "mcl_clock_clock_07.png": [ + 162, + 128, + 83 + ], + "mcl_clock_clock_23.png": [ + 148, + 121, + 80 + ], + "mcl_clock_clock_51.png": [ + 156, + 123, + 80 + ], + "mcl_clock_clock_10.png": [ + 158, + 127, + 85 + ], + "mcl_clock_clock_55.png": [ + 160, + 126, + 81 + ], + "mcl_clock_clock_46.png": [ + 152, + 122, + 81 + ], + "mcl_clock_clock_26.png": [ + 142, + 117, + 79 + ], + "mcl_clock_clock_06.png": [ + 157, + 127, + 86 + ], + "mcl_clock_clock_00.png": [ + 162, + 129, + 87 + ], + "mcl_clock_clock_28.png": [ + 141, + 116, + 77 + ], + "mcl_clock_clock_44.png": [ + 150, + 120, + 79 + ], + "mcl_clock_clock_08.png": [ + 160, + 127, + 81 + ], + "mcl_clock_clock_19.png": [ + 152, + 122, + 80 + ], + "mcl_clock_clock_12.png": [ + 159, + 127, + 83 + ], + "mcl_clock_clock_45.png": [ + 153, + 123, + 81 + ], + "mcl_clock_clock_24.png": [ + 147, + 120, + 80 + ], + "mcl_clock_clock_15.png": [ + 157, + 125, + 81 + ], + "mcl_clock_clock_20.png": [ + 150, + 121, + 79 + ], + "mcl_clock_clock_61.png": [ + 160, + 129, + 88 + ], + "mcl_clock_clock_02.png": [ + 159, + 129, + 89 + ], + "mcl_clock_clock_40.png": [ + 147, + 120, + 79 + ], + "mcl_clock_clock_37.png": [ + 143, + 118, + 79 + ], + "mcl_clock_clock_48.png": [ + 155, + 123, + 79 + ], + "mcl_clock_clock_13.png": [ + 159, + 126, + 82 + ], + "mcl_clock_clock_17.png": [ + 156, + 125, + 81 + ], + "mcl_clock_clock_52.png": [ + 156, + 123, + 80 + ], + "mcl_clock_clock_54.png": [ + 156, + 125, + 84 + ], + "mcl_clock_clock_04.png": [ + 159, + 128, + 87 + ], + "mcl_clock_clock_47.png": [ + 154, + 122, + 80 + ], + "mcl_clock_clock_62.png": [ + 159, + 129, + 89 + ], + "mcl_clock_clock_41.png": [ + 147, + 120, + 79 + ], + "mcl_clock_clock_35.png": [ + 140, + 115, + 76 + ], + "mcl_clock_clock_60.png": [ + 159, + 128, + 87 + ], + "mcl_clock_clock_50.png": [ + 155, + 123, + 80 + ], + "mcl_clock_clock_29.png": [ + 142, + 117, + 78 + ], + "mcl_clock_clock_21.png": [ + 150, + 122, + 81 + ], + "mcl_clock_clock_30.png": [ + 140, + 115, + 76 + ], + "mcl_clock_clock_14.png": [ + 157, + 125, + 81 + ], + "mcl_clock_clock_05.png": [ + 160, + 128, + 85 + ], + "mcl_clock_clock_36.png": [ + 141, + 116, + 77 + ], + "mcl_clock_clock_63.png": [ + 161, + 129, + 88 + ], + "mcl_clock_clock_11.png": [ + 160, + 127, + 82 + ], + "lodestone_side3.png": [ + 83, + 73, + 69 + ], + "mcl_compass_compass_02.png": [ + 116, + 107, + 104 + ], + "lodestone_bottom.png": [ + 81, + 72, + 69 + ], + "mcl_compass_compass_06.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_04.png": [ + 117, + 106, + 104 + ], + "mcl_compass_compass_19.png": [ + 116, + 106, + 103 + ], + "mcl_compass_compass_16.png": [ + 114, + 106, + 104 + ], + "lodestone_side1.png": [ + 83, + 73, + 69 + ], + "mcl_compass_compass_26.png": [ + 117, + 107, + 104 + ], + "lodestone_side4.png": [ + 85, + 75, + 70 + ], + "mcl_compass_compass_25.png": [ + 117, + 107, + 105 + ], + "mcl_compass_compass_24.png": [ + 117, + 107, + 105 + ], + "mcl_compass_compass_17.png": [ + 115, + 106, + 104 + ], + "lodestone_top.png": [ + 78, + 69, + 66 + ], + "mcl_compass_compass_23.png": [ + 117, + 107, + 105 + ], + "mcl_compass_compass_01.png": [ + 115, + 107, + 104 + ], + "mcl_compass_compass_28.png": [ + 116, + 107, + 104 + ], + "mcl_compass_compass_05.png": [ + 117, + 106, + 104 + ], + "mcl_compass_compass_09.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_10.png": [ + 117, + 107, + 105 + ], + "lodestone_side2.png": [ + 82, + 72, + 68 + ], + "mcl_compass_compass_14.png": [ + 116, + 107, + 105 + ], + "mcl_compass_compass_18.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_13.png": [ + 117, + 106, + 104 + ], + "mcl_compass_compass_08.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_21.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_27.png": [ + 117, + 106, + 104 + ], + "mcl_compass_compass_30.png": [ + 116, + 107, + 104 + ], + "mcl_compass_compass_15.png": [ + 115, + 106, + 104 + ], + "mcl_compass_compass_29.png": [ + 115, + 106, + 104 + ], + "mcl_compass_compass_03.png": [ + 116, + 106, + 104 + ], + "mcl_compass_compass_07.png": [ + 117, + 107, + 104 + ], + "mcl_compass_compass_22.png": [ + 117, + 107, + 105 + ], + "mcl_compass_compass_12.png": [ + 117, + 106, + 104 + ], + "mcl_compass_compass_00.png": [ + 114, + 107, + 104 + ], + "mcl_compass_compass_20.png": [ + 116, + 106, + 104 + ], + "mcl_compass_compass_31.png": [ + 115, + 107, + 104 + ], + "mcl_compass_compass_11.png": [ + 117, + 106, + 104 + ], + "mcl_jukebox_record_wait.png": [ + 39, + 42, + 55 + ], + "mcl_jukebox_record_cat.png": [ + 40, + 45, + 51 + ], + "mcl_jukebox_record_mellohi.png": [ + 46, + 44, + 59 + ], + "mcl_jukebox_record_13.png": [ + 51, + 47, + 51 + ], + "mcl_jukebox_record_ward.png": [ + 39, + 43, + 51 + ], + "mcl_jukebox_record_chirp.png": [ + 49, + 40, + 50 + ], + "mcl_jukebox_record_blocks.png": [ + 47, + 37, + 49 + ], + "mcl_jukebox_record_11.png": [ + 41, + 40, + 52 + ], + "mcl_jukebox_record_mall.png": [ + 42, + 41, + 62 + ], + "mcl_jukebox_top.png": [ + 72, + 56, + 44 + ], + "mcl_jukebox_record_strad.png": [ + 45, + 45, + 57 + ], + "mcl_jukebox_record_far.png": [ + 47, + 48, + 52 + ], + "mcl_jukebox_side.png": [ + 94, + 74, + 57 + ], + "mcl_jukebox_record_stal.png": [ + 39, + 38, + 49 + ], + "loom_front.png": [ + 127, + 101, + 84 + ], + "loom_side1.png": [ + 130, + 102, + 80 + ], + "loom_bottom1.png": [ + 163, + 130, + 100 + ], + "loom_top1.png": [ + 186, + 160, + 137 + ], + "loom_bottom.png": [ + 111, + 84, + 69 + ], + "loom_front1.png": [ + 148, + 123, + 102 + ], + "loom_top.png": [ + 134, + 111, + 97 + ], + "loom_side.png": [ + 121, + 91, + 72 + ], + "mcl_fences_fence_acacia.png": [ + 152, + 99, + 68 + ], + "mcl_fences_fence_gate_mask.png": [ + 255, + 126, + 126 + ], + "mcl_fences_fence_gate_spruce.png": [ + 85, + 69, + 56 + ], + "mcl_fences_fence_big_oak.png": [ + 83, + 71, + 59 + ], + "mcl_fences_fence_spruce.png": [ + 84, + 67, + 54 + ], + "mcl_fences_fence_gate_birch.png": [ + 153, + 121, + 94 + ], + "mcl_fences_fence_gate_acacia.png": [ + 155, + 102, + 70 + ], + "mcl_fences_fence_gate_big_oak.png": [ + 85, + 73, + 61 + ], + "mcl_fences_fence_oak.png": [ + 108, + 83, + 64 + ], + "mcl_fences_fence_gate_oak.png": [ + 111, + 85, + 66 + ], + "mcl_fences_fence_jungle.png": [ + 115, + 80, + 60 + ], + "mcl_fences_fence_nether_brick.png": [ + 49, + 24, + 24 + ], + "mcl_fences_fence_birch.png": [ + 151, + 119, + 93 + ], + "mcl_fences_fence_gate_jungle.png": [ + 117, + 82, + 61 + ], + "mcl_fences_fence_mask.png": [ + 255, + 126, + 126 + ], + "mcl_composter_bottom.png": [ + 141, + 111, + 87 + ], + "mcl_composter_side.png": [ + 117, + 92, + 74 + ], + "mcl_composter_ready.png": [ + 109, + 107, + 74 + ], + "mcl_composter_compost.png": [ + 75, + 76, + 41 + ], + "mcl_composter_top.png": [ + 157, + 129, + 103 + ], + "mcl_core_leaves_birch.png": [ + 28, + 57, + 28 + ], + "default_mossycobble.png": [ + 100, + 105, + 94 + ], + "default_flint.png": [ + 70, + 67, + 64 + ], + "mcl_core_bowl.png": [ + 78, + 61, + 47 + ], + "mcl_core_glass_lime_detail.png": [ + 126, + 203, + 24 + ], + "mcl_core_bone_block_top.png": [ + 220, + 201, + 170 + ], + "default_acacia_tree.png": [ + 105, + 91, + 74 + ], + "default_steel_block.png": [ + 159, + 151, + 151 + ], + "mcl_core_stonebrick_mossy.png": [ + 81, + 101, + 76 + ], + "default_diamond_block.png": [ + 92, + 160, + 200 + ], + "mcl_core_glass_brown_detail.png": [ + 101, + 75, + 50 + ], + "mcl_core_glass_blue_detail.png": [ + 50, + 75, + 178 + ], + "default_leaves.png": [ + 39, + 79, + 38 + ], + "mcl_core_web.png": [ + 202, + 189, + 167 + ], + "mcl_core_reeds.png": [ + 57, + 100, + 52 + ], + "default_gold_ingot.png": [ + 179, + 133, + 47 + ], + "mcl_core_grass_path_side.png": [ + 113, + 89, + 62 + ], + "mcl_core_red_sand.png": [ + 224, + 137, + 111 + ], + "mcl_core_glass_black_detail.png": [ + 24, + 24, + 24 + ], + "default_apple.png": [ + 137, + 57, + 44 + ], + "mcl_core_log_birch_top.png": [ + 155, + 130, + 112 + ], + "default_coal_block.png": [ + 51, + 49, + 51 + ], + "mcl_core_andesite_smooth.png": [ + 107, + 113, + 109 + ], + "mcl_core_apple_golden.png": [ + 176, + 138, + 51 + ], + "mcl_core_diorite.png": [ + 153, + 149, + 146 + ], + "mcl_core_granite_smooth.png": [ + 150, + 121, + 110 + ], + "mcl_core_bedrock.png": [ + 91, + 77, + 66 + ], + "mcl_core_planks_spruce.png": [ + 81, + 65, + 54 + ], + "mcl_core_sapling_big_oak.png": [ + 69, + 92, + 80 + ], + "mcl_core_emerald_ore.png": [ + 115, + 122, + 103 + ], + "mcl_core_sandstone_smooth.png": [ + 202, + 155, + 121 + ], + "mcl_core_glass_light_blue.png": [ + 101, + 153, + 215 + ], + "default_brick.png": [ + 139, + 87, + 75 + ], + "mcl_core_redstone_ore.png": [ + 128, + 91, + 88 + ], + "mcl_core_cactus_top.png": [ + 77, + 99, + 49 + ], + "mcl_core_frosted_ice_1.png": [ + 147, + 198, + 227 + ], + "mcl_core_glass_white_detail.png": [ + 254, + 254, + 254 + ], + "mcl_core_sapling_spruce.png": [ + 55, + 72, + 53 + ], + "mcl_core_stripped_acacia_top.png": [ + 157, + 98, + 62 + ], + "mcl_core_log_spruce_top.png": [ + 97, + 71, + 57 + ], + "mcl_core_glass_lime.png": [ + 126, + 203, + 24 + ], + "mcl_core_lapis_ore.png": [ + 111, + 113, + 125 + ], + "default_junglesapling.png": [ + 64, + 88, + 39 + ], + "default_clay_brick.png": [ + 127, + 57, + 48 + ], + "default_gold_block.png": [ + 192, + 147, + 59 + ], + "mcl_core_glass_green_detail.png": [ + 101, + 126, + 50 + ], + "mcl_core_glass_pink_detail.png": [ + 241, + 126, + 164 + ], + "default_water_source_animated.png": [ + 37, + 98, + 129 + ], + "mcl_core_glass_orange_detail.png": [ + 215, + 126, + 50 + ], + "mcl_core_glass_yellow.png": [ + 228, + 228, + 50 + ], + "default_acacia_sapling.png": [ + 109, + 92, + 59 + ], + "mcl_core_stripped_acacia_side.png": [ + 151, + 90, + 57 + ], + "mcl_core_sandstone_carved.png": [ + 199, + 152, + 119 + ], + "mcl_core_glass_blue.png": [ + 50, + 75, + 178 + ], + "mcl_core_glass_gray_detail.png": [ + 75, + 75, + 75 + ], + "mcl_core_red_sandstone_normal.png": [ + 198, + 120, + 104 + ], + "mcl_core_glass_red_detail.png": [ + 153, + 50, + 50 + ], + "mcl_core_glass_gray.png": [ + 75, + 75, + 75 + ], + "mcl_core_leaves_spruce.png": [ + 38, + 74, + 47 + ], + "mcl_core_glass_pink.png": [ + 241, + 126, + 164 + ], + "mcl_core_lapis_block.png": [ + 50, + 92, + 162 + ], + "mcl_core_glass_purple.png": [ + 126, + 62, + 178 + ], + "mcl_core_iron_nugget.png": [ + 156, + 151, + 145 + ], + "default_dry_grass.png": [ + 100, + 94, + 54 + ], + "mcl_core_stripped_dark_oak_top.png": [ + 90, + 78, + 68 + ], + "mcl_core_glass_silver.png": [ + 153, + 153, + 153 + ], + "mcl_core_andesite.png": [ + 104, + 110, + 107 + ], + "mcl_core_frosted_ice_3.png": [ + 165, + 209, + 233 + ], + "mcl_core_sugar.png": [ + 215, + 215, + 215 + ], + "default_acacia_wood.png": [ + 152, + 100, + 69 + ], + "mcl_core_glass_black.png": [ + 24, + 24, + 24 + ], + "mcl_core_iron_ore.png": [ + 134, + 123, + 117 + ], + "mcl_core_stripped_birch_side.png": [ + 179, + 143, + 115 + ], + "default_clay.png": [ + 124, + 124, + 124 + ], + "mcl_core_stripped_jungle_side.png": [ + 175, + 117, + 86 + ], + "mcl_core_glass_red.png": [ + 153, + 50, + 50 + ], + "mcl_core_grass_block_top.png": [ + 141, + 130, + 113 + ], + "mcl_core_planks_birch.png": [ + 145, + 113, + 89 + ], + "mcl_core_glass_white.png": [ + 254, + 254, + 254 + ], + "mcl_core_stripped_oak_side.png": [ + 162, + 122, + 84 + ], + "mcl_core_glass_cyan.png": [ + 75, + 126, + 153 + ], + "mcl_core_cactus_side.png": [ + 88, + 110, + 56 + ], + "default_ladder.png": [ + 83, + 64, + 50 + ], + "mcl_core_glass_silver_detail.png": [ + 153, + 153, + 153 + ], + "default_dry_grass_side.png": [ + 91, + 93, + 52 + ], + "mcl_core_glass_light_blue_detail.png": [ + 101, + 153, + 215 + ], + "mcl_core_stripped_jungle_top.png": [ + 170, + 113, + 83 + ], + "mcl_core_ice_packed.png": [ + 165, + 211, + 231 + ], + "mcl_core_frosted_ice_2.png": [ + 153, + 202, + 229 + ], + "default_dry_shrub.png": [ + 118, + 88, + 69 + ], + "mcl_core_red_sandstone_carved.png": [ + 202, + 122, + 104 + ], + "default_tree.png": [ + 95, + 75, + 57 + ], + "default_clay_lump.png": [ + 111, + 111, + 111 + ], + "mcl_core_red_sandstone_top.png": [ + 212, + 126, + 108 + ], + "mcl_core_dirt_podzol_side.png": [ + 101, + 79, + 63 + ], + "mcl_core_red_sandstone_smooth.png": [ + 207, + 124, + 106 + ], + "default_jungletree_top.png": [ + 125, + 87, + 67 + ], + "mcl_core_coal_ore.png": [ + 109, + 101, + 99 + ], + "default_jungleleaves.png": [ + 29, + 84, + 30 + ], + "mcl_core_vine.png": [ + 21, + 61, + 21 + ], + "default_snow.png": [ + 221, + 229, + 234 + ], + "mcl_core_leaves_big_oak.png": [ + 21, + 69, + 28 + ], + "mcl_core_void.png": [ + 59, + 59, + 59 + ], + "default_tree_top.png": [ + 135, + 104, + 74 + ], + "mcl_core_gold_ore.png": [ + 132, + 119, + 103 + ], + "default_steel_ingot.png": [ + 142, + 137, + 131 + ], + "default_sapling.png": [ + 62, + 90, + 45 + ], + "mcl_core_log_birch.png": [ + 194, + 184, + 174 + ], + "mcl_core_glass_cyan_detail.png": [ + 75, + 126, + 153 + ], + "mcl_core_glass_yellow_detail.png": [ + 228, + 228, + 50 + ], + "mcl_core_stripped_spruce_top.png": [ + 107, + 79, + 64 + ], + "default_water_flowing_animated.png": [ + 38, + 101, + 129 + ], + "mcl_core_emerald_block.png": [ + 44, + 138, + 39 + ], + "default_jungletree.png": [ + 86, + 58, + 45 + ], + "mcl_core_grass_side_snowed.png": [ + 162, + 154, + 150 + ], + "default_stone_brick.png": [ + 97, + 89, + 86 + ], + "default_lava_flowing_animated.png": [ + 177, + 42, + 16 + ], + "mcl_core_stripped_spruce_side.png": [ + 109, + 81, + 67 + ], + "default_coal_lump.png": [ + 41, + 39, + 41 + ], + "mcl_core_glass_purple_detail.png": [ + 126, + 62, + 178 + ], + "default_sand.png": [ + 220, + 170, + 127 + ], + "mcl_core_glass_green.png": [ + 101, + 126, + 50 + ], + "mcl_core_glass_orange.png": [ + 215, + 126, + 50 + ], + "default_acacia_tree_top.png": [ + 130, + 84, + 55 + ], + "mcl_core_stripped_oak_top.png": [ + 153, + 115, + 80 + ], + "mcl_core_grass_block_side_overlay.png": [ + 153, + 142, + 123 + ], + "default_lava_source_animated.png": [ + 180, + 45, + 17 + ], + "mcl_core_cactus_bottom.png": [ + 169, + 168, + 116 + ], + "mcl_core_sandstone_bottom.png": [ + 202, + 155, + 121 + ], + "default_paper.png": [ + 213, + 184, + 154 + ], + "mcl_core_diamond_ore.png": [ + 122, + 124, + 126 + ], + "default_ice.png": [ + 145, + 197, + 226 + ], + "mcl_core_dirt_podzol_top.png": [ + 85, + 63, + 42 + ], + "mcl_core_slime.png": [ + 93, + 157, + 86 + ], + "mcl_core_gold_nugget.png": [ + 213, + 169, + 74 + ], + "default_stick.png": [ + 88, + 70, + 57 + ], + "mcl_core_emerald.png": [ + 59, + 160, + 52 + ], + "default_diamond.png": [ + 109, + 179, + 217 + ], + "mcl_core_mycelium_top.png": [ + 108, + 89, + 117 + ], + "mcl_core_bone_block_side.png": [ + 226, + 207, + 174 + ], + "mcl_core_diorite_smooth.png": [ + 157, + 154, + 152 + ], + "default_obsidian.png": [ + 13, + 9, + 25 + ], + "mcl_core_planks_big_oak.png": [ + 87, + 74, + 62 + ], + "mcl_core_log_spruce.png": [ + 66, + 51, + 44 + ], + "mcl_core_glass_magenta.png": [ + 178, + 75, + 215 + ], + "mcl_core_granite.png": [ + 153, + 121, + 110 + ], + "mcl_core_log_big_oak_top.png": [ + 83, + 70, + 62 + ], + "default_cobble.png": [ + 113, + 106, + 104 + ], + "mcl_core_red_sandstone_bottom.png": [ + 207, + 124, + 106 + ], + "mcl_core_barrier.png": [ + 138, + 46, + 38 + ], + "mcl_core_glass_magenta_detail.png": [ + 178, + 75, + 215 + ], + "mcl_core_stripped_dark_oak_side.png": [ + 91, + 78, + 70 + ], + "mcl_core_mycelium_side.png": [ + 107, + 84, + 87 + ], + "mcl_core_stonebrick_cracked.png": [ + 94, + 87, + 83 + ], + "mcl_core_charcoal.png": [ + 40, + 35, + 32 + ], + "mcl_core_glass_brown.png": [ + 101, + 75, + 50 + ], + "default_glass_detail.png": [ + 244, + 244, + 250 + ], + "mcl_core_papyrus.png": [ + 105, + 105, + 105 + ], + "mcl_core_stonebrick_carved.png": [ + 97, + 90, + 85 + ], + "default_wood.png": [ + 113, + 87, + 67 + ], + "default_dirt.png": [ + 108, + 83, + 70 + ], + "mcl_core_log_big_oak.png": [ + 74, + 62, + 55 + ], + "default_junglewood.png": [ + 113, + 78, + 59 + ], + "mcl_core_frosted_ice_0.png": [ + 140, + 193, + 224 + ], + "mcl_core_sandstone_normal.png": [ + 195, + 149, + 117 + ], + "default_gravel.png": [ + 112, + 105, + 99 + ], + "mcl_core_sandstone_top.png": [ + 201, + 154, + 121 + ], + "default_glass.png": [ + 213, + 223, + 235 + ], + "default_stone.png": [ + 130, + 122, + 118 + ], + "mcl_core_sapling_birch.png": [ + 78, + 110, + 74 + ], + "mcl_core_coarse_dirt.png": [ + 117, + 92, + 76 + ], + "default_acacia_leaves.png": [ + 110, + 89, + 45 + ], + "mcl_core_stripped_birch_top.png": [ + 170, + 135, + 108 + ], + "mcl_core_grass_path_top.png": [ + 125, + 101, + 50 + ], + "mcl_lanterns_chain.png": [ + 40, + 40, + 40 + ], + "mcl_lanterns_soul_lantern.png": [ + 50, + 67, + 68 + ], + "mcl_lanterns_lantern.png": [ + 72, + 59, + 48 + ], + "mcl_lanterns_chain_inv.png": [ + 40, + 40, + 40 + ], + "mcl_lanterns_lantern_inv.png": [ + 98, + 75, + 53 + ], + "mcl_lanterns_soul_lantern_inv.png": [ + 59, + 90, + 91 + ], + "mcl_throwing_ender_pearl.png": [ + 78, + 19, + 26 + ], + "mcl_throwing_egg.png": [ + 199, + 157, + 106 + ], + "mcl_throwing_snowball.png": [ + 191, + 200, + 203 + ], + "mcl_flowers_tulip_red.png": [ + 82, + 57, + 43 + ], + "mcl_flowers_double_plant_rose_top.png": [ + 81, + 69, + 45 + ], + "mcl_flowers_double_plant_sunflower_front.png": [ + 203, + 157, + 61 + ], + "mcl_flowers_tulip_white.png": [ + 106, + 122, + 95 + ], + "mcl_flowers_double_plant_grass_top.png": [ + 156, + 145, + 125 + ], + "mcl_flowers_azure_bluet.png": [ + 97, + 114, + 98 + ], + "mcl_flowers_oxeye_daisy.png": [ + 130, + 139, + 110 + ], + "mcl_flowers_poppy.png": [ + 96, + 59, + 43 + ], + "mcl_flowers_double_plant_paeonia_top.png": [ + 90, + 84, + 81 + ], + "mcl_flowers_double_plant_rose_bottom.png": [ + 78, + 63, + 41 + ], + "mcl_flowers_tallgrass.png": [ + 151, + 141, + 122 + ], + "mcl_flowers_double_plant_sunflower_bottom.png": [ + 45, + 76, + 40 + ], + "mcl_flowers_fern.png": [ + 143, + 132, + 115 + ], + "flowers_tulip.png": [ + 106, + 84, + 51 + ], + "mcl_flowers_double_plant_syringa_bottom.png": [ + 63, + 77, + 60 + ], + "mcl_flowers_double_plant_fern_bottom.png": [ + 140, + 130, + 113 + ], + "flowers_dandelion_yellow.png": [ + 111, + 111, + 55 + ], + "mcl_flowers_double_plant_paeonia_bottom.png": [ + 82, + 83, + 73 + ], + "mcl_flowers_double_plant_sunflower_back.png": [ + 174, + 146, + 57 + ], + "mcl_flowers_allium.png": [ + 120, + 116, + 144 + ], + "flowers_waterlily.png": [ + 28, + 81, + 29 + ], + "mcl_flowers_tulip_pink.png": [ + 100, + 99, + 90 + ], + "mcl_flowers_double_plant_sunflower_top.png": [ + 48, + 81, + 44 + ], + "mcl_flowers_double_plant_syringa_top.png": [ + 95, + 90, + 98 + ], + "mcl_flowers_double_plant_grass_bottom.png": [ + 151, + 140, + 121 + ], + "mcl_flowers_double_plant_grass_inv.png": [ + 48, + 95, + 43 + ], + "mcl_flowers_fern_inv.png": [ + 43, + 86, + 39 + ], + "mcl_flowers_double_plant_fern_top.png": [ + 148, + 138, + 119 + ], + "mcl_flowers_tallgrass_inv.png": [ + 47, + 92, + 41 + ], + "mcl_flowers_double_plant_fern_inv.png": [ + 45, + 89, + 40 + ], + "mcl_flowers_blue_orchid.png": [ + 46, + 91, + 86 + ], + "mcl_armor_leggings_iron.png": [ + 132, + 128, + 123 + ], + "mcl_armor_inv_leggings_iron.png": [ + 130, + 125, + 120 + ], + "mcl_armor_inv_helmet_gold.png": [ + 178, + 134, + 51 + ], + "mcl_armor_leggings_chain.png": [ + 64, + 66, + 69 + ], + "mcl_armor_inv_boots_iron.png": [ + 134, + 129, + 124 + ], + "mcl_armor_inv_chestplate_chain.png": [ + 128, + 105, + 96 + ], + "mcl_armor_inv_chestplate_gold.png": [ + 171, + 128, + 55 + ], + "mcl_armor_inv_helmet_diamond.png": [ + 109, + 130, + 142 + ], + "mcl_armor_boots_leather.png": [ + 122, + 111, + 93 + ], + "mcl_armor_inv_chestplate_diamond.png": [ + 106, + 146, + 168 + ], + "mcl_armor_helmet_diamond.png": [ + 70, + 85, + 93 + ], + "mcl_armor_inv_chestplate_leather.png": [ + 143, + 136, + 118 + ], + "mcl_armor_boots_diamond.png": [ + 87, + 132, + 157 + ], + "mcl_armor_leggings_diamond.png": [ + 78, + 102, + 115 + ], + "mcl_armor_chestplate_gold.png": [ + 157, + 117, + 55 + ], + "mcl_armor_inv_helmet_chain.png": [ + 140, + 137, + 132 + ], + "mcl_armor_inv_leggings_chain.png": [ + 81, + 81, + 82 + ], + "mcl_armor_inv_helmet_iron.png": [ + 143, + 138, + 133 + ], + "mcl_armor_helmet_leather.png": [ + 130, + 121, + 102 + ], + "mcl_armor_chestplate_diamond.png": [ + 110, + 157, + 183 + ], + "mcl_armor_leggings_leather.png": [ + 119, + 108, + 91 + ], + "mcl_armor_inv_boots_gold.png": [ + 152, + 113, + 44 + ], + "mcl_armor_chestplate_leather.png": [ + 139, + 132, + 112 + ], + "mcl_armor_boots_iron.png": [ + 118, + 113, + 109 + ], + "mcl_armor_elytra.png": [ + 75, + 121, + 147 + ], + "mcl_armor_helmet_chain.png": [ + 127, + 124, + 121 + ], + "mcl_armor_helmet_iron.png": [ + 153, + 149, + 144 + ], + "mcl_armor_inv_boots_leather.png": [ + 130, + 121, + 103 + ], + "mcl_armor_leggings_gold.png": [ + 182, + 158, + 126 + ], + "mcl_armor_inv_leggings_gold.png": [ + 175, + 145, + 97 + ], + "mcl_armor_chestplate_iron.png": [ + 130, + 120, + 112 + ], + "mcl_armor_inv_elytra.png": [ + 76, + 122, + 148 + ], + "mcl_armor_boots_chain.png": [ + 88, + 88, + 88 + ], + "mcl_armor_helmet_gold.png": [ + 178, + 136, + 56 + ], + "mcl_armor_inv_boots_diamond.png": [ + 75, + 121, + 147 + ], + "mcl_armor_inv_chestplate_iron.png": [ + 135, + 125, + 115 + ], + "mcl_armor_inv_leggings_diamond.png": [ + 75, + 93, + 103 + ], + "mcl_armor_inv_leggings_leather.png": [ + 126, + 116, + 98 + ], + "mcl_armor_inv_helmet_leather.png": [ + 140, + 132, + 114 + ], + "mcl_armor_inv_boots_chain.png": [ + 69, + 69, + 72 + ], + "mcl_armor_chestplate_chain.png": [ + 119, + 98, + 93 + ], + "mcl_armor_boots_gold.png": [ + 160, + 118, + 42 + ], + "mcl_cartography_table_side2.png": [ + 91, + 76, + 62 + ], + "mcl_cartography_table_side1.png": [ + 81, + 65, + 51 + ], + "mcl_cartography_table_side3.png": [ + 85, + 62, + 47 + ], + "mcl_cartography_table_top.png": [ + 111, + 95, + 80 + ], + "mcl_walls_cobble_wall_top.png": [ + 120, + 114, + 112 + ], + "mcl_walls_cobble_mossy_wall_top.png": [ + 53, + 97, + 61 + ], + "mcl_walls_cobble_wall_side.png": [ + 109, + 103, + 101 + ], + "mcl_walls_cobble_mossy_wall_side.png": [ + 86, + 98, + 83 + ], + "mcl_hoppers_item.png": [ + 44, + 44, + 44 + ], + "mcl_hoppers_hopper_top.png": [ + 43, + 43, + 43 + ], + "mcl_hoppers_hopper_outside.png": [ + 44, + 43, + 43 + ], + "mcl_hoppers_hopper_inside.png": [ + 50, + 50, + 50 + ], + "mcl_stairs_stone_slab_top.png": [ + 127, + 118, + 114 + ], + "mcl_stairs_stone_slab_side.png": [ + 127, + 117, + 113 + ], + "mcl_stairs_turntexture.png": [ + 255, + 0, + 255 + ], + "mcl_shield_pattern_stripe_downleft.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_diagonal_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_center.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_half_vertical_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_straight_cross.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_circle.png": [ + 239, + 239, + 239 + ], + "mcl_shield_pattern_diagonal_left.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_top.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_diagonal_up_left.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_creeper.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_triangle_top.png": [ + 255, + 255, + 255 + ], + "mcl_shield_item_overlay.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_square_top_left.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_flower.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_half_horizontal.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_middle.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_half_vertical.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_triangles_top.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_downright.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_skull.png": [ + 247, + 247, + 247 + ], + "mcl_shield.png": [ + 76, + 61, + 49 + ], + "mcl_shield_pattern_base.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_gradient_up.png": [ + 254, + 254, + 254 + ], + "mcl_shield_pattern_small_stripes.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_square_bottom_left.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_diagonal_up_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_triangles_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_curly_border.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_cross.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_stripe_left.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_gradient.png": [ + 254, + 254, + 254 + ], + "mcl_shield_pattern_square_bottom_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_triangle_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_half_horizontal_bottom.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_bricks.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_thing.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_square_top_right.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_rhombus.png": [ + 255, + 255, + 255 + ], + "mcl_shield_pattern_border.png": [ + 255, + 255, + 255 + ], + "mcl_shield_hud.png": [ + 74, + 58, + 44 + ], + "mcl_shield_base_nopattern.png": [ + 72, + 59, + 49 + ], + "mcl_brewing_bottle_bg.png": [ + 204, + 204, + 204 + ], + "mcl_brewing_bubble_sprite.png": [ + 167, + 167, + 167 + ], + "mcl_brewing_side.png": [ + 175, + 156, + 160 + ], + "mcl_brewing_inventory.png": [ + 168, + 168, + 168 + ], + "mcl_brewing_bubbles_active.png": [ + 186, + 186, + 186 + ], + "mcl_brewing_fuel_bg.png": [ + 200, + 200, + 200 + ], + "mcl_brewing_potion_bg.png": [ + 204, + 204, + 204 + ], + "mcl_brewing_bubbles.png": [ + 154, + 154, + 154 + ], + "mcl_brewing_top.png": [ + 139, + 130, + 126 + ], + "mcl_brewing_base.png": [ + 130, + 122, + 118 + ], + "mcl_brewing_burner.png": [ + 183, + 183, + 183 + ], + "mcl_brewing_burner_active.png": [ + 212, + 161, + 132 + ], + "fletching_table_front.png": [ + 141, + 115, + 95 + ], + "fletching_table_side.png": [ + 150, + 117, + 95 + ], + "fletching_table_top.png": [ + 158, + 129, + 104 + ], + "xpanes_top_glass_cyan.png": [ + 76, + 127, + 153 + ], + "xpanes_top_glass_brown.png": [ + 102, + 76, + 51 + ], + "xpanes_top_glass_magenta.png": [ + 178, + 75, + 215 + ], + "xpanes_top_glass_light_blue.png": [ + 102, + 153, + 216 + ], + "xpanes_top_glass_blue.png": [ + 51, + 76, + 178 + ], + "xpanes_top_glass_gray.png": [ + 76, + 76, + 76 + ], + "xpanes_top_glass_silver.png": [ + 153, + 153, + 153 + ], + "xpanes_top_iron.png": [ + 155, + 146, + 146 + ], + "xpanes_top_glass_black.png": [ + 25, + 25, + 25 + ], + "xpanes_top_glass_white.png": [ + 255, + 255, + 255 + ], + "xpanes_top_glass_lime.png": [ + 127, + 204, + 25 + ], + "xpanes_top_glass_orange.png": [ + 216, + 127, + 51 + ], + "xpanes_top_glass_purple.png": [ + 127, + 63, + 178 + ], + "xpanes_top_glass_red.png": [ + 153, + 51, + 51 + ], + "xpanes_top_glass_natural.png": [ + 222, + 222, + 239 + ], + "xpanes_top_glass_green.png": [ + 102, + 127, + 51 + ], + "xpanes_top_glass_pink.png": [ + 241, + 126, + 164 + ], + "xpanes_pane_iron.png": [ + 160, + 152, + 152 + ], + "xpanes_top_glass_yellow.png": [ + 229, + 229, + 51 + ], + "hardened_clay_stained_pink.png": [ + 164, + 79, + 76 + ], + "mcl_colorblocks_glazed_terracotta_yellow.png": [ + 232, + 199, + 99 + ], + "mcl_colorblocks_glazed_terracotta_orange.png": [ + 170, + 146, + 81 + ], + "mcl_colorblocks_concrete_powder_lime.png": [ + 125, + 186, + 42 + ], + "mcl_colorblocks_concrete_brown.png": [ + 98, + 60, + 32 + ], + "mcl_colorblocks_concrete_magenta.png": [ + 171, + 49, + 162 + ], + "mcl_colorblocks_glazed_terracotta_magenta.png": [ + 210, + 108, + 215 + ], + "mcl_colorblocks_concrete_silver.png": [ + 128, + 129, + 118 + ], + "mcl_colorblocks_glazed_terracotta_grey.png": [ + 90, + 90, + 90 + ], + "mcl_colorblocks_concrete_powder_blue.png": [ + 72, + 75, + 169 + ], + "mcl_colorblocks_concrete_yellow.png": [ + 241, + 177, + 21 + ], + "mcl_colorblocks_concrete_red.png": [ + 146, + 34, + 34 + ], + "mcl_colorblocks_glazed_terracotta_lime.png": [ + 152, + 211, + 72 + ], + "mcl_colorblocks_concrete_black.png": [ + 8, + 10, + 15 + ], + "mcl_colorblocks_glazed_terracotta_silver.png": [ + 134, + 151, + 151 + ], + "hardened_clay_stained_white.png": [ + 213, + 197, + 184 + ], + "mcl_colorblocks_glazed_terracotta_green.png": [ + 111, + 135, + 50 + ], + "mcl_colorblocks_glazed_terracotta_blue.png": [ + 34, + 65, + 117 + ], + "mcl_colorblocks_concrete_powder_red.png": [ + 172, + 57, + 52 + ], + "mcl_colorblocks_concrete_powder_cyan.png": [ + 38, + 150, + 159 + ], + "hardened_clay_stained_purple.png": [ + 81, + 71, + 123 + ], + "hardened_clay_stained_brown.png": [ + 96, + 69, + 61 + ], + "hardened_clay_stained_grey.png": [ + 110, + 92, + 85 + ], + "mcl_colorblocks_concrete_lime.png": [ + 96, + 171, + 25 + ], + "hardened_clay_stained_blue.png": [ + 68, + 91, + 143 + ], + "mcl_colorblocks_concrete_powder_white.png": [ + 224, + 225, + 225 + ], + "hardened_clay_stained_yellow.png": [ + 177, + 128, + 51 + ], + "hardened_clay_stained_light_blue.png": [ + 91, + 128, + 171 + ], + "hardened_clay.png": [ + 143, + 104, + 87 + ], + "mcl_colorblocks_concrete_cyan.png": [ + 21, + 123, + 140 + ], + "mcl_colorblocks_glazed_terracotta_brown.png": [ + 108, + 88, + 64 + ], + "mcl_colorblocks_concrete_grey.png": [ + 56, + 59, + 64 + ], + "mcl_colorblocks_concrete_powder_magenta.png": [ + 196, + 94, + 189 + ], + "mcl_colorblocks_concrete_powder_black.png": [ + 22, + 26, + 30 + ], + "mcl_colorblocks_concrete_pink.png": [ + 213, + 103, + 144 + ], + "mcl_colorblocks_concrete_powder_orange.png": [ + 227, + 141, + 38 + ], + "mcl_colorblocks_glazed_terracotta_cyan.png": [ + 90, + 131, + 136 + ], + "mcl_colorblocks_glazed_terracotta_red.png": [ + 184, + 67, + 53 + ], + "mcl_colorblocks_concrete_green.png": [ + 75, + 94, + 37 + ], + "mcl_colorblocks_concrete_blue.png": [ + 46, + 48, + 147 + ], + "mcl_colorblocks_glazed_terracotta_light_blue.png": [ + 99, + 162, + 204 + ], + "hardened_clay_stained_orange.png": [ + 156, + 95, + 69 + ], + "mcl_colorblocks_concrete_powder_silver.png": [ + 160, + 160, + 155 + ], + "mcl_colorblocks_concrete_powder_pink.png": [ + 224, + 148, + 176 + ], + "hardened_clay_stained_silver.png": [ + 149, + 129, + 117 + ], + "hardened_clay_stained_red.png": [ + 159, + 81, + 66 + ], + "hardened_clay_stained_magenta.png": [ + 150, + 80, + 85 + ], + "mcl_colorblocks_glazed_terracotta_black.png": [ + 38, + 22, + 22 + ], + "mcl_colorblocks_concrete_white.png": [ + 208, + 214, + 215 + ], + "hardened_clay_stained_green.png": [ + 74, + 101, + 63 + ], + "hardened_clay_stained_lime.png": [ + 105, + 134, + 73 + ], + "mcl_colorblocks_concrete_powder_green.png": [ + 104, + 127, + 45 + ], + "mcl_colorblocks_concrete_light_blue.png": [ + 37, + 140, + 200 + ], + "mcl_colorblocks_concrete_powder_brown.png": [ + 128, + 86, + 54 + ], + "mcl_colorblocks_concrete_purple.png": [ + 103, + 32, + 159 + ], + "hardened_clay_stained_cyan.png": [ + 71, + 107, + 123 + ], + "mcl_colorblocks_concrete_powder_purple.png": [ + 138, + 58, + 180 + ], + "mcl_colorblocks_concrete_powder_yellow.png": [ + 230, + 198, + 54 + ], + "mcl_colorblocks_concrete_powder_light_blue.png": [ + 75, + 181, + 212 + ], + "mcl_colorblocks_glazed_terracotta_pink.png": [ + 251, + 138, + 170 + ], + "mcl_colorblocks_glazed_terracotta_purple.png": [ + 112, + 49, + 152 + ], + "mcl_colorblocks_concrete_orange.png": [ + 226, + 101, + 1 + ], + "mcl_colorblocks_concrete_powder_grey.png": [ + 91, + 98, + 103 + ], + "hardened_clay_stained_black.png": [ + 69, + 52, + 46 + ], + "mcl_colorblocks_glazed_terracotta_white.png": [ + 188, + 211, + 202 + ], + "fire_basic_flame_animated.png": [ + 206, + 98, + 34 + ], + "mcl_burning_hud_flame_animated.png": [ + 206, + 98, + 34 + ], + "mcl_fire_fire_charge.png": [ + 95, + 58, + 41 + ], + "mcl_burning_entity_flame_animated.png": [ + 206, + 98, + 34 + ], + "mcl_fire_flint_and_steel.png": [ + 96, + 95, + 93 + ], + "fire_basic_flame.png": [ + 207, + 100, + 36 + ], + "dye_red.png": [ + 113, + 74, + 47 + ], + "dye_yellow.png": [ + 123, + 91, + 49 + ], + "dye_violet.png": [ + 107, + 76, + 57 + ], + "dye_dark_green.png": [ + 99, + 81, + 47 + ], + "mcl_dye_blue.png": [ + 58, + 101, + 173 + ], + "dye_cyan.png": [ + 104, + 89, + 60 + ], + "mcl_dye_lime.png": [ + 107, + 91, + 53 + ], + "dye_pink.png": [ + 120, + 81, + 61 + ], + "mcl_dye_light_blue.png": [ + 103, + 88, + 70 + ], + "dye_dark_grey.png": [ + 108, + 81, + 52 + ], + "mcl_dye_white.png": [ + 205, + 193, + 166 + ], + "dye_grey.png": [ + 113, + 86, + 58 + ], + "dye_magenta.png": [ + 111, + 79, + 59 + ], + "dye_orange.png": [ + 122, + 85, + 48 + ], + "mcl_dye_brown.png": [ + 104, + 75, + 56 + ], + "mcl_dye_black.png": [ + 56, + 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, + 98 + ], + "smoker_front_on.png": [ + 105, + 81, + 68 + ], + "smoker_bottom.png": [ + 115, + 102, + 97 + ], + "smoker_side.png": [ + 105, + 91, + 82 + ], + "smoker_front.png": [ + 93, + 80, + 71 + ], + "smoker_top.png": [ + 110, + 99, + 95 + ], + "mob_spawner.png": [ + 40, + 40, + 40 + ], + "mcl_nether_quartz_chiseled_side.png": [ + 194, + 186, + 183 + ], + "mcl_nether_quartz_pillar_top.png": [ + 195, + 188, + 185 + ], + "mcl_nether_nether_wart.png": [ + 190, + 79, + 75 + ], + "mcl_nether_nether_wart_stage_1.png": [ + 86, + 54, + 51 + ], + "mcl_nether_quartz_ore.png": [ + 133, + 64, + 53 + ], + "mcl_nether_soul_sand.png": [ + 90, + 70, + 51 + ], + "mcl_nether_nether_wart_block.png": [ + 175, + 76, + 73 + ], + "mcl_nether_nether_wart_stage_0.png": [ + 53, + 41, + 38 + ], + "mcl_nether_quartz_block_bottom.png": [ + 198, + 191, + 187 + ], + "mcl_nether_quartz_block_top.png": [ + 198, + 190, + 187 + ], + "mcl_nether_quartz.png": [ + 152, + 149, + 147 + ], + "mcl_nether_quartz_pillar_side.png": [ + 195, + 188, + 184 + ], + "mcl_nether_netherbrick.png": [ + 58, + 24, + 20 + ], + "mcl_nether_glowstone.png": [ + 202, + 154, + 96 + ], + "mcl_nether_netherrack.png": [ + 130, + 50, + 39 + ], + "mcl_nether_red_nether_brick.png": [ + 69, + 17, + 5 + ], + "mcl_nether_quartz_chiseled_top.png": [ + 197, + 189, + 186 + ], + "mcl_nether_glowstone_dust.png": [ + 209, + 137, + 67 + ], + "mcl_nether_nether_wart_stage_2.png": [ + 106, + 57, + 53 + ], + "mcl_nether_quartz_block_side.png": [ + 198, + 190, + 187 + ], + "mcl_nether_nether_brick.png": [ + 49, + 23, + 24 + ], + "mcl_nether_magma.png": [ + 85, + 33, + 27 + ], + "mcl_cauldrons_cauldron_inner.png": [ + 24, + 24, + 24 + ], + "mcl_cauldrons_cauldron_top.png": [ + 54, + 54, + 54 + ], + "mcl_cauldrons_cauldron_bottom.png": [ + 50, + 37, + 38 + ], + "mcl_cauldrons_cauldron.png": [ + 47, + 47, + 47 + ], + "mcl_cauldrons_cauldron_side.png": [ + 43, + 43, + 43 + ], + "mcl_beds_bed_side_bottom_magenta.png": [ + 127, + 48, + 89 + ], + "mcl_beds_bed_blue.png": [ + 73, + 78, + 105 + ], + "mcl_beds_bed_side_top_r_black.png": [ + 99, + 86, + 75 + ], + "mcl_beds_bed_side_bottom_r_magenta.png": [ + 132, + 46, + 94 + ], + "mcl_beds_bed_side_top_brown.png": [ + 98, + 76, + 59 + ], + "respawn_anchor_side2.png": [ + 100, + 76, + 77 + ], + "mcl_beds_bed_lime.png": [ + 96, + 135, + 66 + ], + "mcl_beds_bed_side_top_green.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_light_blue.png": [ + 100, + 107, + 142 + ], + "mcl_beds_bed_pink.png": [ + 184, + 105, + 115 + ], + "mcl_beds_bed_side_bottom_black.png": [ + 66, + 56, + 47 + ], + "mcl_beds_bed_top_bottom_green.png": [ + 57, + 110, + 29 + ], + "mcl_beds_bed_side_top_blue.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_top_pink.png": [ + 217, + 138, + 147 + ], + "mcl_beds_bed_side_bottom_light_blue.png": [ + 90, + 94, + 129 + ], + "mcl_beds_bed_side_bottom_blue.png": [ + 63, + 65, + 90 + ], + "mcl_beds_bed_top_top_red.png": [ + 173, + 90, + 83 + ], + "mcl_beds_bed_side_top_grey.png": [ + 98, + 76, + 59 + ], + "respawn_anchor_bottom.png": [ + 45, + 26, + 54 + ], + "mcl_beds_bed_top_top_white.png": [ + 198, + 190, + 183 + ], + "mcl_beds_bed_top_top_black.png": [ + 107, + 100, + 92 + ], + "mcl_beds_bed_top_bottom_brown.png": [ + 101, + 69, + 38 + ], + "mcl_beds_bed_top_bottom_pink.png": [ + 232, + 105, + 135 + ], + "mcl_beds_bed_side_bottom_r_pink.png": [ + 183, + 95, + 106 + ], + "respawn_anchor_side4.png": [ + 110, + 87, + 85 + ], + "mcl_beds_bed_side_bottom_r_green.png": [ + 73, + 97, + 42 + ], + "mcl_beds_bed_side_bottom_r_grey.png": [ + 86, + 77, + 69 + ], + "mcl_beds_bed_side_top_r_white.png": [ + 158, + 145, + 134 + ], + "mcl_beds_bed_side_bottom_orange.png": [ + 143, + 84, + 28 + ], + "mcl_beds_bed_side_bottom_purple.png": [ + 105, + 36, + 112 + ], + "mcl_beds_bed_side_bottom_r_light_blue.png": [ + 90, + 97, + 136 + ], + "mcl_beds_bed_side_top_r_magenta.png": [ + 140, + 81, + 103 + ], + "mcl_beds_bed_side_bottom_r_yellow.png": [ + 150, + 131, + 25 + ], + "mcl_beds_bed_side_top_r_pink.png": [ + 176, + 111, + 113 + ], + "mcl_beds_bed_top_top_blue.png": [ + 105, + 112, + 137 + ], + "portal.png": [ + 102, + 61, + 130 + ], + "mcl_beds_bed_side_bottom_green.png": [ + 74, + 94, + 43 + ], + "mcl_beds_bed_side_bottom_r_blue.png": [ + 61, + 66, + 95 + ], + "mcl_beds_bed_top_top_grey.png": [ + 129, + 121, + 113 + ], + "mcl_beds_bed_black.png": [ + 76, + 68, + 61 + ], + "mcl_beds_bed_top_top_silver.png": [ + 159, + 151, + 143 + ], + "mcl_beds_bed_white.png": [ + 173, + 165, + 158 + ], + "mcl_beds_bed_top_top_cyan.png": [ + 105, + 144, + 135 + ], + "mcl_beds_bed_top_bottom_orange.png": [ + 184, + 91, + 0 + ], + "mcl_beds_bed_side_top_silver.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_top_brown.png": [ + 143, + 118, + 93 + ], + "mcl_beds_bed_side_top_r_light_blue.png": [ + 115, + 111, + 132 + ], + "mcl_beds_bed_side_bottom_r_lime.png": [ + 86, + 129, + 53 + ], + "mcl_beds_bed_red.png": [ + 139, + 58, + 51 + ], + "mcl_beds_bed_top_bottom_lime.png": [ + 79, + 163, + 47 + ], + "mcl_beds_bed_side_top_r_brown.png": [ + 121, + 97, + 75 + ], + "respawn_anchor_top_off.png": [ + 80, + 61, + 74 + ], + "mcl_beds_bed_side_bottom_r_silver.png": [ + 119, + 109, + 102 + ], + "mcl_beds_bed_yellow.png": [ + 154, + 138, + 41 + ], + "mcl_beds_bed_side_top_yellow.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_bottom_black.png": [ + 37, + 37, + 37 + ], + "mcl_beds_bed_brown.png": [ + 110, + 85, + 61 + ], + "mcl_beds_bed_side_top_orange.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_side_top_red.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_top_purple.png": [ + 148, + 79, + 161 + ], + "mcl_beds_bed_side_bottom_pink.png": [ + 177, + 93, + 102 + ], + "mcl_beds_bed_side_top_r_grey.png": [ + 112, + 99, + 88 + ], + "respawn_anchor_side1.png": [ + 95, + 71, + 76 + ], + "mcl_beds_bed_side_top_r_blue.png": [ + 97, + 91, + 104 + ], + "mcl_beds_bed_side_top_purple.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_side_top_cyan.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_bottom_blue.png": [ + 32, + 60, + 119 + ], + "mcl_beds_bed_side_bottom_yellow.png": [ + 143, + 125, + 28 + ], + "mcl_beds_bed_side_top_black.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_top_orange.png": [ + 188, + 130, + 72 + ], + "mcl_beds_bed_top_bottom_silver.png": [ + 129, + 129, + 129 + ], + "mcl_beds_bed_top_top_green.png": [ + 117, + 140, + 88 + ], + "mcl_beds_bed_cyan.png": [ + 73, + 111, + 103 + ], + "mcl_beds_bed_top_bottom_red.png": [ + 157, + 20, + 20 + ], + "mcl_beds_bed_top_bottom_purple.png": [ + 111, + 0, + 163 + ], + "mcl_beds_bed_side_top_r_silver.png": [ + 133, + 120, + 109 + ], + "mcl_beds_bed_side_bottom_grey.png": [ + 86, + 76, + 67 + ], + "mcl_beds_bed_grey.png": [ + 96, + 88, + 81 + ], + "mcl_beds_bed_side_top_r_yellow.png": [ + 151, + 132, + 62 + ], + "respawn_anchor_side0.png": [ + 81, + 64, + 73 + ], + "mcl_beds_bed_side_top_r_green.png": [ + 103, + 111, + 72 + ], + "mcl_beds_bed_side_bottom_brown.png": [ + 100, + 73, + 48 + ], + "mcl_beds_bed_magenta.png": [ + 138, + 60, + 104 + ], + "mcl_beds_bed_side_bottom_r_red.png": [ + 134, + 44, + 37 + ], + "mcl_beds_bed_side_bottom_r_brown.png": [ + 101, + 73, + 47 + ], + "mcl_beds_bed_side_top_lime.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_side_top_light_blue.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_side_bottom_red.png": [ + 129, + 47, + 38 + ], + "mcl_beds_bed_bottom_top.png": [ + 48, + 38, + 29 + ], + "mcl_beds_bed_top_bottom_grey.png": [ + 76, + 76, + 76 + ], + "mcl_beds_bed_side_bottom_r_orange.png": [ + 150, + 86, + 25 + ], + "mcl_beds_bed_side_bottom_r_black.png": [ + 64, + 54, + 47 + ], + "mcl_beds_bed_top_bottom_cyan.png": [ + 32, + 119, + 114 + ], + "mcl_beds_bed_side_bottom_silver.png": [ + 116, + 106, + 97 + ], + "mcl_beds_bed_side_top_magenta.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_top_bottom_white.png": [ + 201, + 201, + 201 + ], + "mcl_beds_bed_side_top_r_orange.png": [ + 151, + 105, + 62 + ], + "mcl_beds_bed_top_bottom_magenta.png": [ + 154, + 23, + 118 + ], + "mcl_beds_bed_side_top_r_lime.png": [ + 110, + 131, + 80 + ], + "mcl_beds_bed_top_top_magenta.png": [ + 172, + 92, + 137 + ], + "mcl_beds_bed_bottom_bottom.png": [ + 48, + 38, + 29 + ], + "mcl_beds_bed_side_top_r_purple.png": [ + 125, + 73, + 119 + ], + "mcl_beds_bed_side_top_r_cyan.png": [ + 97, + 113, + 103 + ], + "mcl_beds_bed_side_top_white.png": [ + 98, + 76, + 59 + ], + "mcl_beds_bed_side_bottom_r_cyan.png": [ + 61, + 101, + 93 + ], + "mcl_beds_bed_side_bottom_cyan.png": [ + 63, + 97, + 89 + ], + "mcl_beds_bed_side_bottom_white.png": [ + 161, + 151, + 142 + ], + "mcl_beds_bed_top_bottom_yellow.png": [ + 184, + 169, + 0 + ], + "respawn_anchor_side3.png": [ + 104, + 80, + 79 + ], + "mcl_beds_bed_top_bottom_light_blue.png": [ + 82, + 113, + 182 + ], + "mcl_beds_bed_top_top_lime.png": [ + 130, + 169, + 98 + ], + "mcl_beds_bed_silver.png": [ + 109, + 100, + 93 + ], + "mcl_beds_bed_purple.png": [ + 115, + 47, + 128 + ], + "mcl_beds_bed_side_top_r_red.png": [ + 141, + 80, + 69 + ], + "mcl_beds_bed_top_top_light_blue.png": [ + 132, + 141, + 174 + ], + "mcl_beds_bed_side_bottom_r_purple.png": [ + 107, + 32, + 120 + ], + "mcl_beds_bed_side_bottom_r_white.png": [ + 161, + 151, + 144 + ], + "mcl_beds_bed_orange.png": [ + 154, + 96, + 41 + ], + "mcl_beds_bed_top_bottom_gray.png": [ + 57, + 57, + 57 + ], + "mcl_beds_bed_side_bottom_lime.png": [ + 85, + 122, + 53 + ], + "mcl_beds_bed_green.png": [ + 85, + 107, + 56 + ], + "mcl_beds_bed_top_top_yellow.png": [ + 188, + 172, + 72 + ], + "mcl_beds_bed_side_top_pink.png": [ + 98, + 76, + 59 + ], + "mcl_sponges_sponge_wet_river_water.png": [ + 157, + 141, + 104 + ], + "mcl_sponges_sponge.png": [ + 210, + 177, + 118 + ], + "mcl_sponges_sponge_wet.png": [ + 156, + 134, + 92 + ], + "mcl_copper_exposed_cut.png": [ + 129, + 92, + 82 + ], + "mcl_copper_raw.png": [ + 133, + 68, + 50 + ], + "mcl_copper_block_cut.png": [ + 148, + 77, + 57 + ], + "mcl_copper_oxidized_cut.png": [ + 91, + 110, + 110 + ], + "mcl_copper_block.png": [ + 147, + 77, + 56 + ], + "mcl_copper_oxidized.png": [ + 90, + 108, + 110 + ], + "mcl_copper_block_raw.png": [ + 168, + 90, + 68 + ], + "mcl_copper_ingot.png": [ + 157, + 82, + 61 + ], + "mcl_copper_weathered.png": [ + 103, + 102, + 100 + ], + "mcl_copper_weathered_cut.png": [ + 107, + 103, + 100 + ], + "mcl_copper_anti_oxidation_particle.png": [ + 251, + 250, + 247 + ], + "mcl_copper_ore.png": [ + 127, + 66, + 48 + ], + "mcl_copper_exposed.png": [ + 128, + 92, + 83 + ], + "farming_mushroom_red.png": [ + 169, + 59, + 58 + ], + "mcl_mushrooms_mushroom_block_inside.png": [ + 218, + 175, + 136 + ], + "mcl_mushrooms_mushroom_block_skin_brown.png": [ + 131, + 86, + 68 + ], + "mcl_mushrooms_mushroom_block_skin_stem.png": [ + 204, + 183, + 149 + ], + "mcl_mushrooms_mushroom_block_skin_red.png": [ + 137, + 39, + 25 + ], + "farming_mushroom_brown.png": [ + 121, + 81, + 59 + ], + "farming_mushroom_stew.png": [ + 134, + 97, + 67 + ], + "mcl_bells_bell_top.png": [ + 207, + 203, + 82 + ], + "mcl_bells_bell_side.png": [ + 214, + 204, + 84 + ], + "mcl_bells_bell.png": [ + 188, + 143, + 54 + ], + "mcl_bells_bell_bottom.png": [ + 117, + 114, + 39 + ], + "default_tool_goldsword.png": [ + 194, + 154, + 70 + ], + "default_tool_steelsword.png": [ + 134, + 130, + 125 + ], + "default_tool_woodsword.png": [ + 100, + 82, + 68 + ], + "default_tool_goldshovel.png": [ + 167, + 133, + 64 + ], + "default_tool_steelpick.png": [ + 137, + 128, + 119 + ], + "default_tool_woodshovel.png": [ + 108, + 90, + 76 + ], + "default_tool_goldpick.png": [ + 172, + 139, + 73 + ], + "default_tool_woodaxe.png": [ + 110, + 92, + 77 + ], + "default_tool_diamondsword.png": [ + 105, + 133, + 149 + ], + "default_tool_steelshovel.png": [ + 125, + 115, + 107 + ], + "default_tool_stonesword.png": [ + 133, + 125, + 118 + ], + "default_tool_woodpick.png": [ + 110, + 91, + 76 + ], + "default_tool_shears.png": [ + 139, + 132, + 124 + ], + "default_tool_goldaxe.png": [ + 160, + 128, + 66 + ], + "default_tool_stoneshovel.png": [ + 126, + 116, + 107 + ], + "default_tool_diamondaxe.png": [ + 103, + 110, + 113 + ], + "default_tool_diamondshovel.png": [ + 106, + 125, + 134 + ], + "default_tool_steelaxe.png": [ + 129, + 119, + 110 + ], + "default_tool_stoneaxe.png": [ + 126, + 115, + 104 + ], + "default_tool_diamondpick.png": [ + 92, + 105, + 111 + ], + "default_tool_stonepick.png": [ + 126, + 114, + 104 + ], + "mcl_chests_ender_chest_right.png": [ + 73, + 67, + 64 + ], + "mcl_chests_chest_trapped_right.png": [ + 98, + 78, + 62 + ], + "default_chest_front.png": [ + 85, + 70, + 58 + ], + "mcl_chests_blue_shulker_box_top.png": [ + 67, + 85, + 119 + ], + "mcl_chests_chest_left.png": [ + 99, + 78, + 63 + ], + "mcl_chests_dark_green_shulker_box_top.png": [ + 67, + 111, + 70 + ], + "mcl_chests_chest_back.png": [ + 92, + 75, + 61 + ], + "mcl_chests_ender_chest_bottom.png": [ + 61, + 55, + 55 + ], + "mcl_chests_ender.png": [ + 70, + 62, + 58 + ], + "mcl_chests_brown_shulker_box_top.png": [ + 73, + 63, + 55 + ], + "mcl_chests_chest_trapped_back.png": [ + 92, + 75, + 61 + ], + "mcl_chests_chest_trapped_side_big.png": [ + 96, + 77, + 62 + ], + "mcl_chests_magenta_shulker_box_top.png": [ + 128, + 81, + 124 + ], + "mcl_chests_noise.png": [ + 192, + 186, + 189 + ], + "mcl_chests_ender_chest_back.png": [ + 72, + 66, + 64 + ], + "mcl_chests_chest_trapped_bottom.png": [ + 118, + 91, + 70 + ], + "mcl_chests_chest_trapped_front.png": [ + 86, + 68, + 57 + ], + "default_chest_side_big.png": [ + 96, + 77, + 62 + ], + "mcl_chests_green_shulker_box_top.png": [ + 88, + 122, + 75 + ], + "mcl_chests_noise_double.png": [ + 191, + 189, + 189 + ], + "mcl_chests_pink_shulker_box_top.png": [ + 163, + 116, + 158 + ], + "mcl_chests_trapped.png": [ + 95, + 76, + 61 + ], + "mcl_chests_blank.png": [ + 255, + 255, + 255 + ], + "mcl_chests_normal_double.png": [ + 98, + 78, + 62 + ], + "mcl_chests_chest_trapped_top.png": [ + 88, + 73, + 61 + ], + "mcl_chests_normal.png": [ + 95, + 76, + 61 + ], + "default_chest_front_big.png": [ + 93, + 75, + 61 + ], + "mcl_chests_ender_chest_front.png": [ + 76, + 69, + 65 + ], + "mcl_chests_white_shulker_box_top.png": [ + 176, + 178, + 187 + ], + "mcl_chests_cyan_shulker_box_top.png": [ + 67, + 101, + 121 + ], + "mcl_chests_ender_present.png": [ + 123, + 76, + 93 + ], + "mcl_chests_chest_trapped_top_big.png": [ + 100, + 80, + 65 + ], + "default_chest_top_big.png": [ + 100, + 80, + 65 + ], + "mcl_chests_grey_shulker_box_top.png": [ + 126, + 129, + 138 + ], + "mcl_chests_normal_present.png": [ + 181, + 46, + 19 + ], + "mcl_chests_red_shulker_box_top.png": [ + 132, + 58, + 57 + ], + "mcl_chests_trapped_double.png": [ + 98, + 78, + 62 + ], + "mcl_chests_violet_shulker_box_top.png": [ + 120, + 71, + 88 + ], + "mcl_chests_chest_trapped_front_big.png": [ + 94, + 75, + 61 + ], + "mcl_chests_lightblue_shulker_box_top.png": [ + 96, + 130, + 155 + ], + "mcl_chests_dark_grey_shulker_box_top.png": [ + 87, + 90, + 99 + ], + "mcl_chests_black_shulker_box_top.png": [ + 56, + 57, + 62 + ], + "mcl_chests_chest_right.png": [ + 98, + 78, + 62 + ], + "mcl_chests_yellow_shulker_box_top.png": [ + 165, + 116, + 53 + ], + "mcl_chests_trapped_present.png": [ + 73, + 100, + 151 + ], + "mcl_chests_chest_bottom.png": [ + 118, + 91, + 70 + ], + "default_chest_top.png": [ + 88, + 73, + 61 + ], + "mcl_chests_trapped_double_present.png": [ + 143, + 77, + 22 + ], + "mcl_chests_normal_double_present.png": [ + 72, + 90, + 12 + ], + "mcl_chests_ender_chest_top.png": [ + 70, + 64, + 61 + ], + "mcl_chests_ender_chest_left.png": [ + 73, + 67, + 64 + ], + "mcl_chests_chest_trapped_left.png": [ + 99, + 78, + 63 + ], + "mcl_chests_orange_shulker_box_top.png": [ + 143, + 74, + 51 + ], + "screwdriver.png": [ + 132, + 119, + 108 + ], + "_un.png": [ + 0, + 0, + 0 + ], + "_at.png": [ + 0, + 0, + 0 + ], + "_s_.png": [ + 0, + 0, + 0 + ], + "_sz.png": [ + 0, + 0, + 0 + ], + "_q.png": [ + 0, + 0, + 0 + ], + "_1.png": [ + 0, + 0, + 0 + ], + "_h_.png": [ + 0, + 0, + 0 + ], + "_o_tilde.png": [ + 0, + 0, + 0 + ], + "_q_.png": [ + 0, + 0, + 0 + ], + "_ae.png": [ + 0, + 0, + 0 + ], + "_e_circumflex_.png": [ + 0, + 0, + 0 + ], + "_ex.png": [ + 0, + 0, + 0 + ], + "_e_.png": [ + 0, + 0, + 0 + ], + "_qo.png": [ + 0, + 0, + 0 + ], + "_z_.png": [ + 0, + 0, + 0 + ], + "_ps.png": [ + 0, + 0, + 0 + ], + "_pound.png": [ + 0, + 0, + 0 + ], + "_div.png": [ + 0, + 0, + 0 + ], + "_l_.png": [ + 0, + 0, + 0 + ], + "_pilcrow.png": [ + 0, + 0, + 0 + ], + "_3_sup.png": [ + 0, + 0, + 0 + ], + "_e_acute.png": [ + 0, + 0, + 0 + ], + "_9.png": [ + 0, + 0, + 0 + ], + "_e_grave_.png": [ + 0, + 0, + 0 + ], + "_u_acute.png": [ + 0, + 0, + 0 + ], + "_a_sup.png": [ + 0, + 0, + 0 + ], + "_sr.png": [ + 0, + 0, + 0 + ], + "_v.png": [ + 0, + 0, + 0 + ], + "_ue_.png": [ + 0, + 0, + 0 + ], + "_t_.png": [ + 0, + 0, + 0 + ], + "_cl.png": [ + 0, + 0, + 0 + ], + "_n_tilde_.png": [ + 0, + 0, + 0 + ], + "_p_.png": [ + 0, + 0, + 0 + ], + "_c.png": [ + 0, + 0, + 0 + ], + "_a.png": [ + 0, + 0, + 0 + ], + "_a_circumflex_.png": [ + 0, + 0, + 0 + ], + "_8.png": [ + 0, + 0, + 0 + ], + "_s.png": [ + 0, + 0, + 0 + ], + "_o_.png": [ + 0, + 0, + 0 + ], + "_1_4.png": [ + 0, + 0, + 0 + ], + "_e_grave.png": [ + 0, + 0, + 0 + ], + "_o_dash.png": [ + 0, + 0, + 0 + ], + "_5.png": [ + 0, + 0, + 0 + ], + "_d_dash_.png": [ + 0, + 0, + 0 + ], + "_i_grave.png": [ + 0, + 0, + 0 + ], + "_vb.png": [ + 0, + 0, + 0 + ], + "_sp.png": [ + 255, + 255, + 255 + ], + "_a_acute_.png": [ + 0, + 0, + 0 + ], + "_as.png": [ + 0, + 0, + 0 + ], + "_y_acute.png": [ + 0, + 0, + 0 + ], + "_3_4.png": [ + 0, + 0, + 0 + ], + "_6.png": [ + 0, + 0, + 0 + ], + "_7.png": [ + 0, + 0, + 0 + ], + "_tl.png": [ + 0, + 0, + 0 + ], + "_t.png": [ + 0, + 0, + 0 + ], + "_y.png": [ + 0, + 0, + 0 + ], + "_ca.png": [ + 0, + 0, + 0 + ], + "_e.png": [ + 0, + 0, + 0 + ], + "_hs.png": [ + 0, + 0, + 0 + ], + "_copyright.png": [ + 0, + 0, + 0 + ], + "_l.png": [ + 0, + 0, + 0 + ], + "_h.png": [ + 0, + 0, + 0 + ], + "_u_circumflex_.png": [ + 0, + 0, + 0 + ], + "_i_acute_.png": [ + 0, + 0, + 0 + ], + "_ha.png": [ + 0, + 0, + 0 + ], + "_y_diaresis.png": [ + 0, + 0, + 0 + ], + "_gt.png": [ + 0, + 0, + 0 + ], + "_b.png": [ + 0, + 0, + 0 + ], + "_degree.png": [ + 0, + 0, + 0 + ], + "_a_tilde_.png": [ + 0, + 0, + 0 + ], + "_u_.png": [ + 0, + 0, + 0 + ], + "_o_sup.png": [ + 0, + 0, + 0 + ], + "_m_.png": [ + 0, + 0, + 0 + ], + "_c_.png": [ + 0, + 0, + 0 + ], + "_cr.png": [ + 0, + 0, + 0 + ], + "_3.png": [ + 0, + 0, + 0 + ], + "_currency.png": [ + 0, + 0, + 0 + ], + "_f.png": [ + 0, + 0, + 0 + ], + "_cedille.png": [ + 0, + 0, + 0 + ], + "_u_grave_.png": [ + 0, + 0, + 0 + ], + "_dt.png": [ + 0, + 0, + 0 + ], + "_am.png": [ + 0, + 0, + 0 + ], + "_c_cedille_.png": [ + 0, + 0, + 0 + ], + "_u_acute_.png": [ + 0, + 0, + 0 + ], + "_bl.png": [ + 0, + 0, + 0 + ], + "_registered.png": [ + 0, + 0, + 0 + ], + "_i_acute.png": [ + 0, + 0, + 0 + ], + "_lt.png": [ + 0, + 0, + 0 + ], + "_e_acute_.png": [ + 0, + 0, + 0 + ], + "_paragraph.png": [ + 0, + 0, + 0 + ], + "_i_grave_.png": [ + 0, + 0, + 0 + ], + "_o.png": [ + 0, + 0, + 0 + ], + "_1_sup.png": [ + 0, + 0, + 0 + ], + "mcl_signs_sign.png": [ + 114, + 89, + 69 + ], + "_yen.png": [ + 0, + 0, + 0 + ], + "_b_.png": [ + 0, + 0, + 0 + ], + "_macron.png": [ + 0, + 0, + 0 + ], + "_qu_inv.png": [ + 0, + 0, + 0 + ], + "_o_dash_.png": [ + 0, + 0, + 0 + ], + "_guill_right.png": [ + 0, + 0, + 0 + ], + "_p.png": [ + 0, + 0, + 0 + ], + "_thorn_.png": [ + 0, + 0, + 0 + ], + "_2_sup.png": [ + 0, + 0, + 0 + ], + "_pr.png": [ + 0, + 0, + 0 + ], + "default_sign.png": [ + 145, + 115, + 88 + ], + "_times_dot.png": [ + 0, + 0, + 0 + ], + "_acute.png": [ + 0, + 0, + 0 + ], + "_g_.png": [ + 0, + 0, + 0 + ], + "_o_acute_.png": [ + 0, + 0, + 0 + ], + "_a_tilde.png": [ + 0, + 0, + 0 + ], + "_j.png": [ + 0, + 0, + 0 + ], + "_k.png": [ + 0, + 0, + 0 + ], + "_co.png": [ + 0, + 0, + 0 + ], + "_dv.png": [ + 0, + 0, + 0 + ], + "_o_circumflex.png": [ + 0, + 0, + 0 + ], + "_a_ring.png": [ + 0, + 0, + 0 + ], + "_br.png": [ + 0, + 0, + 0 + ], + "_d.png": [ + 0, + 0, + 0 + ], + "_ap.png": [ + 0, + 0, + 0 + ], + "_sl.png": [ + 0, + 0, + 0 + ], + "_mn.png": [ + 0, + 0, + 0 + ], + "_m.png": [ + 0, + 0, + 0 + ], + "_ae_lig.png": [ + 0, + 0, + 0 + ], + "_thorn.png": [ + 0, + 0, + 0 + ], + "_2.png": [ + 0, + 0, + 0 + ], + "_gr.png": [ + 0, + 0, + 0 + ], + "_i.png": [ + 0, + 0, + 0 + ], + "_y_acute_.png": [ + 0, + 0, + 0 + ], + "_diaresis.png": [ + 0, + 0, + 0 + ], + "_oe.png": [ + 0, + 0, + 0 + ], + "_mu.png": [ + 0, + 0, + 0 + ], + "_guill_left.png": [ + 0, + 0, + 0 + ], + "_times_cross.png": [ + 0, + 0, + 0 + ], + "_ae_.png": [ + 0, + 0, + 0 + ], + "_w.png": [ + 0, + 0, + 0 + ], + "_u.png": [ + 0, + 0, + 0 + ], + "_broken_bar.png": [ + 0, + 0, + 0 + ], + "_4.png": [ + 0, + 0, + 0 + ], + "_plus_minus.png": [ + 0, + 0, + 0 + ], + "_1_2.png": [ + 0, + 0, + 0 + ], + "_u_circumflex.png": [ + 0, + 0, + 0 + ], + "_w_.png": [ + 0, + 0, + 0 + ], + "_x_.png": [ + 0, + 0, + 0 + ], + "_e_circumflex.png": [ + 0, + 0, + 0 + ], + "_g.png": [ + 0, + 0, + 0 + ], + "_o_tilde_.png": [ + 0, + 0, + 0 + ], + "_ae_lig_.png": [ + 0, + 0, + 0 + ], + "_v_.png": [ + 0, + 0, + 0 + ], + "_dl.png": [ + 0, + 0, + 0 + ], + "_a_grave.png": [ + 0, + 0, + 0 + ], + "_re.png": [ + 0, + 0, + 0 + ], + "_a_acute.png": [ + 0, + 0, + 0 + ], + "_qu.png": [ + 0, + 0, + 0 + ], + "_oe_.png": [ + 0, + 0, + 0 + ], + "_n_tilde.png": [ + 0, + 0, + 0 + ], + "_eq.png": [ + 0, + 0, + 0 + ], + "_d_.png": [ + 0, + 0, + 0 + ], + "_sm.png": [ + 0, + 0, + 0 + ], + "_y_.png": [ + 0, + 0, + 0 + ], + "_not.png": [ + 0, + 0, + 0 + ], + "_n.png": [ + 0, + 0, + 0 + ], + "_j_.png": [ + 0, + 0, + 0 + ], + "_k_.png": [ + 0, + 0, + 0 + ], + "_0.png": [ + 0, + 0, + 0 + ], + "_o_grave_.png": [ + 0, + 0, + 0 + ], + "_r_.png": [ + 0, + 0, + 0 + ], + "_r.png": [ + 0, + 0, + 0 + ], + "_u_grave.png": [ + 0, + 0, + 0 + ], + "_ee_.png": [ + 0, + 0, + 0 + ], + "_c_cedille.png": [ + 0, + 0, + 0 + ], + "_ex_inv.png": [ + 0, + 0, + 0 + ], + "_cm.png": [ + 0, + 0, + 0 + ], + "_o_grave.png": [ + 0, + 0, + 0 + ], + "_x.png": [ + 0, + 0, + 0 + ], + "_i_.png": [ + 0, + 0, + 0 + ], + "_n_.png": [ + 0, + 0, + 0 + ], + "_rc.png": [ + 0, + 0, + 0 + ], + "_a_.png": [ + 0, + 0, + 0 + ], + "_a_grave_.png": [ + 0, + 0, + 0 + ], + "_ee.png": [ + 0, + 0, + 0 + ], + "_o_acute.png": [ + 0, + 0, + 0 + ], + "_a_ring_.png": [ + 0, + 0, + 0 + ], + "_i_circumflex_.png": [ + 0, + 0, + 0 + ], + "_cent.png": [ + 0, + 0, + 0 + ], + "_d_dash.png": [ + 0, + 0, + 0 + ], + "_f_.png": [ + 0, + 0, + 0 + ], + "_o_circumflex_.png": [ + 0, + 0, + 0 + ], + "_ue.png": [ + 0, + 0, + 0 + ], + "_a_circumflex.png": [ + 0, + 0, + 0 + ], + "_i_circumflex.png": [ + 0, + 0, + 0 + ], + "_z.png": [ + 0, + 0, + 0 + ], + "gui_furnace_arrow_fg.png": [ + 239, + 239, + 239 + ], + "default_furnace_front.png": [ + 105, + 95, + 91 + ], + "default_furnace_fire_bg.png": [ + 139, + 139, + 139 + ], + "default_furnace_top.png": [ + 148, + 138, + 133 + ], + "default_furnace_fire_fg.png": [ + 179, + 115, + 70 + ], + "default_furnace_side.png": [ + 117, + 107, + 102 + ], + "gui_furnace_arrow_bg.png": [ + 139, + 139, + 139 + ], + "default_furnace_front_active.png": [ + 119, + 95, + 85 + ], + "default_furnace_bottom.png": [ + 148, + 138, + 133 + ], + "default_torch_on_floor.png": [ + 115, + 82, + 59 + ], + "default_torch_on_floor_animated.png": [ + 116, + 84, + 61 + ], + "default_tnt_bottom.png": [ + 161, + 54, + 58 + ], + "mcl_tnt_blink.png": [ + 255, + 255, + 255 + ], + "default_tnt_top.png": [ + 125, + 54, + 57 + ], + "default_tnt_side.png": [ + 178, + 105, + 98 + ], + "mcl_heads_skeleton.png": [ + 125, + 125, + 125 + ], + "mcl_heads_skeleton_node.png": [ + 124, + 124, + 124 + ], + "mcl_heads_creeper_node.png": [ + 98, + 107, + 71 + ], + "mcl_heads_zombie.png": [ + 66, + 104, + 69 + ], + "mcl_heads_creeper.png": [ + 92, + 110, + 68 + ], + "mcl_heads_steve_node.png": [ + 115, + 70, + 58 + ], + "mcl_heads_zombie_node.png": [ + 78, + 110, + 105 + ], + "mcl_heads_steve.png": [ + 108, + 76, + 59 + ], + "mcl_heads_wither_skeleton_node.png": [ + 50, + 50, + 50 + ], + "mcl_heads_wither_skeleton.png": [ + 50, + 50, + 50 + ], + "mcl_flowerpots_cactus.png": [ + 109, + 83, + 52 + ], + "mcl_flowerpots_flowerpot_inventory.png": [ + 121, + 54, + 45 + ], + "mcl_flowerpots_flowerpot.png": [ + 120, + 55, + 47 + ], + "mcl_buckets_lava_bucket.png": [ + 166, + 127, + 113 + ], + "bucket_river_water.png": [ + 139, + 152, + 155 + ], + "bucket_water.png": [ + 139, + 147, + 155 + ], + "bucket.png": [ + 147, + 143, + 139 + ], + "mcl_totems_totem.png": [ + 185, + 139, + 52 + ], + "mcl_anvils_anvil_top_damaged_1.png": [ + 50, + 50, + 50 + ], + "mcl_anvils_anvil_top_damaged_2.png": [ + 48, + 48, + 48 + ], + "mcl_anvils_anvil_top_damaged_0.png": [ + 52, + 52, + 52 + ], + "mcl_anvils_anvil_side.png": [ + 45, + 45, + 45 + ], + "mcl_anvils_inventory.png": [ + 157, + 157, + 157 + ], + "mcl_anvils_anvil_base.png": [ + 40, + 40, + 40 + ], + "mcl_maps_player_arrow.png": [ + 95, + 95, + 95 + ], + "mcl_maps_map_filled.png": [ + 213, + 176, + 148 + ], + "mcl_maps_player_dot.png": [ + 105, + 105, + 105 + ], + "mcl_maps_map_empty.png": [ + 217, + 187, + 157 + ], + "mcl_maps_map_filled_markings.png": [ + 183, + 183, + 183 + ], + "mcl_maps_map_background.png": [ + 224, + 196, + 166 + ], + "mcl_dispensers_dispenser_front_vertical.png": [ + 115, + 104, + 99 + ], + "mcl_dispensers_dispenser_front_horizontal.png": [ + 105, + 96, + 92 + ], + "jeija_wall_lever.png": [ + 95, + 80, + 69 + ], + "mesecons_delayer_front_locked_off.png": [ + 97, + 85, + 77 + ], + "mesecons_delayer_locked_on.png": [ + 114, + 100, + 95 + ], + "mesecons_delayer_sides_locked_off.png": [ + 95, + 80, + 73 + ], + "mesecons_delayer_sides_on.png": [ + 106, + 71, + 63 + ], + "mesecons_delayer_item.png": [ + 100, + 87, + 82 + ], + "mesecons_delayer_end_locked_off.png": [ + 97, + 85, + 77 + ], + "mesecons_delayer_end_locked_on.png": [ + 101, + 85, + 78 + ], + "mesecons_delayer_ends_off.png": [ + 99, + 86, + 80 + ], + "mesecons_delayer_front_locked_on.png": [ + 101, + 85, + 77 + ], + "mesecons_delayer_ends_on.png": [ + 105, + 87, + 81 + ], + "mesecons_delayer_sides_locked_on.png": [ + 104, + 81, + 74 + ], + "mesecons_delayer_locked_off.png": [ + 110, + 99, + 95 + ], + "mesecons_delayer_sides_off.png": [ + 90, + 69, + 61 + ], + "mesecons_delayer_off.png": [ + 112, + 100, + 96 + ], + "mesecons_delayer_on.png": [ + 116, + 101, + 97 + ], + "redstone_redstone_dust_line0.png": [ + 168, + 168, + 168 + ], + "redstone_redstone_dust.png": [ + 81, + 0, + 0 + ], + "redstone_redstone_dust_dot.png": [ + 168, + 168, + 168 + ], + "redstone_redstone_dust_line1.png": [ + 173, + 173, + 173 + ], + "jeija_commandblock_off.png": [ + 110, + 99, + 96 + ], + "jeija_commandblock_on.png": [ + 110, + 99, + 96 + ], + "redstone_redstone_block.png": [ + 128, + 8, + 9 + ], + "jeija_torches_on.png": [ + 102, + 68, + 56 + ], + "jeija_torches_off.png": [ + 90, + 66, + 54 + ], + "mesecons_button_wield_mask.png": [ + 255, + 126, + 126 + ], + "mcl_droppers_dropper_front_vertical.png": [ + 118, + 108, + 103 + ], + "mcl_droppers_dropper_front_horizontal.png": [ + 110, + 101, + 96 + ], + "mesecons_noteblock.png": [ + 104, + 81, + 63 + ], + "jeija_solar_panel_inverted.png": [ + 100, + 107, + 117 + ], + "jeija_solar_panel.png": [ + 124, + 113, + 101 + ], + "jeija_solar_panel_side.png": [ + 60, + 47, + 36 + ], + "mcl_observers_observer_top.png": [ + 139, + 128, + 123 + ], + "mcl_observers_observer_front.png": [ + 95, + 80, + 84 + ], + "mcl_observers_observer_back_lit.png": [ + 75, + 67, + 65 + ], + "mcl_observers_observer_back.png": [ + 72, + 67, + 64 + ], + "mcl_observers_observer_side.png": [ + 111, + 103, + 99 + ], + "mesecons_piston_pusher_front_sticky.png": [ + 97, + 81, + 63 + ], + "mesecons_piston_pusher_top.png": [ + 106, + 83, + 65 + ], + "mesecons_piston_back.png": [ + 110, + 101, + 98 + ], + "mesecons_piston_on_front.png": [ + 111, + 101, + 98 + ], + "mesecons_piston_pusher_back.png": [ + 106, + 83, + 65 + ], + "mesecons_piston_bottom.png": [ + 120, + 107, + 100 + ], + "mesecons_piston_pusher_right.png": [ + 106, + 83, + 65 + ], + "mesecons_piston_pusher_bottom.png": [ + 106, + 83, + 65 + ], + "mesecons_piston_pusher_front.png": [ + 106, + 83, + 65 + ], + "mesecons_piston_pusher_left.png": [ + 106, + 83, + 65 + ], + "jeija_lightstone_gray_on.png": [ + 97, + 56, + 37 + ], + "jeija_lightstone_gray_off.png": [ + 64, + 49, + 43 + ], + "mcl_target_target_side.png": [ + 177, + 117, + 94 + ], + "mcl_target_target_top.png": [ + 177, + 117, + 94 + ], + "mcl_comparators_sides_on.png": [ + 105, + 87, + 81 + ], + "mcl_comparators_comp.png": [ + 61, + 20, + 20 + ], + "mcl_comparators_on.png": [ + 116, + 102, + 98 + ], + "mcl_comparators_sides_comp.png": [ + 99, + 88, + 83 + ], + "mcl_comparators_off.png": [ + 113, + 102, + 98 + ], + "mcl_comparators_ends_comp.png": [ + 99, + 88, + 83 + ], + "mcl_comparators_ends_sub.png": [ + 105, + 88, + 83 + ], + "mcl_comparators_ends_off.png": [ + 96, + 80, + 74 + ], + "mcl_comparators_ends_on.png": [ + 105, + 81, + 75 + ], + "mcl_comparators_sub.png": [ + 112, + 25, + 25 + ], + "mcl_comparators_item.png": [ + 98, + 83, + 79 + ], + "mcl_comparators_sides_off.png": [ + 99, + 86, + 80 + ], + "mcl_comparators_sides_sub.png": [ + 105, + 88, + 83 + ], + "default_book.png": [ + 103, + 67, + 44 + ], + "default_bookshelf.png": [ + 84, + 67, + 54 + ], + "mcl_books_book_written.png": [ + 110, + 74, + 44 + ], + "mcl_books_book_bg.png": [ + 203, + 180, + 151 + ], + "mcl_books_button9_pressed.png": [ + 145, + 112, + 86 + ], + "mcl_books_button9.png": [ + 145, + 112, + 86 + ], + "mcl_books_book_writable.png": [ + 151, + 122, + 108 + ], + "mcl_books_bookshelf_top.png": [ + 109, + 84, + 65 + ], + "wool_dark_grey.png": [ + 96, + 87, + 87 + ], + "wool_grey.png": [ + 143, + 134, + 134 + ], + "wool_magenta.png": [ + 140, + 85, + 125 + ], + "wool_black.png": [ + 45, + 42, + 42 + ], + "wool_orange.png": [ + 188, + 106, + 45 + ], + "wool_blue.png": [ + 43, + 73, + 125 + ], + "wool_yellow.png": [ + 201, + 163, + 69 + ], + "wool_pink.png": [ + 171, + 91, + 108 + ], + "wool_dark_green.png": [ + 53, + 91, + 51 + ], + "wool_brown.png": [ + 86, + 57, + 43 + ], + "wool_red.png": [ + 132, + 42, + 45 + ], + "mcl_wool_light_blue.png": [ + 91, + 130, + 180 + ], + "wool_cyan.png": [ + 30, + 94, + 113 + ], + "mcl_wool_lime.png": [ + 107, + 151, + 76 + ], + "wool_white.png": [ + 212, + 199, + 182 + ], + "wool_violet.png": [ + 77, + 57, + 102 + ], + "mcl_potions_melon_speckled.png": [ + 170, + 97, + 62 + ], + "mcl_potions_effect_swift.png": [ + 106, + 96, + 85 + ], + "mcl_potions_spider_eye_fermented.png": [ + 143, + 97, + 62 + ], + "mcl_potions_splash_bottle.png": [ + 168, + 156, + 183 + ], + "mcl_potions_effect_water_breathing.png": [ + 59, + 69, + 100 + ], + "mcl_potions_effect_leaping.png": [ + 100, + 91, + 86 + ], + "mcl_potions_effect_weak.png": [ + 127, + 126, + 126 + ], + "mcl_potions_dragon_breath.png": [ + 171, + 137, + 163 + ], + "mcl_potions_effect_food_poisoning.png": [ + 112, + 123, + 89 + ], + "hudbars_icon_regenerate.png": [ + 195, + 77, + 114 + ], + "mcl_potions_effect_fire_proof.png": [ + 112, + 68, + 68 + ], + "mcl_potions_splash_overlay.png": [ + 202, + 202, + 202 + ], + "mcl_potions_effect_invisible.png": [ + 96, + 103, + 95 + ], + "hbhunger_icon_regen_poison.png": [ + 147, + 111, + 115 + ], + "mcl_potions_effect_slow.png": [ + 78, + 81, + 85 + ], + "mcl_potions_lingering_bottle.png": [ + 181, + 159, + 192 + ], + "mcl_potions_potion_overlay.png": [ + 201, + 201, + 201 + ], + "mcl_potions_effect_regenerating.png": [ + 133, + 90, + 83 + ], + "mcl_potions_arrow_inv.png": [ + 171, + 165, + 160 + ], + "mcl_potions_effect_night_vision.png": [ + 86, + 99, + 74 + ], + "mcl_potions_potion_bottle.png": [ + 156, + 172, + 203 + ], + "mcl_potions_effect_poisoned.png": [ + 78, + 110, + 80 + ], + "mcl_potions_effect_strong.png": [ + 100, + 82, + 97 + ], + "crafting_workbench_front.png": [ + 120, + 93, + 72 + ], + "gui_crafting_arrow.png": [ + 139, + 139, + 139 + ], + "crafting_workbench_side.png": [ + 120, + 93, + 72 + ], + "crafting_workbench_top.png": [ + 152, + 121, + 93 + ], + "mcl_amethyst_amethyst_bud_small.png": [ + 176, + 131, + 203 + ], + "mcl_amethyst_amethyst_block.png": [ + 139, + 84, + 172 + ], + "mcl_amethyst_amethyst_cluster.png": [ + 161, + 111, + 190 + ], + "mcl_amethyst_calcite_block.png": [ + 189, + 193, + 207 + ], + "mcl_amethyst_amethyst_shard.png": [ + 163, + 113, + 192 + ], + "mcl_amethyst_amethyst_bud_medium.png": [ + 184, + 140, + 209 + ], + "mcl_amethyst_amethyst_bud_large.png": [ + 173, + 127, + 201 + ], + "mcl_amethyst_tinted_glass.png": [ + 125, + 67, + 160 + ], + "mcl_amethyst_amethyst_cluster_block.png": [ + 180, + 136, + 206 + ], + "mcl_amethyst_budding_amethyst.png": [ + 134, + 77, + 167 + ], + "mcl_enchanting_glyph_11.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_14.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_6.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_8.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_9.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_3.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_number_1_off.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_number_3_off.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_number_3.png": [ + 151, + 47, + 40 + ], + "mcl_enchanting_book_open.png": [ + 153, + 123, + 99 + ], + "mcl_enchanting_button_off.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_glyph_2.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_1.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_button.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_table_side.png": [ + 66, + 58, + 55 + ], + "mcl_enchanting_book_closed.png": [ + 112, + 78, + 55 + ], + "mcl_enchanting_table_bottom.png": [ + 58, + 51, + 52 + ], + "mcl_enchanting_glyph_15.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_number_2_off.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_glyph_5.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_number_1.png": [ + 149, + 45, + 39 + ], + "mcl_enchanting_glyph_7.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_table_top.png": [ + 88, + 86, + 84 + ], + "mcl_enchanting_number_2.png": [ + 149, + 46, + 39 + ], + "mcl_enchanting_glyph_16.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_button_hovered.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_book_enchanted.png": [ + 122, + 69, + 46 + ], + "mcl_enchanting_glyph_4.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_10.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_13.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_17.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_glyph_18.png": [ + 209, + 209, + 231 + ], + "mcl_enchanting_lapis_background.png": [ + 255, + 255, + 255 + ], + "mcl_enchanting_button_background.png": [ + 229, + 202, + 171 + ], + "mcl_enchanting_glyph_12.png": [ + 209, + 209, + 231 + ], + "doc_basics_gameplay_mtg_2.png": [ + 151, + 168, + 207 + ], + "doc_basics_liquids_renewable_1.png": [ + 139, + 146, + 159 + ], + "doc_basics_players_sam.png": [ + 95, + 133, + 106 + ], + "doc_basics_players_flat.png": [ + 127, + 155, + 130 + ], + "doc_basics_craft_shapeless_2.png": [ + 52, + 52, + 48 + ], + "doc_basics_build.png": [ + 84, + 84, + 55 + ], + "doc_basics_pointing.png": [ + 66, + 104, + 32 + ], + "doc_basics_nodes.png": [ + 108, + 104, + 94 + ], + "doc_basics_craft_groups_2.png": [ + 65, + 58, + 52 + ], + "doc_basics_craft_groups_1.png": [ + 57, + 57, + 58 + ], + "doc_basics_inventory.png": [ + 47, + 47, + 45 + ], + "doc_basics_minimap_radar.png": [ + 73, + 164, + 128 + ], + "doc_basics_sneak.png": [ + 70, + 69, + 69 + ], + "doc_basics_camera_behind.png": [ + 108, + 144, + 135 + ], + "doc_basics_craft_repair.png": [ + 47, + 46, + 45 + ], + "doc_basics_hotbar_relations.png": [ + 85, + 84, + 69 + ], + "doc_basics_gameplay_lott.png": [ + 119, + 122, + 112 + ], + "doc_basics_tools_mining.png": [ + 64, + 62, + 59 + ], + "doc_basics_players_lott.png": [ + 180, + 193, + 224 + ], + "doc_basics_gameplay_outback.png": [ + 146, + 114, + 109 + ], + "doc_basics_gameplay_pixture.png": [ + 94, + 120, + 57 + ], + "doc_basics_craft_grid.png": [ + 46, + 46, + 46 + ], + "doc_basics_craft_groups_3.png": [ + 61, + 58, + 55 + ], + "doc_basics_camera_front.png": [ + 99, + 133, + 110 + ], + "doc_basics_minimap_map.png": [ + 149, + 169, + 183 + ], + "doc_basics_gameplay_mtg_1.png": [ + 136, + 117, + 86 + ], + "doc_basics_gameplay_xtraores_xtension.png": [ + 95, + 15, + 86 + ], + "doc_basics_light_torch.png": [ + 25, + 43, + 14 + ], + "doc_basics_minimap_round.png": [ + 160, + 175, + 189 + ], + "doc_basics_light_test.png": [ + 133, + 113, + 69 + ], + "doc_basics_liquids_nonrenewable.png": [ + 64, + 87, + 87 + ], + "doc_basics_gameplay_hades.png": [ + 81, + 70, + 62 + ], + "doc_basics_gameplay_moontest.png": [ + 75, + 74, + 79 + ], + "doc_basics_liquids_range.png": [ + 146, + 166, + 179 + ], + "doc_basics_inventory_detail.png": [ + 43, + 41, + 39 + ], + "doc_basics_camera_ego.png": [ + 111, + 147, + 139 + ], + "doc_basics_tools.png": [ + 46, + 45, + 42 + ], + "doc_basics_liquids_renewable_2.png": [ + 136, + 148, + 166 + ], + "doc_basics_items_dropped.png": [ + 195, + 185, + 147 + ], + "doc_basics_liquids_types.png": [ + 146, + 164, + 171 + ], + "doc_basics_gameplay_carbone_ng.png": [ + 121, + 118, + 89 + ], + "doc_basics_craft_shaped.png": [ + 55, + 52, + 50 + ], + "doc_basics_hotbar.png": [ + 141, + 175, + 226 + ], + "doc_basics_craft_shapeless_1.png": [ + 52, + 52, + 48 + ], + "doc_button_icon_lores.png": [ + 19, + 143, + 183 + ], + "doc_awards_icon_generic.png": [ + 14, + 125, + 162 + ], + "inventory_plus_doc_inventory_plus.png": [ + 19, + 143, + 183 + ], + "doc_button_icon_hires.png": [ + 30, + 149, + 188 + ], + "doc_identifier_identifier.png": [ + 172, + 151, + 139 + ], + "doc_identifier_identifier_liquid.png": [ + 125, + 147, + 190 + ], + "craftguide_furnace.png": [ + 119, + 95, + 85 + ], + "craftguide_clear_icon.png": [ + 254, + 254, + 254 + ], + "craftguide_book.png": [ + 84, + 117, + 39 + ], + "mcl_craftguide_fuel.png": [ + 187, + 121, + 75 + ], + "craftguide_prev_icon.png": [ + 255, + 255, + 255 + ], + "craftguide_zoomout_icon.png": [ + 255, + 255, + 255 + ], + "craftguide_search_icon.png": [ + 254, + 254, + 254 + ], + "craftguide_arrow.png": [ + 139, + 139, + 139 + ], + "craftguide_zoomin_icon.png": [ + 255, + 255, + 255 + ], + "craftguide_shapeless.png": [ + 130, + 130, + 130 + ], + "craftguide_next_icon.png": [ + 255, + 255, + 255 + ] +} diff --git a/mods/ITEMS/mcl_maps/init.lua b/mods/ITEMS/mcl_maps/init.lua index 893e70073..d882785c5 100644 --- a/mods/ITEMS/mcl_maps/init.lua +++ b/mods/ITEMS/mcl_maps/init.lua @@ -1,87 +1,305 @@ -local S = minetest.get_translator("mcl_maps") +mcl_maps = {} --- Turn empty map into filled map by rightclick -local make_filled_map = function(itemstack, placer, pointed_thing) - local new_map = ItemStack("mcl_maps:filled_map") - itemstack:take_item() - if itemstack:is_empty() then - return new_map - else - local inv = placer:get_inventory() - if inv:room_for_item("main", new_map) then - inv:add_item("main", new_map) - else - minetest.add_item(placer:get_pos(), new_map) +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + +local math = math +local vector = vector +local table = table +local pairs = pairs + +local pos_to_string = minetest.pos_to_string +local string_to_pos = minetest.string_to_pos +local get_item_group = minetest.get_item_group +local dynamic_add_media = minetest.dynamic_add_media +local get_connected_players = minetest.get_connected_players + +local storage = minetest.get_mod_storage() +local worldpath = minetest.get_worldpath() +local map_textures_path = worldpath .. "/mcl_maps/" +--local last_finished_id = storage:get_int("next_id") - 1 + +minetest.mkdir(map_textures_path) + +local function load_json_file(name) + local file = assert(io.open(modpath .. "/" .. name .. ".json", "r")) + local data = minetest.parse_json(file:read("*all")) + file:close() + return data +end + +local texture_colors = load_json_file("colors") +local palettes_grass = load_json_file("palettes_grass") +local palettes_foliage = load_json_file("palettes_foliage") +local palettes_water = load_json_file("palettes_water") + +local color_cache = {} + +local creating_maps = {} +local loaded_maps = {} + +local c_air = minetest.get_content_id("air") + +function mcl_maps.create_map(pos) + local minp = vector.multiply(vector.floor(vector.divide(pos, 128)), 128) + local maxp = vector.add(minp, vector.new(127, 127, 127)) + + local itemstack = ItemStack("mcl_maps:filled_map") + local meta = itemstack:get_meta() + local next_id = storage:get_int("next_id") + storage:set_int("next_id", next_id + 1) + local id = tostring(next_id) + meta:set_string("mcl_maps:id", id) + meta:set_string("mcl_maps:minp", pos_to_string(minp)) + meta:set_string("mcl_maps:maxp", pos_to_string(maxp)) + tt.reload_itemstack_description(itemstack) + + creating_maps[id] = true + minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining) + if calls_remaining > 0 then + return + end + local vm = minetest.get_voxel_manip() + local emin, emax = vm:read_from_map(minp, maxp) + local data = vm:get_data() + local param2data = vm:get_param2_data() + local area = VoxelArea:new({ MinEdge = emin, MaxEdge = emax }) + local pixels = {} + local last_heightmap + for x = 1, 128 do + local map_x = minp.x - 1 + x + local heightmap = {} + for z = 1, 128 do + local map_z = minp.z - 1 + z + local color, height + for map_y = maxp.y, minp.y, -1 do + local index = area:index(map_x, map_y, map_z) + local c_id = data[index] + if c_id ~= c_air then + color = color_cache[c_id] + if color == nil then + local nodename = minetest.get_name_from_content_id(c_id) + local def = minetest.registered_nodes[nodename] + if def then + local texture + if def.palette then + texture = def.palette + elseif def.tiles then + texture = def.tiles[1] + if type(texture) == "table" then + texture = texture.name + end + end + if texture then + texture = texture:match("([^=^%^]-([^.]+))$"):split("^")[1] + end + if def.palette == "mcl_core_palette_grass.png" then + local palette = palettes_grass[texture] + color = palette and { palette = palette } + elseif def.palette == "mcl_core_palette_foliage.png" then + local palette = palettes_foliage[texture] + color = palette and { palette = palette } + elseif def.palette == "mcl_core_palette_water.png" then + local palette = palettes_water[texture] + color = palette and { palette = palette } + else + color = texture_colors[texture] + end + end + end + + if color and color.palette then + color = color.palette[param2data[index] + 1] + else + color_cache[c_id] = color or false + end + + if color and last_heightmap then + local last_height = last_heightmap[z] + if last_height < map_y then + color = { + math.min(255, color[1] + 16), + math.min(255, color[2] + 16), + math.min(255, color[3] + 16), + } + elseif last_height > map_y then + color = { + math.max(0, color[1] - 16), + math.max(0, color[2] - 16), + math.max(0, color[3] - 16), + } + end + end + height = map_y + break + end + end + heightmap[z] = height or minp.y + pixels[z] = pixels[z] or {} + pixels[z][x] = color or { 0, 0, 0 } + end + last_heightmap = heightmap + end + tga_encoder.image(pixels):save(map_textures_path .. "mcl_maps_map_texture_" .. id .. ".tga") + creating_maps[id] = nil + end) + return itemstack +end + +function mcl_maps.load_map(id, callback) + if id == "" or creating_maps[id] then + return false + end + + local texture = "mcl_maps_map_texture_" .. id .. ".tga" + + local result = true + + if not loaded_maps[id] then + if not minetest.features.dynamic_add_media_table then + -- minetest.dynamic_add_media() blocks in + -- Minetest 5.3 and 5.4 until media loads + loaded_maps[id] = true + result = dynamic_add_media(map_textures_path .. texture, function() + end) + if callback then + callback(texture) + end + else + -- minetest.dynamic_add_media() never blocks + -- in Minetest 5.5, callback runs after load + result = dynamic_add_media(map_textures_path .. texture, function() + loaded_maps[id] = true + if callback then + callback(texture) + end + end) + end + end + + if result == false then + return false + end + + if loaded_maps[id] then + if callback then + callback(texture) + end + return texture + end +end + +function mcl_maps.load_map_item(itemstack) + return mcl_maps.load_map(itemstack:get_meta():get_string("mcl_maps:id")) +end + +local function fill_map(itemstack, placer, pointed_thing) + local new_stack = mcl_util.call_on_rightclick(itemstack, placer, pointed_thing) + if new_stack then + return new_stack + end + + if minetest.settings:get_bool("enable_real_maps", true) then + local new_map = mcl_maps.create_map(placer:get_pos()) + itemstack:take_item() + if itemstack:is_empty() then + return new_map + else + local inv = placer:get_inventory() + if inv:room_for_item("main", new_map) then + inv:add_item("main", new_map) + else + minetest.add_item(placer:get_pos(), new_map) + end + return itemstack end - return itemstack end end minetest.register_craftitem("mcl_maps:empty_map", { description = S("Empty Map"), _doc_items_longdesc = S("Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used."), - _doc_items_usagehelp = S("Rightclick to start using the map (which can't be stacked anymore)."), + _doc_items_usagehelp = S("Rightclick to create a filled map (which can't be stacked anymore)."), inventory_image = "mcl_maps_map_empty.png", - groups = { not_in_creative_inventory = 1 }, - on_place = make_filled_map, - on_secondary_use = make_filled_map, + on_place = fill_map, + on_secondary_use = fill_map, stack_max = 64, }) -local function has_item_in_hotbar(player, item) - -- Requirement: player carries the tool in the hotbar - local inv = player:get_inventory() - local hotbar = player:hud_get_hotbar_itemcount() - for i=1, hotbar do - if inv:get_stack("main", i):get_name() == item then - return true - end - end - return false -end - --- Checks if player is still allowed to display the minimap -local function update_minimap(player) - local creative = minetest.is_creative_enabled(player:get_player_name()) - if creative then - player:hud_set_flags({minimap=true, minimap_radar = true}) - else - if has_item_in_hotbar(player, "mcl_maps:filled_map") then - player:hud_set_flags({minimap = true, minimap_radar = false}) - else - player:hud_set_flags({minimap = false, minimap_radar = false}) - end - end -end - --- Remind player how to use the minimap correctly -local function use_minimap(itemstack, player, pointed_thing) - if player and player:is_player() then - update_minimap(player) - minetest.chat_send_player(player:get_player_name(), S("Use the minimap key to show the map.")) - end -end - --- Enables minimap if carried in hotbar. --- If this item is NOT in the hotbar, the minimap is unavailable --- Note: This is not at all like Minecraft right now. Minetest's minimap is pretty overpowered, it --- has a very greatly zoomed-out version and even a radar mode -minetest.register_craftitem("mcl_maps:filled_map", { +local filled_def = { description = S("Map"), - _tt_help = S("Enables minimap"), - _doc_items_longdesc = S("Maps show your surroundings as you explore the world."), - _doc_items_usagehelp = S("Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).").."\n".. - S("In Creative Mode, you don't need this item; the minimap is always available."), - groups = { tool = 1 }, + _tt_help = S("Shows a map image."), + _doc_items_longdesc = S("When created, the map saves the nearby area as an image that can be viewed any time by holding the map."), + _doc_items_usagehelp = S("Hold the map in your hand. This will display a map on your screen."), inventory_image = "mcl_maps_map_filled.png^(mcl_maps_map_filled_markings.png^[colorize:#000000)", - stack_max = 1, + stack_max = 64, + groups = { not_in_creative_inventory = 1, filled_map = 1, tool = 1 }, +} - on_use = use_minimap, - on_secondary_use = use_minimap, -}) +minetest.register_craftitem("mcl_maps:filled_map", filled_def) + +local filled_wield_def = table.copy(filled_def) +filled_wield_def.use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false +filled_wield_def.visual_scale = 1 +filled_wield_def.wield_scale = { x = 1, y = 1, z = 1 } +filled_wield_def.paramtype = "light" +filled_wield_def.drawtype = "mesh" +filled_wield_def.node_placement_prediction = "" +filled_wield_def.on_place = mcl_util.call_on_rightclick +filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map" + +local mcl_skins_enabled = minetest.global_exists("mcl_skins") + +if mcl_skins_enabled then + -- Generate a node for every skin + local list = mcl_skins.get_skin_list() + for _, skin in pairs(list) do + if skin.slim_arms then + local female = table.copy(filled_wield_def) + female._mcl_hand_id = skin.id + female.mesh = "mcl_meshhand_female.b3d" + female.tiles = { skin.texture } + minetest.register_node("mcl_maps:filled_map_" .. skin.id, female) + else + local male = table.copy(filled_wield_def) + male._mcl_hand_id = skin.id + male.mesh = "mcl_meshhand.b3d" + male.tiles = { skin.texture } + minetest.register_node("mcl_maps:filled_map_" .. skin.id, male) + end + end +else + filled_wield_def._mcl_hand_id = "hand" + filled_wield_def.mesh = "mcl_meshhand.b3d" + filled_wield_def.tiles = { "character.png" } + minetest.register_node("mcl_maps:filled_map_hand", filled_wield_def) +end + +local old_add_item = minetest.add_item +function minetest.add_item(pos, stack) + if not pos then + minetest.log("warning", "Trying to add item with missing pos: " .. tostring(stack)) + return + end + stack = ItemStack(stack) + if get_item_group(stack:get_name(), "filled_map") > 0 then + stack:set_name("mcl_maps:filled_map") + end + return old_add_item(pos, stack) +end + +tt.register_priority_snippet(function(itemstring, _, itemstack) + if itemstack and get_item_group(itemstring, "filled_map") > 0 then + local id = itemstack:get_meta():get_string("mcl_maps:id") + if id ~= "" then + return "#" .. id, mcl_colors.GRAY + end + end +end) minetest.register_craft({ - output = "mcl_maps:filled_map", + output = "mcl_maps:empty_map", recipe = { { "mcl_core:paper", "mcl_core:paper", "mcl_core:paper" }, { "mcl_core:paper", "group:compass", "mcl_core:paper" }, @@ -89,20 +307,104 @@ minetest.register_craft({ } }) +minetest.register_craft({ + type = "shapeless", + output = "mcl_maps:filled_map 2", + recipe = { "group:filled_map", "mcl_maps:empty_map" }, +}) + +local function on_craft(itemstack, player, old_craft_grid, craft_inv) + if itemstack:get_name() == "mcl_maps:filled_map" then + for _, stack in pairs(old_craft_grid) do + if get_item_group(stack:get_name(), "filled_map") > 0 then + itemstack:get_meta():from_table(stack:get_meta():to_table()) + return itemstack + end + end + end +end + +minetest.register_on_craft(on_craft) +minetest.register_craft_predict(on_craft) + +local maps = {} +local huds = {} + minetest.register_on_joinplayer(function(player) - update_minimap(player) + local map_def = { + hud_elem_type = "image", + text = "blank.png", + position = { x = 0.75, y = 0.8 }, + alignment = { x = 0, y = -1 }, + offset = { x = 0, y = 0 }, + scale = { x = 2, y = 2 }, + } + local marker_def = table.copy(map_def) + marker_def.alignment = { x = 0, y = 0 } + huds[player] = { + map = player:hud_add(map_def), + marker = player:hud_add(marker_def), + } end) -local updatetimer = 0 -if not minetest.is_creative_enabled("") then - minetest.register_globalstep(function(dtime) - updatetimer = updatetimer + dtime - if updatetimer > 0.1 then - local players = minetest.get_connected_players() - for i=1, #players do - update_minimap(players[i]) +minetest.register_on_leaveplayer(function(player) + maps[player] = nil + huds[player] = nil +end) + +minetest.register_globalstep(function(dtime) + for _, player in pairs(get_connected_players()) do + local wield = player:get_wielded_item() + local texture = mcl_maps.load_map_item(wield) + local hud = huds[player] + if texture then + local wield_def = wield:get_definition() + local hand_def = player:get_inventory():get_stack("hand", 1):get_definition() + + if hand_def and wield_def and hand_def._mcl_hand_id ~= wield_def._mcl_hand_id then + wield:set_name("mcl_maps:filled_map_" .. hand_def._mcl_hand_id) + player:set_wielded_item(wield) end - updatetimer = updatetimer - dtime + + if texture ~= maps[player] then + player:hud_change(hud.map, "text", "[combine:140x140:0,0=mcl_maps_map_background.png:6,6=" .. texture) + maps[player] = texture + end + + local pos = vector.round(player:get_pos()) + local meta = wield:get_meta() + local minp = string_to_pos(meta:get_string("mcl_maps:minp")) + local maxp = string_to_pos(meta:get_string("mcl_maps:maxp")) + + local marker = "mcl_maps_player_arrow.png" + + if pos.x < minp.x then + marker = "mcl_maps_player_dot.png" + pos.x = minp.x + elseif pos.x > maxp.x then + marker = "mcl_maps_player_dot.png" + pos.x = maxp.x + end + + if pos.z < minp.z then + marker = "mcl_maps_player_dot.png" + pos.z = minp.z + elseif pos.z > maxp.z then + marker = "mcl_maps_player_dot.png" + pos.z = maxp.z + end + + if marker == "mcl_maps_player_arrow.png" then + local yaw = (math.floor(player:get_look_horizontal() * 180 / math.pi / 90 + 0.5) % 4) * 90 + marker = marker .. "^[transformR" .. yaw + end + + player:hud_change(hud.marker, "text", marker) + player:hud_change(hud.marker, "offset", { x = (6 - 140 / 2 + pos.x - minp.x) * 2, y = (6 - 140 + maxp.z - pos.z) * 2 }) + elseif maps[player] then + player:hud_change(hud.map, "text", "blank.png") + player:hud_change(hud.marker, "text", "blank.png") + maps[player] = nil end - end) -end + end +end) diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.de.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.de.tr index 6d1836b48..d7762e512 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.de.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.de.tr @@ -1,10 +1,8 @@ # textdomain: mcl_maps Empty Map=Leere Karte Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Leere Karten sind als Karten nicht nützlich, aber sie können gestapelt werden und zu benutzbaren Karten umgewandelt werden. -Rightclick to start using the map (which can't be stacked anymore).=Rechtsklick, um zu beginnen, die Karte zu benutzen. Sie kann dann nicht mehr gestapelt werden. +Rightclick to create a filled map (which can't be stacked anymore).=Rechtsklick, um die Karte zu füllen. Sie kann dann nicht mehr gestapelt werden. Map=Karte -Maps show your surroundings as you explore the world.=Karten zeigen Ihre Umgebung, während Sie die Welt erkunden. -Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Halten Sie die Karte in einen beliebigen Platz in der Schnellleiste. Damit können Sie jetzt die Übersichtskarte aktivieren, indem Sie die Taste zum Umschalten der Karte drücken (siehe Tastenbelegung). -In Creative Mode, you don't need this item; the minimap is always available.=Im Kreativmodus brauchen Sie diesen Gegenstand nicht; die Übersichtskarte ist immer verfügbar. -Enables minimap=Aktiviert Übersichtskarte -Use the minimap key to show the map.=Taste „Karte an/aus“ benutzen, um die Karte zu betrachten. +Shows a map image.=Zeigt ein Kartenbild. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Beim Erstellen speichert die Karte die Gegend in der Nähe als ein Bild, dass jederzeit durch halten der Karte angesehen werden kann. +Hold the map in your hand. This will display a map on your screen.=Halten Sie die Karte in Ihrer Hand. Eine Karte wird auf Ihrem Bildschirm angezeigt werden. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.es.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.es.tr index 513eab136..cec96b17b 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.es.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.es.tr @@ -3,6 +3,3 @@ Empty Map=Mapa vacio Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Los mapas vacíos no son útiles como mapas, pero se pueden apilar y convertir en mapas que se pueden usar. Rightclick to start using the map (which can't be stacked anymore).=Haga clic derecho para comenzar a usar el mapa (que ya no se puede apilar). Map=Mapa -Maps show your surroundings as you explore the world.=Los mapas muestran tu entorno mientras exploras el mundo. -Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Mantenga el mapa en cualquiera de las ranuras de la barra de acceso directo. Esto le permite acceder al minimapa presionando la tecla del minimapa (consulte la configuración de los controles). -In Creative Mode, you don't need this item; the minimap is always available.=En el modo creativo, no necesita este elemento; El minimapa siempre está disponible. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr index 6feb253ae..1808e839d 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.fr.tr @@ -1,10 +1,8 @@ # textdomain: mcl_maps Empty Map=Carte Vierge Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Les cartes vierges ne sont pas utiles en tant que cartes, mais elles peuvent être empilées et transformées en cartes utilisables. -Rightclick to start using the map (which can't be stacked anymore).=Clic droit pour commencer à utiliser la carte (qui ne peut plus être empilée). +Rightclick to create a filled map (which can't be stacked anymore).=Clic droit pour créer une carte remplie (qui ne peut plus être empilée). Map=Carte -Maps show your surroundings as you explore the world.=Les cartes montrent votre environnement lorsque vous explorez le monde. -Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Tenez la carte dans l'un des emplacements de la barre de raccourci. Cela vous permet d'accéder à la mini-carte en appuyant sur la touche de la mini-carte (voir les paramètres des commandes). -In Creative Mode, you don't need this item; the minimap is always available.=En mode créatif, vous n'avez pas besoin de cet élément; la minicarte est toujours disponible. -Enables minimap=Active la minicarte -Use the minimap key to show the map.=Utilisez la touche mini-carte pour afficher la carte. +Shows a map image.=Affiche une carte. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Lors de sa création, la carte sauvegarde le terrain proche sous forme d'image qui peut être consultée n'importe quand en tenant la carte dans la main. +Hold the map in your hand. This will display a map on your screen.=Tenez la carte dans votre main. Cela affichera la carte à l'écran. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr new file mode 100644 index 000000000..a521f3eba --- /dev/null +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.ja.tr @@ -0,0 +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 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_maps/locale/mcl_maps.pl.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.pl.tr new file mode 100644 index 000000000..de6ff84d6 --- /dev/null +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_maps +Empty Map=Pusta mapa +Empty maps are not useful as maps, but they can be stacked and turned to maps which can be used.=Puste mapy nie są tak użyteczne jak mapy ale mogą być grupowane i zamienione w mapy które już są pożyteczne. +Rightclick to create a filled map (which can't be stacked anymore).=Kliknij prawy przycisk aby stworzyć wypełnioną mapę (nie będzie już jej można grupować). +Map=Mapa +Shows a map image.=Pokazuje obraz mapy. +When created, the map saves the nearby area as an image that can be viewed any time by holding the map.=Gdy są utworzone mapy zapisują obszar okolicy jako obrazek, który może być oglądany przez trzymanie mapy w rękach. +Hold the map in your hand. This will display a map on your screen.=Weź mapę do ręki. To pokaże mapę na twoim ekranie. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr index 70243a166..3bb7d6a19 100644 --- a/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.ru.tr @@ -1,10 +1,5 @@ # 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).=Кликните правой, чтобы начать использовать карту (её больше нельзя будет уложить в стопку). +Rightclick to start using the map (which can't be stacked anymore).=Нажмите правую кнопку мыши, чтобы начать использовать карту (её больше нельзя будет уложить в стопку). Map=Карта -Maps show your surroundings as you explore the world.=Карты показывают ваше окружение, когда вы изучаете мир. -Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=Поместите карту в один из отсеков панели быстрого доступа. Это позволит вам вызывать миникарту нажатием клавиши [Миникарта] (см. настройки управления). -In Creative Mode, you don't need this item; the minimap is always available.=Этот предмет не нужен в творческом режиме; там миникарта всегда доступна и так. -Enables minimap=Включает миникарту -Use the minimap key to show the map.=Используйте клавишу [Миникарта] для отображения карты. diff --git a/mods/ITEMS/mcl_maps/locale/mcl_maps.zh_TW.tr b/mods/ITEMS/mcl_maps/locale/mcl_maps.zh_TW.tr new file mode 100644 index 000000000..62206306c --- /dev/null +++ b/mods/ITEMS/mcl_maps/locale/mcl_maps.zh_TW.tr @@ -0,0 +1,10 @@ +# 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).=右鍵單擊以開始使用地圖(該地圖無法再堆疊)。 +Map=地圖 +Maps show your surroundings as you explore the world.=當您探索世界時,地圖會顯示您的周圍環境。 +Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).=在任何一個熱鍵槽中放置地圖。這允許你通過按小地圖鍵來訪問小地圖(見控制設置)。 +In Creative Mode, you don't need this item; the minimap is always available.=在創造模式下,您不需要此項目; 小地圖始終可用。 +Enables minimap=啓用小地圖 +Use the minimap key to show the map.=使用小地圖鍵來顯示小地圖。 diff --git a/mods/ITEMS/mcl_maps/locale/template.txt b/mods/ITEMS/mcl_maps/locale/template.txt index 061ed45e0..27298d2ec 100644 --- a/mods/ITEMS/mcl_maps/locale/template.txt +++ b/mods/ITEMS/mcl_maps/locale/template.txt @@ -1,10 +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).= +Rightclick to create a filled map (which can't be stacked anymore).= Map= -Maps show your surroundings as you explore the world.= -Hold the map in any of the hotbar slots. This allows you to access the minimap by pressing the minimap key (see controls settings).= -In Creative Mode, you don't need this item; the minimap is always available.= -Enables minimap= -Use the minimap key to show the 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_maps/mod.conf b/mods/ITEMS/mcl_maps/mod.conf index 44c4becf0..e1f068963 100644 --- a/mods/ITEMS/mcl_maps/mod.conf +++ b/mods/ITEMS/mcl_maps/mod.conf @@ -1 +1,2 @@ name = mcl_maps +depends = mcl_core, mcl_flowers, tga_encoder, tt, mcl_colors, mcl_skins, mcl_util diff --git a/mods/ITEMS/mcl_maps/palettes_foliage.json b/mods/ITEMS/mcl_maps/palettes_foliage.json new file mode 100644 index 000000000..d5eedf9ab --- /dev/null +++ b/mods/ITEMS/mcl_maps/palettes_foliage.json @@ -0,0 +1 @@ +{"mcl_core_palette_foliage.png": [[86, 164, 117], [109, 196, 117], [118, 177, 120], [159, 193, 114], [159, 193, 114], [74, 107, 58], [94, 190, 107], [94, 190, 107], [222, 188, 101], [90, 197, 87], [35, 175, 105], [92, 182, 119], [93, 181, 76], [93, 181, 76], [82, 153, 81], [91, 177, 85], [86, 164, 117], [94, 190, 107]]} diff --git a/mods/ITEMS/mcl_maps/palettes_grass.json b/mods/ITEMS/mcl_maps/palettes_grass.json new file mode 100644 index 000000000..2018dea18 --- /dev/null +++ b/mods/ITEMS/mcl_maps/palettes_grass.json @@ -0,0 +1 @@ +{"mcl_core_palette_grass.png": [[109, 196, 117], [159, 193, 114], [118, 177, 120], [118, 177, 120], [107, 186, 107], [118, 177, 120], [92, 182, 119], [92, 182, 119], [92, 182, 119], [92, 182, 119], [118, 177, 120], [109, 196, 117], [35, 175, 105], [94, 190, 107], [94, 190, 107], [94, 190, 107], [94, 190, 107], [159, 193, 114], [76, 176, 84], [164, 150, 110], [164, 150, 110], [164, 150, 110], [164, 150, 110], [159, 193, 114], [93, 181, 76], [93, 181, 76], [93, 181, 76], [93, 181, 76], [76, 118, 60], [94, 190, 107]]} diff --git a/mods/ITEMS/mcl_maps/palettes_water.json b/mods/ITEMS/mcl_maps/palettes_water.json new file mode 100644 index 000000000..101e293b9 --- /dev/null +++ b/mods/ITEMS/mcl_maps/palettes_water.json @@ -0,0 +1 @@ +{"mcl_core_palette_water.png": [[63, 118, 228], [82, 121, 179], [66, 149, 235], [65, 174, 233], [62, 104, 221], [60, 93, 215], [46, 100, 218], [61, 120, 181]]} diff --git a/mods/ITEMS/mcl_mobitems/depends.txt b/mods/ITEMS/mcl_mobitems/depends.txt deleted file mode 100644 index 73d023f65..000000000 --- a/mods/ITEMS/mcl_mobitems/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -mcl_hunger diff --git a/mods/ITEMS/mcl_mobitems/init.lua b/mods/ITEMS/mcl_mobitems/init.lua index 4e7eabc9e..2dcfc6372 100644 --- a/mods/ITEMS/mcl_mobitems/init.lua +++ b/mods/ITEMS/mcl_mobitems/init.lua @@ -1,446 +1,551 @@ -local S = minetest.get_translator("mcl_mobitems") - -minetest.register_craftitem("mcl_mobitems:rotten_flesh", { - description = S("Rotten Flesh"), - _tt_help = minetest.colorize("#FFFF00", S("80% chance of food poisoning")), - _doc_items_longdesc = S("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."), - inventory_image = "mcl_mobitems_rotten_flesh.png", - wield_image = "mcl_mobitems_rotten_flesh.png", - on_place = minetest.item_eat(4), - on_secondary_use = minetest.item_eat(4), - groups = { food = 2, eatable = 4 }, - _mcl_saturation = 0.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:mutton", { - description = S("Raw Mutton"), - _doc_items_longdesc = S("Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value."), - inventory_image = "mcl_mobitems_mutton_raw.png", - 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 }, - _mcl_saturation = 1.2, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:cooked_mutton", { - description = S("Cooked Mutton"), - _doc_items_longdesc = S("Cooked mutton is the cooked flesh from a sheep and is used as food."), - inventory_image = "mcl_mobitems_mutton_cooked.png", - wield_image = "mcl_mobitems_mutton_cooked.png", - on_place = minetest.item_eat(6), - on_secondary_use = minetest.item_eat(6), - groups = { food = 2, eatable = 6 }, - _mcl_saturation = 9.6, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:beef", { - description = S("Raw Beef"), - _doc_items_longdesc = S("Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value."), - inventory_image = "mcl_mobitems_beef_raw.png", - 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 }, - _mcl_saturation = 1.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:cooked_beef", { - description = S("Steak"), - _doc_items_longdesc = S("Steak is cooked beef from cows and can be eaten."), - inventory_image = "mcl_mobitems_beef_cooked.png", - wield_image = "mcl_mobitems_beef_cooked.png", - on_place = minetest.item_eat(8), - on_secondary_use = minetest.item_eat(8), - groups = { food = 2, eatable = 8 }, - _mcl_saturation = 12.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:chicken", { - description = S("Raw Chicken"), - _tt_help = minetest.colorize("#FFFF00", S("30% chance of food poisoning")), - _doc_items_longdesc = S("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."), - inventory_image = "mcl_mobitems_chicken_raw.png", - 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 }, - _mcl_saturation = 1.2, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:cooked_chicken", { - description = S("Cooked Chicken"), - _doc_items_longdesc = S("A cooked chicken is a healthy food item which can be eaten."), - inventory_image = "mcl_mobitems_chicken_cooked.png", - wield_image = "mcl_mobitems_chicken_cooked.png", - on_place = minetest.item_eat(6), - on_secondary_use = minetest.item_eat(6), - groups = { food = 2, eatable = 6 }, - _mcl_saturation = 7.2, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:porkchop", { - description = S("Raw Porkchop"), - _doc_items_longdesc = S("A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value."), - inventory_image = "mcl_mobitems_porkchop_raw.png", - 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 }, - _mcl_saturation = 1.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:cooked_porkchop", { - description = S("Cooked Porkchop"), - _doc_items_longdesc = S("Cooked porkchop is the cooked flesh of a pig and is used as food."), - inventory_image = "mcl_mobitems_porkchop_cooked.png", - wield_image = "mcl_mobitems_porkchop_cooked.png", - on_place = minetest.item_eat(8), - on_secondary_use = minetest.item_eat(8), - groups = { food = 2, eatable = 8 }, - _mcl_saturation = 12.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:rabbit", { - description = S("Raw Rabbit"), - _doc_items_longdesc = S("Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value."), - inventory_image = "mcl_mobitems_rabbit_raw.png", - 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 }, - _mcl_saturation = 1.8, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:cooked_rabbit", { - description = S("Cooked Rabbit"), - _doc_items_longdesc = S("This is a food item which can be eaten."), - inventory_image = "mcl_mobitems_rabbit_cooked.png", - wield_image = "mcl_mobitems_rabbit_cooked.png", - on_place = minetest.item_eat(5), - on_secondary_use = minetest.item_eat(5), - groups = { food = 2, eatable = 5 }, - _mcl_saturation = 6.0, - stack_max = 64, -}) - --- Reset food poisoning and status effects -local drink_milk = function(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) - end - mcl_potions._reset_player_effects(player) - return bucket -end - -minetest.register_craftitem("mcl_mobitems:milk_bucket", { - description = S("Milk"), - _tt_help = minetest.colorize("#00FF00", S("Removes all status effects")), - _doc_items_longdesc = S("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."), - _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, - stack_max = 1, - groups = { food = 3, can_eat_when_full = 1 }, -}) - -minetest.register_craftitem("mcl_mobitems:spider_eye", { - description = S("Spider Eye"), - _tt_help = minetest.colorize("#FFFF00", S("Poisonous")), - _doc_items_longdesc = S("Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly."), - inventory_image = "mcl_mobitems_spider_eye.png", - wield_image = "mcl_mobitems_spider_eye.png", - on_place = minetest.item_eat(2), - on_secondary_use = minetest.item_eat(2), - groups = { food = 2, eatable = 2, brewitem = 1 }, - _mcl_saturation = 3.2, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:bone", { - description = S("Bone"), - _doc_items_longdesc = S("Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient."), - _doc_items_usagehelp = S("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."), - inventory_image = "mcl_mobitems_bone.png", - stack_max = 64, - groups = { craftitem=1 }, -}) - -minetest.register_craftitem("mcl_mobitems:string",{ - description = S("String"), - _doc_items_longdesc = S("Strings are used in crafting."), - inventory_image = "mcl_mobitems_string.png", - stack_max = 64, - groups = { craftitem = 1 }, -}) - -minetest.register_craftitem("mcl_mobitems:blaze_rod", { - description = S("Blaze Rod"), - _doc_items_longdesc = S("This is a crafting component dropped from dead blazes."), - wield_image = "mcl_mobitems_blaze_rod.png", - inventory_image = "mcl_mobitems_blaze_rod.png", - groups = { craftitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:blaze_powder", { - description = S("Blaze Powder"), - _doc_items_longdesc = S("This item is mainly used for crafting."), - wield_image = "mcl_mobitems_blaze_powder.png", - inventory_image = "mcl_mobitems_blaze_powder.png", - groups = { craftitem = 1, brewitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:magma_cream", { - description = S("Magma Cream"), - _doc_items_longdesc = S("Magma cream is a crafting component."), - wield_image = "mcl_mobitems_magma_cream.png", - inventory_image = "mcl_mobitems_magma_cream.png", - groups = { craftitem = 1, brewitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:ghast_tear", { - description = S("Ghast Tear"), - _doc_items_longdesc = S("Place this item in an item frame as decoration."), - wield_image = "mcl_mobitems_ghast_tear.png", - inventory_image = "mcl_mobitems_ghast_tear.png", - groups = { brewitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:nether_star", { - description = S("Nether Star"), - _doc_items_longdesc = S("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."), - wield_image = "mcl_mobitems_nether_star.png", - inventory_image = "mcl_mobitems_nether_star.png", - -- TODO: Reveal item when it's useful - groups = { craftitem = 1, not_in_creative_inventory = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:leather", { - description = S("Leather"), - _doc_items_longdesc = S("Leather is a versatile crafting component."), - wield_image = "mcl_mobitems_leather.png", - inventory_image = "mcl_mobitems_leather.png", - groups = { craftitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:feather", { - description = S("Feather"), - _doc_items_longdesc = S("Feathers are used in crafting and are dropped from chickens."), - wield_image = "mcl_mobitems_feather.png", - inventory_image = "mcl_mobitems_feather.png", - groups = { craftitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:rabbit_hide", { - description = S("Rabbit Hide"), - _doc_items_longdesc = S("Rabbit hide is used to create leather."), - wield_image = "mcl_mobitems_rabbit_hide.png", - inventory_image = "mcl_mobitems_rabbit_hide.png", - groups = { craftitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:rabbit_foot", { - description = S("Rabbit's Foot"), - _doc_items_longdesc = S("Must be your lucky day! Place this item in an item frame for decoration."), - wield_image = "mcl_mobitems_rabbit_foot.png", - inventory_image = "mcl_mobitems_rabbit_foot.png", - groups = { brewitem = 1 }, - stack_max = 64, -}) - -minetest.register_craftitem("mcl_mobitems:saddle", { - description = S("Saddle"), - _tt_help = S("Can be placed on animals to ride them"), - _doc_items_longdesc = S("Saddles can be put on some animals in order to mount them."), - _doc_items_usagehelp = S("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."), - wield_image = "mcl_mobitems_saddle.png", - inventory_image = "mcl_mobitems_saddle.png", - groups = { transport = 1 }, - stack_max = 1, -}) - -minetest.register_craftitem("mcl_mobitems:rabbit_stew", { - description = S("Rabbit Stew"), - _doc_items_longdesc = S("Rabbit stew is a very nutricious food item."), - wield_image = "mcl_mobitems_rabbit_stew.png", - inventory_image = "mcl_mobitems_rabbit_stew.png", - 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 }, - _mcl_saturation = 12.0, -}) - -minetest.register_craftitem("mcl_mobitems:shulker_shell", { - description = S("Shulker Shell"), - _doc_items_longdesc = S("Shulker shells are used in crafting. They are dropped from dead shulkers."), - inventory_image = "mcl_mobitems_shulker_shell.png", - groups = { craftitem = 1 }, -}) - -minetest.register_craftitem("mcl_mobitems:slimeball", { - description = S("Slimeball"), - _doc_items_longdesc = S("Slimeballs are used in crafting. They are dropped from slimes."), - inventory_image = "mcl_mobitems_slimeball.png", - groups = { craftitem = 1 }, -}) - -minetest.register_craftitem("mcl_mobitems:gunpowder", { - description = S("Gunpowder"), - _doc_items_longdesc = doc.sub.items.temp.craftitem, - inventory_image = "default_gunpowder.png", - stack_max = 64, - groups = { craftitem=1, brewitem = 1 }, -}) - -minetest.register_tool("mcl_mobitems:carrot_on_a_stick", { - description = S("Carrot on a Stick"), - _tt_help = S("Lets you ride a saddled pig"), - _doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."), - _doc_items_usagehelp = S("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."), - wield_image = "mcl_mobitems_carrot_on_a_stick.png", - inventory_image = "mcl_mobitems_carrot_on_a_stick.png", - groups = { transport = 1 }, -}) - - ------------ --- Crafting ------------ - -minetest.register_craft({ - output = "mcl_mobitems:leather", - recipe = { - { "mcl_mobitems:rabbit_hide", "mcl_mobitems:rabbit_hide" }, - { "mcl_mobitems:rabbit_hide", "mcl_mobitems:rabbit_hide" }, - } -}) - -minetest.register_craft({ - output = "mcl_mobitems:blaze_powder 2", - recipe = {{"mcl_mobitems:blaze_rod"}}, -}) - -minetest.register_craft({ - output = "mcl_mobitems:rabbit_stew", - recipe = { - { "", "mcl_mobitems:cooked_rabbit", "", }, - { "group:mushroom", "mcl_farming:potato_item_baked", "mcl_farming:carrot_item", }, - { "", "mcl_core:bowl", "", }, - }, -}) - -minetest.register_craft({ - output = "mcl_mobitems:rabbit_stew", - recipe = { - { "", "mcl_mobitems:cooked_rabbit", "", }, - { "mcl_farming:carrot_item", "mcl_farming:potato_item_baked", "group:mushroom", }, - { "", "mcl_core:bowl", "", }, - }, -}) - -minetest.register_craft({ - output = "mcl_mobitems:carrot_on_a_stick", - recipe = { - { "mcl_fishing:fishing_rod", "", }, - { "", "mcl_farming:carrot_item" }, - }, -}) - -minetest.register_craft({ - output = "mcl_mobitems:carrot_on_a_stick", - recipe = { - { "", "mcl_fishing:fishing_rod", }, - { "mcl_farming:carrot_item", "" }, - }, -}) - -minetest.register_craft({ - type = "shapeless", - output = "mcl_mobitems:magma_cream", - recipe = {"mcl_mobitems:blaze_powder", "mcl_mobitems:slimeball"}, -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_mobitems:cooked_mutton", - recipe = "mcl_mobitems:mutton", - cooktime = 10, -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_mobitems:cooked_rabbit", - recipe = "mcl_mobitems:rabbit", - cooktime = 10, -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_mobitems:cooked_chicken", - recipe = "mcl_mobitems:chicken", - cooktime = 10, -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_mobitems:cooked_beef", - recipe = "mcl_mobitems:beef", - cooktime = 10, -}) - -minetest.register_craft({ - type = "cooking", - output = "mcl_mobitems:cooked_porkchop", - recipe = "mcl_mobitems:porkchop", - cooktime = 10, -}) - -minetest.register_craft({ - type = "fuel", - recipe = "mcl_mobitems:blaze_rod", - burntime = 120, -}) - -minetest.register_craft({ - output = 'mcl_mobitems:slimeball 9', - recipe = {{"mcl_core:slimeblock"}}, -}) - -minetest.register_craft({ - output = "mcl_core:slimeblock", - recipe = {{"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}, - {"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}, - {"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}}, -}) - -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) - end - -end ) +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_craftitem("mcl_mobitems:rotten_flesh", { + description = S("Rotten Flesh"), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("80% chance of food poisoning")), + _doc_items_longdesc = S("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."), + inventory_image = "mcl_mobitems_rotten_flesh.png", + wield_image = "mcl_mobitems_rotten_flesh.png", + on_place = minetest.item_eat(4), + on_secondary_use = minetest.item_eat(4), + groups = { food = 2, eatable = 4 }, + _mcl_saturation = 0.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:mutton", { + description = S("Raw Mutton"), + _doc_items_longdesc = S("Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value."), + inventory_image = "mcl_mobitems_mutton_raw.png", + 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 }, + _mcl_saturation = 1.2, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:cooked_mutton", { + description = S("Cooked Mutton"), + _doc_items_longdesc = S("Cooked mutton is the cooked flesh from a sheep and is used as food."), + inventory_image = "mcl_mobitems_mutton_cooked.png", + wield_image = "mcl_mobitems_mutton_cooked.png", + on_place = minetest.item_eat(6), + on_secondary_use = minetest.item_eat(6), + groups = { food = 2, eatable = 6 }, + _mcl_saturation = 9.6, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:beef", { + description = S("Raw Beef"), + _doc_items_longdesc = S("Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value."), + inventory_image = "mcl_mobitems_beef_raw.png", + 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 }, + _mcl_saturation = 1.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:cooked_beef", { + description = S("Steak"), + _doc_items_longdesc = S("Steak is cooked beef from cows and can be eaten."), + inventory_image = "mcl_mobitems_beef_cooked.png", + wield_image = "mcl_mobitems_beef_cooked.png", + on_place = minetest.item_eat(8), + on_secondary_use = minetest.item_eat(8), + groups = { food = 2, eatable = 8 }, + _mcl_saturation = 12.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:chicken", { + description = S("Raw Chicken"), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("30% chance of food poisoning")), + _doc_items_longdesc = S("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."), + inventory_image = "mcl_mobitems_chicken_raw.png", + 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 }, + _mcl_saturation = 1.2, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:cooked_chicken", { + description = S("Cooked Chicken"), + _doc_items_longdesc = S("A cooked chicken is a healthy food item which can be eaten."), + inventory_image = "mcl_mobitems_chicken_cooked.png", + wield_image = "mcl_mobitems_chicken_cooked.png", + on_place = minetest.item_eat(6), + on_secondary_use = minetest.item_eat(6), + groups = { food = 2, eatable = 6 }, + _mcl_saturation = 7.2, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:porkchop", { + description = S("Raw Porkchop"), + _doc_items_longdesc = S("A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value."), + inventory_image = "mcl_mobitems_porkchop_raw.png", + 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 }, + _mcl_saturation = 1.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:cooked_porkchop", { + description = S("Cooked Porkchop"), + _doc_items_longdesc = S("Cooked porkchop is the cooked flesh of a pig and is used as food."), + inventory_image = "mcl_mobitems_porkchop_cooked.png", + wield_image = "mcl_mobitems_porkchop_cooked.png", + on_place = minetest.item_eat(8), + on_secondary_use = minetest.item_eat(8), + groups = { food = 2, eatable = 8 }, + _mcl_saturation = 12.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:rabbit", { + description = S("Raw Rabbit"), + _doc_items_longdesc = S("Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value."), + inventory_image = "mcl_mobitems_rabbit_raw.png", + 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 }, + _mcl_saturation = 1.8, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:cooked_rabbit", { + description = S("Cooked Rabbit"), + _doc_items_longdesc = S("This is a food item which can be eaten."), + inventory_image = "mcl_mobitems_rabbit_cooked.png", + wield_image = "mcl_mobitems_rabbit_cooked.png", + on_place = minetest.item_eat(5), + on_secondary_use = minetest.item_eat(5), + groups = { food = 2, eatable = 5 }, + _mcl_saturation = 6.0, + 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) + end + mcl_potions._reset_player_effects(player) + return bucket +end + +minetest.register_craftitem("mcl_mobitems:milk_bucket", { + description = S("Milk"), + _tt_help = minetest.colorize(mcl_colors.GREEN, S("Removes all status effects")), + _doc_items_longdesc = S("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."), + _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, + stack_max = 1, + groups = { food = 3, can_eat_when_full = 1 }, +}) + +minetest.register_craftitem("mcl_mobitems:spider_eye", { + description = S("Spider Eye"), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Poisonous")), + _doc_items_longdesc = S("Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly."), + inventory_image = "mcl_mobitems_spider_eye.png", + wield_image = "mcl_mobitems_spider_eye.png", + on_place = minetest.item_eat(2), + on_secondary_use = minetest.item_eat(2), + groups = { food = 2, eatable = 2, brewitem = 1 }, + _mcl_saturation = 3.2, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:bone", { + description = S("Bone"), + _doc_items_longdesc = S("Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient."), + _doc_items_usagehelp = S("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."), + inventory_image = "mcl_mobitems_bone.png", + stack_max = 64, + groups = { craftitem=1 }, + _mcl_toollike_wield = true, +}) + +minetest.register_craftitem("mcl_mobitems:ink_sac", { + description = S("Squid Ink Sac"), + _doc_items_longdesc = S("This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye."), + inventory_image = "mcl_mobitems_ink_sac.png", + stack_max = 64, + groups = { craftitem = 1 }, +}) + +minetest.register_craftitem("mcl_mobitems:string",{ + description = S("String"), + _doc_items_longdesc = S("Strings are used in crafting."), + inventory_image = "mcl_mobitems_string.png", + stack_max = 64, + groups = { craftitem = 1 }, +}) + +minetest.register_craftitem("mcl_mobitems:blaze_rod", { + description = S("Blaze Rod"), + _doc_items_longdesc = S("This is a crafting component dropped from dead blazes."), + wield_image = "mcl_mobitems_blaze_rod.png", + inventory_image = "mcl_mobitems_blaze_rod.png", + groups = { craftitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:blaze_powder", { + description = S("Blaze Powder"), + _doc_items_longdesc = S("This item is mainly used for crafting."), + wield_image = "mcl_mobitems_blaze_powder.png", + inventory_image = "mcl_mobitems_blaze_powder.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:magma_cream", { + description = S("Magma Cream"), + _doc_items_longdesc = S("Magma cream is a crafting component."), + wield_image = "mcl_mobitems_magma_cream.png", + inventory_image = "mcl_mobitems_magma_cream.png", + groups = { craftitem = 1, brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:ghast_tear", { + description = S("Ghast Tear"), + _doc_items_longdesc = S("Place this item in an item frame as decoration."), + wield_image = "mcl_mobitems_ghast_tear.png", + inventory_image = "mcl_mobitems_ghast_tear.png", + groups = { brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:nether_star", { + description = S("Nether Star"), + _doc_items_longdesc = S("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."), + wield_image = "mcl_mobitems_nether_star.png", + inventory_image = "mcl_mobitems_nether_star.png", + -- TODO: Reveal item when it's useful + groups = { craftitem = 1, not_in_creative_inventory = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:leather", { + description = S("Leather"), + _doc_items_longdesc = S("Leather is a versatile crafting component."), + wield_image = "mcl_mobitems_leather.png", + inventory_image = "mcl_mobitems_leather.png", + groups = { craftitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:feather", { + description = S("Feather"), + _doc_items_longdesc = S("Feathers are used in crafting and are dropped from chickens."), + wield_image = "mcl_mobitems_feather.png", + inventory_image = "mcl_mobitems_feather.png", + groups = { craftitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:rabbit_hide", { + description = S("Rabbit Hide"), + _doc_items_longdesc = S("Rabbit hide is used to create leather."), + wield_image = "mcl_mobitems_rabbit_hide.png", + inventory_image = "mcl_mobitems_rabbit_hide.png", + groups = { craftitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:rabbit_foot", { + description = S("Rabbit's Foot"), + _doc_items_longdesc = S("Must be your lucky day! Place this item in an item frame for decoration."), + wield_image = "mcl_mobitems_rabbit_foot.png", + inventory_image = "mcl_mobitems_rabbit_foot.png", + groups = { brewitem = 1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:saddle", { + description = S("Saddle"), + _tt_help = S("Can be placed on animals to ride them"), + _doc_items_longdesc = S("Saddles can be put on some animals in order to mount them."), + _doc_items_usagehelp = S("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."), + wield_image = "mcl_mobitems_saddle.png", + inventory_image = "mcl_mobitems_saddle.png", + groups = { transport = 1 }, + stack_max = 1, +}) + +minetest.register_craftitem("mcl_mobitems:rabbit_stew", { + description = S("Rabbit Stew"), + _doc_items_longdesc = S("Rabbit stew is a very nutricious food item."), + wield_image = "mcl_mobitems_rabbit_stew.png", + inventory_image = "mcl_mobitems_rabbit_stew.png", + 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 }, + _mcl_saturation = 12.0, +}) + +minetest.register_craftitem("mcl_mobitems:shulker_shell", { + description = S("Shulker Shell"), + _doc_items_longdesc = S("Shulker shells are used in crafting. They are dropped from dead shulkers."), + inventory_image = "mcl_mobitems_shulker_shell.png", + groups = { craftitem = 1 }, +}) + +minetest.register_craftitem("mcl_mobitems:slimeball", { + description = S("Slimeball"), + _doc_items_longdesc = S("Slimeballs are used in crafting. They are dropped from slimes."), + inventory_image = "mcl_mobitems_slimeball.png", + groups = { craftitem = 1 }, +}) + +minetest.register_craftitem("mcl_mobitems:gunpowder", { + description = S("Gunpowder"), + _doc_items_longdesc = doc.sub.items.temp.craftitem, + inventory_image = "default_gunpowder.png", + stack_max = 64, + groups = { craftitem=1, brewitem = 1 }, +}) + +minetest.register_tool("mcl_mobitems:carrot_on_a_stick", { + description = S("Carrot on a Stick"), + _tt_help = S("Lets you ride a saddled pig"), + _doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."), + _doc_items_usagehelp = S("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."), + wield_image = "mcl_mobitems_carrot_on_a_stick.png^[transformFY^[transformR90", + inventory_image = "mcl_mobitems_carrot_on_a_stick.png", + groups = { transport = 1 }, + _mcl_toollike_wield = true, +}) + +minetest.register_tool("mcl_mobitems:warped_fungus_on_a_stick", { + description = S("Warped fungus on a Stick"), + _tt_help = S("Lets you ride a strider"), + _doc_items_longdesc = S("A warped fungus on a stick can be used on saddled striders to ride them."), + _doc_items_usagehelp = S("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."), + wield_image = "mcl_mobitems_warped_fungus_on_a_stick.png^[transformFY^[transformR90", + inventory_image = "mcl_mobitems_warped_fungus_on_a_stick.png", + groups = { transport = 1 }, + _mcl_toollike_wield = true, +}) + +minetest.register_craftitem("mcl_mobitems:nautilus_shell", { + description = S("Nautilus Shell"), + _tt_help = S("Used to craft a conduit"), + _doc_items_longdesc = S("The Nautilus Shell is used to craft a conduit. They can be obtained by fishing or killing a drowned that is wielding a shell."), + inventory_image = "mcl_mobitems_nautilus_shell.png", + groups = { craftitem=1 }, + stack_max = 64, +}) + +minetest.register_craftitem("mcl_mobitems:heart_of_the_sea", { + description = S("Heart of the Sea"), + _tt_help = S("Used to craft a conduit"), + _doc_items_longdesc = S("The Heart of the Sea is used to craft a conduit. They can be obtained by finding them in a buried treasure chest."), + inventory_image = "mcl_mobitems_heart_of_the_sea.png", + groups = { craftitem=1 }, + stack_max = 64, +}) + +local horse_armor_use = S("Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.") + +minetest.register_craftitem("mcl_mobitems:iron_horse_armor", { + description = S("Iron Horse Armor"), + _doc_items_longdesc = S("Iron horse armor can be worn by horses to increase their protection from harm a bit."), + _doc_items_usagehelp = horse_armor_use, + inventory_image = "mcl_mobitems_iron_horse_armor.png", + _horse_overlay_image = "mcl_mobitems_horse_armor_iron.png", + sounds = { + _mcl_armor_equip = "mcl_armor_equip_iron", + }, + stack_max = 1, + groups = { horse_armor = 85 }, +}) + +minetest.register_craftitem("mcl_mobitems:gold_horse_armor", { + description = S("Golden Horse Armor"), + _doc_items_longdesc = S("Golden horse armor can be worn by horses to increase their protection from harm."), + _doc_items_usagehelp = horse_armor_use, + inventory_image = "mcl_mobitems_gold_horse_armor.png", + _horse_overlay_image = "mcl_mobitems_horse_armor_gold.png", + sounds = { + _mcl_armor_equip = "mcl_armor_equip_iron", + }, + stack_max = 1, + groups = { horse_armor = 60 }, +}) + +minetest.register_craftitem("mcl_mobitems:diamond_horse_armor", { + description = S("Diamond Horse Armor"), + _doc_items_longdesc = S("Diamond horse armor can be worn by horses to greatly increase their protection from harm."), + _doc_items_usagehelp = horse_armor_use, + inventory_image = "mcl_mobitems_diamond_horse_armor.png", + _horse_overlay_image = "mcl_mobitems_horse_armor_diamond.png", + sounds = { + _mcl_armor_equip = "mcl_armor_equip_diamond", + }, + stack_max = 1, + groups = { horse_armor = 45 }, +}) + +minetest.register_alias("mobs_mc:iron_horse_armor", "mcl_mobitems:iron_horse_armor") +minetest.register_alias("mobs_mc:gold_horse_armor", "mcl_mobitems:gold_horse_armor") +minetest.register_alias("mobs_mc:diamond_horse_armor", "mcl_mobitems:diamond_horse_armor") + +minetest.register_craftitem("mcl_mobitems:glow_ink_sac", { + description = S("Glow Ink Sac"), + _doc_items_longdesc = S("Use it to craft the Glow Item Frame."), + _doc_items_usagehelp = S("Use the Glow Ink Sac and the normal Item Frame to craft the Glow Item Frame."), + inventory_image = "mcl_mobitems_glow_ink_sac.png", + groups = { craftitem = 1 }, +}) + + +----------- +-- Crafting +----------- + +minetest.register_craft({ + output = "mcl_mobitems:leather", + recipe = { + { "mcl_mobitems:rabbit_hide", "mcl_mobitems:rabbit_hide" }, + { "mcl_mobitems:rabbit_hide", "mcl_mobitems:rabbit_hide" }, + } +}) + +minetest.register_craft({ + output = "mcl_mobitems:blaze_powder 2", + recipe = {{"mcl_mobitems:blaze_rod"}}, +}) + +minetest.register_craft({ + output = "mcl_mobitems:rabbit_stew", + recipe = { + { "", "mcl_mobitems:cooked_rabbit", "", }, + { "group:mushroom", "mcl_farming:potato_item_baked", "mcl_farming:carrot_item", }, + { "", "mcl_core:bowl", "", }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:rabbit_stew", + recipe = { + { "", "mcl_mobitems:cooked_rabbit", "", }, + { "mcl_farming:carrot_item", "mcl_farming:potato_item_baked", "group:mushroom", }, + { "", "mcl_core:bowl", "", }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:carrot_on_a_stick", + recipe = { + { "mcl_fishing:fishing_rod", "", }, + { "", "mcl_farming:carrot_item" }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:carrot_on_a_stick", + recipe = { + { "", "mcl_fishing:fishing_rod", }, + { "mcl_farming:carrot_item", "" }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:warped_fungus_on_a_stick", + recipe = { + { "mcl_fishing:fishing_rod", "", }, + { "", "mcl_crimson:warped_fungus" }, + }, +}) + +minetest.register_craft({ + output = "mcl_mobitems:warped_fungus_on_a_stick", + recipe = { + { "","mcl_fishing:fishing_rod", }, + { "mcl_crimson:warped_fungus", "" }, + }, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_mobitems:magma_cream", + recipe = {"mcl_mobitems:blaze_powder", "mcl_mobitems:slimeball"}, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_mobitems:cooked_mutton", + recipe = "mcl_mobitems:mutton", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_mobitems:cooked_rabbit", + recipe = "mcl_mobitems:rabbit", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_mobitems:cooked_chicken", + recipe = "mcl_mobitems:chicken", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_mobitems:cooked_beef", + recipe = "mcl_mobitems:beef", + cooktime = 10, +}) + +minetest.register_craft({ + type = "cooking", + output = "mcl_mobitems:cooked_porkchop", + recipe = "mcl_mobitems:porkchop", + cooktime = 10, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mcl_mobitems:blaze_rod", + burntime = 120, +}) + +minetest.register_craft({ + output = "mcl_mobitems:slimeball 9", + recipe = {{"mcl_core:slimeblock"}}, +}) + +minetest.register_craft({ + output = "mcl_core:slimeblock", + recipe = {{"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}, + {"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}, + {"mcl_mobitems:slimeball","mcl_mobitems:slimeball","mcl_mobitems:slimeball",}}, +}) + +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) + end +end) diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr index d47b811f0..c1278ad36 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.de.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful 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.=Halten Sie den Knochen in der Nähe von Wölfen, um sie anzulocken. Benutzen Sie die „Platzieren“-Taste auf dem Wolf, um ihm den Knochen zu geben und ihn zu zähmen. Sie können dem gezähmten Wolf Befehle erteilen, indem Sie die „Platzieren“-Taste auf ihm benutzen. +Squid Ink Sac=Tintenbeutel +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.=Dieser Gegenstand wird von toten Tintenfischen abgeworfen. Tintenbeutel können benutzt werden, um Buch und Feder oder schwarzen Farbstoff zu fertigen. + String=Faden Strings are used in crafting.=Fäden sind nützlich in der Fertigung. Blaze Rod=Lohenrute @@ -61,7 +64,7 @@ This item is mainly used for crafting.=Dieser Gegenstand wird hauptsächlich in Magma Cream=Magmacreme Magma cream is a crafting component.=Magmacreme ist eine Fertigungskomponente. Ghast Tear=Ghast-Träne -Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmel als Deko. +Place this item in an item frame as decoration.=Platzieren Sie diesen Gegenstand in einem Rahmen als Deko. Nether Star=Nether-Stern 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.=Ein Netherstern wird abgeworfen, wenn der Wither stirbt. Platzieren Sie ihn in einen Rahmen, um der Welt zu zeigen, wie großartig Sie sind! @@ -93,3 +96,10 @@ A carrot on a stick can be used on saddled pigs to ride them.=Eine Karottenrute 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.=Platzieren Sie sie auf einem Schwein mit Sattel, um sich aufzusatteln. Sie können nun das Schwein wie ein Pferd reiten. Schweine werden auch auf Sie zugehen, wenn Sie einfach nur die Karottenrute halten. +Iron Horse Armor=Eisenpferderüstung +Iron horse armor can be worn by horses to increase their protection from harm a bit.=Eine Eisenpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden etwas zu erhöhen. +Golden Horse Armor=Goldpferderüstung +Golden horse armor can be worn by horses to increase their protection from harm.=Eine Goldpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden zu erhöhen. +Diamond Horse Armor=Diamantpferderüstung +Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Eine Diamantpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden beträchtlich zu erhöhen. +Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Platzieren Sie es auf einem Pferd, um die Pferderüstung aufzusetzen. Esel und Maultiere können keine Pferderüstung tragen. diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr index 746a438b0..1add14030 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.es.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful 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.=Empuña el hueso cerca de los lobos para atraerlos. Usa la tecla "Colocar" en el lobo para darle un hueso y domesticarlo. Luego puede dar órdenes al lobo domesticado utilizando la tecla "Colocar". +Squid Ink Sac=Saco de tinta +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=Cuerda Strings are used in crafting.=Las cuerdas se usan en la elaboración. Blaze Rod=Vara de blaze @@ -93,10 +96,15 @@ A carrot on a stick can be used on saddled pigs to ride them.=La caña con zanah 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.=Colóquelo sobre un cerdo ensillado para montarlo. Ahora puedes montar el cerdo como un caballo. Los cerdos también caminarán hacia ti cuando solo manejes la zanahoria en un palo. - +Iron Horse Armor=Armadura de hierro para caballo +Iron horse armor can be worn by horses to increase their protection from harm a bit.=Los caballos pueden usar armadura de caballo de hierro para aumentar un poco su protección contra el daño. +Golden Horse Armor=Armadura de oro para caballo +Golden horse armor can be worn by horses to increase their protection from harm.=Los caballos pueden usar armadura de caballo de oro para aumentar su protección contra el daño. +Diamond Horse Armor=Armadura de diamante para caballo +Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Los caballos pueden usar armadura de caballo de diamante para aumentar en gran medida su protección contra el daño. +Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Colóquelo en un caballo para ponerle la armadura de caballo. Los burros y las mulas no pueden usar armadura de caballo. ##### not used anymore ##### Milk is very refreshing and can be obtained by using a bucket on a cow. Drinking it will cure all forms of poisoning, but restores no hunger points.=La leche es muy refrescante y se puede obtener usando un cubo en una vaca. Beberlo curará todas las formas de envenenamiento, pero no restaura los puntos de hambre. - diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr index 1bc756260..9e94befa4 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr @@ -1,14 +1,14 @@ # textdomain: mcl_mobitems -Rotten Flesh=Chair Putréfiée +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. -Raw Mutton=Mouton Cru +Raw Mutton=Mouton cru Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.=Le mouton cru est la chair d'un mouton et peut être mangé en toute sécurité. La cuisson augmentera considérablement sa valeur nutritive. -Cooked Mutton=Mouton Cuit +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 @@ -16,32 +16,32 @@ Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly Steak=Steak Steak is cooked beef from cows and can be eaten.=Le steak est du boeuf cuit et peut être mangé. -Raw Chicken=Poulet Cru +Raw Chicken=Poulet cru 30% chance of food poisoning=30% de chances d'intoxication alimentaire 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.=Le poulet cru est un aliment qui n'est pas sûr à consommer. Vous pouvez le manger pour restaurer quelques points de faim, mais il y a 30% de chances de souffrir d'intoxication alimentaire, ce qui augmente votre taux de faim pendant un certain temps. La cuisson du poulet cru le rendra sûr à manger et augmentera sa valeur nutritive. -Cooked Chicken=Poulet Cuit +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 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=Parc Cuit +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 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 +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! 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.= -Spider Eye=Oeil d'Araignée +Use the placement key to drink the milk.=Utilisez la touche de placement pour boire le lait. +Spider Eye=Œil 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. @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful 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.=Maniez l'os près des loups pour les attirer. Utilisez la touche «Placer» sur le loup pour lui donner un os et l'apprivoiser. Vous pouvez ensuite donner des commandes au loup apprivoisé en utilisant la touche "Placer" sur celui-ci. +Squid Ink Sac=Poche d'encre +This item is dropped by dead squids. Squid ink can be used to as an ingredient to craft book and quill or black dye.=Cet objet est lâché par des poulpes morts. L'encre de poulpe peut être utilisée comme ingrédient pour fabriquer des livres et plume ou de l'encre noire. + String=Ficelle Strings are used in crafting.=Les ficelles sont utilisées dans l'artisanat. Blaze Rod=Bâton de Blaze @@ -70,25 +73,48 @@ Leather=Cuir Leather is a versatile crafting component.=Le cuir est un élément d'artisanat polyvalent. Feather=Plume Feathers are used in crafting and are dropped from chickens.=Les plumes sont utilisées dans l'artisanat et tombent des poulets. -Rabbit Hide=Peau de Lapin +Rabbit Hide=Peau de lapin Rabbit hide is used to create leather.=La peau de lapin est utilisée pour créer du cuir. -Rabbit's Foot=Patte de Lapin -Must be your lucky day! Place this item in an item frame for decoration.=Ce doit être votre jour de chance! Placez cet article dans un cadre d'article pour la décoration. +Rabbit's Foot=Patte de lapin +Must be your lucky day! Place this item in an item frame for decoration.=Ce doit être votre jour de chance ! Placez cet objet dans un cadre d'objet pour la décoration. Saddle=Selle Can be placed on animals to ride them=Peut être placé sur les animaux pour les monter Saddles can be put on some animals in order to mount them.=Des selles peuvent être posées sur certains animaux afin de les monter. -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.=Utilisez la touche de placement avec la selle à la main pour essayer de mettre la selle. Les selles conviennent aux chevaux, mulets, ânes et cochons. Les chevaux, les mulets et les ânes doivent d'abord être apprivoisés, sinon ils rejetteront la selle. Les animaux sellés peuvent être montés en utilisant à nouveau la touche de placement. -Rabbit Stew=Ragout de Lapin +Rabbit Stew=Ragout de lapin Rabbit stew is a very nutricious food item.=Le ragoût de lapin est un aliment très nutritif. Shulker Shell=Carapace de Shulker Shulker shells are used in crafting. They are dropped from dead shulkers.=Les carapaces Shulker sont utilisés dans l'artisanat. Ils sont lâchés de shulkers morts. Slimeball=Boule de Slime Slimeballs are used in crafting. They are dropped from slimes.=Les boules de slime sont utilisées dans l'artisanat. Ils sont lâchés par les Slimes. Gunpowder=Poudre à canon -Carrot on a Stick=Carotte sur un Batôn +Carrot on a Stick=Carotte sur un bâton Lets you ride a saddled pig=Vous permet de monter un cochon sellé A carrot on a stick can be used on saddled pigs to ride them.=Une carotte sur un bâton peut être utilisée sur les porcs sellés pour les monter. -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.=Placez-le sur un cochon sellé pour le monter. Vous pouvez maintenant monter le cochon comme un cheval. Les porcs marcheront également vers vous lorsque vous brandirez la carotte sur un bâton. \ No newline at end of file +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.=Placez-le sur un cochon sellé pour le monter. Vous pouvez maintenant monter le cochon comme un cheval. Les porcs marcheront également vers vous lorsque vous brandirez la carotte sur un bâton. + +Warped fungus on a Stick=Champignon tordu sur un bâton +Lets you ride a strider=Vous permet de monter un arpenteur +A warped fungus on a stick can be used on saddled striders to ride them.=Un champignon tordu sur un bâton peut être utilisé sur les arpenteurs sellés pour les monter. +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. +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é. + +Iron Horse Armor=Armure de cheval en fer +Iron horse armor can be worn by horses to increase their protection from harm a bit.=L'armure de cheval en fer peut être portée par les chevaux pour augmenter un peu leur protection contre les dégâts. +Golden Horse Armor=Armure de cheval en or +Golden horse armor can be worn by horses to increase their protection from harm.=Une armure de cheval en or peut être portée par les chevaux pour augmenter leur protection contre les dégâts. +Diamond Horse Armor=Armure de cheval en diamant +Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Une armure de cheval en diamant peut être portée par les chevaux pour augmenter fortement leur protection contre les dégâts. +Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Placez-la sur un cheval pour mettre l'armure de cheval. Les ânes et les mules ne peuvent pas porter d'armure de cheval. + +Glow Ink Sac=Poche d'encre brillante +Use it to craft the Glow Item Frame.=Utilisez la pour fabriquer un Cadre d'objet brillant. +Use the Glow Ink Sac and the normal Item Frame to craft the Glow Item Frame.=Utilisez la Poche d'encre brillante et le Cadre d'objet normal pour fabriquer le Cadre d'objet brillant. diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr new file mode 100644 index 000000000..f5d18c7f1 --- /dev/null +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ja.tr @@ -0,0 +1,108 @@ +# textdomain: mcl_mobitems +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.=ウッ この肉片は明らかに期限切れです。あなたが差し迫っているというのなら、食べて空腹を紛らわせるのもアリですが、八割方 食中りを起こし、しばらくは空腹感が増します。 + +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.=ジンギスカンは羊の肉を調理したもので、食用です。 +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%の確率で食中毒 + +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.=ヤキトリは、食べても大丈夫なヘルシー食品です。 +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.=チャーシューは豚の肉を調理したもので、食用です。 +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.=これは食料品です。 +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.=牛乳はとてもさわやかで、バケツを牛に使うことで採れます。これを飲むと全てのステータス効果を除去しますが、お腹は満たせません。 + +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.=クモの目は主にクラフトに使われます。あなたがどうしようもなく過酷なら、食べることもできます…が、早い話これは毒です。 + +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.=骨をオオカミの近くで振り、引き付けます。オオカミに「設置」キーを使うと、骨を与えて手なずけられます。手なずけたオオカミに「設置」キーを使えば、オオカミに号令が出せます。 + +String=糸 +Strings are used in crafting.=糸はクラフトに使えます。 +Blaze Rod=ブレイズロッド +This is a crafting component dropped from dead blazes.=これは死んだブレイズから落ちた、クラフトの構成材です。 +Blaze Powder=ブレイズパウダー +This item is mainly used for crafting.=このアイテムは主にクラフトに使われます。 +Magma Cream=マグマクリーム +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.=ネザースターは、ウィザーが死んだ時にドロップします。アイテムフレームに入れれば、あなたのハードコアぶりを世界にアピールできます! あるいはただの飾りです。 + +Leather=革 +Leather is a versatile crafting component.=革は、多用途なクラフトの構成材です。 +Feather=羽 +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.=動物によっては、鞍を装着して騎乗できます。 + +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.=ラビットシチューは、とても栄養豊富な食品です。 +Shulker Shell=シュルカーの殻 +Shulker shells are used in crafting. They are dropped from dead shulkers.=シュルカーの殻はクラフトに使われます。それは死んだシュルカーからドロップされます。 +Slimeball=スライムボール +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.=鞍をつけたブタの上にそれを掲げます。 これで、ブタに騎乗できること馬のごとしです。 ニンジン付きの棒を振るうだけでも、ブタはあなたに向かって歩いてきます。 + +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.=ウマに被せると、馬鎧を着せることができます。ロバとラバには、馬鎧を着せられません。 diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr new file mode 100644 index 000000000..a58bfb474 --- /dev/null +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.pl.tr @@ -0,0 +1,99 @@ +# textdomain: mcl_mobitems +Rotten Flesh=Zgniłe mięso +80% chance of food poisoning=80% szans na zatrucie pokarmowe + +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.=Fuj! Ten kawał mięsa zdecydowanie widział lepsze dni. Jeśli jesteś bardzo zdesperowana, możesz je zjeść by odzyskać kilka punktów głodu, ale jest 80 % szans, że spowoduje to zatrucie pokarmowe, które zwiększa chwilowo twój głód. + +Raw Mutton=Surowa baranina + +Raw mutton is the flesh from a sheep and can be eaten safely. Cooking it will greatly increase its nutritional value.=Surowa baranina to mięso z owcy, które może być bezpiecznie zjedzone. Upieczenie go znacząco zwiększy jego wartości odżywcze. + +Cooked Mutton=Pieczona baranina +Cooked mutton is the cooked flesh from a sheep and is used as food.=Upieczona baranina jest upieczonym mięsem z owcy i używana jako jedzenie. +Raw Beef=Surowa wołowina + +Raw beef is the flesh from cows and can be eaten safely. Cooking it will greatly increase its nutritional value.=Surowa wołowina jest mięsem z krowy i może być bezpiecznie zjedzone. Upieczenie go znacząco zwiększy jego wartości odżywcze. + + +Steak=Befsztyk +Steak is cooked beef from cows and can be eaten.=Befsztyk jest upieczoną wołowiną z krowy i może być zjedzony. +Raw Chicken=Surowy drób +30% chance of food poisoning=30% szans na zatrucie pokarmowe + +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.=Surowy drób nie jest bezpieczny do jedzenia. Można go zjeść, co przywróci kilka punktów głodu, jednak jest 30% szans, że spowoduje to zatrucie pokarmowe, które chwilowo zwiększa głód. Upieczenie surowego drobiu sprawi, że będzie on bezpieczny do jedzenia i zwiększy jego wartości odżywcze. + +Cooked Chicken=Pieczony kurczak +A cooked chicken is a healthy food item which can be eaten.=Pieczony kurczak jest zdrowym jedzeniem, które można bezpiecznie zjeść. +Raw Porkchop=Surowy schab + +A raw porkchop is the flesh from a pig and can be eaten safely. Cooking it will greatly increase its nutritional value.=Surowy schab jest mięsem ze świni i może zostać bezpiecznie zjedzony. Upieczenie go znacząco zwiększy jego wartości odżywcze. + +Cooked Porkchop=Pieczony schab +Cooked porkchop is the cooked flesh of a pig and is used as food.=Pieczony schab to upieczone mięso świni i jest używane jako jedzenie. +Raw Rabbit=Surowy mięso królicze + +Raw rabbit is a food item from a dead rabbit. It can be eaten safely. Cooking it will increase its nutritional value.=Surowy mięso królicze jest mięsem z martwego królika. Może zostać bezpiecznie zjedzone. Upieczenie go znacząco zwiększy jego wartości odżywcze. + +Cooked Rabbit=Pieczony królik +This is a food item which can be eaten.=Ten przedmiot można bezpiecznie zjeść. +Milk=Mleko +Removes all status effects=Usuwa wszystkie statusy efektów. + +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.=Mleko jest bardzo odświeżające i może zostać uzyskane przez użycie wiadra na krowie. Wypicie go usunie wszystkie statusy efektów, ale nie przywróci punktów głodu. + +Use the placement key to drink the milk.=Kliknij przycisk umieszczania aby wypić mleko. +Spider Eye=Oko pająka +Poisonous=Trujące + +Spider eyes are used mainly in crafting. If you're really desperate, you can eat a spider eye, but it will poison you briefly.=Oczy pająka są użyteczne przy wytwarzaniu. Jeśli jesteś zdesperowana możesz je zjeść, ale otruje cię ono chwilowo. + +Bone=Kość + +Bones can be used to tame wolves so they will protect you. They are also useful as a crafting ingredient.=Kości mogą być użyte do oswajania wilków, aby cię broniły. Są również użyteczne jako materiały do wytwarzania. + +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.=Trzymaj kość w pobliżu wilków aby je zwabić. Użyj przycisku "Umieść" na wilku aby dać mu kość i go oswoić. Możesz wtedy wydawać polecenia oswojonemu wilkowi klikając przycisk "Umieść" na nim. + +Squid Ink Sac=Torbiel z atramentem +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=Nić +Strings are used in crafting.=Nić jest użyteczna w wytwarzaniu. +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 +This item is mainly used for crafting.=Ten przedmiot jest użyteczny w wytwarzaniu. +Magma Cream=Magmowy krem +Magma cream is a crafting component.=Magmowy krem to materiał do wytwarzania. +Ghast Tear=Łza Ghasta +Place this item in an item frame as decoration.=Umieść ten item w ramce jako dekorację. +Nether Star=Gwiazda Netheru + +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.=Gwiazda Netheru wypada gdy Wither umiera. Umieść ją w ramce by pokazać światu jak bardzo hardkorowa jesteś. + +Leather=Skóra +Leather is a versatile crafting component.=Skóra jest wszechstronnym materiałem do wytwarzania. +Feather=Pióro +Feathers are used in crafting and are dropped from chickens.=Pióra są używane w wytwarzaniu i wypadają z kurczaków. +Rabbit Hide=Królicza skóra +Rabbit hide is used to create leather.=Królicza skóra jest wykorzystywana do tworzenia skóry. +Rabbit's Foot=Królicza łapka +Must be your lucky day! Place this item in an item frame for decoration.=To musi być twój szczęśliwy dzień! Umieść ten przedmiot w ramce jako dekorację. +Saddle=Siodło +Can be placed on animals to ride them=Może być umieszczone na zwierzętach aby na nich jeździć. +Saddles can be put on some animals in order to mount them.=Siodła mogą być umieszczone na zwierzętach aby ich dosiąść. + +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.=Użyj przycisku umieszczania z siodłem w ręku, aby założyć siodło. Siodła pasują na konie, muły, osły i świnie. Konie, muły i osły muszą być najpierw oswojone, w przeciwnym razie nie dadzą się osiodłać. Osiodłane zwierzęta można dosiąść klikając je prawym przyciskiem myszy. + +Rabbit Stew=Potrawka z królika +Rabbit stew is a very nutricious food item.=Potrawka z królika jest bardzo odżywczym posiłkiem. +Shulker Shell=Skorupa shulkera +Shulker shells are used in crafting. They are dropped from dead shulkers.=Skorupy shulkera są użyteczne w wytwarzaniu. Wypadają z martwych shulkerów. +Slimeball=Kula szlamu +Slimeballs are used in crafting. They are dropped from slimes.=Kule szlamu są użyteczne w wytwarzaniu. Wypadają z szlamów. +Gunpowder=Proch +Carrot on a Stick=Marchewka na patyku +Lets you ride a saddled pig=Pozwala prowadzić osiodłaną świnię +A carrot on a stick can be used on saddled pigs to ride them.=Marchewka na patyku może być użyta na osiodłanej świni by ją prowadzić. + +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.=Użyj jej na osiodłanej skrzyni aby ją założyć. Możesz teraz jeździć na świni jak na koniu. Świnie będą także do ciebie podchodzić jeśli po prostu trzymasz marchewkę na patyku. + diff --git a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr index f51e4f562..4e3fc020b 100644 --- a/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr +++ b/mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful 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.= + String=Нити Strings are used in crafting.=Нити используются для крафтинга Blaze Rod=Огненный стержень @@ -93,3 +96,10 @@ 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.=Поместите это на осёдланную свинью, чтобы закрепиться на ней. Теперь вы можете ехать на ней, как на лошади. Свиньи также идут вперёд, когда вы просто держите удочку с морковью. +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.=Поместите это на лошадь, чтобы одеть лошадь в доспехи. Ослики и мулы не могут носить лошадиные доспехи. diff --git a/mods/ITEMS/mcl_mobitems/locale/template.txt b/mods/ITEMS/mcl_mobitems/locale/template.txt index ce5bbcabe..dd97fa0dd 100644 --- a/mods/ITEMS/mcl_mobitems/locale/template.txt +++ b/mods/ITEMS/mcl_mobitems/locale/template.txt @@ -52,6 +52,9 @@ Bones can be used to tame wolves so they will protect you. They are also useful 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.= + String= Strings are used in crafting.= Blaze Rod= @@ -93,3 +96,25 @@ 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.= +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_mobitems/mod.conf b/mods/ITEMS/mcl_mobitems/mod.conf index bd534323a..e9604036e 100644 --- a/mods/ITEMS/mcl_mobitems/mod.conf +++ b/mods/ITEMS/mcl_mobitems/mod.conf @@ -1 +1,2 @@ name = mcl_mobitems +depends = mcl_core, mcl_hunger, mcl_colors diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_bucket_milk.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_bucket_milk.png deleted file mode 100644 index 2ba089a54..000000000 Binary files a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_bucket_milk.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_carrot_on_a_stick.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_carrot_on_a_stick.png deleted file mode 100644 index ff85a30df..000000000 Binary files a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_carrot_on_a_stick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_hide.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_hide.png deleted file mode 100644 index 39e1f2215..000000000 Binary files a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_hide.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_slimeball.png b/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_slimeball.png deleted file mode 100644 index e984e9b97..000000000 Binary files a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_slimeball.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mobspawners/depends.txt b/mods/ITEMS/mcl_mobspawners/depends.txt deleted file mode 100644 index dc1a03b82..000000000 --- a/mods/ITEMS/mcl_mobspawners/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -mcl_mobs diff --git a/mods/ITEMS/mcl_mobspawners/init.lua b/mods/ITEMS/mcl_mobspawners/init.lua index 39abd7227..c5c2212b6 100644 --- a/mods/ITEMS/mcl_mobspawners/init.lua +++ b/mods/ITEMS/mcl_mobspawners/init.lua @@ -1,11 +1,14 @@ -local S = minetest.get_translator("mcl_mobspawners") +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math +local table = table mcl_mobspawners = {} local default_mob = "mobs_mc:pig" -- Mob spawner -local spawner_default = default_mob.." 0 15 4 15" +--local spawner_default = default_mob.." 0 15 4 15" local function get_mob_textures(mob) local list = minetest.registered_entities[mob].texture_list @@ -17,9 +20,9 @@ local function get_mob_textures(mob) end local function find_doll(pos) - for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do + for _,obj in pairs(minetest.get_objects_inside_radius(pos, 0.5)) do if not obj:is_player() then - if obj ~= nil and obj:get_luaentity().name == "mcl_mobspawners:doll" then + if obj and obj:get_luaentity().name == "mcl_mobspawners:doll" then return obj end end @@ -54,6 +57,7 @@ local spawn_count_overrides = { local function set_doll_properties(doll, mob) local mobinfo = minetest.registered_entities[mob] + if not mobinfo then return end local xs, ys if doll_size_overrides[mob] then xs = doll_size_overrides[mob].x @@ -132,7 +136,7 @@ end -- Spawn mobs around pos -- NOTE: The node is timer-based, rather than ABM-based. -local spawn_mobs = function(pos, elapsed) +local function spawn_mobs(pos, elapsed) -- get meta local meta = minetest.get_meta(pos) @@ -151,7 +155,7 @@ local spawn_mobs = function(pos, elapsed) end -- are we spawning a registered mob? - if not mobs.spawning_mobs[mob] then + if not mcl_mobs.spawning_mobs[mob] then minetest.log("error", "[mcl_mobspawners] Mob Spawner: Mob doesn't exist: "..mob) return end @@ -159,7 +163,7 @@ local spawn_mobs = function(pos, elapsed) -- check objects inside 8×8 area around spawner local objs = minetest.get_objects_inside_radius(pos, 8) local count = 0 - local ent = nil + local ent local timer = minetest.get_node_timer(pos) @@ -313,6 +317,9 @@ minetest.register_node("mcl_mobspawners:spawner", { if obj then obj:remove() end + if not minetest.is_creative_enabled("") then + mcl_experience.throw_xp(pos, math.random(15, 43)) + end end, on_punch = function(pos) @@ -382,4 +389,3 @@ minetest.register_lbm({ respawn_doll(pos) end, }) - diff --git a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr new file mode 100644 index 000000000..e80806c5d --- /dev/null +++ b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.ja.tr @@ -0,0 +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=モブを出現させる diff --git a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.pl.tr b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.pl.tr new file mode 100644 index 000000000..5b4a8d896 --- /dev/null +++ b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_mobspawners +Mob Spawner=Spawner mobów +A mob spawner regularily causes mobs to appear around it while a player is nearby. Some mob spawners are disabled while in light.=Spawner mobów sprawia, że wokół niego regularnie pojawiają się moby, gdy w pobliżu jest gracz. Niektóre spawnery są wyłączone w świetle. +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.=Jeśli masz jajo spawnowania, możesz go użyć by zmienić moba, który będzie przywoływany. Aby to zrobić umieść przedmiot na spawnerze. +Makes mobs appear=Tworzy moby diff --git a/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.zh_TW.tr b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.zh_TW.tr new file mode 100644 index 000000000..09cdf6458 --- /dev/null +++ b/mods/ITEMS/mcl_mobspawners/locale/mcl_mobspawners.zh_TW.tr @@ -0,0 +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=生成生物 diff --git a/mods/ITEMS/mcl_mobspawners/mod.conf b/mods/ITEMS/mcl_mobspawners/mod.conf index 36112bf36..1759e3408 100644 --- a/mods/ITEMS/mcl_mobspawners/mod.conf +++ b/mods/ITEMS/mcl_mobspawners/mod.conf @@ -1 +1,2 @@ name = mcl_mobspawners +depends = mcl_sounds, mcl_mobs diff --git a/mods/ITEMS/mcl_mobspawners/textures/mob_spawner.png b/mods/ITEMS/mcl_mobspawners/textures/mob_spawner.png deleted file mode 100644 index 8464193c1..000000000 Binary files a/mods/ITEMS/mcl_mobspawners/textures/mob_spawner.png and /dev/null differ diff --git a/mods/ITEMS/mcl_monster_eggs/depends.txt b/mods/ITEMS/mcl_monster_eggs/depends.txt deleted file mode 100644 index d867036e5..000000000 --- a/mods/ITEMS/mcl_monster_eggs/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -mobs_mc diff --git a/mods/ITEMS/mcl_monster_eggs/description.txt b/mods/ITEMS/mcl_monster_eggs/description.txt deleted file mode 100644 index ae7cab253..000000000 --- a/mods/ITEMS/mcl_monster_eggs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds infested blocks: Blocks which which disguise themselves as stone blocks and spawn a silverfish when broken. diff --git a/mods/ITEMS/mcl_monster_eggs/init.lua b/mods/ITEMS/mcl_monster_eggs/init.lua index 55875159e..f58717d04 100644 --- a/mods/ITEMS/mcl_monster_eggs/init.lua +++ b/mods/ITEMS/mcl_monster_eggs/init.lua @@ -1,16 +1,16 @@ -- Monster eggs! -- Blocks which spawn silverfish when destroyed. -local S = minetest.get_translator("mcl_monster_eggs") +local S = minetest.get_translator(minetest.get_current_modname()) -local spawn_silverfish = function(pos, oldnode, oldmetadata, digger) +local function spawn_silverfish(pos, oldnode, oldmetadata, digger) if not minetest.is_creative_enabled("") then minetest.add_entity(pos, "mobs_mc:silverfish") end end -- Template function for registering monster egg blocks -local register_block = function(subname, description, tiles, is_ground_content) +local function register_block(subname, description, tiles, is_ground_content) if is_ground_content == nil then is_ground_content = false end @@ -19,8 +19,7 @@ local register_block = function(subname, description, tiles, is_ground_content) tiles = tiles, is_ground_content = is_ground_content, groups = {dig_immediate = 3, spawns_silverfish = 1, deco_block = 1}, - drop = '', - is_ground_content = false, + drop = "", sounds = mcl_sounds.node_sound_stone_defaults(), after_dig_node = spawn_silverfish, _tt_help = S("Hides a silverfish"), diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.tr new file mode 100644 index 000000000..5c88cc5be --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.ja.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.=虫喰いブロックは、壊れるとそこからシルバーフィッシュが飛び出してきます。見た目は通常のブロックと同じです。 +Infested Stone=虫喰い石 +Infested Cobblestone=虫喰い丸石 +Infested Stone Bricks=虫喰い石レンガ +Infested Cracked Stone Bricks=ひび割れた虫喰い石レンガ +Infested Mossy Stone Bricks=苔むした虫喰い石レンガ +Infested Chiseled Stone Bricks=模様入り虫喰い石レンガ +Hides a silverfish=シルバーフィッシュを隠す diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pl.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pl.tr new file mode 100644 index 000000000..2d55f713f --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.pl.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.=Zarobaczony blok to blok z którego po rozbiciu wypadną rybiki cukrowe. Wygląda identycznie co niezarobaczona wersja. +Infested Stone=Zarobaczony kamień +Infested Cobblestone=Zarobaczony brukowiec +Infested Stone Bricks=Zarobaczone kamienne cegły +Infested Cracked Stone Bricks=Zarobaczone popękane kamienne cegły +Infested Mossy Stone Bricks=Zarobaczone zamszone kamienne cegły +Infested Chiseled Stone Bricks=Zarobaczone wygładzone kamienne cegły +Hides a silverfish=Chowa w sobie rybika cukrowego diff --git a/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.zh_TW.tr b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.zh_TW.tr new file mode 100644 index 000000000..542c0f1b9 --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/locale/mcl_monster_eggs.zh_TW.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.=蛀蝕的方塊是一個方塊,當它被打破時,蠹魚會從裡面跳出來。它看起來與正常的方塊完全一樣。 +Infested Stone=蛀蝕的石頭 +Infested Cobblestone=蛀蝕的鵝卵石 +Infested Stone Bricks=蛀蝕的石磚 +Infested Cracked Stone Bricks=蛀蝕的裂紋石磚 +Infested Mossy Stone Bricks=蛀蝕的青苔石磚 +Infested Chiseled Stone Bricks=蛀蝕的浮雕石磚 +Hides a silverfish=包含一個蠹魚 diff --git a/mods/ITEMS/mcl_monster_eggs/mod.conf b/mods/ITEMS/mcl_monster_eggs/mod.conf new file mode 100644 index 000000000..b29601864 --- /dev/null +++ b/mods/ITEMS/mcl_monster_eggs/mod.conf @@ -0,0 +1,3 @@ +name = mcl_monster_eggs +description = Adds infested blocks: Blocks which which disguise themselves as stone blocks and spawn a silverfish when broken. +depends = mcl_sounds, mobs_mc diff --git a/mods/ITEMS/mcl_mud/README.txt b/mods/ITEMS/mcl_mud/README.txt new file mode 100644 index 000000000..fe0a3f91c --- /dev/null +++ b/mods/ITEMS/mcl_mud/README.txt @@ -0,0 +1,21 @@ +License of Code +---------------- + +Author: TheRandomLegoBrick +License: GPLv3 +See https://www.gnu.org/licenses/gpl-3.0.en.html for further information + + +License of Media (textures & sounds) +------------------------------------- + +Author: TheRandomLegoBrick +Liscense: CC0 1.0 Universal (CC0 1.0) +Files: + mud_footsteps.ogg + mud_place_dug.ogg + mcl_mud_bricks.png + mcl_mud_packed_mud.png + mcl_mud.png + +See https://creativecommons.org/publicdomain/zero/1.0/legalcode for further information \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/init.lua b/mods/ITEMS/mcl_mud/init.lua new file mode 100644 index 000000000..64ff36c09 --- /dev/null +++ b/mods/ITEMS/mcl_mud/init.lua @@ -0,0 +1,65 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_node("mcl_mud:mud", { + description = S("Mud"), + _doc_items_longdesc = S("Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt."), + _doc_items_hidden = false, + tiles = {"mcl_mud.png"}, + is_ground_content = true, + sounds = { + footstep = {name="mud_footsteps", gain=1}, + dug = {name="mud_place_dug", gain=1}, + place = {name="mud_place_dug", gain=1}, + }, + groups = {handy=1, shovely=1, enderman_takable=1, grass_block=1, soil_sugarcane=1, building_block=1}, + _mcl_blast_resistance = 0.5, + _mcl_hardness = 0.5, + collision_box = { + type = "fixed", + fixed = { + {-8 / 16, -8 / 16, -8 / 16, 8 / 16, 6 / 16, 8 / 16}, + }, + }, +}) + +minetest.register_node("mcl_mud:packed_mud", { + description = S("Packed Mud"), + _doc_items_longdesc = S("Packed mud is a decorative block used to craft mud bricks."), + _doc_items_hidden = false, + tiles = {"mcl_mud_packed_mud.png"}, + groups = {handy=1, pickaxey=1, building_block=1}, + sounds = mcl_sounds.node_sound_dirt_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 1, +}) + +minetest.register_node("mcl_mud:mud_bricks", { + description = S("Mud Bricks"), + _doc_items_longdesc = S("Decorative block crafted from packed mud."), + _doc_items_hidden = false, + tiles = {"mcl_mud_bricks.png"}, + groups = {handy=1, pickaxey=1, building_block=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 3, + _mcl_hardness = 1.5, +}) + +-- packed mud +minetest.register_craft({ + type = "shapeless", + output = "mcl_mud:packed_mud", + recipe = { + "mcl_mud:mud", + "mcl_farming:wheat_item", + } +}) + +-- mud bricks +minetest.register_craft({ + type = "shaped", + output = "mcl_mud:mud_bricks 4", + recipe = { + {"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.fr.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.fr.tr new file mode 100644 index 000000000..d95771bd2 --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.fr.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_mud +Mud=Boue +Mud is a decorative block that generates in mangrove swamps. Mud can also be obtained by using water bottles on dirt or coarse dirt.=La boue est un bloc décoratif généré dans les marécages mangrove. La boue peut aussi être obtenue en utilisant des bouteilles d'eau sur de la terre ou de la terre stérile. +Packed Mud=Boue compactée +Packed mud is a decorative block used to craft mud bricks.=La boue compactée est un bloc décoratif utilisé pour fabriquer des briques de boue. +Mud Bricks=Briques de boue +Decorative block crafted from packed mud.=Bloc décoratif fabriqué à partir de boue compactée. diff --git a/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.tr b/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.tr new file mode 100644 index 000000000..3c4eba845 --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/mcl_mud.ja.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_mud/locale/template.txt b/mods/ITEMS/mcl_mud/locale/template.txt new file mode 100644 index 000000000..a42019d1c --- /dev/null +++ b/mods/ITEMS/mcl_mud/locale/template.txt @@ -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_mud/mod.conf b/mods/ITEMS/mcl_mud/mod.conf new file mode 100644 index 000000000..70f48ef1e --- /dev/null +++ b/mods/ITEMS/mcl_mud/mod.conf @@ -0,0 +1,4 @@ +name = mcl_mud +author = TheRandomLegoBrick +description = Adds various mud blocks. +depends = mcl_sounds \ No newline at end of file diff --git a/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg b/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg new file mode 100644 index 000000000..e18c93965 Binary files /dev/null and b/mods/ITEMS/mcl_mud/sounds/mud_footsteps.ogg differ diff --git a/mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg b/mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg new file mode 100644 index 000000000..5a93ca14a Binary files /dev/null and b/mods/ITEMS/mcl_mud/sounds/mud_place_dug.ogg differ diff --git a/mods/ITEMS/mcl_mushrooms/depends.txt b/mods/ITEMS/mcl_mushrooms/depends.txt deleted file mode 100644 index 7ddb9b8f8..000000000 --- a/mods/ITEMS/mcl_mushrooms/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_util -doc? diff --git a/mods/ITEMS/mcl_mushrooms/huge.lua b/mods/ITEMS/mcl_mushrooms/huge.lua index 12b00db8c..0e99ae0be 100644 --- a/mods/ITEMS/mcl_mushrooms/huge.lua +++ b/mods/ITEMS/mcl_mushrooms/huge.lua @@ -1,7 +1,12 @@ -local S = minetest.get_translator("mcl_mushrooms") +local S = minetest.get_translator(minetest.get_current_modname()) + +local vector = vector local template = { - groups = {handy=1,axey=1, building_block = 1, material_wood = 1, flammable = -1 }, + groups = { + handy = 1, axey = 1, building_block = 1, material_wood = 1, + flammable = -1, compostability = 85 + }, sounds = mcl_sounds.node_sound_wood_defaults(), is_ground_content = true, _mcl_blast_resistance = 0.2, @@ -12,16 +17,16 @@ local template = { local red = table.copy(template) red.drop = { items = { - { items = {'mcl_mushrooms:mushroom_red 1'}, rarity = 2 }, - { items = {'mcl_mushrooms:mushroom_red 1'}, rarity = 2 }, + { items = {"mcl_mushrooms:mushroom_red"}, rarity = 2 }, + { items = {"mcl_mushrooms:mushroom_red"}, rarity = 2 }, } } local brown= table.copy(template) brown.drop = { items = { - { items = {'mcl_mushrooms:mushroom_brown 1'}, rarity = 2 }, - { items = {'mcl_mushrooms:mushroom_brown 1'}, rarity = 2 }, + { items = {"mcl_mushrooms:mushroom_brown"}, rarity = 2 }, + { items = {"mcl_mushrooms:mushroom_brown"}, rarity = 2 }, } } @@ -40,7 +45,7 @@ local function to_binary(num) return binary end -local register_mushroom = function(color, species_id, template, d_cap, d_stem, d_stem_all, longdesc_cap, longdesc_stem) +local function register_mushroom(color, species_id, template, d_cap, d_stem, d_stem_all, longdesc_cap, longdesc_stem) -- Stem texture on all sides local stem_full = table.copy(template) @@ -49,6 +54,7 @@ local register_mushroom = function(color, species_id, template, d_cap, d_stem, d stem_full.tiles = { "mcl_mushrooms_mushroom_block_skin_stem.png" } stem_full.groups.huge_mushroom = species_id stem_full.groups.huge_mushroom_stem = 2 + stem_full.groups.compostability = 65 minetest.register_node("mcl_mushrooms:"..color.."_mushroom_block_stem_full", stem_full) -- Stem @@ -58,6 +64,7 @@ local register_mushroom = function(color, species_id, template, d_cap, d_stem, d stem.tiles = { "mcl_mushrooms_mushroom_block_inside.png", "mcl_mushrooms_mushroom_block_inside.png", "mcl_mushrooms_mushroom_block_skin_stem.png" } stem.groups.huge_mushroom = species_id stem.groups.huge_mushroom_stem = 1 + stem.groups.compostability = 65 minetest.register_node("mcl_mushrooms:"..color.."_mushroom_block_stem", stem) -- Mushroom block (cap) @@ -73,7 +80,7 @@ local register_mushroom = function(color, species_id, template, d_cap, d_stem, d block._doc_items_usagehelp = S("By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.") block.tiles = { "mcl_mushrooms_mushroom_block_skin_"..color..".png" } - block.on_construct = function(pos) + function block.on_construct(pos) local sides = { { { x= 0, y= 1, z= 0 }, 2 }, { { x= 0, y=-1, z= 0 }, 1 }, @@ -85,7 +92,7 @@ local register_mushroom = function(color, species_id, template, d_cap, d_stem, d -- Replace the side of a mushroom node. Returns the new node. -- Or nil, if unchanged. - local replace_side = function(pos, node, side) + local function replace_side(pos, node, side) local bin = string.sub(node.name, -6) if string.sub(bin, side, side) == "1" then local new_bin diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr index 647b36443..40b6644d1 100644 --- a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.fr.tr @@ -2,22 +2,22 @@ This decorative block is like a huge mushroom stem, but with the stem texture on all sides.=Ce bloc décoratif ressemble à une tige de champignon géant, mais avec la texture de la tige de tous les côtés. 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.=Blocs de champignons rouges géants sont les parties du chapeau d'énormes champignons rouges. Il se compose d'une peau rouge et peut avoir des pores sur chacun de ses côtés. The stem part of a huge red mushroom.=La partie tige d'un énorme champignon rouge. -Huge Red Mushroom Block=Bloc de Champignon Rouge Géant -Huge Red Mushroom Stem=Tige de Champignon Rouge Géant -Huge Red Mushroom All-Faces Stem=Tige de Champignon Rouge Géant avec Pores +Huge Red Mushroom Block=Bloc de champignon rouge géant +Huge Red Mushroom Stem=Tige de champignon gouge géant +Huge Red Mushroom All-Faces Stem=Tige de champignon rouge géant avec pores 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.=D'énormes blocs de champignons bruns sont les parties du chapeau d'énormes champignons bruns. Il se compose d'une peau brune et peut avoir des pores sur chacun de ses côtés. 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 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 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. Mushrooms will eventually uproot at a light level of 12 or higher. On mycelium or podzol, they survive and spread at any light level.=Les champignons finiront par déraciner à un niveau de lumière de 12 ou plus. Sur le mycélium ou le podzol, ils survivent et se propagent à n'importe quel niveau de lumière. 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.=Ce champignon peut être placé sur le mycélium et le podzol à n'importe quel niveau de lumière. Il peut également être placé sur des blocs à la fois solides et opaques, tant que le niveau de lumière pendant la journée n'est pas supérieur à 12. -Brown Mushroom=Champignon Marron -Red Mushroom=Champignon Rouge -Mushroom Stew=Ragoût de Champignon +Brown Mushroom=Champignon marron +Red Mushroom=Champignon rouge +Mushroom Stew=Ragoût de champignon Mushroom stew is a healthy soup which can be consumed to restore some hunger points.=Le ragoût de champignons est une soupe saine qui peut être consommée pour restaurer certains points de faim. By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.=En plaçant d'énormes blocs de champignons de la même espèce les uns à côté des autres, les côtés qui se touchent se transformeront en pores de façon permanente. Grows on podzol, mycelium and other blocks=Pousse sur podzol, mycélium et autres blocs diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr new file mode 100644 index 000000000..c0dd56daf --- /dev/null +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.ja.tr @@ -0,0 +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.=この種のキノコは、キノコの周囲の3×3×3キューブ内にある光度12以下のランダムな不透明固体ブロックに向かって、時間経過と共にゆっくりと広がっていきます。キノコの周囲9×3×9ブロックの範囲に同じ種のキノコが5個以上あると、拡散を止めます。 +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=ポドゾル、菌糸体、その他のブロックに生育 +Spreads in darkness=暗闇の中で拡散 diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.pl.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.pl.tr new file mode 100644 index 000000000..3a05b5fb0 --- /dev/null +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.pl.tr @@ -0,0 +1,24 @@ +# textdomain: mcl_mushrooms +This decorative block is like a huge mushroom stem, but with the stem texture on all sides.=Ten dekoracyjny blok jest jak łodyga grzyba, ale z teksturą łodygi na każdej stronie. +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.=Duże czerwone bloki grzybów to część kapelusza dużych czerwonych grzybów. Składają się z czerwonej skóry i mogą mieć pory na ścianach. +The stem part of a huge red mushroom.=Część łodygi dużego czerwonego grzyba. +Huge Red Mushroom Block=Blok dużego czerwonego grzyba +Huge Red Mushroom Stem=Łodyga dużego czerwonego grzyba +Huge Red Mushroom All-Faces Stem=Łodyga dużego czerwonego grzyba (wszystkie ściany) +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.=Duże brązowe bloki grzybów to część kapelusza dużych brązowych grzybów. Składają się z czerwonej skóry i mogą mieć pory na ścianach. +The stem part of a huge brown mushroom.=Część łodygi dużego brązowego grzyba. +Huge Brown Mushroom Block=Blok dużego brązowego grzyba +Huge Brown Mushroom Stem=Łodyga dużego brązowego grzyba +Huge Brown Mushroom All-Faces Stem=Łodyga dużego brązowego grzyba (wszystkie ściany) +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.=Brązowe grzyby to grzyby rosnące i rozprzestrzeniające się w ciemności i czułe na światło. Same są niejadalne, jednak można je wykorzystać do stworzenia jedzenia. +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.=Czerwone grzyby to grzyby rosnące i rozprzestrzeniające się w ciemności i czułe na światło. Same są niejadalne, jednak można je wykorzystać do stworzenia jedzenia. +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.=Pojedynczy grzyb tego gatunku będzie powoli rozrastał się na losowe, nieprzezroczyste, stałe bloki z poziomem oświetlenia 12 lub niższym w sześcianie 3×3×3 wokół grzyba. +Mushrooms will eventually uproot at a light level of 12 or higher. On mycelium or podzol, they survive and spread at any light level.=Grzyby po jakimś czasie obumrą w oświetlenie o poziomie 12 i wyższym. Na grzybni i bielicy przeżyją i będą się rozprzestrzeniać przy każdym poziomie oświetlenia. +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.=Ten grzyb może być postawiony na grzybni oraz bielicy przy dowolnym poziomie oświetlenia. Można go również postawić na dowolnym stałym, nieprzezroczystym bloku tylko jeśli poziom oświetlenia jest nie większy niż 12. +Brown Mushroom=Brązowy grzyb +Red Mushroom=Czerwony grzyb +Mushroom Stew=Zupa grzybowa +Mushroom stew is a healthy soup which can be consumed to restore some hunger points.=Zupa grzybowa jest zdrową zupą, którą można zjeść by odzyskać punkty głodu. +By placing huge mushroom blocks of the same species next to each other, the sides that touch each other will turn into pores permanently.=Kładą bloki dużych grzybów tego samego gatunku obok siebie, ich dotykające się boki zamienią się na stałe w pory. +Grows on podzol, mycelium and other blocks=Rośnie na bielicy, grzybni i innych blokach. +Spreads in darkness=Rozprzestrzenia się w ciemności diff --git a/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.zh_TW.tr b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.zh_TW.tr new file mode 100644 index 000000000..f4c6ba192 --- /dev/null +++ b/mods/ITEMS/mcl_mushrooms/locale/mcl_mushrooms.zh_TW.tr @@ -0,0 +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.=這個品種的單個蘑菇會隨著時間的推移,慢慢地向蘑菇周圍3×3×3立方體中光照度為12或更低的隨機固體不透明方塊擴散。當蘑菇周圍9×3×9塊的區域內有5個或更多相同種類的蘑菇時,它就會停止擴散。 +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=在灰壤,菌絲體和其他方塊上生長 +Spreads in darkness=在黑暗中擴散 diff --git a/mods/ITEMS/mcl_mushrooms/mod.conf b/mods/ITEMS/mcl_mushrooms/mod.conf index 64bbd8ca4..20f7bef16 100644 --- a/mods/ITEMS/mcl_mushrooms/mod.conf +++ b/mods/ITEMS/mcl_mushrooms/mod.conf @@ -1 +1,3 @@ name = mcl_mushrooms +depends = mcl_sounds, mcl_util +optional_depends = doc diff --git a/mods/ITEMS/mcl_mushrooms/small.lua b/mods/ITEMS/mcl_mushrooms/small.lua index 8105386f4..f6fbd2909 100644 --- a/mods/ITEMS/mcl_mushrooms/small.lua +++ b/mods/ITEMS/mcl_mushrooms/small.lua @@ -1,10 +1,9 @@ -local S = minetest.get_translator("mcl_mushrooms") +local S = minetest.get_translator(minetest.get_current_modname()) local on_place = mcl_util.generate_on_place_plant_function(function(place_pos, place_node) local soil_node = minetest.get_node_or_nil({x=place_pos.x, y=place_pos.y-1, z=place_pos.z}) if not soil_node then return false end local snn = soil_node.name -- soil node name - local sd = minetest.registered_nodes[snn] -- soil definition -- Placement rules: -- * Always allowed on podzol or mycelimu @@ -39,7 +38,11 @@ minetest.register_node("mcl_mushrooms:mushroom_brown", { sunlight_propagates = true, paramtype = "light", walkable = false, - groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, + groups = { + attached_node = 1, deco_block = 1, destroy_by_lava_flow = 1, + dig_immediate = 3, dig_by_water = 1, dig_by_piston = 1, + mushroom = 1, enderman_takable = 1, compostability = 65 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), light_source = 1, selection_box = { @@ -63,7 +66,11 @@ minetest.register_node("mcl_mushrooms:mushroom_red", { sunlight_propagates = true, paramtype = "light", walkable = false, - groups = {dig_immediate=3,mushroom=1,attached_node=1,dig_by_water=1,destroy_by_lava_flow=1,dig_by_piston=1,enderman_takable=1,deco_block=1}, + groups = { + attached_node = 1, deco_block = 1, destroy_by_lava_flow = 1, + dig_immediate = 3, dig_by_water = 1, dig_by_piston = 1, + mushroom = 1, enderman_takable = 1, compostability = 65 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), selection_box = { type = "fixed", @@ -88,7 +95,7 @@ minetest.register_craftitem("mcl_mushrooms:mushroom_stew", { minetest.register_craft({ type = "shapeless", output = "mcl_mushrooms:mushroom_stew", - recipe = {'mcl_core:bowl', 'mcl_mushrooms:mushroom_brown', 'mcl_mushrooms:mushroom_red'} + recipe = {"mcl_core:bowl", "mcl_mushrooms:mushroom_brown", "mcl_mushrooms:mushroom_red"} }) --[[ Mushroom spread and death diff --git a/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_brown.png b/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_brown.png deleted file mode 100644 index 37e1d11e8..000000000 Binary files a/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_red.png b/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_red.png deleted file mode 100644 index 5f9135863..000000000 Binary files a/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_inside.png b/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_inside.png deleted file mode 100644 index 06377fee8..000000000 Binary files a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_inside.png and /dev/null differ diff --git a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_brown.png b/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_brown.png deleted file mode 100644 index 65d27c4c2..000000000 Binary files a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/depends.txt b/mods/ITEMS/mcl_nether/depends.txt deleted file mode 100644 index 96f253aa0..000000000 --- a/mods/ITEMS/mcl_nether/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_core -mcl_sounds -mcl_util -walkover -mcl_death_messages? -doc_items -doc? -screwdriver? diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 026428db2..548bd90d5 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -1,7 +1,6 @@ -local S = minetest.get_translator("mcl_nether") +local S = minetest.get_translator(minetest.get_current_modname()) -local mod_death_messages = minetest.get_modpath("mcl_death_messages") -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil +local mod_screwdriver = minetest.get_modpath("screwdriver") local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way @@ -17,9 +16,9 @@ minetest.register_node("mcl_nether:glowstone", { drop = { max_items = 1, items = { - {items = {'mcl_nether:glowstone_dust 4'},rarity = 3}, - {items = {'mcl_nether:glowstone_dust 3'},rarity = 3}, - {items = {'mcl_nether:glowstone_dust 2'}}, + {items = {"mcl_nether:glowstone_dust 4"}, rarity = 3}, + {items = {"mcl_nether:glowstone_dust 3"}, rarity = 3}, + {items = {"mcl_nether:glowstone_dust 2"}}, } }, paramtype = "light", @@ -44,7 +43,7 @@ minetest.register_node("mcl_nether:quartz_ore", { tiles = {"mcl_nether_quartz_ore.png"}, is_ground_content = true, groups = {pickaxey=1, building_block=1, material_stone=1, xp=3}, - drop = 'mcl_nether:quartz', + drop = "mcl_nether:quartz", sounds = mcl_sounds.node_sound_stone_defaults(), _mcl_blast_resistance = 3, _mcl_hardness = 3, @@ -52,15 +51,44 @@ minetest.register_node("mcl_nether:quartz_ore", { _mcl_fortune_drop = mcl_core.fortune_drop_ore }) +minetest.register_node("mcl_nether:ancient_debris", { + description = S("Ancient Debris"), + _doc_items_longdesc = S("Ancient debris can be found in the nether and is very very rare."), + stack_max = 64, + tiles = {"mcl_nether_ancient_debris_top.png", "mcl_nether_ancient_debris_side.png"}, + is_ground_content = true, + groups = {pickaxey=4, building_block=1, material_stone=1, xp=0, blast_furnace_smeltable = 1}, + drop = "mcl_nether:ancient_debris", + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 1200, + _mcl_hardness = 30, + _mcl_silk_touch_drop = true +}) + +minetest.register_node("mcl_nether:netheriteblock", { + description = S("Netherite Block"), + _doc_items_longdesc = S("Netherite block is very hard and can be made of 9 netherite ingots."), + stack_max = 64, + tiles = {"mcl_nether_netheriteblock.png"}, + is_ground_content = true, + groups = { pickaxey=4, building_block=1, material_stone=1, xp = 0, fire_immune=1 }, + drop = "mcl_nether:netheriteblock", + sounds = mcl_sounds.node_sound_stone_defaults(), + _mcl_blast_resistance = 1200, + _mcl_hardness = 50, + _mcl_silk_touch_drop = true, +}) + -- For eternal fire on top of netherrack and magma blocks -- (this code does not require a dependency on mcl_fire) -local eternal_after_destruct = function(pos, oldnode) +local function eternal_after_destruct(pos, oldnode) pos.y = pos.y + 1 if minetest.get_node(pos).name == "mcl_fire:eternal_fire" then minetest.remove_node(pos) end end -local eternal_on_ignite = function(player, pointed_thing) + +local function eternal_on_ignite(player, pointed_thing) local pos = pointed_thing.under local flame_pos = {x = pos.x, y = pos.y + 1, z = pos.z} local fn = minetest.get_node(flame_pos) @@ -95,26 +123,24 @@ minetest.register_node("mcl_nether:netherrack", { minetest.register_node("mcl_nether:magma", { description = S("Magma Block"), - _tt_help = minetest.colorize("#FFFF00", S("Burns your feet")), + _tt_help = minetest.colorize(mcl_colors.YELLOW, S("Burns your feet")), _doc_items_longdesc = S("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."), stack_max = 64, tiles = {{name="mcl_nether_magma.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=1.5}}}, is_ground_content = true, light_source = 3, sunlight_propagates = false, - groups = {pickaxey=1, building_block=1, material_stone=1}, + groups = {pickaxey=1, building_block=1, material_stone=1, fire=1}, sounds = mcl_sounds.node_sound_stone_defaults(), -- From walkover mod on_walk_over = function(loc, nodeiamon, player) - if minetest.global_exists("mcl_potions") and mcl_potions.player_has_effect(player, "fire_proof") then + 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 return end -- Hurt players standing on top of this block if player:get_hp() > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 stood too long on a magma block.", player:get_player_name())) - end - player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" }) + mcl_util.deal_damage(player, 1, {type = "hot_floor"}) end end, _mcl_blast_resistance = 0.5, @@ -132,7 +158,7 @@ minetest.register_node("mcl_nether:soul_sand", { stack_max = 64, tiles = {"mcl_nether_soul_sand.png"}, is_ground_content = true, - groups = {handy=1,shovely=1, building_block=1,soil_nether_wart=1, material_sand=1}, + groups = {handy = 1, shovely = 1, building_block = 1, soil_nether_wart = 1, material_sand = 1, soul_block = 1 }, collision_box = { type = "fixed", fixed = { -0.5, -0.5, -0.5, 0.5, 0.5 - 2/16, 0.5 }, @@ -176,7 +202,7 @@ minetest.register_node("mcl_nether:nether_wart_block", { stack_max = 64, tiles = {"mcl_nether_nether_wart_block.png"}, is_ground_content = false, - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=7, swordy=1, building_block=1, compostability = 85}, sounds = mcl_sounds.node_sound_leaves_defaults( { footstep={name="default_dirt_footstep", gain=0.7}, @@ -253,6 +279,22 @@ minetest.register_craftitem("mcl_nether:quartz", { groups = { craftitem = 1 }, }) +minetest.register_craftitem("mcl_nether:netherite_scrap", { + description = S("Netherite Scrap"), + _doc_items_longdesc = S("Netherite scrap is a crafting ingredient for netherite ingots."), + inventory_image = "mcl_nether_netherite_scrap.png", + stack_max = 64, + groups = { craftitem = 1, fire_immune=1 }, +}) + +minetest.register_craftitem("mcl_nether:netherite_ingot", { + description = S("Netherite Ingot"), + _doc_items_longdesc = S("Netherite ingots can be used with a smithing table to upgrade items to netherite."), + inventory_image = "mcl_nether_netherite_ingot.png", + stack_max = 64, + groups = { craftitem = 1, fire_immune=1 }, +}) + minetest.register_craftitem("mcl_nether:netherbrick", { description = S("Nether Brick"), _doc_items_longdesc = S("Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences."), @@ -269,34 +311,41 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mcl_nether:quartz_block', + type = "cooking", + output = "mcl_nether:netherite_scrap", + recipe = "mcl_nether:ancient_debris", + cooktime = 10, +}) + +minetest.register_craft({ + output = "mcl_nether:quartz_block", recipe = { - {'mcl_nether:quartz', 'mcl_nether:quartz'}, - {'mcl_nether:quartz', 'mcl_nether:quartz'}, + {"mcl_nether:quartz", "mcl_nether:quartz"}, + {"mcl_nether:quartz", "mcl_nether:quartz"}, } }) minetest.register_craft({ - output = 'mcl_nether:quartz_pillar 2', + output = "mcl_nether:quartz_pillar 2", recipe = { - {'mcl_nether:quartz_block'}, - {'mcl_nether:quartz_block'}, + {"mcl_nether:quartz_block"}, + {"mcl_nether:quartz_block"}, } }) minetest.register_craft({ output = "mcl_nether:glowstone", recipe = { - {'mcl_nether:glowstone_dust', 'mcl_nether:glowstone_dust'}, - {'mcl_nether:glowstone_dust', 'mcl_nether:glowstone_dust'}, + {"mcl_nether:glowstone_dust", "mcl_nether:glowstone_dust"}, + {"mcl_nether:glowstone_dust", "mcl_nether:glowstone_dust"}, } }) minetest.register_craft({ output = "mcl_nether:magma", recipe = { - {'mcl_mobitems:magma_cream', 'mcl_mobitems:magma_cream'}, - {'mcl_mobitems:magma_cream', 'mcl_mobitems:magma_cream'}, + {"mcl_mobitems:magma_cream", "mcl_mobitems:magma_cream"}, + {"mcl_mobitems:magma_cream", "mcl_mobitems:magma_cream"}, } }) @@ -310,32 +359,59 @@ minetest.register_craft({ minetest.register_craft({ output = "mcl_nether:nether_brick", recipe = { - {'mcl_nether:netherbrick', 'mcl_nether:netherbrick'}, - {'mcl_nether:netherbrick', 'mcl_nether:netherbrick'}, + {"mcl_nether:netherbrick", "mcl_nether:netherbrick"}, + {"mcl_nether:netherbrick", "mcl_nether:netherbrick"}, } }) minetest.register_craft({ output = "mcl_nether:red_nether_brick", recipe = { - {'mcl_nether:nether_wart_item', 'mcl_nether:netherbrick'}, - {'mcl_nether:netherbrick', 'mcl_nether:nether_wart_item'}, + {"mcl_nether:nether_wart_item", "mcl_nether:netherbrick"}, + {"mcl_nether:netherbrick", "mcl_nether:nether_wart_item"}, } }) minetest.register_craft({ output = "mcl_nether:red_nether_brick", recipe = { - {'mcl_nether:netherbrick', 'mcl_nether:nether_wart_item'}, - {'mcl_nether:nether_wart_item', 'mcl_nether:netherbrick'}, + {"mcl_nether:netherbrick", "mcl_nether:nether_wart_item"}, + {"mcl_nether:nether_wart_item", "mcl_nether:netherbrick"}, } }) minetest.register_craft({ output = "mcl_nether:nether_wart_block", recipe = { - {'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item'}, - {'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item'}, - {'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item', 'mcl_nether:nether_wart_item'}, + {"mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item"}, + {"mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item"}, + {"mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item", "mcl_nether:nether_wart_item"}, + } +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_nether:netherite_ingot", + recipe = { + "mcl_nether:netherite_scrap", "mcl_nether:netherite_scrap", "mcl_nether:netherite_scrap", + "mcl_nether:netherite_scrap", "mcl_core:gold_ingot", "mcl_core:gold_ingot", + "mcl_core:gold_ingot", "mcl_core:gold_ingot", }, +}) + +minetest.register_craft({ + output = "mcl_nether:netheriteblock", + recipe = { + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"}, + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"}, + {"mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot", "mcl_nether:netherite_ingot"} + } +}) + +minetest.register_craft({ + output = "mcl_nether:netherite_ingot 9", + recipe = { + {"mcl_nether:netheriteblock", "", ""}, + {"", "", ""}, + {"", "", ""} } }) diff --git a/mods/ITEMS/mcl_nether/lava.lua b/mods/ITEMS/mcl_nether/lava.lua index da85b8e3c..035a50322 100644 --- a/mods/ITEMS/mcl_nether/lava.lua +++ b/mods/ITEMS/mcl_nether/lava.lua @@ -1,12 +1,6 @@ -- Lava in the Nether -local S = minetest.get_translator("mcl_nether") -local N = function(s) return s end - -local msg = { - N("@1 has become one with the lava."), - N("@1 has been consumed by the lava."), -} +local S = minetest.get_translator(minetest.get_current_modname()) -- TODO: Increase flow speed. This could be done by reducing viscosity, -- but this would also allow players to swim faster in lava. @@ -20,7 +14,6 @@ lava_src_def._doc_items_usagehelp = nil lava_src_def.liquid_range = 7 lava_src_def.liquid_alternative_source = "mcl_nether:nether_lava_source" lava_src_def.liquid_alternative_flowing = "mcl_nether:nether_lava_flowing" -lava_src_def._mcl_node_death_message = msg, minetest.register_node("mcl_nether:nether_lava_source", lava_src_def) local lava_flow_def = table.copy(minetest.registered_nodes["mcl_core:lava_flowing"]) @@ -29,7 +22,6 @@ lava_flow_def._doc_items_create_entry = false lava_flow_def.liquid_range = 7 lava_flow_def.liquid_alternative_flowing = "mcl_nether:nether_lava_flowing" lava_flow_def.liquid_alternative_source = "mcl_nether:nether_lava_source" -lava_flow_def._mcl_node_death_message = msg, minetest.register_node("mcl_nether:nether_lava_flowing", lava_flow_def) -- Add entry aliases for the Help diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr index bfa62488c..f81f381e2 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.de.tr @@ -38,5 +38,3 @@ Place this item on soul sand to plant it and watch it grow.=Platzieren Sie den G Burns your feet=Verbrennt Ihre Füße Grows on soul sand=Wächst auf Seelensand Reduces walking speed=Reduziert das Schritttempo -@1 has become one with the lava.=@1 wurde eins mit der Lava. -@1 has been consumed by the lava.=@1 wurde von der Lava verzehrt. diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr index 78b8a453e..70d8ca8e0 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.fr.tr @@ -1,42 +1,46 @@ # 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 qui abrite le Nether. +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 du Néantrack dans le 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.=Netherrack est un bloc de pierre qui abrite le Nether. Démarrer un feu sur ce bloc créera un feu éternel. +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 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 qu'ils n'aient une résistance au feu. Démarrer un feu sur ce bloc créera un feu éternel. +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 que marcher 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=Brique du Nether -Red Nether Brick Block=Brique Rouge 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 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 -A nether wart block is a purely decorative block made from nether wart.=Un bloc de verrue du Nether est un bloc purement décoratif fabriqué à partir de verrue 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 -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 incandescentes brisées. Il est principalement utilisé dans l'artisanat. +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=Bric 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 de fabrication pour la fabrication de blocs de briques et de clôtures du Nether. +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 +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 habite le Nether, elle se développe dans toutes les dimensions. -Premature Nether Wart (Stage 2)=Verrue du Néant prématurée (étape 2) -Premature Nether Wart (Stage 3)=Verrue du Néant prématurée (étape 3) -Mature Nether Wart=Verrue du Néant 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. Il est prêt à être récolté pour ses articles. +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. +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 +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 qui habitent le Nether. Ils peuvent être plantés sur du sable d'âme et se développer en 4 étapes. +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. Burns your feet=Vous brûle les pieds Grows on soul sand=Pousse sur le sable de l'âme Reduces walking speed=Réduit la vitesse de marche -@1 has become one with the lava.=@1 est devenu un avec la lave. -@1 has been consumed by the lava.=@1 a été consumé par la lave. \ No newline at end of file +Netherite Scrap=Fragments de netherite +Netherite Ingot=Lingot de netherite +Ancient Debris=Débris antiques +Ancient debris can be found in the nether and is very very rare.=Les débris antiques se trouvent dans le Nether et sont extrêmement rares. +Netherite Block=Bloc de netherite +Netherite block is very hard and can be made of 9 netherite ingots.=Les blocs de netherite sont très durs et peuvent être fabriqués à partir de 9 lingots de netherite. diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr new file mode 100644 index 000000000..3ba6bf9fe --- /dev/null +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.ja.tr @@ -0,0 +1,45 @@ +# textdomain: mcl_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.=ネザークォーツ鉱石は、ネザークォーツを含む鉱石です。ネザーの、ネザーラック周辺によく見られます。 +Netherrack=ネザーラック +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.=マグマブロックは高温の固体ブロックであり、その上に立つ者は、火耐性がない限りダメージを受けます。このブロック上で火を起こすと、永続的な炎が発生します。 +@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.=ソウルサンドはネザー由来のブロックです。ソウルサンド上ではゆっくりしか歩けません。ソウルサンドが氷や氷塊、スライムブロックの上にある場合、速度低下の効果が増幅されます。 +Nether Brick Block=ネザーレンガブロック +Red Nether Brick Block=赤いネザーレンガブロック +Nether Wart Block=ネザーウォートブロック +A nether wart block is a purely decorative block made from nether wart.=ネザーウォートブロックは、ネザーウォートを使った純粋な装飾用ブロックです。 +Block of Quartz=クォーツブロック +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.=ネザークォーツは、汎用性の高いクラフト材料です。 +Nether Brick=ネザーレンガ +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段階に分けてゆっくりと成長します(2段階目と3段階目の見た目は同じ)。ネザーウォートはネザーに生息しているものの、どこの次元でも成長します。 +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.=成熟したネザーウォートは、フルサイズに達し成長の止まった、ネザー由来の植物です。もうアイテムとして収穫可能です。 +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.=このアイテムをソウルサンドの上に置いて植えると、その成長を見ることができます。 +Burns your feet=足裏の火傷 +Grows on soul sand=ソウルサンドの上で育つ +Reduces walking speed=歩行速度 低下 +Netherite Scrap=ネザライトスクラップ +Netherite Ingot=ネザライトインゴット +Ancient Debris=古代の残骸 +Netherite Block=ネザライトブロック +Netherite block is very hard and can be made of 9 netherite ingots.=ネザライトブロックは、非常に硬く、9個のネザライトインゴットから作れます。 \ No newline at end of file diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.pl.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.pl.tr new file mode 100644 index 000000000..11edbe3d4 --- /dev/null +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.pl.tr @@ -0,0 +1,40 @@ +# textdomain: mcl_nether +Glowstone=Jasnogłaz +Glowstone is a naturally-glowing block which is home to the Nether.=Jasnogłaz jest naturalnie świecącym blokiem, występującym w Netherze. +Nether Quartz Ore=Ruda Netherowego kwarcu +Nether quartz ore is an ore containing nether quartz. It is commonly found around netherrack in the Nether.=Ruda Netherowego kwarcu jest rudą zawierającą Netherowy kwarc. Występuje często nieopodal skał Netheru. +Netherrack=Skała Netheru +Netherrack is a stone-like block home to the Nether. Starting a fire on this block will create an eternal fire.=Skała Netheru jest blokiem podobnym do kamienia występującym w Netherze. +Magma Block=Blok magmy +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.=Bloki magmy są gorącymi stałymi blokami, które ranią każdego kto na nich stanie, chyba, że mają odporność na ogień. Rozpalenie ognia na tym bloku stworzy wieczny ogień. +@1 stood too long on a magma block.=@1 zbyt długo stała na bloku magmy. +Soul Sand=Piasek dusz +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.=Piasek dusz jest blokiem z Netheru. Można na nim tylko chodzić powoli. Efekt spowolnienia jest mocniejszy gdy piasek dusz jest położony na lodzie, zbitym lodzi lub bloku szlamu. +Nether Brick Block=Blok Netherowych cegieł +Red Nether Brick Block=Blok czerwonych Netherowych cegieł +Nether Wart Block=Blok Netherowej brodawki +A nether wart block is a purely decorative block made from nether wart.=Blok Netherowej brodawki jest dekoracyjnym blokiem utworzonym z Netherowej brodawki. +Block of Quartz=Blok kwarcu +Chiseled Quartz Block=Rzeźbiony blok kwarcu +Pillar Quartz Block=Filarowy blok kwarcu +Smooth Quartz=Gładki kwarc +Glowstone Dust=Pył jasnogłazu +Glowstone dust is the dust which comes out of broken glowstones. It is mainly used in crafting.=Pył jasnogłazu to pył wyrzucany przez rozbite jasnogłazy. Jest głównie wykorzystywany w wytwarzaniu. +Nether Quartz=Netherowy kwarc +Nether quartz is a versatile crafting ingredient.=Netherowy kwarc jest wszechstronnym przedmiotem użytecznym w wytwarzaniu. +Nether Brick=Netherowa cegła +Nether bricks are the main crafting ingredient for crafting nether brick blocks and nether fences.=Netherowe cegły są głównym składnikiem do wytwarzania bloków Netherowej cegły oraz Netherowych ogrodzeń. +Nether Lava Source=Netherowe źródło lawy +Flowing Nether Lava=Płynąca Netherowa lawa +Premature Nether Wart (Stage 1)=Niedojrzała Netherowa brodawka (Etap 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.=Niedojrzała Netherowa brodawka to brodawka, która niedawno została zasadzona na piasku dusz. Netherowa brodawka rośnie na piasku dusz w 4 etapach (drugi i trzeci wyglądają identycznie). Pomimo tego, że brodawki te naturalnie występują tylko w Netherze, mogą one rosnąć w każdym wymiarze. +Premature Nether Wart (Stage 2)=Niedojrzała Netherowa brodawka (Etap 2) +Premature Nether Wart (Stage 3)=Niedojrzała Netherowa brodawka (Etap 3) +Mature Nether Wart=Dojrzała Netherowa brodawka +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.=Dojrzała Netherowa brodawka jest rośliną z Netheru, która osiągnęła swój maksymalny rozmiar i nie urośnie więcej. Jest gotowa do zebrania dla swojego zrzutu. +Nether Wart=Netherowa brodawka +Nether warts are plants home to the Nether. They can be planted on soul sand and grow in 4 stages.=Netherowe brodawki to rośliny występujące w Netherze. Mogą być posadzone na piasku dusz i wyrosną w 4 fazach. +Place this item on soul sand to plant it and watch it grow.=Postaw ten przedmiot na piasku dusz aby zasadzić go i patrz jak rośnie. +Burns your feet=Pali w stopy +Grows on soul sand=Rośnie na piasku dusz +Reduces walking speed=Zmniejsza prędkość poruszania diff --git a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr index 2cfdd370b..f546d16ca 100644 --- a/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr +++ b/mods/ITEMS/mcl_nether/locale/mcl_nether.ru.tr @@ -38,5 +38,3 @@ Place this item on soul sand to plant it and watch it grow.=Поместите Burns your feet=Обжигает ваши ноги Grows on soul sand=Растёт на песке душ Reduces walking speed=Уменьшает скорость ходьбы -@1 has become one with the lava.=@1 породнился(лась) с лавой. -@1 has been consumed by the lava.=@1 был(а) поглощен(а) лавой. diff --git a/mods/ITEMS/mcl_nether/locale/template.txt b/mods/ITEMS/mcl_nether/locale/template.txt index 7b5052166..de0fabcfb 100644 --- a/mods/ITEMS/mcl_nether/locale/template.txt +++ b/mods/ITEMS/mcl_nether/locale/template.txt @@ -38,5 +38,9 @@ Place this item on soul sand to plant it and watch it grow.= Burns your feet= Grows on soul sand= Reduces walking speed= -@1 has become one with the lava.= -@1 has been consumed by the lava.= +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.= diff --git a/mods/ITEMS/mcl_nether/mod.conf b/mods/ITEMS/mcl_nether/mod.conf index 2b6c641af..f5ffa61ac 100644 --- a/mods/ITEMS/mcl_nether/mod.conf +++ b/mods/ITEMS/mcl_nether/mod.conf @@ -1 +1,3 @@ name = mcl_nether +depends = mcl_core, mcl_sounds, mcl_util, walkover, doc_items, mcl_colors +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_nether/nether_wart.lua b/mods/ITEMS/mcl_nether/nether_wart.lua index 681abe094..f6eb0c03c 100644 --- a/mods/ITEMS/mcl_nether/nether_wart.lua +++ b/mods/ITEMS/mcl_nether/nether_wart.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator("mcl_nether") +local S = minetest.get_translator(minetest.get_current_modname()) + +local table = table minetest.register_node("mcl_nether:nether_wart_0", { description = S("Premature Nether Wart (Stage 1)"), @@ -108,6 +110,7 @@ minetest.register_craftitem("mcl_nether:nether_wart_item", { _doc_items_usagehelp = S("Place this item on soul sand to plant it and watch it grow."), inventory_image = "mcl_nether_nether_wart.png", wield_image = "mcl_nether_nether_wart.png", + groups = {craftitem = 1, brewitem = 1, compostability = 30}, on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" then return itemstack @@ -127,7 +130,7 @@ minetest.register_craftitem("mcl_nether:nether_wart_item", { -- Check for correct soil type local chk = minetest.get_item_group(minetest.get_node(soilpos).name, "soil_nether_wart") - if chk ~= 0 and chk ~= nil then + if chk and chk ~= 0 then -- Check if node above soil node allows placement if minetest.registered_items[minetest.get_node(placepos).name].buildable_to then -- Place nether wart @@ -141,7 +144,6 @@ minetest.register_craftitem("mcl_nether:nether_wart_item", { end end end, - groups = { craftitem = 1, brewitem=1 }, }) local names = {"mcl_nether:nether_wart_0", "mcl_nether:nether_wart_1", "mcl_nether:nether_wart_2"} diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_glowstone.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_glowstone.png deleted file mode 100644 index d42c9c9c5..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_glowstone.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_brick.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_brick.png deleted file mode 100644 index 43a1af1bb..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_brick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_2.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_2.png deleted file mode 100644 index 0478c760a..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherbrick.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherbrick.png deleted file mode 100644 index 9d8c32d85..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherbrick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherrack.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_netherrack.png deleted file mode 100644 index 43b978c43..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_netherrack.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_side.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_side.png deleted file mode 100644 index 2e522f8a4..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_top.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_top.png deleted file mode 100644 index 2e522f8a4..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_side.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_side.png deleted file mode 100644 index 6029dace3..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_top.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_top.png deleted file mode 100644 index a6bd32950..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_chiseled_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_ore.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_ore.png deleted file mode 100644 index ee9f5977e..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_ore.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_side.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_side.png deleted file mode 100644 index 32dd3d8c1..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_top.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_top.png deleted file mode 100644 index 1b6fe45b6..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_pillar_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_red_nether_brick.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_red_nether_brick.png deleted file mode 100644 index cd2182886..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_red_nether_brick.png and /dev/null differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_soul_sand.png b/mods/ITEMS/mcl_nether/textures/mcl_nether_soul_sand.png deleted file mode 100644 index dcde3812d..000000000 Binary files a/mods/ITEMS/mcl_nether/textures/mcl_nether_soul_sand.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/corals.lua b/mods/ITEMS/mcl_ocean/corals.lua index f3de5968e..338929a19 100644 --- a/mods/ITEMS/mcl_ocean/corals.lua +++ b/mods/ITEMS/mcl_ocean/corals.lua @@ -1,5 +1,5 @@ -local S = minetest.get_translator("mcl_ocean") -local mod_doc = minetest.get_modpath("doc") ~= nil +local S = minetest.get_translator(minetest.get_current_modname()) +local mod_doc = minetest.get_modpath("doc") local corals = { { "tube", S("Tube Coral Block"), S("Dead Tube Coral Block"), S("Tube Coral"), S("Dead Tube Coral"), S("Tube Coral Fan"), S("Dead Tube Coral Fan") }, @@ -265,7 +265,6 @@ minetest.register_abm({ if minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name ~= "mcl_core:water_source" then -- Find dead form (it's the same as the node's drop) local def = minetest.registered_nodes[node.name] - local dead if def then node.name = def.drop else diff --git a/mods/ITEMS/mcl_ocean/depends.txt b/mods/ITEMS/mcl_ocean/depends.txt deleted file mode 100644 index 66908e83d..000000000 --- a/mods/ITEMS/mcl_ocean/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_sounds -mcl_dye -doc? -doc_items? -screwdriver? diff --git a/mods/ITEMS/mcl_ocean/description.txt b/mods/ITEMS/mcl_ocean/description.txt deleted file mode 100644 index bff01f614..000000000 --- a/mods/ITEMS/mcl_ocean/description.txt +++ /dev/null @@ -1 +0,0 @@ -Ocean-related blocks and items (for the ocean temple). diff --git a/mods/ITEMS/mcl_ocean/init.lua b/mods/ITEMS/mcl_ocean/init.lua index 2a103b8d0..f723a1f3f 100644 --- a/mods/ITEMS/mcl_ocean/init.lua +++ b/mods/ITEMS/mcl_ocean/init.lua @@ -1,3 +1,5 @@ +mcl_ocean = {} + -- Prismarine (includes sea lantern) dofile(minetest.get_modpath(minetest.get_current_modname()).."/prismarine.lua") diff --git a/mods/ITEMS/mcl_ocean/kelp.lua b/mods/ITEMS/mcl_ocean/kelp.lua index 2e0dfe1a5..1084dfa77 100644 --- a/mods/ITEMS/mcl_ocean/kelp.lua +++ b/mods/ITEMS/mcl_ocean/kelp.lua @@ -1,71 +1,419 @@ -local S = minetest.get_translator("mcl_ocean") -local mod_doc = minetest.get_modpath("doc") ~= nil +-- TODO: whenever it becomes possible to fully implement kelp without the +-- plantlike_rooted limitation, please update accordingly. +-- +-- TODO: whenever it becomes possible to make kelp grow infinitely without +-- resorting to making intermediate kelp stem node, please update accordingly. +-- +-- TODO: In MC, you can't actually destroy kelp by bucket'ing water in the middle. +-- However, because of the plantlike_rooted hack, we'll just allow it for now. --- List of supported surfaces for seagrass and kelp -local surfaces = { - { "dirt", "mcl_core:dirt" }, - { "sand", "mcl_core:sand", 1 }, - { "redsand", "mcl_core:redsand", 1 }, - { "gravel", "mcl_core:gravel", 1 }, -} +local S = minetest.get_translator(minetest.get_current_modname()) +local mod_doc = minetest.get_modpath("doc") -local function get_kelp_top(pos, node) - local size = math.ceil(node.param2 / 16) - local pos_water = table.copy(pos) - pos_water.y = pos_water.y + size - return pos_water, minetest.get_node(pos_water) +-------------------------------------------------------------------------------- +-- local-ify runtime functions +-------------------------------------------------------------------------------- +-- objects +local mt_registered_items = minetest.registered_items +local mt_registered_nodes = minetest.registered_nodes + +-- functions +local mt_log = minetest.log +local mt_add_item = minetest.add_item +local mt_get_item_group = minetest.get_item_group +local mt_get_node = minetest.get_node +local mt_get_node_level = minetest.get_node_level +local mt_get_node_max_level = minetest.get_node_max_level +local mt_get_node_or_nil = minetest.get_node_or_nil +local mt_get_meta = minetest.get_meta +local mt_set_node = minetest.set_node +local mt_swap_node = minetest.swap_node +local mt_pos_to_string = minetest.pos_to_string +local mt_is_protected = minetest.is_protected +local mt_record_protection_violation = minetest.record_protection_violation + +local mt_is_creative_enabled = minetest.is_creative_enabled +local mt_sound_play = minetest.sound_play + +local math = math +--local string = string +local table = table + +-- DEBUG: functions +-- local log = minetest.log +-- local chatlog = minetest.chat_send_all + +-------------------------------------------------------------------------------- +-- Kelp API +-------------------------------------------------------------------------------- + +local kelp = {} +mcl_ocean.kelp = kelp + +-- Once reach the maximum, kelp no longer grows. +kelp.MIN_AGE = 0 +kelp.MAX_AGE = 25 + +kelp.TICK = 0.2 -- Tick interval (in seconds) for updating kelp. + +-- The average amount of growth for kelp in a day is 2.16 (https://youtu.be/5Bp4lAjAk3I) +-- Normally, a day lasts 20 minutes, meaning kelp.next_grow() is executed +-- 1200 / TICK times. Per tick probability = (216/100) / (1200/TICK) +-- NOTE: currently, we can't exactly use the same type of randomness MC does, because +-- it has multiple complicated sets of PRNGs. +-- NOTE: Small loss of precision, should be 10 to preserve it. +-- kelp.ROLL_GROWTH_PRECISION = 10 +-- kelp.ROLL_GROWTH_NUMERATOR = 216 * kelp.TICK * kelp.ROLL_GROWTH_PRECISION +-- kelp.ROLL_GROWTH_DENOMINATOR = 100 * 1200 * kelp.ROLL_GROWTH_PRECISION +kelp.ROLL_GROWTH_PRECISION = 1 +kelp.ROLL_GROWTH_NUMERATOR = 216 * kelp.TICK +kelp.ROLL_GROWTH_DENOMINATOR = 100 * 1200 + +-- Sounds used to dig and place kelp. +kelp.leaf_sounds = mcl_sounds.node_sound_leaves_defaults() + +-- is age in the growable range? +function kelp.is_age_growable(age) + return age >= 0 and age < kelp.MAX_AGE end -local function get_submerged(node_water) - local def_water = minetest.registered_nodes[node_water.name] - -- Submerged in water? - if minetest.get_item_group(node_water.name, "water") then - if def_water.liquidtype == "source" then - return "source" - elseif def_water.liquidtype == "flowing" then - return "flowing" - end + +-- Is this water? +-- Returns the liquidtype, if indeed water. +function kelp.is_submerged(node) + if mt_get_item_group(node.name, "water") ~= 0 then + -- Expected only "source" and "flowing" from water liquids + return mt_registered_nodes[node.name].liquidtype end return false end -local function grow_param2_step(param2, snap_into_grid) - local old_param2 = param2 - param2 = param2 + 16 - if param2 > 240 then - param2 = 240 + +-- Is the water downward flowing? +-- (kelp can grow/be placed inside downward flowing water) +function kelp.is_downward_flowing(pos, node, pos_above, node_above, __is_above__) + -- Function params: (pos[, node]) or (node, pos_above) or (node, node_above) + local node = node or mt_get_node(pos) + + local result = (math.floor(node.param2 / 8) % 2) == 1 + if not (result or __is_above__) then + -- If not, also check node above. + -- (this is needed due a weird quirk in the definition of "downwards flowing" + -- liquids in Minetest) + local pos_above = pos_above or {x=pos.x,y=pos.y+1,z=pos.z} + local node_above = node_above or mt_get_node(pos_above) + result = kelp.is_submerged(node_above) + or kelp.is_downward_flowing(nil, node_above, nil, nil, true) end - if snap_into_grid and (param2 % 16 ~= 0) then - param2 = param2 - (param2 % 16) - end - return param2, param2 ~= old_param2 + return result end -local function kelp_check_place(pos_above, node_above, def_above) - if minetest.get_item_group(node_above.name, "water") == 0 then + +-- Will node fall at that position? +-- This only checks if a node would fall, meaning that node need not be at pos. +function kelp.is_falling(pos, node, is_falling, pos_bottom, node_bottom, def_bottom) + -- Optional params: is_falling, pos_bottom, node_bottom, def_bottom + + -- NOTE: Modified from check_single_for_falling in builtin. + -- Please update accordingly. + local nodename = node.name + + if is_falling == false or + is_falling == nil and mt_get_item_group(nodename, "falling_node") == 0 then return false end - local can_place = false - if (def_above.liquidtype == "source") then - can_place = true - elseif (def_above.liquidtype == "flowing") then - -- Check if bit 3 (downwards flowing) is set - can_place = (math.floor(node_above.param2 / 8) % 2) == 1 - if not can_place then - -- If not, also check node above (this is needed due a weird quirk in the definition of - -- "downwards flowing" liquids in Minetest) - local node_above_above = minetest.get_node({x=pos_above.x,y=pos_above.y+1,z=pos_above.z}) - local naa_def = minetest.registered_nodes[node_above_above.name] - can_place = naa_def.liquidtype == "source" - if not can_place then - can_place = (naa_def.liquidtype == "flowing") and ((math.floor(node_above_above.param2 / 8) % 2) == 1) - end - end + + local pos_bottom = pos_bottom or {x = pos.x, y = pos.y - 1, z = pos.z} + -- get_node_or_nil: Only fall if node below is loaded + local node_bottom = node_bottom or mt_get_node_or_nil(pos_bottom) + local nodename_bottom = node_bottom.name + local def_bottom = def_bottom or node_bottom and mt_registered_nodes[nodename_bottom] + if not def_bottom then + return false end - return can_place + + local same = nodename == nodename_bottom + -- Let leveled nodes fall if it can merge with the bottom node + if same and def_bottom.paramtype2 == "leveled" and + mt_get_node_level(pos_bottom) < + mt_get_node_max_level(pos_bottom) then + return true + end + + -- Otherwise only if the bottom node is considered "fall through" + if not same and + (not def_bottom.walkable or def_bottom.buildable_to) and + (mt_get_item_group(nodename, "float") == 0 or + def_bottom.liquidtype == "none") then + return true + end + + return false end -local function kelp_on_place(itemstack, placer, pointed_thing) + +-- Roll whether to grow kelp or not. +function kelp.roll_growth(numerator, denominator) + -- Optional params: numerator, denominator + --return math.random(denominator or kelp.ROLL_GROWTH_DENOMINATOR) <= (numerator or kelp.ROLL_GROWTH_NUMERATOR) + return true -- probability done by ABM +end + + +-- Roll initial age for kelp. +function kelp.roll_init_age(min, max) + -- Optional params + return math.random(min or kelp.MIN_AGE, (max or kelp.MAX_AGE)-1) +end + + +-- Converts param2 to kelp height. +-- For the special case where the max param2 is reached, interpret that as the +-- 16th kelp stem. +function kelp.get_height(param2) + return math.floor(param2 / 16) + math.floor(param2 % 16 / 8) +end + + +-- Obtain pos and node of the tip of kelp. +function kelp.get_tip(pos, height) + -- Optional params: height + local height = height or kelp.get_height(mt_get_node(pos).param2) + local pos_tip = {x=pos.x, y=pos.y+height+1, z=pos.z} + return pos_tip, mt_get_node(pos_tip), height +end + + +-- Obtain position of the first kelp unsubmerged. +function kelp.find_unsubmerged(pos, node, height) + -- Optional params: node, height + local node = node or mt_get_node(pos) + local height = height or ((node.param2 >= 0 and node.param2 < 16) and 1) or kelp.get_height(node.param2) + + local walk_pos = {x=pos.x, z=pos.z} + local y = pos.y + for i=1,height do + walk_pos.y = y + i + local walk_node = mt_get_node(walk_pos) + if not kelp.is_submerged(walk_node) then + return walk_pos, walk_node, height, i + end + end + return nil, nil, height, height +end + + +-- Obtain next param2. +function kelp.next_param2(param2) + -- param2 max value is 255, so adding to 256 causes overflow. + return math.min(param2+16 - param2 % 16, 255); +end + +local function store_age (pos, age) + if pos then + --minetest.log("age: ".. tostring(age) .. ", pos: ".. mt_pos_to_string(pos)) + mt_get_meta(pos):set_int("mcl_ocean:kelp_age", age) + end +end + +local function retrieve_age (pos) + local meta = mt_get_meta(pos) + local age_set = meta:contains("mcl_ocean:kelp_age") + if not age_set then + return nil + end + + local age = meta:get_int("mcl_ocean:kelp_age") + --minetest.log("age: " .. tostring(age)) + return age +end + +-- Initialise a kelp's age. +function kelp.init_age(pos) + -- Watched params: pos + -- Optional params: age, from_lbm + + local age = retrieve_age(pos) + + if not age then + age = kelp.roll_init_age() + --minetest.log("no kelp age set so init with: " .. tostring(new_age)) + store_age(pos, age) + else + --minetest.log("stored_age: " .. tostring(age)) + end + + return age +end + +-- Apply next kelp height. The surface is swapped. so on_construct is skipped. +function kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing) + -- Modified params: node + -- Optional params: node, set_node, pos_tip, node_tip, submerged, downward_flowing + local node = node or mt_get_node(pos) + local pos_tip = pos_tip + local node_tip = node_tip or (pos_tip and mt_get_node(pos_tip)) + if not pos_tip then + pos_tip,node_tip = kelp.get_tip(pos) + end + local downward_flowing = downward_flowing or + (submerged or kelp.is_submerged(node_tip) + and kelp.is_downward_flowing(pos_tip, node_tip)) + + -- Liquid source: Grow normally. + node.param2 = kelp.next_param2(node.param2) + mt_swap_node(pos, node) + + -- 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 + mt_set_node(pos_tip, {name=alt_liq}) + end + end + + return node, pos_tip, node_tip, submerged, downward_flowing +end + + +-- Grow next kelp. +function kelp.next_grow(age, pos, node, pos_tip, node_tip, submerged, downward_flowing) + -- Watched params: pos + -- Modified params: node + -- Optional params: node, pos_tip, node_tip, submerged, downward_flowing + local node = node or mt_get_node(pos) + local pos_tip = pos_tip + local node_tip = node_tip or (pos_tip and mt_get_node(pos_tip)) + if not pos_tip then + pos_tip,node_tip = kelp.get_tip(pos) + end + + -- New kelp must also be submerged in water. + local downward_flowing = downward_flowing or kelp.is_downward_flowing(pos_tip, node_tip) + if not (submerged or kelp.is_submerged(node_tip)) then + return + end + + kelp.next_height(pos, node, pos_tip, node_tip, submerged, downward_flowing) + store_age(pos, age) + return true, node, pos_tip, node_tip, submerged, downward_flowing +end + + +-- Drops the items for detached kelps. +function kelp.detach_drop(pos, height) + -- Optional params: height + local height = height or kelp.get_height(mt_get_node(pos).param2) + local y = pos.y + local walk_pos = {x=pos.x, z=pos.z} + for i=1,height do + walk_pos.y = y+i + mt_add_item(walk_pos, "mcl_ocean:kelp") + end + return true +end + + +-- Detach the kelp at dig_pos, and drop their items. +-- Synonymous to digging the kelp. +-- NOTE: this is intended for whenever kelp truly becomes segmented plants +-- instead of rooted to the floor. Don't try to remove dig_pos. +function kelp.detach_dig(dig_pos, pos, drop, node, height) + -- Optional params: drop, node, height + + local node = node or mt_get_node(pos) + local height = height or kelp.get_height(node.param2) + -- pos.y points to the surface, offset needed to point to the first kelp. + local new_height = dig_pos.y - (pos.y+1) + + -- Digs the entire kelp. + if new_height <= 0 then + if drop then + kelp.detach_drop(dig_pos, height) + end + mt_set_node(pos, { + name=mt_registered_nodes[node.name].node_dig_prediction, + param=node.param, + param2=0 }) + + -- Digs the kelp beginning at a height. + else + if drop then + kelp.detach_drop(dig_pos, height - new_height) + end + mt_swap_node(pos, {name=node.name, param=node.param, param2=16*new_height}) + end +end + + +-------------------------------------------------------------------------------- +-- Kelp callback functions +-------------------------------------------------------------------------------- + +function kelp.surface_on_dig(pos, node, digger) + kelp.detach_dig(pos, pos, true, node) +end + +function kelp.surface_after_dig_node(pos, node) + return mt_set_node(pos, {name=minetest.registered_nodes[node.name].node_dig_prediction}) +end + + +local function detach_unsubmerged(pos) + local node = mt_get_node(pos) + + local dig_pos,_, height = kelp.find_unsubmerged(pos, node) + if dig_pos then + mt_sound_play(mt_registered_nodes[node.name].sounds.dug, { gain = 0.5, pos = dig_pos }, true) + kelp.detach_dig(dig_pos, pos, true, node, height) + local new_age = kelp.roll_init_age() + store_age(pos, new_age) + end +end + +local function grow_kelp (pos) + local node = mt_get_node(pos) + local age = retrieve_age(pos) + + if not age then + --minetest.log("init a new age as not set: " .. mt_pos_to_string(pos)) + age = kelp.init_age(pos) + end + + if kelp.is_age_growable(age) then + --minetest.log("age growable: ".. tostring(age) .. ", pos: ".. mt_pos_to_string(pos)) + kelp.next_grow(age+1, pos, node) + else + --minetest.log("age not: ".. tostring(age) .. ", pos: ".. mt_pos_to_string(pos)) + end +end + +function kelp.surface_on_construct(pos) + --minetest.log("on construct kelp called") + kelp.init_age(pos) +end + + +function kelp.surface_on_destruct(pos) + local node = mt_get_node(pos) + + -- on_falling callback. Activated by pistons for falling nodes too. + -- I'm not sure this works. I think piston digs water and the unsubmerged nature drops kelp. + if kelp.is_falling(pos, node) then + kelp.detach_drop(pos, kelp.get_height(node.param2)) + end +end + + + +function kelp.surface_on_mvps_move(pos, node, oldpos, nodemeta) + -- Pistons moving falling nodes will have already activated on_falling callback. + --minetest.log("kelp.surface_on_mvps_move: " .. mt_pos_to_string(pos)) + kelp.detach_dig(pos, pos, mt_get_item_group(node.name, "falling_node") ~= 1, node) +end + + +function kelp.kelp_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then return itemstack end @@ -73,183 +421,222 @@ local function kelp_on_place(itemstack, placer, pointed_thing) local player_name = placer:get_player_name() local pos_under = pointed_thing.under local pos_above = pointed_thing.above - local node_under = minetest.get_node(pos_under) - local node_above = minetest.get_node(pos_above) - local def_under = minetest.registered_nodes[node_under.name] - local def_above = minetest.registered_nodes[node_above.name] + local node_under = mt_get_node(pos_under) + local nu_name = node_under.name + local def_under = mt_registered_nodes[nu_name] + -- Allow rightclick to override place. if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, placer, itemstack, pointed_thing) or itemstack end - if minetest.is_protected(pos_under, player_name) or - minetest.is_protected(pos_above, player_name) then - minetest.log("action", player_name + -- Protection + if mt_is_protected(pos_under, player_name) or + mt_is_protected(pos_above, player_name) then + mt_log("action", player_name .. " tried to place " .. itemstack:get_name() .. " at protected position " - .. minetest.pos_to_string(pos_under)) - minetest.record_protection_violation(pos_under, player_name) + .. mt_pos_to_string(pos_under)) + mt_record_protection_violation(pos_under, player_name) return itemstack end - local grow_kelp = false - -- Select a kelp node when placed on surface node - if node_under.name == "mcl_core:dirt" then - node_under.name = "mcl_ocean:kelp_dirt" - elseif node_under.name == "mcl_core:sand" then - node_under.name = "mcl_ocean:kelp_sand" - elseif node_under.name == "mcl_core:redsand" then - node_under.name = "mcl_ocean:kelp_redsand" - elseif node_under.name == "mcl_core:gravel" then - node_under.name = "mcl_ocean:kelp_gravel" - elseif minetest.get_item_group(node_under.name, "kelp") == 1 then - -- Place kelp on kelp = grow kelp by 1 node length - node_under.param2, grow_kelp = grow_param2_step(node_under.param2) - if not grow_kelp then - return itemstack - end - else + + local pos_tip, node_tip, def_tip, new_surface, height + -- Kelp must also be placed on the top/tip side of the surface/kelp + if pos_under.y >= pos_above.y then return itemstack end - local submerged = false - if grow_kelp then - -- Kelp placed on kelp ... - -- Kelp can be placed on top of another kelp to make it grow - if pos_under.y >= pos_above.y or pos_under.x ~= pos_above.x or pos_under.z ~= pos_above.z then - -- Placed on side or below node, abort - return itemstack - end - -- New kelp top must also be submerged in water - local top_pos, top_node = get_kelp_top(pos_under, node_under) - local top_def = minetest.registered_nodes[top_node.name] - submerged = kelp_check_place(top_pos, top_node, top_def) - if not submerged then - -- Not submerged in water, abort - return itemstack - end + + -- When placed on kelp. + if mt_get_item_group(nu_name, "kelp") == 1 then + height = kelp.get_height(node_under.param2) + pos_tip,node_tip = kelp.get_tip(pos_under, height) + def_tip = mt_registered_nodes[node_tip.name] + + -- When placed on surface. else - -- New kelp placed ... - if pos_under.y >= pos_above.y then - -- Placed on side or below node, abort + new_surface = false + for _,surface in pairs(kelp.surfaces) do + if nu_name == surface.nodename then + node_under.name = "mcl_ocean:kelp_" ..surface.name + node_under.param2 = 0 + new_surface = true + break + end + end + -- Surface must support kelp + if not new_surface then return itemstack end - -- Kelp can be placed inside a water source or water flowing downwards on top of a surface node - local can_place = kelp_check_place(pos_above, node_above, def_above) - if not can_place then - return itemstack - end - node_under.param2 = minetest.registered_items[node_under.name].place_param2 or 16 + + pos_tip = pos_above + node_tip = mt_get_node(pos_above) + def_tip = mt_registered_nodes[node_tip.name] + height = 0 end - -- Place or grow kelp - local def_node = minetest.registered_items[node_under.name] + + -- Next kelp must also be submerged in water. + local downward_flowing = kelp.is_downward_flowing(pos_tip, node_tip) + local submerged = kelp.is_submerged(node_tip) + if not submerged then + return itemstack + end + + -- Play sound, place surface/kelp and take away an item + local def_node = mt_registered_items[nu_name] if def_node.sounds then - minetest.sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) + mt_sound_play(def_node.sounds.place, { gain = 0.5, pos = pos_under }, true) end - minetest.set_node(pos_under, node_under) - if not minetest.is_creative_enabled(player_name) then + -- TODO: get rid of rooted plantlike hack + if height < 16 then + kelp.next_height(pos_under, node_under, pos_tip, node_tip, def_tip, submerged, downward_flowing) + else + mt_add_item(pos_tip, "mcl_ocean:kelp") + end + if not mt_is_creative_enabled(player_name) then itemstack:take_item() end + kelp.init_age(pos_under) + return itemstack end -local get_kelp_height = function(param2) - return math.floor(param2 / 16) +function kelp.lbm_register(pos) + kelp.init_age(pos) end +-------------------------------------------------------------------------------- +-- Kelp registration API +-------------------------------------------------------------------------------- + +-- List of supported surfaces for seagrass and kelp. +kelp.surfaces = { + { name="dirt", nodename="mcl_core:dirt", }, + { name="sand", nodename="mcl_core:sand", }, + { name="redsand", nodename="mcl_core:redsand", }, + { name="gravel", nodename="mcl_core:gravel", }, +} +kelp.registered_surfaces = {} + +-- Commented properties are the ones obtained using register_kelp_surface. +-- If you define your own properties, it overrides the default ones. +kelp.surface_deftemplate = { + drawtype = "plantlike_rooted", + paramtype = "light", + paramtype2 = "leveled", + place_param2 = 16, + --tiles = def.tiles, + special_tiles = { + { + image = "mcl_ocean_kelp_plant.png", + animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}, + tileable_vertical = true, + } + }, + --inventory_image = "("..def.tiles[1]..")^mcl_ocean_kelp_item.png", + wield_image = "mcl_ocean_kelp_item.png", + selection_box = { + type = "fixed", + fixed = { + { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, + { -0.5, 0.5, -0.5, 0.5, 1.5, 0.5 }, + }, + }, + -- groups.falling_node = is_falling, + groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, }, + --sounds = sounds, + --node_dig_prediction = nodename, + on_construct = kelp.surface_on_construct, + on_destruct = kelp.surface_on_destruct, + on_dig = kelp.surface_on_dig, + after_dig_node = kelp.surface_after_dig_node, + mesecon = { on_mvps_move = kelp.surface_on_mvps_move, }, + drop = "", -- drops are handled in on_dig + --_mcl_falling_node_alternative = is_falling and nodename or nil, + _mcl_hardness = 0, + _mcl_blast_resistance = 0, +} + +-- Commented properties are the ones obtained using register_kelp_surface. +kelp.surface_docs = { + -- entry_id_orig = nodename, + _doc_items_entry_name = S("Kelp"), + _doc_items_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel."), + --_doc_items_create_entry = doc_create, + _doc_items_image = "mcl_ocean_kelp_item.png", +} + +-- Creates new surfaces. +-- NOTE: surface_deftemplate will be modified in-place. +function kelp.register_kelp_surface(surface, surface_deftemplate, surface_docs) + local name = surface.name + local nodename = surface.nodename + local def = mt_registered_nodes[nodename] + local def_tiles = def.tiles + + local surfacename = "mcl_ocean:kelp_"..name + local surface_deftemplate = surface_deftemplate or kelp.surface_deftemplate -- Optional param + + local doc_create = surface.doc_create or false + local surface_docs = surface_docs or kelp.surface_docs -- Optional param + + if doc_create then + surface_deftemplate._doc_items_entry_name = surface_docs._doc_items_entry_name + surface_deftemplate._doc_items_longdesc = surface_docs._doc_items_longdesc + surface_deftemplate._doc_items_create_entry = true + surface_deftemplate._doc_items_image = surface_docs._doc_items_image + -- Sets the first surface as the docs' entry ID + if not surface_docs.entry_id_orig then + surface_docs.entry_id_orig = nodename + end + elseif mod_doc then + doc.add_entry_alias("nodes", surface_docs.entry_id_orig, "nodes", surfacename) + end + + local sounds = table.copy(def.sounds) + sounds.dig = kelp.leaf_sounds.dig + sounds.dug = kelp.leaf_sounds.dug + sounds.place = kelp.leaf_sounds.place + + surface_deftemplate.tiles = surface_deftemplate.tiles or def_tiles + surface_deftemplate.inventory_image = surface_deftemplate.inventory_image or "("..def_tiles[1]..")^mcl_ocean_kelp_item.png" + surface_deftemplate.sounds = surface_deftemplate.sound or sounds + local falling_node = mt_get_item_group(nodename, "falling_node") + surface_deftemplate.node_dig_prediction = surface_deftemplate.node_dig_prediction or nodename + surface_deftemplate.groups.falling_node = surface_deftemplate.groups.falling_node or falling_node + surface_deftemplate._mcl_falling_node_alternative = surface_deftemplate._mcl_falling_node_alternative or (falling_node and nodename or nil) + + minetest.register_node(surfacename, surface_deftemplate) +end + +-- Kelp surfaces nodes --------------------------------------------------------- + +-- Dirt must be registered first, for the docs +kelp.register_kelp_surface(kelp.surfaces[1], table.copy(kelp.surface_deftemplate), kelp.surface_docs) +for i=2, #kelp.surfaces do + kelp.register_kelp_surface(kelp.surfaces[i], table.copy(kelp.surface_deftemplate), kelp.surface_docs) +end + +-- Kelp item ------------------------------------------------------------------- + minetest.register_craftitem("mcl_ocean:kelp", { description = S("Kelp"), _tt_help = S("Grows in water on dirt, sand, gravel"), _doc_items_create_entry = false, inventory_image = "mcl_ocean_kelp_item.png", wield_image = "mcl_ocean_kelp_item.png", - on_place = kelp_on_place, - groups = { deco_block = 1 }, + on_place = kelp.kelp_on_place, + groups = {deco_block = 1, compostability = 30, smoker_cookable = 1}, }) --- Kelp nodes: kelp on a surface node - -for s=1, #surfaces do - local def = minetest.registered_nodes[surfaces[s][2]] - local alt - if surfaces[s][3] == 1 then - alt = surfaces[s][2] - end - local sounds = table.copy(def.sounds) - local leaf_sounds = mcl_sounds.node_sound_leaves_defaults() - sounds.dig = leaf_sounds.dig - sounds.dug = leaf_sounds.dug - sounds.place = leaf_sounds.place - local tt_help, doc_longdesc, doc_img, desc - if surfaces[s][1] == "dirt" then - doc_longdesc = S("Kelp grows inside water on top of dirt, sand or gravel.") - desc = S("Kelp") - doc_create = true - doc_img = "mcl_ocean_kelp_item.png" - else - doc_create = false - end - minetest.register_node("mcl_ocean:kelp_"..surfaces[s][1], { - _doc_items_entry_name = desc, - _doc_items_longdesc = doc_longdesc, - _doc_items_create_entry = doc_create, - _doc_items_image = doc_img, - drawtype = "plantlike_rooted", - paramtype = "light", - paramtype2 = "leveled", - place_param2 = 16, - tiles = def.tiles, - special_tiles = { - { - image = "mcl_ocean_kelp_plant.png", - animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}, - tileable_vertical = true, - } - }, - inventory_image = "("..def.tiles[1]..")^mcl_ocean_kelp_item.png", - wield_image = "mcl_ocean_kelp_item.png", - selection_box = { - type = "fixed", - fixed = { - { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, - { -0.5, 0.5, -0.5, 0.5, 1.5, 0.5 }, - }, - }, - groups = { dig_immediate = 3, deco_block = 1, plant = 1, kelp = 1, falling_node = surfaces[s][3] }, - sounds = sounds, - node_dig_prediction = surfaces[s][2], - after_dig_node = function(pos) - minetest.set_node(pos, {name=surfaces[s][2]}) - end, - on_dig = function(pos, node, digger) - -- Drop kelp as item; item count depends on height - local dname = "" - if digger then - dname = digger:get_player_name() - end - local creative = minetest.is_creative_enabled(dname) - if not creative then - minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_ocean:kelp "..get_kelp_height(node.param2)) - end - minetest.node_dig(pos, node, digger) - end, - drop = "", -- drops are handled in on_dig - _mcl_falling_node_alternative = alt, - _mcl_hardness = 0, - _mcl_blast_resistance = 0, - }) - - if mod_doc and surfaces[s][1] ~= "dirt" then - doc.add_entry_alias("nodes", "mcl_ocean:kelp_dirt", "nodes", "mcl_ocean:kelp_"..surfaces[s][1]) - end -end - if mod_doc then - doc.add_entry_alias("nodes", "mcl_ocean:kelp_dirt", "craftitems", "mcl_ocean:kelp") + doc.add_entry_alias("nodes", kelp.surface_docs.entry_id_orig, "craftitems", "mcl_ocean:kelp") end --- Dried kelp stuff +-- Dried kelp ------------------------------------------------------------------ -- TODO: This is supposed to be eaten very fast minetest.register_craftitem("mcl_ocean:dried_kelp", { @@ -257,31 +644,33 @@ minetest.register_craftitem("mcl_ocean:dried_kelp", { _doc_items_longdesc = S("Dried kelp is a food item."), inventory_image = "mcl_ocean_dried_kelp.png", wield_image = "mcl_ocean_dried_kelp.png", - groups = { food = 2, eatable = 1 }, + groups = {food = 2, eatable = 1, compostability = 30}, on_place = minetest.item_eat(1), on_secondary_use = minetest.item_eat(1), - groups = { food = 2, eatable = 1 }, _mcl_saturation = 0.6, }) -local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil + +local mod_screwdriver = minetest.get_modpath("screwdriver") local on_rotate if mod_screwdriver then on_rotate = screwdriver.rotate_3way end - minetest.register_node("mcl_ocean:dried_kelp_block", { description = S("Dried Kelp Block"), _doc_items_longdesc = S("A decorative block that serves as a great furnace fuel."), tiles = { "mcl_ocean_dried_kelp_top.png", "mcl_ocean_dried_kelp_bottom.png", "mcl_ocean_dried_kelp_side.png" }, - groups = { handy = 1, building_block = 1, flammable = 2, fire_encouragement = 30, fire_flammability = 60 }, + groups = { + handy = 1, hoey = 1, building_block = 1, compostability = 50, + flammable = 2, fire_encouragement = 30, fire_flammability = 60 + }, sounds = mcl_sounds.node_sound_leaves_defaults(), paramtype2 = "facedir", on_place = mcl_util.rotate_axis, on_rotate = on_rotate, _mcl_hardness = 0.5, - _mcl_blast_resistance = 12.5, + _mcl_blast_resistance = 2.5, }) minetest.register_craft({ @@ -310,32 +699,41 @@ minetest.register_craft({ burntime = 200, }) --- Grow kelp +-------------------------------------------------------------------------------- +-- Kelp ABM + LBM's +-------------------------------------------------------------------------------- + + +minetest.register_lbm({ + label = "Kelp initialise", + name = "mcl_ocean:kelp_init_83", + nodenames = { "group:kelp" }, + run_at_every_load = false, -- so old kelps are also initialised + action = kelp.lbm_register, +}) + +minetest.register_abm({ + label = "Kelp drops", + nodenames = { "group:kelp" }, + interval = 1.0, + chance = 1, + catch_up = false, + action = detach_unsubmerged, --surface_unsubmerged_abm, +}) + + +-- 50% growth over a minute https://minecraft.fandom.com/wiki/Tutorials/Kelp_farming +-- 14% chance every random tick +-- On average, blocks are updated every 68.27 seconds (1365.33 game ticks) +-- 1 in 7 every 68 +-- 1 in 28 every 17 +-- 1 in 21 every 22 +-- https://minecraft.fandom.com/wiki/Tick#Random_tick minetest.register_abm({ label = "Kelp growth", nodenames = { "group:kelp" }, - interval = 45, - chance = 12, + interval = 17, + chance = 28, catch_up = false, - action = function(pos, node, active_object_count, active_object_count_wider) - local grown - -- Grow kelp by 1 node length if it would grow inside water - node.param2, grown = grow_param2_step(node.param2, true) - local top, top_node = get_kelp_top(pos, node) - local submerged = get_submerged(top_node) - if grown then - if submerged == "source" then - -- Liquid source: Grow normally - minetest.set_node(pos, node) - elseif submerged == "flowing" then - -- Flowing liquid: Grow 1 step, but also turn the top node into a liquid source - minetest.set_node(pos, node) - local def_liq = minetest.registered_nodes[top_node.name] - local alt_liq = def_liq and def_liq.liquid_alternative_source - if alt_liq then - minetest.set_node(top, {name=alt_liq}) - end - end - end - end, + action = grow_kelp, }) diff --git a/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr new file mode 100644 index 000000000..1db188129 --- /dev/null +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.ja.tr @@ -0,0 +1,60 @@ +# textdomain: mcl_ocean +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 Bricks=プリズマリンレンガ +Dark Prismarine=暗色プリズマリン +Prismarine Crystals=プリズマリンクリスタル +Prismarine Shard=プリズマリンの欠片 +Dried Kelp=乾燥コンブ +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=火ウチワサンゴ +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=死した脳ウチワサンゴ +Dead Brain Coral=死した脳サンゴ +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=死した管サンゴ +Seagrass=海草 +Kelp=コンブ +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.=海草が育つのは、水中の土・砂・砂利の上です。 +A decorative block that serves as a great furnace fuel.=炉の燃料として最適な装飾ブロック。 +Dried kelp is a food item.=乾燥コンブは食品です。 +Grows on coral block of same species=同種のサンゴブロックに生育 +Needs water to live=生きるために水が必要 +Grows in water on dirt, sand, gravel=水中の土・砂・砂利の上で成長 +Glows in the water=水中で成長 +4 possible sizes=4種類のサイズが可能 +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.=死した脳サンゴブロックに生え、水中での光源となるヒカリボヤ。明るさの異なる4種類のサイズがあります。 +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/locale/mcl_ocean.pl.tr b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.pl.tr new file mode 100644 index 000000000..7c63e4959 --- /dev/null +++ b/mods/ITEMS/mcl_ocean/locale/mcl_ocean.pl.tr @@ -0,0 +1,60 @@ +# textdomain: mcl_ocean +Sea Lantern=Latarnia morska +Sea lanterns are decorative light sources which look great underwater but can be placed anywhere.=Latarnie morskie to dekoracyjne źródła światła, które wyglądają bardzo dobrze pod wodą, ale mogą być umieszczone gdziekolwiek. +Prismarine=Pryzmaryn +Prismarine is used as a building block. It slowly changes its color.=Pryzmaryn jest blokiem budowlanym. Powoli zmienia on swój kolor. +Prismarine Bricks=Pryzmarynowe cegły +Dark Prismarine=Ciemny pryzmaryn +Prismarine Crystals=Pryzmarynowe kryształy +Prismarine Shard=Pryzmarynowe odłamki +Dried Kelp=Suszone wodorosty +Dried Kelp Block=Blok suszonych wodorostów +Brain Coral Block=Blok mózgowatego koralowca +Brain Coral Fan=Wachlarz mózgowatego koralowca +Brain Coral=Mózgowaty koralowiec +Bubble Coral Block=Blok bąbelkowego koralowca +Bubble Coral Fan=Wachlarz bąbelkowego koralowca +Bubble Coral=Bąbelkowy koralowiec +Fire Coral Block=Blok ognistego koralowca +Fire Coral Fan=Wachlarz ognistego koralowca +Fire Coral=Ognisty koralowiec +Horn Coral Block=Blok rogatego koralowca +Horn Coral Fan=Wachlarz rogatego koralowca +Horn Coral=Rogaty koralowiec +Tube Coral Block=Blok rurkowatego koralowca +Tube Coral Fan=Wachlarz rurkowatego koralowca +Tube Coral=Rurkowaty koralowiec +Dead Brain Coral Block=Martwy blok mózgowatego koralowca +Dead Brain Coral Fan=Martwy wachlarz mózgowatego koralowca +Dead Brain Coral=Martwy mózgowaty koralowiec +Dead Bubble Coral Block=Martwy blok bąbelkowego koralowca +Dead Bubble Coral Fan=Martwy wachlarz bąbelkowego koralowca +Dead Bubble Coral=Martwy bąbelkowy koralowiec +Dead Fire Coral Block=Martwy blok ognistego koralowca +Dead Fire Coral Fan=Martwy wachlarz ognistego koralowca +Dead Fire Coral=Martwy ognisty koralowiec +Dead Horn Coral Block=Martwy blok rogatego koralowca +Dead Horn Coral Fan=Martwy wachlarz rogatego koralowca +Dead Horn Coral=Martwy rogaty koralowiec +Dead Tube Coral Block=Martwy blok rurkowatego koralowca +Dead Tube Coral Fan=Martwy wachlarz rurkowatego koralowca +Dead Tube Coral=Martwy rurkowaty koralowiec +Seagrass=Trawa morska +Kelp=Wodorosty +Kelp grows inside water on top of dirt, sand or gravel.=Wodorosty rosną w wodzie na ziemi, piasku i żwirze. +Coral blocks live in the oceans and need a water source next to them to survive. Without water, they die off.=Bloki koralowca żyją w oceanach i potrzebują źródła wody obok aby przeżyć. Bez wody obumierają. +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.=Koralowiec rośnie na blokach koralowca i musi być wewnątrz źródła wody aby przeżyć. Bez wody obumiera. +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.=Wachlarz koralowca rośnie na blokach koralowca i musi być wewnątrz źródła wody aby przeżyć. Bez wody obumiera zarówno on jak i blok koralowca pod nim. +Seagrass grows inside water on top of dirt, sand or gravel.=Trawa morska rośnie w wodzie na ziemi, piasku i żwirze. +A decorative block that serves as a great furnace fuel.=Blok dekoracyjny, który świetnie sprawdza się jako paliwo do pieca. +Dried kelp is a food item.=Suszone wodorosty jest przedmiotem do jedzenia. +Grows on coral block of same species=Rośnie na blokach koralowca tego samego gatunku. +Needs water to live=Potrzebuje wody do życia. +Grows in water on dirt, sand, gravel=Rośnie w wodzie na ziemi, piasku i żwirze. +Glows in the water=Świeci w wodzie +4 possible sizes=4 możliwe wielkości +Grows on dead brain coral block=Rośnie na martwych blokach mózgowatego koralowca +Sea Pickle=Iskrzyłuda +Sea pickles grow on dead brain coral blocks and provide light when underwater. They come in 4 sizes that vary in brightness.=Iskrzyłuda rośnie na martwych blokach mózgowatego koralowca i jest źródłem światła pod wodą. +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.=Może być postawiona tylko na blokach mózgowatego koralowca. Postawienie iskrzyłuda na innej iskrzyłudzie sprawi, że się powiększy i będzie jaśniejsza. + diff --git a/mods/ITEMS/mcl_ocean/mod.conf b/mods/ITEMS/mcl_ocean/mod.conf index 664d8e1e8..a50609f52 100644 --- a/mods/ITEMS/mcl_ocean/mod.conf +++ b/mods/ITEMS/mcl_ocean/mod.conf @@ -1,2 +1,4 @@ name = mcl_ocean description = Includes various ocean nodes +depends = mcl_core, mcl_sounds, mcl_dye, mcl_util +optional_depends = doc, doc_items, screwdriver diff --git a/mods/ITEMS/mcl_ocean/prismarine.lua b/mods/ITEMS/mcl_ocean/prismarine.lua index 647e87fe1..32d17538d 100644 --- a/mods/ITEMS/mcl_ocean/prismarine.lua +++ b/mods/ITEMS/mcl_ocean/prismarine.lua @@ -1,6 +1,6 @@ -- Nodes -local S = minetest.get_translator("mcl_ocean") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_node("mcl_ocean:sea_lantern", { description = S("Sea Lantern"), @@ -12,8 +12,8 @@ minetest.register_node("mcl_ocean:sea_lantern", { drop = { max_items = 1, items = { - { items = {'mcl_ocean:prismarine_crystals 3'}, rarity = 2 }, - { items = {'mcl_ocean:prismarine_crystals 2'}} + { items = {"mcl_ocean:prismarine_crystals 3"}, rarity = 2 }, + { items = {"mcl_ocean:prismarine_crystals 2"}} } }, tiles = {{name="mcl_ocean_sea_lantern.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=1.25}}}, @@ -40,7 +40,7 @@ minetest.register_node("mcl_ocean:prismarine", { tiles = {{name="mcl_ocean_prismarine_anim.png", animation={type="vertical_frames", aspect_w=32, aspect_h=32, length=45.0}}}, 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, }) @@ -89,37 +89,37 @@ minetest.register_craftitem("mcl_ocean:prismarine_shard", { -- Crafting minetest.register_craft({ - output = 'mcl_ocean:sea_lantern', + output = "mcl_ocean:sea_lantern", recipe = { - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_crystals', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_crystals', 'mcl_ocean:prismarine_crystals', 'mcl_ocean:prismarine_crystals'}, - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_crystals', 'mcl_ocean:prismarine_shard'}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_crystals", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_crystals", "mcl_ocean:prismarine_crystals", "mcl_ocean:prismarine_crystals"}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_crystals", "mcl_ocean:prismarine_shard"}, } }) minetest.register_craft({ - output = 'mcl_ocean:prismarine', + output = "mcl_ocean:prismarine", recipe = { - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, } }) minetest.register_craft({ - output = 'mcl_ocean:prismarine_brick', + output = "mcl_ocean:prismarine_brick", recipe = { - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, } }) minetest.register_craft({ - output = 'mcl_ocean:prismarine_dark', + output = "mcl_ocean:prismarine_dark", recipe = { - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_shard', 'mcl_dye:black', 'mcl_ocean:prismarine_shard'}, - {'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard', 'mcl_ocean:prismarine_shard'}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_shard", "mcl_dye:black", "mcl_ocean:prismarine_shard"}, + {"mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard"}, } }) diff --git a/mods/ITEMS/mcl_ocean/sea_pickle.lua b/mods/ITEMS/mcl_ocean/sea_pickle.lua index 45b934a92..6a4e4a751 100644 --- a/mods/ITEMS/mcl_ocean/sea_pickle.lua +++ b/mods/ITEMS/mcl_ocean/sea_pickle.lua @@ -1,5 +1,6 @@ -local S = minetest.get_translator("mcl_ocean") -local mod_doc = minetest.get_modpath("doc") ~= nil +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_doc = minetest.get_modpath("doc") local function sea_pickle_on_place(itemstack, placer, pointed_thing) if pointed_thing.type ~= "node" or not placer then @@ -12,7 +13,7 @@ local function sea_pickle_on_place(itemstack, placer, pointed_thing) local node_under = minetest.get_node(pos_under) local node_above = minetest.get_node(pos_above) local def_under = minetest.registered_nodes[node_under.name] - local def_above = minetest.registered_nodes[node_above.name] + --local def_above = minetest.registered_nodes[node_above.name] if def_under and def_under.on_rightclick and not placer:get_player_control().sneak then return def_under.on_rightclick(pos_under, node_under, @@ -105,7 +106,10 @@ for s=1,4 do }, inventory_image = img, wield_image = img, - groups = { dig_immediate = 3, deco_block = 1, sea_pickle=1, not_in_creative_inventory=nici }, + groups = { + dig_immediate = 3, deco_block = 1, sea_pickle = 1, + not_in_creative_inventory=nici, compostability = 65 + }, -- Light level: 6 at size 1, +3 for each additional stage light_source = math.min(6 + (s-1)*3, minetest.LIGHT_MAX), selection_box = { diff --git a/mods/ITEMS/mcl_ocean/seagrass.lua b/mods/ITEMS/mcl_ocean/seagrass.lua index 492205138..328328993 100644 --- a/mods/ITEMS/mcl_ocean/seagrass.lua +++ b/mods/ITEMS/mcl_ocean/seagrass.lua @@ -1,5 +1,6 @@ -local S = minetest.get_translator("mcl_ocean") -local mod_doc = minetest.get_modpath("doc") ~= nil +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_doc = minetest.get_modpath("doc") -- List of supported surfaces for seagrass local surfaces = { @@ -38,13 +39,7 @@ local function seagrass_on_place(itemstack, placer, pointed_thing) return itemstack end - if minetest.is_protected(pos_under, player_name) or - minetest.is_protected(pos_above, player_name) then - minetest.log("action", player_name - .. " tried to place " .. itemstack:get_name() - .. " at protected position " - .. minetest.pos_to_string(pos_under)) - minetest.record_protection_violation(pos_under, player_name) + if mcl_util.check_area_protection(pos_under, pos_above, placer) then return itemstack end @@ -81,10 +76,10 @@ minetest.register_craftitem("mcl_ocean:seagrass", { description = S("Seagrass"), _tt_help = S("Grows in water on dirt, sand, gravel"), _doc_items_create_entry = false, - inventory_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", - wield_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", + inventory_image = "mcl_ocean_seagrass_item.png", + wield_image = "mcl_ocean_seagrass_item.png", on_place = seagrass_on_place, - groups = { deco_block = 1 }, + groups = {deco_block = 1, compostability = 30}, }) -- Seagrass nodes: seagrass on a surface node @@ -105,7 +100,7 @@ for s=1, #surfaces do doc_longdesc = S("Seagrass grows inside water on top of dirt, sand or gravel.") desc = S("Seagrass") doc_create = true - doc_img = "mcl_ocean_seagrass.png" + doc_img = "mcl_ocean_seagrass_item.png" else doc_create = false end @@ -113,11 +108,11 @@ for s=1, #surfaces do _doc_items_entry_name = desc, _doc_items_longdesc = doc_longdesc, _doc_items_create_entry = doc_create, - _doc_items_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", + _doc_items_image = doc_img, drawtype = "plantlike_rooted", paramtype = "light", paramtype2 = "meshoptions", - place_param2 = 3, + param2 = 3, tiles = def.tiles, special_tiles = { { @@ -125,8 +120,8 @@ for s=1, #surfaces do animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length=1.0}, } }, - inventory_image = "("..def.tiles[1]..")^(mcl_ocean_seagrass.png^[verticalframe:12:0)", - wield_image = "mcl_ocean_seagrass.png^[verticalframe:12:0", + inventory_image = "mcl_ocean_seagrass_item.png", + wield_image = "mcl_ocean_seagrass_item.png", selection_box = { type = "fixed", fixed = { diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral.png deleted file mode 100644 index 60a4c53da..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_block.png deleted file mode 100644 index a9a508be8..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_fan.png deleted file mode 100644 index 0ffe520e0..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_brain_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral.png deleted file mode 100644 index 905ba2f7c..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_block.png deleted file mode 100644 index 551975513..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_fan.png deleted file mode 100644 index c9a49f45f..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_bubble_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral.png deleted file mode 100644 index 8d8068200..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_block.png deleted file mode 100644 index 2938880ef..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_fan.png deleted file mode 100644 index b297894e8..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_brain_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral.png deleted file mode 100644 index 0d69e128c..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_block.png deleted file mode 100644 index 86333fb47..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_fan.png deleted file mode 100644 index 0b11adc31..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_bubble_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral.png deleted file mode 100644 index c050ecfea..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_block.png deleted file mode 100644 index 836ab2a7f..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_fan.png deleted file mode 100644 index 63c0806b9..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_fire_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral.png deleted file mode 100644 index c0ede515d..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_block.png deleted file mode 100644 index 8f37cd1e3..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_fan.png deleted file mode 100644 index 161c0ec7b..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_horn_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral.png deleted file mode 100644 index d1bef3abd..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_block.png deleted file mode 100644 index eb0e0da61..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_fan.png deleted file mode 100644 index 5d0500d18..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dead_tube_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp.png deleted file mode 100644 index 2d7879200..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_bottom.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_bottom.png deleted file mode 100644 index 148ecfd35..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_side.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_side.png deleted file mode 100644 index 71d1cb2ad..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_top.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_top.png deleted file mode 100644 index 148ecfd35..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_dried_kelp_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral.png deleted file mode 100644 index e7958d50c..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_block.png deleted file mode 100644 index e562b024e..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_fan.png deleted file mode 100644 index 412e97f8e..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_fire_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral.png deleted file mode 100644 index 8f3227618..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_block.png deleted file mode 100644 index c56a1344e..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_fan.png deleted file mode 100644 index 63e7d12ea..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_horn_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_item.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_item.png deleted file mode 100644 index 396f8b3ef..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_item.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_plant.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_plant.png deleted file mode 100644 index 11eaf610a..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_kelp_plant.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_bricks.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_bricks.png deleted file mode 100644 index f708a270a..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_bricks.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_anim.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_anim.png deleted file mode 100644 index 5c4f0064c..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_anim.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_off.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_off.png deleted file mode 100644 index 24b648777..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_1_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_anim.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_anim.png deleted file mode 100644 index ce063765f..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_anim.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_off.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_off.png deleted file mode 100644 index c0b34e8e9..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_2_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_anim.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_anim.png deleted file mode 100644 index d484085e2..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_anim.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_off.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_off.png deleted file mode 100644 index 56ac78f3a..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_3_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_anim.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_anim.png deleted file mode 100644 index 6d3e56675..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_anim.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_off.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_off.png deleted file mode 100644 index d2df93109..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_4_off.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_item.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_item.png deleted file mode 100644 index 88a4669ad..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_pickle_item.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass.png deleted file mode 100644 index 216d25312..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_seagrass.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral.png deleted file mode 100644 index 63cf864c7..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_block.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_block.png deleted file mode 100644 index 016888db3..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_block.png and /dev/null differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_fan.png b/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_fan.png deleted file mode 100644 index 7d055a7bd..000000000 Binary files a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_tube_coral_fan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/depends.txt b/mods/ITEMS/mcl_portals/depends.txt deleted file mode 100644 index f794e5f9c..000000000 --- a/mods/ITEMS/mcl_portals/depends.txt +++ /dev/null @@ -1,9 +0,0 @@ -mcl_init -mcl_worlds -mcl_core -mcl_nether -mcl_end -mcl_particles -mcl_spawn -awards? -doc? diff --git a/mods/ITEMS/mcl_portals/description.txt b/mods/ITEMS/mcl_portals/description.txt deleted file mode 100644 index fe84531f3..000000000 --- a/mods/ITEMS/mcl_portals/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds buildable portals to the Nether and End dimensions. diff --git a/mods/ITEMS/mcl_portals/init.lua b/mods/ITEMS/mcl_portals/init.lua index 2fd96afad..972e93473 100644 --- a/mods/ITEMS/mcl_portals/init.lua +++ b/mods/ITEMS/mcl_portals/init.lua @@ -1,12 +1,18 @@ -- Load files -mcl_portals = {} +mcl_portals = { + storage = minetest.get_mod_storage(), +} + +local modpath = minetest.get_modpath(minetest.get_current_modname()) -- Nether portal: -- Obsidian frame, activated by flint and steel -dofile(minetest.get_modpath("mcl_portals").."/portal_nether.lua") +dofile(modpath.."/portal_nether.lua") -- End portal (W.I.P): -- Red nether brick block frame, activated by an eye of ender -dofile(minetest.get_modpath("mcl_portals").."/portal_end.lua") +dofile(modpath.."/portal_end.lua") + +dofile(modpath.."/portal_gateway.lua") diff --git a/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr index b01b55353..714075502 100644 --- a/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.fr.tr @@ -1,18 +1,15 @@ # textdomain: mcl_portals End Portal=Portail 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 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 d'End dans l'Overworld vous téléporte à une position fixe dans la dimension d'End et crée une plate-forme d'obsidienne 5×5 à votre destination. Les portails de l'End à la fin 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 portiques d'End sont utilisés dans la construction de portails d'End. Chaque bloc a une prise pour un oeil d'ender. -NOTE: The End dimension is currently incomplete and might change in future versions.=REMARQUE: la dimension d'End est actuellement incomplète et pourrait changer dans les futures versions. -End Portal Frame with Eye of Ender=Cadre de portail de l'End avec Oeil d'Ender +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. +End Portal Frame with Eye of Ender=Cadre de portail de l'End avec œil d'Ender 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!=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.=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'autre dimension. 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étruit, ou s'il a été pris dans une explosion. -Obsidian is also used as the frame of Nether portals.=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.=Une fois placé, un œil d'ender ne peut pas être repris. -Used to construct end portals=Utilisé pour construire des portails d'End - -# 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.=Pour ouvrir un portail du Nether, placez un cadre vertical d'obsidienne d'une largeur de 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 en obsidienne. Les portails du Nether ne fonctionnent que dans l'Overworld et le 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 new file mode 100644 index 000000000..aea984691 --- /dev/null +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.ja.tr @@ -0,0 +1,15 @@ +# 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=エンドポータル・フレーム(エンダーアイ入り) +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 new file mode 100644 index 000000000..18d9b4b7b --- /dev/null +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.pl.tr @@ -0,0 +1,15 @@ +# textdomain: mcl_portals +End Portal=Portal 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. +End Portal Frame with Eye of Ender=Rama portalu Kresu z okiem Kresu. +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.zh_TW.tr b/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr new file mode 100644 index 000000000..a6b389036 --- /dev/null +++ b/mods/ITEMS/mcl_portals/locale/mcl_portals.zh_TW.tr @@ -0,0 +1,15 @@ +# 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=含終界之眼的終界傳送門框架 +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/mod.conf b/mods/ITEMS/mcl_portals/mod.conf index e82fbe6c1..ab03de570 100644 --- a/mods/ITEMS/mcl_portals/mod.conf +++ b/mods/ITEMS/mcl_portals/mod.conf @@ -1 +1,4 @@ name = mcl_portals +description = Adds buildable portals to the Nether and End dimensions. +depends = mcl_nether, mcl_end, mcl_particles, mcl_spawn, mcl_credits, mcl_structures +optional_depends = awards, doc diff --git a/mods/ITEMS/mcl_portals/portal_end.lua b/mods/ITEMS/mcl_portals/portal_end.lua index 5919ef213..8fa22e4fb 100644 --- a/mods/ITEMS/mcl_portals/portal_end.lua +++ b/mods/ITEMS/mcl_portals/portal_end.lua @@ -1,12 +1,18 @@ -local S = minetest.get_translator("mcl_portals") +local S = minetest.get_translator(minetest.get_current_modname()) + +local table = table +local vector = vector +local math = math + +local has_doc = minetest.get_modpath("doc") -- Parameters -local SPAWN_MIN = mcl_vars.mg_end_min+70 -local SPAWN_MAX = mcl_vars.mg_end_min+98 +--local SPAWN_MIN = mcl_vars.mg_end_min+70 +--local SPAWN_MAX = mcl_vars.mg_end_min+98 -local mg_name = minetest.get_mapgen_setting("mg_name") +--local mg_name = minetest.get_mapgen_setting("mg_name") -local destroy_portal = function(pos) +local function destroy_portal(pos) local neighbors = { { x=1, y=0, z=0 }, { x=-1, y=0, z=0 }, @@ -66,7 +72,7 @@ minetest.register_node("mcl_portals:portal_end", { drawtype = "nodebox", paramtype = "light", sunlight_propagates = true, - use_texture_alpha = true, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, walkable = false, diggable = false, pointable = false, @@ -76,7 +82,6 @@ minetest.register_node("mcl_portals:portal_end", { -- This is 15 in MC. light_source = 14, post_effect_color = {a = 192, r = 0, g = 0, b = 0}, - alpha = 192, after_destruct = destroy_portal, -- This prevents “falling through” collision_box = { @@ -94,7 +99,7 @@ minetest.register_node("mcl_portals:portal_end", { groups = {portal=1, not_in_creative_inventory = 1, disable_jump = 1}, _mcl_hardness = -1, - _mcl_blast_resistance = 36000000, + _mcl_blast_resistance = 3600000, }) -- Obsidian platform at the End portal destination in the End @@ -197,7 +202,6 @@ function mcl_portals.end_teleport(obj, pos) end end - local platform build_end_portal_destination(platform_pos) check_and_build_end_portal_destination(platform_pos) @@ -212,6 +216,9 @@ function mcl_portals.end_teleport(obj, pos) -- Look towards the main End island if dim ~= "end" then obj:set_look_horizontal(math.pi/2) + -- Show credits + else + mcl_credits.show(obj) end mcl_worlds.dimension_change(obj, mcl_worlds.pos_to_dimension(target)) minetest.sound_play("mcl_portals_teleport", {pos=target, gain=0.5, max_hear_distance = 16}, true) @@ -219,7 +226,7 @@ function mcl_portals.end_teleport(obj, pos) end function mcl_portals.end_portal_teleport(pos, node) - for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel if obj:is_player() or lua_entity then local objpos = obj:get_pos() @@ -234,7 +241,7 @@ function mcl_portals.end_portal_teleport(pos, node) end mcl_portals.end_teleport(obj, objpos) - + awards.unlock(obj:get_player_name(), "mcl:enterEndPortal") end end end @@ -277,6 +284,7 @@ minetest.register_node("mcl_portals:end_portal_frame", { _doc_items_usagehelp = S("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.") .. "\n" .. S("Place an eye of ender into each block. The end portal appears in the middle after placing the final eye.") .. "\n" .. S("Once placed, an eye of ender can not be taken back."), groups = { creative_breakable = 1, deco_block = 1, end_portal_frame = 1 }, tiles = { "mcl_portals_endframe_top.png", "mcl_portals_endframe_bottom.png", "mcl_portals_endframe_side.png" }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype2 = "facedir", drawtype = "nodebox", node_box = { @@ -301,8 +309,9 @@ minetest.register_node("mcl_portals:end_portal_frame_eye", { description = S("End Portal Frame with Eye of Ender"), _tt_help = S("Used to construct end portals"), _doc_items_create_entry = false, - groups = { creative_breakable = 1, deco_block = 1, comparator_signal = 15, end_portal_frame = 2 }, + groups = { creative_breakable = 1, deco_block = 1, comparator_signal = 15, end_portal_frame = 2, not_in_creative_inventory = 1 }, tiles = { "mcl_portals_endframe_top.png^[lowpart:75:mcl_portals_endframe_eye.png", "mcl_portals_endframe_bottom.png", "mcl_portals_endframe_eye.png^mcl_portals_endframe_side.png" }, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype2 = "facedir", drawtype = "nodebox", node_box = { @@ -332,7 +341,7 @@ minetest.register_node("mcl_portals:end_portal_frame_eye", { _mcl_hardness = -1, }) -if minetest.get_modpath("doc") then +if has_doc then doc.add_entry_alias("nodes", "mcl_portals:end_portal_frame", "nodes", "mcl_portals:end_portal_frame_eye") end @@ -359,7 +368,7 @@ minetest.override_item("mcl_end:ender_eye", { end minetest.set_node(pointed_thing.under, { name = "mcl_portals:end_portal_frame_eye", param2 = node.param2 }) - if minetest.get_modpath("doc") then + if has_doc then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:end_portal_frame") end minetest.sound_play( @@ -374,7 +383,7 @@ minetest.override_item("mcl_end:ender_eye", { -- Epic 'portal open' sound effect that can be heard everywhere minetest.sound_play("mcl_portals_open_end_portal", {gain=0.8}, true) end_portal_area(ppos) - if minetest.get_modpath("doc") then + if has_doc then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end") end end @@ -382,7 +391,3 @@ minetest.override_item("mcl_end:ender_eye", { return itemstack end, }) -minetest.override_item("mcl_core:bedrock", { - after_destruct = destroy_portal, -}) - diff --git a/mods/ITEMS/mcl_portals/portal_gateway.lua b/mods/ITEMS/mcl_portals/portal_gateway.lua new file mode 100644 index 000000000..ca15a61d5 --- /dev/null +++ b/mods/ITEMS/mcl_portals/portal_gateway.lua @@ -0,0 +1,121 @@ +local S = minetest.get_translator(minetest.get_current_modname()) +local storage = mcl_portals.storage + +local vector = vector + +local gateway_positions = { + {x = 96, y = -26925, z = 0}, + {x = 91, y = -26925, z = 29}, + {x = 77, y = -26925, z = 56}, + {x = 56, y = -26925, z = 77}, + {x = 29, y = -26925, z = 91}, + {x = 0, y = -26925, z = 96}, + {x = -29, y = -26925, z = 91}, + {x = -56, y = -26925, z = 77}, + {x = -77, y = -26925, z = 56}, + {x = -91, y = -26925, z = 29}, + {x = -96, y = -26925, z = 0}, + {x = -91, y = -26925, z = -29}, + {x = -77, y = -26925, z = -56}, + {x = -56, y = -26925, z = -77}, + {x = -29, y = -26925, z = -91}, + {x = 0, y = -26925, z = -96}, + {x = 29, y = -26925, z = -91}, + {x = 56, y = -26925, z = -77}, + {x = 77, y = -26925, z = -56}, + {x = 91, y = -26925, z = -29}, +} + +local path_gateway_portal = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_gateway_portal.mts" + +local function spawn_gateway_portal(pos, dest_str) + return mcl_structures.place_schematic(vector.add(pos, vector.new(-1, -2, -1)), path_gateway_portal, "0", nil, true, nil, dest_str and function() + minetest.get_meta(pos):set_string("mcl_portals:gateway_destination", dest_str) + end) +end + +function mcl_portals.spawn_gateway_portal() + local id = storage:get_int("gateway_last_id") + 1 + local pos = gateway_positions[id] + if not pos then return end + storage:set_int("gateway_last_id", id) + spawn_gateway_portal(pos) +end + +local gateway_def = table.copy(minetest.registered_nodes["mcl_portals:portal_end"]) +gateway_def.description = S("End Gateway Portal") +gateway_def._tt_help = S("Used to construct end gateway portals") +gateway_def._doc_items_longdesc = S("An End gateway portal teleports creatures and objects to the outer End (and back!).") +gateway_def._doc_items_usagehelp = S("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.") +gateway_def.after_destruct = nil +gateway_def.drawtype = "normal" +gateway_def.node_box = nil +gateway_def.walkable = true +gateway_def.tiles[3] = nil +minetest.register_node("mcl_portals:portal_gateway", gateway_def) + +local function find_destination_pos(minp, maxp) + for y = maxp.y, minp.y, -1 do + for x = maxp.x, minp.x, -1 do + for z = maxp.z, minp.z, -1 do + local pos = vector.new(x, y, z) + local nn = minetest.get_node(pos).name + if nn ~= "ignore" and nn ~= "mcl_portals:portal_gateway" and nn ~= "mcl_core:bedrock" then + local def = minetest.registered_nodes[nn] + if def and def.walkable then + return vector.add(pos, vector.new(0, 1.5, 0)) + end + end + end + end + end +end + +local preparing = {} + +local function teleport(pos, obj) + local meta = minetest.get_meta(pos) + local dest_portal + local dest_str = meta:get_string("mcl_portals:gateway_destination") + local pos_str = minetest.pos_to_string(pos) + if dest_str == "" then + dest_portal = vector.multiply(vector.direction(vector.new(0, pos.y, 0), pos), math.random(768, 1024)) + dest_portal.y = -26970 + spawn_gateway_portal(dest_portal, pos_str) + meta:set_string("mcl_portals:gateway_destination", minetest.pos_to_string(dest_portal)) + else + dest_portal = minetest.string_to_pos(dest_str) + end + local minp = vector.subtract(dest_portal, vector.new(5, 40, 5)) + local maxp = vector.add(dest_portal, vector.new(5, 10, 5)) + preparing[pos_str] = true + minetest.emerge_area(minp, maxp, function(blockpos, action, calls_remaining, param) + if calls_remaining < 1 then + if obj and obj:is_player() or obj:get_luaentity() then + obj:set_pos(find_destination_pos(minp, maxp) or vector.add(dest_portal, vector.new(0, 3.5, 0))) + end + preparing[pos_str] = false + end + end) +end + +minetest.register_abm({ + label = "End gateway portal teleportation", + nodenames = {"mcl_portals:portal_gateway"}, + interval = 0.1, + chance = 1, + action = function(pos) + if preparing[minetest.pos_to_string(pos)] then return end + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if obj:get_hp() > 0 then + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_throwing:ender_pearl" then + obj:remove() + obj = luaentity._thrower + end + teleport(pos, obj) + return + end + end + end, +}) diff --git a/mods/ITEMS/mcl_portals/portal_nether.lua b/mods/ITEMS/mcl_portals/portal_nether.lua index d35520015..5f889d86f 100644 --- a/mods/ITEMS/mcl_portals/portal_nether.lua +++ b/mods/ITEMS/mcl_portals/portal_nether.lua @@ -1,104 +1,286 @@ -local S = minetest.get_translator("mcl_portals") +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) --- Parameters +local SCAN_2_MAP_CHUNKS = true -- slower but helps to find more suitable places -local OVERWORLD_TO_NETHER_SCALE = 8 -local LIMIT = math.min(math.abs(mcl_vars.mapgen_edge_min), math.abs(mcl_vars.mapgen_edge_max)) +-- Localize functions for better performance +local abs = math.abs +local ceil = math.ceil +local floor = math.floor +local max = math.max +local min = math.min +local random = math.random +local dist = vector.distance +local add = vector.add +local mul = vector.multiply +local sub = vector.subtract --- Portal frame sizes -local FRAME_SIZE_X_MIN = 4 -local FRAME_SIZE_Y_MIN = 5 -local FRAME_SIZE_X_MAX = 23 -local FRAME_SIZE_Y_MAX = 23 +-- Setup +local W_MIN, W_MAX = 4, 23 +local H_MIN, H_MAX = 5, 23 +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 +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 -local PORTAL_NODES_MIN = 5 -local PORTAL_NODES_MAX = (FRAME_SIZE_X_MAX - 2) * (FRAME_SIZE_Y_MAX - 2) - -local TELEPORT_COOLOFF = 3 -- after player was teleported, for this many seconds they won't teleported again -local MOB_TELEPORT_COOLOFF = 14 -- after mob was teleported, 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 TOUCH_CHATTER_TIME_US = TOUCH_CHATTER_TIME * 1000000 -local TELEPORT_DELAY = 3 -- seconds before teleporting in Nether portal (4 minus ABM interval time) -local DESTINATION_EXPIRES = 60 * 1000000 -- cached destination expires after this number of microseconds have passed without using the same origin portal - -local PORTAL_SEARCH_HALF_CHUNK = 40 -- greater values may slow down the teleportation -local PORTAL_SEARCH_ALTITUDE = 128 +-- Alpha and particles +local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" +local node_particles_levels = { none=0, low=1, medium=2, high=3 } +local PARTICLES = node_particles_levels[node_particles_allowed] -- Table of objects (including players) which recently teleported by a -- Nether portal. Those objects have a brief cooloff period before they -- can teleport again. This prevents annoying back-and-forth teleportation. -mcl_portals.nether_portal_cooloff = {} -local touch_chatter_prevention = {} - -local overworld_ymin = math.max(mcl_vars.mg_overworld_min, -31) -local overworld_ymax = math.min(mcl_vars.mg_overworld_max_official, 63) -local nether_ymin = mcl_vars.mg_bedrock_nether_bottom_min -local nether_ymax = mcl_vars.mg_bedrock_nether_top_max -local overworld_dy = overworld_ymax - overworld_ymin + 1 -local nether_dy = nether_ymax - nether_ymin + 1 - -local node_particles_allowed = minetest.settings:get("mcl_node_particles") or "none" -local node_particles_levels = { - high = 3, - medium = 2, - low = 1, - none = 0, -} -local node_particles_allowed_level = node_particles_levels[node_particles_allowed] - - --- Functions - --- Ping-Pong fast travel, https://git.minetest.land/Wuzzy/MineClone2/issues/795#issuecomment-11058 -local function nether_to_overworld(x) - return LIMIT - math.abs(((x * OVERWORLD_TO_NETHER_SCALE + LIMIT) % (LIMIT*4)) - (LIMIT*2)) +local cooloff = {} +function mcl_portals.nether_portal_cooloff(object) + return cooloff[object] end --- Destroy portal if pos (portal frame or portal node) got destroyed -local function destroy_nether_portal(pos) - local meta = minetest.get_meta(pos) - local node = minetest.get_node(pos) - local nn, orientation = node.name, node.param2 - local obsidian = nn == "mcl_core:obsidian" +local chatter = {} - local has_meta = minetest.string_to_pos(meta:get_string("portal_frame1")) - if has_meta then - meta:set_string("portal_frame1", "") - meta:set_string("portal_frame2", "") - meta:set_string("portal_target", "") - meta:set_string("portal_time", "") +local queue = {} +local chunks = {} + +local storage = mcl_portals.storage +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) + if n then + exits[key] = minetest.deserialize(storage:get_string("nether_exits_"..key) or "return {}") or {} end - local check_remove = function(pos, orientation) - local node = minetest.get_node(pos) - if node and (node.name == "mcl_portals:portal" and (orientation == nil or (node.param2 == orientation))) then - minetest.log("action", "[mcl_portal] Destroying Nether portal at " .. minetest.pos_to_string(pos)) - return minetest.remove_node(pos) +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 +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 + +local dimension_to_teleport = { nether = "overworld", overworld = "nether" } + +local limits = { + nether = { + pmin = {x=LIM_MIN, y = N_Y_MIN, z = LIM_MIN}, + pmax = {x=LIM_MAX, y = N_Y_MAX, z = LIM_MAX}, + }, + overworld = { + pmin = {x=LIM_MIN, y = O_Y_MIN, z = LIM_MIN}, + pmax = {x=LIM_MAX, y = O_Y_MAX, z = LIM_MAX}, + }, +} + +local function save_portal_pos(pos,target_pos) + local p1 = vector.offset(pos,-2,-1,-2) + local p2 = vector.offset(pos,2,15,2) + 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)) + end +end + +local function get_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 + local m = minetest.get_meta(p):get_string("target_portal") + if m and m ~= "" and mcl_vars.get_node(p).name == "mcl_portals:portal" then + return minetest.get_position_from_hash(m) end end - if obsidian then -- check each of 6 sides of it and destroy every portal: - check_remove({x = pos.x - 1, y = pos.y, z = pos.z}, 0) - check_remove({x = pos.x + 1, y = pos.y, z = pos.z}, 0) - check_remove({x = pos.x, y = pos.y, z = pos.z - 1}, 1) - check_remove({x = pos.x, y = pos.y, z = pos.z + 1}, 1) - check_remove({x = pos.x, y = pos.y - 1, z = pos.z}) - check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) - return - end - if not has_meta then -- no meta means repeated call: function calls on every node destruction - return - end - if orientation == 0 then - check_remove({x = pos.x - 1, y = pos.y, z = pos.z}, 0) - check_remove({x = pos.x + 1, y = pos.y, z = pos.z}, 0) - else - check_remove({x = pos.x, y = pos.y, z = pos.z - 1}, 1) - check_remove({x = pos.x, y = pos.y, z = pos.z + 1}, 1) - 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}) end -minetest.register_node("mcl_portals:portal", { +-- 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. +local function add_exit(p) + if not p or not p.y or not p.z or not p.x then return 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 not exits[k] then + exits[k]={} + 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 + end + end + e[#e+1] = p + log("action", "[mcl_portals] Exit added at " .. pos_to_string(p)) +end + +-- This function removes Nether portals exits. +local function remove_exit(p) + if not p or not p.y or not p.z or not p.x then return 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 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 + end + end + end +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 + + --y values aren't used + local x = floor(p.x) + --local y = floor(p.y) + local z = floor(p.z) + + local x1 = x-dx+1 + --local y1 = y-dy+1 + local z1 = z-dz+1 + + local x2 = x+dx-1 + --local y2 = y+dy-1 + local z2 = z+dz-1 + + 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 + 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 +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 + end + end +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'. +local destroying_portal = false +local function destroy_nether_portal(pos, node) + if destroying_portal then + return + end + destroying_portal = true + + local orientation = node.param2 + local checked_tab = { [minetest.hash_node_position(pos)] = true } + local nodes = { pos } + + local function check_remove(pos) + local h = minetest.hash_node_position(pos) + if checked_tab[h] then + return + end + + local node = minetest.get_node(pos) + if node and node.name == PORTAL and (orientation == nil or node.param2 == orientation) then + table.insert(nodes, pos) + checked_tab[h] = true + end + end + + local i = 1 + while i <= #nodes do + pos = nodes[i] + if orientation == 0 then + check_remove({x = pos.x - 1, y = pos.y, z = pos.z}) + check_remove({x = pos.x + 1, y = pos.y, z = pos.z}) + else + check_remove({x = pos.x, y = pos.y, z = pos.z - 1}) + check_remove({x = pos.x, y = pos.y, z = pos.z + 1}) + 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) + i = i + 1 + end + + minetest.bulk_set_node(nodes, { name = "air" }) + destroying_portal = false +end + +local on_rotate +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.disallow +end + +minetest.register_node(PORTAL, { description = S("Nether Portal"), _doc_items_longdesc = S("A Nether portal teleports creatures and objects to the hot and dangerous Nether dimension (and back!). Enter at your own risk!"), _doc_items_usagehelp = S("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."), @@ -131,415 +313,346 @@ minetest.register_node("mcl_portals:portal", { paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, - use_texture_alpha = true, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, walkable = false, - diggable = false, - pointable = false, buildable_to = false, is_ground_content = false, drop = "", light_source = 11, post_effect_color = {a = 180, r = 51, g = 7, b = 89}, - alpha = 192, node_box = { type = "fixed", fixed = { {-0.5, -0.5, -0.1, 0.5, 0.5, 0.1}, }, }, - groups = {portal=1, not_in_creative_inventory = 1}, - on_destruct = destroy_nether_portal, + groups = { creative_breakable = 1, portal = 1, not_in_creative_inventory = 1 }, + sounds = mcl_sounds.node_sound_glass_defaults(), + after_destruct = destroy_nether_portal, + on_rotate = on_rotate, _mcl_hardness = -1, _mcl_blast_resistance = 0, }) -local function find_target_y(x, y, z, y_min, y_max) - local y_org = math.max(math.min(y, y_max), y_min) - local node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - return y_org +local function light_frame(x1, y1, z1, x2, y2, z2, name, node, node_frame) + local orientation = 0 + if x1 == x2 then + orientation = 1 end - while node.name ~= "air" and y < y_max do - y = y + 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - break - end - end - if node then - if node.name ~= "air" then - y = y_org - end - end - while node == nil and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - end - if y == y_max and node ~= nil then -- try reverse direction who knows what they built there... - while node.name ~= "air" and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - if node == nil then - break - end - end - end - if node == nil then - return y_org - end - while node.name == "air" and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - while node == nil and y > y_min do - y = y - 1 - node = minetest.get_node_or_nil({x = x, y = y, z = z}) - end - if node == nil then - return y_org - end - end - if y == y_min then - return y_org - end - return math.max(math.min(y, y_max), y_min) -end - -local function find_nether_target_y(x, y, z) - local target_y = find_target_y(x, y, z, nether_ymin + 4, nether_ymax - 25) + 1 - minetest.log("verbose", "[mcl_portal] Found Nether target altitude: " .. tostring(target_y) .. " for pos. " .. minetest.pos_to_string({x = x, y = y, z = z})) - return target_y -end - -local function find_overworld_target_y(x, y, z) - local target_y = find_target_y(x, y, z, overworld_ymin + 4, overworld_ymax - 25) + 1 - local node = minetest.get_node({x = x, y = target_y - 1, z = z}) - if not node then - return target_y - end - local nn = node.name - if nn ~= "air" and minetest.get_item_group(nn, "water") == 0 then - target_y = target_y + 1 - end - minetest.log("verbose", "[mcl_portal] Found Overworld target altitude: " .. tostring(target_y) .. " for pos. " .. minetest.pos_to_string({x = x, y = y, z = z})) - return target_y -end - - -local function update_target(pos, target, time_str) - local stack = {{x = pos.x, y = pos.y, z = pos.z}} - while #stack > 0 do - local i = #stack - local meta = minetest.get_meta(stack[i]) - if meta:get_string("portal_time") == time_str then - stack[i] = nil -- Already updated, skip it - else - local node = minetest.get_node(stack[i]) - local portal = node.name == "mcl_portals:portal" - if not portal then - stack[i] = nil - else - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", time_str) - meta:set_string("portal_target", target) - stack[i].y = y - 1 - stack[i + 1] = {x = x, y = y + 1, z = z} - if node.param2 == 0 then - stack[i + 2] = {x = x - 1, y = y, z = z} - stack[i + 3] = {x = x + 1, y = y, z = z} + 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 + pos.z = z + for y = y1 - 1, y2 + 1 do + 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) else - stack[i + 2] = {x = x, y = y, z = z - 1} - stack[i + 3] = {x = x, y = y, z = z + 1} + set_node(pos, node) + add_exit({x=pos.x, y=pos.y-1, z=pos.z}) end end end end end -local function ecb_setup_target_portal(blockpos, action, calls_remaining, param) - -- param.: srcx, srcy, srcz, dstx, dsty, dstz, srcdim, ax1, ay1, az1, ax2, ay2, az2 +--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) - local portal_search = function(target, p1, p2) - local portal_nodes = minetest.find_nodes_in_area(p1, p2, "mcl_portals:portal") - local portal_pos = false - if portal_nodes and #portal_nodes > 0 then - -- Found some portal(s), use nearest: - portal_pos = {x = portal_nodes[1].x, y = portal_nodes[1].y, z = portal_nodes[1].z} - local nearest_distance = vector.distance(target, portal_pos) - for n = 2, #portal_nodes do - local distance = vector.distance(target, portal_nodes[n]) - if distance < nearest_distance then - portal_pos = {x = portal_nodes[n].x, y = portal_nodes[n].y, z = portal_nodes[n].z} - nearest_distance = distance - end - end - end -- here we have the best portal_pos - return portal_pos + 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"}) 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) - if calls_remaining <= 0 then - minetest.log("action", "[mcl_portal] Area for destination Nether portal emerged!") - local src_pos = {x = param.srcx, y = param.srcy, z = param.srcz} - local dst_pos = {x = param.dstx, y = param.dsty, z = param.dstz} - local meta = minetest.get_meta(src_pos) - local portal_pos = portal_search(dst_pos, {x = param.ax1, y = param.ay1, z = param.az1}, {x = param.ax2, y = param.ay2, z = param.az2}) - - if portal_pos == false then - minetest.log("verbose", "[mcl_portal] No portal in area " .. minetest.pos_to_string({x = param.ax1, y = param.ay1, z = param.az1}) .. "-" .. minetest.pos_to_string({x = param.ax2, y = param.ay2, z = param.az2})) - -- Need to build arrival portal: - local org_dst_y = dst_pos.y - if param.srcdim == "overworld" then - dst_pos.y = find_nether_target_y(dst_pos.x, dst_pos.y, dst_pos.z) - else - dst_pos.y = find_overworld_target_y(dst_pos.x, dst_pos.y, dst_pos.z) - end - if math.abs(org_dst_y - dst_pos.y) >= PORTAL_SEARCH_ALTITUDE / 2 then - portal_pos = portal_search(dst_pos, - {x = dst_pos.x - PORTAL_SEARCH_HALF_CHUNK, y = math.floor(dst_pos.y - PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z - PORTAL_SEARCH_HALF_CHUNK}, - {x = dst_pos.x + PORTAL_SEARCH_HALF_CHUNK, y = math.ceil(dst_pos.y + PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z + PORTAL_SEARCH_HALF_CHUNK} - ) - end - if portal_pos == false then - minetest.log("verbose", "[mcl_portal] 2nd attempt: No portal in area " .. minetest.pos_to_string({x = dst_pos.x - PORTAL_SEARCH_HALF_CHUNK, y = math.floor(dst_pos.y - PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z - PORTAL_SEARCH_HALF_CHUNK}) .. "-" .. minetest.pos_to_string({x = dst_pos.x + PORTAL_SEARCH_HALF_CHUNK, y = math.ceil(dst_pos.y + PORTAL_SEARCH_ALTITUDE / 2), z = dst_pos.z + PORTAL_SEARCH_HALF_CHUNK})) - local width, height = 2, 3 - portal_pos = mcl_portals.build_nether_portal(dst_pos, width, height) + -- 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 + 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 + local nn_1 = get_node(pp_1).name + if ((nn=="air" and nn_1 == "air") or not registered_nodes[nn].is_ground_content) and not is_protected(pp, name) then + set_node(pp, {name = OBSIDIAN}) end end + end - local target_meta = minetest.get_meta(portal_pos) - local p3 = minetest.string_to_pos(target_meta:get_string("portal_frame1")) - local p4 = minetest.string_to_pos(target_meta:get_string("portal_frame2")) - if p3 and p4 then - portal_pos = vector.divide(vector.add(p3, p4), 2.0) - portal_pos.y = math.min(p3.y, p4.y) - portal_pos = vector.round(portal_pos) - local node = minetest.get_node(portal_pos) - if node and node.name ~= "mcl_portals:portal" then - portal_pos = {x = p3.x, y = p3.y, z = p3.z} - if minetest.get_node(portal_pos).name == "mcl_core:obsidian" then - -- Old-version portal: - if p4.z == p3.z then - portal_pos = {x = p3.x + 1, y = p3.y + 1, z = p3.z} - else - portal_pos = {x = p3.x, y = p3.y + 1, z = p3.z + 1} + log("action", "[mcl_portals] Destination Nether portal generated at "..pos_to_string(pos).."!") + + return pos +end + +function mcl_portals.spawn_nether_portal(pos, rot, pr, name) + if not pos then return end + local o = 0 + if rot then + if rot == "270" or rot=="90" then + o = 1 + elseif rot == "random" then + o = random(0,1) + end + end + build_nether_portal(pos, nil, nil, o, name, true) +end + +-- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation +local function stop_teleport_cooloff(o) + cooloff[o] = nil + chatter[o] = nil +end + +local function teleport_cooloff(obj) + cooloff[obj] = true + if obj:is_player() then + minetest.after(PLAYER_COOLOFF, stop_teleport_cooloff, obj) + else + minetest.after(MOB_COOLOFF, stop_teleport_cooloff, obj) + end +end + +local function finalize_teleport(obj, exit) + if not obj or not exit or not exit.x or not exit.y or not exit.z then return end + + local objpos = obj:get_pos() + if not objpos then return end + + local is_player = obj:is_player() + local name + if is_player then + name = obj:get_player_name() + 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 -- + + + -- 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) + 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)..".") + 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)..".") + 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) + else + pos2.x = pos2.x - 1 + nodes = find_nodes_in_area(pos1, pos2, {"air"}) + if #nodes == 48 then + orientation = 1 + 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) + end + end + queue[cn] = nil + end +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) + end + return max(min(mcl_vars.mg_lava_nether_max, pos2.y-1), pos1.y+1) +end + +local function ecb_scan_area_2(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 portals = find_nodes_in_area(pos1, pos2, {PORTAL}) + if portals and #portals>0 then + for _, p in pairs(portals) do + add_exit(p) + end + local exit = find_exit(pos) + if exit then + finalize_teleport(obj, exit) + end + return + end + -- TEMPORATY CODE SECTION ENDS HERE -- + + + local nodes = find_nodes_in_area_under_air(pos1, pos2, {"group:building_block"}) + if nodes then + local nc = #nodes + log("action", "[mcl_portals] Area for destination Nether portal emerged! Found " .. tostring(nc) .. " nodes under the air around "..pos_to_string(pos)) + if nc > 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 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)) + distance = distance0 + pos0 = {x=node1.x, y=node1.y, z=node1.z} + end end end end end - local time_str = tostring(minetest.get_us_time()) - local target = minetest.pos_to_string(portal_pos) - - update_target(src_pos, target, time_str) end -end - -local function nether_portal_get_target_position(src_pos) - local _, current_dimension = mcl_worlds.y_to_layer(src_pos.y) - local x, y, z, y_min, y_max = 0, 0, 0, 0, 0 - if current_dimension == "nether" then - x = math.floor(nether_to_overworld(src_pos.x) + 0.5) - z = math.floor(nether_to_overworld(src_pos.z) + 0.5) - y = math.floor((math.min(math.max(src_pos.y, nether_ymin), nether_ymax) - nether_ymin) / nether_dy * overworld_dy + overworld_ymin + 0.5) - y_min = overworld_ymin - y_max = overworld_ymax - else -- overworld: - x = math.floor(src_pos.x / OVERWORLD_TO_NETHER_SCALE + 0.5) - z = math.floor(src_pos.z / OVERWORLD_TO_NETHER_SCALE + 0.5) - y = math.floor((math.min(math.max(src_pos.y, overworld_ymin), overworld_ymax) - overworld_ymin) / overworld_dy * nether_dy + nether_ymin + 0.5) - y_min = nether_ymin - y_max = nether_ymax + if distance then -- several nodes of air might be better than lava lake, right? + log("action", "[mcl_portals] using backup pos "..pos_to_string(pos0).." to create a portal") + create_portal_2(pos0, name, obj) + return end - return x, y, z, current_dimension, y_min, y_max -end -local function find_or_create_portal(src_pos) - local x, y, z, cdim, y_min, y_max = nether_portal_get_target_position(src_pos) - local pos1 = {x = x - PORTAL_SEARCH_HALF_CHUNK, y = math.max(y_min, math.floor(y - PORTAL_SEARCH_ALTITUDE / 2)), z = z - PORTAL_SEARCH_HALF_CHUNK} - local pos2 = {x = x + PORTAL_SEARCH_HALF_CHUNK, y = math.min(y_max, math.ceil(y + PORTAL_SEARCH_ALTITUDE / 2)), z = z + PORTAL_SEARCH_HALF_CHUNK} - if pos1.y == y_min then - pos2.y = math.min(y_max, pos1.y + PORTAL_SEARCH_ALTITUDE) - else - if pos2.y == y_max then - pos1.y = math.max(y_min, pos2.y - PORTAL_SEARCH_ALTITUDE) + if param.next_chunk_1 and param.next_chunk_2 and param.next_pos then + local pos1, pos2, p = param.next_chunk_1, param.next_chunk_2, param.next_pos + if p.x >= 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}) + return end end - minetest.emerge_area(pos1, pos2, ecb_setup_target_portal, {srcx=src_pos.x, srcy=src_pos.y, srcz=src_pos.z, dstx=x, dsty=y, dstz=z, srcdim=cdim, ax1=pos1.x, ay1=pos1.y, az1=pos1.z, ax2=pos2.x, ay2=pos2.y, az2=pos2.z}) + + 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 + end + create_portal_2(pos, name, obj) end -local function emerge_target_area(src_pos) - local x, y, z, cdim, y_min, y_max = nether_portal_get_target_position(src_pos) - local pos1 = {x = x - PORTAL_SEARCH_HALF_CHUNK, y = math.max(y_min + 2, math.floor(y - PORTAL_SEARCH_ALTITUDE / 2)), z = z - PORTAL_SEARCH_HALF_CHUNK} - local pos2 = {x = x + PORTAL_SEARCH_HALF_CHUNK, y = math.min(y_max - 2, math.ceil(y + PORTAL_SEARCH_ALTITUDE / 2)), z = z + PORTAL_SEARCH_HALF_CHUNK} - minetest.emerge_area(pos1, pos2) - pos1 = {x = x - 1, y = y_min, z = z - 1} - pos2 = {x = x + 1, y = y_max, z = z + 1} - minetest.emerge_area(pos1, pos2) +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 + return + end + chunks[cn] = 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}) end local function available_for_nether_portal(p) - local nn = minetest.get_node(p).name - local obsidian = nn == "mcl_core:obsidian" + local nn = get_node(p).name + local obsidian = nn == OBSIDIAN if nn ~= "air" and minetest.get_item_group(nn, "fire") ~= 1 then return false, obsidian end return true, obsidian end -local function light_frame(x1, y1, z1, x2, y2, z2, build_frame) - local build_frame = build_frame or false - local orientation = 0 - if x1 == x2 then - orientation = 1 - end - local disperse = 50 - local pass = 1 - while true do - local protection = false - - for x = x1 - 1 + orientation, x2 + 1 - orientation do - for z = z1 - orientation, z2 + orientation do - for y = y1 - 1, y2 + 1 do - local frame = (x < x1) or (x > x2) or (y < y1) or (y > y2) or (z < z1) or (z > z2) - if frame then - if build_frame then - if pass == 1 then - if minetest.is_protected({x = x, y = y, z = z}, "") then - protection = true - local offset_x = math.random(-disperse, disperse) - local offset_z = math.random(-disperse, disperse) - disperse = disperse + math.random(25, 177) - if disperse > 5000 then - return nil - end - x1, z1 = x1 + offset_x, z1 + offset_z - x2, z2 = x2 + offset_x, z2 + offset_z - local _, dimension = mcl_worlds.y_to_layer(y1) - local height = math.abs(y2 - y1) - y1 = (y1 + y2) / 2 - if dimension == "nether" then - y1 = find_nether_target_y(math.min(x1, x2), y1, math.min(z1, z2)) - else - y1 = find_overworld_target_y(math.min(x1, x2), y1, math.min(z1, z2)) - end - y2 = y1 + height - break - end - else - minetest.set_node({x = x, y = y, z = z}, {name = "mcl_core:obsidian"}) - end - end - else - if not build_frame or pass == 2 then - local node = minetest.get_node({x = x, y = y, z = z}) - minetest.set_node({x = x, y = y, z = z}, {name = "mcl_portals:portal", param2 = orientation}) - end - end - if not frame and pass == 2 then - local meta = minetest.get_meta({x = x, y = y, z = z}) - -- Portal frame corners - meta:set_string("portal_frame1", minetest.pos_to_string({x = x1, y = y1, z = z1})) - meta:set_string("portal_frame2", minetest.pos_to_string({x = x2, y = y2, z = z2})) - -- Portal target coordinates - meta:set_string("portal_target", "") - -- Portal last teleportation time - meta:set_string("portal_time", tostring(0)) - end - end - if protection then - break - end - end - if protection then - break - end - end - if build_frame == false or pass == 2 then - break - end - if build_frame and not protection and pass == 1 then - pass = 2 - end - end - emerge_target_area({x = x1, y = y1, z = z1}) - return {x = x1, y = y1, z = z1} -end - ---Build arrival portal -function mcl_portals.build_nether_portal(pos, width, height, orientation) - local height = height or FRAME_SIZE_Y_MIN - 2 - local width = width or FRAME_SIZE_X_MIN - 2 - local orientation = orientation or math.random(0, 1) - - if orientation == 0 then - minetest.load_area({x = pos.x - 3, y = pos.y - 1, z = pos.z - width * 2}, {x = pos.x + width + 2, y = pos.y + height + 2, z = pos.z + width * 2}) - else - minetest.load_area({x = pos.x - width * 2, y = pos.y - 1, z = pos.z - 3}, {x = pos.x + width * 2, y = pos.y + height + 2, z = pos.z + width + 2}) - end - - pos = light_frame(pos.x, pos.y, pos.z, pos.x + (1 - orientation) * (width - 1), pos.y + height - 1, pos.z + orientation * (width - 1), true) - - -- Clear some space around: - for x = pos.x - math.random(2 + (width-2)*( orientation), 5 + (2*width-5)*( orientation)), pos.x + width*(1-orientation) + math.random(2+(width-2)*( orientation), 4 + (2*width-4)*( orientation)) do - for z = pos.z - math.random(2 + (width-2)*(1-orientation), 5 + (2*width-5)*(1-orientation)), pos.z + width*( orientation) + math.random(2+(width-2)*(1-orientation), 4 + (2*width-4)*(1-orientation)) do - for y = pos.y - 1, pos.y + height + math.random(1,6) do - local nn = minetest.get_node({x = x, y = y, z = z}).name - if nn ~= "mcl_core:obsidian" and nn ~= "mcl_portals:portal" and minetest.registered_nodes[nn].is_ground_content and not minetest.is_protected({x = x, y = y, z = z}, "") then - minetest.remove_node({x = x, y = y, z = z}) - end - end - end - end - - -- 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 - local pp = {x = x, y = pos.y - 1, z = z} - local nn = minetest.get_node(pp).name - if not minetest.registered_nodes[nn].is_ground_content and not minetest.is_protected(pp, "") then - minetest.set_node(pp, {name = "mcl_core:obsidian"}) - end - end - end - - minetest.log("action", "[mcl_portal] Destination Nether portal generated at "..minetest.pos_to_string(pos).."!") - - return pos -end - local function check_and_light_shape(pos, orientation) local stack = {{x = pos.x, y = pos.y, z = pos.z}} local node_list = {} + local index_list = {} local node_counter = 0 -- Search most low node from the left (pos1) and most right node from the top (pos2) local pos1 = {x = pos.x, y = pos.y, z = pos.z} local pos2 = {x = pos.x, y = pos.y, z = pos.z} - local wrong_portal_nodes_clean_up = function(node_list) - for i = 1, #node_list do - local meta = minetest.get_meta(node_list[i]) - meta:set_string("portal_time", "") - end - return false - end - + local kx, ky, kz = pos.x - 1999, pos.y - 1999, pos.z - 1999 while #stack > 0 do local i = #stack - local meta = minetest.get_meta(stack[i]) - local target = meta:get_string("portal_time") - if target and target == "-2" then + local x, y, z = stack[i].x, stack[i].y, stack[i].z + local k = (x-kx)*16000000 + (y-ky)*4000 + z-kz + if index_list[k] then stack[i] = nil -- Already checked, skip it else local good, obsidian = available_for_nether_portal(stack[i]) if obsidian then stack[i] = nil else - if (not good) or (node_counter >= PORTAL_NODES_MAX) then - return wrong_portal_nodes_clean_up(node_list) + if (not good) or (node_counter >= N_MAX) then + return false end - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", "-2") node_counter = node_counter + 1 node_list[node_counter] = {x = x, y = y, z = z} + index_list[k] = true stack[i].y = y - 1 stack[i + 1] = {x = x, y = y + 1, z = z} if orientation == 0 then @@ -559,40 +672,35 @@ local function check_and_light_shape(pos, orientation) end end - if node_counter < PORTAL_NODES_MIN then - return wrong_portal_nodes_clean_up(node_list) + if node_counter < N_MIN then + return false end -- Limit rectangles width and height - if math.abs(pos2.x - pos1.x + pos2.z - pos1.z) + 3 > FRAME_SIZE_X_MAX or math.abs(pos2.y - pos1.y) + 3 > FRAME_SIZE_Y_MAX then - return wrong_portal_nodes_clean_up(node_list) + if abs(pos2.x - pos1.x + pos2.z - pos1.z) + 3 > W_MAX or abs(pos2.y - pos1.y) + 3 > H_MAX then + return false end for i = 1, node_counter do local node_pos = node_list[i] - local node = minetest.get_node(node_pos) - minetest.set_node(node_pos, {name = "mcl_portals:portal", param2 = orientation}) - local meta = minetest.get_meta(node_pos) - meta:set_string("portal_frame1", minetest.pos_to_string(pos1)) - meta:set_string("portal_frame2", minetest.pos_to_string(pos2)) - meta:set_string("portal_time", tostring(0)) - meta:set_string("portal_target", "") + minetest.set_node(node_pos, {name = PORTAL, param2 = orientation}) + add_exit(node_pos) end - return true + return true end -- Attempts to light a Nether portal at pos -- Pos can be any of the inner part. -- The frame MUST be filled only with air or any fire, which will be replaced with Nether portal blocks. -- If no Nether portal can be lit, nothing happens. --- Returns number of portals created (0, 1 or 2) +-- 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 0 + return false end - local orientation = math.random(0, 1) + local orientation = random(0, 1) for orientation_iteration = 1, 2 do if check_and_light_shape(pos, orientation) then return true @@ -602,126 +710,51 @@ function mcl_portals.light_nether_portal(pos) return false end -local function update_portal_time(pos, time_str) - local stack = {{x = pos.x, y = pos.y, z = pos.z}} - while #stack > 0 do - local i = #stack - local meta = minetest.get_meta(stack[i]) - if meta:get_string("portal_time") == time_str then - stack[i] = nil -- Already updated, skip it - else - local node = minetest.get_node(stack[i]) - local portal = node.name == "mcl_portals:portal" - if not portal then - stack[i] = nil - else - local x, y, z = stack[i].x, stack[i].y, stack[i].z - meta:set_string("portal_time", time_str) - stack[i].y = y - 1 - stack[i + 1] = {x = x, y = y + 1, z = z} - if node.param2 == 0 then - stack[i + 2] = {x = x - 1, y = y, z = z} - stack[i + 3] = {x = x + 1, y = y, z = z} - else - stack[i + 2] = {x = x, y = y, z = z - 1} - stack[i + 3] = {x = x, y = y, z = z + 1} - end - end - end - end -end - -local function prepare_target(pos) - local meta, us_time = minetest.get_meta(pos), minetest.get_us_time() - local portal_time = tonumber(meta:get_string("portal_time")) or 0 - local delta_time_us = us_time - portal_time - local pos1, pos2 = minetest.string_to_pos(meta:get_string("portal_frame1")), minetest.string_to_pos(meta:get_string("portal_frame2")) - if delta_time_us <= DESTINATION_EXPIRES then - -- Destination point must be still cached according to https://minecraft.gamepedia.com/Nether_portal - return update_portal_time(pos, tostring(us_time)) - end - -- No cached destination point - find_or_create_portal(pos) -end - --- Teleportation cooloff for some seconds, to prevent back-and-forth teleportation -local function stop_teleport_cooloff(o) - mcl_portals.nether_portal_cooloff[o] = false - touch_chatter_prevention[o] = nil -end - -local function teleport_cooloff(obj) - if obj:is_player() then - minetest.after(TELEPORT_COOLOFF, stop_teleport_cooloff, obj) - else - minetest.after(MOB_TELEPORT_COOLOFF, stop_teleport_cooloff, obj) - end -end - -- Teleport function local function teleport_no_delay(obj, pos) local is_player = obj:is_player() - if (not obj:get_luaentity()) and (not is_player) then - return - end + if (not is_player and not obj:get_luaentity()) or cooloff[obj] then return end local objpos = obj:get_pos() - if objpos == nil then - return - end + if not objpos then return end - if mcl_portals.nether_portal_cooloff[obj] then - return - end - -- If player stands, player is at ca. something+0.5 - -- which might cause precision problems, so we used ceil. - objpos.y = math.ceil(objpos.y) + -- 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 - if minetest.get_node(objpos).name ~= "mcl_portals:portal" then - return - end - - local meta = minetest.get_meta(pos) - local delta_time = minetest.get_us_time() - (tonumber(meta:get_string("portal_time")) or 0) - local target = minetest.string_to_pos(meta:get_string("portal_target")) - if delta_time > DESTINATION_EXPIRES or target == nil then - -- Area not ready yet - retry after a second - return minetest.after(1, teleport_no_delay, obj, pos) - end - - -- Enable teleportation cooloff for some seconds, to prevent back-and-forth teleportation - teleport_cooloff(obj) - mcl_portals.nether_portal_cooloff[obj] = true - - -- Teleport - obj:set_pos(target) + local target, dim = get_target(objpos) + if not target then return end + local name if is_player then - mcl_worlds.dimension_change(obj, mcl_worlds.pos_to_dimension(target)) - minetest.sound_play("mcl_portals_teleport", {pos=target, gain=0.5, max_hear_distance = 16}, true) - local name = obj:get_player_name() - minetest.log("action", "[mcl_portal] "..name.." teleported to Nether portal at "..minetest.pos_to_string(target)..".") + name = obj:get_player_name() + end + + local exit = find_exit(target) + if exit then + finalize_teleport(obj, exit) + else + dim = dimension_to_teleport[dim] + -- need to create arrival portal + create_portal(target, limits[dim].pmin, limits[dim].pmax, name, obj) end end local function prevent_portal_chatter(obj) - local time_us = minetest.get_us_time() - local chatter = touch_chatter_prevention[obj] or 0 - touch_chatter_prevention[obj] = time_us + local time_us = get_us_time() + local ch = chatter[obj] or 0 + chatter[obj] = time_us minetest.after(TOUCH_CHATTER_TIME, function(o) - if not o or not touch_chatter_prevention[o] then - return - end - if minetest.get_us_time() - touch_chatter_prevention[o] >= TOUCH_CHATTER_TIME_US then - touch_chatter_prevention[o] = nil + if o and chatter[o] and get_us_time() - chatter[o] >= CHATTER_US then + chatter[o] = nil end end, obj) - return time_us - chatter > TOUCH_CHATTER_TIME_US + return time_us - ch > CHATTER_US end local function animation(player, playername) - local chatter = touch_chatter_prevention[player] or 0 - if mcl_portals.nether_portal_cooloff[player] or minetest.get_us_time() - chatter < TOUCH_CHATTER_TIME_US then + local ch = chatter[player] or 0 + if cooloff[player] or get_us_time() - ch < CHATTER_US then local pos = player:get_pos() if not pos then return @@ -752,36 +785,35 @@ local function teleport(obj, portal_pos) name = obj:get_player_name() animation(obj, name) end - -- Call prepare_target() first because it might take a long - prepare_target(portal_pos) - -- Prevent quick back-and-forth teleportation - if not mcl_portals.nether_portal_cooloff[obj] then - local creative_enabled = minetest.is_creative_enabled(name) - if creative_enabled then - return teleport_no_delay(obj, portal_pos) - end - minetest.after(TELEPORT_DELAY, teleport_no_delay, obj, portal_pos) + + if cooloff[obj] then return end + + if minetest.is_creative_enabled(name) then + teleport_no_delay(obj, portal_pos) + return end + + minetest.after(DELAY, teleport_no_delay, obj, portal_pos) end minetest.register_abm({ label = "Nether portal teleportation and particles", - nodenames = {"mcl_portals:portal"}, + nodenames = {PORTAL}, interval = 1, chance = 1, action = function(pos, node) local o = node.param2 -- orientation - local d = math.random(0, 1) -- direction - local time = math.random() * 1.9 + 0.5 + local d = random(0, 1) -- direction + local time = random() * 1.9 + 0.5 local velocity, acceleration if o == 1 then - velocity = {x = math.random() * 0.7 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5} - acceleration = {x = math.random() * 1.1 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5} + velocity = {x = random() * 0.7 + 0.3, y = random() - 0.5, z = random() - 0.5} + acceleration = {x = random() * 1.1 + 0.3, y = random() - 0.5, z = random() - 0.5} else - velocity = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 0.7 + 0.3} - acceleration = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 1.1 + 0.3} + velocity = {x = random() - 0.5, y = random() - 0.5, z = random() * 0.7 + 0.3} + acceleration = {x = random() - 0.5, y = random() - 0.5, z = random() * 1.1 + 0.3} end - local distance = vector.add(vector.multiply(velocity, time), vector.multiply(acceleration, time * time / 2)) + local distance = add(mul(velocity, time), mul(acceleration, time * time / 2)) if d == 1 then if o == 1 then distance.x = -distance.x @@ -793,11 +825,11 @@ minetest.register_abm({ acceleration.z = -acceleration.z end end - distance = vector.subtract(pos, distance) - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 15)) do + distance = sub(pos, distance) + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 15)) do if obj:is_player() then minetest.add_particlespawner({ - amount = node_particles_allowed_level + 1, + amount = PARTICLES + 1, minpos = distance, maxpos = distance, minvel = velocity, @@ -814,7 +846,7 @@ minetest.register_abm({ }) end end - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel + 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 if (obj:is_player() or lua_entity) and prevent_portal_chatter(obj) then teleport(obj, pos) @@ -826,25 +858,41 @@ minetest.register_abm({ --[[ ITEM OVERRIDES ]] -local longdesc = minetest.registered_nodes["mcl_core:obsidian"]._doc_items_longdesc +local longdesc = registered_nodes[OBSIDIAN]._doc_items_longdesc longdesc = longdesc .. "\n" .. S("Obsidian is also used as the frame of Nether portals.") local usagehelp = S("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.") -minetest.override_item("mcl_core:obsidian", { +minetest.override_item(OBSIDIAN, { _doc_items_longdesc = longdesc, _doc_items_usagehelp = usagehelp, - on_destruct = destroy_nether_portal, + after_destruct = function(pos, node) + local function check_remove(pos, orientation) + local node = get_node(pos) + if node and node.name == PORTAL then + minetest.remove_node(pos) + end + end + + -- check each of 6 sides of it and destroy every portal + check_remove({x = pos.x - 1, y = pos.y, z = pos.z}) + check_remove({x = pos.x + 1, y = pos.y, z = pos.z}) + check_remove({x = pos.x, y = pos.y, z = pos.z - 1}) + check_remove({x = pos.x, y = pos.y, z = pos.z + 1}) + check_remove({x = pos.x, y = pos.y - 1, z = pos.z}) + check_remove({x = pos.x, y = pos.y + 1, z = pos.z}) + end, + _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: - local portals_placed = + 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 - minetest.log("action", "[mcl_portal] Nether portal activated at "..minetest.pos_to_string({x=x,y=y,z=z})..".") + log("action", "[mcl_portals] 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", "mcl_portals:portal") + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", PORTAL) -- Achievement for finishing a Nether portal TO the Nether local dim = mcl_worlds.pos_to_dimension({x=x, y=y, z=z}) @@ -859,3 +907,17 @@ minetest.override_item("mcl_core:obsidian", { end, }) +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" + }, +}) diff --git a/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts new file mode 100644 index 000000000..b5d75cdbf Binary files /dev/null and b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal.mts differ diff --git a/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts new file mode 100644 index 000000000..a1c6c79ce Binary files /dev/null and b/mods/ITEMS/mcl_portals/schematics/mcl_portals_nether_portal_open.mts differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_end_portal.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_end_portal.png deleted file mode 100644 index 46d548e92..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_end_portal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_side.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_side.png deleted file mode 100644 index a2370ecef..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle1.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle1.png deleted file mode 100644 index 6695291eb..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle2.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle2.png deleted file mode 100644 index 99b3a191a..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle3.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle3.png deleted file mode 100644 index 3000a799c..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle4.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle4.png deleted file mode 100644 index 28d14cbd6..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle5.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_particle5.png deleted file mode 100644 index fbd67375a..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_particle5.png and /dev/null differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_portal.png b/mods/ITEMS/mcl_portals/textures/mcl_portals_portal.png deleted file mode 100644 index a47f4f4e3..000000000 Binary files a/mods/ITEMS/mcl_portals/textures/mcl_portals_portal.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/commands.lua b/mods/ITEMS/mcl_potions/commands.lua index ad1d65b7f..76ac71e72 100644 --- a/mods/ITEMS/mcl_potions/commands.lua +++ b/mods/ITEMS/mcl_potions/commands.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_potions") +local S = minetest.get_translator(minetest.get_current_modname()) -- ░█████╗░██╗░░██╗░█████╗░████████╗  ░█████╗░░█████╗░███╗░░░███╗███╗░░░███╗░█████╗░███╗░░██╗██████╗░░██████╗ -- ██╔══██╗██║░░██║██╔══██╗╚══██╔══╝  ██╔══██╗██╔══██╗████╗░████║████╗░████║██╔══██╗████╗░██║██╔══██╗██╔════╝ @@ -19,6 +19,7 @@ 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(" []"), diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index f1384ab30..de3f6df10 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -9,6 +9,7 @@ EF.leaping = {} EF.swift = {} -- for swiftness AND slowness EF.night_vision = {} EF.fire_proof = {} +EF.bad_omen = {} local EFFECT_TYPES = 0 for _,_ in pairs(EF) do @@ -35,13 +36,13 @@ local function potions_init_icons(player) local name = player:get_player_name() icon_ids[name] = {} for e=1, EFFECT_TYPES do - local x = -7 + -38 * e + local x = -52 * e - 2 local id = player:hud_add({ hud_elem_type = "image", text = "blank.png", position = { x = 1, y = 0 }, - offset = { x = x, y = 272 }, - scale = { x = 2, y = 2 }, + offset = { x = x, y = 3 }, + scale = { x = 0.375, y = 0.375 }, alignment = { x = 1, y = 1 }, z_index = 100, }) @@ -70,7 +71,7 @@ local function potions_set_icons(player) if effect_name == nil then player:hud_change(icon, "text", "blank.png") else - player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png") + player:hud_change(icon, "text", "mcl_potions_effect_"..effect_name..".png^[resize:128x128") end end @@ -107,7 +108,7 @@ minetest.register_globalstep(function(dtime) EF.invisible[player].timer = EF.invisible[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#B0B0B0") end + 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) @@ -116,6 +117,8 @@ minetest.register_globalstep(function(dtime) meta = player:get_meta() meta:set_string("_is_invisible", minetest.serialize(EF.invisible[player])) end + potions_set_hud(player) + end end @@ -129,20 +132,13 @@ minetest.register_globalstep(function(dtime) 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, "#225533") end + if player:get_pos() then mcl_potions._add_spawner(player, "#4E9331") end if EF.poisoned[player].hit_timer >= EF.poisoned[player].step then - - if entity and entity._cmi_is_mob then - entity.health = math.max(entity.health - 1, 1) - EF.poisoned[player].hit_timer = 0 - elseif is_player then - player:set_hp( math.max(player:get_hp() - 1, 1), { type = "punch", other = "poison"}) - EF.poisoned[player].hit_timer = 0 - else -- if not player or mob then remove - EF.poisoned[player] = nil + 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 @@ -165,14 +161,14 @@ minetest.register_globalstep(function(dtime) 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, "#A52BB2") end + 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._cmi_is_mob then + 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 @@ -199,9 +195,10 @@ minetest.register_globalstep(function(dtime) EF.water_breathing[player].timer = EF.water_breathing[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#0000AA") end + 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 @@ -210,6 +207,7 @@ minetest.register_globalstep(function(dtime) 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 @@ -224,7 +222,7 @@ minetest.register_globalstep(function(dtime) EF.leaping[player].timer = EF.leaping[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#00CC33") end + 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") @@ -232,6 +230,7 @@ minetest.register_globalstep(function(dtime) meta = player:get_meta() meta:set_string("_is_leaping", minetest.serialize(EF.leaping[player])) end + potions_set_hud(player) else EF.leaping[player] = nil @@ -246,7 +245,7 @@ minetest.register_globalstep(function(dtime) EF.swift[player].timer = EF.swift[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#009999") end + 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") @@ -254,6 +253,7 @@ minetest.register_globalstep(function(dtime) meta = player:get_meta() meta:set_string("_is_swift", minetest.serialize(EF.swift[player])) end + potions_set_hud(player) else EF.swift[player] = nil @@ -268,7 +268,7 @@ minetest.register_globalstep(function(dtime) EF.night_vision[player].timer = EF.night_vision[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#1010AA") end + 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 @@ -277,6 +277,7 @@ minetest.register_globalstep(function(dtime) meta:set_int("night_vision", 0) end mcl_weather.skycolor.update_sky_color({player}) + potions_set_hud(player) else EF.night_vision[player] = nil @@ -293,13 +294,14 @@ minetest.register_globalstep(function(dtime) EF.fire_proof[player].timer = EF.fire_proof[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#E0B050") end + 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 @@ -314,7 +316,7 @@ minetest.register_globalstep(function(dtime) EF.weak[player].timer = EF.weak[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#7700BB") end + 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 @@ -335,7 +337,7 @@ minetest.register_globalstep(function(dtime) EF.strong[player].timer = EF.strong[player].timer + dtime - if player:get_pos() then mcl_potions._add_spawner(player, "#7700BB") end + 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 @@ -349,39 +351,34 @@ minetest.register_globalstep(function(dtime) end -end) + -- Check for Bad Omen + for player, vals in pairs(EF.bad_omen) do + is_player = player:is_player() -local is_fire_node = { ["mcl_core:lava_flowing"]=true, - ["mcl_core:lava_source"]=true, - ["mcl_fire:eternal_fire"]=true, - ["mcl_fire:fire"]=true, - ["mcl_nether:magma"]=true, - ["mcl_nether:nether_lava_source"]=true, - ["mcl_nether:nether_lava_flowing"]=true, - ["mcl_nether:nether_lava_source"]=true -} + EF.bad_omen[player].timer = EF.bad_omen[player].timer + dtime --- Prevent damage to player with Fire Resistance enabled -minetest.register_on_player_hpchange(function(player, hp_change, reason) + if player:get_pos() then mcl_potions._add_spawner(player, "#0b6138") end - if EF.fire_proof[player] and hp_change < 0 then - -- This is a bit forced, but it assumes damage is taken by fire and avoids it - -- also assumes any change in hp happens between calls to this function - -- it's worth noting that you don't take damage from players in this case... - local player_info = mcl_playerinfo[player:get_player_name()] - - if is_fire_node[player_info.node_head] or is_fire_node[player_info.node_feet] or is_fire_node[player_info.node_stand] then - return 0 - else - return hp_change + 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 - else - return hp_change end -end, true) +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) @@ -399,38 +396,42 @@ end, true) -- ███████╗╚█████╔╝██║░░██║██████╔╝██╔╝░░░██████╔╝██║░░██║░░╚██╔╝░░███████╗ -- ╚══════╝░╚════╝░╚═╝░░╚═╝╚═════╝░╚═╝░░░░╚═════╝░╚═╝░░╚═╝░░░╚═╝░░░╚══════╝ - -function mcl_potions._reset_player_effects(player, set_hud) - - if not player:is_player() then - return - end - meta = player:get_meta() - - mcl_potions.make_invisible(player, false) +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 + + meta = player: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 + end + + mcl_potions.make_invisible(player, false) + playerphysics.remove_physics_factor(player, "jump", "mcl_potions:leaping") - EF.swift[player] = nil playerphysics.remove_physics_factor(player, "speed", "mcl_potions:swiftness") - EF.night_vision[player] = nil - meta:set_int("night_vision", 0) mcl_weather.skycolor.update_sky_color({player}) - EF.fire_proof[player] = nil + mcl_potions._clear_cached_player_data(player) if set_hud ~= false then potions_set_hud(player) end - end function mcl_potions._save_player_effects(player) @@ -450,6 +451,7 @@ function mcl_potions._save_player_effects(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])) end @@ -501,6 +503,10 @@ function mcl_potions._load_player_effects(player) 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 @@ -511,9 +517,21 @@ function mcl_potions.player_has_effect(player, effect_name) return EF[effect_name][player] ~= nil end +function mcl_potions.player_get_effect(player, effect_name) + if not EF[effect_name] or not EF[effect_name][player] then + return false + end + return EF[effect_name][player] +end + +function mcl_potions.player_clear_effect(player,effect) + EF[effect][player] = nil + potions_set_icons(player) +end + minetest.register_on_leaveplayer( function(player) mcl_potions._save_player_effects(player) - mcl_potions._reset_player_effects(player) -- clearout the buffer to prevent looking for a player not there + mcl_potions._clear_cached_player_data(player) -- clearout the buffer to prevent looking for a player not there icon_ids[player:get_player_name()] = nil end) @@ -539,7 +557,7 @@ end) minetest.register_on_shutdown(function() -- save player effects on server shutdown - for _,player in ipairs(minetest.get_connected_players()) do + for _,player in pairs(minetest.get_connected_players()) do mcl_potions._save_player_effects(player) end @@ -569,7 +587,7 @@ function mcl_potions.is_obj_hit(self, pos) if entity and entity.name ~= self.object:get_luaentity().name then - if entity._cmi_is_mob then + if entity.is_mob then return true end @@ -582,35 +600,24 @@ function mcl_potions.is_obj_hit(self, pos) end -function mcl_potions.make_invisible(player, toggle) - - if not player then - return false - end - - local is_player = player:is_player() - local entity = player:get_luaentity() - - if toggle then -- hide player - - if player:is_player() then - EF.invisible[player].old_size = player:get_properties().visual_size - elseif entity then - EF.invisible[player].old_size = entity.visual_size - else -- if not a player or entity, do nothing - return +function mcl_potions.make_invisible(obj_ref, hide) + if obj_ref:is_player() then + if hide then + mcl_player.player_set_visibility(obj_ref, false) + obj_ref:set_nametag_attributes({ color = { a = 0 } }) + else + mcl_player.player_set_visibility(obj_ref, true) + obj_ref:set_nametag_attributes({ color = { r = 255, g = 255, b = 255, a = 255 } }) + end + else + if hide then + local luaentity = obj_ref:get_luaentity() + EF.invisible[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 }) end - - player:set_properties({visual_size = {x = 0, y = 0}}) - player:set_nametag_attributes({color = {a = 0}}) - - elseif EF.invisible[player] then -- show player - - player:set_properties({visual_size = EF.invisible[player].old_size}) - player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}}) - end - end @@ -688,6 +695,10 @@ function mcl_potions.healing_func(player, hp) local obj = player:get_luaentity() + if player:get_hp() == 0 then + return + end + if obj and obj.harmed_by_heal then hp = -hp end if hp > 0 then @@ -696,7 +707,7 @@ function mcl_potions.healing_func(player, hp) hp = 1 end - if obj and obj._cmi_is_mob then + 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" }) @@ -707,12 +718,7 @@ function mcl_potions.healing_func(player, hp) hp = -1 end - if obj and obj._cmi_is_mob then - obj.health = obj.health + hp - elseif player:is_player() then - player:set_hp(player:get_hp() + hp, { type = "punch", other = "harming" }) - end - + mcl_util.deal_damage(player, -hp, {type = "magic"}) end end @@ -1000,3 +1006,17 @@ function mcl_potions._extinguish_nearby_fire(pos, radius) 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 +end diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index b7f814c24..2ea7e2879 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -1,4 +1,7 @@ -local S = minetest.get_translator("mcl_potions") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + mcl_potions = {} -- duration effects of redstone are a factor of 8/3 @@ -16,8 +19,6 @@ mcl_potions.INV_FACTOR = 0.50 mcl_potions.SPLASH_FACTOR = 0.75 mcl_potions.LINGERING_FACTOR = 0.25 - -local modpath = minetest.get_modpath("mcl_potions") dofile(modpath .. "/functions.lua") dofile(modpath .. "/commands.lua") dofile(modpath .. "/splash.lua") @@ -25,11 +26,9 @@ dofile(modpath .. "/lingering.lua") dofile(modpath .. "/tipped_arrow.lua") dofile(modpath .. "/potions.lua") -local brewhelp = S("Try different combinations to create potions.") - minetest.register_craftitem("mcl_potions:fermented_spider_eye", { description = S("Fermented Spider Eye"), - _doc_items_longdesc = brewhelp, + _doc_items_longdesc = S("Try different combinations to create potions."), wield_image = "mcl_potions_spider_eye_fermented.png", inventory_image = "mcl_potions_spider_eye_fermented.png", groups = { brewitem = 1, }, @@ -65,14 +64,12 @@ minetest.register_craftitem("mcl_potions:glass_bottle", { -- Try to fill glass bottle with water local get_water = false - local from_liquid_source = false + --local from_liquid_source = false local river_water = false - if not def then - -- Unknown node: no-op - elseif def.groups and def.groups.water and def.liquidtype == "source" then + if def and def.groups and def.groups.water and def.liquidtype == "source" then -- Water source get_water = true - from_liquid_source = true + --from_liquid_source = true river_water = node.name == "mclx_core:river_water_source" -- Or reduce water level of cauldron by 1 elseif string.sub(node.name, 1, 14) == "mcl_cauldrons:" then @@ -147,7 +144,7 @@ minetest.register_craft( { -- Template function for creating images of filled potions -- - colorstring must be a ColorString of form “#RRGGBB”, e.g. “#0000FF” for blue. -- - opacity is optional opacity from 0-255 (default: 127) -local potion_image = function(colorstring, opacity) +local function potion_image(colorstring, opacity) if not opacity then opacity = 127 end @@ -179,6 +176,76 @@ local fill_cauldron = function(cauldron, water_type) end end +-- function to set node and empty water bottle (used for cauldrons and mud) +local function set_node_empty_bottle(itemstack, placer, pointed_thing, newitemstring) + local pname = placer:get_player_name() + if minetest.is_protected(pointed_thing.under, pname) then + minetest.record_protection_violation(pointed_thing.under, pname) + return itemstack + end + + -- set the node to `itemstring` + minetest.set_node(pointed_thing.under, {name=newitemstring}) + + -- 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 + return "mcl_potions:glass_bottle" + end +end + +-- used for water bottles and river water bottles +local function dispense_water_bottle(stack, pos, droppos) + local node = minetest.get_node(droppos) + if node.name == "mcl_core:dirt" or node.name == "mcl_core:coarse_dirt" then + -- convert dirt/coarse dirt to mud + minetest.set_node(droppos, {name = "mcl_mud:mud"}) + minetest.sound_play("mcl_potions_bottle_pour", {pos=droppos, gain=0.5, max_hear_range=16}, true) + return ItemStack("mcl_potions:glass_bottle") + + elseif node.name == "mcl_mud:mud" then + -- dont dispense into mud + return stack + end +end + +-- on_place function for `mcl_potions:water` and `mcl_potions:river_water` + +local function water_bottle_on_place(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + local def = minetest.registered_nodes[node.name] + + -- Call on_rightclick if the pointed node defines it + if placer and not placer:get_player_control().sneak then + if def and def.on_rightclick then + return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack + end + end + + local cauldron = nil + if itemstack:get_name() == "mcl_potions:water" then -- regular water + cauldron = fill_cauldron(node.name, "mcl_core:water_source") + elseif itemstack:get_name() == "mcl_potions:river_water" then -- river water + cauldron = fill_cauldron(node.name, "mclx_core:river_water_source") + end + + + if cauldron then + set_node_empty_bottle(itemstack, placer, pointed_thing, cauldron) + elseif node.name == "mcl_core:dirt" or node.name == "mcl_core:coarse_dirt" then + set_node_empty_bottle(itemstack, placer, pointed_thing, "mcl_mud:mud") + end + end + + -- Drink the water by default + return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) +end + -- Itemstring of potions is “mcl_potions:” minetest.register_craftitem("mcl_potions:water", { @@ -190,39 +257,9 @@ minetest.register_craftitem("mcl_potions:water", { inventory_image = potion_image("#0022FF"), wield_image = potion_image("#0022FF"), groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - local def = minetest.registered_nodes[node.name] - - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if def and def.on_rightclick then - return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - local cauldron = fill_cauldron(node.name, "mcl_core:water_source") - if cauldron then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - -- Increase water level of cauldron by 1 - minetest.set_node(pointed_thing.under, {name=cauldron}) - 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 - return "mcl_potions:glass_bottle" - end - end - end - - -- Drink the water by default - return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) - end, + on_place = water_bottle_on_place, + _on_dispense = dispense_water_bottle, + _dispense_into_walkable = true, on_secondary_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), }) @@ -237,45 +274,15 @@ minetest.register_craftitem("mcl_potions:river_water", { inventory_image = potion_image("#0044FF"), wield_image = potion_image("#0044FF"), groups = {brewitem=1, food=3, can_eat_when_full=1, water_bottle=1}, - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - local def = minetest.registered_nodes[node.name] - - -- Call on_rightclick if the pointed node defines it - if placer and not placer:get_player_control().sneak then - if def and def.on_rightclick then - return def.on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack - end - end - - local cauldron = fill_cauldron(node.name, "mclx_core:river_water_source") - if cauldron then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - -- Increase water level of cauldron by 1 - minetest.set_node(pointed_thing.under, {name=cauldron}) - 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 - return "mcl_potions:glass_bottle" - end - end - end - - -- Drink the water by default - return minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, placer, pointed_thing) - end, + on_place = water_bottle_on_place, + _on_dispense = dispense_water_bottle, + _dispense_into_walkable = true, on_secondary_use = minetest.item_eat(0, "mcl_potions:glass_bottle"), }) -- Hurt mobs -local water_splash = function(obj, damage) +local function water_splash(obj, damage) if not obj then return end @@ -284,7 +291,7 @@ local water_splash = function(obj, damage) end -- Damage mobs that are vulnerable to water local lua = obj:get_luaentity() - if lua and lua._cmi_is_mob then + if lua and lua.is_mob then obj:punch(obj, 1.0, { full_punch_interval = 1.0, damage_groups = {water_vulnerable=damage}, @@ -318,9 +325,9 @@ minetest.register_craftitem("mcl_potions:speckled_melon", { minetest.register_craft({ output = "mcl_potions:speckled_melon", recipe = { - {'mcl_core:gold_nugget', 'mcl_core:gold_nugget', 'mcl_core:gold_nugget'}, - {'mcl_core:gold_nugget', 'mcl_farming:melon_item', 'mcl_core:gold_nugget'}, - {'mcl_core:gold_nugget', 'mcl_core:gold_nugget', 'mcl_core:gold_nugget'}, + {"mcl_core:gold_nugget", "mcl_core:gold_nugget", "mcl_core:gold_nugget"}, + {"mcl_core:gold_nugget", "mcl_farming:melon_item", "mcl_core:gold_nugget"}, + {"mcl_core:gold_nugget", "mcl_core:gold_nugget", "mcl_core:gold_nugget"}, } }) @@ -432,22 +439,20 @@ local mod_table = { -- Compare two ingredients for compatable alchemy function mcl_potions.get_alchemy(ingr, pot) - - if output_table[pot] ~= nil then + if output_table[pot] then local brew_table = output_table[pot] - if brew_table[ingr] ~= nil then + if brew_table[ingr] then return brew_table[ingr] end - end - if mod_table[ingr] ~= nil then + if mod_table[ingr] then local brew_table = mod_table[ingr] - if brew_table[pot] ~= nil then + if brew_table[pot] then return brew_table[pot] end @@ -455,3 +460,12 @@ function mcl_potions.get_alchemy(ingr, pot) return false 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 cea045233..17088ad13 100644 --- a/mods/ITEMS/mcl_potions/lingering.lua +++ b/mods/ITEMS/mcl_potions/lingering.lua @@ -1,19 +1,18 @@ -local S = minetest.get_translator("mcl_potions") +local S = minetest.get_translator(minetest.get_current_modname()) -local lingering_image = function(colorstring, opacity) +local mod_target = minetest.get_modpath("mcl_target") + +local function lingering_image(colorstring, opacity) if not opacity then opacity = 127 end return "mcl_potions_splash_overlay.png^[colorize:"..colorstring..":"..tostring(opacity).."^mcl_potions_lingering_bottle.png" 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} - end local function linger_particles(pos, d, texture, color) @@ -67,7 +66,7 @@ minetest.register_globalstep(function(dtime) for _, obj in pairs(minetest.get_objects_inside_radius(pos, d)) do local entity = obj:get_luaentity() - if obj:is_player() or entity._cmi_is_mob then + if obj:is_player() or entity.is_mob then vals.def.potion_fun(obj) -- TODO: Apply timer penalty only if the potion effect was acutally applied @@ -98,71 +97,74 @@ function mcl_potions.register_lingering(name, descr, color, def) end end minetest.register_craftitem(id, { - description = descr, - _tt_help = def.tt, - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = S("Use the “Punch” key to throw it."), - inventory_image = lingering_image(color), - groups = {brewitem=1, not_in_creative_inventory=0}, - 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() - if not minetest.is_creative_enabled(placer:get_player_name()) then - item:take_item() + description = descr, + _tt_help = def.tt, + _doc_items_longdesc = longdesc, + _doc_items_usagehelp = S("Use the “Punch” key to throw it."), + inventory_image = lingering_image(color), + groups = {brewitem=1, not_in_creative_inventory=0}, + 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() + if not minetest.is_creative_enabled(placer:get_player_name()) then + item:take_item() + end + return item + end, + stack_max = 1, + _on_dispense = function(stack, dispenserpos, droppos, dropnode, dropdir) + local s_pos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) + local pos = {x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z} + minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) + local obj = minetest.add_entity(pos, id.."_flying") + 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}) end - return item - end, - stack_max = 1, - _on_dispense = function(stack, dispenserpos, droppos, dropnode, dropdir) - local s_pos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) - local pos = {x=s_pos.x+dropdir.x,y=s_pos.y+dropdir.y,z=s_pos.z+dropdir.z} - minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true) - local obj = minetest.add_entity(pos, id.."_flying") - 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}) - end -}) + }) -local w = 0.7 + local w = 0.7 -minetest.register_entity(id.."_flying",{ - textures = {lingering_image(color)}, - hp_max = 1, - visual_size = {x=w/2,y=w/2}, - collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1}, - pointable = false, - on_step = function(self, dtime) - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local n = node.name - local g = minetest.get_node_group(n, "liquid") - local d = 4 - 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 texture - if name == "water" then - texture = "mcl_particles_droplet_bottle.png" - else - if def.instant then - texture = "mcl_particles_instant_effect.png" + minetest.register_entity(id.."_flying",{ + textures = {lingering_image(color)}, + hp_max = 1, + visual_size = {x=w/2,y=w/2}, + collisionbox = {-0.1,-0.1,-0.1,0.1,0.1,0.1}, + pointable = false, + on_step = function(self, dtime) + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local n = node.name + local g = minetest.get_item_group(n, "liquid") + local d = 4 + if mod_target and n == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + 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 texture + if name == "water" then + texture = "mcl_particles_droplet_bottle.png" else - texture = "mcl_particles_effect.png" + if def.instant then + texture = "mcl_particles_instant_effect.png" + else + texture = "mcl_particles_effect.png" + end end + linger_particles(pos, d, texture, color) + if name == "water" then + mcl_potions._extinguish_nearby_fire(pos, d) + end + self.object:remove() end - linger_particles(pos, d, texture, color) - if name == "water" then - mcl_potions._extinguish_nearby_fire(pos, d) - end - self.object:remove() - end - end, -}) + end, + }) end diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.de.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.de.tr index 36f5280b9..34693d531 100644 --- a/mods/ITEMS/mcl_potions/locale/mcl_potions.de.tr +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.de.tr @@ -112,18 +112,3 @@ No effect=Keine Wirkung A throwable potion that will shatter on impact, where it gives all nearby players and mobs a status effect.=Ein werfbarer Trank, der bei Kollision zerbrechen wird, wo er allen nahen Spielern und Mobs einen Statuseffekt geben wird. This particular arrow is tipped and will give an effect when it hits a player or mob.=Diese Pfeilspitze dieses Pfeils in einem Trank getränkt und gibt einen Effekt, wenn er einen Spieler oder einen Mob trifft. - - - -##### not used anymore ##### - -Lingering Weakness Potion=Schwächeverweiltrank -Lingering Weakness Potion +=Schwächeverweiltrank + -Lingering Strength Potion=Stärkeverweiltrank -Lingering Strength Potion II=Stärkeverweiltrank II -Lingering Strength Potion +=Stärkeverweiltrank + -Weakness Splash Potion=Schwächewurftrank -Weakness Splash Potion +=Schwächewurftrank + -Strength Splash Potion=Stärkewurftrank -Strength Splash Potion II=Stärkewurftrank II -Strength Splash Potion +=Stärkewurftrank + diff --git a/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr index 7cfe1f188..1547a36c0 100644 --- a/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.fr.tr @@ -1,13 +1,13 @@ # 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%)= +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%) -Missing effect parameter!= -Missing or invalid duration parameter!= -Invalid factor parameter!= -@1 is not an available status effect.= -Fermented Spider Eye=Oeil d'araignée fermenté +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 @@ -25,91 +25,91 @@ River water bottles can be used to fill cauldrons. Drinking it has no effect.=Le 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. -Splash Water Bottle= -Extinguishes fire and hurts some mobs= +Splash Water Bottle=Bouteille d'eau jetable +Extinguishes fire and hurts some mobs=Éteint le feu et blesse certains 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.=Une bouteille d'eau jetable qui se brisera à l'impact, où elle éteint le feu à proximité et blesse les mobs vulnérables à l'eau. -Lingering Water Bottle= +Lingering Water Bottle=Bouteille d'eau persistante -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.=Une bouteille d'eau jetable qui se brisera à l'impact, où elle crée un nuage de vapeur d'eau qui s'attarde au sol pendant un moment. Ce nuage éteint le feu et blesse les mobs vulnérables à l'eau. 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.= +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.= +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.= -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=Potion maladroite -Awkward Splash Potion= -Awkward Lingering Potion= -Has an awkward taste and is used for brewing potions.= -Mundane Potion=Potion mondaine -Mundane Splash Potion= -Mundane Lingering Potion= -Has a terrible taste and is not useful for brewing potions.= +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= -Thick Lingering Potion= -Has a bitter taste and is not useful for brewing potions.= -Dragon's Breath=Le souffle du dragon +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.= +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= -+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.= +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.= +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.= +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.ja.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.ja.tr new file mode 100644 index 000000000..89e8fc9ab --- /dev/null +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.ja.tr @@ -0,0 +1,115 @@ +# 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%)=自分自身にステータス効果を付加する。引数は以下の通り。<エフェクト>: ステータス効果の名前。 <デュレーション>:継続時間(秒)。 <ファクター>: 効果の強さの倍率 (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=ガラス瓶 +Liquid container=液体用容器 + +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).=水を集めるには、水の入った釜(水を1レベル取り除く)か、水源(水を全く取り除かない)に使用します。 + +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.=飲むときは「置く」キーを使用します。このアイテムを大釜の上に置くと水を注げます。 + +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.=「置く」キーで飲むことができます。このアイテムを大釜の上に置くと河川水を注げます。 + +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.=投げられる水入り瓶で、衝撃で粉々になり、そこで近くの火を消したり、水に弱いモブにダメージを与えます。 + +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.=投げられる水入り瓶で、衝撃で粉々になり、そこで水蒸気の雲を作り、しばらく地面に留まります。この雲は火を消し、水に弱いモブにダメージを与えます。 + +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/@1s | @2 +@1 HP=@1 HP +@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) +Arrow of @1@2=@1@2 の矢 +@1 + Potion=ポーション(@1 +) +Splash @1 + Potion=飛散ポーション(@1 +) +Lingering @1 + Potion=滞留ポーション(@1 +) +Arrow of @1 +=@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=+4 HP ++8 HP=+8 HP +Instantly heals.=即座に治癒します。 +Harming=負傷 +-6 HP=-6 HP +-12 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=剛力 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/locale/mcl_potions.pl.tr b/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr new file mode 100644 index 000000000..abf61d4d3 --- /dev/null +++ b/mods/ITEMS/mcl_potions/locale/mcl_potions.pl.tr @@ -0,0 +1,115 @@ +# 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%)=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 +Glass Bottle=Szklana butelka +Liquid container=Pojemnik na płyn + +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. + +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. + +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ę. + +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ę. + +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/mod.conf b/mods/ITEMS/mcl_potions/mod.conf index 3d6fd0011..bcb6d8ad3 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 +depends = mcl_core, mcl_farming, mcl_mobitems, 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 4a82348e5..3d89d1d40 100644 --- a/mods/ITEMS/mcl_potions/potions.lua +++ b/mods/ITEMS/mcl_potions/potions.lua @@ -1,7 +1,7 @@ -local S = minetest.get_translator("mcl_potions") -local brewhelp = S("Try different combinations to create potions.") +local S = minetest.get_translator(minetest.get_current_modname()) +--local brewhelp = S("Try different combinations to create potions.") -local potion_image = function(colorstring, opacity) +local function potion_image(colorstring, opacity) if not opacity then opacity = 127 end @@ -98,7 +98,7 @@ local function register_potion(def) end elseif def.name == "healing" or def.name == "harming" then _tt = S("@1 HP", effect) - else + else _tt = tt or time_string(dur) or S("No effect") end return _tt @@ -459,7 +459,7 @@ local healing_def = { _tt = S("+4 HP"), _tt_2 = S("+8 HP"), _longdesc = S("Instantly heals."), - color = "#CC0000", + color = "#F82423", effect = 4, instant = true, on_use = mcl_potions.healing_func, @@ -473,7 +473,7 @@ local harming_def = { _tt = S("-6 HP"), _tt_II = S("-12 HP"), _longdesc = S("Instantly deals damage."), - color = "#660099", + color = "#430A09", effect = -6, instant = true, on_use = mcl_potions.healing_func, @@ -486,7 +486,7 @@ local night_vision_def = { description = S("Night Vision"), _tt = nil, _longdesc = S("Increases the perceived brightness of light under a dark sky."), - color = "#1010AA", + color = "#1F1FA1", effect = nil, is_dur = true, on_use = mcl_potions.night_vision_func, @@ -498,7 +498,7 @@ local swiftness_def = { description = S("Swiftness"), _tt = nil, _longdesc = S("Increases walking speed."), - color = "#009999", + color = "#7CAFC6", effect = 1.2, is_dur = true, on_use = mcl_potions.swiftness_func, @@ -511,7 +511,7 @@ local slowness_def = { description = S("Slowness"), _tt = nil, _longdesc = S("Decreases walking speed."), - color = "#000080", + color = "#5A6C81", effect = 0.85, is_dur = true, on_use = mcl_potions.swiftness_func, @@ -525,7 +525,7 @@ local leaping_def = { description = S("Leaping"), _tt = nil, _longdesc = S("Increases jump strength."), - color = "#00CC33", + color = "#22FF4C", effect = 1.15, is_dur = true, on_use = mcl_potions.leaping_func, @@ -538,7 +538,7 @@ local poison_def = { description = S("Poison"), _tt = nil, _longdesc = S("Applies the poison effect which deals damage at a regular interval."), - color = "#447755", + color = "#4E9331", effect = 2.5, is_dur = true, on_use = mcl_potions.poison_func, @@ -552,7 +552,7 @@ local regeneration_def = { description = S("Regeneration"), _tt = nil, _longdesc = S("Regenerates health over time."), - color = "#B52CC2", + color = "#CD5CAB", effect = 2.5, is_dur = true, on_use = mcl_potions.regeneration_func, @@ -565,7 +565,7 @@ local invisibility_def = { description = S("Invisibility"), _tt = nil, _longdesc = S("Grants invisibility."), - color = "#B0B0B0", + color = "#7F8392", is_dur = true, on_use = mcl_potions.invisiblility_func, is_plus = true, @@ -576,7 +576,7 @@ local water_breathing_def = { description = S("Water Breathing"), _tt = nil, _longdesc = S("Grants limitless breath underwater."), - color = "#0000AA", + color = "#2E5299", is_dur = true, on_use = mcl_potions.water_breathing_func, is_plus = true, @@ -587,7 +587,7 @@ local fire_resistance_def = { description = S("Fire Resistance"), _tt = nil, _longdesc = S("Grants immunity to damage from heat sources like fire."), - color = "#D0A040", + color = "#E49A3A", is_dur = true, on_use = mcl_potions.fire_resistance_func, is_plus = true, @@ -611,22 +611,22 @@ end -- description = S("Weakness"), -- _tt_help = TODO, -- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#6600AA"), --- inventory_image = potion_image("#6600AA"), +-- 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, "#6600AA") +-- 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, "#6600AA") +-- mcl_potions._use_potion(itemstack, user, "#484D48") -- return itemstack -- end -- }) @@ -635,22 +635,22 @@ end -- description = S("Weakness +"), -- _tt_help = TODO, -- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#7700BB"), --- inventory_image = potion_image("#7700BB"), +-- 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, "#7700BB") +-- 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, "#7700BB") +-- mcl_potions._use_potion(itemstack, user, "#484D48") -- return itemstack -- end -- }) @@ -659,22 +659,22 @@ end -- description = S("Strength"), -- _tt_help = TODO, -- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#D444D4"), --- inventory_image = potion_image("#D444D4"), +-- 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, "#D444D4") +-- 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, "#D444D4") +-- mcl_potions._use_potion(itemstack, user, "#932423") -- return itemstack -- end -- }) @@ -683,22 +683,22 @@ end -- description = S("Strength II"), -- _tt_help = TODO, -- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#D444E4"), --- inventory_image = potion_image("#D444E4"), +-- 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, "#D444E4") +-- 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, "#D444E4") +-- mcl_potions._use_potion(itemstack, user, "#932423") -- return itemstack -- end -- }) @@ -707,22 +707,22 @@ end -- description = S("Strength +"), -- _tt_help = TODO, -- _doc_items_longdesc = brewhelp, --- wield_image = potion_image("#D444F4"), --- inventory_image = potion_image("#D444F4"), +-- 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, "#D444F4") +-- 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, "#D444F4") +-- 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 d5cf30782..730796952 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -1,7 +1,9 @@ -local S = minetest.get_translator("mcl_potions") +local S = minetest.get_translator(minetest.get_current_modname()) local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) -local splash_image = function(colorstring, opacity) +local mod_target = minetest.get_modpath("mcl_target") + +local function splash_image(colorstring, opacity) if not opacity then opacity = 127 end @@ -10,7 +12,6 @@ end function mcl_potions.register_splash(name, descr, color, def) - local id = "mcl_potions:"..name.."_splash" local longdesc = def.longdesc if not def.no_effect then @@ -64,9 +65,12 @@ function mcl_potions.register_splash(name, descr, color, def) local pos = self.object:get_pos() local node = minetest.get_node(pos) local n = node.name - local g = minetest.get_node_group(n, "liquid") + local g = minetest.get_item_group(n, "liquid") local d = 0.1 local redux_map = {7/8,0.5,0.25} + if mod_target and n == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + 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}) local texture, acc @@ -106,7 +110,7 @@ function mcl_potions.register_splash(name, descr, color, def) for _,obj in pairs(minetest.get_objects_inside_radius(pos, 4)) do local entity = obj:get_luaentity() - if obj:is_player() or entity._cmi_is_mob then + if obj:is_player() or 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)) @@ -123,6 +127,6 @@ function mcl_potions.register_splash(name, descr, color, def) }) end -local function time_string(dur) +--[[local function time_string(dur) return math.floor(dur/60)..string.format(":%02d",math.floor(dur % 60)) -end +end]] diff --git a/mods/ITEMS/mcl_potions/textures/hbhunger_icon_regen_poison.png b/mods/ITEMS/mcl_potions/textures/hbhunger_icon_regen_poison.png deleted file mode 100644 index d4fe9b4e0..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/hbhunger_icon_regen_poison.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/hudbars_icon_regenerate.png b/mods/ITEMS/mcl_potions/textures/hudbars_icon_regenerate.png deleted file mode 100644 index 4ae259897..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/hudbars_icon_regenerate.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_arrow_inv.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_arrow_inv.png deleted file mode 100644 index 4bda14bd5..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_arrow_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png deleted file mode 100644 index f5df4dab6..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_fire_proof.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png deleted file mode 100644 index 2490b0cfb..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_food_poisoning.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png deleted file mode 100644 index ffefb89bf..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_invisible.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png deleted file mode 100644 index 5614729ba..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_leaping.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png deleted file mode 100644 index 579defa71..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_night_vision.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png deleted file mode 100644 index 1b96ef2d9..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_poisoned.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png deleted file mode 100644 index 634b74fad..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_regenerating.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png deleted file mode 100644 index 1869a58ff..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_slow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png deleted file mode 100644 index 2a69bd4a8..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_strong.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png deleted file mode 100644 index 8ae960cc9..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_swift.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png deleted file mode 100644 index d68983b5a..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_water_breathing.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png deleted file mode 100644 index 9ac3985e2..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_effect_weak.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_lingering_bottle.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_lingering_bottle.png deleted file mode 100644 index 431fe5bc6..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_lingering_bottle.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_bottle.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_bottle.png deleted file mode 100644 index 17a69a8b6..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_bottle.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_overlay.png b/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_overlay.png deleted file mode 100644 index 9acbce6cd..000000000 Binary files a/mods/ITEMS/mcl_potions/textures/mcl_potions_splash_overlay.png and /dev/null differ diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index 31e7c1ddd..53a37705e 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -1,15 +1,20 @@ -local S = minetest.get_translator("mcl_potions") +local S = minetest.get_translator(minetest.get_current_modname()) + +local mod_target = minetest.get_modpath("mcl_target") + +local math = math + -- Time in seconds after which a stuck arrow is deleted local ARROW_TIMEOUT = 60 -- Time after which stuck arrow is rechecked for being stuck local STUCK_RECHECK_TIME = 5 -local GRAVITY = 9.81 +--local GRAVITY = 9.81 local YAW_OFFSET = -math.pi/2 -local dir_to_pitch = function(dir) - local dir2 = vector.normalize(dir) +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) local xz = math.abs(dir.x) + math.abs(dir.z) return -math.atan2(-dir.y, xz) end @@ -18,18 +23,14 @@ local function arrow_image(colorstring, opacity) if not opacity then opacity = 127 end - return {"mcl_bows_arrow.png^[transformFX^(mcl_bows_arrow_overlay.png^[transformFX^[colorize:"..colorstring..":"..tostring(opacity)..")", - "mcl_bows_arrow.png^[transformFX^(mcl_bows_arrow_overlay.png^[transformFX^[colorize:"..colorstring..":"..tostring(opacity)..")", - "mcl_bows_arrow_back.png^[colorize:"..colorstring..":"..tostring(opacity), - "mcl_bows_arrow_front.png^[colorize:"..colorstring..":"..tostring(opacity), - "mcl_bows_arrow.png^(mcl_bows_arrow_overlay.png^[colorize:"..colorstring..":"..tostring(opacity)..")", - "mcl_bows_arrow.png^[transformFX^(mcl_bows_arrow_overlay.png^[transformFX^[colorize:"..colorstring..":"..tostring(opacity)..")"} + return {"mcl_bows_arrow.png^(mcl_bows_arrow_overlay.png^[colorize:"..colorstring..":"..tostring(opacity)..")"} end local how_to_shoot = minetest.registered_items["mcl_bows:arrow"]._doc_items_usagehelp local mod_awards = minetest.get_modpath("awards") and minetest.get_modpath("mcl_achievements") local mod_button = minetest.get_modpath("mesecons_button") +local enable_pvp = minetest.settings:get_bool("enable_pvp") local arrow_longdesc = minetest.registered_items["mcl_bows:arrow"]._doc_items_longdesc or "" local arrow_tt = minetest.registered_items["mcl_bows:arrow"]._tt_help or "" @@ -84,6 +85,7 @@ function mcl_potions.register_arrow(name, desc, color, def) } }, tiles = arrow_image(color, 100), + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", paramtype2 = "facedir", sunlight_propagates = true, @@ -99,9 +101,10 @@ function mcl_potions.register_arrow(name, desc, color, def) local ARROW_ENTITY={ physical = true, - visual = "wielditem", - visual_size = {x=0.4, y=0.4}, - textures = {"mcl_potions:"..name.."_arrow_box"}, + visual = "mesh", + mesh = "mcl_bows_arrow.obj", + visual_size = {x=-1, y=1}, + textures = arrow_image(color, 100), collisionbox = {-0.19, -0.125, -0.19, 0.19, 0.125, 0.19}, collide_with_objects = false, @@ -119,7 +122,7 @@ function mcl_potions.register_arrow(name, desc, color, def) } -- Destroy arrow entity self at pos and drops it as an item - local spawn_item = function(self, pos) + local function spawn_item(self, pos) if not minetest.is_creative_enabled("") then local item = minetest.add_item(pos, "mcl_potions:"..name.."_arrow") item:set_velocity({x=0, y=0, z=0}) @@ -128,7 +131,7 @@ function mcl_potions.register_arrow(name, desc, color, def) self.object:remove() end - ARROW_ENTITY.on_step = function(self, dtime) + function ARROW_ENTITY.on_step(self, dtime) local pos = self.object:get_pos() local dpos = table.copy(pos) -- digital pos dpos = vector.round(dpos) @@ -176,6 +179,25 @@ function mcl_potions.register_arrow(name, desc, color, def) -- Check for object "collision". Done every tick (hopefully this is not too stressing) else + + if self._damage == 10 or self._damage == 9 then + minetest.add_particlespawner({ + amount = 1, + time = .001, + minpos = pos, + maxpos = pos, + minvel = vector.new(-0.1,-0.1,-0.1), + maxvel = vector.new(0.1,0.1,0.1), + minexptime = 0.5, + maxexptime = 0.5, + minsize = 2, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mobs_mc_arrow_particle.png", + glow = 1, + }) + end -- We just check for any hurtable objects nearby. -- The radius of 3 is fairly liberal, but anything lower than than will cause -- arrow to hilariously go through mobs often. @@ -189,35 +211,40 @@ function mcl_potions.register_arrow(name, desc, color, def) end -- Iterate through all objects and remember the closest attackable object - for k, obj in pairs(objs) do - local ok = false - -- Arrows can only damage players and mobs - if obj ~= self._shooter and obj:is_player() then - ok = true - elseif obj:get_luaentity() ~= nil then - if obj ~= self._shooter and obj:get_luaentity()._cmi_is_mob then + local arrow_dir = self.object:get_velocity() + --create a raycast from the arrow based on the velocity of the arrow to deal with lag + local raycast = minetest.raycast(pos, vector.add(pos, vector.multiply(arrow_dir, 0.1)), true, false) + for hitpoint in raycast do + if hitpoint.type == "object" then + -- find the closest object that is in the way of the arrow + local ok = false + if hitpoint.ref:is_player() and enable_pvp then ok = true + elseif not hitpoint.ref:is_player() and hitpoint.ref:get_luaentity() then + if (hitpoint.ref:get_luaentity().is_mob or hitpoint.ref:get_luaentity()._hittable_by_projectile) then + ok = true + end end - end - - if ok then - local dist = vector.distance(pos, obj:get_pos()) - if not closest_object or not closest_distance then - closest_object = obj - closest_distance = dist - elseif dist < closest_distance then - closest_object = obj - closest_distance = dist + if ok then + local dist = vector.distance(hitpoint.ref:get_pos(), pos) + if not closest_object or not closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + elseif dist < closest_distance then + closest_object = hitpoint.ref + closest_distance = dist + end end end end + -- If an attackable object was found, we will damage the closest one only - if closest_object ~= nil then + if closest_object then local obj = closest_object local is_player = obj:is_player() local lua = obj:get_luaentity() - if obj ~= self._shooter and (is_player or (lua and lua._cmi_is_mob)) then + if obj ~= self._shooter and (is_player or (lua and lua.is_mob)) then if obj:get_hp() > 0 then -- Check if there is no solid node between arrow and object @@ -257,7 +284,7 @@ function mcl_potions.register_arrow(name, desc, color, def) if is_player then if self._shooter and self._shooter:is_player() then -- “Ding” sound for hitting another player - minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter}, true) + minetest.sound_play({name="mcl_bows_hit_player", gain=0.1}, {to_player=self._shooter:get_player_name()}, true) end end @@ -323,6 +350,11 @@ function mcl_potions.register_arrow(name, desc, color, def) self.object:set_velocity({x=0, y=0, z=0}) self.object:set_acceleration({x=0, y=0, z=0}) + -- Activate target + if mod_target and snode.name == "mcl_target:target_off" then + mcl_target.hit(self._stuckin, 1) --10 redstone ticks + end + -- Push the button! Push, push, push the button! if mod_button and minetest.get_item_group(node.name, "button") > 0 and minetest.get_item_group(node.name, "button_push_by_arrow") == 1 then local bdir = minetest.wallmounted_to_dir(node.param2) @@ -338,7 +370,7 @@ function mcl_potions.register_arrow(name, desc, color, def) if not v then v = 0 end - local old_v = self._viscosity + --local old_v = self._viscosity self._viscosity = v local vpenalty = math.max(0.1, 0.98 - 0.1 * v) if math.abs(vel.x) > 0.001 then @@ -365,13 +397,13 @@ function mcl_potions.register_arrow(name, desc, color, def) -- Force recheck of stuck arrows when punched. -- Otherwise, punching has no effect. - ARROW_ENTITY.on_punch = function(self) + function ARROW_ENTITY.on_punch(self) if self._stuck then self._stuckrechecktimer = STUCK_RECHECK_TIME end end - ARROW_ENTITY.get_staticdata = function(self) + function ARROW_ENTITY.get_staticdata(self) local out = { lastpos = self._lastpos, startpos = self._startpos, @@ -392,7 +424,7 @@ function mcl_potions.register_arrow(name, desc, color, def) return minetest.serialize(out) end - ARROW_ENTITY.on_activate = function(self, staticdata, dtime_s) + function ARROW_ENTITY.on_activate(self, staticdata, dtime_s) local data = minetest.deserialize(staticdata) if data then self._stuck = data.stuck @@ -430,20 +462,18 @@ function mcl_potions.register_arrow(name, desc, color, def) minetest.register_entity("mcl_potions:"..name.."_arrow_entity", ARROW_ENTITY) if minetest.get_modpath("mcl_bows") then - minetest.register_craft({ - output = 'mcl_potions:'..name..'_arrow 8', + output = "mcl_potions:"..name.."_arrow 8", recipe = { - {'mcl_bows:arrow','mcl_bows:arrow','mcl_bows:arrow'}, - {'mcl_bows:arrow','mcl_potions:'..name..'_lingering','mcl_bows:arrow'}, - {'mcl_bows:arrow','mcl_bows:arrow','mcl_bows:arrow'} + {"mcl_bows:arrow","mcl_bows:arrow","mcl_bows:arrow"}, + {"mcl_bows:arrow","mcl_potions:"..name.."_lingering","mcl_bows:arrow"}, + {"mcl_bows:arrow","mcl_bows:arrow","mcl_bows:arrow"} } }) end - if minetest.get_modpath("doc_identifier") ~= nil then + if minetest.get_modpath("doc_identifier") then doc.sub.identifier.register_object("mcl_bows:arrow_entity", "craftitems", "mcl_bows:arrow") end - end diff --git a/mods/ITEMS/mcl_raw_ores/init.lua b/mods/ITEMS/mcl_raw_ores/init.lua new file mode 100644 index 000000000..be570068f --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/init.lua @@ -0,0 +1,59 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local function register_raw_ore(description, n) + local ore = description:lower() + local n = n or "" + local raw_ingot = "mcl_raw_ores:raw_"..ore + local texture = "mcl_raw_ores_raw_"..ore + + minetest.register_craftitem(raw_ingot, { + description = S("Raw "..description), + _doc_items_longdesc = S("Raw "..ore..". Mine a"..n.." "..ore.." ore to get it."), + inventory_image = texture..".png", + groups = { craftitem = 1, blast_furnace_smeltable = 1 }, + }) + + minetest.register_node(raw_ingot.."_block", { + description = S("Block of Raw "..description), + _doc_items_longdesc = S("A block of raw "..ore.." is mostly a decorative block but also useful as a compact storage of raw "..ore.."."), + tiles = { texture.."_block.png" }, + is_ground_content = false, + groups = { pickaxey = 2, building_block = 1, blast_furnace_smeltable = 1 }, + sounds = mcl_sounds.node_sound_metal_defaults(), + _mcl_blast_resistance = 6, + _mcl_hardness = 5, + }) + + minetest.register_craft({ + output = raw_ingot.."_block", + recipe = { + { raw_ingot, raw_ingot, raw_ingot }, + { raw_ingot, raw_ingot, raw_ingot }, + { raw_ingot, raw_ingot, raw_ingot }, + }, + }) + + minetest.register_craft({ + type = "cooking", + output = "mcl_core:"..ore.."_ingot", + recipe = raw_ingot, + cooktime = 10, + }) + + minetest.register_craft({ + type = "cooking", + output = "mcl_core:"..ore.."block", + recipe = raw_ingot.."_block", + cooktime = 90, + }) + + minetest.register_craft({ + output = raw_ingot.." 9", + recipe = { + { raw_ingot.."_block" }, + }, + }) +end + +register_raw_ore("Iron", "n") +register_raw_ore("Gold") diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.es.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.es.tr new file mode 100644 index 000000000..c286e90ec --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.es.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=Hierro en bruto +Raw Gold=Oro en bruto +Raw Iron. Mine an Iron ore to get it.=Hierro en bruto. Mina una mena de hierro para conseguirlo. +Raw Gold. Mine a Gold ore to get it.=Oro en bruto. Mina una mena de oro para conseguirlo. +Block of Raw Iron=Bloque de hierro en bruto +Block of Raw Gold=Bloque de oro en bruto +A block of raw Iron is mostly a decorative block but also useful as a compact storage of raw Iron.=Un bloque de hierro en bruto es sobre todo un bloque decorativo pero tambíen es útil como almacenamiento compacto de hierro en bruto. +A block of raw Gold is mostly a decorative block but also useful as a compact storage of raw Gold.=Un bloque de oro en bruto es sobre todo un bloque decorativo pero tambíen es útil como almacenamiento compacto de oro en bruto. diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr new file mode 100644 index 000000000..a82da25e9 --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.fr.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_raw_ores +Raw Iron=Fer brut +Raw Gold=Or brut +Raw iron. Mine an iron ore to get it.=Fer brut. Miner du minerai de fer pour en obtenir. +Raw gold. Mine a gold ore to get it.=Or brut. Miner du minerai d'or pour en obtenir. +Block of Raw Iron=Bloc de fer brut +Block of Raw Gold=Bloc d'or brut +A block of raw iron is mostly a decorative block but also useful as a compact storage of raw iron.=Un bloc de fer brut est principalement un bloc décoratif mais aussi utile comme stockage compact de fer brut. +A block of raw gold is mostly a decorative block but also useful as a compact storage of raw gold.=Un bloc d'or brut est principalement un bloc décoratif mais aussi utile comme stockage compact d'or brut. diff --git a/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.tr b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.tr new file mode 100644 index 000000000..dc0b8955e --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/mcl_raw_ores.ja.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.=金の粗鉱ブロックは、主に装飾用のブロックですが、金の粗鉱をコンパクトに収納するのにも便利です。 diff --git a/mods/ITEMS/mcl_raw_ores/locale/template.txt b/mods/ITEMS/mcl_raw_ores/locale/template.txt new file mode 100644 index 000000000..a9927aafa --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/locale/template.txt @@ -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.= diff --git a/mods/ITEMS/mcl_raw_ores/mod.conf b/mods/ITEMS/mcl_raw_ores/mod.conf new file mode 100644 index 000000000..a3ee955c7 --- /dev/null +++ b/mods/ITEMS/mcl_raw_ores/mod.conf @@ -0,0 +1,4 @@ +name = mcl_raw_ores +author = NO11 +depends = mcl_core +description = Adds raw iron and raw gold. \ No newline at end of file diff --git a/mods/ITEMS/mcl_sculk/init.lua b/mods/ITEMS/mcl_sculk/init.lua new file mode 100644 index 000000000..b2ef04152 --- /dev/null +++ b/mods/ITEMS/mcl_sculk/init.lua @@ -0,0 +1,286 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_sculk = {} + +local mt_sound_play = minetest.sound_play + +local spread_to = {"mcl_core:stone","mcl_core:dirt","mcl_core:sand","mcl_core:dirt_with_grass","group:grass_block","mcl_core:andesite","mcl_core:diorite","mcl_core:granite","mcl_core:mycelium","group:dirt","mcl_end:end_stone","mcl_nether:netherrack","mcl_blackstone:basalt","mcl_nether:soul_sand","mcl_blackstone:soul_soil","mcl_crimson:warped_nylium","mcl_crimson:crimson_nylium","mcl_core:gravel"} + +local sounds = { + footstep = {name = "mcl_sculk_block", }, + dug = {name = "mcl_sculk_block", }, +} + +local SPREAD_RANGE = 8 +local SENSOR_RANGE = 8 +local SENSOR_DELAY = 0.5 +local SHRIEKER_COOLDOWN = 10 + +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,1,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +--[[ +local function sensor_action(p,tp) + local s = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:shrieker"}) + local n = minetest.get_node(s) + if s and n.param2 ~= 1 then + minetest.sound_play("mcl_sculk_shrieker", {pos=s, gain=1.5, max_hear_distance = 16}, true) + n.param2 = 1 + minetest.set_node(s,n) + minetest.after(SHRIEKER_COOLDOWN,function(s) + minetest.set_node(s,{name = "mcl_sculk:shrieker",param2=0}) + end,s) + end + --local p1 = vector.offset(p,-SENSOR_RANGE,-SENSOR_RANGE,-SENSOR_RANGE) + --local p2 = vector.offset(p,SENSOR_RANGE,SENSOR_RANGE,SENSOR_RANGE) + --darken_area(p1,p2) +end + +function minetest.sound_play(spec, parameters, ephemeral) + local rt = mt_sound_play(spec, parameters, ephemeral) + if parameters.pos then + pos = parameters.pos + elseif parameters.to_player then + pos = minetest.get_player_by_name(parameters.to_player):get_pos() + end + if not pos then return rt end + local s = minetest.find_node_near(pos,SPREAD_RANGE,{"mcl_sculk:sensor"}) + if s then + --minetest.after(SENSOR_DELAY,sensor_action,s,pos) + end + return rt +end + +walkover.register_global(function(pos, node, player) + local s = minetest.find_node_near(pos,SPREAD_RANGE,{"mcl_sculk:sensor"}) + if not s then return end + local v = player:get_velocity() + if v.x == 0 and v.y == 0 and v.z == 0 then return end + if player:get_player_control().sneak then return end + local def = minetest.registered_nodes[node.name] + if def and def.sounds then + minetest.log("walkover "..node.name) + minetest.after(SENSOR_DELAY,sensor_action,s,pos) + end +end) +--]] + +local function get_node_xp(pos) + local meta = minetest.get_meta(pos) + return meta:get_int("xp") +end +local function set_node_xp(pos,xp) + local meta = minetest.get_meta(pos) + return meta:set_int("xp",xp) +end + +local function sculk_on_destruct(pos) + local xp = get_node_xp(pos) + local n = minetest.get_node(pos) + if n.param2 == 1 then + xp = 1 + end + local obs = mcl_experience.throw_xp(pos,xp) + for _,v in pairs(obs) do + local l = v:get_luaentity() + l._sculkdrop = true + end +end + +local function has_air(pos) + for _,v in pairs(adjacents) do + if minetest.get_item_group(minetest.get_node(vector.add(pos,v)).name,"solid") <= 0 then return true end + end +end + +local function has_nonsculk(pos) + for _,v in pairs(adjacents) do + local p = vector.add(pos,v) + if minetest.get_item_group(minetest.get_node(p).name,"sculk") <= 0 and minetest.get_item_group(minetest.get_node(p).name,"solid") > 0 then return p end + end +end +local function retrieve_close_spreadable_nodes (p) + local nnn = minetest.find_nodes_in_area(vector.offset(p,-SPREAD_RANGE,-SPREAD_RANGE,-SPREAD_RANGE),vector.offset(p,SPREAD_RANGE,SPREAD_RANGE,SPREAD_RANGE),spread_to) + local nn={} + for _,v in pairs(nnn) do + if has_air(v) then + table.insert(nn,v) + end + end + table.sort(nn,function(a, b) + return vector.distance(p, a) < vector.distance(p, b) + end) + return nn +end + +local function spread_sculk (p, xp_amount) + local c = minetest.find_node_near(p,SPREAD_RANGE,{"mcl_sculk:catalyst"}) + if c then + local nn = retrieve_close_spreadable_nodes (p) + if nn and #nn > 0 then + if xp_amount > 0 then + local d = math.random(100) + --[[ --enable to generate shriekers and sensors + if d <= 1 then + minetest.set_node(nn[1],{name = "mcl_sculk:shrieker"}) + set_node_xp(nn[1],math.min(1,self._xp - 10)) + self.object:remove() + return ret + elseif d <= 9 then + minetest.set_node(nn[1],{name = "mcl_sculk:sensor"}) + set_node_xp(nn[1],math.min(1,self._xp - 5)) + self.object:remove() + return ret + else --]] + + + local r = math.min(math.random(#nn), xp_amount) + --minetest.log("r: ".. r) + + for i=1,r do + minetest.set_node(nn[i],{name = "mcl_sculk:sculk" }) + set_node_xp(nn[i],math.floor(xp_amount / r)) + end + for i=1,r do + local p = has_nonsculk(nn[i]) + if p and has_air(p) then + minetest.set_node(vector.offset(p,0,1,0),{name = "mcl_sculk:vein", param2 = 1}) + end + end + set_node_xp(nn[1],get_node_xp(nn[1]) + xp_amount % r) + return true + --self.object:remove() + --end + end + end + end +end + +function mcl_sculk.handle_death(pos, xp_amount) + if not pos or not xp_amount then return end + --local nu = minetest.get_node(vector.offset(p,0,-1,0)) + return spread_sculk (pos, xp_amount) +end + +minetest.register_on_dieplayer(function(player) + if mcl_sculk.handle_death(player:get_pos(), 5) then + --minetest.log("Player is dead. Sculk") + else + --minetest.log("Player is dead. not Sculk") + end +end) + +minetest.register_node("mcl_sculk:sculk", { + description = S("Sculk"), + tiles = { + { name = "mcl_sculk_sculk.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 3.0, + }, }, + }, + drop = "", + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + sounds = sounds, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.6, + _mcl_silk_touch_drop = true, +}) + +minetest.register_node("mcl_sculk:vein", { + description = S("Sculk Vein"), + _doc_items_longdesc = S("Sculk vein."), + drawtype = "signlike", + tiles = {"mcl_sculk_vein.png"}, + inventory_image = "mcl_sculk_vein.png", + wield_image = "mcl_sculk_vein.png", + paramtype = "light", + sunlight_propagates = true, + paramtype2 = "wallmounted", + walkable = false, + climbable = true, + buildable_to = true, + selection_box = { + 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, + }, + sounds = sounds, + drop = "", + _mcl_shears_drop = true, + node_placement_prediction = "", + _mcl_blast_resistance = 0.2, + _mcl_hardness = 0.2, + on_rotate = false, +}) + +minetest.register_node("mcl_sculk:catalyst", { + description = S("Sculk Catalyst"), + tiles = { + "mcl_sculk_catalyst_top.png", + "mcl_sculk_catalyst_bottom.png", + "mcl_sculk_catalyst_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) + +--[[ +minetest.register_node("mcl_sculk:sensor", { + description = S("Sculk Sensor"), + tiles = { + "mcl_sculk_sensor_top.png", + "mcl_sculk_sensor_bottom.png", + "mcl_sculk_sensor_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 1, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) +minetest.register_node("mcl_sculk:shrieker", { + description = S("Sculk Shrieker"), + tiles = { + "mcl_sculk_shrieker_top.png", + "mcl_sculk_shrieker_bottom.png", + "mcl_sculk_shrieker_side.png" + }, + drop = "", + sounds = sounds, + groups = {handy = 1, hoey = 1, building_block=1, sculk = 1,}, + place_param2 = 0, + is_ground_content = false, + on_destruct = sculk_on_destruct, + _mcl_blast_resistance = 3, + light_source = 6, + _mcl_hardness = 3, + _mcl_silk_touch_drop = true, +}) +--]] diff --git a/mods/ITEMS/mcl_sculk/locale/mcl_sculk.fr.tr b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.fr.tr new file mode 100644 index 000000000..fd9a1b973 --- /dev/null +++ b/mods/ITEMS/mcl_sculk/locale/mcl_sculk.fr.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_sculk +Sculk=Sculk +Sculk Vein=Veine de sculk +Sculk vein.=Veine de sculk. +Sculk Catalyst=Catalyseur de sculk +Sculk Sensor=Capteur sculk +Sculk Shrieker=Hurleur sculk \ No newline at end of file diff --git a/mods/ITEMS/mcl_sculk/locale/template.txt b/mods/ITEMS/mcl_sculk/locale/template.txt new file mode 100644 index 000000000..8f2b3973d --- /dev/null +++ b/mods/ITEMS/mcl_sculk/locale/template.txt @@ -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_sculk/mod.conf b/mods/ITEMS/mcl_sculk/mod.conf new file mode 100644 index 000000000..e9fc71e9a --- /dev/null +++ b/mods/ITEMS/mcl_sculk/mod.conf @@ -0,0 +1,3 @@ +name = mcl_sculk +author = cora +depends = mcl_core, mcl_sounds, mcl_experience, walkover diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg new file mode 100644 index 000000000..ca211128d Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk.ogg differ diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg new file mode 100644 index 000000000..352342880 Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_2.ogg differ diff --git a/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg new file mode 100644 index 000000000..e71425d4b Binary files /dev/null and b/mods/ITEMS/mcl_sculk/sounds/mcl_sculk_block.ogg differ diff --git a/mods/ITEMS/mcl_shields/init.lua b/mods/ITEMS/mcl_shields/init.lua new file mode 100644 index 000000000..fa7714366 --- /dev/null +++ b/mods/ITEMS/mcl_shields/init.lua @@ -0,0 +1,521 @@ +local minetest, math, vector = minetest, math, vector +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +mcl_shields = { + types = { + mob = true, + player = true, + arrow = true, + generic = true, + explosion = true, + dragon_breath = true, + }, + enchantments = {"mending", "unbreaking"}, + players = {}, +} + +local interact_priv = minetest.registered_privileges.interact +interact_priv.give_to_singleplayer = false +interact_priv.give_to_admin = false + +local overlay = mcl_enchanting.overlay +local hud = "mcl_shield_hud.png" + +minetest.register_tool("mcl_shields:shield", { + description = S("Shield"), + _doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."), + inventory_image = "mcl_shield.png", + stack_max = 1, + groups = { + shield = 1, + weapon = 1, + enchantability = -1, + offhand_item = 1, + }, + sound = {breaks = "default_tool_breaks"}, + _repair_material = "group:wood", + wield_scale = vector.new(2, 2, 2), + _mcl_wieldview_item = "", +}) + +local function wielded_item(obj, i) + local itemstack = obj:get_wielded_item() + if i == 1 then + itemstack = obj:get_inventory():get_stack("offhand", 1) + end + return itemstack:get_name() +end + +function mcl_shields.wielding_shield(obj, i) + return wielded_item(obj, i):find("mcl_shields:shield") +end + +local function shield_is_enchanted(obj, i) + return mcl_enchanting.is_enchanted(wielded_item(obj, i)) +end + +minetest.register_entity("mcl_shields:shield_entity", { + initial_properties = { + visual = "mesh", + mesh = "mcl_shield.obj", + physical = false, + pointable = false, + collide_with_objects = false, + textures = {"mcl_shield_base_nopattern.png"}, + visual_size = vector.new(1, 1, 1), + }, + _blocking = false, + _shield_number = 2, + _texture_copy = "", + on_step = function(self, dtime, moveresult) + local player = self.object:get_attach() + if not player then + self.object:remove() + return + end + local shield_texture = "mcl_shield_base_nopattern.png" + local i = self._shield_number + local item = wielded_item(player, i) + + if item ~= "mcl_shields:shield" and item ~= "mcl_shields:shield_enchanted" then + local itemstack = player:get_wielded_item() + if i == 1 then + itemstack = player:get_inventory():get_stack("offhand", 1) + end + local meta_texture = itemstack:get_meta():get_string("mcl_shields:shield_custom_pattern_texture") + if meta_texture ~= "" then + shield_texture = meta_texture + else + local color = minetest.registered_items[item]._shield_color + if color then + shield_texture = "mcl_shield_base_nopattern.png^(mcl_shield_pattern_base.png^[colorize:" .. color .. ")" + end + end + end + + if shield_is_enchanted(player, i) then + shield_texture = shield_texture .. overlay + end + + if self._texture_copy ~= shield_texture then + self.object:set_properties({textures = {shield_texture}}) + end + + self._texture_copy = shield_texture + end, +}) + +for _, e in pairs(mcl_shields.enchantments) do + mcl_enchanting.enchantments[e].secondary.shield = true +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 + + local shieldstack = obj:get_wielded_item() + if blocking == 1 then + shieldstack = obj:get_inventory():get_stack("offhand", 1) + end + return blocking, shieldstack +end + +mcl_damage.register_modifier(function(obj, damage, reason) + local type = reason.type + local damager = reason.direct + local blocking, shieldstack = mcl_shields.is_blocking(obj) + + if not (obj:is_player() and blocking and mcl_shields.types[type] and damager) then + return + end + + local entity = damager:get_luaentity() + if entity and entity._shooter then + damager = entity._shooter + end + + local dpos = damager:get_pos() + + -- Used for removed / killed entities before the projectile hits the player + if entity and not entity._shooter and entity._saved_shooter_pos then + dpos = entity._saved_shooter_pos + end + + if not dpos or vector.dot(obj:get_look_dir(), vector.subtract(dpos, obj:get_pos())) < 0 then + return + end + + local durability = 336 + local unbreaking = mcl_enchanting.get_enchantment(shieldstack, mcl_shields.enchantments[2]) + if unbreaking > 0 then + durability = durability * (unbreaking + 1) + end + + if not minetest.is_creative_enabled(obj:get_player_name()) and damage >= 3 then + shieldstack:add_wear(65535 / durability) + if blocking == 2 then + obj:set_wielded_item(shieldstack) + else + obj:get_inventory():set_stack("offhand", 1, shieldstack) + mcl_inventory.update_inventory_formspec(obj) + end + end + minetest.sound_play({name = "mcl_block"}, {pos = obj:get_pos(), max_hear_distance = 16}) + return 0 +end) + +local function modify_shield(player, vpos, vrot, i) + local arm = "Right" + if i == 1 then + arm = "Left" + end + local shield = mcl_shields.players[player].shields[i] + if shield then + shield:set_attach(player, "Arm_" .. arm, vpos, vrot, false) + end +end + +local function set_shield(player, block, i) + if block then + if i == 1 then + modify_shield(player, vector.new(-9, 4, 0.5), vector.new(80, 100, 0), i) -- TODO + else + modify_shield(player, vector.new(-8, 4, -2.5), vector.new(80, 80, 0), i) + end + else + if i == 1 then + modify_shield(player, vector.new(-3, -5, 0), vector.new(0, 180, 0), i) + else + modify_shield(player, vector.new(3, -5, 0), vector.new(0, 0, 0), i) + end + end + local shield = mcl_shields.players[player].shields[i] + if not shield then return end + + local luaentity = shield:get_luaentity() + if not luaentity then return end + + luaentity._blocking = block +end + +local function set_interact(player, interact) + local player_name = player:get_player_name() + local privs = minetest.get_player_privs(player_name) + if privs.interact == interact then + return + end + local meta = player:get_meta() + if meta:get_int("mcl_privs:interact_revoked") ~= 1 then + privs.interact = interact + minetest.set_player_privs(player_name, privs) + meta:set_int("mcl_privs:interact_revoked",0) + end +end + +local shield_hud = {} + +local function remove_shield_hud(player) + if not shield_hud[player] then return end --this function takes a long time. only run it when necessary + player:hud_remove(shield_hud[player]) + shield_hud[player] = nil + set_shield(player, false, 1) + set_shield(player, false, 2) + + local hf = player:hud_get_flags() + if not hf.wielditem then + player:hud_set_flags({wielditem = true}) + end + + playerphysics.remove_physics_factor(player, "speed", "shield_speed") + set_interact(player, true) +end + +local function add_shield_entity(player, i) + local shield = minetest.add_entity(player:get_pos(), "mcl_shields:shield_entity") + shield:get_luaentity()._shield_number = i + mcl_shields.players[player].shields[i] = shield + set_shield(player, false, i) +end + +local function remove_shield_entity(player, i) + local shields = mcl_shields.players[player].shields + if shields[i] then + shields[i]:remove() + shields[i] = nil + end +end + +local function handle_blocking(player) + local player_shield = mcl_shields.players[player] + local rmb = player:get_player_control().RMB + if not rmb then + player_shield.blocking = 0 + return + end + + local shield_in_offhand = mcl_shields.wielding_shield(player, 1) + local shield_in_hand = mcl_shields.wielding_shield(player) + local not_blocking = player_shield.blocking == 0 + + local pos = player:get_pos() + if shield_in_hand then + if not_blocking then + minetest.after(0.25, function() + if (not_blocking or not shield_in_offhand) and shield_in_hand and rmb then + player_shield.blocking = 2 + set_shield(player, true, 2) + end + end) + elseif not shield_in_offhand then + player_shield.blocking = 2 + end + elseif shield_in_offhand then + local pointed_thing = mcl_util.get_pointed_thing(player, true) + local offhand_can_block = (wielded_item(player) == "" or not pointed_thing) + and (minetest.get_item_group(wielded_item(player), "bow") ~= 1 and minetest.get_item_group(wielded_item(player), "crossbow") ~= 1) + + if pointed_thing and pointed_thing.type == "node" then + if minetest.get_item_group(minetest.get_node(pointed_thing.under).name, "container") > 1 then + return + end + end + + if not offhand_can_block then + return + end + if not_blocking then + minetest.after(0.25, function() + if (not_blocking or not shield_in_hand) and shield_in_offhand and rmb and offhand_can_block then + player_shield.blocking = 1 + set_shield(player, true, 1) + end + end) + elseif not shield_in_hand then + player_shield.blocking = 1 + end + else + player_shield.blocking = 0 + end +end + +local function update_shield_entity(player, blocking, i) + local shield = mcl_shields.players[player].shields[i] + if mcl_shields.wielding_shield(player, i) then + if not shield then + add_shield_entity(player, i) + else + if blocking == i then + if shield:get_luaentity() and not shield:get_luaentity()._blocking then + set_shield(player, true, i) + end + else + set_shield(player, false, i) + end + end + elseif shield then + remove_shield_entity(player, i) + end +end + +local function add_shield_hud(shieldstack, player, blocking) + local texture = hud + if mcl_enchanting.is_enchanted(shieldstack:get_name()) then + texture = texture .. overlay + end + local offset = 100 + if blocking == 1 then + texture = texture .. "^[transform4" + offset = -100 + else + player:hud_set_flags({wielditem = false}) + end + shield_hud[player] = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -101, y = -101}, + offset = {x = offset, y = 0}, + text = texture, + z_index = -200, + }) + playerphysics.add_physics_factor(player, "speed", "shield_speed", 0.5) + set_interact(player, nil) +end + +local function update_shield_hud(player, blocking, shieldstack) + local shieldhud = shield_hud[player] + if not shieldhud then + add_shield_hud(shieldstack, player, blocking) + return + end + + local wielditem = player:hud_get_flags().wielditem + if blocking == 1 then + if not wielditem then + player:hud_change(shieldhud, "text", hud .. "^[transform4") + player:hud_change(shieldhud, "offset", {x = -100, y = 0}) + player:hud_set_flags({wielditem = true}) + end + elseif wielditem then + player:hud_change(shieldhud, "text", hud) + player:hud_change(shieldhud, "offset", {x = 100, y = 0}) + player:hud_set_flags({wielditem = false}) + end + + local image = player:hud_get(shieldhud).text + local enchanted = hud .. overlay + local enchanted1 = image == enchanted + local enchanted2 = image == enchanted .. "^[transform4" + if mcl_enchanting.is_enchanted(shieldstack:get_name()) then + if not enchanted1 and not enchanted2 then + if blocking == 1 then + player:hud_change(shieldhud, "text", hud .. overlay .. "^[transform4") + else + player:hud_change(shieldhud, "text", hud .. overlay) + end + end + elseif enchanted1 or enchanted2 then + if blocking == 1 then + player:hud_change(shieldhud, "text", hud .. "^[transform4") + else + player:hud_change(shieldhud, "text", hud) + end + end +end + +minetest.register_globalstep(function(dtime) + for _, player in pairs(minetest.get_connected_players()) do + + handle_blocking(player) + + local blocking, shieldstack = mcl_shields.is_blocking(player) + + if blocking then + update_shield_hud(player, blocking, shieldstack) + else + remove_shield_hud(player) + end + + for i = 1, 2 do + update_shield_entity(player, blocking, i) + end + end +end) + +minetest.register_on_dieplayer(function(player) + remove_shield_hud(player) + if not minetest.settings:get_bool("mcl_keepInventory") then + remove_shield_entity(player, 1) + remove_shield_entity(player, 2) + end +end) + +minetest.register_on_leaveplayer(function(player) + shield_hud[player] = nil + mcl_shields.players[player] = nil +end) + +minetest.register_craft({ + output = "mcl_shields:shield", + recipe = { + {"group:wood", "mcl_core:iron_ingot", "group:wood"}, + {"group:wood", "group:wood", "group:wood"}, + {"", "group:wood", ""}, + } +}) + +for _, colortab in pairs(mcl_banners.colors) do + local color = colortab[1] + minetest.register_tool("mcl_shields:shield_" .. color, { + description = S(colortab[6] .. " Shield"), + _doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."), + inventory_image = "mcl_shield.png^(mcl_shield_item_overlay.png^[colorize:" .. colortab[4] ..")", + stack_max = 1, + groups = { + shield = 1, + weapon = 1, + enchantability = -1, + not_in_creative_inventory = 1, + offhand_item = 1, + }, + sound = {breaks = "default_tool_breaks"}, + _repair_material = "group:wood", + wield_scale = vector.new(2, 2, 2), + _shield_color = colortab[4], + _mcl_wieldview_item = "", + }) + + local banner = "mcl_banners:banner_item_" .. color + minetest.register_craft({ + type = "shapeless", + output = "mcl_shields:shield_" .. color, + recipe = {"mcl_shields:shield", banner}, + }) + minetest.register_craft({ + type = "shapeless", + output = "mcl_shields:shield_" .. color .. "_enchanted", + recipe = {"mcl_shields:shield_enchanted", banner}, + }) +end + +local function to_shield_texture(banner_texture) + return banner_texture + :gsub("mcl_banners_base_inverted.png", "mcl_shield_base_nopattern.png^mcl_shield_pattern_base.png") + :gsub("mcl_banners_banner_base.png", "mcl_shield_base_nopattern.png^mcl_shield_pattern_base.png") + :gsub("mcl_banners_base", "mcl_shield_pattern_base") + :gsub("mcl_banners", "mcl_shield_pattern") +end + +local function craft_banner_on_shield(itemstack, player, old_craft_grid, craft_inv) + if not string.find(itemstack:get_name(), "mcl_shields:shield_") then + return itemstack + end + + local shield_stack + for i = 1, player:get_inventory():get_size("craft") do + local stack = old_craft_grid[i] + local name = stack:get_name() + if minetest.get_item_group(name, "shield") then + shield_stack = stack + break + end + end + + for i = 1, player:get_inventory():get_size("craft") do + local banner_stack = old_craft_grid[i] + local banner_name = banner_stack:get_name() + if string.find(banner_name, "mcl_banners:banner") and shield_stack then + local banner_meta = banner_stack:get_meta() + local layers_meta = banner_meta:get_string("layers") + local new_shield_meta = itemstack:get_meta() + if layers_meta ~= "" then + local color = mcl_banners.color_reverse(banner_name) + local layers = minetest.deserialize(layers_meta) + local texture = mcl_banners.make_banner_texture(color, layers) + new_shield_meta:set_string("description", mcl_banners.make_advanced_banner_description(itemstack:get_description(), layers)) + new_shield_meta:set_string("mcl_shields:shield_custom_pattern_texture", to_shield_texture(texture)) + end + itemstack:set_wear(shield_stack:get_wear()) + break + end + end +end + +minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv) + return craft_banner_on_shield(itemstack, player, old_craft_grid, craft_inv) +end) + +minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv) + return craft_banner_on_shield(itemstack, player, old_craft_grid, craft_inv) +end) + +minetest.register_on_joinplayer(function(player) + mcl_shields.players[player] = { + shields = {}, + blocking = 0, + } + remove_shield_hud(player) +end) diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.de.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.de.tr new file mode 100644 index 000000000..2a4deccc0 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.de.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Schild +A shield is a tool used for protecting the player against attacks.=Der Schild ist eine Schutzwaffe, die den Spieler vor Angriffen schützt. +White Shield=Weißer Schild +Grey Shield=Grauer Schild +Light Grey Shield=Hellgrauer Schild +Black Shield=Schwarzer Schild +Red Shield=Roter Schild +Yellow Shield=Gelber Schild +Green Shield=Grüner Schild +Cyan Shield=Türkiser Schild +Blue Shield=Blauer Schild +Magenta Shield=Magenta Schild +Orange Shield=Oranger Schild +Purple Shield=Violetter Schild +Brown Shield=Brauner Schild +Pink Shield=Rosa Schild +Lime Shield=Hellgrüner Schild +Light Blue Shield=Hellblauer Schild diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.es.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.es.tr new file mode 100644 index 000000000..be941b20a --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.es.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Escudo +A shield is a tool used for protecting the player against attacks.=Un escudo es una herramienta usada para proteger al jugador de ataques. +White Shield=Escudo blanco +Grey Shield=Escudo gris +Light Grey Shield=Escudo gris claro +Black Shield=Escudo negro +Red Shield=Escudo rojo +Yellow Shield=Escudo amarillo +Green Shield=Escudo verde +Cyan Shield=Escudo cian +Blue Shield=Escudo azul +Magenta Shield=Escudo magenta +Orange Shield=Escudo naranja +Purple Shield=Escudo purpura +Brown Shield=Escudo marrón +Pink Shield=Escudo rosa +Lime Shield=Escudo lima +Light Blue Shield=Escudo azul claro diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr new file mode 100644 index 000000000..fb4b5fd70 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.fr.tr @@ -0,0 +1,19 @@ +# textdomain: mcl_shields +Shield=Bouclier +A shield is a tool used for protecting the player against attacks.=Un bouclier est un outil utilisé pour protéger le joueur contre les attaques. +White Shield=Bouclier Blanc +Grey Shield=Bouclier Gris +Light Grey Shield=Bouclier Gris Clair +Black Shield=Bouclier Noir +Red Shield=Bouclier Rouge +Yellow Shield=Bouclier Jaune +Green Shield=Bouclier Vert +Cyan Shield=Bouclier Cyan +Blue Shield=Bouclier Bleu +Magenta Shield=Bouclier Magenta +Orange Shield=Bouclier Orange +Purple Shield=Bouclier Pourpre +Brown Shield=Bouclier Marron +Pink Shield=Bouclier Rose +Lime Shield=Bouclier Vert Clair +Light Blue Shield=Bouclier Bleu Clair \ No newline at end of file diff --git a/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.tr b/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.tr new file mode 100644 index 000000000..794139e38 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/mcl_shields.ja.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_shields/locale/template.txt b/mods/ITEMS/mcl_shields/locale/template.txt new file mode 100644 index 000000000..bcf7b1b54 --- /dev/null +++ b/mods/ITEMS/mcl_shields/locale/template.txt @@ -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_shields/mod.conf b/mods/ITEMS/mcl_shields/mod.conf new file mode 100644 index 000000000..8aded6a62 --- /dev/null +++ b/mods/ITEMS/mcl_shields/mod.conf @@ -0,0 +1,3 @@ +name = mcl_shields +author = NO11 +depends = mcl_damage, mcl_enchanting, mcl_banners, mcl_util, playerphysics diff --git a/mods/ITEMS/mcl_shields/models/mcl_shield.obj b/mods/ITEMS/mcl_shields/models/mcl_shield.obj new file mode 100644 index 000000000..b1cf77c28 --- /dev/null +++ b/mods/ITEMS/mcl_shields/models/mcl_shield.obj @@ -0,0 +1,88 @@ +# Blender v3.0.0 OBJ File: '' +# www.blender.org +mtllib mcl_shield.mtl +o Cube.002_Cube.003 +v 4.663009 11.096291 6.387994 +v 4.663009 4.596560 5.241916 +v 5.213008 4.596560 5.241916 +v 5.213008 11.096291 6.387994 +v 5.213007 13.197435 -5.528180 +v 5.213007 6.697705 -6.674258 +v 4.663008 6.697705 -6.674258 +v 4.663008 13.197435 -5.528180 +v 4.663008 8.641873 -1.863572 +v 4.663008 8.068833 1.386293 +v 1.363008 8.068833 1.386294 +v 1.363008 8.641873 -1.863572 +v 1.363008 9.152122 1.577307 +v 1.363008 9.725162 -1.672559 +v 4.663008 9.152122 1.577306 +v 4.663008 9.725162 -1.672559 +vt 0.015625 0.984375 +vt 0.203125 0.984375 +vt 0.203125 1.000000 +vt 0.015625 1.000000 +vt 0.203125 0.640625 +vt 0.203125 0.984375 +vt 0.015625 0.984375 +vt 0.015625 0.640625 +vt 0.015625 0.984375 +vt 0.015625 0.640625 +vt -0.000000 0.640625 +vt -0.000000 0.984375 +vt 0.203125 0.984375 +vt 0.390625 0.984375 +vt 0.390625 1.000000 +vt 0.203125 1.000000 +vt 0.203125 0.984375 +vt 0.203125 0.640625 +vt 0.218750 0.640625 +vt 0.218750 0.984375 +vt 0.406250 0.640625 +vt 0.406250 0.984375 +vt 0.218750 0.984375 +vt 0.218750 0.640625 +vt 0.531250 0.812500 +vt 0.625000 0.812500 +vt 0.625000 0.906250 +vt 0.531250 0.906250 +vt 0.500000 0.906250 +vt 0.500000 0.812500 +vt 0.531250 0.812500 +vt 0.531250 0.906250 +vt 0.406250 0.812500 +vt 0.500000 0.812500 +vt 0.500000 0.906250 +vt 0.406250 0.906250 +vt 0.625000 0.812500 +vt 0.656250 0.812500 +vt 0.656250 0.906250 +vt 0.625000 0.906250 +vt 0.562500 1.000000 +vt 0.531250 1.000000 +vt 0.531250 0.906250 +vt 0.562500 0.906250 +vt 0.531250 1.000000 +vt 0.500000 1.000000 +vt 0.500000 0.906250 +vt 0.531250 0.906250 +vn 0.0000 -0.1736 0.9848 +vn 1.0000 0.0000 -0.0000 +vn 0.0000 -0.9848 -0.1736 +vn 0.0000 0.1736 -0.9848 +vn 0.0000 0.9848 0.1736 +vn -1.0000 -0.0000 0.0000 +usemtl Material.002 +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 4/6/2 3/7/2 6/8/2 +f 6/9/3 3/10/3 2/11/3 7/12/3 +f 7/13/4 8/14/4 5/15/4 6/16/4 +f 8/17/5 1/18/5 4/19/5 5/20/5 +f 7/21/6 2/22/6 1/23/6 8/24/6 +f 9/25/3 10/26/3 11/27/3 12/28/3 +f 12/29/6 11/30/6 13/31/6 14/32/6 +f 14/33/5 13/34/5 15/35/5 16/36/5 +f 16/37/2 15/38/2 10/39/2 9/40/2 +f 12/41/4 14/42/4 16/43/4 9/44/4 +f 13/45/1 11/46/1 10/47/1 15/48/1 diff --git a/mods/ITEMS/mcl_shields/sounds/mcl_block.ogg b/mods/ITEMS/mcl_shields/sounds/mcl_block.ogg new file mode 100644 index 000000000..3af7f04b4 Binary files /dev/null and b/mods/ITEMS/mcl_shields/sounds/mcl_block.ogg differ diff --git a/mods/ITEMS/mcl_signs/README.txt b/mods/ITEMS/mcl_signs/README.txt index ee161fc95..e4fbead8a 100644 --- a/mods/ITEMS/mcl_signs/README.txt +++ b/mods/ITEMS/mcl_signs/README.txt @@ -1,4 +1,21 @@ -Mod based on reworked signs mod by PilzAdam: + +--- +# Mineclone2-Signs +--- +A reworking of MineClone 2's mcl_signs to be colorable and made to glow. Requires Minetest and Mineclone2. +--- + +Created by Michieal (FaerRaven) @ DateTime: 10/14/22 4:05 PM + + +Reworked to be an API and to allow players to color, and/or make the lettering for the signs glow (be bright at night). +Reworked by Michieal (FaerRaven), including the sign textures batch changed to be white instead of the original black. + +A special thanks to Cora for pointing me in the right direction (as always). + + +The original Mod, MCL_SIGNS is based on reworked signs mod by PilzAdam: + https://forum.minetest.net/viewtopic.php?t=3289 License of code and font: MIT License @@ -6,8 +23,22 @@ 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. +License of textures: See README.md in top directory of MineClone 2, 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/). +Credit Michieal (Faerraven). The extra sign textures are provided for you to use, modify, etc., with the goal being to +make the game better. (All of these textures were changed / created by me, to make them usable / better.) License of models: GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html) + Models author: 22i. + Source: https://github.com/22i/amc + +Mineclone 2 source code: +https://git.minetest.land/MineClone2/MineClone2 + +--- +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 diff --git a/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt new file mode 100644 index 000000000..e98741137 --- /dev/null +++ b/mods/ITEMS/mcl_signs/SIGNS_API_DOC.txt @@ -0,0 +1,122 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/22/22 3:44 PM +--- + +SIGNS API + +--- How to Use: + +The simplest way to create a new sign is to use mcl_signs.register_sign [mcl_signs.register_sign (modname, color, _name, +ttsign)]. It's an all-in-one sign creator. It makes use of the standard textures for the signs, and colors them based on +the color code that you give it, and names it "mcl_signs:wall_sign" + _name. So, using the spruce sign to illustrate, it +would be named "mcl_signs:wall_sign_sprucewood", as we made _name equal to "_sprucewood" after the name of the +registered wood. + +To create a sign with specific textures: use the mcl_signs.register_sign_custom [mcl_signs.register_sign_custom +(modname, _name, tiles, color, inventory_image, wield_image, ttsign)]. Like the register_sign() function, this is also an +all-in-one sign creation function. With this function you can designate what textures to use, and give them a specified +color. This function follows the same naming conventions. + +If you wish to override / recreate one of the predefined signs, you may also do that. The reregister_sign() and +reregister_sign_custom() functions will replace an existing sign's definition with a new one. Caution, ONLY use this on +existing signs. If the sign doesn't exist, use the regular register_sign* functions. + +--- What the parameters mean, and what they do: + +* modname: optional (pass "" or "false" to ignore), for using mcl_signs with other mods to allow the creation of a sign +from the mod's wood (if installed). Use this to prevent failures of the specific mod is not installed that has the needed +information (textures, wood, etc.) Setting this is important, because it prevents items from being registered if the +mod in not installed. + +* tiles: the texture file to use for the sign's node. + +* color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, and just use the +texture as is. + +* inventory_image: the texture file to use for the sign's display in inventory. + +* wield_image: the texture file to use for the sign's weilded (in hand) object. + +* _name: the sign's name suffix, such as "_dark" or "_sprucewood", etc., appended to "wall_sign" or "standing_sign" + +* ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. ttsign stands +for translated tooltip sign. + +* wood_item_string: example: "mcl_core:wood", "mcl_core:sprucewood" or "mymod:mywood". This is used when defining the +recipe for the sign. + +--- Other Functions of Importance: + +* register_dye [mcl_signs.register_dye (modname, item_name, color_code)] -- this registers a new dye that the sign knows +about so that the player can color their signs with the dye. +Parameters: + modname: your mod / module's name. make sure to use this for compatibility. + item_name: the item_string of the dye to register. + color_code: the hex code for the color to make the lettering. Also called HTML color code. Ex. "#FFFFFF" is white. + +* register_sign_craft [mcl_signs.register_sign_craft(modname, wood_item_string, _name)] -- this is what creates the +recipes for the sign, and makes the sign "burnable". Typically called right after the register_sign* functions. +Parameters: + _name: MUST be the same name as used for the sign. So, if your sign _name is "_sprucewood" then this should be too. + wood_item_string: the item_string of the wood to use for the sign's recipe. Example: "mcl_core:wood" (default oak). + modname: like with the other functions that has this parameter, used to make sure that nothing breaks. + +* make_lbm() [mcl_signs.make_lbm()] -- This innocuous function is very important. This is the function that makes the +signs work after reloading the game. This function is the last to be called in your sign creation work flow. Note, you +do not need to call this function after every definition, just at the end of the last definition. +(See Example WorkFlow below.) + +--- Example Workflow for sign creation. + +* these are, at the time of writing, a selection of the actual signs' definitions. Note the functions called, and when. + +-- ---------------------------- -- +-- Register Signs for use. -- +-- ---------------------------- -- + +-- sprucewood Sign +mcl_signs.register_sign_custom("mcl_core", "_sprucewood", + "mcl_signs_sign_dark.png","#ffffff", "default_sign_dark.png", + "default_sign_dark.png", "Spruce Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:sprucewood", "_sprucewood") + +-- darkwood Sign +mcl_signs.register_sign_custom("mcl_core", "_darkwood", + "mcl_signs_sign_greyscale.png","#856443", "default_sign_greyscale.png", + "default_sign_greyscale.png", "Dark Oak Sign" +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:darkwood", "_darkwood") + +-- acaciawood Sign +mcl_signs.register_sign("mcl_core", "#ea7479", "_acaciawood", "Acacia Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:acaciawood", "_acaciawood") + +-- junglewood Sign +mcl_signs.register_sign("mcl_core", "#866249", "_junglewood", "Jungle Sign") +mcl_signs.register_sign_craft("mcl_core", "mcl_core:junglewood", "_junglewood") + +-- Register the LBMs for the created signs. +mcl_signs.make_lbm() + +--- ----------------------------------------------------------------------------- + +* If you wish to use a recipe other than the standard sign recipe, you will need to define your own recipe. In doing so, +use this output line: + output = "mcl_signs:wall_sign" .. _name .. " 3", +where _name is the same string that you have used throughout your sign's workflow. That way, when players make the recipe, +they get your sign (x3). + +--- Future landmarks on the horizon for the Signs API: + +* Once the forthcoming Hanging Signs are in Minecraft, and we implement the code for them in here, hanging signs will +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. + +And that... is all there is to it! + +-- written by Michieal. \ No newline at end of file diff --git a/mods/ITEMS/mcl_signs/depends.txt b/mods/ITEMS/mcl_signs/depends.txt deleted file mode 100644 index f123382f8..000000000 --- a/mods/ITEMS/mcl_signs/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds? -mcl_core? -doc? diff --git a/mods/ITEMS/mcl_signs/init.lua b/mods/ITEMS/mcl_signs/init.lua index d21b58242..117f5665c 100644 --- a/mods/ITEMS/mcl_signs/init.lua +++ b/mods/ITEMS/mcl_signs/init.lua @@ -1,573 +1,158 @@ -local S = minetest.get_translator("mcl_signs") -local F = minetest.formspec_escape +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- DateTime: 10/14/22 4:05 PM +--- --- Load the characters map (characters.txt) ---[[ File format of characters.txt: -It's an UTF-8 encoded text file that contains metadata for all supported characters. It contains a sequence of info blocks, one for each character. Each info block is made out of 3 lines: -Line 1: The literal UTF-8 encoded character -Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory -Line 3: Currently ignored. Previously this was for the character width in pixels +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) -After line 3, another info block may follow. This repeats until the end of the file. +-- Signs API +dofile(modpath .. "/signs_api.lua") -All character files must be 5 or 6 pixels wide (5 pixels are preferred) -]] - -local chars_file = io.open(minetest.get_modpath("mcl_signs").."/characters.txt", "r") --- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. -local charmap = {} -if not chars_file then - minetest.log("error", "[mcl_signs] : character map file not found") -else - while true do - local char = chars_file:read("*l") - if char == nil then - break - end - local img = chars_file:read("*l") - chars_file:read("*l") - charmap[char] = img - end -end - --- CONSTANTS -local SIGN_WIDTH = 115 - -local LINE_LENGTH = 15 -local NUMBER_OF_LINES = 4 - -local LINE_HEIGHT = 14 -local CHAR_WIDTH = 5 - - --- Helper functions -local function round(num, idp) - local mult = 10^(idp or 0) - return math.floor(num * mult + 0.5) / mult -end - -local string_to_array = function(str) - local tab = {} - for i=1,string.len(str) do - table.insert(tab, string.sub(str, i,i)) - end - return tab -end - -local string_to_line_array = function(str) - local tab = {} - local current = 1 - local linechar = 1 - tab[1] = "" - for _,char in ipairs(string_to_array(str)) do - -- New line - if char == "\n" then - current = current + 1 - tab[current] = "" - linechar = 1 - else - tab[current] = tab[current]..char - linechar = linechar + 1 - end - end - return tab -end - -local create_lines = function(text) - local line_num = 1 - local tab = {} - for _, line in ipairs(string_to_line_array(text)) do - if line_num > NUMBER_OF_LINES then - break - end - table.insert(tab, line) - line_num = line_num + 1 - end - return tab -end - -local generate_line = function(s, ypos) - local i = 1 - local parsed = {} - local width = 0 - local chars = 0 - local printed_char_width = CHAR_WIDTH + 1 - while chars < LINE_LENGTH and i <= #s do - local file = nil - -- Get and render character - if charmap[s:sub(i, i)] ~= nil then - file = charmap[s:sub(i, i)] - i = i + 1 - elseif i < #s and charmap[s:sub(i, i + 1)] ~= nil then - file = charmap[s:sub(i, i + 1)] - i = i + 2 - else - -- No character image found. - -- Use replacement character: - file = "_rc" - i = i + 1 - minetest.log("verbose", "[mcl_signs] Unknown symbol in '"..s.."' at "..i) - end - if file ~= nil then - width = width + printed_char_width - table.insert(parsed, file) - chars = chars + 1 - end - end - width = width - 1 - - local texture = "" - local xpos = math.floor((SIGN_WIDTH - width) / 2) - for i = 1, #parsed do - texture = texture..":"..xpos..","..ypos.."="..parsed[i]..".png" - xpos = xpos + printed_char_width - end - return texture -end - -local generate_texture = function(lines, signnodename) - local texture = "[combine:"..SIGN_WIDTH.."x"..SIGN_WIDTH - local ypos - if signnodename == "mcl_signs:wall_sign" then - ypos = 30 - else - ypos = 0 - end - for i = 1, #lines do - texture = texture..generate_line(lines[i], ypos) - ypos = ypos + LINE_HEIGHT - end - return texture -end - -local n = 23/56 - 1/128 - -local signtext_info_wall = { - {delta = {x = 0, y = 0, z = n}, yaw = 0}, - {delta = {x = n, y = 0, z = 0}, yaw = math.pi / -2}, - {delta = {x = 0, y = 0, z = -n}, yaw = math.pi}, - {delta = {x = -n, y = 0, z = 0}, yaw = math.pi / 2}, -} - -local signtext_info_standing = {} - -local m = -1/16 + 1/64 -for rot=0, 15 do - local yaw = math.pi*2 - (((math.pi*2) / 16) * rot) - local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) - -- Offset because sign is a bit above node boundaries - delta.y = delta.y + 2/28 - table.insert(signtext_info_standing, { delta = delta, yaw = yaw }) -end - -local function get_rotation_level(facedir, nodename) - local rl = facedir * 4 - if nodename == "mcl_signs:standing_sign22_5" then - rl = rl + 1 - elseif nodename == "mcl_signs:standing_sign45" then - rl = rl + 2 - elseif nodename == "mcl_signs:standing_sign67_5" then - rl = rl + 3 - end - return rl -end - -local function get_wall_signtext_info(param2, nodename) - local dir = minetest.wallmounted_to_dir(param2) - if dir.x > 0 then - return 2 - elseif dir.z > 0 then - return 1 - elseif dir.x < 0 then - return 4 - else - return 3 - end -end - -local sign_groups = {handy=1,axey=1, flammable=1, deco_block=1, material_wood=1, attached_node=1, dig_by_piston=1, flammable=-1} - -local destruct_sign = function(pos) - local objects = minetest.get_objects_inside_radius(pos, 0.5) - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - v:remove() - end - end - local players = minetest.get_connected_players() - for p=1, #players do - if vector.distance(players[p]:get_pos(), pos) <= 30 then - minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_"..pos.x.."_"..pos.y.."_"..pos.z) - end - end -end - -local update_sign = function(pos, fields, sender, force_remove) - local meta = minetest.get_meta(pos) - if not meta then - return - end - local text = meta:get_string("text") - if fields and (text == "" and fields.text) then - meta:set_string("text", fields.text) - text = fields.text - end - if text == nil then - text = "" - end - - local sign_info - local n = minetest.get_node(pos) - local nn = n.name - if nn == "mcl_signs:standing_sign" or nn == "mcl_signs:standing_sign22_5" or nn == "mcl_signs:standing_sign45" or nn == "mcl_signs:standing_sign67_5" then - sign_info = signtext_info_standing[get_rotation_level(n.param2, nn) + 1] - elseif nn == "mcl_signs:wall_sign" then - sign_info = signtext_info_wall[get_wall_signtext_info(n.param2)] - end - if sign_info == nil then - minetest.log("error", "[mcl_signs] Missing sign_info!") - return - end - - local objects = minetest.get_objects_inside_radius(pos, 0.5) - local text_entity - for _, v in ipairs(objects) do - local ent = v:get_luaentity() - if ent and ent.name == "mcl_signs:text" then - if force_remove then - v:remove() - else - text_entity = v - break - end - end - end - - if not text_entity then - text_entity = minetest.add_entity({ - x = pos.x + sign_info.delta.x, - y = pos.y + sign_info.delta.y, - z = pos.z + sign_info.delta.z}, "mcl_signs:text") - end - text_entity:get_luaentity()._signnodename = nn - text_entity:set_properties({textures={generate_texture(create_lines(text), nn)}}) - - text_entity:set_yaw(sign_info.yaw) -end - -local show_formspec = function(player, pos) - 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")).."]" - ) -end +-- LOCALIZATION +local S = minetest.get_translator(modname) +-- HANDLE THE FORMSPEC CALLBACK minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname:find("mcl_signs:set_text_") == 1 then - local x, y, z = formname:match("mcl_signs:set_text_(.-)_(.-)_(.*)") - local pos = {x=tonumber(x), y=tonumber(y), z=tonumber(z)} - if not pos or not pos.x or not pos.y or not pos.z then return end - update_sign(pos, fields, player) - end + if formname:find("mcl_signs:set_text_") == 1 then + local x, y, z = formname:match("mcl_signs:set_text_(.-)_(.-)_(.*)") + local pos = { x = tonumber(x), y = tonumber(y), z = tonumber(z) } + if not pos or not pos.x or not pos.y or not pos.z then + return + end + mcl_signs:update_sign(pos, fields, player) + end end) -local node_sounds -if minetest.get_modpath("mcl_sounds") then - node_sounds = mcl_sounds.node_sound_wood_defaults() -end - -minetest.register_node("mcl_signs:wall_sign", { - 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."), - inventory_image = "default_sign.png", - walkable = false, - is_ground_content = false, - wield_image = "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"}, - groups = sign_groups, - stack_max = 16, - sounds = node_sounds, - - on_place = function(itemstack, placer, pointed_thing) - local above = pointed_thing.above - local under = pointed_thing.under - - -- Use pointed node's on_rightclick function first, if present - local node_under = minetest.get_node(under) - if placer and not placer:get_player_control().sneak then - if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then - return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack - end - end - - local dir = vector.subtract(under, above) - - -- Only build when it's legal - local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] - if not abovenodedef or abovenodedef.buildable_to == false then - return itemstack - end - - local wdir = minetest.dir_to_wallmounted(dir) - - local placer_pos = placer:get_pos() - - local fdir = minetest.dir_to_facedir(dir) - - local sign_info - local nodeitem = ItemStack(itemstack) - -- Ceiling - if wdir == 0 then - --how would you add sign to ceiling? - return itemstack - -- Floor - elseif wdir == 1 then - -- Standing sign - - -- Determine the sign rotation based on player's yaw - local yaw = math.pi*2 - placer:get_look_horizontal() - - -- Select one of 16 possible rotations (0-15) - local rotation_level = round((yaw / (math.pi*2)) * 16) - - if rotation_level > 15 then - rotation_level = 0 - elseif rotation_level < 0 then - rotation_level = 15 - end - - -- The actual rotation is a combination of predefined mesh and facedir (see node definition) - if rotation_level % 4 == 0 then - nodeitem:set_name("mcl_signs:standing_sign") - elseif rotation_level % 4 == 1 then - nodeitem:set_name("mcl_signs:standing_sign22_5") - elseif rotation_level % 4 == 2 then - nodeitem:set_name("mcl_signs:standing_sign45") - elseif rotation_level % 4 == 3 then - nodeitem:set_name("mcl_signs:standing_sign67_5") - end - fdir = math.floor(rotation_level / 4) - - -- Place the node! - local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) - if not success then - return itemstack - end - if not minetest.is_creative_enabled(placer:get_player_name()) then - itemstack:take_item() - end - sign_info = signtext_info_standing[rotation_level + 1] - -- Side - else - -- Wall sign - local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) - if not success then - return itemstack - end - sign_info = signtext_info_wall[fdir + 1] - end - - -- Determine spawn position of entity - local place_pos - if minetest.registered_nodes[node_under.name].buildable_to then - place_pos = under - else - place_pos = above - end - - local text_entity = minetest.add_entity({ - x = place_pos.x + sign_info.delta.x, - y = place_pos.y + sign_info.delta.y, - z = place_pos.z + sign_info.delta.z}, "mcl_signs:text") - text_entity:set_yaw(sign_info.yaw) - text_entity:get_luaentity()._signnodename = nodeitem:get_name() - - minetest.sound_play({name="default_place_node_hard", gain=1.0}, {pos = place_pos}, true) - - show_formspec(placer, place_pos) - return itemstack - end, - on_destruct = destruct_sign, - on_punch = function(pos, node, puncher) - update_sign(pos) - end, - on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - local r = screwdriver.rotate.wallmounted(pos, node, mode) - node.param2 = r - minetest.swap_node(pos, node) - update_sign(pos, nil, nil, true) - return true - else - return false - end - end, - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -}) - --- Standing sign nodes. --- 4 rotations at 0°, 22.5°, 45° and 67.5°. --- These are 4 out of 16 possible rotations. --- With facedir the remaining 12 rotations are constructed. - --- 0° -local ssign = { - paramtype = "light", - 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 = sign_groups, - drop = "mcl_signs:wall_sign", - stack_max = 16, - sounds = node_sounds, - - on_destruct = destruct_sign, - on_punch = function(pos, node, puncher) - update_sign(pos) - end, - 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) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true - end, - - _mcl_hardness = 1, - _mcl_blast_resistance = 1, -} - -minetest.register_node("mcl_signs:standing_sign", ssign) - --- 22.5° -local ssign22_5 = table.copy(ssign) -ssign22_5.mesh = "mcl_signs_sign22.5.obj" -ssign22_5.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign45" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign22_5", ssign22_5) - --- 45° -local ssign45 = table.copy(ssign) -ssign45.mesh = "mcl_signs_sign45.obj" -ssign45.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign67_5" - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign45", ssign45) - --- 67.5° -local ssign67_5 = table.copy(ssign) -ssign67_5.mesh = "mcl_signs_sign67.5.obj" -ssign67_5.on_rotate = function(pos, node, user, mode) - if mode == screwdriver.ROTATE_FACE then - node.name = "mcl_signs:standing_sign" - node.param2 = (node.param2 + 1) % 4 - minetest.swap_node(pos, node) - elseif mode == screwdriver.ROTATE_AXIS then - return false - end - update_sign(pos, nil, nil, true) - return true -end -minetest.register_node("mcl_signs:standing_sign67_5", ssign67_5) - +-- This defines the text entity for the lettering of the sign. -- FIXME: Prevent entity destruction by /clearobjects minetest.register_entity("mcl_signs:text", { - pointable = false, - visual = "upright_sprite", - textures = {}, - physical = false, - collide_with_objects = false, + pointable = false, + visual = "upright_sprite", + textures = {}, + physical = false, + collide_with_objects = false, - _signnodename = nil, -- node name of sign node to which the text belongs + _signnodename = nil, -- node name of sign node to which the text belongs - on_activate = function(self, staticdata) - if staticdata ~= nil and staticdata ~= "" then - local des = minetest.deserialize(staticdata) - if des then - self._signnodename = des._signnodename - end - end - local meta = minetest.get_meta(self.object:get_pos()) - local text = meta:get_string("text") - self.object:set_properties({ - textures={generate_texture(create_lines(text), self._signnodename)}, - }) - self.object:set_armor_groups({ immortal = 1 }) - end, - get_staticdata = function(self) - local out = { _signnodename = self._signnodename } - return minetest.serialize(out) - end, + on_activate = function(self, staticdata) + + local meta = minetest.get_meta(self.object:get_pos()) + local text = meta:get_string("text") + local text_color = meta:get_string("mcl_signs:text_color") + local glowing_sign = meta:get_string("mcl_signs:glowing_sign") + if staticdata and staticdata ~= "" then + local des = minetest.deserialize(staticdata) + if des then + self._signnodename = des._signnodename + if des._text_color ~= nil and des._text_color ~= "" then + self.text_color = des._text_color + end + if des._glowing_sign ~= nil and des._glowing_sign ~= "" then + self.glowing_sign = des._glowing_sign + end + end + end + + if text_color == "" or text_color == nil then + text_color = "#000000" -- default to black text. + meta:set_string("mcl_signs:text_color", text_color) + end + + if glowing_sign == "" or glowing_sign == nil then + glowing_sign = "false" -- default to not glowing. + meta:set_string("mcl_signs:glowing_sign", glowing_sign) + end + + self.object:set_properties({ + textures = { mcl_signs:create_lettering(text, self._signnodename, text_color) }, + }) + if glowing_sign == "true" then + self.object:set_properties({ + glow = 6, --sign_glow, + }) + end + + self.object:set_armor_groups({ immortal = 1 }) + + end, + get_staticdata = function(self) + local out = { + _signnodename = self._signnodename, + } + return minetest.serialize(out) + end, }) -minetest.register_craft({ - type = "fuel", - recipe = "mcl_signs:wall_sign", - burntime = 10, -}) +-- Build the signs x,y,z & rotations so that they work. (IE, do not remove!) +mcl_signs.build_signs_info() -if minetest.get_modpath("mcl_core") then - minetest.register_craft({ - output = 'mcl_signs:wall_sign 3', - recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'group:wood', 'group:wood', 'group:wood'}, - {'', 'mcl_core:stick', ''}, - } - }) +-- ---------------------------- -- +-- Register Signs for use. -- +-- ---------------------------- -- + +-- Standard (original) Sign +mcl_signs.register_sign("mcl_core", "#ffffff", "", S("Sign")) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:wood", "") + +-- birchwood Sign "#d5cb8d" / "#ffdba7" +mcl_signs.register_sign_custom("mcl_core", "_birchwood", + "mcl_signs_sign_greyscale.png","#ffdba7", "mcl_signs_default_sign_greyscale.png", + "mcl_signs_default_sign_greyscale.png", S("Birch Sign") +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:birchwood", "_birchwood") + +-- sprucewood Sign +mcl_signs.register_sign_custom("mcl_core", "_sprucewood", + "mcl_signs_sign_dark.png","#ffffff", "mcl_signs_default_sign_dark.png", + "mcl_signs_default_sign_dark.png", S("Spruce Sign") +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:sprucewood", "_sprucewood") + +-- darkwood Sign "#291f1a" / "#856443" +mcl_signs.register_sign_custom("mcl_core", "_darkwood", + "mcl_signs_sign_greyscale.png","#856443", "mcl_signs_default_sign_greyscale.png", + "mcl_signs_default_sign_greyscale.png", S("Dark Oak Sign") +) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:darkwood", "_darkwood") + +-- junglewood Sign +mcl_signs.register_sign("mcl_core", "#866249", "_junglewood", S("Jungle Sign")) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:junglewood", "_junglewood") + +-- acaciawood Sign "b8693d" +mcl_signs.register_sign("mcl_core", "#ea7479", "_acaciawood", S("Acacia Sign")) +mcl_signs.register_sign_craft("mcl_core", "mcl_core:acaciawood", "_acaciawood") + +if minetest.get_modpath("mcl_mangrove") then + -- mangrove_wood Sign "#c7545c" + mcl_signs.register_sign("mcl_mangrove", "#b8693d", "_mangrove_wood", S("Mangrove Sign")) + mcl_signs.register_sign_craft("mcl_mangrove", "mcl_mangrove:mangrove_wood", "_mangrove_wood") end -if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45") - doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5") +-- add in the nether wood signs +if minetest.get_modpath("mcl_crimson") then + + -- warped_hyphae_wood Sign + mcl_signs.register_sign_custom("mcl_crimson","_warped_hyphae_wood", "mcl_signs_sign_greyscale.png", + "#9f7dcf", "mcl_signs_default_sign_greyscale.png", "mcl_signs_default_sign_greyscale.png", + S("Warped Hyphae Sign")) + mcl_signs.register_sign_craft("mcl_crimson", "mcl_crimson:warped_hyphae_wood", "_warped_hyphae_wood") + + -- crimson_hyphae_wood Sign + mcl_signs.register_sign_custom("mcl_crimson", "_crimson_hyphae_wood","mcl_signs_sign_greyscale.png", + "#c35f51","mcl_signs_default_sign_greyscale.png", "mcl_signs_default_sign_greyscale.png", + S("Crimson Hyphae Sign")) + mcl_signs.register_sign_craft("mcl_crimson", "mcl_crimson:crimson_hyphae_wood", "_crimson_hyphae_wood") + end +-- Register the LBMs for the created signs. +mcl_signs.make_lbm() + +-- really ancient compatibility. minetest.register_alias("signs:sign_wall", "mcl_signs:wall_sign") minetest.register_alias("signs:sign_yard", "mcl_signs:standing_sign") - -minetest.register_lbm({ - name = "mcl_signs:respawn_entities", - label = "Respawn sign text entities", - run_at_every_load = true, - nodenames = { "mcl_signs:wall_sign", "mcl_signs:standing_sign", "mcl_signs:standing_sign22_5", "mcl_signs:standing_sign45", "mcl_signs:standing_sign67_5" }, - action = function(pos, node) - update_sign(pos) - end, -}) +minetest.register_alias("mcl_signs:wall_sign_dark", "mcl_signs:wall_sign_sprucewood") +minetest.register_alias("mcl_signs:standing_sign_dark", "mcl_signs:standing_sign_sprucewood") diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr index a7513659b..323e90364 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.de.tr @@ -1,9 +1,18 @@ # textdomain: mcl_signs -Sign=Schild +Sign=Zeichen / Schild 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.=Schilder können beschrieben werden und kommen in zwei Varianten: Wandschild und stehendes Schild. Sie können auf und an den Seiten von anderen Blöclen platziert werden, aber nicht unter ihnen. -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.=Nachdem das Schild platziert wurde, kann man etwas darauf schreiben. 4 Zeilen mit je 15 Zeichen pro Zeile sind verfügbar, alles darüber geht verloren. Es werden nicht alle Zeichen unterstützt. Der Text kann nicht geändert werden, sobald er geschrieben wurde; man muss das Schild erneut platzieren. +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.=Nachdem das Schild platziert wurde, kann man etwas darauf schreiben. 4 Zeilen mit je 15 Zeichen pro Zeile sind verfügbar, alles darüber geht verloren. Es werden nicht alle Zeichen unterstützt. Der Text kann nicht geändert werden, sobald er geschrieben wurde; man muss das Schild erneut platzieren. Kann gefärbt und zum Leuchten gebracht werden. Enter sign text:=Schildtext eingeben: Maximum line length: 15=Maximale Zeilenlänge: 15 Maximum lines: 4=Maximale Zeilen: 4 Done=Fertig Can be written=Kann beschriftet werden +Oak Sign=Eichezeichen +Birch Sign=Birke Zeichen +Spruce Sign=Fichtenzeichen +Dark Oak Sign=Dunkles Eichenschild +Jungle Sign=Dschungelzeichen +Acacia Sign=Akazienzeichen +Mangrove Sign=Mangroven-Zeichen +Warped Hyphae Sign=Verzerrtes Hyphen-Zeichen +Crimson Hyphae Sign=Hochrotes Hyphen-Zeichen diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr index d67e2da0d..87f737935 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.es.tr @@ -1,8 +1,18 @@ # textdomain: mcl_signs -Sign=Firmar +Sign=Signo / Firmar 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.=Los letreros se pueden escribir y vienen en dos variantes: letrero de muro y letrero en un poste de letrero. Los letreros se pueden colocar en la parte superior y en los costados de otros bloques, pero no debajo de ellos. -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.=Después de colocar el letrero, puede escribir algo en él. Tiene 4 líneas de texto con hasta 15 caracteres para cada línea; todo lo que esté más allá de estos límites se pierde. No todos los personajes son compatibles. El texto no se puede cambiar una vez que se ha escrito; tienes que romper y colocar el letrero nuevamente. +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.=Después de colocar el letrero, puede escribir algo en él. Tiene 4 líneas de texto con hasta 15 caracteres para cada línea; todo lo que esté más allá de estos límites se pierde. No todos los personajes son compatibles. El texto no se puede cambiar una vez que se ha escrito; tienes que romper y colocar el letrero nuevamente. Enter sign text:=Inserte el texto del letrero: Maximum line length: 15=Longitud máxima de línea: 15 Maximum lines: 4=Líneas máximas: 4 +Can be written=Los letreros se pueden escribir Done=Escribir cartel +Oak Sign=Signo de roble +Birch Sign=Signo de abedul +Spruce Sign=Signo de abeto +Dark Oak Sign=Signo de roble oscuro +Jungle Sign= Signo de la selva +Acacia Sign= Signo de acacia +Mangrove Sign= Signo de manglar +Warped Hyphae Sign=Signo de hifas deformadas +Crimson Hyphae Sign=Signo de hifas carmesí diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr index 158640dae..8792f4d2e 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.fr.tr @@ -1,9 +1,19 @@ # textdomain: mcl_signs Sign=Panneau 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.=Les panneaux peuvent être écrits et se déclinent en deux variantes: panneau mural et panneau sur poteau. Des panneaux peuvent être placés en haut et sur les côtés des autres blocs, mais pas en dessous. -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.=Après avoir placé le panneau, vous pouvez écrire quelque chose dessus. Vous avez 4 lignes de texte avec jusqu'à 15 caractères pour chaque ligne; tout ce qui dépasse ces limites est perdu. Tous les caractères ne sont pas pris en charge. Le texte ne peut pas être modifié une fois qu'il a été écrit; vous devez casser et placer à nouveau le panneau. -Enter sign text:=Saisir le texte du panneau: -Maximum line length: 15=Longueur maximum des lignes: 15 -Maximum lines: 4=Nombre maximum de lignes: 4 +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.=Après avoir placé le panneau, vous pouvez écrire quelque chose dessus. Vous avez 4 lignes de texte avec jusqu'à 15 caractères pour chaque ligne; tout ce qui dépasse ces limites est perdu. Tous les caractères ne sont pas pris en charge. Le texte ne peut pas être modifié une fois qu'il a été écrit; vous devez casser et placer à nouveau le panneau. Peut être coloré et rendu brillant. +Enter sign text:=Saisir le texte du panneau : +Maximum line length: 15=Longueur maximum des lignes : 15 +Maximum lines: 4=Nombre maximum de lignes : 4 Done=Terminé Can be written=Peut être écrit +Oak Sign=Panneau de chêne +Birch Sign=Panneau de bouleau +Spruce Sign=Panneau de sapin +Dark Oak Sign=Panneau de chêne noir +Jungle Sign=Panneau d'acajou +Acacia Sign=Panneau d'acacia +Mangrove Sign=Panneau de palétuvier +Warped Hyphae Sign=Panneau d'hyphe tordu +Crimson Hyphae Sign=Panneau d'hyphe écarlate +Bamboo Sign=Panneau de bambou diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr new file mode 100644 index 000000000..c6b4032c3 --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.ja.tr @@ -0,0 +1,16 @@ +# 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.=看板は書くことができ、2つのバリエーションがあります(壁かけ看板と立て看板)。看板の設置は、他のブロックの上部と側面にできますが、下部にはできません。 +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.=看板を設置した後、そこに何かを書き込めます。文字数は、1行あたり15文字で4行まで、それ以上は失われます。すべての文字がサポートされているわけではありません。一度書いた文字は変更できません(変えるには看板を壊して再配置)。着色や発光が可能です。 +Enter sign text:=看板の文字を入力: +Maximum line length: 15=1行あたりの最大文字数:15 +Maximum lines: 4=最大行数:4 +Done=完了 +Can be written=書き込み可能 +Oak Sign=オークの看板 +Birch Sign=シラカバの看板 +Spruce Sign=トウヒの看板 +Dark Oak Sign=ダークオークの看板 +Jungle Sign=ジャングルの看板 +Acacia Sign=アカシアの看板 +Mangrove Sign=マングローブの看板 diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr new file mode 100644 index 000000000..b9fbcd1bf --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.pl.tr @@ -0,0 +1,18 @@ +# textdomain: mcl_signs +Sign=Znak +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.=Na znakach można pisać i postawić je w dwóch wariantach: znak ścienny i znak na patyku. Znaki mogą być stawiane na górze i na bokach bloków, ale nie pod nimi. +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.=Po postawieniu znaku możesz coś na nim napisać. Masz miejsce na cztery linie tekstu po 15 znaków każda; cokolwiek poza limitami będzie utracone. Nie wszystkie znaki są wspierane. Tekstu nie można zmienić po napisaniu; musisz zniszczyć znak i postawić go ponownie. Może być pokolorowany i rozświetlony. +Enter sign text:=Wpisz tekst znaku: +Maximum line length: 15=Maksymalna długość linii: 15 +Maximum lines: 4=Maksymalna liczba linii: 4 +Done=Skończone +Can be written=Można na nim coś napisać +Oak Sign=Znak dębu +Birch Sign=Brzoza Znak +Spruce Sign=Świerk Znak +Dark Oak Sign=Znak ciemnego dębu +Jungle Sign=Znak Dżungli +Acacia Sign=Znak akacji +Mangrove Sign=Znak namorzynowy +Warped Hyphae Sign=Wypaczony znak strzępek +Crimson Hyphae Sign=Karmazynowy znak strzępek diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr index 354e556a8..279bde614 100644 --- a/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.ru.tr @@ -1,9 +1,18 @@ # 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.=После установки таблички вы можете написать на ней что-то. Вам доступны 4 строки текста, до 15 символов в каждой; всё, что вы напишете сверх лимита, потеряется. Поддерживаются не все символы. Текст нельзя изменить. Чтобы изменить его, вам придётся сломать табличку и подписать её снова. +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=Багровый знак гиф diff --git a/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr b/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr new file mode 100644 index 000000000..d2cabe04e --- /dev/null +++ b/mods/ITEMS/mcl_signs/locale/mcl_signs.zh_TW.tr @@ -0,0 +1,16 @@ +# 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:=輸入告示牌文字: +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=紅樹林標誌 diff --git a/mods/ITEMS/mcl_signs/locale/template.txt b/mods/ITEMS/mcl_signs/locale/template.txt index 6635e989f..e1002e126 100644 --- a/mods/ITEMS/mcl_signs/locale/template.txt +++ b/mods/ITEMS/mcl_signs/locale/template.txt @@ -1,9 +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.= +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.= Enter sign text:= Maximum line length: 15= Maximum lines: 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= +Bamboo Sign= diff --git a/mods/ITEMS/mcl_signs/mod.conf b/mods/ITEMS/mcl_signs/mod.conf index 8346bbcb4..e2fe9d40a 100644 --- a/mods/ITEMS/mcl_signs/mod.conf +++ b/mods/ITEMS/mcl_signs/mod.conf @@ -1 +1,4 @@ name = mcl_signs +description = New and Improved signs - can be colored and made to glow. +depends = mcl_core, mcl_sounds, mcl_dye, mcl_colors, mcl_util +optional_depends = doc diff --git a/mods/ITEMS/mcl_signs/signs_api.lua b/mods/ITEMS/mcl_signs/signs_api.lua new file mode 100644 index 000000000..7ada6a646 --- /dev/null +++ b/mods/ITEMS/mcl_signs/signs_api.lua @@ -0,0 +1,2032 @@ +--- +--- Generated by EmmyLua. +--- Created by Michieal (FaerRaven). +--- 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 + +-- LOCALIZATION +local S = minetest.get_translator("mcl_signs") +-- Signs form +local F = minetest.formspec_escape + +-- PATHs +local modpath = minetest.get_modpath("mcl_signs") + +-- CONSTANTS +local SIGN_WIDTH = 115 + +local LINE_LENGTH = 15 +local NUMBER_OF_LINES = 4 + +local LINE_HEIGHT = 14 +local CHAR_WIDTH = 5 +local TIMER_INTERVAL = 40.0 +-- ----------------------- +-- CACHE LOCAL COPIES +local table = table +local string = string + +-- CACHE NODE_SOUNDS +local node_sounds +if minetest.get_modpath("mcl_sounds") then + node_sounds = mcl_sounds.node_sound_wood_defaults() +end + +-- SET UP THE CHARACTER MAPPING +-- Load the characters map (characters.txt) +--[[ File format of characters.txt: +It's an UTF-8 encoded text file that contains metadata for all supported characters. It contains a sequence of info + blocks, one for each character. Each info block is made out of 3 lines: +Line 1: The literal UTF-8 encoded character +Line 2: Name of the texture file for this character minus the “.png” suffix; found in the “textures/” sub-directory +Line 3: Currently ignored. Previously this was for the character width in pixels + +After line 3, another info block may follow. This repeats until the end of the file. + +All character files must be 5 or 6 pixels wide (5 pixels are preferred) +]] + +local chars_file = io.open(modpath .. "/characters.txt", "r") +-- FIXME: Support more characters (many characters are missing). Currently ASCII and Latin-1 Supplement are supported. +local charmap = {} +if not chars_file then + minetest.log("error", "[mcl_signs] : character map file not found") +else + while true do + local char = chars_file:read("*l") + if char == nil then + break + end + local img = chars_file:read("*l") + chars_file:read("*l") + charmap[char] = img + end +end + +local pi = 3.1415926 -- enough accuracy, to build an engine for a car. + +local math = math + +-- locally cached copy of the official colors; this way, it updates as mcl_colors updates. +local mcl_colors_official = mcl_colors +if DEBUG then + minetest.log("verbose", "[mcl_signs]Official MCL_Colors:\n" .. dump(mcl_colors_official)) +end + +-- INITIALIZE THE GLOBAL API FOR SIGNS. +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 } +--- colors used for wools. +mcl_signs.mcl_wool_colors = { + unicolor_white = "#FFFFFF", + unicolor_dark_orange = "#502A00", + unicolor_grey = "#5B5B5B", + unicolor_darkgrey = "#303030", + unicolor_blue = "#0000CC", + unicolor_dark_green = "#005000", + unicolor_green_or_lime = "#50CC00", + unicolor_violet_purple = "#5000CC", + unicolor_light_red_pink = "#FF5050", + unicolor_yellow = "#CCCC00", + unicolor_orange = "#CC5000", + unicolor_red = "#CC0000", + unicolor_cyan = "#00CCCC", + unicolor_red_violet_magenta = "#CC0050", + unicolor_black = "#000000", + unicolor_light_blue = "#5050FF", +} +mcl_signs.signtext_info_wall = {} +mcl_signs.signtext_info_standing = {} -- built in build_signs_info(). +-- the rotational levels for all of the standing signs. +mcl_signs.standing_rotation_levels = {} + +-- data structure block for dynamically registered signs. +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. + local m = -1 / 16 + 1 / 64 -- " " " " " " " " + + mcl_signs.signtext_info_wall = { + { delta = { x = 0, y = 0, z = n }, yaw = 0 }, + { delta = { x = n, y = 0, z = 0 }, yaw = pi / -2 }, + { delta = { x = 0, y = 0, z = -n }, yaw = pi }, + { delta = { x = -n, y = 0, z = 0 }, yaw = pi / 2 }, + } + + -- PLACE YAW VALUES INTO THE TABLE. + for rot = 0, 15 do + local yaw = pi * 2 - (((pi * 2) / 16) * rot) + local delta = vector.multiply(minetest.yaw_to_dir(yaw), m) + -- Offset because sign is a bit above node boundaries + delta.y = delta.y + 2 / 28 + table.insert(mcl_signs.signtext_info_standing, { delta = delta, yaw = yaw }) + end + +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, + stack_max = 16, + sounds = node_sounds, + + 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) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + + --local placer_pos = placer:get_pos() + + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + end + + if wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign") + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5") + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45") + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5") + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + if DEBUG then + minetest.log("verbose", "[mcl_signs]Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + 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) + if mode == screwdriver.ROTATE_FACE then + local r = screwdriver.rotate.wallmounted(pos, node, mode) + node.param2 = r + minetest.swap_node(pos, node) + mcl_signs:update_sign(pos, nil, nil, true) + return true + 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 + + -- 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) + -- 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) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + 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, +} + +-- HELPER FUNCTIONS' VARIABLES +local sign_glow = 6 +local Dyes_table = { + { "mcl_dye:aqua", mcl_colors_official.AQUA }, + { "mcl_dye:black", mcl_colors_official.BLACK }, + { "mcl_dye:blue", mcl_colors_official.BLUE }, + { "mcl_dye:brown", mcl_colors_official.brown }, + { "mcl_dye:cyan", mcl_signs.mcl_wool_colors.unicolor_cyan }, + { "mcl_dye:green", mcl_colors_official.GREEN }, + { "mcl_dye:dark_green", mcl_colors_official.DARK_GREEN }, + { "mcl_dye:grey", mcl_colors_official.GRAY }, + { "mcl_dye:dark_grey", mcl_colors_official.DARK_GRAY }, + { "mcl_dye:lightblue", mcl_signs.mcl_wool_colors.unicolor_light_blue }, + { "mcl_dye:lime", mcl_signs.unicolor_green_or_lime }, + { "mcl_dye:magenta", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:orange", mcl_signs.mcl_wool_colors.unicolor_orange }, + { "mcl_dye:pink", mcl_signs.mcl_wool_colors.unicolor_light_red_pink }, + { "mcl_dye:purple", mcl_colors_official.LIGHT_PURPLE }, + { "mcl_dye:red", mcl_signs.mcl_wool_colors.unicolor_red }, + { "mcl_dye:silver", mcl_signs.mcl_wool_colors.unicolor_grey }, + { "mcl_dye:violet", mcl_colors_official.DARK_PURPLE }, + { "mcl_dye:white", mcl_colors_official.WHITE }, + { "mcl_dye:yellow", mcl_colors_official.YELLOW }, +} + +local function update_sign_registry(type, name) + if type == "wall" then + table.insert(mcl_signs.registered_signs.wall_signs, name) + end + if type == "standing" then + table.insert(mcl_signs.registered_signs.standing_signs, name) + end + if type == "hanging" then + table.insert(mcl_signs.registered_signs.hanging_signs, name) + end +end + +function mcl_signs.make_lbm() + + local registered_sign_nodenames = {} + + for i = 0, #mcl_signs.registered_signs.wall_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.wall_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.standing_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.standing_signs[i]) + end + + for i = 0, #mcl_signs.registered_signs.hanging_signs do + table.insert(registered_sign_nodenames, mcl_signs.registered_signs.hanging_signs[i]) + end + + -- the above is not yet used. + minetest.register_lbm({ + name = "mcl_signs:respawn_entities", + label = "Respawn sign text entities", + run_at_every_load = true, + nodenames = registered_sign_nodenames, + action = function(pos, node) + mcl_signs:update_sign(pos) + end, + }) + +end + +function mcl_signs.register_dye (modname, item_name, color_code) + if minetest.get_modpath(modname) then + table.insert(Dyes_table, { item_name, color_code }) + end +end + +--- Register a new sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = ttsign + + new_sign.wield_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + + local yaw = 0 + + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? simple - hanging sign. + -- add code for placement underneath a node. + + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + 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 }) +end + +--- The same as register_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "mcl_signs_default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.register_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + if not color or color == nil then + new_sign.wield_image = wield_image + new_sign.tiles = { tiles } + new_sign.inventory_image = inventory_image + else + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + end + + new_sign.description = ttsign + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.register_node(":mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + if not color or color == nil then + new_sign_standing.wield_image = wield_image + new_sign_standing.tiles = { tiles } + new_sign_standing.inventory_image = inventory_image + else + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + end + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.register_node(":mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.register_node(":mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + 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 }) + +end + +--- Override an existing sign, tint the textures, and gives it an unique node name. Creates both wall and standing signs. +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- color: the color code to color the base sign textures. must be a valid html color code. +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign (modname, color, _name, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + if color == nil or color == "" then + color = "#FFFFFF" + end + + new_sign = table.copy(mcl_signs.wall_standard) + new_sign.description = ttsign + + new_sign.wield_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + new_sign.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + if DEBUG then + minetest.log("action", "[mcl_signs] Register_Sign::Placed position:" .. dump(place_pos) .. "\nSign_info: " .. dump(sign_info)) + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:wall_sign" .. _name .. color .. "\n" .. dump(new_sign)) + minetest.log("action", "[mcl_signs] mcl_signs:wall_sign_standard\n" .. dump(mcl_signs.wall_standard)) + end + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + new_sign_standing.drop = "mcl_signs:wall_sign" .. _name + new_sign_standing.wield_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(mcl_signs_sign.png^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(mcl_signs_default_sign.png^[multiply:" .. color .. ")" + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Registered: mcl_signs:standing_sign" .. _name .. color .. "\n" .. dump(new_sign_standing)) + end + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + 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 }) +end + +--- The same as reregister_sign, except caller defines the textures. Note, there is a greyscale version of the sign, +--- called "mcl_signs_default_sign_greyscale.png" and "mcl_signs_sign_greyscale.png" for optional use in the textures directory. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +--- +--- tiles: the texture file to use for the sign. +--- +--- color: color the texture file to use with this color. Use white (#FFFFFF) to negate the color, +--- and just use the texture as is +--- +--- inventory_image: the texture file to use for the sign's display in inventory. +--- +--- wield_image: the texture file to use for the sign's weilded (in hand) object. +--- +--- inventory_image: the image used for in-inventory and in hand. +--- +--- ttsign: the tool tip of the sign that gets translated. Shown when the mouse hovers the inventory sign. +--- For example: the basic, default oak (wood) sign is just "Sign"; and a spruce sign would be "Spruce Sign" +function mcl_signs.reregister_sign_custom (modname, _name, tiles, color, inventory_image, wield_image, ttsign) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + local new_sign = {} + + new_sign = table.copy(mcl_signs.wall_standard) + + if not color or color == nil then + new_sign.wield_image = wield_image + new_sign.tiles = { tiles } + new_sign.inventory_image = inventory_image + else + new_sign.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + end + new_sign.description = ttsign + -- currently have to do this, because of how the base node placement works. + new_sign.on_place = function(itemstack, placer, pointed_thing) + local above = pointed_thing.above + local under = pointed_thing.under + + -- Use pointed node's on_rightclick function first, if present + local node_under = minetest.get_node(under) + if placer and not placer:get_player_control().sneak then + if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then + return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack + end + end + + local dir = vector.subtract(under, above) + + -- Only build when it's legal + local abovenodedef = minetest.registered_nodes[minetest.get_node(above).name] + if not abovenodedef or abovenodedef.buildable_to == false then + return itemstack + end + + local wdir = minetest.dir_to_wallmounted(dir) + local fdir = minetest.dir_to_facedir(dir) + + local sign_info + local nodeitem = ItemStack(itemstack) + -- Ceiling + if wdir == 0 then + --how would you add sign to ceiling? + return itemstack + -- Floor + elseif wdir == 1 then + -- Standing sign + + -- Determine the sign rotation based on player's yaw + local yaw = pi * 2 - placer:get_look_horizontal() + + -- Select one of 16 possible rotations (0-15) + local rotation_level = mcl_signs:round((yaw / (pi * 2)) * 16) + + if rotation_level > 15 then + rotation_level = 0 + elseif rotation_level < 0 then + rotation_level = 15 + end + + -- The actual rotation is a combination of predefined mesh and facedir (see node definition) + if rotation_level % 4 == 0 then + nodeitem:set_name("mcl_signs:standing_sign" .. _name) + elseif rotation_level % 4 == 1 then + nodeitem:set_name("mcl_signs:standing_sign22_5" .. _name) + elseif rotation_level % 4 == 2 then + nodeitem:set_name("mcl_signs:standing_sign45" .. _name) + elseif rotation_level % 4 == 3 then + nodeitem:set_name("mcl_signs:standing_sign67_5" .. _name) + end + fdir = math.floor(rotation_level / 4) + + -- Place the node! + local _, success = minetest.item_place_node(nodeitem, placer, pointed_thing, fdir) + if not success then + return itemstack + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + itemstack:take_item() + end + sign_info = mcl_signs.signtext_info_standing[rotation_level + 1] + -- Side + else + -- Wall sign + local _, success = minetest.item_place_node(itemstack, placer, pointed_thing, wdir) + if not success then + return itemstack + end + sign_info = mcl_signs.signtext_info_wall[fdir + 1] + end + + -- Determine spawn position of entity + local place_pos + if minetest.registered_nodes[node_under.name].buildable_to then + place_pos = under + else + place_pos = above + end + + local text_entity = minetest.add_entity({ + x = place_pos.x + sign_info.delta.x, + y = place_pos.y + sign_info.delta.y, + z = place_pos.z + sign_info.delta.z }, "mcl_signs:text") + text_entity:set_yaw(sign_info.yaw) + text_entity:get_luaentity()._signnodename = nodeitem:get_name() + + minetest.sound_play({ name = "default_place_node_hard", gain = 1.0 }, { pos = place_pos }, true) + + mcl_signs:show_formspec(placer, place_pos) + return itemstack + end + minetest.override_item("mcl_signs:wall_sign" .. _name, new_sign) + update_sign_registry("wall", "mcl_signs:wall_sign" .. _name) + + -- standing sign base. + local new_sign_standing = {} + new_sign_standing = table.copy(mcl_signs.standing_standard) + if not color or color == nil then + new_sign_standing.wield_image = wield_image + new_sign_standing.tiles = { tiles } + new_sign_standing.inventory_image = inventory_image + else + new_sign_standing.wield_image = "(" .. wield_image .. "^[multiply:" .. color .. ")" + new_sign_standing.tiles = { "(" .. tiles .. "^[multiply:" .. color .. ")" } + new_sign_standing.inventory_image = "(" .. inventory_image .. "^[multiply:" .. color .. ")" + end + new_sign_standing.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign22_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end, + minetest.override_item("mcl_signs:standing_sign" .. _name, new_sign_standing) + update_sign_registry("standing", "mcl_signs:standing_sign" .. _name) + + -- 22.5° + local ssign22_5d = table.copy(new_sign_standing) + ssign22_5d.mesh = "mcl_signs_sign22.5.obj" + ssign22_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign45" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign22_5" .. _name, ssign22_5d) + update_sign_registry("standing", "mcl_signs:standing_sign22_5" .. _name) + + -- 45° + local ssign45d = table.copy(new_sign_standing) + ssign45d.mesh = "mcl_signs_sign45.obj" + ssign45d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign67_5" .. _name + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign45" .. _name, ssign45d) + update_sign_registry("standing", "mcl_signs:standing_sign45" .. _name) + + -- 67.5° + local ssign67_5d = table.copy(new_sign_standing) + ssign67_5d.mesh = "mcl_signs_sign67.5.obj" + ssign67_5d.on_rotate = function(pos, node, user, mode) + if mode == screwdriver.ROTATE_FACE then + node.name = "mcl_signs:standing_sign" .. _name + node.param2 = (node.param2 + 1) % 4 + minetest.swap_node(pos, node) + elseif mode == screwdriver.ROTATE_AXIS then + return false + end + mcl_signs:update_sign(pos, nil, nil, true) + return true + end + minetest.override_item("mcl_signs:standing_sign67_5" .. _name, ssign67_5d) + update_sign_registry("standing", "mcl_signs:standing_sign67_5" .. _name) + + -- register Doc entry + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:wall_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign22_5" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign45" .. _name) + doc.add_entry_alias("nodes", "mcl_signs:wall_sign", "nodes", "mcl_signs:standing_sign67_5" .. _name) + end + + --register standing sign's rotation_levels + 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 }) + +end + +--- Usage: Call this with the mod's name, the wood's item string (for the planks), and with the sign's suffix. +--- Registers the crafting recipe for that sign. for every registered sign, call this function to register the +--- standard recipe for the sign. Otherwise, you have to do your own register craft call. +--- +--- modname: optional (pass "" or "false" to ignore), for use with other mods to +--- allow the creation of a sign from the mod's wood (if installed). Example: "mcl_core". +--- +--- wood_item_string: example: "mcl_core:wood" or "mcl_core:sprucewood" +--- +--- _name: the sign's name suffix, such as "_dark" or "_red", etc., appended to "wall_sign" or "standing_sign" +function mcl_signs.register_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = "mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = "mcl_signs:wall_sign" + + minetest.register_craft({ + output = itemstring .. _name .. " 3", + recipe = { + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + { "", "mcl_core:stick", "" }, + }, + }) + end +end + +function mcl_signs.register_hanging_sign_craft(modname, wood_item_string, _name) + local mod_name_pass = false + if modname ~= "" and modname ~= "false" then + if minetest.get_modpath(modname) then + mod_name_pass = true + end + if mod_name_pass == false then + return + end + end + + minetest.register_craft({ + type = "fuel", + recipe = ":mcl_signs:wall_sign" .. _name, + burntime = 10, + }) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Register Sign Crafts: \n" .. modname .. "\n" .. wood_item_string .. "\n" .. _name) + end + + -- register crafts (actual recipe) + if minetest.get_modpath(modname) then + + local itemstring = ":mcl_signs:hanging_sign" + local quantity = "6" + + local bamboo = string.find(wood_item_string, "bamboo") + if bamboo then + quantity = "2" + end + minetest.register_craft({ + output = itemstring .. _name .. " " .. quantity, + recipe = { + { "mcl_lanterns:chain", "", "mcl_lanterns:chain" }, + { wood_item_string, wood_item_string, wood_item_string }, + { wood_item_string, wood_item_string, wood_item_string }, + }, + }) + end +end + +-- Helper functions +local function string_to_array(str) + local string_table = {} + for i = 1, string.len(str) do + table.insert(string_table, string.sub(str, i, i)) + end + return string_table +end + +local function string_to_line_array(str) + local linechar_table = {} + local current = 1 + local linechar = 1 + linechar_table[1] = "" + for _, char in ipairs(string_to_array(str)) do + -- New line + if char == "\n" then + current = current + 1 + linechar_table[current] = "" + linechar = 1 + else + linechar_table[current] = linechar_table[current] .. char + linechar = linechar + 1 + end + end + return linechar_table +end + +local function get_rotation_level(facedir, nodename) + local nnames = mcl_signs.standing_rotation_levels -- functional copy... was easier this way. #LazyAF :P + + local rl + local offset = 0 + for x = 1, #nnames do + if nnames[x][1] == nodename then + offset = nnames[x][2] + break + end + end + rl = facedir * 4 + offset + if DEBUG then + minetest.log("action", "[mcl_signs] GetRotationLevel: NodeName: " .. nodename .. " RL value: " .. rl) + end + return rl +end + +function mcl_signs:round(num, idp) + local mult = 10 ^ (idp or 0) + return math.floor(num * mult + 0.5) / mult +end + +function mcl_signs:get_color_for_sign(item_name) + + for d = 1, #Dyes_table do + if Dyes_table[d][1] == item_name then + return Dyes_table[d][2] + end + end + return "false" +end + +function mcl_signs:color_sign (pos, text_color) + + local success = mcl_signs:update_sign(pos, nil, nil, true, text_color) + + -- debug step + local meta = minetest.get_meta(pos) + if not meta then + minetest.log("error", "[mcl_signs] Sign Color Fail - Metadata.") + + return false + end + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Color: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return success + +end + +function mcl_signs:glow_sign (pos, remove_glow) + local success = true + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text") + if text == nil then + text = "" + end + + -- we can't make the text glow if there isn't any text + if text == "" then + return false + end + + if remove_glow == nil then + remove_glow = false + end + + -- set up text glow + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + text_entity = v + break + end + end + if remove_glow == true then + text_entity:set_properties({ + glow = nil, + }) + meta:set_string("mcl_signs:glowing_sign", "false") + else + text_entity:set_properties({ + glow = sign_glow, + }) + meta:set_string("mcl_signs:glowing_sign", "true") + end + if not text_entity then + return false + end + text_entity:get_luaentity()._glowing_sign = meta:get_string("mcl_signs:glowing_sign") + + -- debug step + if DEBUG then + minetest.log("verbose", "[mcl_signs] Post-Sign Glow: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + return success +end + +function mcl_signs:create_lettering(text, signnodename, sign_color) + if sign_color == nil then + sign_color = mcl_colors.BLACK + end + local texture = mcl_signs:generate_texture(mcl_signs:create_lines(text), signnodename, sign_color) + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Creating sign text; text:" .. text) + end + + return texture +end + +function mcl_signs:create_lines(text) + local line_num = 1 + local text_table = {} + for _, line in ipairs(string_to_line_array(text)) do + if line_num > NUMBER_OF_LINES then + break + end + table.insert(text_table, line) + line_num = line_num + 1 + end + return text_table +end + +function mcl_signs:generate_line(s, ypos) + local i = 1 + local parsed = {} + local width = 0 + local chars = 0 + local printed_char_width = CHAR_WIDTH + 1 + while chars < LINE_LENGTH and i <= #s do + local file + -- Get and render character + if charmap[s:sub(i, i)] then + file = charmap[s:sub(i, i)] + i = i + 1 + elseif i < #s and charmap[s:sub(i, i + 1)] then + file = charmap[s:sub(i, i + 1)] + i = i + 2 + else + -- No character image found. + -- Use replacement character: + file = "_rc" + i = i + 1 + if DEBUG then + minetest.log("verbose", "[mcl_signs] Unknown symbol in '" .. s .. "' at " .. i) + end + end + if file then + width = width + printed_char_width + table.insert(parsed, file) + chars = chars + 1 + end + end + width = width - 1 + + local texture = "" + local xpos = math.floor((SIGN_WIDTH - width) / 2) + + for j = 1, #parsed do + texture = texture .. ":" .. xpos .. "," .. ypos .. "=" .. parsed[j] .. ".png" + xpos = xpos + printed_char_width + end + return texture +end + +function mcl_signs:generate_texture(lines, signnodename, letter_color) + local texture = "[combine:" .. SIGN_WIDTH .. "x" .. SIGN_WIDTH + local ypos = 0 + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if signnodename == mcl_signs.registered_signs.wall_signs[x] then + ypos = 30 + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if signnodename == mcl_signs.registered_signs.standing_signs[x] then + ypos = 0 + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if signnodename == mcl_signs.registered_signs.hanging_signs[x] then + ypos = 30 + break + end + end + ]] + + -- kept in for now, compatibility with existing hard coded signs. TODO: Remove after done with api. + if signnodename == "mcl_signs:wall_sign" or signnodename == "mcl_signs:wall_sign_dark" then + ypos = 30 + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Generate_Texture::Debug_Data:\nSignNodeName: " .. dump(signnodename) .. "\nYPOS: " .. ypos) + end + + for i = 1, #lines do + texture = texture .. mcl_signs:generate_line(lines[i], ypos) + ypos = ypos + LINE_HEIGHT + end + + texture = "(" .. texture .. "^[multiply:" .. letter_color .. ")" + return texture +end + +function mcl_signs:get_wall_signtext_info(param2, nodename) + local dir = minetest.wallmounted_to_dir(param2) + if dir.x > 0 then + return 2 + elseif dir.z > 0 then + return 1 + elseif dir.x < 0 then + return 4 + else + return 3 + end +end + +function mcl_signs:destruct_sign(pos) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + v:remove() + end + end + local players = minetest.get_connected_players() + for p = 1, #players do + if vector.distance(players[p]:get_pos(), pos) <= 30 then + minetest.close_formspec(players[p]:get_player_name(), "mcl_signs:set_text_" .. pos.x .. "_" .. pos.y .. "_" .. pos.z) + end + end +end + +function mcl_signs:update_sign(pos, fields, sender, force_remove, text_color) + -- Get Meta Data for the sign. + local meta = minetest.get_meta(pos) + + if not meta then + return false + end + local text = meta:get_string("text", "") + if fields and (text == "" and fields.text) then + meta:set_string("text", fields.text) + text = fields.text + end + if text == nil then + text = "" + end + + -- find text color. + local sign_color + + if meta:get_string("mcl_signs:text_color") == "" then + -- if no sign text color has been assigned, make it black. + sign_color = mcl_colors.BLACK + meta:set_string("mcl_signs:text_color", sign_color) + else + sign_color = meta:get_string("mcl_signs:text_color") + end + + if text_color == nil or text == "" then + text_color = "false" + end + + if text_color == "false" then + text_color = sign_color --if a new color hasn't been chosen, then keep the existing color. + end + + -- find the sign's glow value + local has_glow = false + + if meta:get_string("mcl_signs:glowing_sign") == "" or meta:get_string("mcl_signs:glowing_sign") == "false" then + has_glow = false + meta:set_string("mcl_signs:glowing_sign", "false") + else + has_glow = true + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Signs: Pre-Sign Update: " .. sign_color .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + local sign_info + local npos = minetest.get_node(pos) + local npos_name = npos.name + + -- Handle all of the dynamically created signs. + for x = 1, #mcl_signs.registered_signs.wall_signs do + if npos_name == mcl_signs.registered_signs.wall_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + break + end + end + for x = 1, #mcl_signs.registered_signs.standing_signs do + if npos_name == mcl_signs.registered_signs.standing_signs[x] then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + break + end + end + -- for future inclusion, when the hanging sings are made. + --[[ + for x = 1, #mcl_signs.registered_signs.hanging_signs do + if nn == mcl_signs.registered_signs.hanging_signs[x] then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(n.param2)] + break + end + end + ]] + + -- the following if..elseif..end block is here for compatibility with the old code. TODO: remove this block after the new api is complete. + if npos_name == "mcl_signs:standing_sign_dark" or npos_name == "mcl_signs:standing_sign22_5_dark" or npos_name == "mcl_signs:standing_sign45_dark" or npos_name == "mcl_signs:standing_sign67_5_dark" then + sign_info = mcl_signs.signtext_info_standing[get_rotation_level(npos.param2, npos_name) + 1] + elseif npos_name == "mcl_signs:wall_sign_dark" then + sign_info = mcl_signs.signtext_info_wall[mcl_signs:get_wall_signtext_info(npos.param2)] + end + if sign_info == nil then + minetest.log("error", "[mcl_signs] Update_Signs: Missing sign_info!") + return false + end + + local text_entity + text_entity = mcl_signs:get_text_entity(pos,force_remove) + + if not text_entity then + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Text_Entity - does not exist, creating it now.") + end + text_entity = minetest.add_entity({ + x = pos.x + sign_info.delta.x, + y = pos.y + sign_info.delta.y, + z = pos.z + sign_info.delta.z }, "mcl_signs:text") + + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Placed position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + end + text_entity:get_luaentity()._signnodename = npos_name + + -- set up special case: Dark Oak Sign. Dark Oak signs are soooo dark, they start off with white lettering. + if npos_name == "mcl_signs:wall_sign_darkwood" or + npos_name == "mcl_signs:standing_sign67_5_darkwood" or + npos_name == "mcl_signs:standing_sign45_darkwood" or + npos_name == "mcl_signs:standing_sign22_5_darkwood" or + npos_name == "mcl_signs:standing_sign_darkwood" + then + if text_color == "#000000" then + text_color = "#ffffff" + end + end + + -- Set the actual properties for the sign + + text_entity:set_properties({ + textures = { mcl_signs:create_lettering(text, npos_name, text_color) }, + }) + + if has_glow then + text_entity:set_properties({ + glow = sign_glow, + }) + end + + text_entity:set_yaw(sign_info.yaw) + if DEBUG then + minetest.log("verbose", "[mcl_signs] Update_Sign: After texture recreation.") + minetest.log("action", "[mcl_signs] Update_Sign: " .. npos_name .. "\nPlaced position:" .. dump(pos) .. "\nSign_info: " .. dump(sign_info)) + end + + -- save sign metadata. + meta:set_string("mcl_signs:text_color", text_color) + + -- Moved timer stuff to here, to make sure that it's called and only has one set of code. + local timer = minetest.get_node_timer(pos) + if text_entity and text ~= "" then + -- Do timer related stuff - but only if there is text to display. + -- Also, prevent excessive use with punching. (see node def.) + if timer:is_started() == false then + timer:start(TIMER_INTERVAL) + else + timer:stop() + timer:start(TIMER_INTERVAL) + end + else + if timer:is_started() == true then + timer:stop() + end + end + + -- debug step + if DEBUG then + minetest.log("action", "[mcl_signs] Update_Sign: Post-Sign Update: " .. meta:get_string("mcl_signs:text_color") .. " " .. meta:get_string("mcl_signs:glowing_sign") .. ".\n" .. dump(pos)) + end + + return true + +end + +function mcl_signs:show_formspec(player, pos) + 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")) .. "]" + ) +end + +function mcl_signs:get_text_entity (pos, force_remove) + local objects = minetest.get_objects_inside_radius(pos, 0.5) + local text_entity = false -- just to have a check for failure. + for _, v in ipairs(objects) do + local ent = v:get_luaentity() + if ent and ent.name == "mcl_signs:text" then + if force_remove ~= nil and force_remove == true then + v:remove() + else + text_entity = v + break + end + end + end + return text_entity +end diff --git a/mods/ITEMS/mcl_signs/textures/_0.png b/mods/ITEMS/mcl_signs/textures/_0.png deleted file mode 100644 index e764f3d6a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_0.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_1.png b/mods/ITEMS/mcl_signs/textures/_1.png deleted file mode 100644 index 7fae5fa4c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_1.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_2.png b/mods/ITEMS/mcl_signs/textures/_1_2.png deleted file mode 100644 index 52d025e87..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_1_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_4.png b/mods/ITEMS/mcl_signs/textures/_1_4.png deleted file mode 100644 index 220e65ef5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_1_4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_1_sup.png b/mods/ITEMS/mcl_signs/textures/_1_sup.png deleted file mode 100644 index 6be5fdcb1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_1_sup.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_2.png b/mods/ITEMS/mcl_signs/textures/_2.png deleted file mode 100644 index e32866d03..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_2.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_2_sup.png b/mods/ITEMS/mcl_signs/textures/_2_sup.png deleted file mode 100644 index 3db952179..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_2_sup.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_3.png b/mods/ITEMS/mcl_signs/textures/_3.png deleted file mode 100644 index 4e7da5665..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_3.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_3_4.png b/mods/ITEMS/mcl_signs/textures/_3_4.png deleted file mode 100644 index 46e171049..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_3_4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_3_sup.png b/mods/ITEMS/mcl_signs/textures/_3_sup.png deleted file mode 100644 index add337326..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_3_sup.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_4.png b/mods/ITEMS/mcl_signs/textures/_4.png deleted file mode 100644 index 5f3d95656..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_4.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_5.png b/mods/ITEMS/mcl_signs/textures/_5.png deleted file mode 100644 index baf23b273..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_5.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_6.png b/mods/ITEMS/mcl_signs/textures/_6.png deleted file mode 100644 index 31fcd7d72..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_6.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_7.png b/mods/ITEMS/mcl_signs/textures/_7.png deleted file mode 100644 index 7594eb9d6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_7.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_8.png b/mods/ITEMS/mcl_signs/textures/_8.png deleted file mode 100644 index b61f4e294..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_8.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_9.png b/mods/ITEMS/mcl_signs/textures/_9.png deleted file mode 100644 index 5ed82070b..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_9.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a.png b/mods/ITEMS/mcl_signs/textures/_a.png deleted file mode 100644 index 4b9356ac4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_.png b/mods/ITEMS/mcl_signs/textures/_a_.png deleted file mode 100644 index 152beabd4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_acute.png b/mods/ITEMS/mcl_signs/textures/_a_acute.png deleted file mode 100644 index b72b4853e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_acute_.png b/mods/ITEMS/mcl_signs/textures/_a_acute_.png deleted file mode 100644 index d038b45ce..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_circumflex.png b/mods/ITEMS/mcl_signs/textures/_a_circumflex.png deleted file mode 100644 index f9b80df66..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_circumflex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png deleted file mode 100644 index 8b35bdf7c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_circumflex_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_grave.png b/mods/ITEMS/mcl_signs/textures/_a_grave.png deleted file mode 100644 index 3f0de45a5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_grave.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_grave_.png b/mods/ITEMS/mcl_signs/textures/_a_grave_.png deleted file mode 100644 index 8176f51c5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_grave_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_ring.png b/mods/ITEMS/mcl_signs/textures/_a_ring.png deleted file mode 100644 index d3c06ae6d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_ring.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_ring_.png b/mods/ITEMS/mcl_signs/textures/_a_ring_.png deleted file mode 100644 index d3e9b7e96..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_ring_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_sup.png b/mods/ITEMS/mcl_signs/textures/_a_sup.png deleted file mode 100644 index 4f4f9801c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_sup.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_tilde.png b/mods/ITEMS/mcl_signs/textures/_a_tilde.png deleted file mode 100644 index 567632c37..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_tilde.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_a_tilde_.png b/mods/ITEMS/mcl_signs/textures/_a_tilde_.png deleted file mode 100644 index fd3d97784..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_a_tilde_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_acute.png b/mods/ITEMS/mcl_signs/textures/_acute.png deleted file mode 100644 index 0655de2dd..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae.png b/mods/ITEMS/mcl_signs/textures/_ae.png deleted file mode 100644 index 7f199e477..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ae.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_.png b/mods/ITEMS/mcl_signs/textures/_ae_.png deleted file mode 100644 index e19fdf1c8..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_lig.png b/mods/ITEMS/mcl_signs/textures/_ae_lig.png deleted file mode 100644 index a02bd30cf..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_lig.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ae_lig_.png b/mods/ITEMS/mcl_signs/textures/_ae_lig_.png deleted file mode 100644 index 0eb5d2f5c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ae_lig_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_am.png b/mods/ITEMS/mcl_signs/textures/_am.png deleted file mode 100644 index 76a886757..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_am.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ap.png b/mods/ITEMS/mcl_signs/textures/_ap.png deleted file mode 100644 index bced380ac..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ap.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_as.png b/mods/ITEMS/mcl_signs/textures/_as.png deleted file mode 100644 index 702a519b8..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_as.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_at.png b/mods/ITEMS/mcl_signs/textures/_at.png deleted file mode 100644 index 1c7fa502c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_at.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_b.png b/mods/ITEMS/mcl_signs/textures/_b.png deleted file mode 100644 index 427f488e5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_b.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_b_.png b/mods/ITEMS/mcl_signs/textures/_b_.png deleted file mode 100644 index c89961d1b..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_b_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_bl.png b/mods/ITEMS/mcl_signs/textures/_bl.png deleted file mode 100644 index 422fcc586..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_bl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_br.png b/mods/ITEMS/mcl_signs/textures/_br.png deleted file mode 100644 index 88b1ba4a3..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_br.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_broken_bar.png b/mods/ITEMS/mcl_signs/textures/_broken_bar.png deleted file mode 100644 index c733fd862..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_broken_bar.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_c.png b/mods/ITEMS/mcl_signs/textures/_c.png deleted file mode 100644 index 0ae311f3d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_c.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_.png b/mods/ITEMS/mcl_signs/textures/_c_.png deleted file mode 100644 index 135260913..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_c_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_cedille.png b/mods/ITEMS/mcl_signs/textures/_c_cedille.png deleted file mode 100644 index 9d5a4b564..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_c_cedille.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_c_cedille_.png b/mods/ITEMS/mcl_signs/textures/_c_cedille_.png deleted file mode 100644 index 7eb654bc4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_c_cedille_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ca.png b/mods/ITEMS/mcl_signs/textures/_ca.png deleted file mode 100644 index 79fa4345f..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ca.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_cedille.png b/mods/ITEMS/mcl_signs/textures/_cedille.png deleted file mode 100644 index 0de32ed0c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_cedille.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_cent.png b/mods/ITEMS/mcl_signs/textures/_cent.png deleted file mode 100644 index ecdb1f1d1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_cent.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_cl.png b/mods/ITEMS/mcl_signs/textures/_cl.png deleted file mode 100644 index 38cad796c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_cl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_cm.png b/mods/ITEMS/mcl_signs/textures/_cm.png deleted file mode 100644 index 6b2b10a17..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_cm.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_co.png b/mods/ITEMS/mcl_signs/textures/_co.png deleted file mode 100644 index 6775d5eaf..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_co.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_copyright.png b/mods/ITEMS/mcl_signs/textures/_copyright.png deleted file mode 100644 index 7cfdf217e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_copyright.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_cr.png b/mods/ITEMS/mcl_signs/textures/_cr.png deleted file mode 100644 index cd6d6dac6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_cr.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_currency.png b/mods/ITEMS/mcl_signs/textures/_currency.png deleted file mode 100644 index 1264c8945..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_currency.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_d.png b/mods/ITEMS/mcl_signs/textures/_d.png deleted file mode 100644 index d7988e2be..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_d.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_.png b/mods/ITEMS/mcl_signs/textures/_d_.png deleted file mode 100644 index 8803ea036..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_d_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_dash.png b/mods/ITEMS/mcl_signs/textures/_d_dash.png deleted file mode 100644 index 73f5a1246..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_d_dash.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_d_dash_.png b/mods/ITEMS/mcl_signs/textures/_d_dash_.png deleted file mode 100644 index e9c9e69c7..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_d_dash_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_degree.png b/mods/ITEMS/mcl_signs/textures/_degree.png deleted file mode 100644 index 64a7ee2b1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_degree.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_diaresis.png b/mods/ITEMS/mcl_signs/textures/_diaresis.png deleted file mode 100644 index f8b75d38d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_diaresis.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_div.png b/mods/ITEMS/mcl_signs/textures/_div.png deleted file mode 100644 index 808343753..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_div.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_dl.png b/mods/ITEMS/mcl_signs/textures/_dl.png deleted file mode 100644 index 044e4f00b..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_dl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_dt.png b/mods/ITEMS/mcl_signs/textures/_dt.png deleted file mode 100644 index 5dfa75349..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_dt.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_dv.png b/mods/ITEMS/mcl_signs/textures/_dv.png deleted file mode 100644 index 2989d93db..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_dv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e.png b/mods/ITEMS/mcl_signs/textures/_e.png deleted file mode 100644 index 316e966a1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_.png b/mods/ITEMS/mcl_signs/textures/_e_.png deleted file mode 100644 index 5ef88d282..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_acute.png b/mods/ITEMS/mcl_signs/textures/_e_acute.png deleted file mode 100644 index 911207f86..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_acute_.png b/mods/ITEMS/mcl_signs/textures/_e_acute_.png deleted file mode 100644 index b60193740..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_circumflex.png b/mods/ITEMS/mcl_signs/textures/_e_circumflex.png deleted file mode 100644 index 2b5ace3c4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_circumflex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png deleted file mode 100644 index c17d9dc29..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_circumflex_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_grave.png b/mods/ITEMS/mcl_signs/textures/_e_grave.png deleted file mode 100644 index c24ab4635..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_grave.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_e_grave_.png b/mods/ITEMS/mcl_signs/textures/_e_grave_.png deleted file mode 100644 index c71bb2ef6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_e_grave_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ee.png b/mods/ITEMS/mcl_signs/textures/_ee.png deleted file mode 100644 index 646c19e14..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ee.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ee_.png b/mods/ITEMS/mcl_signs/textures/_ee_.png deleted file mode 100644 index 5db7bc66a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ee_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_eq.png b/mods/ITEMS/mcl_signs/textures/_eq.png deleted file mode 100644 index 166f7a30d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_eq.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ex.png b/mods/ITEMS/mcl_signs/textures/_ex.png deleted file mode 100644 index 65a76aad1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ex_inv.png b/mods/ITEMS/mcl_signs/textures/_ex_inv.png deleted file mode 100644 index 1e7bbfe87..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ex_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_f.png b/mods/ITEMS/mcl_signs/textures/_f.png deleted file mode 100644 index 1e431df13..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_f.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_f_.png b/mods/ITEMS/mcl_signs/textures/_f_.png deleted file mode 100644 index d0dec2b35..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_f_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_g.png b/mods/ITEMS/mcl_signs/textures/_g.png deleted file mode 100644 index 0b39fc95e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_g.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_g_.png b/mods/ITEMS/mcl_signs/textures/_g_.png deleted file mode 100644 index bfe054638..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_g_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_gr.png b/mods/ITEMS/mcl_signs/textures/_gr.png deleted file mode 100644 index 3f806499a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_gr.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_gt.png b/mods/ITEMS/mcl_signs/textures/_gt.png deleted file mode 100644 index 0449b44de..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_gt.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_guill_left.png b/mods/ITEMS/mcl_signs/textures/_guill_left.png deleted file mode 100644 index 32b90c3e2..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_guill_left.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_guill_right.png b/mods/ITEMS/mcl_signs/textures/_guill_right.png deleted file mode 100644 index d372e6a85..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_guill_right.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_h.png b/mods/ITEMS/mcl_signs/textures/_h.png deleted file mode 100644 index bd6f1891c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_h.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_h_.png b/mods/ITEMS/mcl_signs/textures/_h_.png deleted file mode 100644 index 08cb5d8b0..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_h_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ha.png b/mods/ITEMS/mcl_signs/textures/_ha.png deleted file mode 100644 index 946ae4e5e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ha.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_hs.png b/mods/ITEMS/mcl_signs/textures/_hs.png deleted file mode 100644 index 682a92a2d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_hs.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i.png b/mods/ITEMS/mcl_signs/textures/_i.png deleted file mode 100644 index 9ba3e01a3..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_.png b/mods/ITEMS/mcl_signs/textures/_i_.png deleted file mode 100644 index ffe090aa8..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_acute.png b/mods/ITEMS/mcl_signs/textures/_i_acute.png deleted file mode 100644 index 20bdafb62..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_acute_.png b/mods/ITEMS/mcl_signs/textures/_i_acute_.png deleted file mode 100644 index 4cdc943d9..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_circumflex.png b/mods/ITEMS/mcl_signs/textures/_i_circumflex.png deleted file mode 100644 index f0e712725..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_circumflex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png deleted file mode 100644 index dc46f3ff5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_circumflex_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_grave.png b/mods/ITEMS/mcl_signs/textures/_i_grave.png deleted file mode 100644 index 7254cd7d2..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_grave.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_i_grave_.png b/mods/ITEMS/mcl_signs/textures/_i_grave_.png deleted file mode 100644 index 1e2212679..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_i_grave_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_j.png b/mods/ITEMS/mcl_signs/textures/_j.png deleted file mode 100644 index 7fec50215..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_j.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_j_.png b/mods/ITEMS/mcl_signs/textures/_j_.png deleted file mode 100644 index 440af26d5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_j_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_k.png b/mods/ITEMS/mcl_signs/textures/_k.png deleted file mode 100644 index af07f4bf3..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_k.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_k_.png b/mods/ITEMS/mcl_signs/textures/_k_.png deleted file mode 100644 index 5e0a6b995..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_k_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_l.png b/mods/ITEMS/mcl_signs/textures/_l.png deleted file mode 100644 index d28a863f3..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_l.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_l_.png b/mods/ITEMS/mcl_signs/textures/_l_.png deleted file mode 100644 index c40390194..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_l_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_lt.png b/mods/ITEMS/mcl_signs/textures/_lt.png deleted file mode 100644 index 54295121e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_lt.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_m.png b/mods/ITEMS/mcl_signs/textures/_m.png deleted file mode 100644 index e4110bbb0..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_m.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_m_.png b/mods/ITEMS/mcl_signs/textures/_m_.png deleted file mode 100644 index ac516a053..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_m_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_macron.png b/mods/ITEMS/mcl_signs/textures/_macron.png deleted file mode 100644 index ffb9dfd77..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_macron.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_mn.png b/mods/ITEMS/mcl_signs/textures/_mn.png deleted file mode 100644 index 2230e1065..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_mn.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_mu.png b/mods/ITEMS/mcl_signs/textures/_mu.png deleted file mode 100644 index 3d8c1b890..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_mu.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_n.png b/mods/ITEMS/mcl_signs/textures/_n.png deleted file mode 100644 index ca5ea2787..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_n.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_.png b/mods/ITEMS/mcl_signs/textures/_n_.png deleted file mode 100644 index b96f27c62..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_n_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_tilde.png b/mods/ITEMS/mcl_signs/textures/_n_tilde.png deleted file mode 100644 index 471669116..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_n_tilde.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_n_tilde_.png b/mods/ITEMS/mcl_signs/textures/_n_tilde_.png deleted file mode 100644 index 0dba0d471..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_n_tilde_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_not.png b/mods/ITEMS/mcl_signs/textures/_not.png deleted file mode 100644 index a98f885e9..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_not.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o.png b/mods/ITEMS/mcl_signs/textures/_o.png deleted file mode 100644 index 2a579385d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_.png b/mods/ITEMS/mcl_signs/textures/_o_.png deleted file mode 100644 index 44ac3cbca..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_acute.png b/mods/ITEMS/mcl_signs/textures/_o_acute.png deleted file mode 100644 index cda99b3a6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_acute_.png b/mods/ITEMS/mcl_signs/textures/_o_acute_.png deleted file mode 100644 index e25a3a7f4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_circumflex.png b/mods/ITEMS/mcl_signs/textures/_o_circumflex.png deleted file mode 100644 index 2f7a188df..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_circumflex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png deleted file mode 100644 index 5e4c6be6a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_circumflex_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_dash.png b/mods/ITEMS/mcl_signs/textures/_o_dash.png deleted file mode 100644 index 9e5de53d1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_dash.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_dash_.png b/mods/ITEMS/mcl_signs/textures/_o_dash_.png deleted file mode 100644 index badbe9b88..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_dash_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_grave.png b/mods/ITEMS/mcl_signs/textures/_o_grave.png deleted file mode 100644 index b6b31a9a6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_grave.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_grave_.png b/mods/ITEMS/mcl_signs/textures/_o_grave_.png deleted file mode 100644 index d34e9d71c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_grave_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_sup.png b/mods/ITEMS/mcl_signs/textures/_o_sup.png deleted file mode 100644 index eeff0a295..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_sup.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_tilde.png b/mods/ITEMS/mcl_signs/textures/_o_tilde.png deleted file mode 100644 index 6cbd7cec0..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_tilde.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_o_tilde_.png b/mods/ITEMS/mcl_signs/textures/_o_tilde_.png deleted file mode 100644 index bb0616918..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_o_tilde_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_oe.png b/mods/ITEMS/mcl_signs/textures/_oe.png deleted file mode 100644 index 9b6892155..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_oe.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_oe_.png b/mods/ITEMS/mcl_signs/textures/_oe_.png deleted file mode 100644 index 73b4da80e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_oe_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_p.png b/mods/ITEMS/mcl_signs/textures/_p.png deleted file mode 100644 index 08f8534d0..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_p.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_p_.png b/mods/ITEMS/mcl_signs/textures/_p_.png deleted file mode 100644 index 2ff300509..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_p_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_paragraph.png b/mods/ITEMS/mcl_signs/textures/_paragraph.png deleted file mode 100644 index 52c162120..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_paragraph.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_pilcrow.png b/mods/ITEMS/mcl_signs/textures/_pilcrow.png deleted file mode 100644 index 9764ff8b5..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_pilcrow.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_plus_minus.png b/mods/ITEMS/mcl_signs/textures/_plus_minus.png deleted file mode 100644 index e7c3f1200..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_plus_minus.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_pound.png b/mods/ITEMS/mcl_signs/textures/_pound.png deleted file mode 100644 index 31d38d392..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_pound.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_pr.png b/mods/ITEMS/mcl_signs/textures/_pr.png deleted file mode 100644 index c8783948d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_pr.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ps.png b/mods/ITEMS/mcl_signs/textures/_ps.png deleted file mode 100644 index 74b1f5b8e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ps.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_q.png b/mods/ITEMS/mcl_signs/textures/_q.png deleted file mode 100644 index b5fbcc27d..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_q.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_q_.png b/mods/ITEMS/mcl_signs/textures/_q_.png deleted file mode 100644 index 674799413..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_q_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_qo.png b/mods/ITEMS/mcl_signs/textures/_qo.png deleted file mode 100644 index c7b87be68..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_qo.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_qu.png b/mods/ITEMS/mcl_signs/textures/_qu.png deleted file mode 100644 index 1458c7e10..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_qu.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_qu_inv.png b/mods/ITEMS/mcl_signs/textures/_qu_inv.png deleted file mode 100644 index 757bd06db..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_qu_inv.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_r.png b/mods/ITEMS/mcl_signs/textures/_r.png deleted file mode 100644 index 709c53889..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_r.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_r_.png b/mods/ITEMS/mcl_signs/textures/_r_.png deleted file mode 100644 index f8b472755..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_r_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_rc.png b/mods/ITEMS/mcl_signs/textures/_rc.png deleted file mode 100644 index 8b66915e6..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_rc.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_re.png b/mods/ITEMS/mcl_signs/textures/_re.png deleted file mode 100644 index 8fdaf4d24..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_re.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_registered.png b/mods/ITEMS/mcl_signs/textures/_registered.png deleted file mode 100644 index 9a78dda3c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_registered.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_s.png b/mods/ITEMS/mcl_signs/textures/_s.png deleted file mode 100644 index 4c47aee01..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_s.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_s_.png b/mods/ITEMS/mcl_signs/textures/_s_.png deleted file mode 100644 index 08cf6ff68..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_s_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_sl.png b/mods/ITEMS/mcl_signs/textures/_sl.png deleted file mode 100644 index 413aa5778..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_sl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_sm.png b/mods/ITEMS/mcl_signs/textures/_sm.png deleted file mode 100644 index 460c5d6dd..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_sm.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_sp.png b/mods/ITEMS/mcl_signs/textures/_sp.png deleted file mode 100644 index 4aae0ea85..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_sp.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_sr.png b/mods/ITEMS/mcl_signs/textures/_sr.png deleted file mode 100644 index afefa91b2..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_sr.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_sz.png b/mods/ITEMS/mcl_signs/textures/_sz.png deleted file mode 100644 index 56d2847a1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_sz.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_t.png b/mods/ITEMS/mcl_signs/textures/_t.png deleted file mode 100644 index e750dd98e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_t.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_t_.png b/mods/ITEMS/mcl_signs/textures/_t_.png deleted file mode 100644 index d7aabd04a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_t_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_thorn.png b/mods/ITEMS/mcl_signs/textures/_thorn.png deleted file mode 100644 index e44f23d85..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_thorn.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_thorn_.png b/mods/ITEMS/mcl_signs/textures/_thorn_.png deleted file mode 100644 index 1b6d2558b..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_thorn_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_times_cross.png b/mods/ITEMS/mcl_signs/textures/_times_cross.png deleted file mode 100644 index 25af91b68..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_times_cross.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_times_dot.png b/mods/ITEMS/mcl_signs/textures/_times_dot.png deleted file mode 100644 index 42dac52bc..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_times_dot.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_tl.png b/mods/ITEMS/mcl_signs/textures/_tl.png deleted file mode 100644 index 5f1b4fb43..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_tl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u.png b/mods/ITEMS/mcl_signs/textures/_u.png deleted file mode 100644 index 2665e5685..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_.png b/mods/ITEMS/mcl_signs/textures/_u_.png deleted file mode 100644 index d04ff5481..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_acute.png b/mods/ITEMS/mcl_signs/textures/_u_acute.png deleted file mode 100644 index 580f61042..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_acute_.png b/mods/ITEMS/mcl_signs/textures/_u_acute_.png deleted file mode 100644 index 9237d3caf..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_circumflex.png b/mods/ITEMS/mcl_signs/textures/_u_circumflex.png deleted file mode 100644 index 2b238be12..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_circumflex.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png b/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png deleted file mode 100644 index 1608ecf17..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_circumflex_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_grave.png b/mods/ITEMS/mcl_signs/textures/_u_grave.png deleted file mode 100644 index 051280428..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_grave.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_u_grave_.png b/mods/ITEMS/mcl_signs/textures/_u_grave_.png deleted file mode 100644 index 668685793..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_u_grave_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ue.png b/mods/ITEMS/mcl_signs/textures/_ue.png deleted file mode 100644 index 6249aaebb..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_ue_.png b/mods/ITEMS/mcl_signs/textures/_ue_.png deleted file mode 100644 index 3193a9412..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_ue_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_un.png b/mods/ITEMS/mcl_signs/textures/_un.png deleted file mode 100644 index d65f12d4e..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_un.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_v.png b/mods/ITEMS/mcl_signs/textures/_v.png deleted file mode 100644 index 888b2f1cf..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_v.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_v_.png b/mods/ITEMS/mcl_signs/textures/_v_.png deleted file mode 100644 index f2ecbf143..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_v_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_vb.png b/mods/ITEMS/mcl_signs/textures/_vb.png deleted file mode 100644 index ca2e5667a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_vb.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_w.png b/mods/ITEMS/mcl_signs/textures/_w.png deleted file mode 100644 index 6c2eea3e1..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_w.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_w_.png b/mods/ITEMS/mcl_signs/textures/_w_.png deleted file mode 100644 index f1e26c108..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_w_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_x.png b/mods/ITEMS/mcl_signs/textures/_x.png deleted file mode 100644 index 3eb2d52d7..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_x.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_x_.png b/mods/ITEMS/mcl_signs/textures/_x_.png deleted file mode 100644 index bcb351d56..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_x_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_y.png b/mods/ITEMS/mcl_signs/textures/_y.png deleted file mode 100644 index 7cd1d87b7..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_y.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_.png b/mods/ITEMS/mcl_signs/textures/_y_.png deleted file mode 100644 index b5f49850c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_y_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_acute.png b/mods/ITEMS/mcl_signs/textures/_y_acute.png deleted file mode 100644 index 37cb54b30..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_y_acute.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_acute_.png b/mods/ITEMS/mcl_signs/textures/_y_acute_.png deleted file mode 100644 index bcc15c41c..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_y_acute_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_y_diaresis.png b/mods/ITEMS/mcl_signs/textures/_y_diaresis.png deleted file mode 100644 index 135a8ce25..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_y_diaresis.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_yen.png b/mods/ITEMS/mcl_signs/textures/_yen.png deleted file mode 100644 index ec4ad65ee..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_yen.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_z.png b/mods/ITEMS/mcl_signs/textures/_z.png deleted file mode 100644 index 8a710780a..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_z.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/_z_.png b/mods/ITEMS/mcl_signs/textures/_z_.png deleted file mode 100644 index 6192800b4..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/_z_.png and /dev/null differ diff --git a/mods/ITEMS/mcl_signs/textures/default_sign.png b/mods/ITEMS/mcl_signs/textures/default_sign.png deleted file mode 100644 index 077983118..000000000 Binary files a/mods/ITEMS/mcl_signs/textures/default_sign.png and /dev/null differ diff --git a/mods/ITEMS/mcl_smithing_table/init.lua b/mods/ITEMS/mcl_smithing_table/init.lua new file mode 100644 index 000000000..dbb6c620f --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/init.lua @@ -0,0 +1,145 @@ +--[[ +By EliasFleckenstein03 and Code-Sploit +]] + +local S = minetest.get_translator("mcl_smithing_table") +mcl_smithing_table = {} + +-- Function to upgrade diamond tool/armor to netherite tool/armor +function mcl_smithing_table.upgrade_item(itemstack) + local def = itemstack:get_definition() + + if not def or not def._mcl_upgradable then + return + end + local itemname = itemstack:get_name() + local upgrade_item = itemname:gsub("diamond", "netherite") + + if def._mcl_upgrade_item and upgrade_item == itemname then + return + end + + itemstack:set_name(upgrade_item) + + -- Reload the ToolTips of the tool + + tt.reload_itemstack_description(itemstack) + + -- Only return itemstack if upgrade was successfull + return itemstack +end + +-- Badly copied over from mcl_anvils +-- ToDo: Make better formspec + +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]" + +local function reset_upgraded_item(pos) + local inv = minetest.get_meta(pos):get_inventory() + local upgraded_item + + 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)) + end + + inv:set_stack("upgraded_item", 1, upgraded_item) +end + +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}, + + tiles = { + "mcl_smithing_table_top.png", + "mcl_smithing_table_bottom.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_side.png", + "mcl_smithing_table_front.png", + }, + + sounds = mcl_sounds.node_sound_metal_defaults(), + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", formspec) + + local inv = meta:get_inventory() + + inv:set_size("diamond_item", 1) + inv:set_size("netherite", 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 + return stack:get_count() + end + + return 0 + end, + + allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + return 0 + end, + + on_metadata_inventory_put = reset_upgraded_item, + + 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 + if stack:get_name() == "mcl_farming:hoe_netherite" then + awards.unlock(player:get_player_name(), "mcl:seriousDedication") + end + end + + reset_upgraded_item(pos) + end, + + _mcl_blast_resistance = 2.5, + _mcl_hardness = 2.5 +}) + + +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", ""} + } +}) diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr new file mode 100644 index 000000000..b3f9349a7 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_smithing_table +Inventory=Inventaire +Upgrade Gear=Améliorer l'équipement +Smithing table=Table de forgeron diff --git a/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr new file mode 100644 index 000000000..792b0afe0 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/mcl_smithing_table.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_smithing_table +Smithing table=鍛冶台 diff --git a/mods/ITEMS/mcl_smithing_table/locale/template.txt b/mods/ITEMS/mcl_smithing_table/locale/template.txt new file mode 100644 index 000000000..6133a22db --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/locale/template.txt @@ -0,0 +1,4 @@ +# textdomain: mcl_smithing_table +Inventory= +Upgrade Gear= +Smithing table= diff --git a/mods/ITEMS/mcl_smithing_table/mod.conf b/mods/ITEMS/mcl_smithing_table/mod.conf new file mode 100644 index 000000000..aee93fa65 --- /dev/null +++ b/mods/ITEMS/mcl_smithing_table/mod.conf @@ -0,0 +1,2 @@ +name = mcl_smithing_table +depends = mcl_colors, mcl_formspec diff --git a/mods/ITEMS/mcl_smoker/README.md b/mods/ITEMS/mcl_smoker/README.md new file mode 100644 index 000000000..895a8dd81 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/README.md @@ -0,0 +1,13 @@ +Smoker for MineClone 2. +Heavily based on Minetest Game (default/furnace.lua) and the MineClone 2 Furnaces. + +License of source code +---------------------- +LGPLv2.1 +Based on code from Minetest Game. +Modified by Wuzzy. +MCl 2 Furances modified by PrairieWind. + +License of media +---------------- +See the main MineClone 2 README.md file. diff --git a/mods/ITEMS/mcl_smoker/init.lua b/mods/ITEMS/mcl_smoker/init.lua new file mode 100644 index 000000000..4a4cfca15 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/init.lua @@ -0,0 +1,572 @@ + +local S = minetest.get_translator(minetest.get_current_modname()) + +local LIGHT_ACTIVE_FURNACE = 13 + +-- +-- 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("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]" +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]".. + -- 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]" + +local receive_fields = function(pos, formname, fields, sender) + if fields.craftguide then + mcl_craftguide.show(sender:get_player_name()) + end +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 xp = meta:get_int("xp") + if xp > 0 then + if player then + mcl_experience.add_xp(player, xp) + else + mcl_experience.throw_xp(vector.add(pos, dir), xp) + end + meta:set_int("xp", 0) + end +end + +-- +-- Node callback functions that are the same for active and inactive furnace +-- + +local function allow_metadata_inventory_put(pos, listname, index, stack, player) + if mcl_util.check_position_protection(pos, player) then + return 0 + end + + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + if listname == "fuel" then + -- 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}}) + if output.time ~= 0 then + -- Only allow to place 1 item if fuel get replaced by recipe. + -- This is the case for lava buckets. + local replace_item = decremented_input.items[1] + if replace_item:is_empty() then + -- For most fuels, just allow to place everything + return stack:get_count() + else + if inv:get_stack(listname, index):get_count() == 0 then + return 1 + else + return 0 + end + end + else + return 0 + end + elseif listname == "src" then + return stack:get_count() + elseif listname == "dst" then + return 0 + end +end + +local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local stack = inv:get_stack(from_list, from_index) + return allow_metadata_inventory_put(pos, to_list, to_index, stack, player) +end + +local function allow_metadata_inventory_take(pos, listname, index, stack, player) + local name = player:get_player_name() + if minetest.is_protected(pos, name) then + minetest.record_protection_violation(pos, name) + return 0 + end + return stack:get_count() +end + +local function on_metadata_inventory_take(pos, listname, index, stack, player) + -- Award smelting achievements + if listname == "dst" then + if stack:get_name() == "mcl_fishing:fish_cooked" then + awards.unlock(player:get_player_name(), "mcl:cookFish") + end + give_xp(pos, player) + end +end + +local function on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + if from_list == "dst" then + give_xp(pos, player) + end +end + +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 } + 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 } + 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 } + 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 } + else + return + end + mcl_particles.add_node_particlespawner(pos, { + amount = 4, + 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 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.4, + maxsize = 0.8, + texture = "mcl_particles_flame.png", + glow = LIGHT_ACTIVE_FURNACE, + }, "low") +end + +local function swap_node(pos, name) + local node = minetest.get_node(pos) + if node.name == name then + return + end + node.name = name + minetest.swap_node(pos, node) + if name == "mcl_smoker:smoker_active" then + spawn_flames(pos, node.param2) + else + mcl_particles.delete_node_particlespawners(pos) + end +end + +local function smoker_reset_delta_time(pos) + local meta = minetest.get_meta(pos) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) + if (time_speed < 0.1) then + return + end + local time_multiplier = 86400 / time_speed + local current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier) + + -- TODO: Change meta:get/set_string() to get/set_float() for "last_gametime". + -- In Windows *_float() works OK but under Linux it returns rounded unusable values like 449540.000000000 + local last_game_time = meta:get_string("last_gametime") + if last_game_time then + last_game_time = tonumber(last_game_time) + end + if not last_game_time or last_game_time < 1 or math.abs(last_game_time - current_game_time) <= 1.5 then + return + end + + meta:set_string("last_gametime", tostring(current_game_time)) +end + +local function smoker_get_delta_time(pos, elapsed) + local meta = minetest.get_meta(pos) + local time_speed = tonumber(minetest.settings:get("time_speed") or 72) + local current_game_time + if (time_speed < 0.1) then + return meta, elapsed + else + local time_multiplier = 86400 / time_speed + current_game_time = .0 + ((minetest.get_day_count() + minetest.get_timeofday()) * time_multiplier) + end + + local last_game_time = meta:get_string("last_gametime") + if last_game_time then + last_game_time = tonumber(last_game_time) + end + if not last_game_time or last_game_time < 1 then + last_game_time = current_game_time - 0.1 + elseif last_game_time == current_game_time then + current_game_time = current_game_time + 1.0 + end + + local elapsed_game_time = .0 + current_game_time - last_game_time + + meta:set_string("last_gametime", tostring(current_game_time)) + + return meta, elapsed_game_time +end + +local function smoker_node_timer(pos, elapsed) + -- + -- Inizialize metadata + -- + local meta, elapsed_game_time = smoker_get_delta_time(pos, elapsed) + + local fuel_time = meta:get_float("fuel_time") or 0 + local src_time = meta:get_float("src_time") or 0 + local src_item = meta:get_string("src_item") or "" + local fuel_totaltime = meta:get_float("fuel_totaltime") or 0 + + local inv = meta:get_inventory() + local srclist, fuellist + + local cookable, cooked + local active = true + local fuel + + srclist = inv:get_list("src") + fuellist = inv:get_list("fuel") + + -- Check if src item has been changed + if srclist[1]:get_name() ~= src_item then + -- Reset cooking progress in this case + src_time = 0 + src_item = srclist[1]:get_name() + end + + local update = true + while elapsed_game_time > 0.00001 and update do + -- + -- Cooking + -- + + -- Run the smoker at twice the speed of a furnace. + local el = elapsed_game_time * 2 + + -- Check if we have cookable content: cookable + local aftercooked + 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 + if not inv:room_for_item("dst", cooked.item) then + cookable = false + end + end + + if cookable then -- fuel lasts long enough, adjust el to cooking duration + el = math.min(el, cooked.time - src_time) + end + + -- Check if we have enough fuel to burn + active = fuel_time < fuel_totaltime + 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}) + + if fuel.time == 0 then + -- No valid fuel in fuel list -- stop + fuel_totaltime = 0 + src_time = 0 + update = false + else + -- Take fuel from fuel list + inv:set_stack("fuel", 1, afterfuel.items[1]) + fuel_time = 0 + fuel_totaltime = fuel.time + el = math.min(el, fuel_totaltime) + active = true + fuellist = inv:get_list("fuel") + end + elseif active then + el = math.min(el, fuel_totaltime - fuel_time) + -- The furnace is currently active and has enough fuel + fuel_time = fuel_time + el + end + + -- If there is a cookable item then check if it is ready yet + if cookable and active then + src_time = src_time + el + -- Place result in dst list if done + if src_time >= cooked.time then + inv:add_item("dst", cooked.item) + inv:set_stack("src", 1, aftercooked.items[1]) + + 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 + end + end + + elapsed_game_time = elapsed_game_time - el + end + + if fuel and fuel_totaltime > fuel.time then + fuel_totaltime = fuel.time + end + if srclist and srclist[1]:is_empty() then + src_time = 0 + end + + -- + -- Update formspec and node + -- + local formspec = inactive_formspec + local item_percent = 0 + if cookable then + item_percent = math.floor(src_time / cooked.time * 100) + end + + local result = false + + if active then + local fuel_percent = 0 + if fuel_totaltime > 0 then + fuel_percent = math.floor(fuel_time / fuel_totaltime * 100) + end + formspec = active_formspec(fuel_percent, item_percent) + swap_node(pos, "mcl_smoker:smoker_active") + -- make sure timer restarts automatically + result = true + else + swap_node(pos, "mcl_smoker:smoker") + -- stop timer on the inactive furnace + minetest.get_node_timer(pos):stop() + end + + -- + -- Set meta values + -- + meta:set_float("fuel_totaltime", fuel_totaltime) + meta:set_float("fuel_time", fuel_time) + meta:set_float("src_time", src_time) + if srclist then + meta:set_string("src_item", src_item) + else + meta:set_string("src_item", "") + end + meta:set_string("formspec", formspec) + + return result +end + +local on_rotate, after_rotate_active +if minetest.get_modpath("screwdriver") then + on_rotate = screwdriver.rotate_simple + after_rotate_active = function(pos) + local node = minetest.get_node(pos) + mcl_particles.delete_node_particlespawners(pos) + if node.name == "mcl_smoker:smoker" then + return + end + spawn_flames(pos, node.param2) + end +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_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."), + _doc_items_hidden = false, + tiles = { + "smoker_top.png", "smoker_bottom.png", + "smoker_side.png", "smoker_side.png", + "smoker_side.png", "smoker_front.png" + }, + paramtype2 = "facedir", + groups = {pickaxey=1, container=4, deco_block=1, material_stone=1}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + + on_timer = smoker_node_timer, + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta:to_table() + meta:from_table(oldmetadata) + local inv = meta:get_inventory() + 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) + end + end + meta:from_table(meta2) + end, + + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", inactive_formspec) + local inv = meta:get_inventory() + inv:set_size("src", 1) + inv:set_size("fuel", 1) + inv:set_size("dst", 1) + end, + on_destruct = function(pos) + mcl_particles.delete_node_particlespawners(pos) + give_xp(pos) + end, + + on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) + -- Reset accumulated game time when player works with furnace: + smoker_reset_delta_time(pos) + minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) + end, + on_metadata_inventory_put = function(pos) + -- Reset accumulated game time when player works with furnace: + smoker_reset_delta_time(pos) + -- start timer function, it will sort out whether furnace can burn or not. + minetest.get_node_timer(pos):start(1.0) + end, + on_metadata_inventory_take = function(pos, listname, index, stack, player) + -- Reset accumulated game time when player works with furnace: + smoker_reset_delta_time(pos) + -- start timer function, it will helpful if player clears dst slot + minetest.get_node_timer(pos):start(1.0) + + on_metadata_inventory_take(pos, listname, index, stack, player) + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + on_receive_fields = receive_fields, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + on_rotate = on_rotate, +}) + +minetest.register_node("mcl_smoker:smoker_active", { + description = S("Burning Smoker"), + _doc_items_create_entry = false, + 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}}, + }, + 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}, + is_ground_content = false, + sounds = mcl_sounds.node_sound_stone_defaults(), + on_timer = smoker_node_timer, + + after_dig_node = function(pos, oldnode, oldmetadata, digger) + local meta = minetest.get_meta(pos) + local meta2 = meta + meta:from_table(oldmetadata) + local inv = meta:get_inventory() + 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) + end + end + meta:from_table(meta2:to_table()) + end, + + on_construct = function(pos) + local node = minetest.get_node(pos) + spawn_flames(pos, node.param2) + end, + on_destruct = function(pos) + mcl_particles.delete_node_particlespawners(pos) + give_xp(pos) + end, + + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_take = allow_metadata_inventory_take, + on_metadata_inventory_move = on_metadata_inventory_move, + on_metadata_inventory_take = on_metadata_inventory_take, + on_receive_fields = receive_fields, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + on_rotate = on_rotate, + after_rotate = after_rotate_active, +}) + +minetest.register_craft({ + output = "mcl_smoker:smoker", + recipe = { + { "", "group:tree", "" }, + { "group:tree", "mcl_furnaces:furnace", "group:tree" }, + { "", "group:tree", "" }, + } +}) + +-- Add entry alias for the Help +if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", "mcl_smoker:smoker", "nodes", "mcl_smoker:smoker_active") +end + +minetest.register_lbm({ + label = "Active smoker flame particles", + name = "mcl_smoker:flames", + nodenames = {"mcl_smoker:smoker_active"}, + run_at_every_load = true, + action = function(pos, node) + spawn_flames(pos, node.param2) + end, +}) diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.es.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.es.tr new file mode 100644 index 000000000..5d91ec0fd --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.es.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_smoker +Inventory=Inventario +Smoker=Ahumador +Cooks food faster than furnace=Cocina la comida más rápido que el horno +Use the smoker to open the furnace menu.=Usa el ahumador para abrir el menú del horno. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Coloque un combustible de horno en la ranura inferior y el material de origen en la ranura superior. +The smoker will slowly use its fuel to smelt the item.=El ahumador usará lentamente su combustible para cocinar la comida. +The result will be placed into the output slot at the right side.=El resultado se colocará en la ranura de salida en el lado derecho. +Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn.=Use el libro de recetas para para ver qué comidas puede cocinar, qué puede usar como combustible y durante cuánto tiempo se quemará. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Los ahumadores cocinan varios artículos, principalmente alimentos crudos en cocidos, pero el doble de rápido que un horno normal. +Burning Smoker=Ahumador ardiente diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr new file mode 100644 index 000000000..cfbbff113 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.fr.tr @@ -0,0 +1,11 @@ +# textdomain: mcl_smoker +Inventory=Inventaire +Smoker=Fumoir +Cooks food faster than furnace=Cuit la nourriture plus vite qu'un fourneau +Use the smoker to open the furnace menu.=Utiliser le fumoir pour ouvrir le menu. +Place a furnace fuel in the lower slot and the source material in the upper slot.=Placer le combustible dans la case en bas et le matériau source dans la case du haut. +The smoker will slowly use its fuel to smelt the item.=Le fumoir utilisera son combustible pour fondre lentement l'objet. +The result will be placed into the output slot at the right side.=Le résultat sera placé dans la case de sortie à droite. +Use the recipe book to see what foods you can smelt, what you can use as fuel and how long it will burn.=Utiliser le livre de recettes pour voir quels aliments vous pouvez cuire, ce que vous pouvez utiliser comme combustible et combien de temps ça va brûler. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Les fumoirs cuisent plusieurs objets, surtout de la nourriture crue, en de la nourriture cuite, mais deux fois plus vite qu'un fourneau normal. +Burning Smoker=Fumoir actif diff --git a/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr new file mode 100644 index 000000000..9c058c713 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/mcl_smoker.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_smoker +Inventory=インベントリ +Smoker=燻製器 +Cooks food faster than furnace=食料はかまどより早く調理可能 +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=レシピ本を使って、何を製錬できるか、何を燃料にできるか、どれくらい燃えるかを確認しましょう。 +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=かまどを使用してかまどのメニューを開きます。かまどの燃料を下スロットに、素材を上スロットに入れます。かまどはゆっくりと燃料を使い、アイテムを製錬します。製錬結果は右側の出力スロットに置かれます。 +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=燻製器は、生ものを中心とした数種類を調理品に仕上げますが、普通のかまどの2倍早く調理します。 +Burning Smoker=燻製器 燃焼中 diff --git a/mods/ITEMS/mcl_smoker/locale/template.txt b/mods/ITEMS/mcl_smoker/locale/template.txt new file mode 100644 index 000000000..b8e27608a --- /dev/null +++ b/mods/ITEMS/mcl_smoker/locale/template.txt @@ -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_smoker/mcl_smoker.ru.tr b/mods/ITEMS/mcl_smoker/mcl_smoker.ru.tr new file mode 100644 index 000000000..3a58b11d7 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/mcl_smoker.ru.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_smoker +Inventory=Инвентарь +Smoker=Коптильня +Cooks food faster than furnace=Приготовление еды быстрее, чем в печи +Use the recipe book to see what you can smelt, what you can use as fuel and how long it will burn.=Используйте книгу рецептов, чтобы узнать, что вы можете выпекать, что можно использовать в качестве топлива и как долго оно будет гореть. +Use the furnace to open the furnace menu.\nPlace a furnace fuel in the lower slot and the source material in the upper slot.\nThe furnace will slowly use its fuel to smelt the item.\nThe result will be placed into the output slot at the right side.=Используйте печь, чтобы открыть окно взаимодействия с печью.\nПоместите топливо в нижнюю ячейку, а исходное сырьё в верхнюю ячейку.\nПечь будет медленно использовать топливо для выплавки изделия.\nВыходник будет помещён в выходную ячейку с правой стороны. +Smokers cook several items, mainly raw foods, into cooked foods, but twice as fast as a normal furnace.=Коптильни готовят несколько предметов, в основном сырых, в виде готовых блюд, но в два раза быстрее, чем в обычной печи. +Burning Smoker=Зажжённая печь \ No newline at end of file diff --git a/mods/ITEMS/mcl_smoker/mod.conf b/mods/ITEMS/mcl_smoker/mod.conf new file mode 100644 index 000000000..c2c49db62 --- /dev/null +++ b/mods/ITEMS/mcl_smoker/mod.conf @@ -0,0 +1,3 @@ +name = mcl_smoker +depends = mcl_init, mcl_formspec, mcl_core, mcl_furnaces, mcl_sounds, mcl_craftguide, mcl_achievements, mcl_particles, mcl_util +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_sponges/depends.txt b/mods/ITEMS/mcl_sponges/depends.txt deleted file mode 100644 index 10e9d2909..000000000 --- a/mods/ITEMS/mcl_sponges/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core? -mclx_core? diff --git a/mods/ITEMS/mcl_sponges/description.txt b/mods/ITEMS/mcl_sponges/description.txt deleted file mode 100644 index 80f47c25f..000000000 --- a/mods/ITEMS/mcl_sponges/description.txt +++ /dev/null @@ -1 +0,0 @@ -A sponge which sucks in water (WIP). diff --git a/mods/ITEMS/mcl_sponges/init.lua b/mods/ITEMS/mcl_sponges/init.lua index 4a2107f88..e9755479b 100644 --- a/mods/ITEMS/mcl_sponges/init.lua +++ b/mods/ITEMS/mcl_sponges/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_sponges") +local S = minetest.get_translator(minetest.get_current_modname()) local absorb = function(pos) local change = false @@ -48,7 +48,7 @@ minetest.register_node("mcl_sponges:sponge", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, on_place = function(itemstack, placer, pointed_thing) local pn = placer:get_player_name() if pointed_thing.type ~= "node" then @@ -73,7 +73,7 @@ minetest.register_node("mcl_sponges:sponge", { on_water = true end local water_found = minetest.find_node_near(pos, 1, "group:water") - if water_found ~= nil then + if water_found then on_water = true end if on_water then @@ -94,6 +94,54 @@ minetest.register_node("mcl_sponges:sponge", { _mcl_hardness = 0.6, }) +function place_wet_sponge(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + return itemstack + 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 + + local name = placer:get_player_name() + + if minetest.is_protected(pointed_thing.above, name) then + return itemstack + end + + if mcl_worlds.pos_to_dimension(pointed_thing.above) == "nether" then + minetest.item_place_node(ItemStack("mcl_sponges:sponge"), placer, pointed_thing) + local pos = pointed_thing.above + + for n = 1, 5 do + minetest.add_particlespawner({ + amount = 5, + time = 0.1, + minpos = vector.offset(pos, -0.5, 0.6, -0.5), + maxpos = vector.offset(pos, 0.5, 0.6, 0.5), + minvel = vector.new(0, 0.1, 0), + maxvel = vector.new(0, 1, 0), + minexptime = 0.1, + maxexptime = 1, + minsize = 2, + maxsize = 5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_sponge" .. n .. ".png", + }) + end + if not minetest.is_creative_enabled(name) then + itemstack:take_item() + end + return itemstack + end + + return minetest.item_place_node(itemstack, placer, pointed_thing) +end + minetest.register_node("mcl_sponges:sponge_wet", { description = S("Waterlogged Sponge"), _tt_help = S("Can be dried in furnace"), @@ -107,7 +155,8 @@ minetest.register_node("mcl_sponges:sponge_wet", { buildable_to = false, stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), - groups = {handy=1, building_block=1}, + groups = {handy=1, hoey=1, building_block=1}, + on_place = place_wet_sponge, _mcl_blast_resistance = 0.6, _mcl_hardness = 0.6, }) @@ -127,6 +176,7 @@ if minetest.get_modpath("mclx_core") then stack_max = 64, sounds = mcl_sounds.node_sound_dirt_defaults(), groups = {handy=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.es.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.es.tr index 4ee44838a..2c775bec0 100644 --- a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.es.tr +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.es.tr @@ -6,3 +6,5 @@ A waterlogged sponge can be dried in the furnace to turn it into (dry) sponge. W Riverwaterlogged Sponge=Esponja mojada con agua de 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 es una esponja mojada con agua de río. Se puede secar en el horno para convertirlo en una esponja (seca). Cuando hay un balde vacío en la ranura de combustible del horno, el agua del río se vierte en el balde. A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=Una esponja se inunda de río (en lugar de inundarse) si absorbe más agua de río que el agua (normal). +Removes water on contact=Remueve agua al contacto +Can be dried in furnace=Puede secarse en un horno diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr new file mode 100644 index 000000000..e2fa7d1dd --- /dev/null +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.ja.tr @@ -0,0 +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.=水を吸ったスポンジをかまどの中で乾燥させると、(乾いた)スポンジになります。かまどの燃料スロットに空のバケツがあると、バケツに水が流れ込みます。 +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=接触している水を除去 +Can be dried in furnace=かまどで乾燥可能 diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pl.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pl.tr new file mode 100644 index 000000000..6cb6bf474 --- /dev/null +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.pl.tr @@ -0,0 +1,10 @@ +# textdomain: mcl_sponges +Sponge=Gąbka +Sponges are blocks which remove water around them when they are placed or come in contact with water, turning it into a wet sponge.=Gąbki to bloki które usuwają wodę wokół siebie gdy są postawione, lub gdy wejdą w kontakt z wodą, zamieniając się w mokre gąbki. +Waterlogged Sponge=Nasiąknięta gąbka +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.=Nasiąknięta gąbka może zostać wysuszona w piecu by zamienić się w (suchą) gąbkę. Jeśli w miejscu na paliwo jest puste wiadro, to woda wyleje się do wiaderka. +Riverwaterlogged Sponge=Gąbka nasiąknięta wodą rzeczną +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.=To jest gąbka, która wchłonęła wodę rzeczną. Może zostać wysuszona w piecu by zamienić się w (suchą) gąbkę. Jeśli w miejscu na paliwo jest puste wiadro, to woda rzeczna wyleje się do wiaderka. +A sponge becomes riverwaterlogged (instead of waterlogged) if it sucks up more river water than (normal) water.=Gąbka zostanie nasiąknięta wodą rzeczną jeśli nasiąknie większą ilością wody z rzeki niż normalnej wody. +Removes water on contact=Usuwa dotkniętą wodę +Can be dried in furnace=Może zostać wysuszona w piecu diff --git a/mods/ITEMS/mcl_sponges/locale/mcl_sponges.zh_TW.tr b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.zh_TW.tr new file mode 100644 index 000000000..3b466dff4 --- /dev/null +++ b/mods/ITEMS/mcl_sponges/locale/mcl_sponges.zh_TW.tr @@ -0,0 +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.=濕海綿可以在熔爐裡烘乾,變成(乾)海綿。當爐子的燃料槽裡有一個空桶時,水會倒進桶裡。 +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=如果海綿吸的河水比(正常的)水多,它就會變成濕河水海綿(而不是濕海綿)。 +Can be dried in furnace=可以在熔爐裏烘乾 diff --git a/mods/ITEMS/mcl_sponges/mod.conf b/mods/ITEMS/mcl_sponges/mod.conf index 71a459c10..d833493b3 100644 --- a/mods/ITEMS/mcl_sponges/mod.conf +++ b/mods/ITEMS/mcl_sponges/mod.conf @@ -1 +1,4 @@ name = mcl_sponges +description = A sponge which sucks in water (WIP). +depends = mcl_sounds +optional_depends = mcl_core, mclx_core diff --git a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge.png b/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge.png deleted file mode 100644 index 0d68d872f..000000000 Binary files a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge.png and /dev/null differ diff --git a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet.png b/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet.png deleted file mode 100644 index 7f4e84206..000000000 Binary files a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet.png and /dev/null differ diff --git a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet_river_water.png b/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet_river_water.png deleted file mode 100644 index 5d9475a56..000000000 Binary files a/mods/ITEMS/mcl_sponges/textures/mcl_sponges_sponge_wet_river_water.png and /dev/null differ diff --git a/mods/ITEMS/mcl_spyglass/init.lua b/mods/ITEMS/mcl_spyglass/init.lua new file mode 100644 index 000000000..fa1a82339 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/init.lua @@ -0,0 +1,73 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_tool("mcl_spyglass:spyglass",{ + description = S("Spyglass"), + _doc_items_longdesc = S("A spyglass is an item that can be used for zooming in on specific locations."), + inventory_image = "mcl_spyglass.png", + stack_max = 1, + _mcl_toollike_wield = true, +}) + +minetest.register_craft({ + output = "mcl_spyglass:spyglass", + recipe = { + {"mcl_amethyst:amethyst_shard"}, + {"mcl_copper:copper_ingot"}, + {"mcl_copper:copper_ingot"}, + } +}) + +local spyglass_scope = {} + +local function add_scope(player) + local wielditem = player:get_wielded_item() + if wielditem:get_name() == "mcl_spyglass:spyglass" then + spyglass_scope[player] = player:hud_add({ + hud_elem_type = "image", + position = {x = 0.5, y = 0.5}, + scale = {x = -100, y = -100}, + text = "mcl_spyglass_scope.png", + }) + player:hud_set_flags({wielditem = false}) + end +end + +local function remove_scope(player) + if spyglass_scope[player] then + player:hud_remove(spyglass_scope[player]) + spyglass_scope[player] = nil + player:hud_set_flags({wielditem = true}) + player:set_fov(86.1) + end +end + +controls.register_on_press(function(player, key) + if key ~= "RMB" then return end + add_scope(player) +end) + +controls.register_on_release(function(player, key, time) + if key ~= "RMB" then return end + remove_scope(player) +end) + +controls.register_on_hold(function(player, key, time) + if key ~= "RMB" then return end + local wielditem = player:get_wielded_item() + if wielditem:get_name() == "mcl_spyglass:spyglass" then + player:set_fov(8, false, 0.1) + if spyglass_scope[player] == nil then + add_scope(player) + end + else + remove_scope(player) + end +end) + +minetest.register_on_dieplayer(function(player) + remove_scope(player) +end) + +minetest.register_on_leaveplayer(function(player) + spyglass_scope[player] = nil +end) diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr new file mode 100644 index 000000000..ecd181146 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.fr.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=Longue-vue +A spyglass is an item that can be used for zooming in on specific locations.=Une longue-vue peut être utilisée pour zoomer sur des endroits spécifiques. diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr new file mode 100644 index 000000000..9c132604e --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=望遠鏡 +A spyglass is an item that can be used for zooming in on specific locations.=望遠鏡は、特定の場所を拡大して見るためのアイテムです。 diff --git a/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr new file mode 100644 index 000000000..32b7fa96a --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/mcl_spyglass.ru.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass=Подзорная труба +A spyglass is an item that can be used for zooming in on specific locations.=Подзорная труба это предмет который позволяет смотреть вдаль. \ No newline at end of file diff --git a/mods/ITEMS/mcl_spyglass/locale/template.txt b/mods/ITEMS/mcl_spyglass/locale/template.txt new file mode 100644 index 000000000..606b46455 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_spyglass +Spyglass= +A spyglass is an item that can be used for zooming in on specific locations.= diff --git a/mods/ITEMS/mcl_spyglass/mod.conf b/mods/ITEMS/mcl_spyglass/mod.conf new file mode 100644 index 000000000..c13b281e1 --- /dev/null +++ b/mods/ITEMS/mcl_spyglass/mod.conf @@ -0,0 +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 diff --git a/mods/ITEMS/mcl_stairs/api.lua b/mods/ITEMS/mcl_stairs/api.lua index aecf10836..6167d7e06 100644 --- a/mods/ITEMS/mcl_stairs/api.lua +++ b/mods/ITEMS/mcl_stairs/api.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_stairs") +local S = minetest.get_translator(minetest.get_current_modname()) -- Core mcl_stairs API @@ -20,7 +20,7 @@ local function place_slab_normal(itemstack, placer, pointed_thing) local p0 = pointed_thing.under local p1 = pointed_thing.above - local placer_pos = placer:get_pos() + --local placer_pos = placer:get_pos() local fpos = get_fpos(placer, pointed_thing) @@ -71,8 +71,6 @@ end -- Node will be called mcl_stairs:stair_ function mcl_stairs.register_stair(subname, recipeitem, groups, images, description, sounds, blast_resistance, hardness, corner_stair_texture_override) - groups.stair = 1 - groups.building_block = 1 if recipeitem then if not images then @@ -92,6 +90,9 @@ function mcl_stairs.register_stair(subname, recipeitem, groups, images, descript end end + groups.stair = 1 + groups.building_block = 1 + minetest.register_node(":mcl_stairs:stair_" .. subname, { description = description, _doc_items_longdesc = S("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."), @@ -155,7 +156,7 @@ function mcl_stairs.register_stair(subname, recipeitem, groups, images, descript if recipeitem then minetest.register_craft({ - output = 'mcl_stairs:stair_' .. subname .. ' 4', + output = "mcl_stairs:stair_" .. subname .. " 4", recipe = { {recipeitem, "", ""}, {recipeitem, recipeitem, ""}, @@ -165,7 +166,7 @@ function mcl_stairs.register_stair(subname, recipeitem, groups, images, descript -- Flipped recipe minetest.register_craft({ - output = 'mcl_stairs:stair_' .. subname .. ' 4', + output = "mcl_stairs:stair_" .. subname .. " 4", recipe = { {"", "", recipeitem}, {"", recipeitem, recipeitem}, @@ -179,7 +180,7 @@ end -- Slab facedir to placement 6d matching table -local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4} +--local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4} -- Register slabs. -- Node will be called mcl_stairs:slab_ @@ -212,7 +213,6 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti -- Automatically generate double slab description if not double_description then double_description = S("Double @1", description) - minetest.log("warning", "[stairs] No explicit description for double slab '"..double_slab.."' added. Using auto-generated description.") end groups.slab = 1 @@ -268,6 +268,7 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti end end, _mcl_hardness = hardness, + _mcl_blast_resistance = blast_resistance, _mcl_other_slab_half = upper_slab, on_rotate = function(pos, node, user, mode, param2) -- Flip slab @@ -296,7 +297,7 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti topdef._doc_items_usagehelp = nil topdef.drop = lower_slab topdef._mcl_other_slab_half = lower_slab - topdef.on_rotate = function(pos, node, user, mode, param2) + function topdef.on_rotate(pos, node, user, mode, param2) -- Flip slab if mode == screwdriver.ROTATE_AXIS then node.name = lower_slab @@ -331,6 +332,7 @@ function mcl_stairs.register_slab(subname, recipeitem, groups, images, descripti sounds = sounds, drop = lower_slab .. " 2", _mcl_hardness = hardness, + _mcl_blast_resistance = blast_resistance, }) if recipeitem then diff --git a/mods/ITEMS/mcl_stairs/cornerstair.lua b/mods/ITEMS/mcl_stairs/cornerstair.lua index 2d5f214e1..ae3eb4ea3 100644 --- a/mods/ITEMS/mcl_stairs/cornerstair.lua +++ b/mods/ITEMS/mcl_stairs/cornerstair.lua @@ -5,7 +5,7 @@ mcl_stairs.cornerstair = {} -local get_stair_param = function(node) +local function get_stair_param(node) local stair = minetest.get_item_group(node.name, "stair") if stair == 1 then return node.param2 @@ -24,7 +24,7 @@ local get_stair_param = function(node) end end -local get_stair_from_param = function(param, stairs) +local function get_stair_from_param(param, stairs) if param < 12 then if param < 4 then return {name = stairs[1], param2 = param} @@ -44,7 +44,7 @@ local get_stair_from_param = function(param, stairs) end end -local stair_param_to_connect = function(param, ceiling) +local function stair_param_to_connect(param, ceiling) local out = {false, false, false, false, false, false, false, false} if not ceiling then if param == 0 then @@ -126,7 +126,7 @@ local stair_param_to_connect = function(param, ceiling) return out end -local stair_connect_to_param = function(connect, ceiling) +local function stair_connect_to_param(connect, ceiling) local param if not ceiling then if connect[3] and connect[8] then @@ -240,7 +240,7 @@ function mcl_stairs.cornerstair.add(name, stairtiles) inner_groups.stair = 3 inner_groups.not_in_craft_guide = 1 local drop = node_def.drop or name - local after_dig_node = function(pos, oldnode) + local function after_dig_node(pos, oldnode) local param = get_stair_param(oldnode) local ceiling if param < 12 then @@ -273,7 +273,7 @@ function mcl_stairs.cornerstair.add(name, stairtiles) end end end - local swap_stair = function(index, n1, n2) + local function swap_stair(index, n1, n2) local connect = {false, false, false, false, false, false, false, false} connect[n1] = true connect[n2] = true @@ -425,13 +425,13 @@ function mcl_stairs.cornerstair.add(name, stairtiles) end end end - local reset_node = function(n1, n2) + local function reset_node(n1, n2) local connect = {false, false, false, false, false, false, false, false} connect[n1] = true connect[n2] = true node = get_stair_from_param(stair_connect_to_param(connect, ceiling), t[5].stairs) end - local swap_stair = function(index, n1, n2) + local function swap_stair(index, n1, n2) local connect = {false, false, false, false, false, false, false, false} connect[n1] = true connect[n2] = true diff --git a/mods/ITEMS/mcl_stairs/crafting.lua b/mods/ITEMS/mcl_stairs/crafting.lua index 702a78068..f31237eed 100644 --- a/mods/ITEMS/mcl_stairs/crafting.lua +++ b/mods/ITEMS/mcl_stairs/crafting.lua @@ -1,40 +1,40 @@ minetest.register_craft({ - output = 'mcl_core:sandstonecarved', + output = "mcl_core:sandstonecarved", recipe = { - {'mcl_stairs:slab_sandstone'}, - {'mcl_stairs:slab_sandstone'} + {"mcl_stairs:slab_sandstone"}, + {"mcl_stairs:slab_sandstone"} } }) minetest.register_craft({ - output = 'mcl_core:redsandstonecarved', + output = "mcl_core:redsandstonecarved", recipe = { - {'mcl_stairs:slab_redsandstone'}, - {'mcl_stairs:slab_redsandstone'} + {"mcl_stairs:slab_redsandstone"}, + {"mcl_stairs:slab_redsandstone"} } }) minetest.register_craft({ - output = 'mcl_core:stonebrickcarved', + output = "mcl_core:stonebrickcarved", recipe = { - {'mcl_stairs:slab_stonebrick'}, - {'mcl_stairs:slab_stonebrick'} + {"mcl_stairs:slab_stonebrick"}, + {"mcl_stairs:slab_stonebrick"} } }) minetest.register_craft({ - output = 'mcl_end:purpur_pillar', + output = "mcl_end:purpur_pillar", recipe = { - {'mcl_stairs:slab_purpur_block'}, - {'mcl_stairs:slab_purpur_block'} + {"mcl_stairs:slab_purpur_block"}, + {"mcl_stairs:slab_purpur_block"} } }) minetest.register_craft({ - output = 'mcl_nether:quartz_chiseled 2', + output = "mcl_nether:quartz_chiseled 2", recipe = { - {'mcl_stairs:slab_quartzblock'}, - {'mcl_stairs:slab_quartzblock'}, + {"mcl_stairs:slab_quartzblock"}, + {"mcl_stairs:slab_quartzblock"}, } }) diff --git a/mods/ITEMS/mcl_stairs/depends.txt b/mods/ITEMS/mcl_stairs/depends.txt deleted file mode 100644 index 96e184bd9..000000000 --- a/mods/ITEMS/mcl_stairs/depends.txt +++ /dev/null @@ -1,5 +0,0 @@ -mcl_core -mcl_sounds -mcl_nether -mcl_end -mcl_ocean diff --git a/mods/ITEMS/mcl_stairs/init.lua b/mods/ITEMS/mcl_stairs/init.lua index a5ca820bf..92f0640b3 100644 --- a/mods/ITEMS/mcl_stairs/init.lua +++ b/mods/ITEMS/mcl_stairs/init.lua @@ -7,8 +7,10 @@ mcl_stairs = {} -- Load other files -dofile(minetest.get_modpath("mcl_stairs").."/api.lua") -dofile(minetest.get_modpath("mcl_stairs").."/cornerstair.lua") -dofile(minetest.get_modpath("mcl_stairs").."/register.lua") -dofile(minetest.get_modpath("mcl_stairs").."/crafting.lua") -dofile(minetest.get_modpath("mcl_stairs").."/alias.lua") +local modpath = minetest.get_modpath(minetest.get_current_modname()) + +dofile(modpath.."/api.lua") +dofile(modpath.."/cornerstair.lua") +dofile(modpath.."/register.lua") +dofile(modpath.."/crafting.lua") +dofile(modpath.."/alias.lua") diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr index 9c6684fc6..76ff95dce 100644 --- a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.fr.tr @@ -4,98 +4,101 @@ Double @1=Double @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.=Les dalles sont deux fois moins hautes que leurs homologues de bloc complet et occupent la partie inférieure ou supérieure d'un bloc, selon la façon dont il a été placé. Les dalles peuvent être facilement franchies sans avoir à sauter. Lorsqu'une dalle est placée sur une autre dalle du même type, une double dalle est créée. Upper @1=@1 Supérieur Double slabs are full blocks which are created by placing two slabs of the same kind on each other.=Les dalles doubles sont des blocs entiers qui sont créés en plaçant deux dalles du même type l'une sur l'autre. -Oak Wood Stairs=Escalier en Bois de Chêne -Oak Wood Slab=Dalle en Bois de Chêne -Double Oak Wood Slab=Double Dalle en Bois de Chêne -Jungle Wood Stairs=Escalier en Bois d'Acajou -Jungle Wood Slab=Dalle en Bois d'Acajou -Double Jungle Wood Slab=Double Dalle en Bois d'Acajou -Acacia Wood Stairs=Escalier en Bois d'Acacia -Acacia Wood Slab=Dalle en Bois d'Acacia -Double Acacia Wood Slab=Double Dalle en Bois d'Acacia -Spruce Wood Stairs=Escalier en Bois de Sapin -Spruce Wood Slab=Dalle en Bois de Sapin -Double Spruce Wood Slab=Double Dalle en Bois de Sapin -Birch Wood Stairs=Escalier en Bois de Bouleau -Birch Wood Slab=Dalle en Bois de Bouleau -Double Birch Wood Slab=Double Dalle en Bois de Bouleau -Dark Oak Wood Stairs=Escalier en Bois de Chêne Noir -Dark Oak Wood Slab=Dalle en Bois de Chêne Noir -Double Dark Oak Wood Slab=Double Dalle en Bois de Chêne Noir -Stone Stairs=Escalier en Roche -Stone Slab=Dalle en Roche -Double Stone Slab=Double Dalle en Roche -Polished Stone Slab=Dalle en Pierre Polie -Double Polished Stone Slab=Double Dalle en Pierre Polie -Andesite Stairs=Escalier en Andésite -Andesite Slab=Dalle en Andésite -Double Andesite Slab=Double Dalle en Andésite -Granite Stairs=Escalier en Granite -Granite Slab=Dalle en Granite -Double Granite Slab=Double Dalle en Granite -Diorite Stairs=Escalier en Diorite -Diorite Slab=Dalle en Diorite -Double Diorite Slab=Double Dalle en Diorite -Cobblestone Stairs=Escalier en Pierre -Cobblestone Slab=Dalle en Pierre -Double Cobblestone Slab=Double Dalle en Pierre -Mossy Cobblestone Stairs=Escalier en Pierre Moussue -Mossy Cobblestone Slab=Dalle en Pierre Moussue -Double Mossy Cobblestone Slab=Double Dalle en Pierre Moussue -Brick Stairs=Escalier de Brique -Brick Slab=Dalle en Brique -Double Brick Slab=Double Dalle en Brique -Sandstone Stairs=Escalier en Grès -Sandstone Slab=Dalle en Grès -Double Sandstone Slab=Double Dalle en Grès -Smooth Sandstone Stairs=Escalier en Grès Poli -Smooth Sandstone Slab=Dalle en Grès Poli -Double Smooth Sandstone Slab=Double Dalle en Grès Poli -Red Sandstone Stairs=Escalier en Grès Rouge -Red Sandstone Slab=Dalle en Grès Rouge -Double Red Sandstone Slab=Double Dalle en Grès Rouge -Smooth Red Sandstone Stairs=Escalier en Grès Rouge Poli -Smooth Red Sandstone Slab=Dalle en Grès Rouge Poli -Double Smooth Red Sandstone Slab=Double Dalle en Grès Rouge Poli -Stone Bricks Stairs=Escalier en Pierre Taillée -Stone Bricks Slab=Dalle en Pierre Taillée -Double Stone Bricks Slab=Double Dalle en Pierre Taillée -Quartz Stairs=Escalier en Quartz -Quartz Slab=Dalle en Quartz -Double Quartz Slab=Double Dalle en Quartz -Smooth Quartz Stairs=Escalier en Quartz Poli -Smooth Quartz Slab=Dallle en Quartz Poli -Double Smooth Quartz Slab=Double Dalle en Quartz Poli -Nether Brick Stairs=Escalier en Brique du Nether -Nether Brick Slab=Dalle en Brique du Nether -Double Nether Brick Slab=Double Dalle en Brique du Nether -Red Nether Brick Stairs=Escalier en Brique Rouge du Nether -Red Nether Brick Slab=Dalle en Brique Rouge du Nether -Double Red Nether Brick Slab=Double Dalle en Brique Rouge du Nether -End Stone Brick Stairs=Escalier en Pierre de l'End -End Stone Brick Slab=Dalle en Pierre de l'End -Double End Stone Brick Slab=Double Dalle en Pierre de l'End -Purpur Stairs=Escalier en Purpur -Purpur Slab=Dalle en Purpur -Double Purpur Slab=Double Dalle en Purpur -Prismarine Stairs=Escalier en Prismarine -Prismarine Slab=Dalle en Prismarine -Double Prismarine Slab=Double Dalle en Prismarine -Prismarine Brick Stairs=Escalier en Brique Prismarine -Prismarine Brick Slab=Dalle en Brique Prismarine -Double Prismarine Brick Slab=Double Dalle en Brique Prismarine -Dark Prismarine Stairs=Escalier en Prismarine Sombre -Dark Prismarine Slab=Dalle en Prismarine Sombre -Double Dark Prismarine Slab=Double Dalle en Prismarine Sombre -Polished Andesite Slab=Dalle en Andésite Polie -Double Polished Andesite Slab=Double Dalle en Andésite Polie -Polished Andesite Stairs=Escalier en Andésite Polie -Polished Granite Slab=Dalle en Granit Poli -Double Polished Granite Slab=Double Dalle en Granit Poli -Polished Granite Stairs=Escalier en Granit Poli -Polished Diorite Slab=Dalle en Diorite Polie -Double Polished Diorite Slab=Double Dalle en Diorite Polie -Polished Diorite Stairs=Escalier en Diorite Polie -Mossy Stone Brick Stairs=Escalier en Pierre Taillée Moussue -Mossy Stone Brick Slab=Dalle en Pierre Taillée Moussue -Double Mossy Stone Brick Slab=Double Dalle en Pierre Taillée Moussue +Oak Wood Stairs=Escalier en bois de chêne +Oak Wood Slab=Dalle en bois de chêne +Double Oak Wood Slab=Double dalle en bois de chêne +Jungle Wood Stairs=Escalier en bois d'acajou +Jungle Wood Slab=Dalle en bois d'acajou +Double Jungle Wood Slab=Double dalle en bois d'acajou +Acacia Wood Stairs=Escalier en bois d'acacia +Acacia Wood Slab=Dalle en bois d'acacia +Double Acacia Wood Slab=Double dalle en bois d'acacia +Spruce Wood Stairs=Escalier en bois de sapin +Spruce Wood Slab=Dalle en bois de sapin +Double Spruce Wood Slab=Double dalle en bois de sapin +Birch Wood Stairs=Escalier en bois de bouleau +Birch Wood Slab=Dalle en bois de bouleau +Double Birch Wood Slab=Double dalle en bois de bouleau +Dark Oak Wood Stairs=Escalier en bois de chêne noir +Dark Oak Wood Slab=Dalle en bois de chêne noir +Double Dark Oak Wood Slab=Double dalle en bois de chêne noir +Stone Stairs=Escalier en roche +Stone Slab=Dalle en roche +Double Stone Slab=Double dalle en roche +Polished Stone Slab=Dalle en pierre polie +Double Polished Stone Slab=Double dalle en pierre polie +Andesite Stairs=Escalier en andésite +Andesite Slab=Dalle en andésite +Double Andesite Slab=Double dalle en andésite +Granite Stairs=Escalier en granite +Granite Slab=Dalle en granite +Double Granite Slab=Double dalle en granite +Diorite Stairs=Escalier en diorite +Diorite Slab=Dalle en diorite +Double Diorite Slab=Double dalle en diorite +Cobblestone Stairs=Escalier en pierre +Cobblestone Slab=Dalle en pierre +Double Cobblestone Slab=Double dalle en pierre +Mossy Cobblestone Stairs=Escalier en pierre moussue +Mossy Cobblestone Slab=Dalle en pierre moussue +Double Mossy Cobblestone Slab=Double dalle en pierre moussue +Brick Stairs=Escalier de brique +Brick Slab=Dalle en brique +Double Brick Slab=Double dalle en brique +Sandstone Stairs=Escalier en grès +Sandstone Slab=Dalle en grès +Double Sandstone Slab=Double dalle en grès +Smooth Sandstone Stairs=Escalier en grès poli +Smooth Sandstone Slab=Dalle en grès poli +Double Smooth Sandstone Slab=Double dalle en grès poli +Red Sandstone Stairs=Escalier en grès rouge +Red Sandstone Slab=Dalle en grès rouge +Double Red Sandstone Slab=Double dalle en grès rouge +Smooth Red Sandstone Stairs=Escalier en grès rouge poli +Smooth Red Sandstone Slab=Dalle en grès rouge poli +Double Smooth Red Sandstone Slab=Double dalle en grès rouge poli +Stone Bricks Stairs=Escalier en pierre taillée +Stone Bricks Slab=Dalle en pierre taillée +Double Stone Bricks Slab=Double dalle en pierre taillée +Quartz Stairs=Escalier en quartz +Quartz Slab=Dalle en quartz +Double Quartz Slab=Double dalle en quartz +Smooth Quartz Stairs=Escalier en quartz poli +Smooth Quartz Slab=Dallle en quartz poli +Double Smooth Quartz Slab=Double dalle en quartz poli +Nether Brick Stairs=Escalier en brique du Nether +Nether Brick Slab=Dalle en brique du Nether +Double Nether Brick Slab=Double dalle en brique du Nether +Red Nether Brick Stairs=Escalier en brique rouge du Nether +Red Nether Brick Slab=Dalle en brique rouge du Nether +Double Red Nether Brick Slab=Double dalle en brique rouge du Nether +End Stone Brick Stairs=Escalier en pierre de l'End +End Stone Brick Slab=Dalle en pierre de l'End +Double End Stone Brick Slab=Double dalle en pierre de l'End +Purpur Stairs=Escalier en purpur +Purpur Slab=Dalle en purpur +Double Purpur Slab=Double dalle en purpur +Prismarine Stairs=Escalier en prismarine +Prismarine Slab=Dalle en prismarine +Double Prismarine Slab=Double dalle en prismarine +Prismarine Brick Stairs=Escalier en brique prismarine +Prismarine Brick Slab=Dalle en brique prismarine +Double Prismarine Brick Slab=Double dalle en brique prismarine +Dark Prismarine Stairs=Escalier en prismarine sombre +Dark Prismarine Slab=Dalle en prismarine sombre +Double Dark Prismarine Slab=Double dalle en prismarine sombre +Polished Andesite Slab=Dalle en andésite polie +Double Polished Andesite Slab=Double dalle en andésite polie +Polished Andesite Stairs=Escalier en andésite polie +Polished Granite Slab=Dalle en granite poli +Double Polished Granite Slab=Double dalle en granite poli +Polished Granite Stairs=Escalier en granite poli +Polished Diorite Slab=Dalle en diorite polie +Double Polished Diorite Slab=Double dalle en diorite polie +Polished Diorite Stairs=Escalier en diorite polie +Mossy Stone Brick Stairs=Escalier en pierre taillée moussue +Mossy Stone Brick Slab=Dalle en pierre taillée moussue +Double Mossy Stone Brick Slab=Double dalle en pierre taillée moussue +Mud Brick Stair=Escalier en briques de boue +Mud Brick Slab=Dalle en briques de boue +Double Mud Brick Slab=Double dalle en briques de boue diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr new file mode 100644 index 000000000..630f382e9 --- /dev/null +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.ja.tr @@ -0,0 +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.=階段は、その上を歩いて高いところに行くのに便利なものです(ジャンプは不要)。階段を隅に配置すると、隅階段になります。天井やブロックの側面の上半分に階段を設置すると、逆さまに設置されます。 +Double @1=2重 @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.=スラブは、高さがフルブロックの半分で、配置によってブロックの下部または上部を占めます。スラブはジャンプすることなく簡単に登れます。スラブの上に同種のスラブを置くと、2重スラブになります。 +Upper @1=上部 @1 +Double slabs are full blocks which are created by placing two slabs of the same kind on each other.=2重スラブとは、同種のスラブを2枚重ねて作るフルブロックのことです。 +Oak Wood Stairs=オーク材の階段 +Oak Wood Slab=オーク材のスラブ +Double Oak Wood Slab=オーク材2重スラブ +Jungle Wood Stairs=ジャングル材の階段 +Jungle Wood Slab=ジャングル材のスラブ +Double Jungle Wood Slab=ジャングル材の2重スラブ +Acacia Wood Stairs=アカシア材の階段 +Acacia Wood Slab=アカシア材のスラブ +Double Acacia Wood Slab=アカシア材の2重スラブ +Spruce Wood Stairs=トウヒ材の階段 +Spruce Wood Slab=トウヒ材のスラブ +Double Spruce Wood Slab=トウヒ材の2重スラブ +Birch Wood Stairs=シラカバ材の階段 +Birch Wood Slab=シラカバ材のスラブ +Double Birch Wood Slab=シラカバ材の2重スラブ +Dark Oak Wood Stairs=ダークオーク材の階段 +Dark Oak Wood Slab=ダークオーク材のスラブ +Double Dark Oak Wood Slab=ダークオーク材の2重スラブ +Stone Stairs=石の階段 +Stone Slab=石のスラブ +Double Stone Slab=石の2重スラブ +Polished Stone Slab=研がれた石のスラブ +Double Polished Stone Slab=研がれた石の2重スラブ +Andesite Stairs=安山岩の階段 +Andesite Slab=安山岩のスラブ +Double Andesite Slab=安山岩の2重スラブ +Granite Stairs=花崗岩の階段 +Granite Slab=花崗岩のスラブ +Double Granite Slab=花崗岩の2重スラブ +Diorite Stairs=閃緑岩の階段 +Diorite Slab=閃緑岩のスラブ +Double Diorite Slab=閃緑岩の2重スラブ +Cobblestone Stairs=丸石の階段 +Cobblestone Slab=丸石のスラブ +Double Cobblestone Slab=丸石の2重スラブ +Mossy Cobblestone Stairs=苔むした丸石の階段 +Mossy Cobblestone Slab=苔むした丸石のスラブ +Double Mossy Cobblestone Slab=苔むした丸石の2重スラブ +Brick Stairs=レンガの階段 +Brick Slab=レンガのスラブ +Double Brick Slab=レンガの2重スラブ +Sandstone Stairs=砂岩の階段 +Sandstone Slab=砂岩のスラブ +Double Sandstone Slab=砂岩の2重スラブ +Smooth Sandstone Stairs=滑らかな砂岩の階段 +Smooth Sandstone Slab=滑らかな砂岩のスラブ +Double Smooth Sandstone Slab=滑らかな砂岩の2重スラブ +Red Sandstone Stairs=赤い砂岩の階段 +Red Sandstone Slab=赤い砂岩のスラブ +Double Red Sandstone Slab=赤い砂岩の2重スラブ +Smooth Red Sandstone Stairs=滑らかな赤い砂岩の階段 +Smooth Red Sandstone Slab=滑らかな赤い砂岩のスラブ +Double Smooth Red Sandstone Slab=滑らかな赤い砂岩の2重スラブ +Stone Bricks Stairs=石レンガの階段 +Stone Bricks Slab=石レンガのスラブ +Double Stone Bricks Slab=石レンガの2重スラブ +Quartz Stairs=クォーツの階段 +Quartz Slab=クォーツのスラブ +Double Quartz Slab=クォーツの2重スラブ +Smooth Quartz Stairs=滑らかなクォーツの階段 +Smooth Quartz Slab=滑らかなクォーツのスラブ +Double Smooth Quartz Slab=滑らかなクォーツの2重スラブ +Nether Brick Stairs=ネザーレンガの階段 +Nether Brick Slab=ネザーレンガのスラブ +Double Nether Brick Slab=ネザーレンガの2重スラブ +Red Nether Brick Stairs=赤いネザーレンガの階段 +Red Nether Brick Slab=赤いネザーレンガのスラブ +Double Red Nether Brick Slab=赤いネザーレンガの2重スラブ +End Stone Brick Stairs=エンドストーンレンガの階段 +End Stone Brick Slab=エンドストーンレンガのスラブ +Double End Stone Brick Slab=エンドストーンレンガの2重スラブ +Purpur Stairs=プルプァの階段 +Purpur Slab=プルプァのスラブ +Double Purpur Slab=プルプァの2重スラブ +Prismarine Stairs=プリズマリンの階段 +Prismarine Slab=プリズマリンのスラブ +Double Prismarine Slab=プリズマリンの2重スラブ +Prismarine Brick Stairs=プリズマリンレンガの階段 +Prismarine Brick Slab=プリズマリンレンガのスラブ +Double Prismarine Brick Slab=プリズマリンレンガの2重スラブ +Dark Prismarine Stairs=暗色プリズマリンの階段 +Dark Prismarine Slab=暗色プリズマリンのスラブ +Double Dark Prismarine Slab=暗色プリズマリンの2重スラブ +Polished Andesite Slab=研がれた安山岩のスラブ +Double Polished Andesite Slab=研がれた安山岩の2重スラブ +Polished Andesite Stairs=研がれた安山岩の階段 +Polished Granite Slab=研がれた花崗岩のスラブ +Double Polished Granite Slab=研がれた花崗岩の2重スラブ +Polished Granite Stairs=研がれた花崗岩の階段 +Polished Diorite Slab=研がれた閃緑岩のスラブ +Double Polished Diorite Slab=研がれた閃緑岩の2重スラブ +Polished Diorite Stairs=研がれた閃緑岩の階段 +Mossy Stone Brick Stairs=苔むした石レンガの階段 +Mossy Stone Brick Slab=苔むした石レンガのスラブ +Double Mossy Stone Brick Slab=苔むした石レンガの2重スラブ +Mud Brick Stair=泥レンガの階段 +Mud Brick Slab=泥レンガのスラブ +Double Mud Brick Slab=泥レンガの2重スラブ \ No newline at end of file diff --git a/mods/ITEMS/mcl_stairs/locale/mcl_stairs.pl.tr b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.pl.tr new file mode 100644 index 000000000..2b2b52486 --- /dev/null +++ b/mods/ITEMS/mcl_stairs/locale/mcl_stairs.pl.tr @@ -0,0 +1,101 @@ +# 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.=Schody są użyteczne by wspiąć się do wyższych miejsc poprzez chodzenie po nich. Nie trzeba na nich skakać. Umieszczenie schodów w rogu schodów dopasuje schodu do rogu. Schody postawione na suficie lub na górnej części bloku będą postawione do góry nogami. +Double @1=Podwójna @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.=Płyty są wysokości połowy odpowiadającego im bloku i zajmują górną lub dolną część bloku w zależności od tego jak są postawione. Na płyty można łatwo wejść bez konieczności skakania. Gdy płyta jest postawiona na innej płycie tego samego typu, podwójna płyta jest tworzona. +Upper @1=Górna @1 +Double slabs are full blocks which are created by placing two slabs of the same kind on each other.=Podwójne płyty są pełnymi blokami tworzonymi przez położenie dwóch płyt tego samego typu jedna na drugiej. +Oak Wood Stairs=Dębowe schody +Oak Wood Slab=Dębowa płyta +Double Oak Wood Slab=Podwójna dębowa płyta +Jungle Wood Stairs=Tropikalne schody +Jungle Wood Slab=Tropikalna płyta +Double Jungle Wood Slab=Podwójna tropikalna płyta +Acacia Wood Stairs=Akacjowe schody +Acacia Wood Slab=Akacjowa płyta +Double Acacia Wood Slab=Podwójna akacjowa płyta +Spruce Wood Stairs=Świerkowe schody +Spruce Wood Slab=Świerkowa płyta +Double Spruce Wood Slab=Podwójna świerkowa płyta +Birch Wood Stairs=Brzozowe schody +Birch Wood Slab=Brzozowa płyta +Double Birch Wood Slab=Podwójna brzozowa płyta +Dark Oak Wood Stairs=Ciemno-dębowe schody +Dark Oak Wood Slab=Ciemno-dębowa płyta +Double Dark Oak Wood Slab=Podwójna ciemno-dębowa płyta +Stone Stairs=Kamienne schody +Stone Slab=Kamienna płyta +Double Stone Slab=Podwójna kamienna płyta +Polished Stone Slab=Polerowana kamienna płyta +Double Polished Stone Slab=Podwójna polerowana kamienna płyta +Andesite Stairs=Andezytowe schody +Andesite Slab=Andezytowa płyta +Double Andesite Slab=Podwójne andezytowa płyta +Granite Stairs=Granitowe schody +Granite Slab=Granitowa płyta +Double Granite Slab=Podwójna granitowa płyta +Diorite Stairs=Diorytowe schody +Diorite Slab=Diorytowa płyta +Double Diorite Slab=Podwójna diorytowa płyta +Cobblestone Stairs=Brukowane schody +Cobblestone Slab=Brukowana płyta +Double Cobblestone Slab=Podwójna brukowana płyta +Mossy Cobblestone Stairs=Zamszone brukowane schody +Mossy Cobblestone Slab=Zamszona brukowana płyta +Double Mossy Cobblestone Slab=Podwójna zamszona brukowana płyta +Brick Stairs=Ceglane schody +Brick Slab=Ceglana płyta +Double Brick Slab=Podwójna ceglana płyta +Sandstone Stairs=Piaskowcowe schody +Sandstone Slab=Piaskowcowa płyta +Double Sandstone Slab=Podwójna piaskowcowa płyta +Smooth Sandstone Stairs=Polerowane piaskowcowe schody +Smooth Sandstone Slab=Polerowana piaskowcowa płyta +Double Smooth Sandstone Slab=Podwójna polerowana piaskowcowa płyta +Red Sandstone Stairs=Czerwone piaskowcowe schody +Red Sandstone Slab=Czerwona piaskowcowa płyta +Double Red Sandstone Slab=Podwójna czerwona piaskowcowa płyta +Smooth Red Sandstone Stairs=Polerowane czerwone piaskowcowe schody +Smooth Red Sandstone Slab=Polerowana czerwona piaskowcowa płyta +Double Smooth Red Sandstone Slab=Podwójna polerowana czerwona piaskowcowa płyta +Stone Bricks Stairs=Ceglane kamienne schody +Stone Bricks Slab=Ceglana kamienna płyta +Double Stone Bricks Slab=Podwójna ceglana kamienna płyta +Quartz Stairs=Kwarcowe schody +Quartz Slab=Kwarcowa płyta +Double Quartz Slab=Podwójna kwarcowa płyta +Smooth Quartz Stairs=Polerowane kwarcowe schody +Smooth Quartz Slab=Polerowana kwarcowa płyta +Double Smooth Quartz Slab=Podwójna polerowana kwarcowa płyta +Nether Brick Stairs=Netherowe ceglane schody +Nether Brick Slab=Netherowa ceglana płyta +Double Nether Brick Slab=Podwójna Netherowa ceglana płyta +Red Nether Brick Stairs=Czerwone Netherowe ceglane schody +Red Nether Brick Slab=Czerwona Netherowa ceglana płyta +Double Red Nether Brick Slab=Podwójna czerwona Netherowa ceglana płyta +End Stone Brick Stairs=Kresowe ceglane kamienne schody +End Stone Brick Slab=Kresowa ceglana kamienna płyta +Double End Stone Brick Slab=Podwójna kresowa ceglana kamienna płyta +Purpur Stairs=Purpurowe schody +Purpur Slab=Purpurowa płyta +Double Purpur Slab=Podwójna purpurowe płyta +Prismarine Stairs=Pryzmarynowe schody +Prismarine Slab=Pryzmarynowa płyta +Double Prismarine Slab=Podwójna pryzmarynowa płyta +Prismarine Brick Stairs=Pryzmarynowe ceglane schody +Prismarine Brick Slab=Pryzmarynowa ceglana płyta +Double Prismarine Brick Slab=Podwójna pryzmarynowa ceglana płyta +Dark Prismarine Stairs=Ciemne pryzmarynowe schody +Dark Prismarine Slab=Ciemna pryzmarynowa płyta +Double Dark Prismarine Slab=Podwójna ciemna pryzmarynowa płyta +Polished Andesite Slab=Polerowana andezytowa płyta +Double Polished Andesite Slab=Podwójna polerowana andezytowa płyta +Polished Andesite Stairs=Polerowane andezytowe schody +Polished Granite Slab=Polerowana granitowa płyta +Double Polished Granite Slab=Podwójna polerowana granitowa płyta +Polished Granite Stairs=Polerowane granitowe schody +Polished Diorite Slab=Polerowana diorytowa płyta +Double Polished Diorite Slab=Podwójna polerowana diorytowa płyta +Polished Diorite Stairs=Polerowane diorytowe schody +Mossy Stone Brick Stairs=Zamszone kamienne ceglane schody +Mossy Stone Brick Slab=Zamszona kamienna ceglana płyta +Double Mossy Stone Brick Slab=Podwójna zamszona kamienna ceglana płyta diff --git a/mods/ITEMS/mcl_stairs/locale/template.txt b/mods/ITEMS/mcl_stairs/locale/template.txt index 0638af3db..dfacc1b5c 100644 --- a/mods/ITEMS/mcl_stairs/locale/template.txt +++ b/mods/ITEMS/mcl_stairs/locale/template.txt @@ -99,3 +99,6 @@ 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 4540a7981..2fb3180b2 100644 --- a/mods/ITEMS/mcl_stairs/mod.conf +++ b/mods/ITEMS/mcl_stairs/mod.conf @@ -1 +1,2 @@ name = mcl_stairs +depends = mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_ocean, mcl_mud diff --git a/mods/ITEMS/mcl_stairs/register.lua b/mods/ITEMS/mcl_stairs/register.lua index 565f5409b..eee4c5dc2 100644 --- a/mods/ITEMS/mcl_stairs/register.lua +++ b/mods/ITEMS/mcl_stairs/register.lua @@ -3,7 +3,7 @@ -- slabs actually take slightly longer to be dug than their stair counterparts. -- Note sure if it is a good idea to preserve this oddity. -local S = minetest.get_translator("mcl_stairs") +local S = minetest.get_translator(minetest.get_current_modname()) local woods = { { "wood", "default_wood.png", S("Oak Wood Stairs"), S("Oak Wood Slab"), S("Double Oak Wood Slab") }, @@ -138,6 +138,8 @@ mcl_stairs.register_slab("purpur_block", "group:purpur_block", 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_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_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")) diff --git a/mods/ITEMS/mcl_stairs/textures/mcl_stairs_stone_slab_top.png b/mods/ITEMS/mcl_stairs/textures/mcl_stairs_stone_slab_top.png deleted file mode 100644 index 8e5a355be..000000000 Binary files a/mods/ITEMS/mcl_stairs/textures/mcl_stairs_stone_slab_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_starting_inventory/README.txt b/mods/ITEMS/mcl_starting_inventory/README.txt new file mode 100644 index 000000000..126504b04 --- /dev/null +++ b/mods/ITEMS/mcl_starting_inventory/README.txt @@ -0,0 +1,11 @@ +Mcl_starting_inventory, adapted for Mineclone 2 by Michieal. + +Based on: +Minetest Game mod: give_initial_stuff +===================================== +See license.txt for license information. + +Authors of source code +---------------------- +Perttu Ahola (celeron55) (MIT) +Various Minetest developers and contributors (MIT) diff --git a/mods/ITEMS/mcl_starting_inventory/init.lua b/mods/ITEMS/mcl_starting_inventory/init.lua new file mode 100644 index 000000000..137391bd3 --- /dev/null +++ b/mods/ITEMS/mcl_starting_inventory/init.lua @@ -0,0 +1,62 @@ +--- Copyright 2023, Michieal. (Modifications for the mod to be usable in Mineclone 2.) +--- Based on mtg mod, give_initial_stuff. "Written by C55 and various minetest developers." +--- +--- Copyright notice created for the license to be valid. (MIT 3) + +local DEBUG = false + +local function mcl_log(message) + if DEBUG then + minetest.log(message) + end +end + +local give_inventory = minetest.settings:get_bool("give_starting_inv", false) + +local stuff_string = "mcl_tools:pick_iron,mcl_tools:axe_iron,mcl_tools:shovel_iron,mcl_torches:torch 32,mcl_core:cobble 32" + +mcl_starting_inventory = { + items = {} +} + +function mcl_starting_inventory.give(player) + mcl_log("Giving initial stuff to player " .. player:get_player_name()) + local inv = player:get_inventory() + for _, stack in ipairs(mcl_starting_inventory.items) do + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else + mcl_log("no room for the item: " .. dump(stack)) + end + end +end + +function mcl_starting_inventory.add(stack) + mcl_starting_inventory.items[#mcl_starting_inventory.items + 1] = ItemStack(stack) +end + +function mcl_starting_inventory.clear() + mcl_starting_inventory.items = {} +end + +function mcl_starting_inventory.add_from_csv(str) + local items = str:split(",") + for _, itemname in ipairs(items) do + mcl_starting_inventory.add(itemname) + end +end + +function mcl_starting_inventory.set_list(list) + mcl_starting_inventory.items = list +end + +function mcl_starting_inventory.get_list() + return mcl_starting_inventory.items +end + +if give_inventory and give_inventory == true then + mcl_starting_inventory.add_from_csv(stuff_string) + mcl_log("Okay to give inventory:\n" .. dump(mcl_starting_inventory.get_list())) +end + +minetest.register_on_newplayer(mcl_starting_inventory.give) diff --git a/mods/ITEMS/mcl_starting_inventory/license.txt b/mods/ITEMS/mcl_starting_inventory/license.txt new file mode 100644 index 000000000..8134c920e --- /dev/null +++ b/mods/ITEMS/mcl_starting_inventory/license.txt @@ -0,0 +1,25 @@ +License of source code +---------------------- + +The MIT License (MIT) +Copyright (C) 2012-2016 Perttu Ahola (celeron55) +Copyright (C) 2012-2016 Various Minetest developers and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit +persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + +For more details: +https://opensource.org/licenses/MIT diff --git a/mods/ITEMS/mcl_starting_inventory/mod.conf b/mods/ITEMS/mcl_starting_inventory/mod.conf new file mode 100644 index 000000000..dd91a9e8e --- /dev/null +++ b/mods/ITEMS/mcl_starting_inventory/mod.conf @@ -0,0 +1,3 @@ +name = mcl_starting_inventory +description = Mineclone 2 mod, Give Starting Inventory +depends = mcl_core, mcl_tools, mcl_torches diff --git a/mods/ITEMS/mcl_stonecutter/README.md b/mods/ITEMS/mcl_stonecutter/README.md new file mode 100644 index 000000000..c6316a5a2 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/README.md @@ -0,0 +1,17 @@ +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. + +License of code +--------------- +See the main MineClone 2 README.md file. +Author: PrairieWind + +License of media +---------------- +mcl_stonecutter_bottom.png +mcl_stonecutter_side.png +mcl_stonecutter_top.png +mcl_stonecutter_saw.png +License: CC0 1.0 Universal (CC0 1.0) +Author: RandomLegoBrick diff --git a/mods/ITEMS/mcl_stonecutter/init.lua b/mods/ITEMS/mcl_stonecutter/init.lua new file mode 100644 index 000000000..e75884990 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/init.lua @@ -0,0 +1,58 @@ +--||||||||||||||||||||||| +--||||| STONECUTTER ||||| +--||||||||||||||||||||||| + +-- TO-DO: +-- * Add GUI + +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_node("mcl_stonecutter:stonecutter", { + description = S("Stone Cutter"), + _tt_help = S("Used to cut stone like materials."), + _doc_items_longdesc = S("Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager."), + tiles = { + "mcl_stonecutter_top.png", + "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 + }} + }, + use_texture_alpha = "clip", + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + 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 + } + }, + _mcl_blast_resistance = 3.5, + _mcl_hardness = 3.5, + sounds = mcl_sounds.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + output = "mcl_stonecutter:stonecutter", + recipe = { + { "", "", "" }, + { "", "mcl_core:iron_ingot", "" }, + { "mcl_core:stone", "mcl_core:stone", "mcl_core:stone" }, + } +}) diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr new file mode 100644 index 000000000..415093305 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.fr.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_stonecutter +Stone Cutter=Tailleur de pierre +Used to cut stone like materials.=utilisé pour couper les matériaux similaires à la pierre. +Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager.=Les tailleurs de pierre sont utilisés pour créer des escaliers et dalles à partir de matériaux similaires à la pierre. C'est aussi le poste de travail du villageois maçon. diff --git a/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.tr b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.tr new file mode 100644 index 000000000..d26819d64 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/mcl_stonecutter.ja.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/locale/template.txt b/mods/ITEMS/mcl_stonecutter/locale/template.txt new file mode 100644 index 000000000..d9bd51c32 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/locale/template.txt @@ -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 new file mode 100644 index 000000000..d9781e474 --- /dev/null +++ b/mods/ITEMS/mcl_stonecutter/mod.conf @@ -0,0 +1,4 @@ +name = mcl_stonecutter +author = PrairieWind +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 diff --git a/mods/ITEMS/mcl_sus_stew/LICENSE b/mods/ITEMS/mcl_sus_stew/LICENSE new file mode 100644 index 000000000..d41c0bd98 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/LICENSE @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 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/ITEMS/mcl_sus_stew/Note b/mods/ITEMS/mcl_sus_stew/Note new file mode 100644 index 000000000..cbf07b1f8 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/Note @@ -0,0 +1 @@ +The texture for the suspicious stew is from the Minecraft resourcepack "Pixel Perfection Legacy" (https://www.curseforge.com/minecraft/texture-packs/pixel-perfection-legacy), wich is licensed under CC BY-SA 4.0 (Creative Commons license)! \ No newline at end of file diff --git a/mods/ITEMS/mcl_sus_stew/README.md b/mods/ITEMS/mcl_sus_stew/README.md new file mode 100644 index 000000000..374d80b92 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/README.md @@ -0,0 +1,3 @@ +# mcl_sus_stew + +This Mod adds Suspicious Stews for Mineclone \ No newline at end of file diff --git a/mods/ITEMS/mcl_sus_stew/init.lua b/mods/ITEMS/mcl_sus_stew/init.lua new file mode 100644 index 000000000..cfb294532 --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/init.lua @@ -0,0 +1,142 @@ + +-- ____________________________ +--_________________________________________/ 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:lily_of_the_valley" ] = "poison", + [ "mcl_flowers:blue_orchid" ] = "hunger", + [ "mcl_flowers:dandelion" ] = "hunger", + [ "mcl_flowers:cornflower" ] = "jump", + [ "mcl_flowers:oxeye_daisy" ] = "regeneration", + [ "mcl_flowers:poppy" ] = "night_vision" +} + +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) + 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) + return eat(itemstack, placer, pointed_thing) + end, + + ["jump"] = function(itemstack, placer, pointed_thing) + mcl_potions.leaping_func(placer, 1, 6) + return eat(itemstack, placer, pointed_thing) + end, + + ["regeneration"] = function(itemstack, placer, pointed_thing) + mcl_potions.regeneration_func(placer, 1, 8) + return eat(itemstack, placer, pointed_thing) + end, + + ["night_vision"] = function(itemstack, placer, pointed_thing) + mcl_potions.night_vision_func(placer, 1, 5) + return eat(itemstack, placer, pointed_thing) + end, +} +local function get_random_effect() + local keys = {} + for k in pairs(effects) do + table.insert(keys, k) + end + return effects[keys[math.random(#keys)]] +end + +local function eat_stew(itemstack, placer, pointed_thing) + 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 + return "mcl_core:bowl" + end +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 + for _,it in pairs(old_craft_grid) do + if it:get_name() == f then + itemstack:get_meta():set_string("effect",e) + return itemstack + end + end + end +end) + +-- ________________________ +--_________________________________________/ Item Regestration \_________________ +minetest.register_craftitem("mcl_sus_stew:stew",{ + description = "Suspicious Stew", + inventory_image = "sus_stew.png", + stack_max = 1, + on_place = eat_stew, + on_secondary_use = eat_stew, + groups = { food = 2, eatable = 4, can_eat_when_full = 1, not_in_creative_inventory=1,}, + _mcl_saturation = 7.2, +}) + +mcl_hunger.register_food("mcl_sus_stew:stew",6, "mcl_core:bowl") + +--compat with old (mcl5) sus_stew +minetest.register_alias("mcl_sus_stew:poison_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:hunger_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:jump_boost_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:regneration_stew", "mcl_sus_stew:stew") +minetest.register_alias("mcl_sus_stew:night_vision_stew", "mcl_sus_stew:stew") + +-- ______________ +--_________________________________________/ Crafts \________________________________ + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:allium"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:lily_of_the_valley"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:blue_orchid"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:dandelion"} , +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:cornflower"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:oxeye_daisy"}, +}) + +minetest.register_craft({ + type = "shapeless", + output = "mcl_sus_stew:stew", + recipe = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown", "mcl_core:bowl", "mcl_flowers:poppy"}, +}) diff --git a/mods/ITEMS/mcl_sus_stew/mod.conf b/mods/ITEMS/mcl_sus_stew/mod.conf new file mode 100644 index 000000000..c67a120ba --- /dev/null +++ b/mods/ITEMS/mcl_sus_stew/mod.conf @@ -0,0 +1,3 @@ +name = mcl_sus_stew +author = chmodsayshello, cora +depends = mcl_core, mcl_mushrooms, mcl_flowers, mcl_potions, mcl_hunger diff --git a/mods/ITEMS/mcl_throwing/API.md b/mods/ITEMS/mcl_throwing/API.md new file mode 100644 index 000000000..41a47223a --- /dev/null +++ b/mods/ITEMS/mcl_throwing/API.md @@ -0,0 +1,41 @@ +# mcl_throwing + +## mcl_throwing.throw(throw_item, pos, dir, velocity, thrower) +Throw a throwable item. + +* throw_item: itemstring of the throwable item +* pos: initial position of the entity +* dir: direction where the throwable item will be thrown +* velocity: (optional) will overide the default velocity value (can be nil) +* thrower: (optional) player/entity who throw the object (can be nil) + +## mcl_throwing.register_throwable_object(name, entity, velocity) +Register a throwable item. + +* name: itemname of the throwable object +* entity: entity thrown +* velocity: initial velocity of the entity + +## mcl_throwing.dispense_function(stack, dispenserpos, droppos, dropnode, dropdir) +Throw throwable item from dispencer. + +Shouldn't be called directly. + +Must be used in item definition: + +`_on_dispense = mcl_throwing.dispense_function,` + +## mcl_throwing.get_player_throw_function(entity_name, velocity) + +Return a function who handle item throwing (to be used in item definition) + +Handle creative mode, and throw params. + +* entity_name: the name of the entity to throw +* velocity: (optional) velocity overide (can be nil) + +## mcl_throwing.get_staticdata(self) +Must be used in entity def if you want the entity to be saved after unloading mapblock. + +## mcl_throwing.on_activate(self, staticdata, dtime_s) +Must be used in entity def if you want the entity to be saved after unloading mapblock. diff --git a/mods/ITEMS/mcl_throwing/depends.txt b/mods/ITEMS/mcl_throwing/depends.txt deleted file mode 100644 index 2787220ee..000000000 --- a/mods/ITEMS/mcl_throwing/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core? -mcl_mobitems? -doc? -mcl_fishing diff --git a/mods/ITEMS/mcl_throwing/init.lua b/mods/ITEMS/mcl_throwing/init.lua index 5fe34b45e..c468946dd 100644 --- a/mods/ITEMS/mcl_throwing/init.lua +++ b/mods/ITEMS/mcl_throwing/init.lua @@ -1,30 +1,22 @@ mcl_throwing = {} -local S = minetest.get_translator("mcl_throwing") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") -local mod_fishing = minetest.get_modpath("mcl_fishing") +local modpath = minetest.get_modpath(minetest.get_current_modname()) --- +-- -- Snowballs and other throwable items -- local GRAVITY = tonumber(minetest.settings:get("movement_gravity")) -local entity_mapping = { - ["mcl_throwing:flying_bobber"] = "mcl_throwing:flying_bobber_entity", - ["mcl_throwing:snowball"] = "mcl_throwing:snowball_entity", - ["mcl_throwing:egg"] = "mcl_throwing:egg_entity", - ["mcl_throwing:ender_pearl"] = "mcl_throwing:ender_pearl_entity", -} +local entity_mapping = {} +local velocities = {} -local velocities = { - ["mcl_throwing:flying_bobber_entity"] = 5, - ["mcl_throwing:snowball_entity"] = 22, - ["mcl_throwing:egg_entity"] = 22, - ["mcl_throwing:ender_pearl_entity"] = 22, -} +function mcl_throwing.register_throwable_object(name, entity, velocity) + entity_mapping[name] = entity + velocities[name] = velocity +end -mcl_throwing.throw = function(throw_item, pos, dir, velocity, thrower) +function mcl_throwing.throw(throw_item, pos, dir, velocity, thrower) if velocity == nil then velocity = velocities[throw_item] end @@ -44,11 +36,11 @@ mcl_throwing.throw = function(throw_item, pos, dir, velocity, thrower) end -- Throw item -local player_throw_function = function(entity_name, velocity) - local func = function(item, player, pointed_thing) +function mcl_throwing.get_player_throw_function(entity_name, velocity) + local function func(item, player, pointed_thing) local playerpos = player:get_pos() local dir = player:get_look_dir() - local obj = mcl_throwing.throw(item, {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, velocity, player:get_player_name()) + mcl_throwing.throw(item, {x=playerpos.x, y=playerpos.y+1.5, z=playerpos.z}, dir, velocity, player:get_player_name()) if not minetest.is_creative_enabled(player:get_player_name()) then item:take_item() end @@ -57,14 +49,14 @@ local player_throw_function = function(entity_name, velocity) return func end -local dispense_function = function(stack, dispenserpos, droppos, dropnode, dropdir) +function mcl_throwing.dispense_function(stack, dispenserpos, droppos, dropnode, dropdir) -- Launch throwable item local shootpos = vector.add(dispenserpos, vector.multiply(dropdir, 0.51)) mcl_throwing.throw(stack:get_name(), shootpos, dropdir) end -- Staticdata handling because objects may want to be reloaded -local get_staticdata = function(self) +function mcl_throwing.get_staticdata(self) local thrower -- Only save thrower if it's a player name if type(self._thrower) == "string" then @@ -77,7 +69,7 @@ local get_staticdata = function(self) return minetest.serialize(data) end -local on_activate = function(self, staticdata, dtime_s) +function mcl_throwing.on_activate(self, staticdata, dtime_s) local data = minetest.deserialize(staticdata) if data then self._lastpos = data._lastpos @@ -85,374 +77,4 @@ local on_activate = function(self, staticdata, dtime_s) end end --- The snowball entity -local snowball_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_snowball.png"}, - visual_size = {x=0.5, y=0.5}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - _thrower = nil, - - _lastpos={}, -} -local egg_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_egg.png"}, - visual_size = {x=0.45, y=0.45}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - _thrower = nil, - - _lastpos={}, -} --- Ender pearl entity -local pearl_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_throwing_ender_pearl.png"}, - visual_size = {x=0.9, y=0.9}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - - _lastpos={}, - _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl -} - -local flying_bobber_ENTITY={ - physical = false, - timer=0, - textures = {"mcl_fishing_bobber.png"}, --FIXME: Replace with correct texture. - visual_size = {x=0.5, y=0.5}, - collisionbox = {0,0,0,0,0,0}, - pointable = false, - - get_staticdata = get_staticdata, - on_activate = on_activate, - - _lastpos={}, - _thrower = nil, - objtype="fishing", -} - -local check_object_hit = function(self, pos, dmg) - for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do - - local entity = object:get_luaentity() - - if entity - and entity.name ~= self.object:get_luaentity().name then - - if object:is_player() and self._thrower ~= object:get_player_name() then - -- TODO: Deal knockback - self.object:remove() - return true - elseif (entity._cmi_is_mob == true or entity._hittable_by_projectile) and (self._thrower ~= object) then - -- FIXME: Knockback is broken - object:punch(self.object, 1.0, { - full_punch_interval = 1.0, - damage_groups = dmg, - }, nil) - return true - end - end - end - return false -end - -local snowball_particles = function(pos, vel) - local vel = vector.normalize(vector.multiply(vel, -1)) - minetest.add_particlespawner({ - amount = 20, - time = 0.001, - minpos = pos, - maxpos = pos, - minvel = vector.add({x=-2, y=3, z=-2}, vel), - maxvel = vector.add({x=2, y=5, z=2}, vel), - minacc = {x=0, y=-9.81, z=0}, - maxacc = {x=0, y=-9.81, z=0}, - minexptime = 1, - maxexptime = 3, - minsize = 0.7, - maxsize = 0.7, - collisiondetection = true, - collision_removal = true, - object_collision = false, - texture = "weather_pack_snow_snowflake"..math.random(1,2)..".png", - }) -end - --- Snowball on_step()--> called when snowball is moving. -local snowball_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local vel = self.object:get_velocity() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - if (def and def.walkable) or not def then - minetest.sound_play("mcl_throwing_snowball_impact_hard", { pos = pos, max_hear_distance=16, gain=0.7 }, true) - snowball_particles(self._lastpos, vel) - self.object:remove() - return - end - end - - if check_object_hit(self, pos, {snowball_vulnerable = 3}) then - minetest.sound_play("mcl_throwing_snowball_impact_soft", { pos = pos, max_hear_distance=16, gain=0.7 }, true) - snowball_particles(pos, vel) - self.object:remove() - return - end - - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set _lastpos-->Node will be added at last pos outside the node -end - --- Movement function of egg -local egg_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - - -- Destroy when hitting a solid node with chance to spawn chicks - if self._lastpos.x~=nil then - if (def and def.walkable) or not def then - -- 1/8 chance to spawn a chick - -- FIXME: Chicks have a quite good chance to spawn in walls - local r = math.random(1,8) - - -- Turn given object into a child - local make_child= function(object) - local ent = object:get_luaentity() - object:set_properties({ - visual_size = { x = ent.base_size.x/2, y = ent.base_size.y/2 }, - collisionbox = { - ent.base_colbox[1]/2, - ent.base_colbox[2]/2, - ent.base_colbox[3]/2, - ent.base_colbox[4]/2, - ent.base_colbox[5]/2, - ent.base_colbox[6]/2, - } - }) - ent.child = true - end - if r == 1 then - make_child(minetest.add_entity(self._lastpos, "mobs_mc:chicken")) - - -- BONUS ROUND: 1/32 chance to spawn 3 additional chicks - local r = math.random(1,32) - if r == 1 then - local offsets = { - { x=0.7, y=0, z=0 }, - { x=-0.7, y=0, z=-0.7 }, - { x=-0.7, y=0, z=0.7 }, - } - for o=1, 3 do - local pos = vector.add(self._lastpos, offsets[o]) - make_child(minetest.add_entity(pos, "mobs_mc:chicken")) - end - end - end - minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) - self.object:remove() - return - end - end - - -- Destroy when hitting a mob or player (no chick spawning) - if check_object_hit(self, pos) then - minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) - self.object:remove() - return - end - - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - --- Movement function of ender pearl -local pearl_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - pos.y = math.floor(pos.y) - local node = minetest.get_node(pos) - local nn = node.name - local def = minetest.registered_nodes[node.name] - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - local walkable = (def and def.walkable) - - -- No teleport for hitting ignore for now. Otherwise the player could get stuck. - -- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas - if node.name == "ignore" then - self.object:remove() - -- Activate when hitting a solid node or a plant - elseif walkable or nn == "mcl_core:vine" or nn == "mcl_core:deadbush" or minetest.get_item_group(nn, "flower") ~= 0 or minetest.get_item_group(nn, "sapling") ~= 0 or minetest.get_item_group(nn, "plant") ~= 0 or minetest.get_item_group(nn, "mushroom") ~= 0 or not def then - local player = minetest.get_player_by_name(self._thrower) - if player then - -- Teleport and hurt player - - -- First determine good teleport position - local dir = {x=0, y=0, z=0} - - local v = self.object:get_velocity() - if walkable then - local vc = table.copy(v) -- vector for calculating - -- Node is walkable, we have to find a place somewhere outside of that node - vc = vector.normalize(vc) - - -- Zero-out the two axes with a lower absolute value than - -- the axis with the strongest force - local lv, ld - lv, ld = math.abs(vc.y), "y" - if math.abs(vc.x) > lv then - lv, ld = math.abs(vc.x), "x" - end - if math.abs(vc.z) > lv then - lv, ld = math.abs(vc.z), "z" - end - if ld ~= "x" then vc.x = 0 end - if ld ~= "y" then vc.y = 0 end - if ld ~= "z" then vc.z = 0 end - - -- Final tweaks to the teleporting pos, based on direction - -- Impact from the side - dir.x = vc.x * -1 - dir.z = vc.z * -1 - - -- Special case: top or bottom of node - if vc.y > 0 then - -- We need more space when impact is from below - dir.y = -2.3 - elseif vc.y < 0 then - -- Standing on top - dir.y = 0.5 - end - end - -- If node was not walkable, no modification to pos is made. - - -- Final teleportation position - local telepos = vector.add(pos, dir) - local telenode = minetest.get_node(telepos) - - --[[ It may be possible that telepos is walkable due to the algorithm. - Especially when the ender pearl is faster horizontally than vertical. - This applies final fixing, just to be sure we're not in a walkable node ]] - if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then - if v.y < 0 then - telepos.y = telepos.y + 0.5 - else - telepos.y = telepos.y - 2.3 - end - end - - local oldpos = player:get_pos() - -- Teleport and hurt player - player:set_pos(telepos) - player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" }) - - -- 5% chance to spawn endermite at the player's origin - local r = math.random(1,20) - if r == 1 then - minetest.add_entity(oldpos, "mobs_mc:endermite") - end - - end - self.object:remove() - return - end - end - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - --- Movement function of flying bobber -local flying_bobber_on_step = function(self, dtime) - self.timer=self.timer+dtime - local pos = self.object:get_pos() - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - --local player = minetest.get_player_by_name(self._thrower) - - -- Destroy when hitting a solid node - if self._lastpos.x~=nil then - if (def and (def.walkable or def.liquidtype == "flowing" or def.liquidtype == "source")) or not def then - local make_child= function(object) - local ent = object:get_luaentity() - ent.player = self._thrower - ent.child = true - end - make_child(minetest.add_entity(self._lastpos, "mcl_fishing:bobber_entity")) - self.object:remove() - return - end - end - self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node -end - -snowball_ENTITY.on_step = snowball_on_step -egg_ENTITY.on_step = egg_on_step -pearl_ENTITY.on_step = pearl_on_step -flying_bobber_ENTITY.on_step = flying_bobber_on_step - -minetest.register_entity("mcl_throwing:snowball_entity", snowball_ENTITY) -minetest.register_entity("mcl_throwing:egg_entity", egg_ENTITY) -minetest.register_entity("mcl_throwing:ender_pearl_entity", pearl_ENTITY) -minetest.register_entity("mcl_throwing:flying_bobber_entity", flying_bobber_ENTITY) - -local how_to_throw = S("Use the punch key to throw.") - --- Snowball -minetest.register_craftitem("mcl_throwing:snowball", { - description = S("Snowball"), - _tt_help = S("Throwable"), - _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, - groups = { weapon_ranged = 1 }, - on_use = player_throw_function("mcl_throwing:snowball_entity"), - _on_dispense = dispense_function, -}) - --- Egg -minetest.register_craftitem("mcl_throwing:egg", { - description = S("Egg"), - _tt_help = S("Throwable").."\n"..S("Chance to hatch chicks when broken"), - _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, - on_use = player_throw_function("mcl_throwing:egg_entity"), - _on_dispense = dispense_function, - groups = { craftitem = 1 }, -}) - --- Ender Pearl -minetest.register_craftitem("mcl_throwing:ender_pearl", { - description = S("Ender Pearl"), - _tt_help = S("Throwable").."\n"..minetest.colorize("#FFFF00", S("Teleports you on impact for cost of 5 HP")), - _doc_items_longdesc = S("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."), - _doc_items_usagehelp = how_to_throw, - wield_image = "mcl_throwing_ender_pearl.png", - inventory_image = "mcl_throwing_ender_pearl.png", - stack_max = 16, - on_use = player_throw_function("mcl_throwing:ender_pearl_entity"), - groups = { transport = 1 }, -}) - +dofile(modpath.."/register.lua") \ No newline at end of file diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr new file mode 100644 index 000000000..983002598 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.ja.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_throwing +@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.=雪玉は、投げたりディスペンサーから発射したりして楽しめます。雪玉を何かにぶつけても何も起こりません。 +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ヒットポイントずつダメージを受けます。 +Throwable=投擲可能 +Chance to hatch chicks when broken=壊れてもヒナが孵化するチャンス +Teleports you on impact for cost of 5 HP=HPを5消費し衝撃でテレポート diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pl.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pl.tr new file mode 100644 index 000000000..e27970424 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.pl.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_throwing +@1 used the ender pearl too often.=@1 zbyt często używała perły kresu. +Use the punch key to throw.=Użyj przycisku ataku by rzucić. +Snowball=Śnieżka +Snowballs can be thrown or launched from a dispenser for fun. Hitting something with a snowball does nothing.=Śnieżki mogą być rzucone lub wystrzelone z dozownika dla zabawy. Uderzenie czegoś śnieżką niczego nie daje. +Egg=Jajo +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.=Jaja mogą być rzucone lub wystrzelone z dozownika i rozbiją się przy uderzeniu. Jest mała szansa, że 1 lub nawet 4 kurczęta wyskoczą z jaja. +Ender Pearl=Perła kresu +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.=Perła kresu jest przedmiotem, który można wykorzystać do teleportacji kosztem zdrowia. Może być rzucona, a rzucający zostanie przeteleportowany w miejsce gdzie uderzyła ona stały blok lub roślinę. +Throwable=Można rzucać +Chance to hatch chicks when broken=Szansa na wyklucie kurcząt po rozbiciu +Teleports you on impact for cost of 5 HP=Teleportuje przy uderzeniu za 5 HP diff --git a/mods/ITEMS/mcl_throwing/locale/mcl_throwing.zh_TW.tr b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.zh_TW.tr new file mode 100644 index 000000000..3ee220925 --- /dev/null +++ b/mods/ITEMS/mcl_throwing/locale/mcl_throwing.zh_TW.tr @@ -0,0 +1,12 @@ +# textdomain: mcl_throwing +@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.=雪球可以被扔出或從發射器中發射出去取樂。用雪球打東西沒有任何作用。 +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點生命值。 +Throwable=可扔出 +Chance to hatch chicks when broken=破碎時有可能孵化小雞 +Teleports you on impact for cost of 5 HP=損失5點生命值以傳送 diff --git a/mods/ITEMS/mcl_throwing/mod.conf b/mods/ITEMS/mcl_throwing/mod.conf index 117ca80a7..18248e76f 100644 --- a/mods/ITEMS/mcl_throwing/mod.conf +++ b/mods/ITEMS/mcl_throwing/mod.conf @@ -1 +1,3 @@ name = mcl_throwing +depends = mcl_colors +optional_depends = mcl_core, mcl_mobitems, doc, mcl_target diff --git a/mods/ITEMS/mcl_throwing/register.lua b/mods/ITEMS/mcl_throwing/register.lua new file mode 100644 index 000000000..43dedd33b --- /dev/null +++ b/mods/ITEMS/mcl_throwing/register.lua @@ -0,0 +1,330 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local math = math +local vector = vector + +local mod_target = minetest.get_modpath("mcl_target") + +-- The snowball entity +local snowball_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_snowball.png"}, + visual_size = {x=0.5, y=0.5}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, + _thrower = nil, + + _lastpos={}, +} + +local egg_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_egg.png"}, + visual_size = {x=0.45, y=0.45}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, + _thrower = nil, + + _lastpos={}, +} + +-- Ender pearl entity +local pearl_ENTITY={ + physical = false, + timer=0, + textures = {"mcl_throwing_ender_pearl.png"}, + visual_size = {x=0.9, y=0.9}, + collisionbox = {0,0,0,0,0,0}, + pointable = false, + + get_staticdata = mcl_throwing.get_staticdata, + on_activate = mcl_throwing.on_activate, + + _lastpos={}, + _thrower = nil, -- Player ObjectRef of the player who threw the ender pearl +} + +local function check_object_hit(self, pos, dmg) + for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.5)) do + + local entity = object:get_luaentity() + + if entity + and entity.name ~= self.object:get_luaentity().name then + + if object:is_player() and self._thrower ~= object:get_player_name() then + self.object:remove() + return true + elseif (entity.is_mob == true or entity._hittable_by_projectile) and (self._thrower ~= object) then + object:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = dmg, + }, nil) + return true + end + end + end + return false +end + +local function snowball_particles(pos, vel) + local vel = vector.normalize(vector.multiply(vel, -1)) + minetest.add_particlespawner({ + amount = 20, + time = 0.001, + minpos = pos, + maxpos = pos, + minvel = vector.add({x=-2, y=3, z=-2}, vel), + maxvel = vector.add({x=2, y=5, z=2}, vel), + minacc = {x=0, y=-9.81, z=0}, + maxacc = {x=0, y=-9.81, z=0}, + minexptime = 1, + maxexptime = 3, + minsize = 0.7, + maxsize = 0.7, + collisiondetection = true, + collision_removal = true, + object_collision = false, + texture = "weather_pack_snow_snowflake"..math.random(1,2)..".png", + }) +end + +-- Snowball on_step()--> called when snowball is moving. +local function snowball_on_step(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:get_pos() + local vel = self.object:get_velocity() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + if (def and def.walkable) or not def then + minetest.sound_play("mcl_throwing_snowball_impact_hard", { pos = pos, max_hear_distance=16, gain=0.7 }, true) + snowball_particles(self._lastpos, vel) + self.object:remove() + if mod_target and node.name == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + end + return + end + end + if check_object_hit(self, pos, {snowball_vulnerable = 3}) then + minetest.sound_play("mcl_throwing_snowball_impact_soft", { pos = pos, max_hear_distance=16, gain=0.7 }, true) + snowball_particles(pos, vel) + self.object:remove() + return + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set _lastpos-->Node will be added at last pos outside the node +end + +-- Movement function of egg +local function egg_on_step(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:get_pos() + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + + -- Destroy when hitting a solid node with chance to spawn chicks + if self._lastpos.x then + if (def and def.walkable) or not def then + -- 1/8 chance to spawn a chick + -- FIXME: Chicks have a quite good chance to spawn in walls + local r = math.random(1,8) + + if r == 1 then + mcl_mobs.spawn_child(self._lastpos, "mobs_mc:chicken") + + -- BONUS ROUND: 1/32 chance to spawn 3 additional chicks + local r = math.random(1,32) + if r == 1 then + local offsets = { + { x=0.7, y=0, z=0 }, + { x=-0.7, y=0, z=-0.7 }, + { x=-0.7, y=0, z=0.7 }, + } + for o=1, 3 do + local pos = vector.add(self._lastpos, offsets[o]) + mcl_mobs.spawn_child(pos, "mobs_mc:chicken") + end + end + end + minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) + self.object:remove() + if mod_target and node.name == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + end + return + end + end + + -- Destroy when hitting a mob or player (no chick spawning) + if check_object_hit(self, pos, 0) then + minetest.sound_play("mcl_throwing_egg_impact", { pos = self.object:get_pos(), max_hear_distance=10, gain=0.5 }, true) + self.object:remove() + return + end + + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +-- Movement function of ender pearl +local function pearl_on_step(self, dtime) + self.timer = self.timer + dtime + local pos = self.object:get_pos() + pos.y = math.floor(pos.y) + local node = minetest.get_node(pos) + local nn = node.name + local def = minetest.registered_nodes[node.name] + + -- Destroy when hitting a solid node + if self._lastpos.x~=nil then + local walkable = (def and def.walkable) + + -- No teleport for hitting ignore for now. Otherwise the player could get stuck. + -- FIXME: This also means the player loses an ender pearl for throwing into unloaded areas + if node.name == "ignore" then + self.object:remove() + -- Activate when hitting a solid node or a plant + elseif walkable or nn == "mcl_core:vine" or nn == "mcl_core:deadbush" or minetest.get_item_group(nn, "flower") ~= 0 or minetest.get_item_group(nn, "sapling") ~= 0 or minetest.get_item_group(nn, "plant") ~= 0 or minetest.get_item_group(nn, "mushroom") ~= 0 or not def then + local player = self._thrower and minetest.get_player_by_name(self._thrower) + if player then + -- Teleport and hurt player + + -- First determine good teleport position + local dir = {x=0, y=0, z=0} + + local v = self.object:get_velocity() + if walkable then + local vc = table.copy(v) -- vector for calculating + -- Node is walkable, we have to find a place somewhere outside of that node + vc = vector.normalize(vc) + + -- Zero-out the two axes with a lower absolute value than + -- the axis with the strongest force + local lv, ld + lv, ld = math.abs(vc.y), "y" + if math.abs(vc.x) > lv then + lv, ld = math.abs(vc.x), "x" + end + if math.abs(vc.z) > lv then + ld = "z" --math.abs(vc.z) + end + if ld ~= "x" then vc.x = 0 end + if ld ~= "y" then vc.y = 0 end + if ld ~= "z" then vc.z = 0 end + + -- Final tweaks to the teleporting pos, based on direction + -- Impact from the side + dir.x = vc.x * -1 + dir.z = vc.z * -1 + + -- Special case: top or bottom of node + if vc.y > 0 then + -- We need more space when impact is from below + dir.y = -2.3 + elseif vc.y < 0 then + -- Standing on top + dir.y = 0.5 + end + end + -- If node was not walkable, no modification to pos is made. + + -- Final teleportation position + local telepos = vector.add(pos, dir) + local telenode = minetest.get_node(telepos) + + --[[ It may be possible that telepos is walkable due to the algorithm. + Especially when the ender pearl is faster horizontally than vertical. + This applies final fixing, just to be sure we're not in a walkable node ]] + if not minetest.registered_nodes[telenode.name] or minetest.registered_nodes[telenode.name].walkable then + if v.y < 0 then + telepos.y = telepos.y + 0.5 + else + telepos.y = telepos.y - 2.3 + end + end + + local oldpos = player:get_pos() + -- Teleport and hurt player + player:set_pos(telepos) + player:set_hp(player:get_hp() - 5, { type = "fall", from = "mod" }) + + -- 5% chance to spawn endermite at the player's origin + local r = math.random(1,20) + if r == 1 then + minetest.add_entity(oldpos, "mobs_mc:endermite") + end + + end + self.object:remove() + if mod_target and node.name == "mcl_target:target_off" then + mcl_target.hit(vector.round(pos), 0.4) --4 redstone ticks + end + return + end + end + self._lastpos={x=pos.x, y=pos.y, z=pos.z} -- Set lastpos-->Node will be added at last pos outside the node +end + +snowball_ENTITY.on_step = snowball_on_step +egg_ENTITY.on_step = egg_on_step +pearl_ENTITY.on_step = pearl_on_step + +minetest.register_entity("mcl_throwing:snowball_entity", snowball_ENTITY) +minetest.register_entity("mcl_throwing:egg_entity", egg_ENTITY) +minetest.register_entity("mcl_throwing:ender_pearl_entity", pearl_ENTITY) + + +local how_to_throw = S("Use the punch key to throw.") + +-- Snowball +minetest.register_craftitem("mcl_throwing:snowball", { + description = S("Snowball"), + _tt_help = S("Throwable"), + _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, + groups = { weapon_ranged = 1 }, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:snowball_entity"), + _on_dispense = mcl_throwing.dispense_function, +}) + +-- Egg +minetest.register_craftitem("mcl_throwing:egg", { + description = S("Egg"), + _tt_help = S("Throwable").."\n"..S("Chance to hatch chicks when broken"), + _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, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:egg_entity"), + _on_dispense = mcl_throwing.dispense_function, + groups = { craftitem = 1 }, +}) + +-- Ender Pearl +minetest.register_craftitem("mcl_throwing:ender_pearl", { + description = S("Ender Pearl"), + _tt_help = S("Throwable").."\n"..minetest.colorize(mcl_colors.YELLOW, S("Teleports you on impact for cost of 5 HP")), + _doc_items_longdesc = S("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."), + _doc_items_usagehelp = how_to_throw, + wield_image = "mcl_throwing_ender_pearl.png", + inventory_image = "mcl_throwing_ender_pearl.png", + stack_max = 16, + on_use = mcl_throwing.get_player_throw_function("mcl_throwing:ender_pearl_entity"), + groups = { transport = 1 }, +}) + +mcl_throwing.register_throwable_object("mcl_throwing:snowball", "mcl_throwing:snowball_entity", 22) +mcl_throwing.register_throwable_object("mcl_throwing:egg", "mcl_throwing:egg_entity", 22) +mcl_throwing.register_throwable_object("mcl_throwing:ender_pearl", "mcl_throwing:ender_pearl_entity", 22) diff --git a/mods/ITEMS/mcl_throwing/textures/mcl_throwing_ender_pearl.png b/mods/ITEMS/mcl_throwing/textures/mcl_throwing_ender_pearl.png deleted file mode 100644 index 61e1786d2..000000000 Binary files a/mods/ITEMS/mcl_throwing/textures/mcl_throwing_ender_pearl.png and /dev/null differ diff --git a/mods/ITEMS/mcl_throwing/textures/mcl_throwing_snowball.png b/mods/ITEMS/mcl_throwing/textures/mcl_throwing_snowball.png deleted file mode 100644 index 5fcc76f2f..000000000 Binary files a/mods/ITEMS/mcl_throwing/textures/mcl_throwing_snowball.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tnt/depends.txt b/mods/ITEMS/mcl_tnt/depends.txt deleted file mode 100644 index 6a2354764..000000000 --- a/mods/ITEMS/mcl_tnt/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_explosions -mcl_particles -mcl_sounds? -mcl_mobitems? -mcl_death_messages? -doc_identifier? -mesecons? diff --git a/mods/ITEMS/mcl_tnt/init.lua b/mods/ITEMS/mcl_tnt/init.lua index ef4fb33c2..4d7be3125 100644 --- a/mods/ITEMS/mcl_tnt/init.lua +++ b/mods/ITEMS/mcl_tnt/init.lua @@ -1,78 +1,99 @@ -local S = minetest.get_translator("mcl_tnt") -local tnt_griefing = minetest.settings:get_bool("mcl_tnt_griefing", true) - -local mod_death_messages = minetest.get_modpath("mcl_death_messages") - -local function spawn_tnt(pos, entname) - minetest.sound_play("tnt_ignite", {pos = pos,gain = 1.0,max_hear_distance = 15,}, true) - local tnt = minetest.add_entity(pos, entname) - tnt:set_armor_groups({immortal=1}) - return tnt -end +local S = minetest.get_translator(minetest.get_current_modname()) +local explosions_griefing = minetest.settings:get_bool("mcl_explosions_griefing", true) tnt = {} -tnt.ignite = function(pos) + +tnt.BOOMTIMER = 4 +tnt.BLINKTIMER = 0.25 + +---@param pos Vector +---@param entname string +---@return ObjectRef? +local function spawn_tnt(pos, entname) + minetest.sound_play("tnt_ignite", { pos = pos, gain = 1.0, max_hear_distance = 15 }, true) + local ent = minetest.add_entity(pos, entname) + if ent then + ent:set_armor_groups({ immortal = 1 }) + end + return ent +end + +---@param pos Vector +---@return ObjectRef? +function tnt.ignite(pos) minetest.remove_node(pos) local e = spawn_tnt(pos, "mcl_tnt:tnt") minetest.check_for_falling(pos) return e end --- Add smoke particle of entity at pos. --- Intended to be called every step -tnt.smoke_step = function(pos) +---Add smoke particle of entity at pos. +--- +---Intended to be called every step. +---@param pos Vector +function tnt.smoke_step(pos) minetest.add_particle({ - pos = {x=pos.x,y=pos.y+0.5,z=pos.z}, - velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1), - acceleration = vector.new(0, -0.1, 0), - expirationtime = 0.15 + math.random() * 0.25, - size = 1.0 + math.random(), + pos = vector.offset(pos, 0, 0.5, 0), + velocity = vector.new(math.random() * 0.2 - 0.1, 1.0 + math.random(), math.random() * 0.2 - 0.1), + acceleration = vector.new(0, -0.1, 0), + expirationtime = 0.15 + math.random() * 0.25, + size = 1.0 + math.random(), collisiondetection = false, - texture = "mcl_particles_smoke.png" + texture = "mcl_particles_smoke.png" }) end -tnt.BOOMTIMER = 4 -tnt.BLINKTIMER = 0.25 - local TNT_RANGE = 3 local sounds if minetest.get_modpath("mcl_sounds") then sounds = mcl_sounds.node_sound_wood_defaults() end + local tnt_mesecons if minetest.get_modpath("mesecons") then - tnt_mesecons = {effector = { - action_on = tnt.ignite, - rules = mesecon.rules.alldirs, - }} + tnt_mesecons = { + effector = { + action_on = tnt.ignite, + rules = mesecon.rules.alldirs, + }, + } end local longdesc -if tnt_griefing then - longdesc = S("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.", TNT_RANGE) +if explosions_griefing then + longdesc = S("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." + , TNT_RANGE) else - longdesc = S("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.", TNT_RANGE) + longdesc = S("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." + , TNT_RANGE) end minetest.register_node("mcl_tnt:tnt", { - tiles = {"default_tnt_top.png", "default_tnt_bottom.png", - "default_tnt_side.png", "default_tnt_side.png", - "default_tnt_side.png", "default_tnt_side.png"}, + tiles = { + "default_tnt_top.png", + "default_tnt_bottom.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + }, is_ground_content = false, stack_max = 64, description = S("TNT"), paramtype = "light", sunlight_propagates = true, - _tt_help = S("Ignited by tools, explosions, fire, lava, redstone power").."\n"..S("Explosion radius: @1", tostring(TNT_RANGE)), + _tt_help = S("Ignited by tools, explosions, fire, lava, redstone power") .. + "\n" .. S("Explosion radius: @1", tostring(TNT_RANGE)), _doc_items_longdesc = longdesc, _doc_items_usagehelp = S("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."), - groups = { dig_immediate = 3, tnt = 1, enderman_takable=1, flammable=-1 }, + groups = { dig_immediate = 3, tnt = 1, enderman_takable = 1, flammable = -1 }, mesecons = tnt_mesecons, - on_blast = function(pos) - local e = tnt.ignite(pos) - e:get_luaentity().timer = tnt.BOOMTIMER - (0.5 + math.random()) + on_blast = function(pos, _) + local e = tnt.ignite(pos) + if e then + e:get_luaentity().timer = tnt.BOOMTIMER - (0.5 + math.random()) + end end, _on_ignite = function(player, pointed_thing) tnt.ignite(pointed_thing.under) @@ -85,7 +106,7 @@ minetest.register_node("mcl_tnt:tnt", { _on_dispense = function(stack, pos, droppos, dropnode, dropdir) -- Place and ignite TNT if minetest.registered_nodes[dropnode.name].buildable_to then - minetest.set_node(droppos, {name = stack:get_name()}) + minetest.set_node(droppos, { name = stack:get_name() }) tnt.ignite(droppos) end end, @@ -95,35 +116,41 @@ minetest.register_node("mcl_tnt:tnt", { local TNT = { -- Static definition physical = true, -- Collides with things - --weight = -100, - collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5}, + --weight = -100, + collisionbox = { -0.5, -0.5, -0.5, 0.5, 0.5, 0.5 }, visual = "cube", - textures = {"default_tnt_top.png", "default_tnt_bottom.png", - "default_tnt_side.png", "default_tnt_side.png", - "default_tnt_side.png", "default_tnt_side.png"}, + textures = { + "default_tnt_top.png", + "default_tnt_bottom.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + "default_tnt_side.png", + }, -- Initial value for our timer timer = 0, blinktimer = 0, tnt_knockback = true, - blinkstatus = true,} + blinkstatus = true, +} -function TNT:on_activate(staticdata) - local phi = math.random(0, 65535) / 65535 * 2*math.pi +function TNT:on_activate(_, _) + local phi = math.random(0, 65535) / 65535 * 2 * math.pi local hdir_x = math.cos(phi) * 0.02 local hdir_z = math.sin(phi) * 0.02 - self.object:set_velocity({x=hdir_x, y=2, z=hdir_z}) - self.object:set_acceleration({x=0, y=-10, z=0}) + self.object:set_velocity(vector.new(hdir_x, 2, hdir_z)) + self.object:set_acceleration(vector.new(0, -10, 0)) self.object:set_texture_mod("^mcl_tnt_blink.png") end -local function add_effects(pos, radius, drops) +--[[local function add_effects(pos, radius, drops) minetest.add_particlespawner({ amount = 64, time = 0.5, minpos = vector.subtract(pos, radius / 2), maxpos = vector.add(pos, radius / 2), - minvel = {x = -10, y = -10, z = -10}, - maxvel = {x = 10, y = 10, z = 10}, + minvel = vector.new(-10, -10, -10), + maxvel = vector.new(10, 10, 10), minacc = vector.new(), maxacc = vector.new(), minexptime = 1, @@ -153,9 +180,9 @@ local function add_effects(pos, radius, drops) time = 0.1, minpos = vector.subtract(pos, radius / 2), maxpos = vector.add(pos, radius / 2), - minvel = {x = -3, y = 0, z = -3}, - maxvel = {x = 3, y = 5, z = 3}, - minacc = {x = 0, y = -10, z = 0}, + minvel = vector.new(-3, 0, -3), + maxvel = vector.new(3, 5, 3), + minacc = vector.new(0, -10, 0), minexptime = 0.8, maxexptime = 2.0, minsize = radius * 0.66, @@ -163,9 +190,9 @@ local function add_effects(pos, radius, drops) texture = texture, collisiondetection = true, }) -end +end]] -function TNT:on_step(dtime) +function TNT:on_step(dtime, _) local pos = self.object:get_pos() tnt.smoke_step(pos) self.timer = self.timer + dtime @@ -180,7 +207,7 @@ function TNT:on_step(dtime) self.blinkstatus = not self.blinkstatus end if self.timer > tnt.BOOMTIMER then - mcl_explosions.explode(self.object:get_pos(), 4, { drop_chance = 1.0 }, self.object) + mcl_explosions.explode(self.object:get_pos(), 4, {}, self.object) self.object:remove() end end @@ -191,10 +218,10 @@ if minetest.get_modpath("mcl_mobitems") then minetest.register_craft({ output = "mcl_tnt:tnt", recipe = { - {'mcl_mobitems:gunpowder','group:sand','mcl_mobitems:gunpowder'}, - {'group:sand','mcl_mobitems:gunpowder','group:sand'}, - {'mcl_mobitems:gunpowder','group:sand','mcl_mobitems:gunpowder'} - } + { "mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder" }, + { "group:sand", "mcl_mobitems:gunpowder", "group:sand" }, + { "mcl_mobitems:gunpowder", "group:sand", "mcl_mobitems:gunpowder" } + }, }) end diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.es.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.es.tr index 81d30dcd7..a226b5bcb 100644 --- a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.es.tr +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.es.tr @@ -3,3 +3,5 @@ TNT=Dinamita 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.=Un artefacto explosivo. Cuando explota, dañará a los seres vivos y destruirá los bloques a su alrededor. La dinamita tiene un radio de explosión de @1. Con una pequeña posibilidad, los bloques pueden caer como un elemento (como si se extrajera) en lugar de ser destruidos. La dinamita puede encenderse con herramientas, explosiones, fuego, lava y señales de redstone. 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.=Coloque el dinamita y enciéndalo con uno de los métodos anteriores. Aléjese rápidamente a una distancia segura. La dinamita comenzará a verse afectada por la gravedad y explotará en 4 segundos. +Ignited by tools, explosions, fire, lava, redstone power=Encendida por herramientas, explosiones, fuego, lava, y energía de redstone +Explosion radius: @1=Radio de exposión: @1 diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr new file mode 100644 index 000000000..fbb2e76b3 --- /dev/null +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_tnt +@1 was caught in an explosion.=@1 は爆発に巻き込まれました。 +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.=爆破装置です。爆発すると、生物を傷つけ、周囲のブロックを破壊します。 TNTの爆発半径は@1です。 小確率で、ブロックは破壊されずにアイテムとして(採掘されるように)ドロップすることがあります。TNTは道具、爆発、火、溶岩、レッドストーン信号で着火できます。 +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.=爆破装置です。爆発すると、生物を傷つけます。TNTの爆発半径は@1です。 TNTは道具、爆発、火、溶岩、レッドストーン信号で着火できます。 +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.=TNTを設置し、上記のいずれかの方法で点火します。速やかに安全な距離をとって。TNTは重力の影響を受け始め、4秒後に爆発します。 +Ignited by tools, explosions, fire, lava, redstone power=道具、爆発、火、溶岩、レッドストーン動力で点火 +Explosion radius: @1=爆発半径: @1 diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pl.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pl.tr new file mode 100644 index 000000000..39e520684 --- /dev/null +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_tnt +@1 was caught in an explosion.=@1 została wysadzona. +TNT=Trotyl +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.=Wybuchowy materiał. Gdy wybucha rani żywe istoty w pobliżu i niszczy pobliskie bloki. Trotyl ma promień wybuchu równy @1. Trotyl może być zapalony narzędziami, eksplozjami, ogniem, lawą i energią z czerwienitu. +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.=Materiał wybuchowy Gdy wybucha rani żywe istoty. Trotyl ma promień wybuchu równy @1. Trotyl może być zapalony narzędziami, eksplozjami, ogniem, lawą i energią z czerwienitu. +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.=Postaw trotyl i zapal go za pomocą metod opisanych powyżej. Szybko oddal się na bezpieczny dystans. Na trotyl zacznie działać grawitacja, a po 4 sekundach wybuchnie. +Ignited by tools, explosions, fire, lava, redstone power=Zapalany przez narzędzia, eksplozję, ogień lawę, energię z czerwienitu +Explosion radius: @1=Promień wybuchu: @1 diff --git a/mods/ITEMS/mcl_tnt/locale/mcl_tnt.zh_TW.tr b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.zh_TW.tr new file mode 100644 index 000000000..aaa4c1e52 --- /dev/null +++ b/mods/ITEMS/mcl_tnt/locale/mcl_tnt.zh_TW.tr @@ -0,0 +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.=一個爆炸性裝置。當它爆炸時,會傷害生物,並摧毀周圍的方塊。TNT的爆炸半徑為@1。有很小的機率,方塊可能會作為物品掉落(就像被開採一樣)而不是被摧毀。TNT可以被工具、爆炸、火、熔岩和紅石信號點燃。 +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.=一個爆炸性裝置。當它爆炸時,會傷害生物,並摧毀周圍的方塊。TNT的爆炸半徑為@1。TNT可以被工具、爆炸、火、熔岩和紅石信號點燃。 +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.=放置TNT,並用上述方法之一點燃它。迅速和TNT保持安全距離。TNT將開始受到重力的影響,並在4秒內爆炸。 +Ignited by tools, explosions, fire, lava, redstone power=被工具、爆炸、火、熔岩和紅石信號點燃。 +Explosion radius: @1=爆炸半徑:@1 diff --git a/mods/ITEMS/mcl_tnt/mod.conf b/mods/ITEMS/mcl_tnt/mod.conf index 96d4584cf..2e90ddb80 100644 --- a/mods/ITEMS/mcl_tnt/mod.conf +++ b/mods/ITEMS/mcl_tnt/mod.conf @@ -1 +1,3 @@ name = mcl_tnt +depends = mcl_explosions, mcl_particles +optional_depends = mcl_sounds, mcl_mobitems, doc_identifier, mesecons diff --git a/mods/ITEMS/mcl_tnt/textures/default_tnt_bottom.png b/mods/ITEMS/mcl_tnt/textures/default_tnt_bottom.png deleted file mode 100644 index 61b911be9..000000000 Binary files a/mods/ITEMS/mcl_tnt/textures/default_tnt_bottom.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tnt/textures/default_tnt_side.png b/mods/ITEMS/mcl_tnt/textures/default_tnt_side.png deleted file mode 100644 index 8eda266e6..000000000 Binary files a/mods/ITEMS/mcl_tnt/textures/default_tnt_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tnt/textures/default_tnt_top.png b/mods/ITEMS/mcl_tnt/textures/default_tnt_top.png deleted file mode 100644 index b8f8d39a6..000000000 Binary files a/mods/ITEMS/mcl_tnt/textures/default_tnt_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tnt/textures/mcl_tnt_blink.png b/mods/ITEMS/mcl_tnt/textures/mcl_tnt_blink.png deleted file mode 100644 index b6739757d..000000000 Binary files a/mods/ITEMS/mcl_tnt/textures/mcl_tnt_blink.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tools/crafting.lua b/mods/ITEMS/mcl_tools/crafting.lua index 00d378d7c..07032b184 100644 --- a/mods/ITEMS/mcl_tools/crafting.lua +++ b/mods/ITEMS/mcl_tools/crafting.lua @@ -1,235 +1,235 @@ minetest.register_craft({ - output = 'mcl_tools:pick_wood', + output = "mcl_tools:pick_wood", recipe = { - {'group:wood', 'group:wood', 'group:wood'}, - {'', 'mcl_core:stick', ''}, - {'', 'mcl_core:stick', ''}, + {"group:wood", "group:wood", "group:wood"}, + {"", "mcl_core:stick", ""}, + {"", "mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:pick_stone', + output = "mcl_tools:pick_stone", recipe = { - {'mcl_core:cobble', 'mcl_core:cobble', 'mcl_core:cobble'}, - {'', 'mcl_core:stick', ''}, - {'', 'mcl_core:stick', ''}, + {"group:cobble", "group:cobble", "group:cobble"}, + {"", "mcl_core:stick", ""}, + {"", "mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:pick_iron', + output = "mcl_tools:pick_iron", recipe = { - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'', 'mcl_core:stick', ''}, - {'', 'mcl_core:stick', ''}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"", "mcl_core:stick", ""}, + {"", "mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:pick_gold', + output = "mcl_tools:pick_gold", recipe = { - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, - {'', 'mcl_core:stick', ''}, - {'', 'mcl_core:stick', ''}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"", "mcl_core:stick", ""}, + {"", "mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:pick_diamond', + output = "mcl_tools:pick_diamond", recipe = { - {'mcl_core:diamond', 'mcl_core:diamond', 'mcl_core:diamond'}, - {'', 'mcl_core:stick', ''}, - {'', 'mcl_core:stick', ''}, + {"mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond"}, + {"", "mcl_core:stick", ""}, + {"", "mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:shovel_wood', + output = "mcl_tools:shovel_wood", recipe = { - {'group:wood'}, - {'mcl_core:stick'}, - {'mcl_core:stick'}, + {"group:wood"}, + {"mcl_core:stick"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:shovel_stone', + output = "mcl_tools:shovel_stone", recipe = { - {'mcl_core:cobble'}, - {'mcl_core:stick'}, - {'mcl_core:stick'}, + {"group:cobble"}, + {"mcl_core:stick"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:shovel_iron', + output = "mcl_tools:shovel_iron", recipe = { - {'mcl_core:iron_ingot'}, - {'mcl_core:stick'}, - {'mcl_core:stick'}, + {"mcl_core:iron_ingot"}, + {"mcl_core:stick"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:shovel_gold', + output = "mcl_tools:shovel_gold", recipe = { - {'mcl_core:gold_ingot'}, - {'mcl_core:stick'}, - {'mcl_core:stick'}, + {"mcl_core:gold_ingot"}, + {"mcl_core:stick"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:shovel_diamond', + output = "mcl_tools:shovel_diamond", recipe = { - {'mcl_core:diamond'}, - {'mcl_core:stick'}, - {'mcl_core:stick'}, + {"mcl_core:diamond"}, + {"mcl_core:stick"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_wood', + output = "mcl_tools:axe_wood", recipe = { - {'group:wood', 'group:wood'}, - {'group:wood', 'mcl_core:stick'}, - {'', 'mcl_core:stick'}, + {"group:wood", "group:wood"}, + {"group:wood", "mcl_core:stick"}, + {"", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_wood', + output = "mcl_tools:axe_wood", recipe = { - {'group:wood', 'group:wood'}, - {'mcl_core:stick', 'group:wood'}, - {'mcl_core:stick', ''}, + {"group:wood", "group:wood"}, + {"mcl_core:stick", "group:wood"}, + {"mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_stone', + output = "mcl_tools:axe_stone", recipe = { - {'mcl_core:cobble', 'mcl_core:cobble'}, - {'mcl_core:cobble', 'mcl_core:stick'}, - {'', 'mcl_core:stick'}, + {"group:cobble", "group:cobble"}, + {"group:cobble", "mcl_core:stick"}, + {"", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_stone', + output = "mcl_tools:axe_stone", recipe = { - {'mcl_core:cobble', 'mcl_core:cobble'}, - {'mcl_core:stick', 'mcl_core:cobble'}, - {'mcl_core:stick', ''}, + {"group:cobble", "group:cobble"}, + {"mcl_core:stick", "group:cobble"}, + {"mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_iron', + output = "mcl_tools:axe_iron", recipe = { - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot', 'mcl_core:stick'}, - {'', 'mcl_core:stick'}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot", "mcl_core:stick"}, + {"", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_iron', + output = "mcl_tools:axe_iron", recipe = { - {'mcl_core:iron_ingot', 'mcl_core:iron_ingot'}, - {'mcl_core:stick', 'mcl_core:iron_ingot'}, - {'mcl_core:stick', ''}, + {"mcl_core:iron_ingot", "mcl_core:iron_ingot"}, + {"mcl_core:stick", "mcl_core:iron_ingot"}, + {"mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_gold', + output = "mcl_tools:axe_gold", recipe = { - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, - {'mcl_core:gold_ingot', 'mcl_core:stick'}, - {'', 'mcl_core:stick'}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot", "mcl_core:stick"}, + {"", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_gold', + output = "mcl_tools:axe_gold", recipe = { - {'mcl_core:gold_ingot', 'mcl_core:gold_ingot'}, - {'mcl_core:stick', 'mcl_core:gold_ingot'}, - {'mcl_core:stick', ''}, + {"mcl_core:gold_ingot", "mcl_core:gold_ingot"}, + {"mcl_core:stick", "mcl_core:gold_ingot"}, + {"mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_diamond', + output = "mcl_tools:axe_diamond", recipe = { - {'mcl_core:diamond', 'mcl_core:diamond'}, - {'mcl_core:diamond', 'mcl_core:stick'}, - {'', 'mcl_core:stick'}, + {"mcl_core:diamond", "mcl_core:diamond"}, + {"mcl_core:diamond", "mcl_core:stick"}, + {"", "mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:axe_diamond', + output = "mcl_tools:axe_diamond", recipe = { - {'mcl_core:diamond', 'mcl_core:diamond'}, - {'mcl_core:stick', 'mcl_core:diamond'}, - {'mcl_core:stick', ''}, + {"mcl_core:diamond", "mcl_core:diamond"}, + {"mcl_core:stick", "mcl_core:diamond"}, + {"mcl_core:stick", ""}, } }) minetest.register_craft({ - output = 'mcl_tools:sword_wood', + output = "mcl_tools:sword_wood", recipe = { - {'group:wood'}, - {'group:wood'}, - {'mcl_core:stick'}, + {"group:wood"}, + {"group:wood"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:sword_stone', + output = "mcl_tools:sword_stone", recipe = { - {'mcl_core:cobble'}, - {'mcl_core:cobble'}, - {'mcl_core:stick'}, + {"group:cobble"}, + {"group:cobble"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:sword_iron', + output = "mcl_tools:sword_iron", recipe = { - {'mcl_core:iron_ingot'}, - {'mcl_core:iron_ingot'}, - {'mcl_core:stick'}, + {"mcl_core:iron_ingot"}, + {"mcl_core:iron_ingot"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:sword_gold', + output = "mcl_tools:sword_gold", recipe = { - {'mcl_core:gold_ingot'}, - {'mcl_core:gold_ingot'}, - {'mcl_core:stick'}, + {"mcl_core:gold_ingot"}, + {"mcl_core:gold_ingot"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:sword_diamond', + output = "mcl_tools:sword_diamond", recipe = { - {'mcl_core:diamond'}, - {'mcl_core:diamond'}, - {'mcl_core:stick'}, + {"mcl_core:diamond"}, + {"mcl_core:diamond"}, + {"mcl_core:stick"}, } }) minetest.register_craft({ - output = 'mcl_tools:shears', + output = "mcl_tools:shears", recipe = { - { 'mcl_core:iron_ingot', '' }, - { '', 'mcl_core:iron_ingot', }, + { "mcl_core:iron_ingot", "" }, + { "", "mcl_core:iron_ingot", }, } }) minetest.register_craft({ - output = 'mcl_tools:shears', + output = "mcl_tools:shears", recipe = { - { '', 'mcl_core:iron_ingot', }, - { 'mcl_core:iron_ingot', '' }, + { "", "mcl_core:iron_ingot" }, + { "mcl_core:iron_ingot", "" }, } }) diff --git a/mods/ITEMS/mcl_tools/depends.txt b/mods/ITEMS/mcl_tools/depends.txt deleted file mode 100644 index 5ce101eda..000000000 --- a/mods/ITEMS/mcl_tools/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -_mcl_autogroup diff --git a/mods/ITEMS/mcl_tools/init.lua b/mods/ITEMS/mcl_tools/init.lua index 91aacc287..5f96fa3fa 100644 --- a/mods/ITEMS/mcl_tools/init.lua +++ b/mods/ITEMS/mcl_tools/init.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator("mcl_tools") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) -- mods/default/tools.lua @@ -6,14 +8,7 @@ local S = minetest.get_translator("mcl_tools") -- Tool definition -- ---[[ Maximum drop level definitions: -- 0: Hand -- 1: Wood / Shears -- 2: Gold -- 3: Stone -- 4: Iron -- 5: Diamond - +--[[ dig_speed_class group: - 1: Painfully slow - 2: Very slow @@ -24,45 +19,6 @@ dig_speed_class group: - 7: Instantaneous ]] --- The hand -local groupcaps, hand_range, hand_groups -if minetest.is_creative_enabled("") then - -- Instant breaking in creative mode - groupcaps = { - creative_breakable = {times={[1]=0}, uses=0}, - } - -- mcl_autogroup provides the creative digging times for all digging groups - for k,v in pairs(mcl_autogroup.creativetimes) do - groupcaps[k] = { times = v, uses = 0 } - end - hand_range = 10 - hand_groups = { dig_speed_class = 7 } -else - groupcaps = { - handy_dig = {times=mcl_autogroup.digtimes.handy_dig, uses=0}, - } - hand_range = 4 - hand_groups = { dig_speed_class = 1 } -end -minetest.register_item(":", { - type = "none", - _doc_items_longdesc = S("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.").."\n".. - S("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.").."\n".. - S("In Creative Mode, the hand is able to break all blocks instantly."), - wield_image = "wieldhand.png", - wield_scale = {x=1.0,y=1.0,z=2.0}, - -- According to Minecraft Wiki, the exact range is 3.975. - -- Minetest seems to only support whole numbers, so we use 4. - range = hand_range, - tool_capabilities = { - full_punch_interval = 0.25, - max_drop_level = 0, - groupcaps = groupcaps, - damage_groups = {fleshy=1}, - }, - groups = hand_groups, -}) - -- Help texts local pickaxe_longdesc = S("Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.") local axe_longdesc = S("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.") @@ -72,7 +28,7 @@ local shovel_use = S("To turn a grass block into a grass path, hold the shovel i local shears_longdesc = S("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.") local shears_use = S("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.") -local wield_scale = { x = 1.8, y = 1.8, z = 1 } +local wield_scale = mcl_vars.tool_wield_scale -- Picks minetest.register_tool("mcl_tools:pick_wood", { @@ -86,14 +42,15 @@ minetest.register_tool("mcl_tools:pick_wood", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=1, - groupcaps={ - pickaxey_dig_wood = {times=mcl_autogroup.digtimes.pickaxey_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:pick_stone", { description = S("Stone Pickaxe"), @@ -105,14 +62,15 @@ minetest.register_tool("mcl_tools:pick_stone", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=3, - groupcaps={ - pickaxey_dig_stone = {times=mcl_autogroup.digtimes.pickaxey_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, sound = { breaks = "default_tool_breaks" }, - _repair_material = "mcl_core:cobble", + _repair_material = "group:cobble", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:pick_iron", { description = S("Iron Pickaxe"), @@ -124,14 +82,15 @@ minetest.register_tool("mcl_tools:pick_iron", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=4, - groupcaps={ - pickaxey_dig_iron = {times=mcl_autogroup.digtimes.pickaxey_dig_iron , uses=251, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:pick_gold", { description = S("Golden Pickaxe"), @@ -143,14 +102,15 @@ minetest.register_tool("mcl_tools:pick_gold", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=2, - groupcaps={ - pickaxey_dig_gold = {times=mcl_autogroup.digtimes.pickaxey_dig_gold , uses=33, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:pick_diamond", { description = S("Diamond Pickaxe"), @@ -162,35 +122,39 @@ minetest.register_tool("mcl_tools:pick_diamond", { -- 1/1.2 full_punch_interval = 0.83333333, max_drop_level=5, - groupcaps={ - pickaxey_dig_diamond = {times=mcl_autogroup.digtimes.pickaxey_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 8, level = 5, uses = 1562 } + }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:pick_netherite" }) -local get_shovel_dig_group = function(itemstack) - local itemstring = itemstack:get_name() - local efficiency_level = mcl_enchanting.get_enchantment(itemstack, "efficiency") - local postfix = efficiency_level > 0 and "_efficiency_" .. efficiency_level or "" - if itemstring:find("mcl_tools:shovel_wood") == 1 then - return "shovely_dig_wood" .. postfix - elseif itemstring:find("mcl_tools:shovel_stone") == 1 then - return "shovely_dig_stone" .. postfix - elseif itemstring:find("mcl_tools:shovel_iron") == 1 then - return "shovely_dig_iron" .. postfix - elseif itemstring:find("mcl_tools:shovel_gold") == 1 then - return "shovely_dig_gold" .. postfix - elseif itemstring:find("mcl_tools:shovel_diamond") == 1 then - return "shovely_dig_diamond" .. postfix - else - -- Fallback - return "shovely_dig_wood" - end -end +minetest.register_tool("mcl_tools:pick_netherite", { + description = S("Netherite Pickaxe"), + _doc_items_longdesc = pickaxe_longdesc, + inventory_image = "default_tool_netheritepick.png", + wield_scale = wield_scale, + groups = { tool=1, pickaxe=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + -- 1/1.2 + full_punch_interval = 0.83333333, + max_drop_level=5, + damage_groups = {fleshy=6}, + punch_attack_uses = 1016, + }, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + pickaxey = { speed = 9.5, level = 6, uses = 2031 } + }, +}) local make_grass_path = function(itemstack, placer, pointed_thing) -- Use pointed node's on_rightclick function first, if present @@ -206,7 +170,7 @@ local make_grass_path = function(itemstack, placer, pointed_thing) return itemstack end - if (minetest.get_item_group(node.name, "grass_block") == 1) then + if (minetest.get_item_group(node.name, "path_creation_possible") == 1) then local above = table.copy(pointed_thing.under) above.y = above.y + 1 if minetest.get_node(above).name == "air" then @@ -216,16 +180,12 @@ local make_grass_path = function(itemstack, placer, pointed_thing) end if not minetest.is_creative_enabled(placer:get_player_name()) then - -- Add wear, as if digging a level 0 shovely node + -- Add wear (as if digging a shovely node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(itemstack) - local toolcaps = itemstack:get_tool_capabilities() - local base_uses = toolcaps.groupcaps[group].uses - local maxlevel = toolcaps.groupcaps[group].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) - itemstack:add_wear(wear) + local wear = mcl_autogroup.get_wear(toolname, "shovely") + if wear then + itemstack:add_wear(wear) + end end minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) minetest.swap_node(pointed_thing.under, {name="mcl_core:grass_path"}) @@ -236,7 +196,7 @@ end local carve_pumpkin if minetest.get_modpath("mcl_farming") then - carve_pumpkin = function(itemstack, placer, pointed_thing) + function carve_pumpkin(itemstack, placer, pointed_thing) -- 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 @@ -253,18 +213,16 @@ if minetest.get_modpath("mcl_farming") then if not minetest.is_creative_enabled(placer:get_player_name()) then -- Add wear (as if digging a shearsy node) local toolname = itemstack:get_name() - local def = minetest.registered_items[toolname] - local group = get_shovel_dig_group(toolname) - local base_uses = def.tool_capabilities.groupcaps["shearsy_dig"].uses - local maxlevel = def.tool_capabilities.groupcaps["shearsy_dig"].maxlevel - local uses = base_uses * math.pow(3, maxlevel) - local wear = math.ceil(65535 / uses) - itemstack:add_wear(wear) + local wear = mcl_autogroup.get_wear(toolname, "shearsy") + if wear then + itemstack:add_wear(wear) + end + end - minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = above}, true) + minetest.sound_play({name="default_grass_footstep", gain=1}, {pos = pointed_thing.above}, true) local dir = vector.subtract(pointed_thing.under, pointed_thing.above) local param2 = minetest.dir_to_facedir(dir) - minetest.swap_node(pointed_thing.under, {name="mcl_farming:pumpkin_face", param2 = param2}) + minetest.set_node(pointed_thing.under, {name="mcl_farming:pumpkin_face", param2 = param2}) minetest.add_item(pointed_thing.above, "mcl_farming:pumpkin_seeds 4") end return itemstack @@ -283,15 +241,16 @@ minetest.register_tool("mcl_tools:shovel_wood", { tool_capabilities = { full_punch_interval = 1, max_drop_level=1, - groupcaps={ - shovely_dig_wood = {times=mcl_autogroup.digtimes.shovely_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 30, }, on_place = make_grass_path, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 2, level = 2, uses = 60 } + }, }) minetest.register_tool("mcl_tools:shovel_stone", { description = S("Stone Shovel"), @@ -303,15 +262,16 @@ minetest.register_tool("mcl_tools:shovel_stone", { tool_capabilities = { full_punch_interval = 1, max_drop_level=3, - groupcaps={ - shovely_dig_stone = {times=mcl_autogroup.digtimes.shovely_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=3}, punch_attack_uses = 66, }, on_place = make_grass_path, sound = { breaks = "default_tool_breaks" }, - _repair_material = "mcl_core:cobble", + _repair_material = "group:cobble", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:shovel_iron", { description = S("Iron Shovel"), @@ -323,15 +283,16 @@ minetest.register_tool("mcl_tools:shovel_iron", { tool_capabilities = { full_punch_interval = 1, max_drop_level=4, - groupcaps={ - shovely_dig_iron = {times=mcl_autogroup.digtimes.shovely_dig_iron, uses=251, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 126, }, on_place = make_grass_path, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:shovel_gold", { description = S("Golden Shovel"), @@ -343,15 +304,16 @@ minetest.register_tool("mcl_tools:shovel_gold", { tool_capabilities = { full_punch_interval = 1, max_drop_level=2, - groupcaps={ - shovely_dig_gold = {times=mcl_autogroup.digtimes.shovely_dig_gold, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=2}, punch_attack_uses = 17, }, on_place = make_grass_path, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:shovel_diamond", { description = S("Diamond Shovel"), @@ -363,18 +325,83 @@ minetest.register_tool("mcl_tools:shovel_diamond", { tool_capabilities = { full_punch_interval = 1, max_drop_level=5, - groupcaps={ - shovely_dig_diamond = {times=mcl_autogroup.digtimes.shovely_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 781, }, on_place = make_grass_path, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 8, level = 5, uses = 1562 } + }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:shovel_netherite" +}) + +minetest.register_tool("mcl_tools:shovel_netherite", { + description = S("Netherite Shovel"), + _doc_items_longdesc = shovel_longdesc, + _doc_items_usagehelp = shovel_use, + inventory_image = "default_tool_netheriteshovel.png", + wield_scale = wield_scale, + groups = { tool=1, shovel=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 1, + max_drop_level=5, + damage_groups = {fleshy=5}, + punch_attack_uses = 1016, + }, + on_place = make_grass_path, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + shovely = { speed = 9, level = 6, uses = 2031 } + }, }) -- Axes +local function make_stripped_trunk(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then return end + + local node = minetest.get_node(pointed_thing.under) + local node_name = minetest.get_node(pointed_thing.under).name + + local noddef = minetest.registered_nodes[node_name] + + if not noddef then + minetest.log("warning", "Trying to right click with an axe the unregistered node: " .. tostring(node_name)) + return + end + + if not placer:get_player_control().sneak and noddef.on_rightclick then + return minetest.item_place(itemstack, placer, pointed_thing) + end + 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 noddef._mcl_stripped_variant == nil then + return itemstack + else + minetest.swap_node(pointed_thing.under, {name=noddef._mcl_stripped_variant, param2=node.param2}) + if minetest.get_item_group(node_name, "waxed") ~= 0 then + awards.unlock(placer:get_player_name(), "mcl:wax_off") + end + if not minetest.is_creative_enabled(placer:get_player_name()) then + -- Add wear (as if digging a axey node) + local toolname = itemstack:get_name() + local wear = mcl_autogroup.get_wear(toolname, "axey") + if wear then + itemstack:add_wear(wear) + end + end + end + return itemstack +end + minetest.register_tool("mcl_tools:axe_wood", { description = S("Wooden Axe"), _doc_items_longdesc = axe_longdesc, @@ -385,14 +412,16 @@ minetest.register_tool("mcl_tools:axe_wood", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=1, - groupcaps={ - axey_dig_wood = {times=mcl_autogroup.digtimes.axey_dig_wood, uses=60, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 30, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:axe_stone", { description = S("Stone Axe"), @@ -403,14 +432,16 @@ minetest.register_tool("mcl_tools:axe_stone", { tool_capabilities = { full_punch_interval = 1.25, max_drop_level=3, - groupcaps={ - axey_dig_stone = {times=mcl_autogroup.digtimes.axey_dig_stone, uses=132, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 66, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, - _repair_material = "mcl_core:cobble", + _repair_material = "group:cobble", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:axe_iron", { description = S("Iron Axe"), @@ -422,14 +453,16 @@ minetest.register_tool("mcl_tools:axe_iron", { -- 1/0.9 full_punch_interval = 1.11111111, max_drop_level=4, - groupcaps={ - axey_dig_iron = {times=mcl_autogroup.digtimes.axey_dig_iron, uses=251, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 126, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:axe_gold", { description = S("Golden Axe"), @@ -440,14 +473,16 @@ minetest.register_tool("mcl_tools:axe_gold", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=2, - groupcaps={ - axey_dig_gold= {times=mcl_autogroup.digtimes.axey_dig_gold, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 17, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:axe_diamond", { description = S("Diamond Axe"), @@ -458,14 +493,39 @@ minetest.register_tool("mcl_tools:axe_diamond", { tool_capabilities = { full_punch_interval = 1.0, max_drop_level=5, - groupcaps={ - axey_dig_diamond = {times=mcl_autogroup.digtimes.axey_dig_diamond, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=9}, punch_attack_uses = 781, }, + on_place = make_stripped_trunk, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 8, level = 5, uses = 1562 } + }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:axe_netherite" +}) + +minetest.register_tool("mcl_tools:axe_netherite", { + description = S("Netherite Axe"), + _doc_items_longdesc = axe_longdesc, + inventory_image = "default_tool_netheriteaxe.png", + wield_scale = wield_scale, + groups = { tool=1, axe=1, dig_speed_class=6, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 1.0, + max_drop_level=5, + damage_groups = {fleshy=10}, + punch_attack_uses = 1016, + }, + on_place = make_stripped_trunk, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + axey = { speed = 9, level = 6, uses = 2031 } + }, }) -- Swords @@ -479,15 +539,16 @@ minetest.register_tool("mcl_tools:sword_wood", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=1, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=60, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=60, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 60, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "group:wood", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 2, level = 1, uses = 60 }, + swordy_cobweb = { speed = 2, level = 1, uses = 60 } + }, }) minetest.register_tool("mcl_tools:sword_stone", { description = S("Stone Sword"), @@ -498,15 +559,16 @@ minetest.register_tool("mcl_tools:sword_stone", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=3, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig , uses=132, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=132, maxlevel=0}, - }, damage_groups = {fleshy=5}, punch_attack_uses = 132, }, sound = { breaks = "default_tool_breaks" }, - _repair_material = "mcl_core:cobble", + _repair_material = "group:cobble", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 4, level = 3, uses = 132 }, + swordy_cobweb = { speed = 4, level = 3, uses = 132 } + }, }) minetest.register_tool("mcl_tools:sword_iron", { description = S("Iron Sword"), @@ -517,15 +579,16 @@ minetest.register_tool("mcl_tools:sword_iron", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=4, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=251, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig , uses=251, maxlevel=0}, - }, damage_groups = {fleshy=6}, punch_attack_uses = 251, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:iron_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 6, level = 4, uses = 251 }, + swordy_cobweb = { speed = 6, level = 4, uses = 251 } + }, }) minetest.register_tool("mcl_tools:sword_gold", { description = S("Golden Sword"), @@ -536,15 +599,16 @@ minetest.register_tool("mcl_tools:sword_gold", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=2, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=33, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=33, maxlevel=0}, - }, damage_groups = {fleshy=4}, punch_attack_uses = 33, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:gold_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 12, level = 2, uses = 33 }, + swordy_cobweb = { speed = 12, level = 2, uses = 33 } + }, }) minetest.register_tool("mcl_tools:sword_diamond", { description = S("Diamond Sword"), @@ -555,15 +619,38 @@ minetest.register_tool("mcl_tools:sword_diamond", { tool_capabilities = { full_punch_interval = 0.625, max_drop_level=5, - groupcaps={ - swordy_dig = {times=mcl_autogroup.digtimes.swordy_dig, uses=1562, maxlevel=0}, - swordy_cobweb_dig = {times=mcl_autogroup.digtimes.swordy_cobweb_dig, uses=1562, maxlevel=0}, - }, damage_groups = {fleshy=7}, punch_attack_uses = 1562, }, sound = { breaks = "default_tool_breaks" }, _repair_material = "mcl_core:diamond", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 8, level = 5, uses = 1562 }, + swordy_cobweb = { speed = 8, level = 5, uses = 1562 } + }, + _mcl_upgradable = true, + _mcl_upgrade_item = "mcl_tools:sword_netherite" +}) +minetest.register_tool("mcl_tools:sword_netherite", { + description = S("Netherite Sword"), + _doc_items_longdesc = sword_longdesc, + inventory_image = "default_tool_netheritesword.png", + wield_scale = wield_scale, + groups = { weapon=1, sword=1, dig_speed_class=5, enchantability=10, fire_immune=1 }, + tool_capabilities = { + full_punch_interval = 0.625, + max_drop_level=5, + damage_groups = {fleshy=9}, + punch_attack_uses = 2031, + }, + sound = { breaks = "default_tool_breaks" }, + _repair_material = "mcl_nether:netherite_ingot", + _mcl_toollike_wield = true, + _mcl_diggroups = { + swordy = { speed = 8, level = 5, uses = 2031 }, + swordy_cobweb = { speed = 8, level = 5, uses = 2031 } + }, }) --Shears @@ -578,15 +665,17 @@ minetest.register_tool("mcl_tools:shears", { tool_capabilities = { full_punch_interval = 0.5, max_drop_level=1, - groupcaps={ - shearsy_dig = {times=mcl_autogroup.digtimes.shearsy_dig, uses=238, maxlevel=0}, - shearsy_wool_dig = {times=mcl_autogroup.digtimes.shearsy_wool_dig, uses=238, maxlevel=0}, - } }, on_place = carve_pumpkin, sound = { breaks = "default_tool_breaks" }, + _mcl_toollike_wield = true, + _mcl_diggroups = { + shearsy = { speed = 1.5, level = 1, uses = 238 }, + shearsy_wool = { speed = 5, level = 1, uses = 238 }, + shearsy_cobweb = { speed = 15, level = 1, uses = 238 } + }, }) -dofile(minetest.get_modpath("mcl_tools").."/crafting.lua") -dofile(minetest.get_modpath("mcl_tools").."/aliases.lua") +dofile(modpath.."/crafting.lua") +dofile(modpath.."/aliases.lua") diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr index 02cd7f2bd..1d3c46648 100644 --- a/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.tr +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.fr.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.=Vous utilisez votre main nue lorsque vous ne portez aucun objet. Avec votre main, vous pouvez miner la plupart des blocs, mais c'est la méthode la plus lente et seuls les blocs les plus faibles produiront un élément utile. La main inflige également des dégâts mineurs en frappant. L'utilisation de la main est souvent un dernier recours, car les outils et les armes d'extraction appropriés sont bien meilleurs. +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.=Vous utilisez votre main nue lorsque vous ne portez aucun objet. Avec votre main, vous pouvez miner la plupart des blocs, mais c'est la méthode la plus lente et seuls les blocs les plus faibles donneront des éléments utiles. La main inflige également des dégâts mineurs en frappant. L'utilisation de la main est souvent un dernier recours, car les outils et les armes d'extraction appropriées sont bien meilleures. 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.=Lorsque vous maniez un objet qui n'est ni un outil d'extraction ni une arme, il se comportera comme s'il s'agissait de la main lorsque vous commencez à extraire ou à frapper. In Creative Mode, the hand is able to break all blocks instantly.=En mode créatif, la main est capable de briser tous les blocs instantanément. Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Les pioches sont des outils d'extraction pour extraire des blocs durs, comme la pierre. Une pioche peut également être utilisée comme arme, mais elle est plutôt inefficace. 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.=Une hache est votre outil de choix pour abattre des arbres, des blocs à base de bois et d'autres blocs. Les haches infligent également beaucoup de dégâts, mais elles sont plutôt lentes. 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.=Les épées sont excellentes en combat de mêlée, car elles sont rapides, infligent des dégâts élevés et peuvent supporter d'innombrables batailles. Les épées peuvent également être utilisées pour couper quelques blocs particuliers, tels que les toiles d'araignées. -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.=Les pelles sont des outils pour creuser des blocs grossiers, tels que la terre, le sable et le gravier. Ils peuvent également être utilisés pour transformer des blocs d'herbe en chemins de terre. Les pelles peuvent être utilisées comme armes, mais elles sont très faibles. +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.=Les pelles sont des outils pour creuser des blocs grossiers, tels que la terre, le sable et le gravier. Elles peuvent également être utilisées pour transformer des blocs d'herbe en chemins de terre. Les pelles peuvent être utilisées comme armes, mais elles sont très faibles. 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.=Pour transformer un bloc d'herbe en chemin de terre, tenez la pelle dans votre main, puis utilisez (clic droit) le haut ou le côté d'un bloc d'herbe. Cela ne fonctionne que lorsqu'il y a de l'air au-dessus du bloc d'herbe. 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.=Les cisailles sont des outils pour tondre les moutons et pour extraire quelques types de blocs. Les cisailles sont un outil d'extraction spécial et peuvent être utilisées pour obtenir l'élément d'origine à partir d'herbe, de feuilles et de blocs similaires qui nécessitent une coupe. -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.=Pour tondre des moutons ou tailler des citrouilles sans visage, utilisez la touche "placer" dessus. Les visages ne peuvent être sculptés que sur le côté des citrouilles sans visage. L'exploitation minière fonctionne comme d'habitude, mais les éléments sont différentes pour quelques blocs. -Wooden Pickaxe=Pioche en Bois -Stone Pickaxe=Pioche en Pierre -Iron Pickaxe=Pioche en Fer -Golden Pickaxe=Pioche en Or -Diamond Pickaxe=Pioche en Diamant -Wooden Shovel=Pelle en Bois -Stone Shovel=Pelle en Pierre -Iron Shovel=Pelle en Fer -Golden Shovel=Pelle en Or -Diamond Shovel=Pelle en Diamant -Wooden Axe=Hache en Bois -Stone Axe=Hache en Pierre -Iron Axe=Hache en Fer -Golden Axe=Hache en Or -Diamond Axe=Hache en Diamant -Wooden Sword=Épée en Bois -Stone Sword=Épée en Pierre -Iron Sword=Épée en Fer -Golden Sword=Épée en Or -Diamond Sword=Épée en Diamant +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.=Pour tondre des moutons ou tailler des citrouilles sans visage, utilisez la touche "placer" dessus. Les visages ne peuvent être sculptés que sur le côté des citrouilles sans visage. L'exploitation minière fonctionne comme d'habitude, mais les éléments obtenus sont différentes pour quelques blocs. +Wooden Pickaxe=Pioche en bois +Stone Pickaxe=Pioche en pierre +Iron Pickaxe=Pioche en fer +Golden Pickaxe=Pioche en or +Diamond Pickaxe=Pioche en diamant +Netherite Pickaxe=Pioche en netherite +Wooden Shovel=Pelle en bois +Stone Shovel=Pelle en pierre +Iron Shovel=Pelle en fer +Golden Shovel=Pelle en or +Diamond Shovel=Pelle en diamant +Netherite Shovel=Pelle en netherite +Wooden Axe=Hache en bois +Stone Axe=Hache en pierre +Iron Axe=Hache en fer +Golden Axe=Hache en or +Diamond Axe=Hache en diamant +Netherite Axe=Hache en netherite +Wooden Sword=Épée en bois +Stone Sword=Épée en pierre +Iron Sword=Épée en fer +Golden Sword=Épée en or +Diamond Sword=Épée en diamant +Netherite Sword=Épée en netherite Shears=Cisailles diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.tr new file mode 100644 index 000000000..063bd8a48 --- /dev/null +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.ja.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.=何のアイテムも用いていないときは、いつだって素手を使います。手でほとんどのブロックを採掘できますが、この方法は最も時間がかかるうえ、有用なドロップをもたらすのは脆弱なブロックだけです。また、手で殴ることで小さなダメージを与えることもできます。 適切な採掘道具や武器の方がはるかに良いので、手を使うのは往々にして最後の手段です。 +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_tools/locale/mcl_tools.pl.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.pl.tr new file mode 100644 index 000000000..afe42593f --- /dev/null +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.pl.tr @@ -0,0 +1,33 @@ +# 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.=Gdy nie trzymasz żadnego przedmiotu używasz swoich gołych dłoni. Swoją dłonią możesz wykopać większość bloków, ale jest to najwolniejsza metoda i tylko najsłabsze bloki wyrzucą z siebie użyteczny zrzut. Ręce zadają również niewielkie obrażenia przy uderzaniu. Używanie ręki to często ostateczność, ponieważ porządne narzędzia do kopania i bronie są o wiele lepsze. +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.=Gdy trzymasz przedmiot który nie jest narzędziem do kopania ani bronią, będzie się on zachowywał jakby był dłonią podczas kopania i uderzania. +In Creative Mode, the hand is able to break all blocks instantly.=W trybie kreatywnym ręka jest w stanie zniszczyć wszystkie bloki natychmiastowo. +Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.=Kilofy są narzędziami wykorzystywanymi do kopania twardych bloków, takich jak kamień. Mogą być również wykorzystane jako bronie, ale nie jest to bardzo efektywne. +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.=Siekiera jest narzędziem do ścinania drzew, bloków z desek i innych bloków. Siekiery zadają duże obrażenia, ale są wolne. +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.=Miecze są świetne do walki wręcz, ponieważ są szybkie, zadają duże obrażenia i mogą wytrzymać niezliczone pojedynki. Można je również wykorzystać do ścięcia niektórych bloków takich jak pajęczyny. +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.=Łopaty są użyteczne do kopania sypkich bloków takich jak ziemia, piasek czy żwir. Można je również wykorzystać by zmienić bloki trawy w ścieżki. Mogą być również wykorzystane jako broń, ale są bardzo słabe. +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.=Aby zmienić blok trawy w ścieżkę, weź łopatę do ręki, następnie użyj prawego przycisku myszy na wierzchu lub boku bloku trawy. To zadziała tylko pod warunkiem, że nad blokiem ziemi jest blok powietrza. +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.=Nożyce są narzędziem do strzyżenia owiec i kopania kilku typów bloków. Są one specjalnym narzędziem do kopania i można je wykorzystać do uzyskania oryginalnych przedmiotów z trawy, liści i podobnych bloków wymagających ścinania. +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.=Aby ostrzyc owcę lub wydrążyć dynię użyj przycisku "umieść" na nich. Twarze mogą zostać wydrążone na bokach dyń bez twarzy. Kopanie działa jak zwykle, ale zrzut jest inny dla niektórych bloków. +Wooden Pickaxe=Drewniany kilof +Stone Pickaxe=Kamienny kilof +Iron Pickaxe=Żelazny kilof +Golden Pickaxe=Złoty kilof +Diamond Pickaxe=Diamentowy kilof +Wooden Shovel=Drewniana łopata +Stone Shovel=Kamienna łopata +Iron Shovel=Żelazna łopata +Golden Shovel=Złota łopata +Diamond Shovel=Diamentowa łopata +Wooden Axe=Drewniana siekiera +Stone Axe=Kamienna siekiera +Iron Axe=Żelazna siekiera +Golden Axe=Złota siekiera +Diamond Axe=Diamentowa siekiera +Wooden Sword=Drewniany miecz +Stone Sword=Kamienny miecz +Iron Sword=Żelazny miecz +Golden Sword=Złoty miecz +Diamond Sword=Diamentowy miecz +Shears=Nożyce + diff --git a/mods/ITEMS/mcl_tools/locale/mcl_tools.zh_TW.tr b/mods/ITEMS/mcl_tools/locale/mcl_tools.zh_TW.tr new file mode 100644 index 000000000..ed40c64ba --- /dev/null +++ b/mods/ITEMS/mcl_tools/locale/mcl_tools.zh_TW.tr @@ -0,0 +1,32 @@ +# 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.=要剪羊毛或雕刻南瓜,請在其上使用「放置」鍵。只能在南瓜側面雕刻臉部。開採照常進行,但是掉落物在部分方塊上是不同的。 +Wooden Pickaxe=木鎬 +Stone Pickaxe=石鎬 +Iron Pickaxe=鐵鎬 +Golden Pickaxe=金鎬 +Diamond Pickaxe=鑽石鎬 +Wooden Shovel=木鏟 +Stone Shovel=石鏟 +Iron Shovel=鐵鏟 +Golden Shovel=金鏟 +Diamond Shovel=鑽石鏟 +Wooden Axe=木斧 +Stone Axe=石斧 +Iron Axe=鐵斧 +Golden Axe=金斧 +Diamond Axe=鑽石斧 +Wooden Sword=木劍 +Stone Sword=石劍 +Iron Sword=鐵劍 +Golden Sword=金劍 +Diamond Sword=鑽石劍 +Shears=剪刀 diff --git a/mods/ITEMS/mcl_tools/locale/template.txt b/mods/ITEMS/mcl_tools/locale/template.txt index ecb94105f..2f5830312 100644 --- a/mods/ITEMS/mcl_tools/locale/template.txt +++ b/mods/ITEMS/mcl_tools/locale/template.txt @@ -14,19 +14,23 @@ 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_tools/mod.conf b/mods/ITEMS/mcl_tools/mod.conf index fb522b423..d2d93197b 100644 --- a/mods/ITEMS/mcl_tools/mod.conf +++ b/mods/ITEMS/mcl_tools/mod.conf @@ -1 +1,2 @@ name = mcl_tools +depends = mcl_sounds, mcl_init diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_diamondshovel.png b/mods/ITEMS/mcl_tools/textures/default_tool_diamondshovel.png deleted file mode 100644 index 6cc561115..000000000 Binary files a/mods/ITEMS/mcl_tools/textures/default_tool_diamondshovel.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_woodshovel.png b/mods/ITEMS/mcl_tools/textures/default_tool_woodshovel.png deleted file mode 100644 index e1855b5ae..000000000 Binary files a/mods/ITEMS/mcl_tools/textures/default_tool_woodshovel.png and /dev/null differ diff --git a/mods/ITEMS/mcl_tools/textures/wieldhand.png b/mods/ITEMS/mcl_tools/textures/wieldhand.png deleted file mode 100644 index 47d21f690..000000000 Binary files a/mods/ITEMS/mcl_tools/textures/wieldhand.png and /dev/null differ diff --git a/mods/ITEMS/mcl_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua new file mode 100644 index 000000000..a2e49aa0d --- /dev/null +++ b/mods/ITEMS/mcl_torches/api.lua @@ -0,0 +1,289 @@ +local flame_texture = {"mcl_particles_flame.png", "mcl_particles_soul_fire_flame.png"} + +local smoke_pdef = { + amount = 0.5, + maxexptime = 2.0, + minvel = { x = 0.0, y = 0.5, z = 0.0 }, + maxvel = { x = 0.0, y = 0.6, z = 0.0 }, + minsize = 1.5, + maxsize = 1.5, + minrelpos = { x = -1/16, y = 0.04, z = -1/16 }, + maxrelpos = { x = 1/16, y = 0.06, z = 1/16 }, +} + +local function spawn_flames_floor(pos, flame_type) + + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), + maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = flame_texture[flame_type], + glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source, + }, "low") + -- Smoke + mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) +end + +local function spawn_flames_wall(pos, flame_type) + --local minrelpos, maxrelpos + local node = minetest.get_node(pos) + local dir = minetest.wallmounted_to_dir(node.param2) + + local smoke_pdef = table.copy(smoke_pdef) + + if dir.x < 0 then + smoke_pdef.minrelpos = { x = -0.38, y = 0.24, z = -0.1 } + smoke_pdef.maxrelpos = { x = -0.2, y = 0.34, z = 0.1 } + elseif dir.x > 0 then + smoke_pdef.minrelpos = { x = 0.2, y = 0.24, z = -0.1 } + smoke_pdef.maxrelpos = { x = 0.38, y = 0.34, z = 0.1 } + elseif dir.z < 0 then + smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = -0.38 } + smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = -0.2 } + elseif dir.z > 0 then + smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = 0.2 } + smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = 0.38 } + else + return + end + + + -- Flames + mcl_particles.add_node_particlespawner(pos, { + amount = 8, + time = 0, + minpos = vector.add(pos, smoke_pdef.minrelpos), + maxpos = vector.add(pos, smoke_pdef.maxrelpos), + minvel = { x = -0.01, y = 0, z = -0.01 }, + maxvel = { x = 0.01, y = 0.1, z = 0.01 }, + minexptime = 0.3, + maxexptime = 0.6, + minsize = 0.7, + maxsize = 2, + texture = flame_texture[flame_type], + glow = minetest.registered_nodes[node.name].light_source, + }, "low") + -- Smoke + mcl_particles.spawn_smoke(pos, "torch", smoke_pdef) +end + +local function set_flames(pos, flame_type, attached_to) + if attached_to == "wall" then + return function(pos) + spawn_flames_wall(pos, flame_type) + end + end + + return function(pos) + spawn_flames_floor(pos, flame_type) + end +end + +local function remove_flames(pos) + mcl_particles.delete_node_particlespawners(pos) +end + +-- +-- 3d torch part +-- + +-- Check if placement at given node is allowed +local function check_placement_allowed(node, wdir) + -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. + -- Special allowed nodes: + -- * soul sand + -- * mob spawner + -- * chorus flower + -- * glass, barrier, ice + -- * Fence, wall, end portal frame with ender eye: Only on top + -- * Slab, stairs: Only on top if upside down + + -- Special forbidden nodes: + -- * Piston, sticky piston + local def = minetest.registered_nodes[node.name] + if not def then + return false + -- No ceiling torches + elseif wdir == 0 then + return false + elseif not def.buildable_to then + if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and + ((not def.groups.solid) or (not def.groups.opaque)) then + -- Only allow top placement on these nodes + if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then + if wdir ~= 1 then + return false + end + else + return false + end + elseif minetest.get_item_group(node.name, "piston") >= 1 then + return false + end + end + return true +end + +function mcl_torches.register_torch(def) + local itemstring = minetest.get_current_modname() .. ":" .. def.name + local itemstring_wall = itemstring .. "_wall" + + def.light = def.light or minetest.LIGHT_MAX + def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj" + def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj" + def.flame_type = def.flame_type or 1 + + local groups = def.groups or {} + + groups.attached_node = 1 + groups.torch = 1 + groups.torch_particles = def.particles and 1 + groups.dig_by_water = 1 + groups.destroy_by_lava_flow = 1 + groups.dig_by_piston = 1 + groups.flame_type = def.flame_type or 1 + + local floordef = { + description = def.description, + _doc_items_longdesc = def.doc_items_longdesc, + _doc_items_usagehelp = def.doc_items_usagehelp, + _doc_items_hidden = def.doc_items_hidden, + _doc_items_create_entry = def._doc_items_create_entry, + drawtype = "mesh", + mesh = def.mesh_floor, + inventory_image = def.icon, + wield_image = def.icon, + tiles = def.tiles, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + liquids_pointable = false, + light_source = def.light, + groups = groups, + drop = def.drop or itemstring, + use_texture_alpha = "clip", + selection_box = { + type = "wallmounted", + wall_bottom = {-2/16, -0.5, -2/16, 2/16, 1/16, 2/16}, + }, + sounds = def.sounds, + node_placement_prediction = "", + on_place = function(itemstack, placer, pointed_thing) + if pointed_thing.type ~= "node" then + -- no interaction possible with entities, for now. + return itemstack + end + + local under = pointed_thing.under + local node = minetest.get_node(under) + local def = minetest.registered_nodes[node.name] + if not def then return itemstack end + + -- Call on_rightclick if the pointed node defines it + 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(under, node, placer, itemstack) or itemstack + end + end + + local above = pointed_thing.above + local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) + + if check_placement_allowed(node, wdir) == false then + return itemstack + end + + local itemstring = itemstack:get_name() + local fakestack = ItemStack(itemstack) + local idef = fakestack:get_definition() + local retval + + if wdir == 1 then + retval = fakestack:set_name(itemstring) + else + retval = fakestack:set_name(itemstring_wall) + end + if not retval then + return itemstack + end + + local success + itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) + itemstack:set_name(itemstring) + + if success and idef.sounds and idef.sounds.place then + minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) + end + return itemstack + end, + on_rotate = false, + on_construct = function(pos) + if def.particles then + set_flames(pos, def.flame_type, "floor") + end + end, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring, floordef) + + local groups_wall = table.copy(groups) + groups_wall.torch = 2 + + local walldef = { + drawtype = "mesh", + mesh = def.mesh_wall, + tiles = def.tiles, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + is_ground_content = false, + walkable = false, + light_source = def.light, + groups = groups_wall, + drop = def.drop or itemstring, + use_texture_alpha = "clip", + selection_box = { + type = "wallmounted", + wall_side = {-0.5, -0.3, -0.1, -0.2, 0.325, 0.1}, + }, + sounds = def.sounds, + on_rotate = false, + on_construct = function(pos) + if def.particles then + set_flames(pos, def.flame_type, "wall") + end + end, + on_destruct = def.particles and remove_flames, + } + minetest.register_node(itemstring_wall, walldef) + + -- Add entry alias for the Help + if minetest.get_modpath("doc") then + doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) + end +end + +minetest.register_lbm({ + label = "Torch flame particles", + name = "mcl_torches:flames", + nodenames = {"group:torch_particles"}, + run_at_every_load = true, + action = function(pos, node) + local torch_group = minetest.get_item_group(node.name, "torch") + if torch_group == 1 then + spawn_flames_floor(pos, minetest.get_item_group(node.name, "flame_type")) + elseif torch_group == 2 then + spawn_flames_wall(pos, minetest.get_item_group(node.name, "flame_type")) + end + end, +}) diff --git a/mods/ITEMS/mcl_torches/depends.txt b/mods/ITEMS/mcl_torches/depends.txt deleted file mode 100644 index d15228bce..000000000 --- a/mods/ITEMS/mcl_torches/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_sounds -mcl_particles -doc? diff --git a/mods/ITEMS/mcl_torches/description.txt b/mods/ITEMS/mcl_torches/description.txt deleted file mode 100644 index 1ce04a366..000000000 --- a/mods/ITEMS/mcl_torches/description.txt +++ /dev/null @@ -1 +0,0 @@ -Mesh-based torches - three dimensional torches for minetest. diff --git a/mods/ITEMS/mcl_torches/init.lua b/mods/ITEMS/mcl_torches/init.lua index 179308358..6b6ebcae9 100644 --- a/mods/ITEMS/mcl_torches/init.lua +++ b/mods/ITEMS/mcl_torches/init.lua @@ -1,336 +1,6 @@ -local S = minetest.get_translator("mcl_torches") -local LIGHT_TORCH = minetest.LIGHT_MAX - -local spawn_flames_floor = function(pos) - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - time = 0, - minpos = vector.add(pos, { x = -0.1, y = 0.05, z = -0.1 }), - maxpos = vector.add(pos, { x = 0.1, y = 0.15, z = 0.1 }), - minvel = { x = -0.01, y = 0, z = -0.01 }, - maxvel = { x = 0.01, y = 0.1, z = 0.01 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, { x = -1/16, y = 0.04, z = -1/16 }), - maxpos = vector.add(pos, { x = -1/16, y = 0.06, z = -1/16 }), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local spawn_flames_wall = function(pos, param2) - local minrelpos, maxrelpos - local dir = minetest.wallmounted_to_dir(param2) - if dir.x < 0 then - minrelpos = { x = -0.38, y = 0.04, z = -0.1 } - maxrelpos = { x = -0.2, y = 0.14, z = 0.1 } - elseif dir.x > 0 then - minrelpos = { x = 0.2, y = 0.04, z = -0.1 } - maxrelpos = { x = 0.38, y = 0.14, z = 0.1 } - elseif dir.z < 0 then - minrelpos = { x = -0.1, y = 0.04, z = -0.38 } - maxrelpos = { x = 0.1, y = 0.14, z = -0.2 } - elseif dir.z > 0 then - minrelpos = { x = -0.1, y = 0.04, z = 0.2 } - maxrelpos = { x = 0.1, y = 0.14, z = 0.38 } - else - return - end - -- Flames - mcl_particles.add_node_particlespawner(pos, { - amount = 8, - 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 }, - minexptime = 0.3, - maxexptime = 0.6, - minsize = 0.7, - maxsize = 2, - texture = "mcl_particles_flame.png", - glow = LIGHT_TORCH, - }, "low") - -- Smoke - mcl_particles.add_node_particlespawner(pos, { - amount = 0.5, - time = 0, - minpos = vector.add(pos, minrelpos), - maxpos = vector.add(pos, maxrelpos), - minvel = { x = 0, y = 0.5, z = 0 }, - maxvel = { x = 0, y = 0.6, z = 0 }, - minexptime = 2.0, - maxexptime = 2.0, - minsize = 1.5, - maxsize = 1.5, - texture = "mcl_particles_smoke_anim.png", - animation = { - type = "vertical_frames", - aspect_w = 8, - aspect_h = 8, - length = 2.05, - }, - }, "medium") -end - -local remove_flames = function(pos) - mcl_particles.delete_node_particlespawners(pos) -end - --- --- 3d torch part --- - --- Check if placement at given node is allowed -local function check_placement_allowed(node, wdir) - -- Torch placement rules: Disallow placement on some nodes. General rule: Solid, opaque, full cube collision box nodes are allowed. - -- Special allowed nodes: - -- * soul sand - -- * mob spawner - -- * chorus flower - -- * glass, barrier, ice - -- * Fence, wall, end portal frame with ender eye: Only on top - -- * Slab, stairs: Only on top if upside down - - -- Special forbidden nodes: - -- * Piston, sticky piston - local def = minetest.registered_nodes[node.name] - if not def then - return false - -- No ceiling torches - elseif wdir == 0 then - return false - elseif not def.buildable_to then - if node.name ~= "mcl_core:ice" and node.name ~= "mcl_nether:soul_sand" and node.name ~= "mcl_mobspawners:spawner" and node.name ~= "mcl_core:barrier" and node.name ~= "mcl_end:chorus_flower" and node.name ~= "mcl_end:chorus_flower_dead" and (not def.groups.glass) and - ((not def.groups.solid) or (not def.groups.opaque)) then - -- Only allow top placement on these nodes - if node.name == "mcl_end:dragon_egg" or node.name == "mcl_portals:end_portal_frame_eye" or def.groups.fence == 1 or def.groups.wall or def.groups.slab_top == 1 or def.groups.anvil or def.groups.pane or (def.groups.stair == 1 and minetest.facedir_to_dir(node.param2).y ~= 0) then - if wdir ~= 1 then - return false - end - else - return false - end - elseif minetest.get_item_group(node.name, "piston") >= 1 then - return false - end - end - return true -end - mcl_torches = {} -mcl_torches.register_torch = function(substring, description, doc_items_longdesc, doc_items_usagehelp, icon, mesh_floor, mesh_wall, tiles, light, groups, sounds, moredef, moredef_floor, moredef_wall) - local itemstring = minetest.get_current_modname()..":"..substring - local itemstring_wall = minetest.get_current_modname()..":"..substring.."_wall" - - if light == nil then light = minetest.LIGHT_MAX end - if mesh_floor == nil then mesh_floor = "mcl_torches_torch_floor.obj" end - if mesh_wall == nil then mesh_wall = "mcl_torches_torch_wall.obj" end - if groups == nil then groups = {} end - - groups.attached_node = 1 - groups.torch = 1 - groups.dig_by_water = 1 - groups.destroy_by_lava_flow = 1 - groups.dig_by_piston = 1 - - local floordef = { - description = description, - _doc_items_longdesc = doc_items_longdesc, - _doc_items_usagehelp = doc_items_usagehelp, - drawtype = "mesh", - mesh = mesh_floor, - inventory_image = icon, - wield_image = icon, - tiles = tiles, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - liquids_pointable = false, - light_source = light, - groups = groups, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16}, - wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16}, - }, - sounds = sounds, - node_placement_prediction = "", - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing.type ~= "node" then - -- no interaction possible with entities, for now. - return itemstack - end - - local under = pointed_thing.under - local node = minetest.get_node(under) - local def = minetest.registered_nodes[node.name] - if not def then return itemstack end - - -- Call on_rightclick if the pointed node defines it - 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(under, node, placer, itemstack) or itemstack - end - end - - local above = pointed_thing.above - local wdir = minetest.dir_to_wallmounted({x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}) - - if check_placement_allowed(node, wdir) == false then - return itemstack - end - - local itemstring = itemstack:get_name() - local fakestack = ItemStack(itemstack) - local idef = fakestack:get_definition() - local retval - - if wdir == 1 then - retval = fakestack:set_name(itemstring) - else - retval = fakestack:set_name(itemstring_wall) - end - if not retval then - return itemstack - end - - local success - itemstack, success = minetest.item_place(fakestack, placer, pointed_thing, wdir) - itemstack:set_name(itemstring) - - if success and idef.sounds and idef.sounds.place then - minetest.sound_play(idef.sounds.place, {pos=under, gain=1}, true) - end - return itemstack - end, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - floordef[k] = v - end - end - if moredef_floor ~= nil then - for k,v in pairs(moredef_floor) do - floordef[k] = v - end - end - minetest.register_node(itemstring, floordef) - - local groups_wall = table.copy(groups) - groups_wall.torch = 2 - - local walldef = { - drawtype = "mesh", - mesh = mesh_wall, - tiles = tiles, - paramtype = "light", - paramtype2 = "wallmounted", - sunlight_propagates = true, - is_ground_content = false, - walkable = false, - light_source = light, - groups = groups_wall, - drop = itemstring, - selection_box = { - type = "wallmounted", - wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1}, - wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1}, - wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1}, - }, - sounds = sounds, - on_rotate = false, - } - if moredef ~= nil then - for k,v in pairs(moredef) do - walldef[k] = v - end - end - if moredef_wall ~= nil then - for k,v in pairs(moredef_wall) do - walldef[k] = v - end - end - minetest.register_node(itemstring_wall, walldef) - - - -- Add entry alias for the Help - if minetest.get_modpath("doc") then - doc.add_entry_alias("nodes", itemstring, "nodes", itemstring_wall) - end - -end - -mcl_torches.register_torch("torch", - S("Torch"), - S("Torches are light sources which can be placed at the side or on the top of most blocks."), - nil, - "default_torch_on_floor.png", - "mcl_torches_torch_floor.obj", "mcl_torches_torch_wall.obj", - {{ - name = "default_torch_on_floor_animated.png", - animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} - }}, - LIGHT_TORCH, - {dig_immediate=3, torch=1, deco_block=1}, - mcl_sounds.node_sound_wood_defaults(), - {_doc_items_hidden = false, - on_destruct = function(pos) - remove_flames(pos) - end}, - {on_construct = function(pos) - spawn_flames_floor(pos) - end}, - {on_construct = function(pos) - local node = minetest.get_node(pos) - spawn_flames_wall(pos, node.param2) - end}) - -minetest.register_craft({ - output = "mcl_torches:torch 4", - recipe = { - { "group:coal" }, - { "mcl_core:stick" }, - } -}) - -minetest.register_lbm({ - label = "Torch flame particles", - name = "mcl_torches:flames", - nodenames = {"mcl_torches:torch", "mcl_torches:torch_wall"}, - run_at_every_load = true, - action = function(pos, node) - if node.name == "mcl_torches:torch" then - spawn_flames_floor(pos) - elseif node.name == "mcl_torches:torch_wall" then - spawn_flames_wall(pos, node.param2) - end - end, -}) +local modpath = minetest.get_modpath(minetest.get_current_modname()) +dofile(modpath .. "/api.lua") +dofile(modpath .. "/register.lua") diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr new file mode 100644 index 000000000..eccc36053 --- /dev/null +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_torches +Torch=松明 +Torches are light sources which can be placed at the side or on the top of most blocks.=松明は光源で、ほとんどのブロックの側面や上部に設置できます。 diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.pl.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.pl.tr new file mode 100644 index 000000000..ae1c118ae --- /dev/null +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.pl.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_torches +Torch=Pochodnia +Torches are light sources which can be placed at the side or on the top of most blocks.=Pochodnie są źródłami światła, które może zostać postawione na boku lub na górze większości bloków. diff --git a/mods/ITEMS/mcl_torches/locale/mcl_torches.zh_TW.tr b/mods/ITEMS/mcl_torches/locale/mcl_torches.zh_TW.tr new file mode 100644 index 000000000..01088cd96 --- /dev/null +++ b/mods/ITEMS/mcl_torches/locale/mcl_torches.zh_TW.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_torches +Torch=火把 +Torches are light sources which can be placed at the side or on the top of most blocks.=火把是光源,可以放在大多數方塊的側面或頂部。 diff --git a/mods/ITEMS/mcl_torches/mod.conf b/mods/ITEMS/mcl_torches/mod.conf index ec9cfb624..b383df2a7 100644 --- a/mods/ITEMS/mcl_torches/mod.conf +++ b/mods/ITEMS/mcl_torches/mod.conf @@ -1 +1,4 @@ name = mcl_torches +description = Mesh-based torches - three dimensional torches for minetest. +depends = mcl_core, mcl_sounds, mcl_particles +optional_depends = doc diff --git a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj index ac4234d3e..b0683b59c 100644 --- a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj +++ b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_floor.obj @@ -1,29 +1,72 @@ -# Blender v2.76 (sub 0) OBJ File: 'torch_on_floor_node.blend' +# Blender 3.3.1 # www.blender.org -o torch_Cube_Cube.001_Cube_Cube.001_Material.001 +mtllib mcl_torches_torch_floor.mtl +o cube.004 +v -0.062500 0.437500 -0.500000 +v -0.062500 -0.562500 -0.500000 +v -0.062500 0.437500 0.500000 +v -0.062500 -0.562500 0.500000 v 0.062500 0.062500 0.062500 v 0.062500 0.062500 -0.062500 +v 0.062500 -0.562500 0.062500 +v 0.062500 -0.562500 -0.062500 v -0.062500 0.062500 -0.062500 v -0.062500 0.062500 0.062500 -v -0.062500 -0.500000 0.062500 -v 0.062500 -0.500000 0.062500 -v 0.062500 -0.500000 -0.062500 -v -0.062500 -0.500000 -0.062500 +v -0.062500 -0.562500 -0.062500 +v -0.062500 -0.562500 0.062500 +v 0.500000 0.437500 0.062500 +v 0.500000 -0.562500 0.062500 +v -0.500000 0.437500 0.062500 +v -0.500000 -0.562500 0.062500 +v 0.500000 0.437500 -0.062500 +v 0.500000 -0.562500 -0.062500 +v -0.500000 0.437500 -0.062500 +v -0.500000 -0.562500 -0.062500 +v 0.062500 0.437500 -0.500000 +v 0.062500 -0.562500 -0.500000 +v 0.062500 0.437500 0.500000 +v 0.062500 -0.562500 0.500000 +vn 1.0000 -0.0000 -0.0000 +vn -0.0000 1.0000 -0.0000 +vn -0.0000 -1.0000 -0.0000 +vn -0.0000 -0.0000 -1.0000 +vn -0.0000 -0.0000 1.0000 +vn -1.0000 -0.0000 -0.0000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 vt 0.562500 0.500000 vt 0.562500 0.625000 +vt 0.562500 0.125000 +vt 0.562500 0.000063 vt 0.437500 0.625000 vt 0.437500 0.500000 -vt 0.437500 0.000000 -vt 0.562500 0.000000 -vt 0.562500 0.125000 +vt 0.437500 0.000063 vt 0.437500 0.125000 -vn 0.000000 1.000000 0.000000 -vn 0.000000 0.000000 -1.000000 -vn 1.000000 0.000000 0.000000 -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/2/2 6/6/2 5/5/2 4/3/2 -f 2/3/3 1/2/3 6/6/3 7/5/3 -f 3/2/2 2/3/2 7/5/2 8/6/2 -f 4/3/3 5/5/3 8/6/3 3/2/3 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +s 0 +usemtl m_0.002 +f 3/3/1 4/4/1 1/1/1 +f 4/4/1 2/2/1 1/1/1 +f 9/9/2 10/10/2 6/6/2 +f 10/10/2 5/5/2 6/6/2 +f 12/12/3 11/11/3 7/7/3 +f 11/11/3 8/8/3 7/7/3 +f 13/13/4 14/14/4 15/15/4 +f 14/14/4 16/16/4 15/15/4 +f 19/19/5 20/20/5 17/17/5 +f 20/20/5 18/18/5 17/17/5 +f 21/21/6 22/22/6 23/23/6 +f 22/22/6 24/24/6 23/23/6 diff --git a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj index 824223e6d..35c192c25 100644 --- a/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj +++ b/mods/ITEMS/mcl_torches/models/mcl_torches_torch_wall.obj @@ -1,29 +1,72 @@ -# Blender v2.76 (sub 0) OBJ File: 'torch_on_wall_node.blend' +# Blender 3.3.1 # www.blender.org -o torch_wall_Cube_Cube.001_Cube_Cube.001_Material.001 -v 0.062469 -0.303502 0.086070 -v 0.062469 -0.195248 0.023570 -v -0.062531 -0.195248 0.023570 -v -0.062531 -0.303502 0.086070 -v -0.062531 -0.584752 -0.401070 -v 0.062469 -0.584752 -0.401070 -v 0.062469 -0.476498 -0.463570 -v -0.062531 -0.476498 -0.463570 +mtllib mcl_torches_torch_wall.mtl +o cube +v -0.062500 -0.198340 0.273825 +v -0.062500 -0.313825 0.321660 +v -0.062500 -0.437517 -0.303600 +v -0.062500 -0.553002 -0.255765 +v 0.062500 -0.313825 0.321660 +v 0.062500 -0.198340 0.273825 +v 0.062500 -0.553002 -0.255765 +v 0.062500 -0.437517 -0.303600 +v -0.500000 -0.054833 0.620280 +v -0.500000 -0.437517 -0.303600 +v 0.500000 -0.054834 0.620280 +v 0.500000 -0.437517 -0.303600 +v -0.500000 -0.170318 0.668115 +v -0.500000 -0.553002 -0.255765 +v 0.500000 -0.170318 0.668115 +v 0.500000 -0.553002 -0.255765 +v -0.062500 -0.574516 0.835539 +v -0.062500 -0.957199 -0.088340 +v -0.062500 0.349364 0.452856 +v -0.062500 -0.033320 -0.471024 +v 0.062500 -0.574516 0.835539 +v 0.062500 -0.957199 -0.088340 +v 0.062500 0.349364 0.452856 +v 0.062500 -0.033320 -0.471024 +vn -0.0000 0.3827 0.9239 +vn -0.0000 -0.3827 -0.9239 +vn -0.0000 -0.9239 0.3827 +vn -0.0000 0.9239 -0.3827 +vn 1.0000 -0.0000 -0.0000 +vn -1.0000 -0.0000 -0.0000 vt 0.562500 0.500000 vt 0.562500 0.625000 +vt 0.562500 0.125000 +vt 0.562500 0.000063 vt 0.437500 0.625000 vt 0.437500 0.500000 -vt 0.437500 0.000000 -vt 0.562500 0.000000 -vt 0.562500 0.125000 +vt 0.437500 0.000063 vt 0.437500 0.125000 -vn 0.000000 0.500000 0.866000 -vn 0.000000 0.866000 -0.500000 -vn 1.000000 -0.000000 0.000000 -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/2/2 6/6/2 5/5/2 4/3/2 -f 2/3/3 1/2/3 6/6/3 7/5/3 -f 3/2/2 2/3/2 7/5/2 8/6/2 -f 4/3/3 5/5/3 8/6/3 3/2/3 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 1.000000 1.000000 +vt 1.000000 0.000000 +vt 0.000000 1.000000 +vt 0.000000 0.000000 +s 0 +usemtl m_0.001 +f 5/5/1 6/6/1 2/2/1 +f 6/6/1 1/1/1 2/2/1 +f 8/8/2 7/7/2 3/3/2 +f 7/7/2 4/4/2 3/3/2 +f 9/9/3 10/10/3 11/11/3 +f 10/10/3 12/12/3 11/11/3 +f 15/15/4 16/16/4 13/13/4 +f 16/16/4 14/14/4 13/13/4 +f 17/17/5 18/18/5 19/19/5 +f 18/18/5 20/20/5 19/19/5 +f 23/23/6 24/24/6 21/21/6 +f 24/24/6 22/22/6 21/21/6 diff --git a/mods/ITEMS/mcl_torches/register.lua b/mods/ITEMS/mcl_torches/register.lua new file mode 100644 index 000000000..4eead4024 --- /dev/null +++ b/mods/ITEMS/mcl_torches/register.lua @@ -0,0 +1,28 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +mcl_torches.register_torch({ + name = "torch", + description = S("Torch"), + doc_items_longdesc = S("Torches are light sources which can be placed at the side or on the top of most blocks."), + doc_items_hidden = false, + icon = "default_torch_on_floor.png", + tiles = {{ + name = "default_torch_on_floor_animated.png", + animation = {type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 3.3} + }}, + -- this is 15 in minecraft + light = 14, + groups = {dig_immediate = 3, deco_block = 1}, + sounds = mcl_sounds.node_sound_wood_defaults(), + particles = true, + flame_type = 1, +}) + +minetest.register_craft({ + output = "mcl_torches:torch 4", + recipe = { + {"group:coal"}, + {"mcl_core:stick"}, + } +}) + diff --git a/mods/ITEMS/mcl_torches/screenshot.png b/mods/ITEMS/mcl_torches/screenshot.png deleted file mode 100644 index 5c9f85919..000000000 Binary files a/mods/ITEMS/mcl_torches/screenshot.png and /dev/null differ diff --git a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png deleted file mode 100644 index cb0ce15f1..000000000 Binary files a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor.png and /dev/null differ diff --git a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png b/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png deleted file mode 100644 index 28cdc64c7..000000000 Binary files a/mods/ITEMS/mcl_torches/textures/default_torch_on_floor_animated.png and /dev/null differ diff --git a/mods/ITEMS/mcl_totems/depends.txt b/mods/ITEMS/mcl_totems/depends.txt deleted file mode 100644 index 9b7650e03..000000000 --- a/mods/ITEMS/mcl_totems/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mobs_mc diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index b4ec3eb8d..26874b50b 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -1,5 +1,107 @@ --- Node is currently defined in mobs_mc. --- TODO: Add full item definition here when status effects become a thing. +local S = minetest.get_translator(minetest.get_current_modname()) --- Add group for Creative Mode. -minetest.override_item("mobs_mc:totem", {groups = { combat_item=1}}) +local hud_totem = {} + +minetest.register_on_leaveplayer(function(player) + hud_totem[player] = nil +end) + +minetest.register_craftitem("mcl_totems:totem", { + description = S("Totem of Undying"), + _tt_help = minetest.colorize(mcl_colors.GREEN, S("Protects you from death while wielding it")), + _doc_items_longdesc = S("A totem of undying is a rare artifact which may safe you from certain death."), + _doc_items_usagehelp = S("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."), + inventory_image = "mcl_totems_totem.png", + wield_image = "mcl_totems_totem.png", + stack_max = 1, + groups = {combat_item = 1, offhand_item = 1}, +}) +minetest.register_alias("mobs_mc:totem", "mcl_totems:totem") + +local particle_colors = {"98BF22", "C49E09", "337D0B", "B0B021", "1E9200"} -- TODO: real MC colors + +-- Save the player from death when holding totem of undying in hand +mcl_damage.register_modifier(function(obj, damage, reason) + if obj:is_player() and not reason.bypasses_totem then + local hp = obj:get_hp() + if hp - damage <= 0 then + local wield = obj:get_wielded_item() + local in_offhand = false + if not (wield:get_name() == "mcl_totems:totem") then + local inv = obj:get_inventory() + if inv then + wield = obj:get_inventory():get_stack("offhand", 1) + in_offhand = true + end + end + if wield:get_name() == "mcl_totems:totem" then + local ppos = obj:get_pos() + local pnname = minetest.get_node(ppos).name + + if obj:get_breath() < 11 then + obj:set_breath(10) + end + + if not minetest.is_creative_enabled(obj:get_player_name()) then + wield:take_item() + if in_offhand then + obj:get_inventory():set_stack("offhand", 1, wield) + mcl_inventory.update_inventory_formspec(obj) + else + obj:set_wielded_item(wield) + end + end + awards.unlock(obj:get_player_name(), "mcl:postMortal") + + -- Effects + minetest.sound_play({name = "mcl_totems_totem", gain = 1}, {pos=ppos, max_hear_distance = 16}, true) + + for i = 1, 4 do + for c = 1, #particle_colors do + minetest.add_particlespawner({ + amount = math.floor(100 / (4 * #particle_colors)), + time = 1, + minpos = vector.offset(ppos, 0, -1, 0), + maxpos = vector.offset(ppos, 0, 1, 0), + minvel = vector.new(-1.5, 0, -1.5), + maxvel = vector.new(1.5, 1.5, 1.5), + minacc = vector.new(0, -0.1, 0), + maxacc = vector.new(0, -1, 0), + minexptime = 1, + maxexptime = 3, + minsize = 1, + maxsize = 2, + collisiondetection = true, + collision_removal = true, + object_collision = false, + vertical = false, + texture = "mcl_particles_totem" .. i .. ".png^[colorize:#" .. particle_colors[c], + glow = 10, + }) + end + end + + -- Big totem overlay + if not hud_totem[obj] then + hud_totem[obj] = obj:hud_add({ + hud_elem_type = "image", + text = "mcl_totems_totem.png", + position = {x = 0.5, y = 1}, + scale = {x = 17, y = 17}, + offset = {x = 0, y = -178}, + z_index = 100, + }) + minetest.after(3, function() + if obj:is_player() then + obj:hud_remove(hud_totem[obj]) + hud_totem[obj] = nil + end + end) + end + + -- Set HP to exactly 1 + return hp - 1 + end + end + end +end, 1000) diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.de.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.de.tr new file mode 100644 index 000000000..e0ac4f2f1 --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.de.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=Totem der Unsterblichkeit +A totem of undying is a rare artifact which may safe you from certain death.=Ein Totem der Unsterblichkeit ist ein seltenes Artefakt, dass Sie vor dem sicheren Tod bewahren kann. +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.=Der Totem funktioniert nur, während Sie ihn halten. Wenn Sie normalerweise tödlich hohen Schaden erhalten, werden Sie vor dem Tod bewahrt und Sie erhalten eine zweite Chance mit 1 TP. Der Totem wird dabei zerstört. +Protects you from death while wielding it=Schützt vor dem Tod, wenn es gehalten wird diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.es.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.es.tr new file mode 100644 index 000000000..2b451ccb1 --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.es.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_totems +Totem of Undying=Tótem de la inmortalidad +A totem of undying is a rare artifact which may safe you from certain death.=Un tótem de la inmortalidad es un artefacto raro que puede salvarte de una muerte segura. +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.=El tótem solo funciona mientras lo sostienes en tu mano. Si recibes un daño crítico, no mueres y obtienes una segunda oportunidad con 1 HP. Sin embargo, el tótem se destruye en el proceso. diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.fr.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.fr.tr new file mode 100644 index 000000000..174251f3c --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.fr.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=Totem d'immortalité +A totem of undying is a rare artifact which may safe you from certain death.=Un totem d'immortalité est un artefact rare qui peut vous protéger d'une mort certaine. +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.=Le totem ne fonctionne que lorsque vous le tenez dans votre main. Si vous recevez des dégâts mortels, vous êtes sauvé de la mort et vous obtenez une seconde chance avec 1 HP. Cependant, le totem est détruit. +Protects you from death while wielding it=Vous protège de la mort en la maniant diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr new file mode 100644 index 000000000..ff57aa264 --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=不死のトーテム +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.=トーテムは手に持っている間だけ御利益があります。致命傷を受けても、死から救済され HP1で再チャンスを得られます。がしかし、その過程でトーテムは壊れてしまいます。 +Protects you from death while wielding it=それを手にしている間、死からあなたを守護 diff --git a/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr b/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr new file mode 100644 index 000000000..d293efe01 --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/mcl_totems.ru.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying=Тотем бессмертия +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=Защищает вас от смерти, пока вы владеете им diff --git a/mods/ITEMS/mcl_totems/locale/template.txt b/mods/ITEMS/mcl_totems/locale/template.txt new file mode 100644 index 000000000..7afebc44c --- /dev/null +++ b/mods/ITEMS/mcl_totems/locale/template.txt @@ -0,0 +1,5 @@ +# textdomain: mcl_totems +Totem of Undying= +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.= +Protects you from death while wielding it= diff --git a/mods/ITEMS/mcl_totems/mod.conf b/mods/ITEMS/mcl_totems/mod.conf new file mode 100644 index 000000000..4ba94defc --- /dev/null +++ b/mods/ITEMS/mcl_totems/mod.conf @@ -0,0 +1,2 @@ +name = mcl_totems +depends = mobs_mc, mcl_damage diff --git a/mods/ITEMS/mcl_walls/depends.txt b/mods/ITEMS/mcl_walls/depends.txt deleted file mode 100644 index de1f8a39b..000000000 --- a/mods/ITEMS/mcl_walls/depends.txt +++ /dev/null @@ -1,6 +0,0 @@ -mcl_core -mcl_end -mcl_ocean -mcl_nether -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_walls/init.lua b/mods/ITEMS/mcl_walls/init.lua index 5704309db..14b512ffd 100644 --- a/mods/ITEMS/mcl_walls/init.lua +++ b/mods/ITEMS/mcl_walls/init.lua @@ -1,4 +1,6 @@ -local S = minetest.get_translator("mcl_walls") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) mcl_walls = {} @@ -29,7 +31,7 @@ local function update_wall(pos) local colonpos = thisnode.name:find(":") local underscorepos local itemname, basename, modname - if colonpos ~= nil then + if colonpos then itemname = thisnode.name:sub(colonpos+1) modname = thisnode.name:sub(1, colonpos-1) end @@ -151,12 +153,13 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory minetest.register_node(nodename.."_"..i, { collision_box = { - type = 'fixed', + type = "fixed", fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16} }, drawtype = "nodebox", is_ground_content = false, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", sunlight_propagates = true, groups = internal_groups, @@ -179,10 +182,11 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory minetest.register_node(nodename.."_16", { drawtype = "nodebox", collision_box = { - type = 'fixed', + type = "fixed", fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16} }, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", sunlight_propagates = true, is_ground_content = false, @@ -204,10 +208,11 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory minetest.register_node(nodename.."_21", { drawtype = "nodebox", collision_box = { - type = 'fixed', + type = "fixed", fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16} }, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, paramtype = "light", sunlight_propagates = true, is_ground_content = false, @@ -235,6 +240,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory is_ground_content = false, groups = main_node_groups, tiles = tiles, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, inventory_image = inventory_image, stack_max = 64, drawtype = "nodebox", @@ -243,7 +249,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory fixed = pillar }, collision_box = { - type = 'fixed', + type = "fixed", fixed = {-4/16, -0.5, -4/16, 4/16, 1, 4/16} }, collisionbox = {-0.2, 0, -0.2, 0.2, 1.4, 0.2}, @@ -263,7 +269,7 @@ function mcl_walls.register_wall(nodename, description, source, tiles, inventory end end -dofile(minetest.get_modpath("mcl_walls") .. "/register.lua") +dofile(modpath.."/register.lua") minetest.register_on_placenode(update_wall_global) minetest.register_on_dignode(update_wall_global) diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr index e4bbfd0dd..8fe748c81 100644 --- a/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.fr.tr @@ -14,3 +14,4 @@ Prismarine Wall=Muret de Prismarine End Stone Brick Wall=Muret de Brique de l'End Nether Brick Wall=Muret de Brique du Nether Red Nether Brick Wall=Muret de Brique Rouge du Nether +Mud Brick Wall=Muret de Brique de Boue \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.tr new file mode 100644 index 000000000..c568788a7 --- /dev/null +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.ja.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.=壁の一部。単なるジャンプでは飛び越えられません。これを複数個並べて置いたなら、自動的にイイ感じの壁面に仕上がるでしょう。 +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=苔むした石レンガの壁 +Prismarine Wall=プリズマリンの壁 +End Stone Brick Wall=エンドストーンレンガの壁 +Nether Brick Wall=ネザーレンガの壁 +Red Nether Brick Wall=赤いネザーレンガの壁 +Mud Brick Wall=泥レンガの壁 \ No newline at end of file diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.pl.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.pl.tr new file mode 100644 index 000000000..9d75eb18d --- /dev/null +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.pl.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.=Kawałek ściany. Nie może być przeskoczony pojedynczym skokiem. Gdy kilka z nich jest położonych obok siebie, automatycznie połączą się one w ścianę. +Cobblestone Wall=Ściana z brukowca +Mossy Cobblestone Wall=Ściana z zamszonego brukowca +Andesite Wall=Andezytowa ściana +Granite Wall=Granitowa ściana +Diorite Wall=Diorytowa ściana +Brick Wall=Ceglana ściana +Sandstone Wall=Ściana z piaskowca +Red Sandstone Wall=Ściana z czerwienitu +Stone Brick Wall=Ściana z ceglanego kamienia +Mossy Stone Brick Wall=Ściana z zamszonego ceglanego kamienia +Prismarine Wall=Pryzmarynowa ściana +End Stone Brick Wall=Ściana z ceglanego kamienia Kresu +Nether Brick Wall=Ściana z Netherowej cegły +Red Nether Brick Wall=Ściana z czerwonej Netherowej cegły + diff --git a/mods/ITEMS/mcl_walls/locale/mcl_walls.zh_TW.tr b/mods/ITEMS/mcl_walls/locale/mcl_walls.zh_TW.tr new file mode 100644 index 000000000..111241e04 --- /dev/null +++ b/mods/ITEMS/mcl_walls/locale/mcl_walls.zh_TW.tr @@ -0,0 +1,16 @@ +# 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.=一塊牆。它不能用簡單的跳躍方式跳過去。當多個這樣的東西被放在一起時,它們會自動建立一個漂亮的牆體結構。 +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=青苔石磚牆 +Prismarine Wall=海磷石牆 +End Stone Brick Wall=終界石磚牆 +Nether Brick Wall=地獄磚牆 +Red Nether Brick Wall=紅地獄磚牆 diff --git a/mods/ITEMS/mcl_walls/locale/template.txt b/mods/ITEMS/mcl_walls/locale/template.txt index 765365997..e4bfa3602 100644 --- a/mods/ITEMS/mcl_walls/locale/template.txt +++ b/mods/ITEMS/mcl_walls/locale/template.txt @@ -14,3 +14,4 @@ Prismarine Wall= End Stone Brick Wall= 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 new file mode 100644 index 000000000..b6b221007 --- /dev/null +++ b/mods/ITEMS/mcl_walls/mod.conf @@ -0,0 +1,3 @@ +name = mcl_walls +depends = mcl_core, mcl_end, mcl_ocean, mcl_nether, mcl_sounds, mcl_mud +optional_depends = doc diff --git a/mods/ITEMS/mcl_walls/register.lua b/mods/ITEMS/mcl_walls/register.lua index 0ccefd62f..96a1b9b9f 100644 --- a/mods/ITEMS/mcl_walls/register.lua +++ b/mods/ITEMS/mcl_walls/register.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_walls") +local S = minetest.get_translator(minetest.get_current_modname()) mcl_walls.register_wall("mcl_walls:cobble", S("Cobblestone Wall"), "mcl_core:cobble", {"mcl_walls_cobble_wall_top.png", "default_cobble.png", "mcl_walls_cobble_wall_side.png"}) mcl_walls.register_wall("mcl_walls:mossycobble", S("Mossy Cobblestone Wall"), "mcl_core:mossycobble", {"mcl_walls_cobble_mossy_wall_top.png", "default_mossycobble.png", "mcl_walls_cobble_mossy_wall_side.png"}) @@ -14,3 +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 diff --git a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_side.png b/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_side.png deleted file mode 100644 index 69d575d98..000000000 Binary files a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_top.png b/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_top.png deleted file mode 100644 index c6ca4c364..000000000 Binary files a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_mossy_wall_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_side.png b/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_side.png deleted file mode 100644 index 01937236d..000000000 Binary files a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_side.png and /dev/null differ diff --git a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_top.png b/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_top.png deleted file mode 100644 index bdde29c6c..000000000 Binary files a/mods/ITEMS/mcl_walls/textures/mcl_walls_cobble_wall_top.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/depends.txt b/mods/ITEMS/mcl_wool/depends.txt deleted file mode 100644 index 9699080ad..000000000 --- a/mods/ITEMS/mcl_wool/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_sounds -doc? diff --git a/mods/ITEMS/mcl_wool/init.lua b/mods/ITEMS/mcl_wool/init.lua index 22648efc9..65cbb8708 100644 --- a/mods/ITEMS/mcl_wool/init.lua +++ b/mods/ITEMS/mcl_wool/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mcl_wool") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") -- minetest/wool/init.lua @@ -71,12 +71,11 @@ for _, row in ipairs(wool.dyes) do _doc_items_entry_name = name_carpet, _doc_items_longdesc = longdesc_carpet, - walkable = false, -- See is_ground_content = false, tiles = {texture..".png"}, wield_image = texture..".png", wield_scale = { x=1, y=1, z=0.5 }, - groups = {handy=1, carpet=1,attached_node=1,flammable=1,fire_encouragement=60, fire_flammability=20, dig_by_water=1,deco_block=1,[color_group]=1}, + groups = {handy=1, carpet=1,supported_node=1,flammable=1,fire_encouragement=60, fire_flammability=20, dig_by_water=1,deco_block=1,[color_group]=1}, sounds = mcl_sounds.node_sound_wool_defaults(), paramtype = "light", sunlight_propagates = true, @@ -99,13 +98,13 @@ for _, row in ipairs(wool.dyes) do -- Crafting from dye and white wool minetest.register_craft({ type = "shapeless", - output = 'mcl_wool:'..name, - recipe = {"mcl_dye:"..dye, 'mcl_wool:white'}, + output = "mcl_wool:"..name, + recipe = {"mcl_dye:"..dye, "mcl_wool:white"}, }) end minetest.register_craft({ - output = 'mcl_wool:'..name..'_carpet 3', - recipe = {{'mcl_wool:'..name, 'mcl_wool:'..name}}, + output = "mcl_wool:"..name.."_carpet 3", + recipe = {{"mcl_wool:"..name, "mcl_wool:"..name}}, }) end diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.de.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.de.tr index 5b979d51b..9f67a52fb 100644 --- a/mods/ITEMS/mcl_wool/locale/mcl_wool.de.tr +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.de.tr @@ -22,7 +22,7 @@ Blue Carpet=Blauer Teppich Magenta Wool=Magenta Wolle Magenta Carpet=Magenta Teppich Orange Wool=Orange Wolle -Orange Carpet=Orange Teppich +Orange Carpet=Oranger Teppich Purple Wool=Violette Wolle Purple Carpet=Violetter Teppich Brown Wool=Braune Wolle diff --git a/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr new file mode 100644 index 000000000..9b8ed335a --- /dev/null +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.ja.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_wool +Wool=羊毛 +Carpet=カーペット +White Wool=白色の羊毛 +White Carpet=白色のカーペット +Grey Wool=灰色の羊毛 +Grey Carpet=灰色のカーペット +Light Grey Wool=薄灰色の羊毛 +Light Grey Carpet=薄灰色のカーペット +Black Wool=黒色の羊毛 +Black Carpet=黒色のカーペット +Red Wool=赤色の羊毛 +Red Carpet=赤色のカーペット +Yellow Wool=黄色の羊毛 +Yellow Carpet=黄色のカーペット +Green Wool=緑色の羊毛 +Green Carpet=緑色のカーペット +Cyan Wool=青緑色の羊毛 +Cyan Carpet=青緑色のカーペット +Blue Wool=青色の羊毛 +Blue Carpet=青色のカーペット +Magenta Wool=赤紫色の羊毛 +Magenta Carpet=赤紫色のカーペット +Orange Wool=橙色の羊毛 +Orange Carpet=橙色のカーペット +Purple Wool=紫色の羊毛 +Purple Carpet=紫色のカーペット +Brown Wool=茶色の羊毛 +Brown Carpet=茶色のカーペット +Pink Wool=桃色の羊毛 +Pink 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/mcl_wool/locale/mcl_wool.pl.tr b/mods/ITEMS/mcl_wool/locale/mcl_wool.pl.tr new file mode 100644 index 000000000..ac92171d1 --- /dev/null +++ b/mods/ITEMS/mcl_wool/locale/mcl_wool.pl.tr @@ -0,0 +1,37 @@ +# textdomain: mcl_wool +Wool=Wełna +Carpet=Dywan +White Wool=Biała wełna +White Carpet=Biały dywan +Grey Wool=Szara wełna +Grey Carpet=Szary dywan +Light Grey Wool=Jasnoszara wełna +Light Grey Carpet=Jasnoszary dywan +Black Wool=Czarna wełna +Black Carpet=Czarny dywan +Red Wool=Czerwona wełna +Red Carpet=Czerwony dywan +Yellow Wool=Żółta wełna +Yellow Carpet=Żółty dywan +Green Wool=Zielona wełna +Green Carpet=Zielony dywan +Cyan Wool=Błękitna wełna +Cyan Carpet=Błękitny dywan +Blue Wool=Niebieska wełna +Blue Carpet=Niebieski dywan +Magenta Wool=Karmazynowa wełna +Magenta Carpet=Karmazynowy dywan +Orange Wool=Pomarańczowa wełna +Orange Carpet=Pomarańczowy dywan +Purple Wool=Fioletowa wełna +Purple Carpet=Fioletowy dywan +Brown Wool=Brązowa wełna +Brown Carpet=Brązowy dywan +Pink Wool=Różowa wełna +Pink Carpet=Różowy dywan +Lime Wool=Jasnozielona wełna +Lime Carpet=Jasnozielony dywan +Light Blue Wool=Jasnoniebieska wełna +Light Blue Carpet=Jasnoniebieski dywan +Wool is a decorative block which comes in many different colors.=Wełna jest blokiem dekoracyjnym, który może mieć wiele różnych kolorów. +Carpets are thin floor covers which come in many different colors.=Dywany są cienkimi pokrywami na podłogi, które mogą mieć wiele różnych kolorów. diff --git a/mods/ITEMS/mcl_wool/mod.conf b/mods/ITEMS/mcl_wool/mod.conf index 2a4f86800..b7e9a4dab 100644 --- a/mods/ITEMS/mcl_wool/mod.conf +++ b/mods/ITEMS/mcl_wool/mod.conf @@ -1 +1,3 @@ name = mcl_wool +depends = mcl_sounds +optional_depends = doc diff --git a/mods/ITEMS/mcl_wool/textures/mcl_wool_light_blue.png b/mods/ITEMS/mcl_wool/textures/mcl_wool_light_blue.png deleted file mode 100644 index 3d37d909e..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/mcl_wool_light_blue.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/mcl_wool_lime.png b/mods/ITEMS/mcl_wool/textures/mcl_wool_lime.png deleted file mode 100644 index 6d57a55d4..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/mcl_wool_lime.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_brown.png b/mods/ITEMS/mcl_wool/textures/wool_brown.png deleted file mode 100644 index 04cf6eb83..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_brown.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_cyan.png b/mods/ITEMS/mcl_wool/textures/wool_cyan.png deleted file mode 100644 index d4e48d6ad..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_cyan.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_dark_green.png b/mods/ITEMS/mcl_wool/textures/wool_dark_green.png deleted file mode 100644 index 9e3c29f2e..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_dark_green.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_dark_grey.png b/mods/ITEMS/mcl_wool/textures/wool_dark_grey.png deleted file mode 100644 index e2af0870c..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_dark_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_grey.png b/mods/ITEMS/mcl_wool/textures/wool_grey.png deleted file mode 100644 index 69273bfe0..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_grey.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_magenta.png b/mods/ITEMS/mcl_wool/textures/wool_magenta.png deleted file mode 100644 index 6f727a973..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_magenta.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_red.png b/mods/ITEMS/mcl_wool/textures/wool_red.png deleted file mode 100644 index 4c84133a1..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_red.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_violet.png b/mods/ITEMS/mcl_wool/textures/wool_violet.png deleted file mode 100644 index 12fb3ebb7..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_violet.png and /dev/null differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_white.png b/mods/ITEMS/mcl_wool/textures/wool_white.png deleted file mode 100644 index 794cbb15f..000000000 Binary files a/mods/ITEMS/mcl_wool/textures/wool_white.png and /dev/null differ diff --git a/mods/ITEMS/mclx_core/depends.txt b/mods/ITEMS/mclx_core/depends.txt deleted file mode 100644 index 870d9cb09..000000000 --- a/mods/ITEMS/mclx_core/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_core -doc? diff --git a/mods/ITEMS/mclx_core/description.txt b/mods/ITEMS/mclx_core/description.txt deleted file mode 100644 index 422e6da57..000000000 --- a/mods/ITEMS/mclx_core/description.txt +++ /dev/null @@ -1 +0,0 @@ -Core items not found in Minecraft diff --git a/mods/ITEMS/mclx_core/init.lua b/mods/ITEMS/mclx_core/init.lua index bc17e0075..eb2c8a902 100644 --- a/mods/ITEMS/mclx_core/init.lua +++ b/mods/ITEMS/mclx_core/init.lua @@ -1,10 +1,14 @@ -local S = minetest.get_translator("mclx_core") +local S = minetest.get_translator(minetest.get_current_modname()) -- Liquids: River Water local source = table.copy(minetest.registered_nodes["mcl_core:water_source"]) source.description = S("River Water Source") source.liquid_range = 2 +source.waving = 3 +source.color = "#0084FF" +source.paramtype2 = nil +source.palette = nil source.liquid_alternative_flowing = "mclx_core:river_water_flowing" source.liquid_alternative_source = "mclx_core:river_water_source" source.liquid_renewable = false @@ -12,39 +16,17 @@ source._doc_items_longdesc = S("River water has the same properties as water, bu source._doc_items_entry_name = S("River Water") -- Auto-expose entry only in valleys mapgen source._doc_items_hidden = minetest.get_mapgen_setting("mg_name") ~= "valleys" -source.post_effect_color = {a=192, r=0x2c, g=0x88, b=0x8c} -source.tiles = { - {name="default_river_water_source_animated.png", animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}} -} -source.special_tiles = { - -- New-style water source material (mostly unused) - { - name="default_river_water_source_animated.png", - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=5.0}, - backface_culling = false, - } -} +source.post_effect_color = {a=60, r=0, g=132, b=255} local flowing = table.copy(minetest.registered_nodes["mcl_core:water_flowing"]) flowing.description = S("Flowing River Water") flowing.liquid_range = 2 +flowing.waving = 3 +flowing.color = "#0084FF" flowing.liquid_alternative_flowing = "mclx_core:river_water_flowing" flowing.liquid_alternative_source = "mclx_core:river_water_source" flowing.liquid_renewable = false -flowing.tiles = {"default_river_water_flowing_animated.png^[verticalframe:64:0"} -flowing.post_effect_color = {a=192, r=0x2c, g=0x88, b=0x8c} -flowing.special_tiles = { - { - image="default_river_water_flowing_animated.png", - backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} - }, - { - image="default_river_water_flowing_animated.png", - backface_culling=false, - animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=4.0} - }, -} +flowing.post_effect_color = {a=60, r=0, g=132, b=255} minetest.register_node("mclx_core:river_water_source", source) minetest.register_node("mclx_core:river_water_flowing", flowing) diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr b/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr new file mode 100644 index 000000000..038ab5675 --- /dev/null +++ b/mods/ITEMS/mclx_core/locale/mclx_core.ja.tr @@ -0,0 +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=河川水 +Flowing River Water=流れる河川水 diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.pl.tr b/mods/ITEMS/mclx_core/locale/mclx_core.pl.tr new file mode 100644 index 000000000..757507065 --- /dev/null +++ b/mods/ITEMS/mclx_core/locale/mclx_core.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mclx_core +River Water Source=Źródło wody rzecznej +River water has the same properties as water, but has a reduced flowing distance and is not renewable.=Woda rzeczna ma takie same własności jak woda, ale ma zmniejszony zasięg płynięcia i nie jest odnawialna. +River Water=Woda rzeczna +Flowing River Water=Płynąca woda rzeczna diff --git a/mods/ITEMS/mclx_core/locale/mclx_core.zh_TW.tr b/mods/ITEMS/mclx_core/locale/mclx_core.zh_TW.tr new file mode 100644 index 000000000..649fc353d --- /dev/null +++ b/mods/ITEMS/mclx_core/locale/mclx_core.zh_TW.tr @@ -0,0 +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=河水 +Flowing River Water=流動的河水 diff --git a/mods/ITEMS/mclx_core/mod.conf b/mods/ITEMS/mclx_core/mod.conf index 235cf6d3f..62e8d5fb3 100644 --- a/mods/ITEMS/mclx_core/mod.conf +++ b/mods/ITEMS/mclx_core/mod.conf @@ -1 +1,4 @@ name = mclx_core +description = Core items not found in Minecraft +depends = mcl_core +optional_depends = doc diff --git a/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png b/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png deleted file mode 100644 index 9e126d3c1..000000000 Binary files a/mods/ITEMS/mclx_core/textures/default_river_water_flowing_animated.png and /dev/null differ diff --git a/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png b/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png deleted file mode 100644 index fb8ae17bd..000000000 Binary files a/mods/ITEMS/mclx_core/textures/default_river_water_source_animated.png and /dev/null differ diff --git a/mods/ITEMS/mclx_fences/depends.txt b/mods/ITEMS/mclx_fences/depends.txt deleted file mode 100644 index 640669f2a..000000000 --- a/mods/ITEMS/mclx_fences/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_fences diff --git a/mods/ITEMS/mclx_fences/description.txt b/mods/ITEMS/mclx_fences/description.txt deleted file mode 100644 index 57005b4cf..000000000 --- a/mods/ITEMS/mclx_fences/description.txt +++ /dev/null @@ -1 +0,0 @@ -Additional fences and fence gates diff --git a/mods/ITEMS/mclx_fences/init.lua b/mods/ITEMS/mclx_fences/init.lua index 08c3d91ac..e78c7ef7f 100644 --- a/mods/ITEMS/mclx_fences/init.lua +++ b/mods/ITEMS/mclx_fences/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mclx_fences") +local S = minetest.get_translator(minetest.get_current_modname()) -- Red Nether Brick Fence @@ -25,7 +25,7 @@ mcl_fences.register_fence_gate( -- Crafting minetest.register_craft({ - output = 'mclx_fences:red_nether_brick_fence 6', + output = "mclx_fences:red_nether_brick_fence 6", recipe = { {"mcl_nether:red_nether_brick", "mcl_nether:netherbrick", "mcl_nether:red_nether_brick"}, {"mcl_nether:red_nether_brick", "mcl_nether:netherbrick", "mcl_nether:red_nether_brick"}, @@ -33,14 +33,14 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mclx_fences:red_nether_brick_fence_gate', + output = "mclx_fences:red_nether_brick_fence_gate", recipe = { {"mcl_nether:nether_wart_item", "mcl_nether:red_nether_brick", "mcl_nether:netherbrick"}, {"mcl_nether:netherbrick", "mcl_nether:red_nether_brick", "mcl_nether:nether_wart_item"}, } }) minetest.register_craft({ - output = 'mclx_fences:red_nether_brick_fence_gate', + output = "mclx_fences:red_nether_brick_fence_gate", recipe = { {"mcl_nether:netherbrick", "mcl_nether:red_nether_brick", "mcl_nether:nether_wart_item"}, {"mcl_nether:nether_wart_item", "mcl_nether:red_nether_brick", "mcl_nether:netherbrick"}, @@ -48,7 +48,7 @@ minetest.register_craft({ }) minetest.register_craft({ - output = 'mclx_fences:nether_brick_fence_gate 2', + output = "mclx_fences:nether_brick_fence_gate 2", recipe = { {"mcl_nether:netherbrick", "mcl_nether:nether_brick", "mcl_nether:netherbrick"}, {"mcl_nether:netherbrick", "mcl_nether:nether_brick", "mcl_nether:netherbrick"}, diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.fr.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.fr.tr index 244b588c1..77d38d2c6 100644 --- a/mods/ITEMS/mclx_fences/locale/mclx_fences.fr.tr +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.fr.tr @@ -1,4 +1,4 @@ # textdomain: mclx_fences Red Nether Brick Fence=Barrière en Brique Rouge du Nether -Red Nether Brick Fence Gate=Porte de Barrière en Brique Rouge du Nether -Nether Brick Fence Gate=Porte de Barrière en Brique du Nether +Red Nether Brick Fence Gate=Portillon en Brique Rouge du Nether +Nether Brick Fence Gate=Portillon en Brique du Nether diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr new file mode 100644 index 000000000..3e1383cef --- /dev/null +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mclx_fences +Red Nether Brick Fence=赤いネザーレンガのフェンス +Red Nether Brick Fence Gate=赤いネザーレンガのフェンスゲート +Nether Brick Fence Gate=ネザーレンガのフェンスゲート diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.pl.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.pl.tr new file mode 100644 index 000000000..ecdd84562 --- /dev/null +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.pl.tr @@ -0,0 +1,4 @@ +# textdomain: mclx_fences +Red Nether Brick Fence=Płot z czerwonej netherowej cegły +Red Nether Brick Fence Gate=Furtka z czerwonej netherowej cegły +Nether Brick Fence Gate=Furtka z netherowej cegły diff --git a/mods/ITEMS/mclx_fences/locale/mclx_fences.zh_TW.tr b/mods/ITEMS/mclx_fences/locale/mclx_fences.zh_TW.tr new file mode 100644 index 000000000..bf06d7240 --- /dev/null +++ b/mods/ITEMS/mclx_fences/locale/mclx_fences.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: mclx_fences +Red Nether Brick Fence=紅地獄磚柵欄 +Red Nether Brick Fence Gate=紅地獄磚柵欄門 +Nether Brick Fence Gate=地獄磚柵欄門 diff --git a/mods/ITEMS/mclx_fences/mod.conf b/mods/ITEMS/mclx_fences/mod.conf index b53158aad..a4795159d 100644 --- a/mods/ITEMS/mclx_fences/mod.conf +++ b/mods/ITEMS/mclx_fences/mod.conf @@ -1 +1,3 @@ name = mclx_fences +description = Additional fences and fence gates +depends = mcl_fences diff --git a/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_gate_red_nether_brick.png b/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_gate_red_nether_brick.png deleted file mode 100644 index 2436408bd..000000000 Binary files a/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_gate_red_nether_brick.png and /dev/null differ diff --git a/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_red_nether_brick.png b/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_red_nether_brick.png deleted file mode 100644 index ee7501818..000000000 Binary files a/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_red_nether_brick.png and /dev/null differ diff --git a/mods/ITEMS/mclx_stairs/depends.txt b/mods/ITEMS/mclx_stairs/depends.txt deleted file mode 100644 index 49805c174..000000000 --- a/mods/ITEMS/mclx_stairs/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_ocean -mcl_core -mcl_sounds -mcl_nether -mcl_end -mcl_colorblocks -mcl_stairs -doc? diff --git a/mods/ITEMS/mclx_stairs/description.txt b/mods/ITEMS/mclx_stairs/description.txt deleted file mode 100644 index 896be59b9..000000000 --- a/mods/ITEMS/mclx_stairs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Additional stairs and slabs not found in Minecraft 1.11 diff --git a/mods/ITEMS/mclx_stairs/init.lua b/mods/ITEMS/mclx_stairs/init.lua index 26ab5c4b5..effa87f13 100644 --- a/mods/ITEMS/mclx_stairs/init.lua +++ b/mods/ITEMS/mclx_stairs/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("mclx_stairs") +local S = minetest.get_translator(minetest.get_current_modname()) local doc_mod = minetest.get_modpath("doc") diff --git a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.fr.tr b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.fr.tr index 98becd492..243fc1e91 100644 --- a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.fr.tr +++ b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.fr.tr @@ -1,82 +1,82 @@ # textdomain: mclx_stairs -Oak Bark Stairs=Escalier en écorse de Chêne -Oak Bark Slab=Plaque d'écorce de Chêne -Double Oak Bark Slab=Double Dalle d'écorce de Chêne -Acacia Bark Stairs=Escalier en écorce d'Acacia -Acacia Bark Slab=Plaque d'écorce d'Acacia -Double Acacia Bark Slab=Double Dalle d'écorce d'Acacia -Spruce Bark Stairs=Escalier en écorse de Sapin -Spruce Bark Slab=Plaque d'écorce de Sapin -Double Spruce Bark Slab=Double Dalle d'écorce de Sapin -Birch Bark Stairs=Escalier en écorse de Bouleau -Birch Bark Slab=Plaque d'écorce de Bouleau -Double Birch Bark Slab=Double Dalle d'écorce de Bouleau -Jungle Bark Stairs=Escalier en écorse d'Acajou -Jungle Bark Slab=Plaque d'écorce d'Acajou -Double Jungle Bark Slab=Double Dalle d'écorce d'Acajou -Dark Oak Bark Stairs=Escalier en écorse de Chêne Noir -Dark Oak Bark Slab=Plaque d'écorce de Chêne Noir -Double Dark Oak Bark Slab=Double Dalle d'écorce de Chêne Noir -Lapis Lazuli Slab=Dalle de Lapis Lazuli -Double Lapis Lazuli Slab=Double Dalle de Lapis Lazuli -Lapis Lazuli Stairs=Escalier de Lapis Lazuli -Slab of Gold=Dalle en Or -Double Slab of Gold=Double Dalle en Or -Stairs of Gold=Escalier en Or -Slab of Iron=Dalle en Fer -Double Slab of Iron=Double Dalle en Fer -Stairs of Iron=Escalier en Fer -Cracked Stone Brick Stairs=Escalier en Brique de Pierre Fissurée -Cracked Stone Brick Slab=Dalle de Brique de Pierre Fissurée -Double Cracked Stone Brick Slab=Double Dalle de Brique de Pierre Fissurée -White Concrete Stairs=Escalier en Béton Blanc -White Concrete Slab=Dalle en Béton Blanc -Double White Concrete Slab=Double Dalle en Béton Blanc -Grey Concrete Stairs=Escalier en Béton Gris -Grey Concrete Slab=Dalle en Béton Gris -Double Grey Concrete Slab=Double Dalle en Béton Gris -Light Grey Concrete Stairs=Escalier en Béton Gris Clair -Light Grey Concrete Slab=Dalle en Béton Gris Clair -Double Light Grey Concrete Slab=Double Dalle en Béton Gris Clair -Black Concrete Stairs=Escalier en Béton Noir -Black Concrete Slab=Dalle en Béton Noir -Double Black Concrete Slab=Double Dalle en Béton Noir -Red Concrete Stairs=Escalier en Béton Rouge -Red Concrete Slab=Dalle en Béton Rouge -Double Red Concrete Slab=Double Dalle en Béton Rouge -Yellow Concrete Stairs=Escalier en Béton Jaune -Yellow Concrete Slab=Dalle en Béton Jaune -Double Yellow Concrete Slab=Double Dalle en Béton Jaune -Green Concrete Stairs=Escalier en Béton Vert -Green Concrete Slab=Dalle en Béton Vert -Double Green Concrete Slab=Double Dalle en Béton Vert -Cyan Concrete Stairs=Escalier en Béton Cyan -Cyan Concrete Slab=Dalle en Béton Cyan -Double Cyan Concrete Slab=Double Dalle en Béton Cyan -Blue Concrete Stairs=Escalier en Béton Bleu -Blue Concrete Slab=Dalle en Béton Bleu -Double Blue Concrete Slab=Double Dalle en Béton Bleu -Magenta Concrete Stairs=Escalier en Béton Magenta -Magenta Concrete Slab=Dalle en Béton Magenta -Double Magenta Concrete Slab=Double Dalle en Béton Magenta -Orange Concrete Stairs=Escalier en Béton Orange -Orange Concrete Slab=Dalle en Béton Orange -Double Orange Concrete Slab=Double Dalle en Béton Orange -Purple Concrete Stairs=Escalier en Béton Violet -Purple Concrete Slab=Dalle en Béton Violet -Double Purple Concrete Slab=Double Dalle en Béton Violet -Brown Concrete Stairs=Escalier en Béton Marron -Brown Concrete Slab=Dalle en Béton Marron -Double Brown Concrete Slab=Double Dalle en Béton Marron -Pink Concrete Stairs=Escalier en Béton Rose -Pink Concrete Slab=Dalle en Béton Rose -Double Pink Concrete Slab=Double Dalle en Béton Rose -Lime Concrete Stairs=Escalier en Béton Vert Clair -Lime Concrete Slab=Dalle en Béton Vert Clair -Double Lime Concrete Slab=Double Dalle en Béton Vert Clair -Light Blue Concrete Stairs=Escalier en Béton Bleu Clair -Light Blue Concrete Slab=Dalle en Béton Bleu Clair -Double Light Blue Concrete Slab=Double Dalle en Béton Bleu Clair -Concrete Slab=Dalle en Béton -Double Concrete Slab=Double Dalle en Béton -Concrete Stairs=Escalier en Béton +Oak Bark Stairs=Escalier en écorce de chêne +Oak Bark Slab=Plaque d'écorce de chêne +Double Oak Bark Slab=Double dalle d'écorce de chêne +Acacia Bark Stairs=Escalier en écorce d'acacia +Acacia Bark Slab=Plaque d'écorce d'acacia +Double Acacia Bark Slab=Double dalle d'écorce d'acacia +Spruce Bark Stairs=Escalier en écorce de sapin +Spruce Bark Slab=Plaque d'écorce de sapin +Double Spruce Bark Slab=Double dalle d'écorce de sapin +Birch Bark Stairs=Escalier en écorce de bouleau +Birch Bark Slab=Plaque d'écorce de bouleau +Double Birch Bark Slab=Double dalle d'écorce de bouleau +Jungle Bark Stairs=Escalier en écorce d'acajou +Jungle Bark Slab=Plaque d'écorce d'acajou +Double Jungle Bark Slab=Double dalle d'écorce d'acajou +Dark Oak Bark Stairs=Escalier en écorce de chêne noir +Dark Oak Bark Slab=Plaque d'écorce de chêne noir +Double Dark Oak Bark Slab=Double dalle d'écorce de chêne noir +Lapis Lazuli Slab=Dalle de lapis-lazuli +Double Lapis Lazuli Slab=Double dalle de lapis-lazuli +Lapis Lazuli Stairs=Escalier de lapis-lazuli +Slab of Gold=Dalle en or +Double Slab of Gold=Double dalle en or +Stairs of Gold=Escalier en or +Slab of Iron=Dalle en fer +Double Slab of Iron=Double dalle en fer +Stairs of Iron=Escalier en fer +Cracked Stone Brick Stairs=Escalier en brique de pierre fissurée +Cracked Stone Brick Slab=Dalle de brique de pierre fissurée +Double Cracked Stone Brick Slab=Double dalle de brique de pierre fissurée +White Concrete Stairs=Escalier en béton blanc +White Concrete Slab=Dalle en béton blanc +Double White Concrete Slab=Double dalle en béton blanc +Grey Concrete Stairs=Escalier en béton gris +Grey Concrete Slab=Dalle en béton gris +Double Grey Concrete Slab=Double dalle en béton gris +Light Grey Concrete Stairs=Escalier en béton gris clair +Light Grey Concrete Slab=Dalle en béton gris clair +Double Light Grey Concrete Slab=Double dalle en béton gris clair +Black Concrete Stairs=Escalier en béton noir +Black Concrete Slab=Dalle en béton noir +Double Black Concrete Slab=Double dalle en béton noir +Red Concrete Stairs=Escalier en béton rouge +Red Concrete Slab=Dalle en béton rouge +Double Red Concrete Slab=Double dalle en béton rouge +Yellow Concrete Stairs=Escalier en béton jaune +Yellow Concrete Slab=Dalle en béton jaune +Double Yellow Concrete Slab=Double dalle en béton jaune +Green Concrete Stairs=Escalier en béton vert +Green Concrete Slab=Dalle en béton vert +Double Green Concrete Slab=Double dalle en béton vert +Cyan Concrete Stairs=Escalier en béton cyan +Cyan Concrete Slab=Dalle en béton cyan +Double Cyan Concrete Slab=Double dalle en béton cyan +Blue Concrete Stairs=Escalier en béton bleu +Blue Concrete Slab=Dalle en béton bleu +Double Blue Concrete Slab=Double dalle en béton bleu +Magenta Concrete Stairs=Escalier en béton magenta +Magenta Concrete Slab=Dalle en béton magenta +Double Magenta Concrete Slab=Double dalle en béton magenta +Orange Concrete Stairs=Escalier en béton orange +Orange Concrete Slab=Dalle en béton orange +Double Orange Concrete Slab=Double dalle en béton orange +Purple Concrete Stairs=Escalier en béton violet +Purple Concrete Slab=Dalle en béton violet +Double Purple Concrete Slab=Double dalle en béton violet +Brown Concrete Stairs=Escalier en béton marron +Brown Concrete Slab=Dalle en béton marron +Double Brown Concrete Slab=Double dalle en béton marron +Pink Concrete Stairs=Escalier en béton rose +Pink Concrete Slab=Dalle en béton rose +Double Pink Concrete Slab=Double dalle en béton rose +Lime Concrete Stairs=Escalier en béton vert clair +Lime Concrete Slab=Dalle en béton vert clair +Double Lime Concrete Slab=Double dalle en béton vert clair +Light Blue Concrete Stairs=Escalier en béton bleu clair +Light Blue Concrete Slab=Dalle en béton bleu clair +Double Light Blue Concrete Slab=Double dalle en béton bleu clair +Concrete Slab=Dalle en béton +Double Concrete Slab=Double dalle en béton +Concrete Stairs=Escalier en béton diff --git a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr new file mode 100644 index 000000000..bbe2ee209 --- /dev/null +++ b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.ja.tr @@ -0,0 +1,82 @@ +# textdomain: mclx_stairs +Oak Bark Stairs=オーク樹皮の階段 +Oak Bark Slab=オーク樹皮のスラブ +Double Oak Bark Slab=オーク樹皮の2重スラブ +Acacia Bark Stairs=アカシア樹皮の階段 +Acacia Bark Slab=アカシア樹皮のスラブ +Double Acacia Bark Slab=アカシア樹皮の2重スラブ +Spruce Bark Stairs=トウヒ樹皮の階段 +Spruce Bark Slab=トウヒ樹皮のスラブ +Double Spruce Bark Slab=トウヒ樹皮の2重スラブ +Birch Bark Stairs=シラカバ樹皮の階段 +Birch Bark Slab=シラカバ樹皮のスラブ +Double Birch Bark Slab=シラカバ樹皮の2重スラブ +Jungle Bark Stairs=ジャングル樹皮の階段 +Jungle Bark Slab=ジャングル樹皮のスラブ +Double Jungle Bark Slab=ジャングル樹皮の2重スラブ +Dark Oak Bark Stairs=ダークオーク樹皮の階段 +Dark Oak Bark Slab=ダークオーク樹皮のスラブ +Double Dark Oak Bark Slab=ダークオーク樹皮の2重スラブ +Lapis Lazuli Slab=ラピスラズリのスラブ +Double Lapis Lazuli Slab=ラピスラズリの2重スラブ +Lapis Lazuli Stairs=ラピスラズリの階段 +Slab of Gold=金のスラブ +Double Slab of Gold=金の2重スラブ +Stairs of Gold=金の階段 +Slab of Iron=鉄のスラブ +Double Slab of Iron=鉄の2重スラブ +Stairs of Iron=鉄の階段 +Cracked Stone Brick Stairs=ひび割れた石レンガの階段 +Cracked Stone Brick Slab=ひび割れた石レンガのスラブ +Double Cracked Stone Brick Slab=ひび割れた石レンガの2重スラブ +White Concrete Stairs=白色コンクリートの階段 +White Concrete Slab=白色コンクリートのスラブ +Double White Concrete Slab=白色コンクリートの2重スラブ +Grey Concrete Stairs=灰色コンクリートの階段 +Grey Concrete Slab=灰色コンクリートのスラブ +Double Grey Concrete Slab=灰色コンクリートの2重スラブ +Light Grey Concrete Stairs=薄灰色コンクリートの階段 +Light Grey Concrete Slab=薄灰色コンクリートのスラブ +Double Light Grey Concrete Slab=薄灰色コンクリートの2重スラブ +Black Concrete Stairs=黒色コンクリートの階段 +Black Concrete Slab=黒色コンクリートのスラブ +Double Black Concrete Slab=黒色コンクリートの2重スラブ +Red Concrete Stairs=赤色コンクリートの階段 +Red Concrete Slab=赤色コンクリートのスラブ +Double Red Concrete Slab=赤色コンクリートの2重スラブ +Yellow Concrete Stairs=黄色コンクリートの階段 +Yellow Concrete Slab=黄色コンクリートのスラブ +Double Yellow Concrete Slab=黄色コンクリートの2重スラブ +Green Concrete Stairs=緑色コンクリートの階段 +Green Concrete Slab=緑色コンクリートのスラブ +Double Green Concrete Slab=緑色コンクリートの2重スラブ +Cyan Concrete Stairs=青緑色コンクリートの階段 +Cyan Concrete Slab=青緑色コンクリートのスラブ +Double Cyan Concrete Slab=青緑色コンクリートの2重スラブ +Blue Concrete Stairs=青色コンクリートの階段 +Blue Concrete Slab=青色コンクリートのスラブ +Double Blue Concrete Slab=青色コンクリートの2重スラブ +Magenta Concrete Stairs=赤紫色コンクリートの階段 +Magenta Concrete Slab=赤紫色コンクリートのスラブ +Double Magenta Concrete Slab=赤紫色コンクリートの2重スラブ +Orange Concrete Stairs=橙色コンクリートの階段 +Orange Concrete Slab=橙色コンクリートのスラブ +Double Orange Concrete Slab=橙色コンクリートの2重スラブ +Purple Concrete Stairs=紫色コンクリートの階段 +Purple Concrete Slab=紫色コンクリートのスラブ +Double Purple Concrete Slab=紫色コンクリートの2重スラブ +Brown Concrete Stairs=茶色コンクリートの階段 +Brown Concrete Slab=茶色コンクリートのスラブ +Double Brown Concrete Slab=茶色コンクリートの2重スラブ +Pink Concrete Stairs=桃色コンクリートの階段 +Pink Concrete Slab=桃色コンクリートのスラブ +Double Pink Concrete Slab=桃色コンクリートの2重スラブ +Lime Concrete Stairs=黄緑色コンクリートの階段 +Lime Concrete Slab=黄緑色コンクリートのスラブ +Double Lime Concrete Slab=黄緑色コンクリートの2重スラブ +Light Blue Concrete Stairs=空色コンクリートの階段 +Light Blue Concrete Slab=空色コンクリートのスラブ +Double Light Blue Concrete Slab=空色コンクリートの2重スラブ +Concrete Slab=コンクリートのスラブ +Double Concrete Slab=コンクリートの2重スラブ +Concrete Stairs=コンクリートの階段 diff --git a/mods/ITEMS/mclx_stairs/locale/mclx_stairs.pl.tr b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.pl.tr new file mode 100644 index 000000000..8a4c4d5e2 --- /dev/null +++ b/mods/ITEMS/mclx_stairs/locale/mclx_stairs.pl.tr @@ -0,0 +1,82 @@ +# textdomain: mclx_stairs +Oak Bark Stairs=Schody z dębowej kory +Oak Bark Slab=Płyta z dębowej kory +Double Oak Bark Slab=Podwójna płyta z dębowej kory +Acacia Bark Stairs=Schody z akacjowej kory +Acacia Bark Slab=Płyta z akacjowej kory +Double Acacia Bark Slab=Podwójna płyta z akacjowej kory +Spruce Bark Stairs=Schody ze świerkowej kory +Spruce Bark Slab=Płyta ze świerkowej kory +Double Spruce Bark Slab=Podwójna płyta ze świerkowej kory +Birch Bark Stairs=Schody z brzozowej kory +Birch Bark Slab=Płyta z brzozowej kory +Double Birch Bark Slab=Podwójna płyta z brzozowej kory +Jungle Bark Stairs=Schody z tropikalnej kory +Jungle Bark Slab=Płyta z tropikalnej kory +Double Jungle Bark Slab=Podwójna płyta z tropikalnej kory +Dark Oak Bark Stairs=Schody z ciemno-dębowej kory +Dark Oak Bark Slab=Płyta z ciemno-dębowej kory +Double Dark Oak Bark Slab=Podwójna płyta z ciemno-dębowej kory +Lapis Lazuli Slab=Płyta lazurytu +Double Lapis Lazuli Slab=Podwójna płyta lazurytu +Lapis Lazuli Stairs=Lazurytowe schody +Slab of Gold=Płyta złota +Double Slab of Gold=Podwójna płyta złota +Stairs of Gold=Złote schody +Slab of Iron=Płyta żelaza +Double Slab of Iron=Podwójna płyta żelaza +Stairs of Iron=Żelazne schody +Cracked Stone Brick Stairs=Schody z pękniętych ceglanych kamieni +Cracked Stone Brick Slab=Płyta z pękniętych ceglanych kamieni +Double Cracked Stone Brick Slab=Podwójna płyta z pękniętych ceglanych kamieni +White Concrete Stairs=Schody z białego cementu +White Concrete Slab=Płyta z białego cementu +Double White Concrete Slab=Podwójna płyta z białego cementu +Grey Concrete Stairs=Schody z szarego cementu +Grey Concrete Slab=Płyta z szarego cementu +Double Grey Concrete Slab=Podwójna płyta z szarego cementu +Light Grey Concrete Stairs=Schody z jasnoszarego cementu +Light Grey Concrete Slab=Płyta z jasnoszarego cementu +Double Light Grey Concrete Slab=Podwójna płyta z jasnoszarego cementu +Black Concrete Stairs=Schody z czarnego cementu +Black Concrete Slab=Płyta z czarnego cementu +Double Black Concrete Slab=Podwójna płyta z czarnego cementu +Red Concrete Stairs=Schody z czerwonego cementu +Red Concrete Slab=Płyta z czerwonego cementu +Double Red Concrete Slab=Podwójna płyta z czerwonego cementu +Yellow Concrete Stairs=Schody z żółtego cementu +Yellow Concrete Slab=Płyta z żółtego cementu +Double Yellow Concrete Slab=Podwójna płyta z żółtego cementu +Green Concrete Stairs=Schody z zielonego cementu +Green Concrete Slab=Płyta z zielonego cementu +Double Green Concrete Slab=Podwójna płyta z zielonego cementu +Cyan Concrete Stairs=Schody z błękitnego cementu +Cyan Concrete Slab=Płyta z błękitnego cementu +Double Cyan Concrete Slab=Podwójna płyta z błękitnego cementu +Blue Concrete Stairs=Schody z niebieskiego cementu +Blue Concrete Slab=Płyta z niebieskiego cementu +Double Blue Concrete Slab=Podwójna płyta z niebieskiego cementu +Magenta Concrete Stairs=Schody z karmazynowego cementu +Magenta Concrete Slab=Płyta z karmazynowego cementu +Double Magenta Concrete Slab=Podwójna płyta z karmazynowego cementu +Orange Concrete Stairs=Schody z pomarańczowego cementu +Orange Concrete Slab=Płyta z pomarańczowego cementu +Double Orange Concrete Slab=Podwójna płyta z pomarańczowego cementu +Purple Concrete Stairs=Schody z fioletowego cementu +Purple Concrete Slab=Płyta z fioletowego cementu +Double Purple Concrete Slab=Podwójna płyta z fioletowego cementu +Brown Concrete Stairs=Schody z brązowego cementu +Brown Concrete Slab=Płyta z brązowego cementu +Double Brown Concrete Slab=Podwójna płyta z brązowego cementu +Pink Concrete Stairs=Schody z różowego cementu +Pink Concrete Slab=Płyta z różowego cementu +Double Pink Concrete Slab=Podwójna płyta z różowego cementu +Lime Concrete Stairs=Schody z jasnozielonego cementu +Lime Concrete Slab=Płyta z jasnozielonego cementu +Double Lime Concrete Slab=Podwójna płyta z jasnozielonego cementu +Light Blue Concrete Stairs=Schody z jasnoniebieskiego cementu +Light Blue Concrete Slab=Płyta z jasnoniebieskiego cementu +Double Light Blue Concrete Slab=Podwójna płyta z jasnoniebieskiego cementu +Concrete Slab=płyta betonu +Double Concrete Slab=Podwójna płyta betonu +Concrete Stairs=Betonowe schody diff --git a/mods/ITEMS/mclx_stairs/mod.conf b/mods/ITEMS/mclx_stairs/mod.conf index 9d514a88c..b3aecd806 100644 --- a/mods/ITEMS/mclx_stairs/mod.conf +++ b/mods/ITEMS/mclx_stairs/mod.conf @@ -1 +1,4 @@ name = mclx_stairs +description = Additional stairs and slabs not found in Minecraft 1.11 +depends = mcl_ocean, mcl_core, mcl_sounds, mcl_nether, mcl_end, mcl_colorblocks, mcl_stairs +optional_depends = doc diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_andesite_smooth_slab.png b/mods/ITEMS/mclx_stairs/textures/mcl_stairs_andesite_smooth_slab.png deleted file mode 100644 index daf6e96ca..000000000 Binary files a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_andesite_smooth_slab.png and /dev/null differ diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_diorite_smooth_slab.png b/mods/ITEMS/mclx_stairs/textures/mcl_stairs_diorite_smooth_slab.png deleted file mode 100644 index 57d147bae..000000000 Binary files a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_diorite_smooth_slab.png and /dev/null differ diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_gold_block_slab.png b/mods/ITEMS/mclx_stairs/textures/mcl_stairs_gold_block_slab.png deleted file mode 100644 index 7f490e704..000000000 Binary files a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_gold_block_slab.png and /dev/null differ diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_iron_block_slab.png b/mods/ITEMS/mclx_stairs/textures/mcl_stairs_iron_block_slab.png deleted file mode 100644 index 101f62c46..000000000 Binary files a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_iron_block_slab.png and /dev/null differ diff --git a/mods/ITEMS/screwdriver/init.lua b/mods/ITEMS/screwdriver/init.lua index ec4f1a2ad..baa4ff9c5 100644 --- a/mods/ITEMS/screwdriver/init.lua +++ b/mods/ITEMS/screwdriver/init.lua @@ -1,18 +1,21 @@ -local S = minetest.get_translator("screwdriver") +local S = minetest.get_translator(minetest.get_current_modname()) screwdriver = {} screwdriver.ROTATE_FACE = 1 screwdriver.ROTATE_AXIS = 2 -screwdriver.disallow = function(pos, node, user, mode, new_param2) + +function screwdriver.disallow(pos, node, user, mode, new_param2) return false end -screwdriver.rotate_simple = function(pos, node, user, mode, new_param2) + +function screwdriver.rotate_simple(pos, node, user, mode, new_param2) if mode ~= screwdriver.ROTATE_FACE then return false end end -screwdriver.rotate_3way = function(pos, node, user, mode, new_param2) + +function screwdriver.rotate_3way(pos, node, user, mode, new_param2) if mode == screwdriver.ROTATE_AXIS then if node.param2 == 0 then node.param2 = 6 @@ -71,7 +74,7 @@ local facedir_tbl = { }, } -screwdriver.rotate.facedir = function(pos, node, mode) +function screwdriver.rotate.facedir(pos, node, mode) local rotation = node.param2 % 32 -- get first 5 bits local other = node.param2 - rotation rotation = facedir_tbl[mode][rotation] or 0 @@ -82,10 +85,10 @@ screwdriver.rotate.colorfacedir = screwdriver.rotate.facedir local wallmounted_tbl = { [screwdriver.ROTATE_FACE] = {[2] = 5, [3] = 4, [4] = 2, [5] = 3, [1] = 0, [0] = 1}, - [screwdriver.ROTATE_AXIS] = {[2] = 5, [3] = 4, [4] = 2, [5] = 1, [1] = 0, [0] = 3} + [screwdriver.ROTATE_AXIS] = {[2] = 5, [3] = 4, [4] = 2, [5] = 1, [1] = 0, [0] = 3}, } -screwdriver.rotate.wallmounted = function(pos, node, mode) +function screwdriver.rotate.wallmounted(pos, node, mode) local rotation = node.param2 % 8 -- get first 3 bits local other = node.param2 - rotation rotation = wallmounted_tbl[mode][rotation] or 0 @@ -105,7 +108,7 @@ end screwdriver.rotate.colorwallmounted = screwdriver.rotate.wallmounted -- Handles rotation -screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) +function screwdriver.handler(itemstack, user, pointed_thing, mode, uses) if pointed_thing.type ~= "node" then return end @@ -157,7 +160,6 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) if should_rotate and new_param2 ~= node.param2 then node.param2 = new_param2 minetest.swap_node(pos, node) - minetest.check_for_falling(pos) if ndef.after_rotate then ndef.after_rotate(vector.new(pos)) @@ -187,6 +189,7 @@ minetest.register_tool("screwdriver:screwdriver", { end, }) +mcl_wip.register_wip_item("screwdriver:screwdriver") minetest.register_craft({ output = "screwdriver:screwdriver", diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.de.tr b/mods/ITEMS/screwdriver/locale/screwdriver.de.tr index 35c99c05f..eaf44b0d6 100644 --- a/mods/ITEMS/screwdriver/locale/screwdriver.de.tr +++ b/mods/ITEMS/screwdriver/locale/screwdriver.de.tr @@ -1,2 +1,2 @@ # textdomain: screwdriver -Screwdriver=Schraubendreher +Screwdriver=Schraubenzieher diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.fr.tr b/mods/ITEMS/screwdriver/locale/screwdriver.fr.tr index ae014ea09..cce37b34a 100644 --- a/mods/ITEMS/screwdriver/locale/screwdriver.fr.tr +++ b/mods/ITEMS/screwdriver/locale/screwdriver.fr.tr @@ -1,2 +1,2 @@ -#textdomain: screwdriver +# textdomain: screwdriver Screwdriver=Tournevis diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr b/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr new file mode 100644 index 000000000..0a80459f6 --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.ja.tr @@ -0,0 +1,2 @@ +# textdomain: screwdriver +Screwdriver=ドライバー diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.pl.tr b/mods/ITEMS/screwdriver/locale/screwdriver.pl.tr new file mode 100644 index 000000000..d4c0436ab --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.pl.tr @@ -0,0 +1,2 @@ +# textdomain: screwdriver +Screwdriver=Śrubokręt diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.ru.tr b/mods/ITEMS/screwdriver/locale/screwdriver.ru.tr index fb6321684..6d7605ae5 100644 --- a/mods/ITEMS/screwdriver/locale/screwdriver.ru.tr +++ b/mods/ITEMS/screwdriver/locale/screwdriver.ru.tr @@ -1,2 +1,2 @@ -#textdomain: screwdriver +# textdomain: screwdriver Screwdriver=Отвёртка diff --git a/mods/ITEMS/screwdriver/locale/screwdriver.zh_TW.tr b/mods/ITEMS/screwdriver/locale/screwdriver.zh_TW.tr new file mode 100644 index 000000000..12eb2576c --- /dev/null +++ b/mods/ITEMS/screwdriver/locale/screwdriver.zh_TW.tr @@ -0,0 +1,2 @@ +# textdomain: screwdriver +Screwdriver=螺絲刀 diff --git a/mods/ITEMS/screwdriver/locale/template.txt b/mods/ITEMS/screwdriver/locale/template.txt index b3871a116..41309d57e 100644 --- a/mods/ITEMS/screwdriver/locale/template.txt +++ b/mods/ITEMS/screwdriver/locale/template.txt @@ -1,2 +1,2 @@ -#textdomain: screwdriver +# textdomain: screwdriver Screwdriver= diff --git a/mods/ITEMS/screwdriver/mod.conf b/mods/ITEMS/screwdriver/mod.conf new file mode 100644 index 000000000..a18279839 --- /dev/null +++ b/mods/ITEMS/screwdriver/mod.conf @@ -0,0 +1,2 @@ +name = screwdriver +depends = mcl_wip \ No newline at end of file diff --git a/mods/ITEMS/screwdriver/textures/screwdriver.png b/mods/ITEMS/screwdriver/textures/screwdriver.png deleted file mode 100644 index 27d13db8c..000000000 Binary files a/mods/ITEMS/screwdriver/textures/screwdriver.png and /dev/null differ diff --git a/mods/ITEMS/xpanes/depends.txt b/mods/ITEMS/xpanes/depends.txt deleted file mode 100644 index 812afabce..000000000 --- a/mods/ITEMS/xpanes/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_sounds -mcl_core -doc? diff --git a/mods/ITEMS/xpanes/init.lua b/mods/ITEMS/xpanes/init.lua index c17f2cd69..85405308b 100644 --- a/mods/ITEMS/xpanes/init.lua +++ b/mods/ITEMS/xpanes/init.lua @@ -1,4 +1,4 @@ -local S = minetest.get_translator("xpanes") +local S = minetest.get_translator(minetest.get_current_modname()) local mod_doc = minetest.get_modpath("doc") local function is_pane(pos) @@ -69,16 +69,16 @@ local function update_pane(pos) end minetest.register_on_placenode(function(pos, node) - if minetest.get_item_group(node, "pane") then - update_pane(pos) - end + if minetest.get_item_group(node.name, "pane") <= 0 then return end + update_pane(pos) for i = 0, 3 do local dir = minetest.facedir_to_dir(i) update_pane(vector.add(pos, dir)) end end) -minetest.register_on_dignode(function(pos) +minetest.register_on_dignode(function(pos,node) + if minetest.get_item_group(node.name, "pane") <= 0 then return end for i = 0, 3 do local dir = minetest.facedir_to_dir(i) update_pane(vector.add(pos, dir)) @@ -86,6 +86,7 @@ minetest.register_on_dignode(function(pos) end) xpanes = {} +xpanes.update_pane = update_pane function xpanes.register_pane(name, def) for i = 1, 15 do minetest.register_alias("xpanes:" .. name .. "_" .. i, "xpanes:" .. name .. "_flat") @@ -142,7 +143,7 @@ function xpanes.register_pane(name, def) tiles = {def.textures[3], def.textures[2], def.textures[1]}, use_texture_alpha = def.use_texture_alpha, groups = groups, - drop = "xpanes:" .. name .. "_flat", + drop = drop, sounds = def.sounds, node_box = { type = "connected", @@ -153,7 +154,6 @@ function xpanes.register_pane(name, def) connect_right = {{1/32, -1/2, -1/32, 1/2, 1/2, 1/32}}, }, connects_to = {"group:pane", "group:stone", "group:glass", "group:wood", "group:tree"}, - drop = drop, _mcl_blast_resistance = def._mcl_blast_resistance, _mcl_hardness = def._mcl_hardness, _mcl_silk_touch_drop = def._mcl_silk_touch_drop and {"xpanes:" .. name .. "_flat"}, @@ -171,7 +171,7 @@ end local canonical_color = "yellow" -- Register glass pane (stained and unstained) -local pane = function(description, node, append) +local function pane(description, node, append) local texture1, longdesc, entry_name, create_entry local is_canonical = true -- Special case: Default (unstained) glass texture @@ -194,7 +194,7 @@ local pane = function(description, node, append) _doc_items_entry_name = entry_name, _doc_items_longdesc = longdesc, textures = {texture1, texture1, "xpanes_top_glass"..append..".png"}, - use_texture_alpha = true, + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "blend" or true, inventory_image = texture1, wield_image = texture1, sounds = mcl_sounds.node_sound_glass_defaults(), @@ -224,6 +224,7 @@ xpanes.register_pane("bar", { wield_image = "xpanes_pane_iron.png", groups = {pickaxey=1}, sounds = mcl_sounds.node_sound_metal_defaults(), + use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true, recipe = { {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, {"mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot"}, diff --git a/mods/ITEMS/xpanes/locale/xpanes.ja.tr b/mods/ITEMS/xpanes/locale/xpanes.ja.tr new file mode 100644 index 000000000..bd67ee498 --- /dev/null +++ b/mods/ITEMS/xpanes/locale/xpanes.ja.tr @@ -0,0 +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.=鉄格子は、組み立てると隣の格子ときれいにつながっていきます。 +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=青緑色ガラス板 diff --git a/mods/ITEMS/xpanes/locale/xpanes.pl.tr b/mods/ITEMS/xpanes/locale/xpanes.pl.tr new file mode 100644 index 000000000..d169c1f97 --- /dev/null +++ b/mods/ITEMS/xpanes/locale/xpanes.pl.tr @@ -0,0 +1,23 @@ +# textdomain: xpanes +Glass panes are thin layers of glass which neatly connect to their neighbors as you build them.=Szyby są cienkimi warstwami szkła które łączą się z sąsiadującymi blokami podczas budowania. +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.=Kolorowe szyby są cienkimi warstwami kolorowego szkła które łączą się z sąsiadującymi blokami podczas budowania. Można je pokolorować na wiele kolorów. +Iron Bars=Żelazne kraty +Iron bars neatly connect to their neighbors as you build them.=Żelazne kraty łączą się z sąsiadującymi blokami podczas budowania. +Glass Pane=Szyba +Stained Glass Pane=Kolorowa szyba +Red Stained Glass Pane=Czerwona szyba +Green Stained Glass Pane=Zielona szyba +Blue Stained Glass Pane=Niebieska szyba +Light Blue Stained Glass Pane=Jasnoniebieska szyba +Black Stained Glass Pane=Czarna szyba +White Stained Glass Pane=Biała szyba +Yellow Stained Glass Pane=Żółta szyba +Brown Stained Glass Pane=Brązowa szyba +Orange Stained Glass Pane=Pomarańczowa szyba +Pink Stained Glass Pane=Różowa szyba +Grey Stained Glass Pane=Szara szyba +Lime Stained Glass Pane=Jasnozielona szyba +Light Grey Stained Glass Pane=Jasnoszara szyba +Magenta Stained Glass Pane=Karmazynowa szyba +Purple Stained Glass Pane=Fioletowa szyba +Cyan Stained Glass Pane=Błękitna szyba diff --git a/mods/ITEMS/xpanes/locale/xpanes.zh_TW.tr b/mods/ITEMS/xpanes/locale/xpanes.zh_TW.tr new file mode 100644 index 000000000..bcf33c205 --- /dev/null +++ b/mods/ITEMS/xpanes/locale/xpanes.zh_TW.tr @@ -0,0 +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.=在你建造鐵柵欄時,它們會整齊地連接到鄰近的方塊。 +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=青色玻璃片 diff --git a/mods/ITEMS/xpanes/mod.conf b/mods/ITEMS/xpanes/mod.conf new file mode 100644 index 000000000..ba2147663 --- /dev/null +++ b/mods/ITEMS/xpanes/mod.conf @@ -0,0 +1,3 @@ +name = xpanes +depends = mcl_sounds, mcl_core +optional_depends = doc diff --git a/mods/ITEMS/xpanes/textures/xpanes_pane_iron.png b/mods/ITEMS/xpanes/textures/xpanes_pane_iron.png deleted file mode 100644 index 45c4bf13c..000000000 Binary files a/mods/ITEMS/xpanes/textures/xpanes_pane_iron.png and /dev/null differ diff --git a/mods/MAPGEN/mcl_biomes/depends.txt b/mods/MAPGEN/mcl_biomes/depends.txt deleted file mode 100644 index dd21ef64f..000000000 --- a/mods/MAPGEN/mcl_biomes/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_core -mcl_worlds -mcl_farming -mcl_flowers -mcl_end -mcl_ocean diff --git a/mods/MAPGEN/mcl_biomes/description.txt b/mods/MAPGEN/mcl_biomes/description.txt deleted file mode 100644 index 496ffb217..000000000 --- a/mods/MAPGEN/mcl_biomes/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds the various biomes and biome-related things for non-v6 map generators. diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index 5687db1b3..d42720d26 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -1,3 +1,18 @@ +local overworld_fogcolor = "#C0D8FF" +local beach_skycolor = "#78A7FF" -- This is the case for all beach biomes except for the snowy ones! Those beaches will have their own colour instead of this one. +local ocean_skycolor = "#7BA4FF" -- This is the case for all ocean biomes except for non-deep frozen oceans! Those oceans will have their own colour instead of this one. + +local nether_skycolor = "#6EB1FF" -- The Nether biomes seemingly don't use the sky colour, despite having this value according to the wiki. The fog colour is used for both sky and fog. + +local end_skycolor = "#000000" +local end_fogcolor = "#A080A0" -- The End biomes seemingly don't use the fog colour, despite having this value according to the wiki. The sky colour is used for both sky and fog. + +local default_waterfogcolor = "#3F76E4" +local lukewarm_waterfogcolor = "#45ADF2" +local warm_waterfogcolor = "#43D5EE" +local cold_waterfogcolor = "#3D57D6" +local frozen_waterfogcolor = "#3938C9" + local mg_name = minetest.get_mapgen_setting("mg_name") local mg_seed = minetest.get_mapgen_setting("seed") @@ -6,8 +21,12 @@ local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superfl local generate_fallen_logs = minetest.settings:get_bool("mcl_generate_fallen_logs", false) --- Jungle bush schematic. In PC/Java Edition it's Jungle Wood + Oak Leaves -local jungle_bush_schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_bush_oak_leaves.mts" +local mod_mcl_structures = minetest.get_modpath("mcl_structures") +local mod_mcl_core = minetest.get_modpath("mcl_core") +local mod_mcl_mushrooms = minetest.get_modpath("mcl_mushrooms") +local mod_mcl_crimson = minetest.get_modpath("mcl_crimson") +local mod_mcl_blackstone = minetest.get_modpath("mcl_blackstone") +local mod_mcl_mangrove = minetest.get_modpath("mcl_mangrove") local deco_id_chorus_plant @@ -37,7 +56,12 @@ local function register_classic_superflat_biome() humidity_point = 50, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 0, + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) end @@ -121,6 +145,11 @@ local function register_biomes() "MesaBryce", "MesaPlateauF", "MesaPlateauFM", + "MangroveSwamp", + "BambooJungle", + "BambooJungleM", + "BambooJungleEdge", + "BambooJungleEdgeM", } -- Ice Plains Spikes (rare) @@ -140,7 +169,12 @@ local function register_biomes() humidity_point = 24, heat_point = -5, _mcl_biome_type = "snowy", - _mcl_palette_index = 2, + _mcl_grass_palette_index = 2, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "IcePlainsSpikes_ocean", @@ -156,7 +190,12 @@ local function register_biomes() humidity_point = 24, heat_point = -5, _mcl_biome_type = "snowy", - _mcl_palette_index = 2, + _mcl_grass_palette_index = 2, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Cold Taiga @@ -174,7 +213,12 @@ local function register_biomes() humidity_point = 58, heat_point = 8, _mcl_biome_type = "snowy", - _mcl_palette_index = 3, + _mcl_grass_palette_index = 3, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#839EFF", + _mcl_fogcolor = overworld_fogcolor }) -- A cold beach-like biome, implemented as low part of Cold Taiga @@ -194,7 +238,12 @@ local function register_biomes() humidity_point = 58, heat_point = 8, _mcl_biome_type = "snowy", - _mcl_palette_index = 3, + _mcl_grass_palette_index = 3, + _mcl_foliage_palette_index = 16, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Water part of the beach. Added to prevent snow being on the ice. minetest.register_biome({ @@ -212,7 +261,12 @@ local function register_biomes() humidity_point = 58, heat_point = 8, _mcl_biome_type = "snowy", - _mcl_palette_index = 3, + _mcl_grass_palette_index = 3, + _mcl_foliage_palette_index = 16, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ColdTaiga_ocean", @@ -228,10 +282,15 @@ local function register_biomes() heat_point = 8, vertical_blend = 1, _mcl_biome_type = "snowy", - _mcl_palette_index = 3, + _mcl_grass_palette_index = 3, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) - -- Mega Taiga + -- Mega Pine Taiga minetest.register_biome({ name = "MegaTaiga", node_top = "mcl_core:podzol", @@ -245,7 +304,12 @@ local function register_biomes() humidity_point = 76, heat_point = 10, _mcl_biome_type = "cold", - _mcl_palette_index = 4, + _mcl_grass_palette_index = 4, + _mcl_foliage_palette_index = 9, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7CA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MegaTaiga_ocean", @@ -260,7 +324,12 @@ local function register_biomes() humidity_point = 76, heat_point = 10, _mcl_biome_type = "cold", - _mcl_palette_index = 4, + _mcl_grass_palette_index = 4, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mega Spruce Taiga @@ -277,7 +346,12 @@ local function register_biomes() humidity_point = 100, heat_point = 8, _mcl_biome_type = "cold", - _mcl_palette_index = 5, + _mcl_grass_palette_index = 5, + _mcl_foliage_palette_index = 10, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MegaSpruceTaiga_ocean", @@ -292,7 +366,12 @@ local function register_biomes() humidity_point = 100, heat_point = 8, _mcl_biome_type = "cold", - _mcl_palette_index = 5, + _mcl_grass_palette_index = 5, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills @@ -310,7 +389,12 @@ local function register_biomes() humidity_point = 10, heat_point = 45, _mcl_biome_type = "cold", - _mcl_palette_index = 6, + _mcl_grass_palette_index = 6, + _mcl_foliage_palette_index = 11, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills_beach", @@ -326,7 +410,12 @@ local function register_biomes() humidity_point = 10, heat_point = 45, _mcl_biome_type = "cold", - _mcl_palette_index = 6, + _mcl_grass_palette_index = 6, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills_ocean", @@ -342,7 +431,12 @@ local function register_biomes() humidity_point = 10, heat_point = 45, _mcl_biome_type = "cold", - _mcl_palette_index = 6, + _mcl_grass_palette_index = 6, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills M @@ -360,7 +454,12 @@ local function register_biomes() humidity_point = 0, heat_point = 25, _mcl_biome_type = "cold", - _mcl_palette_index = 7, + _mcl_grass_palette_index = 7, + _mcl_foliage_palette_index = 11, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHillsM_ocean", @@ -375,7 +474,12 @@ local function register_biomes() humidity_point = 0, heat_point = 25, _mcl_biome_type = "cold", - _mcl_palette_index = 7, + _mcl_grass_palette_index = 7, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Extreme Hills+ @@ -395,7 +499,12 @@ local function register_biomes() heat_point = 25, vertical_blend = 6, _mcl_biome_type = "cold", - _mcl_palette_index = 8, + _mcl_grass_palette_index = 8, + _mcl_foliage_palette_index = 11, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) ---- Sub-biome for Extreme Hills+ for those snow forests minetest.register_biome({ @@ -413,7 +522,12 @@ local function register_biomes() humidity_point = 24, heat_point = 25, _mcl_biome_type = "cold", - _mcl_palette_index = 8, + _mcl_grass_palette_index = 8, + _mcl_foliage_palette_index = 11, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "ExtremeHills+_ocean", @@ -428,7 +542,12 @@ local function register_biomes() humidity_point = 24, heat_point = 25, _mcl_biome_type = "cold", - _mcl_palette_index = 8, + _mcl_grass_palette_index = 8, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Stone beach @@ -443,7 +562,12 @@ local function register_biomes() humidity_point = 0, heat_point = 8, _mcl_biome_type = "cold", - _mcl_palette_index = 9, + _mcl_grass_palette_index = 9, + _mcl_foliage_palette_index = 11, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA2FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ @@ -458,7 +582,12 @@ local function register_biomes() humidity_point = 0, heat_point = 8, _mcl_biome_type = "cold", - _mcl_palette_index = 9, + _mcl_grass_palette_index = 9, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Ice Plains @@ -479,7 +608,12 @@ local function register_biomes() humidity_point = 24, heat_point = 8, _mcl_biome_type = "snowy", - _mcl_palette_index = 10, + _mcl_grass_palette_index = 10, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "IcePlains_ocean", @@ -494,7 +628,12 @@ local function register_biomes() humidity_point = 24, heat_point = 8, _mcl_biome_type = "snowy", - _mcl_palette_index = 10, + _mcl_grass_palette_index = 10, + _mcl_foliage_palette_index = 2, + _mcl_water_palette_index = 5, + _mcl_waterfogcolor = frozen_waterfogcolor, + _mcl_skycolor = "#7FA1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Plains @@ -511,7 +650,12 @@ local function register_biomes() humidity_point = 39, heat_point = 58, _mcl_biome_type = "medium", - _mcl_palette_index = 0, + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Plains_beach", @@ -526,7 +670,12 @@ local function register_biomes() humidity_point = 39, heat_point = 58, _mcl_biome_type = "medium", - _mcl_palette_index = 0, + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Plains_ocean", @@ -541,7 +690,12 @@ local function register_biomes() humidity_point = 39, heat_point = 58, _mcl_biome_type = "medium", - _mcl_palette_index = 0, + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Sunflower Plains @@ -558,7 +712,12 @@ local function register_biomes() humidity_point = 28, heat_point = 45, _mcl_biome_type = "medium", - _mcl_palette_index = 11, + _mcl_grass_palette_index = 11, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "SunflowerPlains_ocean", @@ -573,7 +732,12 @@ local function register_biomes() humidity_point = 28, heat_point = 45, _mcl_biome_type = "medium", - _mcl_palette_index = 11, + _mcl_grass_palette_index = 11, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Taiga @@ -590,7 +754,12 @@ local function register_biomes() humidity_point = 58, heat_point = 22, _mcl_biome_type = "cold", - _mcl_palette_index = 12, + _mcl_grass_palette_index = 12, + _mcl_foliage_palette_index = 10, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = "#7DA3FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Taiga_beach", @@ -605,7 +774,12 @@ local function register_biomes() humidity_point = 58, heat_point = 22, _mcl_biome_type = "cold", - _mcl_palette_index = 12, + _mcl_grass_palette_index = 12, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Taiga_ocean", @@ -620,7 +794,12 @@ local function register_biomes() humidity_point = 58, heat_point = 22, _mcl_biome_type = "cold", - _mcl_palette_index = 12, + _mcl_grass_palette_index = 12, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 4, + _mcl_waterfogcolor = cold_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Forest @@ -637,7 +816,12 @@ local function register_biomes() humidity_point = 61, heat_point = 45, _mcl_biome_type = "medium", - _mcl_palette_index = 13, + _mcl_grass_palette_index = 13, + _mcl_foliage_palette_index = 7, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Forest_beach", @@ -652,7 +836,12 @@ local function register_biomes() humidity_point = 61, heat_point = 45, _mcl_biome_type = "medium", - _mcl_palette_index = 13, + _mcl_grass_palette_index = 13, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Forest_ocean", @@ -667,7 +856,12 @@ local function register_biomes() humidity_point = 61, heat_point = 45, _mcl_biome_type = "medium", - _mcl_palette_index = 13, + _mcl_grass_palette_index = 13, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Flower Forest @@ -684,7 +878,12 @@ local function register_biomes() humidity_point = 44, heat_point = 32, _mcl_biome_type = "medium", - _mcl_palette_index = 14, + _mcl_grass_palette_index = 14, + _mcl_foliage_palette_index = 7, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "FlowerForest_beach", @@ -699,7 +898,12 @@ local function register_biomes() humidity_point = 44, heat_point = 32, _mcl_biome_type = "medium", - _mcl_palette_index = 14, + _mcl_grass_palette_index = 14, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "FlowerForest_ocean", @@ -714,7 +918,12 @@ local function register_biomes() humidity_point = 44, heat_point = 32, _mcl_biome_type = "medium", - _mcl_palette_index = 14, + _mcl_grass_palette_index = 14, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Birch Forest @@ -731,7 +940,12 @@ local function register_biomes() humidity_point = 78, heat_point = 31, _mcl_biome_type = "medium", - _mcl_palette_index = 15, + _mcl_grass_palette_index = 15, + _mcl_foliage_palette_index = 8, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#7AA5FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "BirchForest_ocean", @@ -746,7 +960,12 @@ local function register_biomes() humidity_point = 78, heat_point = 31, _mcl_biome_type = "medium", - _mcl_palette_index = 15, + _mcl_grass_palette_index = 15, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Birch Forest M @@ -763,7 +982,12 @@ local function register_biomes() humidity_point = 77, heat_point = 27, _mcl_biome_type = "medium", - _mcl_palette_index = 16, + _mcl_grass_palette_index = 16, + _mcl_foliage_palette_index = 8, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#7AA5FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "BirchForestM_ocean", @@ -778,7 +1002,12 @@ local function register_biomes() humidity_point = 77, heat_point = 27, _mcl_biome_type = "medium", - _mcl_palette_index = 16, + _mcl_grass_palette_index = 16, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Desert @@ -796,7 +1025,12 @@ local function register_biomes() humidity_point = 26, heat_point = 94, _mcl_biome_type = "hot", - _mcl_palette_index = 17, + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Desert_ocean", @@ -811,7 +1045,12 @@ local function register_biomes() humidity_point = 26, heat_point = 94, _mcl_biome_type = "hot", - _mcl_palette_index = 17, + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Roofed Forest @@ -828,7 +1067,12 @@ local function register_biomes() humidity_point = 94, heat_point = 27, _mcl_biome_type = "medium", - _mcl_palette_index = 18, + _mcl_grass_palette_index = 18, + _mcl_foliage_palette_index = 7, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#79A6FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "RoofedForest_ocean", @@ -843,7 +1087,12 @@ local function register_biomes() humidity_point = 94, heat_point = 27, _mcl_biome_type = "medium", - _mcl_palette_index = 18, + _mcl_grass_palette_index = 18, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa: Starts with a couple of sand-covered layers (the "sandlevel"), @@ -861,7 +1110,12 @@ local function register_biomes() humidity_point = 0, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_grass_palette_index = 19, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Helper biome for the red sand at the bottom of Mesas. minetest.register_biome({ @@ -878,7 +1132,12 @@ local function register_biomes() humidity_point = 0, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_grass_palette_index = 19, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Mesa_ocean", @@ -894,7 +1153,12 @@ local function register_biomes() humidity_point = 0, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_grass_palette_index = 19, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa Bryce: Variant of Mesa, but with perfect strata and a much smaller red sand desert @@ -911,7 +1175,12 @@ local function register_biomes() humidity_point = -5, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 20, + _mcl_grass_palette_index = 20, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaBryce_sandlevel", @@ -927,7 +1196,12 @@ local function register_biomes() humidity_point = -5, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 20, + _mcl_grass_palette_index = 20, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaBryce_ocean", @@ -943,11 +1217,14 @@ local function register_biomes() humidity_point = -5, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 20, + _mcl_grass_palette_index = 20, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) - - -- Mesa Plateau F -- Identical to Mesa below Y=30. At Y=30 and above there is a "dry" oak forest minetest.register_biome({ @@ -964,7 +1241,12 @@ local function register_biomes() heat_point = 60, vertical_blend = 0, -- we want a sharp transition _mcl_biome_type = "hot", - _mcl_palette_index = 21, + _mcl_grass_palette_index = 21, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- The oak forest plateau of this biome. -- This is a plateau for grass blocks, dry shrubs, tall grass, coarse dirt and oaks. @@ -983,7 +1265,12 @@ local function register_biomes() humidity_point = 0, heat_point = 60, _mcl_biome_type = "hot", - _mcl_palette_index = 21, + _mcl_grass_palette_index = 21, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauF_sandlevel", @@ -999,7 +1286,12 @@ local function register_biomes() humidity_point = 0, heat_point = 60, _mcl_biome_type = "hot", - _mcl_palette_index = 21, + _mcl_grass_palette_index = 21, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauF_ocean", @@ -1015,7 +1307,12 @@ local function register_biomes() humidity_point = 0, heat_point = 60, _mcl_biome_type = "hot", - _mcl_palette_index = 21, + _mcl_grass_palette_index = 21, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mesa Plateau FM @@ -1036,7 +1333,12 @@ local function register_biomes() heat_point = 60, vertical_blend = 5, _mcl_biome_type = "hot", - _mcl_palette_index = 22, + _mcl_grass_palette_index = 22, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) -- Grass plateau minetest.register_biome({ @@ -1053,7 +1355,12 @@ local function register_biomes() humidity_point = -5, heat_point = 60, _mcl_biome_type = "hot", - _mcl_palette_index = 22, + _mcl_grass_palette_index = 22, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauFM_sandlevel", @@ -1071,7 +1378,12 @@ local function register_biomes() heat_point = 60, vertical_blend = 4, _mcl_biome_type = "hot", - _mcl_palette_index = 22, + _mcl_grass_palette_index = 22, + _mcl_foliage_palette_index = 4, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MesaPlateauFM_ocean", @@ -1087,7 +1399,12 @@ local function register_biomes() humidity_point = -5, heat_point = 60, _mcl_biome_type = "hot", - _mcl_palette_index = 22, + _mcl_grass_palette_index = 22, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 3, + _mcl_waterfogcolor = warm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) @@ -1105,7 +1422,12 @@ local function register_biomes() humidity_point = 36, heat_point = 79, _mcl_biome_type = "hot", - _mcl_palette_index = 1, + _mcl_grass_palette_index = 1, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Savanna_beach", @@ -1120,7 +1442,12 @@ local function register_biomes() humidity_point = 36, heat_point = 79, _mcl_biome_type = "hot", - _mcl_palette_index = 1, + _mcl_grass_palette_index = 1, + _mcl_foliage_palette_index = 1, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = beach_skycolor, + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Savanna_ocean", @@ -1135,7 +1462,12 @@ local function register_biomes() humidity_point = 36, heat_point = 79, _mcl_biome_type = "hot", - _mcl_palette_index = 1, + _mcl_grass_palette_index = 1, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Savanna M @@ -1154,7 +1486,12 @@ local function register_biomes() humidity_point = 48, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 23, + _mcl_grass_palette_index = 23, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#6EB1FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "SavannaM_ocean", @@ -1169,7 +1506,12 @@ local function register_biomes() humidity_point = 48, heat_point = 100, _mcl_biome_type = "hot", - _mcl_palette_index = 23, + _mcl_grass_palette_index = 23, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle @@ -1186,7 +1528,12 @@ local function register_biomes() humidity_point = 88, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 24, + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Jungle_shore", @@ -1201,7 +1548,12 @@ local function register_biomes() humidity_point = 88, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 24, + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Jungle_ocean", @@ -1217,7 +1569,12 @@ local function register_biomes() humidity_point = 88, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 24, + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle M @@ -1235,7 +1592,12 @@ local function register_biomes() humidity_point = 92, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 25, + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleM_shore", @@ -1250,7 +1612,12 @@ local function register_biomes() humidity_point = 92, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 25, + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleM_ocean", @@ -1266,7 +1633,12 @@ local function register_biomes() humidity_point = 92, heat_point = 81, _mcl_biome_type = "medium", - _mcl_palette_index = 25, + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle Edge @@ -1283,7 +1655,12 @@ local function register_biomes() humidity_point = 88, heat_point = 76, _mcl_biome_type = "medium", - _mcl_palette_index = 26, + _mcl_grass_palette_index = 26, + _mcl_foliage_palette_index = 13, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleEdge_ocean", @@ -1298,7 +1675,12 @@ local function register_biomes() humidity_point = 88, heat_point = 76, _mcl_biome_type = "medium", - _mcl_palette_index = 26, + _mcl_grass_palette_index = 26, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Jungle Edge M (very rare). @@ -1318,7 +1700,12 @@ local function register_biomes() humidity_point = 90, heat_point = 79, _mcl_biome_type = "medium", - _mcl_palette_index = 27, + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 13, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "JungleEdgeM_ocean", @@ -1333,9 +1720,77 @@ local function register_biomes() humidity_point = 90, heat_point = 79, _mcl_biome_type = "medium", - _mcl_palette_index = 27, + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) + -- Mangrove swamp + minetest.register_biome({ + name = "MangroveSwamp", + node_top = "mcl_mud:mud", + depth_top = 1, + node_filler = "mcl_mud:mud", + depth_filler = 3, + node_riverbed = "mcl_core:dirt", + depth_riverbed = 2, + y_min = 1, + -- Note: Limited in height! + y_max = 27, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 6, + _mcl_water_palette_index = 7, + _mcl_waterfogcolor = "#3A7A6A", + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "MangroveSwamp_shore", + node_top = "mcl_mud:mud", + depth_top = 1, + node_filler = "mcl_mud:mud", + depth_filler = 3, + node_riverbed = "mcl_core:dirt", + depth_riverbed = 2, + y_min = -5, + y_max = 0, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 6, + _mcl_water_palette_index = 7, + _mcl_waterfogcolor = "#3A7A6A", + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "MangroveSwamp_ocean", + node_top = "mcl_core:dirt", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:gravel", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = -6, + vertical_blend = 1, + humidity_point = 95, + heat_point = 94, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 7, + _mcl_waterfogcolor = "#3A7A6A", + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) -- Swampland minetest.register_biome({ name = "Swampland", @@ -1351,7 +1806,12 @@ local function register_biomes() humidity_point = 90, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 28, + _mcl_grass_palette_index = 28, + _mcl_foliage_palette_index = 5, + _mcl_water_palette_index = 1, + _mcl_waterfogcolor = "#617B64", + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Swampland_shore", @@ -1366,7 +1826,12 @@ local function register_biomes() humidity_point = 90, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 28, + _mcl_grass_palette_index = 28, + _mcl_foliage_palette_index = 5, + _mcl_water_palette_index = 1, + _mcl_waterfogcolor = "#617B64", + _mcl_skycolor = "#78A7FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "Swampland_ocean", @@ -1382,7 +1847,12 @@ local function register_biomes() humidity_point = 90, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 28, + _mcl_grass_palette_index = 28, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 1, + _mcl_waterfogcolor = "#617B64", + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Mushroom Island / Mushroom Island Shore (rare) @@ -1402,7 +1872,12 @@ local function register_biomes() humidity_point = 106, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 29, + _mcl_grass_palette_index = 29, + _mcl_foliage_palette_index = 17, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ @@ -1418,7 +1893,12 @@ local function register_biomes() humidity_point = 106, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 29, + _mcl_grass_palette_index = 29, + _mcl_foliage_palette_index = 17, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor }) minetest.register_biome({ name = "MushroomIsland_ocean", @@ -1433,11 +1913,231 @@ local function register_biomes() humidity_point = 106, heat_point = 50, _mcl_biome_type = "medium", - _mcl_palette_index = 29, + _mcl_grass_palette_index = 29, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) + + -- Bamboo Jungle areas are like the Jungle areas, but warmer and more humid. + -- Bamboo Jungle + minetest.register_biome({ + name = "BambooJungle", + node_top = "mcl_core:dirt_with_grass", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + humidity_point = 90, + heat_point = 95, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungle_shore", + node_top = "mcl_core:dirt", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = -2, + y_max = 0, + humidity_point = 90, + heat_point = 95, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungle_ocean", + node_top = "mcl_core:sand", + depth_top = 1, + node_filler = "mcl_core:sand", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = -3, + vertical_blend = 1, + humidity_point = 95, + heat_point = 90, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 24, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) + + -- Bamboo Jungle M + -- Like Bamboo Jungle but with even more dense vegetation + minetest.register_biome({ + name = "BambooJungleM", + node_top = "mcl_core:dirt_with_grass", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + humidity_point = 95, + heat_point = 95, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungleM_shore", + node_top = "mcl_core:dirt", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = -2, + y_max = 0, + humidity_point = 95, + heat_point = 90, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 12, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungleM_ocean", + node_top = "mcl_core:sand", + depth_top = 1, + node_filler = "mcl_core:sand", + depth_filler = 3, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = -3, + vertical_blend = 1, + humidity_point = 95, + heat_point = 95, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 25, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) + + -- Bamboo Jungle Edge + minetest.register_biome({ + name = "BambooJungleEdge", + node_top = "mcl_core:dirt_with_grass", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 2, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + humidity_point = 92, + heat_point = 90, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 26, + _mcl_foliage_palette_index = 13, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungleEdge_ocean", + node_top = "mcl_core:sand", + depth_top = 1, + node_filler = "mcl_core:sand", + depth_filler = 2, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = 0, + humidity_point = 95, + heat_point = 88, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 26, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor + }) + + -- Jungle Edge M (very rare). + -- Almost identical to Jungle Edge. Has deeper dirt. Melons spawn here a lot. + -- This biome occours directly between Jungle M and Jungle Edge but also has a small border to Jungle. + -- This biome is very small in general. + minetest.register_biome({ + name = "BambooJungleEdgeM", + node_top = "mcl_core:dirt_with_grass", + depth_top = 1, + node_filler = "mcl_core:dirt", + depth_filler = 4, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + humidity_point = 95, + heat_point = 95, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 13, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = "#77A8FF", + _mcl_fogcolor = overworld_fogcolor + }) + minetest.register_biome({ + name = "BambooJungleEdgeM_ocean", + node_top = "mcl_core:sand", + depth_top = 1, + node_filler = "mcl_core:sand", + depth_filler = 4, + node_riverbed = "mcl_core:sand", + depth_riverbed = 2, + y_min = OCEAN_MIN, + y_max = 0, + humidity_point = 97, + heat_point = 90, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 27, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 2, + _mcl_waterfogcolor = lukewarm_waterfogcolor, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Add deep ocean and underground biomes automatically. - for i=1, #overworld_biomes do + for i = 1, #overworld_biomes do local biome = overworld_biomes[i] -- Deep Ocean @@ -1447,15 +2147,19 @@ local function register_biomes() humidity_point = minetest.registered_biomes[biome].humidity_point, y_min = DEEP_OCEAN_MIN, y_max = DEEP_OCEAN_MAX, - node_top = minetest.registered_biomes[biome.."_ocean"].node_top, + node_top = minetest.registered_biomes[biome .. "_ocean"].node_top, depth_top = 2, - node_filler = minetest.registered_biomes[biome.."_ocean"].node_filler, + node_filler = minetest.registered_biomes[biome .. "_ocean"].node_filler, depth_filler = 3, - node_riverbed = minetest.registered_biomes[biome.."_ocean"].node_riverbed, + node_riverbed = minetest.registered_biomes[biome .. "_ocean"].node_riverbed, depth_riverbed = 2, vertical_blend = 5, _mcl_biome_type = minetest.registered_biomes[biome]._mcl_biome_type, - _mcl_palette_index = minetest.registered_biomes[biome]._mcl_palette_index, + _mcl_grass_palette_index = minetest.registered_biomes[biome]._mcl_grass_palette_index, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = minetest.registered_biomes[biome]._mcl_water_palette_index, + _mcl_skycolor = ocean_skycolor, + _mcl_fogcolor = overworld_fogcolor }) -- Underground biomes are used to identify the underground and to prevent nodes from the surface @@ -1467,7 +2171,11 @@ local function register_biomes() y_min = mcl_vars.mg_overworld_min, y_max = DEEP_OCEAN_MIN - 1, _mcl_biome_type = minetest.registered_biomes[biome]._mcl_biome_type, - _mcl_palette_index = minetest.registered_biomes[biome]._mcl_palette_index, + _mcl_grass_palette_index = minetest.registered_biomes[biome]._mcl_grass_palette_index, + _mcl_foliage_palette_index = minetest.registered_biomes[biome]._mcl_foliage_palette_index, + _mcl_water_palette_index = minetest.registered_biomes[biome]._mcl_water_palette_index, + _mcl_skycolor = minetest.registered_biomes[biome]._mcl_skycolor, + _mcl_fogcolor = minetest.registered_biomes[biome]._mcl_fogcolor, }) end @@ -1478,20 +2186,241 @@ local function register_dimension_biomes() --[[ REALMS ]] --[[ THE NETHER ]] + -- the following decoration is a hack to cover exposed bedrock in netherrack - be careful not to put any ceiling decorations in a way that would apply to this (they would get generated regardless of biome) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:bedrock"}, + sidelen = 16, + fill_ratio = 10, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max + 15, + height = 6, + max_height = 10, + decoration = "mcl_nether:netherrack", + flags = "all_ceilings", + param2 = 0, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:bedrock"}, + sidelen = 16, + fill_ratio = 10, + y_min = mcl_vars.mg_nether_min - 10, + y_max = mcl_vars.mg_lava_nether_max, + height = 7, + max_height = 14, + decoration = "mcl_nether:netherrack", + flags = "all_floors,force_placement", + param2 = 0, + }) + minetest.register_biome({ name = "Nether", node_filler = "mcl_nether:netherrack", node_stone = "mcl_nether:netherrack", + node_top = "mcl_nether:netherrack", node_water = "air", node_river_water = "air", + node_cave_liquid = "air", y_min = mcl_vars.mg_nether_min, - -- FIXME: For some reason the Nether stops generating early if this constant is not added. - -- Figure out why. + y_max = mcl_vars.mg_nether_max + 80, heat_point = 100, humidity_point = 0, _mcl_biome_type = "hot", - _mcl_palette_index = 19, + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = nether_skycolor, + _mcl_fogcolor = "#330808" + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_blackstone:nether_gold", "mcl_nether:quartz_ore", "mcl_core:gravel", "mcl_nether:soul_sand", "mcl_nether:glowstone", "mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_nether:netherrack", + flags = "all_floors", + param2 = 0, + }) + + minetest.register_biome({ + name = "SoulsandValley", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_blackstone:soul_soil", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 77, + humidity_point = 33, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = nether_skycolor, + _mcl_fogcolor = "#1B4745" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_blackstone:soul_soil", + flags = "all_floors, all_ceilings", + param2 = 0, + }) + + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_nether:soul_sand", + wherein = {"mcl_nether:netherrack", "mcl_blackstone:soul_soil"}, + clust_scarcity = 100, + clust_num_ores = 225, + clust_size = 15, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_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_biome({ + name = "CrimsonForest", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_crimson:crimson_nylium", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 60, + humidity_point = 47, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = nether_skycolor, + _mcl_fogcolor = "#330303" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_blackstone:nether_gold", "mcl_nether:quartz_ore", "mcl_core:gravel", "mcl_nether:soul_sand", "mcl_nether:magma", "mcl_blackstone:blackstone"}, + sidelen = 16, + fill_ratio = 10, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_crimson:crimson_nylium", + flags = "all_floors", + param2 = 0, + }) + minetest.register_biome({ + name = "WarpedForest", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_crimson:warped_nylium", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 37, + humidity_point = 70, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = nether_skycolor, + _mcl_fogcolor = "#1A051A" + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_blackstone:nether_gold", "mcl_nether:quartz_ore", "mcl_core:gravel", "mcl_nether:soul_sand", "mcl_nether:magma", "mcl_blackstone:blackstone"}, + sidelen = 16, + fill_ratio = 10, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_crimson:warped_nylium", + flags = "all_floors", + param2 = 0, + }) + minetest.register_biome({ + name = "BasaltDelta", + node_filler = "mcl_nether:netherrack", + node_stone = "mcl_nether:netherrack", + node_top = "mcl_blackstone:basalt", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max + 80, + heat_point = 27, + humidity_point = 80, + _mcl_biome_type = "hot", + _mcl_grass_palette_index = 17, + _mcl_foliage_palette_index = 3, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = nether_skycolor, + _mcl_fogcolor = "#685F70" + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_blackstone:nether_gold", "mcl_nether:quartz_ore", "mcl_core:gravel", "mcl_nether:soul_sand", "mcl_blackstone:blackstone", "mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 10, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_max, + decoration = "mcl_blackstone:basalt", + flags = "all_floors", + param2 = 0, + }) + + minetest.register_ore({ + ore_type = "blob", + ore = "mcl_blackstone:blackstone", + wherein = {"mcl_nether:netherrack", "mcl_nether:glowstone", "mcl_core:gravel"}, + clust_scarcity = 100, + clust_num_ores = 400, + clust_size = 20, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_deco_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", + } }) --[[ THE END ]] @@ -1501,14 +2430,143 @@ local function register_dimension_biomes() node_filler = "air", node_water = "air", node_river_water = "air", - -- FIXME: For some reason the End stops generating early if this constant is not added. - -- Figure out why. + node_cave_liquid = "air", y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, --ridiculously high values so End Island always takes precedent + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndBarrens", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndMidlands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndHighlands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + minetest.register_biome({ + name = "EndSmallIslands", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 1000, + humidity_point = 1000, + vertical_blend = 16, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + + minetest.register_biome({ + name = "EndBorder", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max + 80, + heat_point = 500, + humidity_point = 500, + vertical_blend = 16, + max_pos = {x = 1250, y = mcl_vars.mg_end_min + 512, z = 1250}, + min_pos = {x = -1250, y = mcl_vars.mg_end_min, z = -1250}, + _mcl_biome_type = "medium", + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor + }) + + minetest.register_biome({ + name = "EndIsland", + node_stone = "air", + node_filler = "air", + node_water = "air", + node_river_water = "air", + node_cave_liquid = "air", + max_pos = {x = 650, y = mcl_vars.mg_end_min + 512, z = 650}, + min_pos = {x = -650, y = mcl_vars.mg_end_min, z = -650}, heat_point = 50, humidity_point = 50, + vertical_blend = 16, _mcl_biome_type = "medium", - _mcl_palette_index = 0, + _mcl_grass_palette_index = 0, + _mcl_foliage_palette_index = 0, + _mcl_water_palette_index = 0, + _mcl_waterfogcolor = default_waterfogcolor, + _mcl_skycolor = end_skycolor, + _mcl_fogcolor = end_fogcolor }) end @@ -1519,15 +2577,15 @@ local function register_biome_ores() -- Emeralds minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, clust_scarcity = 16384, clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(4), - y_max = mcl_worlds.layer_to_y(32), - biomes = { + clust_size = 1, + y_min = mcl_worlds.layer_to_y(4), + y_max = mcl_worlds.layer_to_y(32), + biomes = { "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground", "ExtremeHills+", "ExtremeHills+_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills+_underground", "ExtremeHillsM", "ExtremeHillsM_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHillsM_underground", @@ -1543,15 +2601,15 @@ local function register_biome_ores() monster_egg_scarcity = 26 * 26 * 26 end minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_monster_eggs:monster_egg_stone", - wherein = "mcl_core:stone", + ore_type = "scatter", + ore = "mcl_monster_eggs:monster_egg_stone", + wherein = "mcl_core:stone", clust_scarcity = monster_egg_scarcity, clust_num_ores = 3, - clust_size = 2, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(61), - biomes = { + clust_size = 2, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(61), + biomes = { "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground", "ExtremeHills+", "ExtremeHills+_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills+_underground", "ExtremeHillsM", "ExtremeHillsM_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHillsM_underground", @@ -1561,18 +2619,51 @@ local function register_biome_ores() -- Bonus gold spawn in Mesa if mg_name ~= "v6" then minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, clust_scarcity = 3333, clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(32), - y_max = mcl_worlds.layer_to_y(79), - biomes = { "Mesa", "Mesa_sandlevel", "Mesa_ocean", - "MesaBryce", "MesaBryce_sandlevel", "MesaBryce_ocean", - "MesaPlateauF", "MesaPlateauF_sandlevel", "MesaPlateauF_ocean", - "MesaPlateauFM", "MesaPlateauFM_sandlevel", "MesaPlateauFM_ocean", }, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(32), + y_max = mcl_worlds.layer_to_y(79), + biomes = {"Mesa", "Mesa_sandlevel", "Mesa_ocean", + "MesaBryce", "MesaBryce_sandlevel", "MesaBryce_ocean", + "MesaPlateauF", "MesaPlateauF_sandlevel", "MesaPlateauF_ocean", + "MesaPlateauFM", "MesaPlateauFM_sandlevel", "MesaPlateauFM_ocean", }, + }) + end + --nether gold + if mg_name ~= "v6" then + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:blackstone_gilded", + wherein = "mcl_blackstone:blackstone", + clust_scarcity = 4775, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:nether_gold", + wherein = "mcl_nether:netherrack", + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_blackstone:nether_gold", + wherein = "mcl_nether:netherrack", + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, }) end end @@ -1582,132 +2673,182 @@ local function register_biomelike_ores() -- Random coarse dirt floor in Mega Taiga and Mesa Plateau F minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:coarse_dirt", - wherein = {"mcl_core:podzol", "mcl_core:dirt"}, - clust_scarcity = 1, - clust_num_ores = 12, - clust_size = 10, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, + ore_type = "sheet", + ore = "mcl_core:coarse_dirt", + wherein = {"mcl_core:podzol", "mcl_core:dirt"}, + clust_scarcity = 1, + clust_num_ores = 12, + clust_size = 10, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, noise_threshold = 0.2, - noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=24, octaves=3, persist=0.70}, - biomes = { "MegaTaiga" }, + noise_params = {offset = 0, scale = 15, spread = {x = 130, y = 130, z = 130}, seed = 24, octaves = 3, persist = 0.70}, + biomes = {"MegaTaiga"}, }) minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:coarse_dirt", - wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, + ore_type = "sheet", + ore = "mcl_core:coarse_dirt", + wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, column_height_max = 1, column_midpoint_factor = 0.0, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, noise_threshold = 0.0, - noise_params = {offset=0, scale=15, spread={x=250, y=250, z=250}, seed=24, octaves=3, persist=0.70}, - biomes = { "MesaPlateauF_grasstop" }, + noise_params = {offset = 0, scale = 15, spread = {x = 250, y = 250, z = 250}, seed = 24, octaves = 3, persist = 0.70}, + biomes = {"MesaPlateauF_grasstop"}, }) minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:coarse_dirt", - wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, - clust_scarcity = 1500, - clust_num_ores = 25, - clust_size = 7, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - biomes = { "MesaPlateauF_grasstop" }, + ore_type = "blob", + ore = "mcl_core:coarse_dirt", + wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, + clust_scarcity = 1500, + clust_num_ores = 25, + clust_size = 7, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + }, + biomes = {"MesaPlateauF_grasstop"}, }) minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:coarse_dirt", - wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, + ore_type = "sheet", + ore = "mcl_core:coarse_dirt", + wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, column_height_max = 1, column_midpoint_factor = 0.0, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, noise_threshold = -2.5, - noise_params = {offset=1, scale=15, spread={x=250, y=250, z=250}, seed=24, octaves=3, persist=0.80}, - biomes = { "MesaPlateauFM_grasstop" }, + noise_params = {offset = 1, scale = 15, spread = {x = 250, y = 250, z = 250}, seed = 24, octaves = 3, persist = 0.80}, + biomes = {"MesaPlateauFM_grasstop"}, }) minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:coarse_dirt", - wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, - clust_scarcity = 1800, - clust_num_ores = 65, - clust_size = 15, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - biomes = { "MesaPlateauFM_grasstop" }, + ore_type = "blob", + ore = "mcl_core:coarse_dirt", + wherein = {"mcl_core:dirt_with_grass", "mcl_core:dirt"}, + clust_scarcity = 1800, + clust_num_ores = 65, + clust_size = 15, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + }, + biomes = {"MesaPlateauFM_grasstop"}, }) -- Occasionally dig out portions of MesaPlateauFM minetest.register_ore({ - ore_type = "blob", - ore = "air", - wherein = {"group:hardened_clay", "group:sand","mcl_core:coarse_dirt"}, - clust_scarcity = 4000, - clust_size = 5, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - biomes = { "MesaPlateauFM", "MesaPlateauFM_grasstop" }, + ore_type = "blob", + ore = "air", + wherein = {"group:hardened_clay", "group:sand", "mcl_core:coarse_dirt"}, + clust_scarcity = 4000, + clust_size = 5, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + }, + biomes = {"MesaPlateauFM", "MesaPlateauFM_grasstop"}, }) minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:redsandstone", - wherein = {"mcl_colorblocks:hardened_clay_orange"}, - clust_scarcity = 300, - clust_size = 8, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - biomes = { "MesaPlateauFM_sandlevel" }, + ore_type = "blob", + ore = "mcl_core:redsandstone", + wherein = {"mcl_colorblocks:hardened_clay_orange"}, + clust_scarcity = 300, + clust_size = 8, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + }, + biomes = {"MesaPlateauFM_sandlevel"}, }) -- More red sand in MesaPlateauFM minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:redsand", - wherein = {"group:hardened_clay"}, - clust_scarcity = 1, - clust_num_ores = 12, - clust_size = 10, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, + ore_type = "sheet", + ore = "mcl_core:redsand", + wherein = {"group:hardened_clay"}, + clust_scarcity = 1, + clust_num_ores = 12, + clust_size = 10, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, noise_threshold = 0.1, - noise_params = {offset=0, scale=15, spread={x=130, y=130, z=130}, seed=95, octaves=3, persist=0.70}, - biomes = { "MesaPlateauFM" }, + noise_params = {offset = 0, scale = 15, spread = {x = 130, y = 130, z = 130}, seed = 95, octaves = 3, persist = 0.70}, + biomes = {"MesaPlateauFM"}, }) minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:redsand", - wherein = {"group:hardened_clay"}, - clust_scarcity = 1500, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - biomes = { "MesaPlateauFM", "MesaPlateauFM_grasstop", "MesaPlateauFM_sandlevel" }, + ore_type = "blob", + ore = "mcl_core:redsand", + wherein = {"group:hardened_clay"}, + clust_scarcity = 1500, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + }, + biomes = {"MesaPlateauFM", "MesaPlateauFM_grasstop", "MesaPlateauFM_sandlevel"}, }) -- Small dirt patches in Extreme Hills M minetest.register_ore({ - ore_type = "blob", + ore_type = "blob", -- TODO: Should be grass block. But generating this as ore means gras blocks will spawn undeground. :-( - ore = "mcl_core:dirt", - wherein = {"mcl_core:gravel"}, - clust_scarcity = 5000, - clust_num_ores = 12, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, + ore = "mcl_core:dirt", + wherein = {"mcl_core:gravel"}, + clust_scarcity = 5000, + clust_num_ores = 12, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, noise_threshold = 0.2, - noise_params = {offset=0, scale=5, spread={x=250, y=250, z=250}, seed=64, octaves=3, persist=0.60}, - biomes = { "ExtremeHillsM" }, + noise_params = {offset = 0, scale = 5, spread = {x = 250, y = 250, z = 250}, seed = 64, octaves = 3, persist = 0.60}, + biomes = {"ExtremeHillsM"}, }) -- For a transition from stone to hardened clay in mesa biomes that is not perfectly flat minetest.register_ore({ ore_type = "stratum", ore = "mcl_core:stone", wherein = {"group:hardened_clay"}, - noise_params = {offset=-6, scale=2, spread={x=25, y=25, z=25}, octaves=1, persist=0.60}, + noise_params = {offset = -6, scale = 2, spread = {x = 25, y = 25, z = 25}, octaves = 1, persist = 0.60}, stratum_thickness = 8, biomes = { "Mesa_sandlevel", "Mesa_ocean", @@ -1723,25 +2864,25 @@ local function register_biomelike_ores() -- Mesa strata (registered as sheet ores) -- Helper function to create strata. - local stratum = function(y_min, height, color, seed, is_perfect) + local function stratum(y_min, height, color, seed, is_perfect) if not height then height = 1 end if not seed then seed = 39 end - local y_max = y_min + height-1 + local y_max = y_min + height - 1 local perfect_biomes if is_perfect then -- "perfect" means no erosion - perfect_biomes = { "MesaBryce", "Mesa", "MesaPlateauF", "MesaPlateauFM" } + perfect_biomes = {"MesaBryce", "Mesa", "MesaPlateauF", "MesaPlateauFM"} else - perfect_biomes = { "MesaBryce" } + perfect_biomes = {"MesaBryce"} end -- Full, perfect stratum minetest.register_ore({ ore_type = "stratum", - ore = "mcl_colorblocks:hardened_clay_"..color, + ore = "mcl_colorblocks:hardened_clay_" .. color, -- Only paint uncolored so the biome can choose -- a color in advance. wherein = {"mcl_colorblocks:hardened_clay"}, @@ -1750,56 +2891,56 @@ local function register_biomelike_ores() biomes = perfect_biomes, }) if not is_perfect then - -- Slightly eroded stratum, only minor imperfections - minetest.register_ore({ - ore_type = "stratum", - ore = "mcl_colorblocks:hardened_clay_"..color, - wherein = {"mcl_colorblocks:hardened_clay"}, - y_min = y_min, - y_max = y_max, - biomes = { "Mesa", "MesaPlateauF" }, - noise_params = { - offset = y_min+(y_max-y_min)/2, - scale = 0, - spread = {x = 50, y = 50, z = 50}, - seed = seed+4, - octaves = 1, - persist = 1.0 - }, - np_stratum_thickness = { - offset = 1.28, - scale = 1, - spread = {x = 18, y = 18, z = 18}, - seed = seed+4, - octaves = 3, - persist = 0.8, - }, - }) - -- Very eroded stratum, most of the color is gone - minetest.register_ore({ - ore_type = "stratum", - ore = "mcl_colorblocks:hardened_clay_"..color, - wherein = {"mcl_colorblocks:hardened_clay"}, - y_min = y_min, - y_max = y_max, - biomes = { "MesaPlateauFM" }, - noise_params = { - offset = y_min+(y_max-y_min)/2, - scale = 0, - spread = {x = 50, y = 50, z = 50}, - seed = seed+4, - octaves = 1, - persist = 1.0 - }, - np_stratum_thickness = { - offset = 0.1, - scale = 1, - spread = {x = 28, y = 28, z = 28}, - seed = seed+4, - octaves = 2, - persist = 0.6, - }, - }) + -- Slightly eroded stratum, only minor imperfections + minetest.register_ore({ + ore_type = "stratum", + ore = "mcl_colorblocks:hardened_clay_" .. color, + wherein = {"mcl_colorblocks:hardened_clay"}, + y_min = y_min, + y_max = y_max, + biomes = {"Mesa", "MesaPlateauF"}, + noise_params = { + offset = y_min + (y_max - y_min) / 2, + scale = 0, + spread = {x = 50, y = 50, z = 50}, + seed = seed + 4, + octaves = 1, + persist = 1.0 + }, + np_stratum_thickness = { + offset = 1.28, + scale = 1, + spread = {x = 18, y = 18, z = 18}, + seed = seed + 4, + octaves = 3, + persist = 0.8, + }, + }) + -- Very eroded stratum, most of the color is gone + minetest.register_ore({ + ore_type = "stratum", + ore = "mcl_colorblocks:hardened_clay_" .. color, + wherein = {"mcl_colorblocks:hardened_clay"}, + y_min = y_min, + y_max = y_max, + biomes = {"MesaPlateauFM"}, + noise_params = { + offset = y_min + (y_max - y_min) / 2, + scale = 0, + spread = {x = 50, y = 50, z = 50}, + seed = seed + 4, + octaves = 1, + persist = 1.0 + }, + np_stratum_thickness = { + offset = 0.1, + scale = 1, + spread = {x = 28, y = 28, z = 28}, + seed = seed + 4, + octaves = 2, + persist = 0.6, + }, + }) end end @@ -1828,7 +2969,7 @@ local function register_biomelike_ores() suddenly don't match up anymore. ]] -- Available Mesa colors: - local mesa_stratum_colors = { "silver", "brown", "orange", "red", "yellow", "white" } + local mesa_stratum_colors = {"silver", "brown", "orange", "red", "yellow", "white"} -- Start level local y = 17 @@ -1888,17 +3029,17 @@ local function register_dimension_ores() -- Soul sand minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_nether:soul_sand", + ore_type = "sheet", + ore = "mcl_nether:soul_sand", -- Note: Stone is included only for v6 mapgen support. Netherrack is not generated naturally -- in v6, but instead set with the on_generated function in mcl_mapgen_core. - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 13 * 13 * 13, - clust_size = 5, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_worlds.layer_to_y(64, "nether"), + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 13 * 13 * 13, + clust_size = 5, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_worlds.layer_to_y(64, "nether"), noise_threshold = 0.0, - noise_params = { + noise_params = { offset = 0.5, scale = 0.1, spread = {x = 5, y = 5, z = 5}, @@ -1910,37 +3051,57 @@ local function register_dimension_ores() -- Magma blocks minetest.register_ore({ - ore_type = "blob", - ore = "mcl_nether:magma", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 8*8*8, + ore_type = "blob", + ore = "mcl_nether:magma", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 8 * 8 * 8, clust_num_ores = 45, - clust_size = 6, - y_min = mcl_worlds.layer_to_y(23, "nether"), - y_max = mcl_worlds.layer_to_y(37, "nether"), + clust_size = 6, + y_min = mcl_worlds.layer_to_y(23, "nether"), + y_max = mcl_worlds.layer_to_y(37, "nether"), + 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_nether:magma", - wherein = {"mcl_nether:netherrack"}, - clust_scarcity = 10*10*10, + ore_type = "blob", + ore = "mcl_nether:magma", + wherein = {"mcl_nether:netherrack"}, + clust_scarcity = 10 * 10 * 10, clust_num_ores = 65, - clust_size = 8, - y_min = mcl_worlds.layer_to_y(23, "nether"), - y_max = mcl_worlds.layer_to_y(37, "nether"), + clust_size = 8, + y_min = mcl_worlds.layer_to_y(23, "nether"), + y_max = mcl_worlds.layer_to_y(37, "nether"), + noise_params = { + offset = 0, + scale = 1, + spread = {x = 250, y = 250, z = 250}, + seed = 12345, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + }, }) -- Glowstone minetest.register_ore({ - ore_type = "blob", - ore = "mcl_nether:glowstone", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 26 * 26 * 26, - clust_size = 5, - y_min = mcl_vars.mg_lava_nether_max + 10, - y_max = mcl_vars.mg_nether_max, + ore_type = "blob", + ore = "mcl_nether:glowstone", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 26 * 26 * 26, + clust_size = 5, + y_min = mcl_vars.mg_lava_nether_max + 10, + y_max = mcl_vars.mg_nether_max - 13, noise_threshold = 0.0, - noise_params = { + noise_params = { offset = 0.5, scale = 0.1, spread = {x = 5, y = 5, z = 5}, @@ -1952,17 +3113,17 @@ local function register_dimension_ores() -- Gravel (Nether) minetest.register_ore({ - ore_type = "sheet", - ore = "mcl_core:gravel", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + ore_type = "sheet", + ore = "mcl_core:gravel", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, column_height_min = 1, column_height_max = 1, column_midpoint_factor = 0, - y_min = mcl_worlds.layer_to_y(63, "nether"), + y_min = mcl_worlds.layer_to_y(63, "nether"), -- This should be 65, but for some reason with this setting, the sheet ore really stops at 65. o_O - y_max = mcl_worlds.layer_to_y(65+2, "nether"), + y_max = mcl_worlds.layer_to_y(65 + 2, "nether"), noise_threshold = 0.2, - noise_params = { + noise_params = { offset = 0.0, scale = 0.5, spread = {x = 20, y = 20, z = 20}, @@ -1973,69 +3134,87 @@ local function register_dimension_ores() }) -- Nether quartz - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 850, - clust_num_ores = 4, -- MC cluster amount: 4-10 - clust_size = 3, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:quartz_ore", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, - clust_scarcity = 1650, - clust_num_ores = 8, -- MC cluster amount: 4-10 - clust_size = 4, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_nether_max, - }) + if minetest.settings:get_bool("mcl_generate_ores", true) then + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 850, + clust_num_ores = 4, -- MC cluster amount: 4-10 + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:quartz_ore", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 1650, + clust_num_ores = 8, -- MC cluster amount: 4-10 + clust_size = 4, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + }) + end -- Lava springs in the Nether minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + clust_scarcity = 13500, --rare + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max - 13, + }) + + local lava_biomes = {"BasaltDelta", "Nether"} + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 500, clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_nether_min, - y_max = mcl_vars.mg_lava_nether_max + 1, + clust_size = 1, + biomes = lava_biomes, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_lava_nether_max + 1, }) minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 1000, clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_lava_nether_max + 2, - y_max = mcl_vars.mg_lava_nether_max + 12, + clust_size = 1, + biomes = lava_biomes, + y_min = mcl_vars.mg_lava_nether_max + 2, + y_max = mcl_vars.mg_lava_nether_max + 12, }) minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 2000, clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_lava_nether_max + 13, - y_max = mcl_vars.mg_lava_nether_max + 48, + clust_size = 1, + biomes = lava_biomes, + y_min = mcl_vars.mg_lava_nether_max + 13, + y_max = mcl_vars.mg_lava_nether_max + 48, }) minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_nether:nether_lava_source", - wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, + ore_type = "scatter", + ore = "mcl_nether:nether_lava_source", + wherein = {"mcl_nether:netherrack", "mcl_core:stone"}, clust_scarcity = 3500, clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_lava_nether_max + 49, - y_max = mcl_vars.mg_nether_max, + clust_size = 1, + biomes = lava_biomes, + y_min = mcl_vars.mg_lava_nether_max + 49, + y_max = mcl_vars.mg_nether_max - 13, }) --[[ THE END ]] @@ -2051,27 +3230,64 @@ local function register_dimension_ores() end_wherein = {"air"} end + local mult = 1.0 + minetest.register_ore({ - ore_type = "stratum", - ore = "mcl_end:end_stone", - wherein = end_wherein, - y_min = mcl_vars.mg_end_min+64, - y_max = mcl_vars.mg_end_min+80, + ore_type = "stratum", + ore = "mcl_end:end_stone", + wherein = end_wherein, + biomes = {"EndSmallIslands", "Endborder"}, + y_min = mcl_vars.mg_end_min + 64, + y_max = mcl_vars.mg_end_min + 80, + clust_num_ores = 3375, + clust_size = 15, noise_params = { - offset = mcl_vars.mg_end_min+70, - scale = -1, - spread = {x=126, y=126, z=126}, - seed = mg_seed+9999, + offset = mcl_vars.mg_end_min + 70, + scale = -1, + spread = {x = 84, y = 84, z = 84}, + seed = 145, + octaves = 3, + persist = 0.6, + lacunarity = 2, + --flags = "defaults", + }, + + np_stratum_thickness = { + offset = 0, + scale = 15, + spread = {x = 84, y = 84, z = 84}, + seed = 145, + octaves = 3, + persist = 0.6, + lacunarity = 2, + --flags = "defaults", + }, + clust_scarcity = 1, + }) + + minetest.register_ore({ + ore_type = "stratum", + ore = "mcl_end:end_stone", + wherein = end_wherein, + biomes = {"End", "EndMidlands", "EndHighlands", "EndBarrens"}, + y_min = mcl_vars.mg_end_min + 64, + y_max = mcl_vars.mg_end_min + 80, + + noise_params = { + offset = mcl_vars.mg_end_min + 70, + scale = -1, + spread = {x = 126, y = 126, z = 126}, + seed = mg_seed + 9999, octaves = 3, persist = 0.5, }, np_stratum_thickness = { - offset = -2, - scale = 10, - spread = {x=126, y=126, z=126}, - seed = mg_seed+9999, + offset = -2, + scale = 10, + spread = {x = 126, y = 126, z = 126}, + seed = mg_seed + 9999, octaves = 3, persist = 0.5, }, @@ -2079,52 +3295,54 @@ local function register_dimension_ores() }) minetest.register_ore({ - ore_type = "stratum", - ore = "mcl_end:end_stone", - wherein = end_wherein, - y_min = mcl_vars.mg_end_min+64, - y_max = mcl_vars.mg_end_min+80, + ore_type = "stratum", + ore = "mcl_end:end_stone", + wherein = end_wherein, + biomes = {"End", "EndMidlands", "EndHighlands", "EndBarrens"}, + y_min = mcl_vars.mg_end_min + 64, + y_max = mcl_vars.mg_end_min + 80, noise_params = { - offset = mcl_vars.mg_end_min+72, - scale = -3, - spread = {x=84, y=84, z=84}, - seed = mg_seed+999, + offset = mcl_vars.mg_end_min + 72, + scale = -3, + spread = {x = 84, y = 84, z = 84}, + seed = mg_seed + 999, octaves = 4, persist = 0.8, }, np_stratum_thickness = { - offset = -4, - scale = 10, - spread = {x=84, y=84, z=84}, - seed = mg_seed+999, + offset = -4, + scale = 10, + spread = {x = 84, y = 84, z = 84}, + seed = mg_seed + 999, octaves = 4, persist = 0.8, }, clust_scarcity = 1, }) minetest.register_ore({ - ore_type = "stratum", - ore = "mcl_end:end_stone", - wherein = end_wherein, - y_min = mcl_vars.mg_end_min+64, - y_max = mcl_vars.mg_end_min+80, + ore_type = "stratum", + ore = "mcl_end:end_stone", + wherein = end_wherein, + biomes = {"End", "EndMidlands", "EndHighlands", "EndBarrens"}, + y_min = mcl_vars.mg_end_min + 64, + y_max = mcl_vars.mg_end_min + 80, noise_params = { - offset = mcl_vars.mg_end_min+70, - scale = -2, - spread = {x=84, y=84, z=84}, - seed = mg_seed+99, + offset = mcl_vars.mg_end_min + 70, + scale = -2, + spread = {x = 84, y = 84, z = 84}, + seed = mg_seed + 99, octaves = 4, persist = 0.85, }, np_stratum_thickness = { - offset = -3, - scale = 5, - spread = {x=63, y=63, z=63}, - seed = mg_seed+50, + offset = -3, + scale = 5, + spread = {x = 63, y = 63, z = 63}, + seed = mg_seed + 50, octaves = 4, persist = 0.85, }, @@ -2141,11 +3359,11 @@ local function register_grass_decoration(grasstype, offset, scale, biomes) local place_on, seed, node if grasstype == "fern" then node = "mcl_flowers:fern" - place_on = {"group:grass_block_no_snow", "mcl_core:podzol"} + place_on = {"group:grass_block_no_snow", "mcl_core:podzol", "mcl_mud:mud"} seed = 333 elseif grasstype == "tallgrass" then node = "mcl_flowers:tallgrass" - place_on = {"group:grass_block_no_snow"} + place_on = {"group:grass_block_no_snow", "mcl_mud:mud"} seed = 420 end local noise = { @@ -2156,14 +3374,14 @@ local function register_grass_decoration(grasstype, offset, scale, biomes) octaves = 3, persist = 0.6 } - for b=1, #biomes do - local param2 = minetest.registered_biomes[biomes[b]]._mcl_palette_index + for b = 1, #biomes do + local param2 = minetest.registered_biomes[biomes[b]]._mcl_grass_palette_index minetest.register_decoration({ deco_type = "simple", place_on = place_on, sidelen = 16, noise_params = noise, - biomes = { biomes[b] }, + biomes = {biomes[b]}, y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = node, @@ -2176,15 +3394,15 @@ local function register_seagrass_decoration(grasstype, offset, scale, biomes) local seed, nodes, surfaces, param2, param2_max, y_max if grasstype == "seagrass" then seed = 16 - surfaces = { "mcl_core:dirt", "mcl_core:sand", "mcl_core:gravel", "mcl_core:redsand" } - nodes = { "mcl_ocean:seagrass_dirt", "mcl_ocean:seagrass_sand", "mcl_ocean:seagrass_gravel", "mcl_ocean:seagrass_redsand" } + surfaces = {"mcl_core:dirt", "mcl_core:sand", "mcl_core:gravel", "mcl_core:redsand"} + nodes = {"mcl_ocean:seagrass_dirt", "mcl_ocean:seagrass_sand", "mcl_ocean:seagrass_gravel", "mcl_ocean:seagrass_redsand"} y_max = 0 elseif grasstype == "kelp" then seed = 32 param2 = 16 param2_max = 96 - surfaces = { "mcl_core:dirt", "mcl_core:sand", "mcl_core:gravel" } - nodes = { "mcl_ocean:kelp_dirt", "mcl_ocean:kelp_sand", "mcl_ocean:kelp_gravel" } + surfaces = {"mcl_core:dirt", "mcl_core:sand", "mcl_core:gravel"} + nodes = {"mcl_ocean:kelp_dirt", "mcl_ocean:kelp_sand", "mcl_ocean:kelp_gravel"} y_max = -6 end local noise = { @@ -2196,10 +3414,10 @@ local function register_seagrass_decoration(grasstype, offset, scale, biomes) persist = 0.6, } - for s=1, #surfaces do + for s = 1, #surfaces do minetest.register_decoration({ deco_type = "simple", - place_on = { surfaces[s] }, + place_on = {surfaces[s]}, sidelen = 16, noise_params = noise, biomes = biomes, @@ -2214,9 +3432,218 @@ local function register_seagrass_decoration(grasstype, offset, scale, biomes) end end +local coral_min = OCEAN_MIN +local coral_max = -10 +local warm_oceans = { + "JungleEdgeM_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "Swampland_ocean", + "Mesa_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "MushroomIsland_ocean", + "SavannaM_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "Jungle_ocean", + "Desert_ocean", + "JungleM_ocean", + "MangroveSwamp_ocean" +} +local corals = { + "brain", + "horn", + "bubble", + "tube", + "fire" +} +local function register_coral_decos(ck) + local c = corals[ck] + local noise = { + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 1.8, + lacunarity = 3.5, + flags = "absvalue" + } + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand", "mcl_core:gravel", "mcl_mud:mud"}, + sidelen = 80, + noise_params = noise, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures .. "/schematics/mcl_structures_coral_" .. c .. "_1.mts", + rotation = "random", + flags = "all_floors,force_placement", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand", "mcl_core:gravel", "mcl_mud:mud"}, + noise_params = noise, + sidelen = 80, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures .. "/schematics/mcl_structures_coral_" .. c .. "_2.mts", + rotation = "random", + flags = "all_floors,force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:" .. c .. "_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:" .. c .. "_coral", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:horn_coral_block"}, + sidelen = 16, + fill_ratio = 7, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:" .. c .. "_coral_fan", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + }) +end local function register_decorations() + -- Coral Reefs + for k, _ in pairs(corals) do + register_coral_decos(k) + end + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "mcl_core:gravel", "mcl_mud:mud"}, + sidelen = 16, + noise_params = { + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 1.8, + lacunarity = 3.5, + flags = "absvalue" + }, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_1_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 3, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_2_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 2, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_3_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_ocean:dead_brain_coral_block"}, + sidelen = 16, + fill_ratio = 2, + y_min = coral_min, + y_max = coral_max, + decoration = "mcl_ocean:sea_pickle_4_dead_brain_coral_block", + biomes = warm_oceans, + flags = "force_placement, all_floors", + height = 1, + height_max = 1, + place_offset_y = -1, + }) + --rare CORAl + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:sand", "mcl_core:gravel"}, + fill_ratio = 0.0001, + sidelen = 80, + biomes = warm_oceans, + y_min = coral_min, + y_max = coral_max, + schematic = mod_mcl_structures .. "/schematics/coral_cora.mts", + rotation = "random", + flags = "place_center_x,place_center_z, force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass", "mcl_core:podzol"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.012, + spread = {x = 100, y = 100, z = 100}, + seed = 354, + octaves = 1, + persist = 0.5, + lacunarity = 1.0, + flags = "absvalue" + }, + biomes = {"Taiga", "ColdTaiga", "MegaTaiga", "MegaSpruceTaiga", "Forest"}, + y_max = mcl_vars.mg_overworld_max, + y_min = 2, + decoration = "mcl_sweet_berry:sweet_berry_bush_3" + }) + -- Large ice spike minetest.register_decoration({ deco_type = "schematic", @@ -2233,7 +3660,7 @@ local function register_decorations() biomes = {"IcePlainsSpikes"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts", + schematic = mod_mcl_structures .. "/schematics/mcl_structures_ice_spike_large.mts", rotation = "random", flags = "place_center_x, place_center_z", }) @@ -2254,14 +3681,14 @@ local function register_decorations() biomes = {"IcePlainsSpikes"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts", + schematic = mod_mcl_structures .. "/schematics/mcl_structures_ice_spike_small.mts", rotation = "random", flags = "place_center_x, place_center_z", }) -- Oak -- Large oaks - for i=1, 4 do + for i = 1, 4 do minetest.register_decoration({ deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, @@ -2277,7 +3704,7 @@ local function register_decorations() biomes = {"Forest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_large_"..i..".mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_large_" .. i .. ".mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2297,7 +3724,7 @@ local function register_decorations() biomes = {"ExtremeHills", "ExtremeHillsM", "ExtremeHills+", "ExtremeHills+_snowtop"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_large_"..i..".mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_large_" .. i .. ".mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2318,7 +3745,7 @@ local function register_decorations() biomes = {"Forest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2337,7 +3764,7 @@ local function register_decorations() biomes = {"FlowerForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2356,7 +3783,7 @@ local function register_decorations() biomes = {"ExtremeHills", "ExtremeHillsM", "ExtremeHills+", "ExtremeHills+_snowtop"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2376,7 +3803,7 @@ local function register_decorations() biomes = {"ExtremeHills+", "ExtremeHills+_snowtop"}, y_min = 50, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2395,7 +3822,7 @@ local function register_decorations() biomes = {"MesaPlateauF_grasstop"}, y_min = 30, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2414,7 +3841,7 @@ local function register_decorations() biomes = {"MesaPlateauFM_grasstop"}, y_min = 30, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2434,7 +3861,7 @@ local function register_decorations() biomes = {"IcePlains"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2446,7 +3873,7 @@ local function register_decorations() biomes = {"Jungle", "JungleM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2458,11 +3885,52 @@ local function register_decorations() biomes = {"JungleEdge", "JungleEdgeM", "Savanna"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_classic.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic.mts", flags = "place_center_x, place_center_z", rotation = "random", }) - + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.0002, + biomes = {"FlowerForest"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.00002, + biomes = {"Forest"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_classic_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) -- Rare balloon oak minetest.register_decoration({ @@ -2480,7 +3948,7 @@ local function register_decorations() biomes = {"Forest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_balloon.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_balloon.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2501,24 +3969,164 @@ local function register_decorations() biomes = {"Swampland", "Swampland_shore"}, y_min = 0, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_oak_swamp.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_oak_swamp.mts", flags = "place_center_x, place_center_z", rotation = "random", }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_1", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.0065, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_tree_1.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_2", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.0045, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_tree_2.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_3", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_tree_3.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_4", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_tree_4.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + name = "mcl_biomes:mangrove_tree_4", + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.023, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = -1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_tree_5.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.0005, + biomes = {"MangroveSwamp"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_mangrove .. "/schematics/mcl_mangrove_bee_nest.mts", + flags = "place_center_x, place_center_z, force_placement", + rotation = "random", + spawn_by = "group:flower", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.045, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = 0, + y_max = 0, + decoration = "mcl_mangrove:water_logged_roots", + flags = "place_center_x, place_center_z, force_placement", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mangrove:mangrove_roots"}, + spawn_by = {"group:water"}, + num_spawn_by = 2, + sidelen = 80, + fill_ratio = 10, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + y_min = 0, + y_max = 0, + decoration = "mcl_mangrove:water_logged_roots", + flags = "place_center_x, place_center_z, force_placement, all_ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.045, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + place_offset_y = -1, + decoration = "mcl_mangrove:mangrove_mud_roots", + flags = "place_center_x, place_center_z, force_placement", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_mud:mud"}, + sidelen = 80, + fill_ratio = 0.008, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + decoration = "mcl_core:deadbush", + flags = "place_center_x, place_center_z", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:water_source"}, + sidelen = 80, + fill_ratio = 0.035, + biomes = {"MangroveSwamp", "MangroveSwamp_shore"}, + decoration = "mcl_flowers:waterlily", + flags = "place_center_x, place_center_z, liquid_surface", + }) + -- Jungle tree - -- Huge jungle tree (2 variants) - for i=1, 2 do + -- Huge jungle tree (4 variants) + for i = 1, 4 do minetest.register_decoration({ deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.00125, + fill_ratio = 0.0008, biomes = {"Jungle"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_tree_huge_"..i..".mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_huge_" .. i .. ".mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2526,11 +4134,11 @@ local function register_decorations() deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.004, + fill_ratio = 0.003, biomes = {"JungleM"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_tree_huge_"..i..".mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_huge_" .. i .. ".mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2541,11 +4149,59 @@ local function register_decorations() deco_type = "schematic", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - fill_ratio = 0.045, + fill_ratio = 0.025, biomes = {"Jungle"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_tree.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.015, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_2.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_3.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.005, + biomes = {"Jungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_4.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + fill_ratio = 0.025, + biomes = {"Jungle","BambooJungle"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2554,10 +4210,10 @@ local function register_decorations() place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = 0.0045, - biomes = {"JungleEdge", "JungleEdgeM"}, + biomes = {"JungleEdge", "JungleEdgeM", "BambooJungleEdge", "BambooJungleEdgeM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_tree.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree.mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2567,14 +4223,13 @@ local function register_decorations() place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = 0.09, - biomes = {"JungleM"}, + biomes = {"JungleM", "BambooJungleM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_jungle_tree.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_tree_2.mts", flags = "place_center_x, place_center_z", rotation = "random", }) - -- Spruce local function quick_spruce(seed, offset, sprucename, biomes, y) if not y then @@ -2595,7 +4250,7 @@ local function register_decorations() biomes = biomes, y_min = y, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/"..sprucename, + schematic = mod_mcl_core .. "/schematics/" .. sprucename, flags = "place_center_x, place_center_z", }) end @@ -2649,7 +4304,7 @@ local function register_decorations() biomes = {"Taiga", "ColdTaiga"}, y_min = 2, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_spruce_lollipop.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_spruce_lollipop.mts", flags = "place_center_x, place_center_z", }) @@ -2669,7 +4324,7 @@ local function register_decorations() biomes = {"Taiga", "ColdTaiga"}, y_min = 3, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_spruce_matchstick.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_spruce_matchstick.mts", flags = "place_center_x, place_center_z", }) @@ -2689,12 +4344,12 @@ local function register_decorations() biomes = {"IcePlains"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_spruce_5.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_spruce_5.mts", flags = "place_center_x, place_center_z", }) -- Acacia (many variants) - for a=1, 7 do + for a = 1, 7 do minetest.register_decoration({ deco_type = "schematic", place_on = {"mcl_core:dirt_with_grass", "mcl_core:dirt", "mcl_core:coarse_dirt"}, @@ -2703,7 +4358,7 @@ local function register_decorations() biomes = {"Savanna", "SavannaM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_acacia_"..a..".mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_acacia_" .. a .. ".mts", flags = "place_center_x, place_center_z", rotation = "random", }) @@ -2725,7 +4380,7 @@ local function register_decorations() biomes = {"BirchForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_birch.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_birch.mts", flags = "place_center_x, place_center_z", }) minetest.register_decoration({ @@ -2743,7 +4398,7 @@ local function register_decorations() biomes = {"BirchForestM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_birch_tall.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_birch_tall.mts", flags = "place_center_x, place_center_z", }) @@ -2762,9 +4417,30 @@ local function register_decorations() biomes = {"Forest", "FlowerForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_birch.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_birch.mts", flags = "place_center_x, place_center_z", }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 16, + --[[noise_params = { + offset = 0.01, + scale = 0.00001, + spread = {x = 250, y = 250, z = 250}, + seed = 2, + octaves = 3, + persist = 0.33 + },]]-- + fill_ratio = 0.00002, + biomes = {"Forest", "BirchForest", "BirchForestM"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_birch_bee_nest.mts", + flags = "place_center_x, place_center_z", + rotation = "random", + spawn_by = "group:flower", + }) -- Dark Oak minetest.register_decoration({ @@ -2782,66 +4458,65 @@ local function register_decorations() biomes = {"RoofedForest"}, y_min = 4, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_core").."/schematics/mcl_core_dark_oak.mts", + schematic = mod_mcl_core .. "/schematics/mcl_core_dark_oak.mts", flags = "place_center_x, place_center_z", rotation = "random", }) - local ratio_mushroom = 0.0001 - local ratio_mushroom_huge = ratio_mushroom * (11/12) - local ratio_mushroom_giant = ratio_mushroom * (1/12) + local ratio_mushroom_huge = ratio_mushroom * (11 / 12) + local ratio_mushroom_giant = ratio_mushroom * (1 / 12) local ratio_mushroom_mycelium = 0.002 - local ratio_mushroom_mycelium_huge = ratio_mushroom_mycelium * (11/12) - local ratio_mushroom_mycelium_giant = ratio_mushroom_mycelium * (1/12) + local ratio_mushroom_mycelium_huge = ratio_mushroom_mycelium * (11 / 12) + local ratio_mushroom_mycelium_giant = ratio_mushroom_mycelium * (1 / 12) -- Huge Brown Mushroom minetest.register_decoration({ deco_type = "schematic", - place_on = { "group:grass_block_no_snow", "mcl_core:dirt" }, + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = ratio_mushroom_huge, - biomes = { "RoofedForest" }, + biomes = {"RoofedForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_brown.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_huge_brown.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "group:grass_block_no_snow", "mcl_core:dirt" }, + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = ratio_mushroom_giant, - biomes = { "RoofedForest" }, + biomes = {"RoofedForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_giant_brown.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_giant_brown.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "mcl_core:mycelium" }, + place_on = {"mcl_core:mycelium"}, sidelen = 80, fill_ratio = ratio_mushroom_mycelium_huge, - biomes = { "MushroomIsland", "MushroomIslandShore" }, + biomes = {"MushroomIsland", "MushroomIslandShore"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_brown.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_huge_brown.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "mcl_core:mycelium" }, + place_on = {"mcl_core:mycelium"}, sidelen = 80, fill_ratio = ratio_mushroom_mycelium_giant, - biomes = { "MushroomIsland", "MushroomIslandShore" }, + biomes = {"MushroomIsland", "MushroomIslandShore"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_giant_brown.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_giant_brown.mts", flags = "place_center_x, place_center_z", rotation = "0", }) @@ -2849,54 +4524,89 @@ local function register_decorations() -- Huge Red Mushroom minetest.register_decoration({ deco_type = "schematic", - place_on = { "group:grass_block_no_snow", "mcl_core:dirt" }, + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = ratio_mushroom_huge, - biomes = { "RoofedForest" }, + biomes = {"RoofedForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_red.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_huge_red.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "group:grass_block_no_snow", "mcl_core:dirt" }, + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, fill_ratio = ratio_mushroom_giant, - biomes = { "RoofedForest" }, + biomes = {"RoofedForest"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_giant_red.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_giant_red.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "mcl_core:mycelium" }, + place_on = {"mcl_core:mycelium"}, sidelen = 80, fill_ratio = ratio_mushroom_mycelium_huge, - biomes = { "MushroomIsland", "MushroomIslandShore" }, + biomes = {"MushroomIsland", "MushroomIslandShore"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_huge_red.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_huge_red.mts", flags = "place_center_x, place_center_z", rotation = "0", }) minetest.register_decoration({ deco_type = "schematic", - place_on = { "mcl_core:mycelium" }, + place_on = {"mcl_core:mycelium"}, sidelen = 80, fill_ratio = ratio_mushroom_mycelium_giant, - biomes = { "MushroomIsland", "MushroomIslandShore" }, + biomes = {"MushroomIsland", "MushroomIslandShore"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_mushrooms").."/schematics/mcl_mushrooms_giant_red.mts", + schematic = mod_mcl_mushrooms .. "/schematics/mcl_mushrooms_giant_red.mts", flags = "place_center_x, place_center_z", rotation = "0", }) + --Snow on snowy dirt + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt_with_grass_snow"}, + sidelen = 80, + fill_ratio = 10, + flags = "all_floors", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:snow", + }) + + --Mushrooms in caves + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:material_stone"}, + sidelen = 80, + fill_ratio = 0.009, + noise_threshold = 2.0, + flags = "all_floors", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_mushrooms:mushroom_red", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:material_stone"}, + sidelen = 80, + fill_ratio = 0.009, + noise_threshold = 2.0, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_mushrooms:mushroom_brown", + }) + -- Mossy cobblestone boulder (3×3) minetest.register_decoration({ deco_type = "schematic", @@ -2913,8 +4623,9 @@ local function register_decorations() biomes = {"MegaTaiga", "MegaSpruceTaiga"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_boulder.mts", + schematic = mod_mcl_structures .. "/schematics/mcl_structures_boulder.mts", flags = "place_center_x, place_center_z", + rotation = "random", }) -- Small mossy cobblestone boulder (2×2) @@ -2933,8 +4644,9 @@ local function register_decorations() biomes = {"MegaTaiga", "MegaSpruceTaiga"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_boulder_small.mts", + schematic = mod_mcl_structures .. "/schematics/mcl_structures_boulder_small.mts", flags = "place_center_x, place_center_z", + rotation = "random", }) -- Cacti @@ -2954,9 +4666,9 @@ local function register_decorations() y_max = mcl_vars.mg_overworld_max, decoration = "mcl_core:cactus", biomes = {"Desert", - "Mesa","Mesa_sandlevel", - "MesaPlateauF","MesaPlateauF_sandlevel", - "MesaPlateauFM","MesaPlateauFM_sandlevel"}, + "Mesa", "Mesa_sandlevel", + "MesaPlateauF", "MesaPlateauF_sandlevel", + "MesaPlateauFM", "MesaPlateauFM_sandlevel"}, height = 1, height_max = 3, }) @@ -2979,7 +4691,7 @@ local function register_decorations() decoration = "mcl_core:reeds", height = 1, height_max = 3, - spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, + spawn_by = {"mcl_core:water_source", "group:frosted_ice"}, num_spawn_by = 1, }) minetest.register_decoration({ @@ -3000,23 +4712,23 @@ local function register_decorations() decoration = "mcl_core:reeds", height = 1, height_max = 3, - spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, + spawn_by = {"mcl_core:water_source", "group:frosted_ice"}, num_spawn_by = 1, }) -- Doubletall grass - local register_doubletall_grass = function(offset, scale, biomes) + local function register_doubletall_grass(offset, scale, biomes) - for b=1, #biomes do - local param2 = minetest.registered_biomes[biomes[b]]._mcl_palette_index + for b = 1, #biomes do + local param2 = minetest.registered_biomes[biomes[b]]._mcl_grass_palette_index minetest.register_decoration({ deco_type = "schematic", schematic = { - size = { x=1, y=3, z=1 }, + size = {x = 1, y = 3, z = 1}, data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_grass", param1=255, param2=param2 }, - { name = "mcl_flowers:double_grass_top", param1=255, param2=param2 }, + {name = "air", prob = 0}, + {name = "mcl_flowers:double_grass", param1 = 255, param2 = param2}, + {name = "mcl_flowers:double_grass_top", param1 = 255, param2 = param2}, }, }, place_on = {"group:grass_block_no_snow"}, @@ -3031,7 +4743,7 @@ local function register_decorations() }, y_min = 1, y_max = mcl_vars.mg_overworld_max, - biomes = { biomes[b] }, + biomes = {biomes[b]}, }) end end @@ -3041,17 +4753,17 @@ local function register_decorations() register_doubletall_grass(-0.0005, -0.03, {"Savanna", "SavannaM"}) -- Large ferns - local register_double_fern = function(offset, scale, biomes) - for b=1, #biomes do - local param2 = minetest.registered_biomes[biomes[b]]._mcl_palette_index + local function register_double_fern(offset, scale, biomes) + for b = 1, #biomes do + local param2 = minetest.registered_biomes[biomes[b]]._mcl_grass_palette_index minetest.register_decoration({ deco_type = "schematic", schematic = { - size = { x=1, y=3, z=1 }, + size = {x = 1, y = 3, z = 1}, data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_fern", param1=255, param2=param2 }, - { name = "mcl_flowers:double_fern_top", param1=255, param2=param2 }, + {name = "air", prob = 0}, + {name = "mcl_flowers:double_fern", param1 = 255, param2 = param2}, + {name = "mcl_flowers:double_fern_top", param1 = 255, param2 = param2}, }, }, place_on = {"group:grass_block_no_snow", "mcl_core:podzol"}, @@ -3071,35 +4783,35 @@ local function register_decorations() end end - register_double_fern(0.01, 0.03, { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "ColdTaiga", "MegaTaiga", "MegaSpruceTaiga" }) - register_double_fern(0.15, 0.1, { "JungleM" }) + register_double_fern(0.01, 0.03, {"Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "ColdTaiga", "MegaTaiga", "MegaSpruceTaiga", "BambooJungle", "BambooJungleM", "BambooJungleEdge", "BambooJungleEdgeM", }) + register_double_fern(0.15, 0.1, {"JungleM", "BambooJungleM", "BambooJungle"}) -- Large flowers - local register_large_flower = function(name, biomes, seed, offset, flower_forest_offset) + local function register_large_flower(name, biomes, seed, offset, flower_forest_offset) local maxi if flower_forest_offset then maxi = 2 else maxi = 1 end - for i=1, maxi do + for i = 1, maxi do local o, b -- offset, biomes if i == 1 then o = offset b = biomes else o = flower_forest_offset - b = { "FlowerForest" } + b = {"FlowerForest"} end minetest.register_decoration({ deco_type = "schematic", schematic = { - size = { x=1, y=3, z=1 }, + size = {x = 1, y = 3, z = 1}, data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:"..name, param1=255, }, - { name = "mcl_flowers:"..name.."_top", param1=255, }, + {name = "air", prob = 0}, + {name = "mcl_flowers:" .. name, param1 = 255, }, + {name = "mcl_flowers:" .. name .. "_top", param1 = 255, }, }, }, place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, @@ -3134,7 +4846,7 @@ local function register_decorations() sidelen = 80, noise_params = { offset = 0.0196, - scale = 0.025, + scale = 0.015, spread = {x = 250, y = 250, z = 250}, seed = 2930, octaves = 4, @@ -3143,7 +4855,25 @@ local function register_decorations() biomes = {"Jungle"}, y_min = 3, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_bush_oak_leaves.mts", + flags = "place_center_x, place_center_z", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, + sidelen = 80, + noise_params = { + offset = 0.0196, + scale = 0.005, + spread = {x = 250, y = 250, z = 250}, + seed = 2930, + octaves = 4, + persist = 0.6, + }, + biomes = {"Jungle", }, + y_min = 3, + y_max = mcl_vars.mg_overworld_max, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_bush_oak_leaves_2.mts", flags = "place_center_x, place_center_z", }) minetest.register_decoration({ @@ -3158,10 +4888,10 @@ local function register_decorations() octaves = 4, persist = 0.6, }, - biomes = {"JungleM"}, + biomes = {"JungleM","BambooJungleM"}, y_min = 1, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_bush_oak_leaves.mts", flags = "place_center_x, place_center_z", }) minetest.register_decoration({ @@ -3176,13 +4906,68 @@ local function register_decorations() octaves = 4, persist = 0.6, }, - biomes = {"JungleEdge", "JungleEdgeM"}, + biomes = {"JungleEdge", "JungleEdgeM", "BambooJungleEdgeM"}, y_min = 3, y_max = mcl_vars.mg_overworld_max, - schematic = jungle_bush_schematic, + schematic = mod_mcl_core .. "/schematics/mcl_core_jungle_bush_oak_leaves.mts", flags = "place_center_x, place_center_z", }) + -- Bamboo + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt", }, + sidelen = 80, + fill_ratio = 0.0043, + biomes = {"Jungle", "JungleM", "JungleEdge", "JungleEdgeM"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_bamboo:bamboo", + height = 9, + max_height = 11, + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol"}, + sidelen = 80, + fill_ratio = 0.095, + biomes = {"BambooJungle", "BambooJungleM", "BambooJungleEdge", "BambooJungleEdgeM"}, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_bamboo:bamboo", + height = 9, + max_height = 10, + flags = "place_center_x, place_center_z", + rotation = "random", + }) + + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.012, + spread = {x = 100, y = 100, z = 100}, + seed = 354, + octaves = 1, + persist = 0.5, + lacunarity = 1.0, + flags = "absvalue" + }, + biomes = {"BambooJungle", "BambooJungleEdge","BambooJungleM", "BambooJungleEdge"}, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + decoration = "mcl_flowers:tallgrass" + }) + + register_doubletall_grass(-0.0005, -0.3, {"BambooJungle", "BambooJungleM", "BambooJungleEdge"}) + register_grass_decoration("tallgrass", -0.03, 1, {"BambooJungle", "BambooJungleM", "BambooJungleEdge"}) + + ----------------- -- Fallen logs -- These fallen logs are not really good yet. They must be longer and also have one upright block. -- Note the decortion API does not like wide schematics, they are likely to overhang. @@ -3265,7 +5050,7 @@ local function register_decorations() octaves = 3, persist = 0.66 }, - biomes = {"BirchForest", "BirchForestM",}, + biomes = {"BirchForest", "BirchForestM", }, y_min = 1, y_max = mcl_vars.mg_overworld_max, schematic = { @@ -3349,23 +5134,23 @@ local function register_decorations() -- Lily pad local lily_schem = { - { name = "mcl_core:water_source" }, - { name = "mcl_flowers:waterlily" }, + {name = "mcl_core:water_source"}, + {name = "mcl_flowers:waterlily"}, } -- Spawn them in shallow water at ocean level in Swampland. -- Tweak lilydepth to change the maximum water depth local lilydepth = 2 - for d=1, lilydepth do + for d = 1, lilydepth do local height = d + 2 local y = 1 - d - table.insert(lily_schem, 1, { name = "air", prob = 0 }) + table.insert(lily_schem, 1, {name = "air", prob = 0}) minetest.register_decoration({ deco_type = "schematic", schematic = { - size = { x=1, y=height, z=1 }, + size = {x = 1, y = height, z = 1}, data = lily_schem, }, place_on = "mcl_core:dirt", @@ -3380,7 +5165,7 @@ local function register_decorations() }, y_min = y, y_max = y, - biomes = { "Swampland_shore" }, + biomes = {"Swampland_shore"}, rotation = "random", }) end @@ -3401,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"}, }) minetest.register_decoration({ deco_type = "simple", @@ -3418,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"}, }) minetest.register_decoration({ deco_type = "simple", @@ -3435,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"}, }) -- Lots of melons in Jungle Edge M @@ -3454,13 +5239,13 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = "mcl_farming:melon", - biomes = { "JungleEdgeM" }, + biomes = {"JungleEdgeM"}, }) -- Pumpkin minetest.register_decoration({ deco_type = "simple", - decoration = "mcl_farming:pumpkin_face", + decoration = "mcl_farming:pumpkin", param2 = 0, param2_max = 3, place_on = {"group:grass_block_no_snow"}, @@ -3480,16 +5265,16 @@ local function register_decorations() -- Grasses and ferns local grass_forest = {"Plains", "Taiga", "Forest", "FlowerForest", "BirchForest", "BirchForestM", "RoofedForest", "Swampland", } local grass_mpf = {"MesaPlateauF_grasstop"} - local grass_plains = {"Plains", "SunflowerPlains", "JungleEdge", "JungleEdgeM" } + local grass_plains = {"Plains", "SunflowerPlains", "JungleEdge", "JungleEdgeM", "MangroveSwamp"} local grass_savanna = {"Savanna", "SavannaM"} - local grass_sparse = {"ExtremeHills", "ExtremeHills+", "ExtremeHills+_snowtop", "ExtremeHillsM", "Jungle" } - local grass_mpfm = {"MesaPlateauFM_grasstop" } + local grass_sparse = {"ExtremeHills", "ExtremeHills+", "ExtremeHills+_snowtop", "ExtremeHillsM", "Jungle"} + local grass_mpfm = {"MesaPlateauFM_grasstop"} - register_grass_decoration("tallgrass", -0.03, 0.09, grass_forest) + register_grass_decoration("tallgrass", -0.03, 0.09, grass_forest) register_grass_decoration("tallgrass", -0.015, 0.075, grass_forest) - register_grass_decoration("tallgrass", 0, 0.06, grass_forest) - register_grass_decoration("tallgrass", 0.015, 0.045, grass_forest) - register_grass_decoration("tallgrass", 0.03, 0.03, grass_forest) + register_grass_decoration("tallgrass", 0, 0.06, grass_forest) + register_grass_decoration("tallgrass", 0.015, 0.045, grass_forest) + register_grass_decoration("tallgrass", 0.03, 0.03, grass_forest) register_grass_decoration("tallgrass", -0.03, 0.09, grass_mpf) register_grass_decoration("tallgrass", -0.015, 0.075, grass_mpf) register_grass_decoration("tallgrass", 0, 0.06, grass_mpf) @@ -3503,33 +5288,34 @@ local function register_decorations() register_grass_decoration("tallgrass", 0.05, -0.03, grass_sparse) register_grass_decoration("tallgrass", 0.05, 0.05, grass_mpfm) - local fern_minimal = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga", "ColdTaiga" } - local fern_low = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga" } - local fern_Jungle = { "Jungle", "JungleM", "JungleEdge", "JungleEdgeM" } - local fern_JungleM = { "JungleM" }, - register_grass_decoration("fern", -0.03, 0.09, fern_minimal) + local fern_minimal = {"Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga", "ColdTaiga", "MangroveSwamp"} + local fern_low = {"Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Taiga", "MegaTaiga", "MegaSpruceTaiga"} + local fern_Jungle = {"Jungle", "JungleM", "JungleEdge", "JungleEdgeM"} + --local fern_JungleM = { "JungleM" }, + + register_grass_decoration("fern", -0.03, 0.09, fern_minimal) register_grass_decoration("fern", -0.015, 0.075, fern_minimal) - register_grass_decoration("fern", 0, 0.06, fern_minimal) - register_grass_decoration("fern", 0.015, 0.045, fern_low) - register_grass_decoration("fern", 0.03, 0.03, fern_low) + register_grass_decoration("fern", 0, 0.06, fern_minimal) + register_grass_decoration("fern", 0.015, 0.045, fern_low) + register_grass_decoration("fern", 0.03, 0.03, fern_low) register_grass_decoration("fern", 0.01, 0.05, fern_Jungle) register_grass_decoration("fern", 0.03, 0.03, fern_Jungle) register_grass_decoration("fern", 0.05, 0.01, fern_Jungle) register_grass_decoration("fern", 0.07, -0.01, fern_Jungle) register_grass_decoration("fern", 0.09, -0.03, fern_Jungle) - register_grass_decoration("fern", 0.12, -0.03, fern_JungleM) + register_grass_decoration("fern", 0.12, -0.03, {"JungleM"}) - local b_seagrass = {"ColdTaiga_ocean","ExtremeHills_ocean","ExtremeHillsM_ocean","ExtremeHills+_ocean","Taiga_ocean","MegaTaiga_ocean","MegaSpruceTaiga_ocean","StoneBeach_ocean","Plains_ocean","SunflowerPlains_ocean","Forest_ocean","FlowerForest_ocean","BirchForest_ocean","BirchForestM_ocean","RoofedForest_ocean","Swampland_ocean","Jungle_ocean","JungleM_ocean","JungleEdge_ocean","JungleEdgeM_ocean","MushroomIsland_ocean","Desert_ocean","Savanna_ocean","SavannaM_ocean","Mesa_ocean","MesaBryce_ocean","MesaPlateauF_ocean","MesaPlateauFM_ocean", -"ColdTaiga_deep_ocean","ExtremeHills_deep_ocean","ExtremeHillsM_deep_ocean","ExtremeHills+_deep_ocean","Taiga_deep_ocean","MegaTaiga_deep_ocean","MegaSpruceTaiga_deep_ocean","StoneBeach_deep_ocean","Plains_deep_ocean","SunflowerPlains_deep_ocean","Forest_deep_ocean","FlowerForest_deep_ocean","BirchForest_deep_ocean","BirchForestM_deep_ocean","RoofedForest_deep_ocean","Swampland_deep_ocean","Jungle_deep_ocean","JungleM_deep_ocean","JungleEdge_deep_ocean","JungleEdgeM_deep_ocean","MushroomIsland_deep_ocean","Desert_deep_ocean","Savanna_deep_ocean","SavannaM_deep_ocean","Mesa_deep_ocean","MesaBryce_deep_ocean","MesaPlateauF_deep_ocean","MesaPlateauFM_deep_ocean", -"Mesa_sandlevel","MesaBryce_sandlevel","MesaPlateauF_sandlevel","MesaPlateauFM_sandlevel","Swampland_shore","Jungle_shore","JungleM_shore","Savanna_beach","FlowerForest_beach","ColdTaiga_beach_water","ExtremeHills_beach"} - local b_kelp = {"ExtremeHillsM_ocean","ExtremeHills+_ocean","MegaTaiga_ocean","MegaSpruceTaiga_ocean","Plains_ocean","SunflowerPlains_ocean","Forest_ocean","FlowerForest_ocean","BirchForest_ocean","BirchForestM_ocean","RoofedForest_ocean","Swampland_ocean","Jungle_ocean","JungleM_ocean","JungleEdge_ocean","JungleEdgeM_ocean","MushroomIsland_ocean", -"ExtremeHillsM_deep_ocean","ExtremeHills+_deep_ocean","MegaTaiga_deep_ocean","MegaSpruceTaiga_deep_ocean","Plains_deep_ocean","SunflowerPlains_deep_ocean","Forest_deep_ocean","FlowerForest_deep_ocean","BirchForest_deep_ocean","BirchForestM_deep_ocean","RoofedForest_deep_ocean","Swampland_deep_ocean","Jungle_deep_ocean","JungleM_deep_ocean","JungleEdge_deep_ocean","JungleEdgeM_deep_ocean","MushroomIsland_deep_ocean" -} + local b_seagrass = {"ColdTaiga_ocean", "ExtremeHills_ocean", "ExtremeHillsM_ocean", "ExtremeHills+_ocean", "Taiga_ocean", "MegaTaiga_ocean", "MegaSpruceTaiga_ocean", "StoneBeach_ocean", "Plains_ocean", "SunflowerPlains_ocean", "Forest_ocean", "FlowerForest_ocean", "BirchForest_ocean", "BirchForestM_ocean", "RoofedForest_ocean", "Swampland_ocean", "Jungle_ocean", "JungleM_ocean", "JungleEdge_ocean", "JungleEdgeM_ocean", "MushroomIsland_ocean", "Desert_ocean", "Savanna_ocean", "SavannaM_ocean", "Mesa_ocean", "MesaBryce_ocean", "MesaPlateauF_ocean", "MesaPlateauFM_ocean", + "ColdTaiga_deep_ocean", "ExtremeHills_deep_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHills+_deep_ocean", "Taiga_deep_ocean", "MegaTaiga_deep_ocean", "MegaSpruceTaiga_deep_ocean", "StoneBeach_deep_ocean", "Plains_deep_ocean", "SunflowerPlains_deep_ocean", "Forest_deep_ocean", "FlowerForest_deep_ocean", "BirchForest_deep_ocean", "BirchForestM_deep_ocean", "RoofedForest_deep_ocean", "Swampland_deep_ocean", "Jungle_deep_ocean", "JungleM_deep_ocean", "JungleEdge_deep_ocean", "JungleEdgeM_deep_ocean", "MushroomIsland_deep_ocean", "Desert_deep_ocean", "Savanna_deep_ocean", "SavannaM_deep_ocean", "Mesa_deep_ocean", "MesaBryce_deep_ocean", "MesaPlateauF_deep_ocean", "MesaPlateauFM_deep_ocean", + "Mesa_sandlevel", "MesaBryce_sandlevel", "MesaPlateauF_sandlevel", "MesaPlateauFM_sandlevel", "Swampland_shore", "Jungle_shore", "JungleM_shore", "Savanna_beach", "FlowerForest_beach", "ColdTaiga_beach_water", "ExtremeHills_beach"} + local b_kelp = {"ExtremeHillsM_ocean", "ExtremeHills+_ocean", "MegaTaiga_ocean", "MegaSpruceTaiga_ocean", "Plains_ocean", "SunflowerPlains_ocean", "Forest_ocean", "FlowerForest_ocean", "BirchForest_ocean", "BirchForestM_ocean", "RoofedForest_ocean", "Swampland_ocean", "Jungle_ocean", "JungleM_ocean", "JungleEdge_ocean", "JungleEdgeM_ocean", "MushroomIsland_ocean", + "ExtremeHillsM_deep_ocean", "ExtremeHills+_deep_ocean", "MegaTaiga_deep_ocean", "MegaSpruceTaiga_deep_ocean", "Plains_deep_ocean", "SunflowerPlains_deep_ocean", "Forest_deep_ocean", "FlowerForest_deep_ocean", "BirchForest_deep_ocean", "BirchForestM_deep_ocean", "RoofedForest_deep_ocean", "Swampland_deep_ocean", "Jungle_deep_ocean", "JungleM_deep_ocean", "JungleEdge_deep_ocean", "JungleEdgeM_deep_ocean", "MushroomIsland_deep_ocean" + } register_seagrass_decoration("seagrass", 0, 0.5, b_seagrass) register_seagrass_decoration("kelp", -0.5, 1, b_kelp) - local b_sponge = {"Plains_deep_ocean","SunflowerPlains_deep_ocean","Forest_deep_ocean","FlowerForest_deep_ocean","BirchForest_deep_ocean","BirchForestM_deep_ocean","RoofedForest_deep_ocean","Jungle_deep_ocean","JungleM_deep_ocean","JungleEdge_deep_ocean","JungleEdgeM_deep_ocean","MushroomIsland_deep_ocean","Desert_deep_ocean","Savanna_deep_ocean","SavannaM_deep_ocean","Mesa_deep_ocean","MesaBryce_deep_ocean","MesaPlateauF_deep_ocean","MesaPlateauFM_deep_ocean"} + local b_sponge = {"Plains_deep_ocean", "SunflowerPlains_deep_ocean", "Forest_deep_ocean", "FlowerForest_deep_ocean", "BirchForest_deep_ocean", "BirchForestM_deep_ocean", "RoofedForest_deep_ocean", "Jungle_deep_ocean", "JungleM_deep_ocean", "JungleEdge_deep_ocean", "JungleEdgeM_deep_ocean", "MushroomIsland_deep_ocean", "Desert_deep_ocean", "Savanna_deep_ocean", "SavannaM_deep_ocean", "Mesa_deep_ocean", "MesaBryce_deep_ocean", "MesaPlateauF_deep_ocean", "MesaPlateauFM_deep_ocean"} -- Wet Sponge -- TODO: Remove this when we got ocean monuments minetest.register_decoration({ @@ -3538,7 +5324,7 @@ local function register_decorations() biomes = b_sponge, spawn_by = {"group:water"}, num_spawn_by = 1, - place_on = {"mcl_core:dirt","mcl_core:sand","mcl_core:gravel"}, + place_on = {"mcl_core:dirt", "mcl_core:sand", "mcl_core:gravel"}, sidelen = 16, noise_params = { offset = 0.00495, @@ -3570,10 +5356,10 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, schematic = { - size = { x=1, y=2, z=1 }, + size = {x = 1, y = 2, z = 1}, data = { - { name = "mcl_core:dirt_with_grass", force_place=true, }, - { name = "mcl_flowers:tallgrass", param2 = minetest.registered_biomes["IcePlains"]._mcl_palette_index }, + {name = "mcl_core:dirt_with_grass", force_place = true, }, + {name = "mcl_flowers:tallgrass", param2 = minetest.registered_biomes["IcePlains"]._mcl_grass_palette_index}, }, }, }) @@ -3593,10 +5379,10 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, schematic = { - size = { x=1, y=2, z=1 }, + size = {x = 1, y = 2, z = 1}, data = { - { name = "mcl_core:dirt_with_grass", force_place=true, }, - { name = "mcl_flowers:tallgrass", param2 = minetest.registered_biomes["ExtremeHills+_snowtop"]._mcl_palette_index }, + {name = "mcl_core:dirt_with_grass", force_place = true, }, + {name = "mcl_flowers:tallgrass", param2 = minetest.registered_biomes["ExtremeHills+_snowtop"]._mcl_grass_palette_index}, }, }, }) @@ -3605,11 +5391,11 @@ local function register_decorations() -- Dead bushes minetest.register_decoration({ deco_type = "simple", - place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:dirt_with_grass", "mcl_core:coarse_dirt", "group:hardened_clay"}, + place_on = {"mcl_core:podzol", "mcl_core:dirt", "mcl_core:dirt_with_grass", "mcl_core:coarse_dirt", "group:hardened_clay"}, sidelen = 16, noise_params = { - offset = 0.0, - scale = 0.035, + offset = 0.01, + scale = 0.003, spread = {x = 100, y = 100, z = 100}, seed = 1972, octaves = 3, @@ -3617,7 +5403,43 @@ local function register_decorations() }, y_min = 4, y_max = mcl_vars.mg_overworld_max, - biomes = {"Desert", "Mesa", "Mesa_sandlevel", "MesaPlateauF", "MesaPlateauF_sandlevel", "MesaPlateauF_grasstop","MesaBryce","Taiga", "MegaTaiga"}, + biomes = {"MegaSpruceTaiga", "MegaTaiga"}, + decoration = "mcl_core:deadbush", + height = 1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "group:hardened_clay"}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.006, + spread = {x = 100, y = 100, z = 100}, + seed = 1972, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + biomes = {"Desert"}, + decoration = "mcl_core:deadbush", + height = 1, + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:dirt_with_grass", "mcl_core:coarse_dirt", "group:hardened_clay"}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.06, + spread = {x = 100, y = 100, z = 100}, + seed = 1972, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + biomes = {"Mesa", "Mesa_sandlevel", "MesaPlateauF", "MesaPlateauF_sandlevel", "MesaPlateauF_grasstop", "MesaBryce"}, decoration = "mcl_core:deadbush", height = 1, }) @@ -3626,8 +5448,8 @@ local function register_decorations() place_on = {"group:sand", "mcl_core:dirt", "mcl_core:dirt_with_grass", "mcl_core:coarse_dirt"}, sidelen = 16, noise_params = { - offset = 0.1, - scale = 0.035, + offset = 0.01, + scale = 0.06, spread = {x = 100, y = 100, z = 100}, seed = 1972, octaves = 3, @@ -3644,8 +5466,8 @@ local function register_decorations() place_on = {"group:sand"}, sidelen = 16, noise_params = { - offset = 0.045, - scale = 0.055, + offset = 0.01, + scale = 0.06, spread = {x = 100, y = 100, z = 100}, seed = 1972, octaves = 3, @@ -3653,7 +5475,7 @@ local function register_decorations() }, y_min = 4, y_max = mcl_vars.mg_overworld_max, - biomes = {"MesaPlateauFM","MesaPlateauFM_sandlevel"}, + biomes = {"MesaPlateauFM", "MesaPlateauFM_sandlevel"}, decoration = "mcl_core:deadbush", height = 1, }) @@ -3662,8 +5484,8 @@ local function register_decorations() place_on = {"group:hardened_clay"}, sidelen = 16, noise_params = { - offset = 0.010, - scale = 0.035, + offset = 0.01, + scale = 0.06, spread = {x = 100, y = 100, z = 100}, seed = 1972, octaves = 3, @@ -3724,8 +5546,8 @@ local function register_decorations() -- Mushrooms next to trees local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} - local mseeds = { 7133, 8244 } - for m=1, #mushrooms do + local mseeds = {7133, 8244} + for m = 1, #mushrooms do -- Mushrooms next to trees minetest.register_decoration({ deco_type = "simple", @@ -3742,7 +5564,7 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = mushrooms[m], - spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree" }, + spawn_by = {"mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree"}, num_spawn_by = 1, }) @@ -3762,8 +5584,8 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, decoration = mushrooms[m], - biomes = { "Swampland"}, - spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree" }, + biomes = {"Swampland"}, + spawn_by = {"mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree"}, num_spawn_by = 1, }) end @@ -3787,7 +5609,7 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, biomes = biomes, - decoration = "mcl_flowers:"..name, + decoration = "mcl_flowers:" .. name, }) end if is_in_flower_forest then @@ -3795,8 +5617,8 @@ local function register_decorations() deco_type = "simple", place_on = {"group:grass_block_no_snow", "mcl_core:dirt"}, sidelen = 80, - noise_params= { - offset = 0.0008*40, + noise_params = { + offset = 0.0008 * 40, scale = 0.003, spread = {x = 100, y = 100, z = 100}, seed = seed, @@ -3806,12 +5628,12 @@ local function register_decorations() y_min = 1, y_max = mcl_vars.mg_overworld_max, biomes = {"FlowerForest"}, - decoration = "mcl_flowers:"..name, + decoration = "mcl_flowers:" .. name, }) end end - local flower_biomes1 = {"Plains", "SunflowerPlains", "RoofedForest", "Forest", "BirchForest", "BirchForestM", "Taiga", "ColdTaiga", "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Savanna", "SavannaM", "ExtremeHills", "ExtremeHillsM", "ExtremeHills+", "ExtremeHills+_snowtop" } + local flower_biomes1 = {"Plains", "SunflowerPlains", "RoofedForest", "Forest", "BirchForest", "BirchForestM", "Taiga", "ColdTaiga", "Jungle", "JungleM", "JungleEdge", "JungleEdgeM", "Savanna", "SavannaM", "ExtremeHills", "ExtremeHillsM", "ExtremeHills+", "ExtremeHills+_snowtop"} register_flower("dandelion", flower_biomes1, 8) register_flower("poppy", flower_biomes1, 9439) @@ -3827,20 +5649,362 @@ local function register_decorations() register_flower("allium", nil, 0) -- flower Forest only register_flower("blue_orchid", {"Swampland"}, 64500, false) + register_flower("lily_of_the_valley", nil, 325) + register_flower("cornflower", flower_biomes2, 486) end -- Decorations in non-Overworld dimensions local function register_dimension_decorations() --[[ NETHER ]] - -- TODO: Nether + --NETHER WASTES (Nether) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack", "mcl_nether:magma"}, + sidelen = 16, + fill_ratio = 0.04, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_fire:eternal_fire", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.013, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_mushrooms:mushroom_brown", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.012, + biomes = {"Nether"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 1, + flags = "all_floors", + decoration = "mcl_mushrooms:mushroom_red", + }) + + -- WARPED FOREST + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.02, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors", + decoration = "mcl_crimson:warped_fungus", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree1", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.007, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 15, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/warped_fungus_1.mts", + size = {x = 5, y = 11, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree2", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.005, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/warped_fungus_2.mts", + size = {x = 5, y = 6, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:warped_tree3", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.003, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 14, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/warped_fungus_3.mts", + size = {x = 5, y = 12, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium", "mcl_crimson:twisting_vines"}, + sidelen = 16, + fill_ratio = 0.032, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + height = 2, + height_max = 8, + decoration = "mcl_crimson:twisting_vines", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium"}, + sidelen = 16, + fill_ratio = 0.0812, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_crimson:warped_roots", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.052, + biomes = {"WarpedForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + decoration = "mcl_crimson:nether_sprouts", + }) + -- CRIMSON FOREST + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.02, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors", + decoration = "mcl_crimson:crimson_fungus", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.008, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 10, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/crimson_fungus_1.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree2", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.006, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 15, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/crimson_fungus_2.mts", + size = {x = 5, y = 12, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + name = "mcl_biomes:crimson_tree3", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.004, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 20, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_crimson .. "/schematics/crimson_fungus_3.mts", + size = {x = 7, y = 13, z = 7}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:warped_nylium", "mcl_crimson:weeping_vines", "mcl_nether:netherrack"}, + sidelen = 16, + fill_ratio = 0.063, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max, + flags = "all_ceilings", + height = 2, + height_max = 8, + decoration = "mcl_crimson:weeping_vines", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_crimson:crimson_nylium"}, + sidelen = 16, + fill_ratio = 0.082, + biomes = {"CrimsonForest"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_crimson:crimson_roots", + }) + + --SOULSAND VALLEY + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_blackstone:soul_soil", "mcl_nether:soul_sand"}, + sidelen = 16, + fill_ratio = 0.062, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors", + max_height = 5, + decoration = "mcl_blackstone:soul_fire", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil", "mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.000212, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone .. "/schematics/mcl_blackstone_nether_fossil_1.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil", "mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.0002233, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone .. "/schematics/mcl_blackstone_nether_fossil_2.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil", "mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.000225, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone .. "/schematics/mcl_blackstone_nether_fossil_3.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + minetest.register_decoration({ + deco_type = "schematic", + place_on = {"mcl_blackstone:soul_soil", "mcl_nether:soulsand"}, + sidelen = 16, + fill_ratio = 0.00022323, + biomes = {"SoulsandValley"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, place_center_x, place_center_z", + schematic = mod_mcl_blackstone .. "/schematics/mcl_blackstone_nether_fossil_4.mts", + size = {x = 5, y = 8, z = 5}, + rotation = "random", + }) + --BASALT DELTA + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt", "mcl_nether:netherrack", "mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 55, + noise_params = { + offset = -0.0085, + scale = 0.002, + spread = {x = 25, y = 120, z = 25}, + seed = 2325, + octaves = 5, + persist = 2, + lacunarity = 3.5, + flags = "absvalue" + }, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 50, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt", "mcl_nether:netherrack", "mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 15, + noise_params = { + offset = -0.0085, + scale = 0.004, + spread = {x = 25, y = 120, z = 25}, + seed = 235, + octaves = 5, + persist = 2.5, + lacunarity = 3.5, + flags = "absvalue" + }, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 15, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_blackstone:basalt", + place_on = {"mcl_blackstone:basalt", "mcl_nether:netherrack", "mcl_blackstone:blackstone"}, + sidelen = 80, + height_max = 3, + fill_ratio = 0.4, + biomes = {"BasaltDelta"}, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_deco_max - 15, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_nether:magma", + place_on = {"mcl_blackstone:basalt", "mcl_nether:netherrack", "mcl_blackstone:blackstone"}, + sidelen = 80, + fill_ratio = 0.082323, + biomes = {"BasaltDelta"}, + place_offset_y = -1, + y_min = mcl_vars.mg_lava_nether_max + 1, + flags = "all_floors, all ceilings", + }) + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_nether:nether_lava_source", + place_on = {"mcl_blackstone:basalt", "mcl_nether:netherrack", "mcl_blackstone:blackstone"}, + spawn_by = {"mcl_blackstone:basalt", "mcl_blackstone:blackstone"}, + num_spawn_by = 14, + sidelen = 80, + fill_ratio = 4, + biomes = {"BasaltDelta"}, + place_offset_y = -1, + y_min = mcl_vars.mg_lava_nether_max + 1, + y_max = mcl_vars.mg_nether_max - 5, + flags = "all_floors, force_placement", + }) --[[ THE END ]] -- Chorus plant minetest.register_decoration({ - name = "mcl_biomes:chorus_plant", + name = "mcl_biomes:chorus", deco_type = "simple", - place_on = {"mcl_end:end_stone", "air"}, + place_on = {"mcl_end:end_stone"}, flags = "all_floors", sidelen = 16, noise_params = { @@ -3853,19 +6017,42 @@ local function register_dimension_decorations() }, y_min = mcl_vars.mg_end_min, y_max = mcl_vars.mg_end_max, + decoration = "mcl_end:chorus_plant", + height = 1, + height_max = 8, + biomes = {"End", "EndMidlands", "EndHighlands", "EndBarrens", "EndSmallIslands"}, + }) + minetest.register_decoration({ + name = "mcl_biomes:chorus_plant", + deco_type = "simple", + place_on = {"mcl_end:chorus_plant"}, + flags = "all_floors", + sidelen = 16, + fill_ratio = 10, + --[[noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 257, + octaves = 3, + persist = 0.6 + },--]] + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, decoration = "mcl_end:chorus_flower", height = 1, - biomes = { "End" }, + biomes = {"End", "EndMidlands", "EndHighlands", "EndBarrens", "EndSmallIslands"}, }) deco_id_chorus_plant = minetest.get_decoration_id("mcl_biomes:chorus_plant") - minetest.set_gen_notify({decoration=true}, { deco_id_chorus_plant }) + minetest.set_gen_notify({decoration = true}, {deco_id_chorus_plant}) -- TODO: End cities end + -- -- Detect mapgen to select functions -- @@ -3896,16 +6083,103 @@ if mg_name ~= "singlenode" then -- Overworld decorations for v6 are handled in mcl_mapgen_core - if deco_id_chorus_plant then - minetest.register_on_generated(function(minp, maxp, blockseed) + local deco_ids_fungus = { + minetest.get_decoration_id("mcl_biomes:crimson_tree1"), + minetest.get_decoration_id("mcl_biomes:crimson_tree2"), + minetest.get_decoration_id("mcl_biomes:crimson_tree3"), + minetest.get_decoration_id("mcl_biomes:warped_tree1"), + minetest.get_decoration_id("mcl_biomes:warped_tree2"), + minetest.get_decoration_id("mcl_biomes:warped_tree3") + } + local deco_ids_trees = { + minetest.get_decoration_id("mcl_biomes:mangrove_tree_1"), + minetest.get_decoration_id("mcl_biomes:mangrove_tree_2"), + minetest.get_decoration_id("mcl_biomes:mangrove_tree_3"), + } + for _, f in pairs(deco_ids_fungus) do + minetest.set_gen_notify({decoration = true}, {f}) + end + for _, f in pairs(deco_ids_trees) do + minetest.set_gen_notify({decoration = true}, {f}) + end + + local function mangrove_roots_gen(gennotify, pr) + for _, f in pairs(deco_ids_trees) do + for _, pos in ipairs(gennotify["decoration#" .. f] or {}) do + local nn = minetest.find_nodes_in_area(vector.offset(pos, -8, -1, -8), vector.offset(pos, 8, 0, 8), {"mcl_mangrove:mangrove_roots"}) + for _, v in pairs(nn) do + local l = pr:next(2, 16) + local n = minetest.get_node(vector.offset(v, 0, -1, 0)).name + if minetest.get_item_group(n, "water") > 0 then + local wl = "mcl_mangrove:water_logged_roots" + if n:find("river") then + wl = "mcl_mangrove:river_water_logged_roots" + end + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v, 0, 0, 0), vector.offset(v, 0, -l, 0), {"group:water"}), {name = wl}) + elseif n == "mcl_mud:mud" then + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v, 0, 0, 0), vector.offset(v, 0, -l, 0), {"mcl_mud:mud"}), {name = "mcl_mangrove:mangrove_mud_roots"}) + elseif n == "air" then + minetest.bulk_set_node(minetest.find_nodes_in_area(vector.offset(v, 0, 0, 0), vector.offset(v, 0, -l, 0), {"air"}), {name = "mcl_mangrove:mangrove_roots"}) + end + end + end + end + end + + local function chorus_gen (gennotify, pr) + for _, pos in ipairs(gennotify["decoration#" .. deco_id_chorus_plant] or {}) do + local x, y, z = pos.x, pos.y, pos.z + if x < -10 or x > 10 or z < -10 or z > 10 then + local realpos = {x = x, y = y + 1, z = z} + local node = minetest.get_node(realpos) + if node and node.name == "mcl_end:chorus_flower" then + mcl_end.grow_chorus_plant(realpos, node, pr) + end + end + end + end + + local function crimson_warped_gen(gennotify) + for _, f in pairs(deco_ids_fungus) do + for _, pos in ipairs(gennotify["decoration#" .. f] or {}) do + minetest.fix_light(vector.offset(pos, -8, -8, -8), vector.offset(pos, 8, 8, 8)) + end + end + end + + if deco_id_chorus_plant or deco_ids_fungus or deco_ids_trees then + mcl_mapgen_core.register_generator("chorus_grow", nil, function(minp, maxp, blockseed) local gennotify = minetest.get_mapgen_object("gennotify") - local poslist = {} - for _, pos in ipairs(gennotify["decoration#"..deco_id_chorus_plant] or {}) do - local realpos = { x = pos.x, y = pos.y + 1, z = pos.z } - mcl_end.grow_chorus_plant(realpos) + local pr = PseudoRandom(blockseed + 14) + + if not (maxp.y < mcl_vars.mg_overworld_min or minp.y > mcl_vars.mg_overworld_max) then + local biomemap = minetest.get_mapgen_object("biomemap") + --minetest.log("mangrove stuff: " .. dump(biomemap)) + local swamp_biome_id = minetest.get_biome_id("MangroveSwamp") + local swamp_shore_id = minetest.get_biome_id("MangroveSwamp_shore") + local is_swamp = table.indexof(biomemap, swamp_biome_id) ~= -1 + local is_swamp_shore = table.indexof(biomemap, swamp_shore_id) ~= -1 + + if is_swamp or is_swamp_shore then + --minetest.log("Mangrove swamp biomes...") + --minetest.log("is_swamp: " .. dump(is_swamp)) + --minetest.log("is_swamp_shore: " .. dump(is_swamp_shore)) + mangrove_roots_gen(gennotify, pr) + else + --minetest.log("is not mangrove swamp biomes...") + end + end + + if not (maxp.y < mcl_vars.mg_end_min or minp.y > mcl_vars.mg_end_max) then + --minetest.log("chorus stuff") + chorus_gen(gennotify, pr) + end + + if not (maxp.y < mcl_vars.mg_nether_min or minp.y > mcl_vars.mg_nether_max) then + --minetest.log("nether stuff") + crimson_warped_gen(gennotify) end end) end end - diff --git a/mods/MAPGEN/mcl_biomes/mod.conf b/mods/MAPGEN/mcl_biomes/mod.conf new file mode 100644 index 000000000..6cce58bf4 --- /dev/null +++ b/mods/MAPGEN/mcl_biomes/mod.conf @@ -0,0 +1,4 @@ +name = mcl_biomes +author = maikerumine +description = Adds the various biomes and biome-related things for non-v6 map generators. +depends = mcl_init, mcl_mapgen_core, mcl_core, mcl_worlds, mcl_farming, mcl_flowers, mcl_end, mcl_ocean, mcl_crimson, mcl_blackstone, mcl_mangrove diff --git a/mods/MAPGEN/mcl_dungeons/depends.txt b/mods/MAPGEN/mcl_dungeons/depends.txt deleted file mode 100644 index 4c803c72d..000000000 --- a/mods/MAPGEN/mcl_dungeons/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_init -mcl_core -mcl_chests -mcl_mobs -mcl_mobspawners -mcl_mapgen_core -mobs_mc diff --git a/mods/MAPGEN/mcl_dungeons/description.txt b/mods/MAPGEN/mcl_dungeons/description.txt deleted file mode 100644 index 343cb7bdb..000000000 --- a/mods/MAPGEN/mcl_dungeons/description.txt +++ /dev/null @@ -1 +0,0 @@ -Generates random dungeons in the world diff --git a/mods/MAPGEN/mcl_dungeons/init.lua b/mods/MAPGEN/mcl_dungeons/init.lua index 1ce1556b2..c115c35c3 100644 --- a/mods/MAPGEN/mcl_dungeons/init.lua +++ b/mods/MAPGEN/mcl_dungeons/init.lua @@ -1,17 +1,70 @@ -- FIXME: Chests may appear at openings +mcl_dungeons = {} + local mg_name = minetest.get_mapgen_setting("mg_name") -local pr = PseudoRandom(os.time()) -- Are dungeons disabled? -if mcl_vars.mg_dungeons == false then +if mcl_vars.mg_dungeons == false or mg_name == "singlenode" then return end -if mg_name ~= "singlenode" then --- Get loot for dungeon chests -local get_loot = function() - local loottable = { +--lua locals +--minetest +local registered_nodes = minetest.registered_nodes +local swap_node = minetest.swap_node +local set_node = minetest.set_node +local dir_to_facedir = minetest.dir_to_facedir +local get_meta = minetest.get_meta +local emerge_area = minetest.emerge_area + +--vector +local vector_add = vector.add +local vector_subtract = vector.subtract + +--table +local table_insert = table.insert +local table_sort = table.sort + +--math +local math_min = math.min +local math_max = math.max +local math_ceil = math.ceil + +--custom mcl_vars +local get_node = mcl_vars.get_node + + +local min_y = math_max(mcl_vars.mg_overworld_min, mcl_vars.mg_bedrock_overworld_max) + 1 +local max_y = mcl_vars.mg_overworld_max - 1 +-- Calculate the number of dungeon spawn attempts +-- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). +-- Minetest chunks don't have this size, so scale the number accordingly. +local attempts = math_ceil(((mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE) ^ 3) / 8192) -- 63 = 80*80*80/8192 + +local dungeonsizes = { + { x=5, y=4, z=5}, + { x=5, y=4, z=7}, + { x=7, y=4, z=5}, + { x=7, y=4, z=7}, +} + +--[[local dirs = { + { x= 1, y=0, z= 0 }, + { x= 0, y=0, z= 1 }, + { x=-1, y=0, z= 0 }, + { x= 0, y=0, z=-1 }, +}]] + +local surround_vectors = { + { x=-1, y=0, z=0 }, + { x=1, y=0, z=0 }, + { x=0, y=0, z=-1 }, + { x=0, y=0, z=1 }, +} + +local loottable = +{ { stacks_min = 1, stacks_max = 3, @@ -20,11 +73,13 @@ local get_loot = function() { itemstring = "mcl_mobitems:saddle", weight = 20 }, { itemstring = "mcl_jukebox:record_1", weight = 15 }, { itemstring = "mcl_jukebox:record_4", weight = 15 }, - { itemstring = "mobs_mc:iron_horse_armor", weight = 15 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 15 }, { itemstring = "mcl_core:apple_gold", weight = 15 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 10 }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 10 }, - { itemstring = "mobs_mc:diamond_horse_armor", weight = 5 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 10 }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 5 }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 2 }, } }, @@ -34,6 +89,7 @@ local get_loot = function() items = { { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, { itemstring = "mcl_farming:bread", weight = 20 }, + { itemstring = "mcl_cherry_blossom:cherrysapling", weight = 15, amount_min = 1, amount_max = 4 }, -- FIXME: Remove when cherry blossom map generation is implemented. { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, { itemstring = "mesecons:redstone", weight = 15, amount_min = 1, amount_max = 4 }, { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, @@ -54,347 +110,318 @@ local get_loot = function() { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, }, } - } +} - -- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. - if mg_name == "v6" then - table.insert(loottable, { - stacks_min = 1, - stacks_max = 3, - items = { - { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, - { itemstring = "", weight = 6 }, - }, - }) - end - local items = mcl_loot.get_multi_loot(loottable, pr) - - return items +-- Bonus loot for v6 mapgen: Otherwise unobtainable saplings. +if mg_name == "v6" then + table.insert(loottable, { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_core:birchsapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_core:acaciasapling", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "", weight = 6 }, + }, + }) end +local function ecb_spawn_dungeon(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end --- Buffer for LuaVoxelManip -local lvm_buffer = {} + local p1, _, dim, pr = param.p1, param.p2, param.dim, param.pr + local x, y, z = p1.x, p1.y, p1.z + local check = not (param.dontcheck or false) --- Below the bedrock, generate air/void -minetest.register_on_generated(function(minp, maxp) - if maxp.y < mcl_vars.mg_overworld_min or minp.y > mcl_vars.mg_overworld_max then - return + -- Check floor and ceiling: Must be *completely* solid + local y_floor = y + local y_ceiling = y + dim.y + 1 + if check then + for tx = x+1, x+dim.x do + for tz = z+1, z+dim.z do + local fdef = registered_nodes[get_node({x = tx, y = y_floor , z = tz}).name] + local cdef = registered_nodes[get_node({x = tx, y = y_ceiling, z = tz}).name] + if not fdef or not fdef.walkable or not cdef or not cdef.walkable then return false end + end + end end - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data(lvm_buffer) - local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) - local lvm_used = false + -- Check for air openings (2 stacked air at ground level) in wall positions + local openings_counter = 0 + -- Store positions of openings; walls will not be generated here + local openings = {} + -- Corners are stored because a corner-only opening needs to be increased, + -- so entities can get through. + local corners = {} - local c_air = minetest.get_content_id("air") - local c_cobble = minetest.get_content_id("mcl_core:cobble") - local c_mossycobble = minetest.get_content_id("mcl_core:mossycobble") + local x2,z2 = x+dim.x+1, z+dim.z+1 + + if get_node({x=x, y=y+1, z=z}).name == "air" and get_node({x=x, y=y+2, z=z}).name == "air" then + openings_counter = openings_counter + 1 + if not openings[x] then openings[x]={} end + openings[x][z] = true + table_insert(corners, {x=x, z=z}) + end + if get_node({x=x2, y=y+1, z=z}).name == "air" and get_node({x=x2, y=y+2, z=z}).name == "air" then + openings_counter = openings_counter + 1 + if not openings[x2] then openings[x2]={} end + openings[x2][z] = true + table_insert(corners, {x=x2, z=z}) + end + if get_node({x=x, y=y+1, z=z2}).name == "air" and get_node({x=x, y=y+2, z=z2}).name == "air" then + openings_counter = openings_counter + 1 + if not openings[x] then openings[x]={} end + openings[x][z2] = true + table_insert(corners, {x=x, z=z2}) + end + if get_node({x=x2, y=y+1, z=z2}).name == "air" and get_node({x=x2, y=y+2, z=z2}).name == "air" then + openings_counter = openings_counter + 1 + if not openings[x2] then openings[x2]={} end + openings[x2][z2] = true + table_insert(corners, {x=x2, z=z2}) + end + + for wx = x+1, x+dim.x do + if get_node({x=wx, y=y+1, z=z}).name == "air" and get_node({x=wx, y=y+2, z=z}).name == "air" then + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[wx] then openings[wx]={} end + openings[wx][z] = true + end + if get_node({x=wx, y=y+1, z=z2}).name == "air" and get_node({x=wx, y=y+2, z=z2}).name == "air" then + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[wx] then openings[wx]={} end + openings[wx][z2] = true + end + end + for wz = z+1, z+dim.z do + if get_node({x=x, y=y+1, z=wz}).name == "air" and get_node({x=x, y=y+2, z=wz}).name == "air" then + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[x] then openings[x]={} end + openings[x][wz] = true + end + if get_node({x=x2, y=y+1, z=wz}).name == "air" and get_node({x=x2, y=y+2, z=wz}).name == "air" then + openings_counter = openings_counter + 1 + if check and openings_counter > 5 then return end + if not openings[x2] then openings[x2]={} end + openings[x2][wz] = true + end + end + + -- If all openings are only at corners, the dungeon can't be accessed yet. + -- This code extends the openings of corners so they can be entered. + if openings_counter >= 1 and openings_counter == #corners then + for c=1, #corners do + -- Prevent creating too many openings because this would lead to dungeon rejection + if openings_counter >= 5 then + break + end + -- A corner is widened by adding openings to both neighbors + local cx, cz = corners[c].x, corners[c].z + local cxn, czn = cx, cz + if x == cx then + cxn = cxn + 1 + else + cxn = cxn - 1 + end + if z == cz then + czn = czn + 1 + else + czn = czn - 1 + end + openings[cx][czn] = true + openings_counter = openings_counter + 1 + if openings_counter < 5 then + if not openings[cxn] then openings[cxn]={} end + openings[cxn][cz] = true + openings_counter = openings_counter + 1 + end + end + end + + -- Check conditions. If okay, start generating + if check and (openings_counter < 1 or openings_counter > 5) then return end + + minetest.log("action","[mcl_dungeons] Placing new dungeon at "..minetest.pos_to_string({x=x,y=y,z=z})) + -- Okay! Spawning starts! -- Remember spawner chest positions to set metadata later - local chest_posses = {} + local chests = {} local spawner_posses = {} - -- Calculate the number of dungeon spawn attempts - local sizevector = vector.subtract(maxp, minp) - sizevector = vector.add(sizevector, 1) - local chunksize = sizevector.x * sizevector.y * sizevector.z + -- First prepare random chest positions. + -- Chests spawn at wall - -- In Minecraft, there 8 dungeon spawn attempts Minecraft chunk (16*256*16 = 65536 blocks). - -- Minetest chunks don't have this size, so scale the number accordingly. - local attempts = math.ceil(chunksize / 65536 * 8) - - for a=1, attempts do - local x, y, z - local b = 7 -- buffer - x = math.random(minp.x+b, maxp.x-b) - - local ymin = math.min(mcl_vars.mg_overworld_max, math.max(minp.y, mcl_vars.mg_bedrock_overworld_max) + 7) - local ymax = math.min(mcl_vars.mg_overworld_max, math.max(maxp.y, mcl_vars.mg_bedrock_overworld_max) - 4) - - y = math.random(ymin, ymax) - z = math.random(minp.z+b, maxp.z-b) - - local dungeonsizes = { - { x=5, y=4, z=5}, - { x=5, y=4, z=7}, - { x=7, y=4, z=5}, - { x=7, y=4, z=7}, - } - local dim = dungeonsizes[math.random(1, #dungeonsizes)] - - -- Check floor and ceiling: Must be *completely* solid - local ceilingfloor_ok = true - for tx = x, x+dim.x do - for tz = z, z+dim.z do - local floor = minetest.get_name_from_content_id(data[area:index(tx, y, tz)]) - local ceiling = minetest.get_name_from_content_id(data[area:index(tx, y+dim.y+1, tz)]) - if (not minetest.registered_nodes[floor].walkable) or (not minetest.registered_nodes[ceiling].walkable) then - ceilingfloor_ok = false - break - end - end - if not ceilingfloor_ok then break end + -- We assign each position at the wall a number and each chest gets one of these numbers randomly + local totalChests = 2 -- this code strongly relies on this number being 2 + local totalChestSlots = (dim.x + dim.z - 2) * 2 + local chestSlots = {} + -- There is a small chance that both chests have the same slot. + -- In that case, we give a 2nd chance for the 2nd chest to get spawned. + -- If it failed again, tough luck! We stick with only 1 chest spawned. + local lastRandom + local secondChance = true -- second chance is still available + for i=1, totalChests do + local r = pr:next(1, totalChestSlots) + if r == lastRandom and secondChance then + -- Oops! Same slot selected. Try again. + r = pr:next(1, totalChestSlots) + secondChance = false end + lastRandom = r + table_insert(chestSlots, r) + end + table_sort(chestSlots) + local currentChest = 1 - -- Check for air openings (2 stacked air at ground level) in wall positions - local openings_counter = 0 - -- Store positions of openings; walls will not be generated here - local openings = {} - -- Corners are stored because a corner-only opening needs to be increased, - -- so entities can get through. - local corners = {} - if ceilingfloor_ok then - - local walls = { - -- walls along x axis (contain corners) - { x, x+dim.x+1, "x", "z", z }, - { x, x+dim.x+1, "x", "z", z+dim.z+1 }, - -- walls along z axis (exclude corners) - { z+1, z+dim.z, "z", "x", x }, - { z+1, z+dim.z, "z", "x", x+dim.x+1 }, - } - - for w=1, #walls do - local wall = walls[w] - for iter = wall[1], wall[2] do - local pos = {} - pos[wall[3]] = iter - pos[wall[4]] = wall[5] - pos.y = y+1 - - if openings[pos.x] == nil then openings[pos.x] = {} end - - local door1 = area:index(pos.x, pos.y, pos.z) - pos.y = y+2 - local door2 = area:index(pos.x, pos.y, pos.z) - local doorname1 = minetest.get_name_from_content_id(data[door1]) - local doorname2 = minetest.get_name_from_content_id(data[door2]) - if doorname1 == "air" and doorname2 == "air" then - openings_counter = openings_counter + 1 - openings[pos.x][pos.z] = true - - -- Record corners - if wall[3] == "x" and (iter == wall[1] or iter == wall[2]) then - table.insert(corners, {x=pos.x, z=pos.z}) - end - end - end - end - - end - - -- If all openings are only at corners, the dungeon can't be accessed yet. - -- This code extends the openings of corners so they can be entered. - if openings_counter >= 1 and openings_counter == #corners then - for c=1, #corners do - -- Prevent creating too many openings because this would lead to dungeon rejection - if openings_counter >= 5 then - break - end - -- A corner is widened by adding openings to both neighbors - local cx, cz = corners[c].x, corners[c].z - local cxn, czn = cx, cz - if x == cx then - cxn = cxn + 1 - else - cxn = cxn - 1 - end - if z == cz then - czn = czn + 1 - else - czn = czn - 1 - end - openings[cx][czn] = true - openings_counter = openings_counter + 1 - if openings_counter < 5 then - openings[cxn][cz] = true - openings_counter = openings_counter + 1 - end - end - end - - -- Check conditions. If okay, start generating - if ceilingfloor_ok and openings_counter >= 1 and openings_counter <= 5 then - -- Okay! Spawning starts! - - -- First prepare random chest positions. - -- Chests spawn at wall - - -- We assign each position at the wall a number and each chest gets one of these numbers randomly - local totalChests = 2 -- this code strongly relies on this number being 2 - local totalChestSlots = (dim.x-1) * (dim.z-1) - local chestSlots = {} - -- There is a small chance that both chests have the same slot. - -- In that case, we give a 2nd chance for the 2nd chest to get spawned. - -- If it failed again, tough luck! We stick with only 1 chest spawned. - local lastRandom - local secondChance = true -- second chance is still available - for i=1, totalChests do - local r = math.random(1, totalChestSlots) - if r == lastRandom and secondChance then - -- Oops! Same slot selected. Try again. - r = math.random(1, totalChestSlots) - secondChance = false - end - lastRandom = r - table.insert(chestSlots, r) - end - table.sort(chestSlots) - local currentChest = 1 - - -- Calculate the mob spawner position, to be re-used for later - local spawner_pos = {x = x + math.ceil(dim.x/2), y = y+1, z = z + math.ceil(dim.z/2)} - table.insert(spawner_posses, spawner_pos) - - -- Generate walls and floor - local maxx, maxy, maxz = x+dim.x+1, y+dim.y, z+dim.z+1 - local chestSlotCounter = 1 - for tx = x, maxx do - for tz = z, maxz do - for ty = y, maxy do - local p_pos = area:index(tx, ty, tz) - - -- Do not overwrite nodes with is_ground_content == false (e.g. bedrock) - -- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other - local name = minetest.get_name_from_content_id(data[p_pos]) - if name == "mcl_core:cobble" or name == "mcl_core:mossycobble" or minetest.registered_nodes[name].is_ground_content then - -- Floor - if ty == y then - if math.random(1,4) == 1 then - data[p_pos] = c_cobble - else - data[p_pos] = c_mossycobble - end - - -- Generate walls - --[[ Note: No additional cobblestone ceiling is generated. This is intentional. - The solid blocks above the dungeon are considered as the “ceiling”. - It is possible (but rare) for a dungeon to generate below sand or gravel. ]] - - elseif ty > y and (tx == x or tx == maxx or (tz == z or tz == maxz)) then - -- Check if it's an opening first - if (not openings[tx][tz]) or ty == maxy then - -- Place wall or ceiling - data[p_pos] = c_cobble - elseif ty < maxy - 1 then - -- Normally the openings are already clear, but not if it is a corner - -- widening. Make sure to clear at least the bottom 2 nodes of an opening. - data[p_pos] = c_air - elseif ty == maxy - 1 and data[p_pos] ~= c_air then - -- This allows for variation between 2-node and 3-node high openings. - data[p_pos] = c_cobble - end - -- If it was an opening, the lower 3 blocks are not touched at all - - -- Room interiour - else - local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) - - -- Place next chest at the wall (if it was its chosen wall slot) - if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then - table.insert(chest_posses, {x=tx, y=ty, z=tz}) - currentChest = currentChest + 1 - else - data[p_pos] = c_air - end - if forChest then - chestSlotCounter = chestSlotCounter + 1 - end - end - end - - end - end - end - end - - lvm_used = true + -- Calculate the mob spawner position, to be re-used for later + local sp = {x = x + math_ceil(dim.x/2), y = y+1, z = z + math_ceil(dim.z/2)} + local rn = registered_nodes[get_node(sp).name] + if rn and rn.is_ground_content then + table_insert(spawner_posses, sp) end - if lvm_used then - local chest_param2 = {} - -- Determine correct chest rotation (must pointi outwards) - for c=1, #chest_posses do - local cpos = chest_posses[c] + -- Generate walls and floor + local maxx, maxy, maxz = x+dim.x+1, y+dim.y, z+dim.z+1 + local chestSlotCounter = 1 + for tx = x, maxx do + for tz = z, maxz do + for ty = y, maxy do + local p = {x = tx, y=ty, z=tz} - -- Check surroundings of chest to determine correct rotation - local surround_vectors = { - { x=-1, y=0, z=0 }, - { x=1, y=0, z=0 }, - { x=0, y=0, z=-1 }, - { x=0, y=0, z=1 }, - } - local surroundings = {} - - for s=1, #surround_vectors do - -- Detect the 4 horizontal neighbors - local spos = vector.add(cpos, surround_vectors[s]) - local wpos = vector.subtract(cpos, surround_vectors[s]) - local p_pos = area:index(spos.x, spos.y, spos.z) - local p_pos2 = area:index(wpos.x, wpos.y, wpos.z) - - local nodename = minetest.get_name_from_content_id(data[p_pos]) - local nodename2 = minetest.get_name_from_content_id(data[p_pos2]) - local nodedef = minetest.registered_nodes[nodename] - local nodedef2 = minetest.registered_nodes[nodename2] - -- The chest needs an open space in front of it and a walkable node (except chest) behind it - if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then - table.insert(surroundings, spos) + -- Do not overwrite nodes with is_ground_content == false (e.g. bedrock) + -- Exceptions: cobblestone and mossy cobblestone so neighborings dungeons nicely connect to each other + local name = get_node(p).name + local rn = registered_nodes[name] + if rn and rn.is_ground_content or name == "mcl_core:cobble" or name == "mcl_core:mossycobble" then + -- Floor + if ty == y then + if pr:next(1,4) == 1 then + swap_node(p, {name = "mcl_core:cobble"}) + else + swap_node(p, {name = "mcl_core:mossycobble"}) end - end - -- Set param2 (=facedir) of this chest - local facedir - if #surroundings <= 0 then - -- Fallback if chest ended up in the middle of a room for some reason - facedir = math.random(0, 0) + + -- Generate walls + --[[ Note: No additional cobblestone ceiling is generated. This is intentional. + The solid blocks above the dungeon are considered as the “ceiling”. + It is possible (but rare) for a dungeon to generate below sand or gravel. ]] + + elseif tx == x or tz == z or tx == maxx or tz == maxz then + -- Check if it's an opening first + if (ty == maxy) or (not (openings[tx] and openings[tx][tz])) then + -- Place wall or ceiling + swap_node(p, {name = "mcl_core:cobble"}) + elseif ty < maxy - 1 then + -- Normally the openings are already clear, but not if it is a corner + -- widening. Make sure to clear at least the bottom 2 nodes of an opening. + if name ~= "air" then swap_node(p, {name = "air"}) end + elseif name ~= "air" then + -- This allows for variation between 2-node and 3-node high openings. + swap_node(p, {name = "mcl_core:cobble"}) + end + -- If it was an opening, the lower 3 blocks are not touched at all + + -- Room interiour else - -- 1 or multiple possible open directions: Choose random facedir - local face_to = surroundings[math.random(1, #surroundings)] - facedir = minetest.dir_to_facedir(vector.subtract(cpos, face_to)) - end - chest_param2[c] = facedir - end + if (ty==y+1) and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then + currentChest = currentChest + 1 + table_insert(chests, {x=tx, y=ty, z=tz}) + else + swap_node(p, {name = "air"}) + end - -- Finally generate the dungeons all at once (except the chests and the spawners) - vm:set_data(data) - vm:calc_lighting() - vm:update_liquids() - vm:write_to_map() + local forChest = ty==y+1 and (tx==x+1 or tx==maxx-1 or tz==z+1 or tz==maxz-1) - -- Chests are placed seperately - for c=1, #chest_posses do - local cpos = chest_posses[c] - minetest.set_node(cpos, {name="mcl_chests:chest", param2=chest_param2[c]}) - local meta = minetest.get_meta(cpos) - local inv = meta:get_inventory() - local items = get_loot() - mcl_loot.fill_inventory(inv, "main", items) - end - - -- Mob spawners are placed seperately, too - -- We don't want to destroy non-ground nodes - for s=1, #spawner_posses do - local sp = spawner_posses[s] - local n = minetest.get_name_from_content_id(data[area:index(sp.x,sp.y,sp.z)]) - if minetest.registered_nodes[n].is_ground_content then - - -- ... and place it and select a random mob - minetest.set_node(sp, {name = "mcl_mobspawners:spawner"}) - local mobs = { - "mobs_mc:zombie", - "mobs_mc:zombie", - "mobs_mc:spider", - "mobs_mc:skeleton", - } - local spawner_mob = mobs[math.random(1, #mobs)] - - mcl_mobspawners.setup_spawner(sp, spawner_mob, 0, 7) + -- Place next chest at the wall (if it was its chosen wall slot) + if forChest and (currentChest < totalChests + 1) and (chestSlots[currentChest] == chestSlotCounter) then + currentChest = currentChest + 1 + table_insert(chests, {x=tx, y=ty, z=tz}) + -- else + --swap_node(p, {name = "air"}) + end + if forChest then + chestSlotCounter = chestSlotCounter + 1 + end end end + end end end + for c=#chests, 1, -1 do + local pos = chests[c] + + local surroundings = {} + for s=1, #surround_vectors do + -- Detect the 4 horizontal neighbors + local spos = vector_add(pos, surround_vectors[s]) + local wpos = vector_subtract(pos, surround_vectors[s]) + local nodename = get_node(spos).name + local nodename2 = get_node(wpos).name + local nodedef = registered_nodes[nodename] + local nodedef2 = registered_nodes[nodename2] + -- The chest needs an open space in front of it and a walkable node (except chest) behind it + if nodedef and nodedef.walkable == false and nodedef2 and nodedef2.walkable == true and nodename2 ~= "mcl_chests:chest" then + table_insert(surroundings, spos) + end + end + -- Set param2 (=facedir) of this chest + local facedir + if #surroundings <= 0 then + -- Fallback if chest ended up in the middle of a room for some reason + facedir = pr:next(0, 0) + else + -- 1 or multiple possible open directions: Choose random facedir + local face_to = surroundings[pr:next(1, #surroundings)] + facedir = dir_to_facedir(vector_subtract(pos, face_to)) + end + + set_node(pos, {name="mcl_chests:chest", param2=facedir}) + local meta = get_meta(pos) + minetest.log("action", "[mcl_dungeons] Filling chest " .. tostring(c) .. " at " .. minetest.pos_to_string(pos)) + mcl_loot.fill_inventory(meta:get_inventory(), "main", mcl_loot.get_multi_loot(loottable, pr), pr) end -end) + -- Mob spawners are placed seperately, too + -- We don't want to destroy non-ground nodes + for s=#spawner_posses, 1, -1 do + local sp = spawner_posses[s] + -- ... and place it and select a random mob + set_node(sp, {name = "mcl_mobspawners:spawner"}) + local mobs = { + "mobs_mc:zombie", + "mobs_mc:zombie", + "mobs_mc:spider", + "mobs_mc:skeleton", + } + local spawner_mob = mobs[pr:next(1, #mobs)] + + mcl_mobspawners.setup_spawner(sp, spawner_mob, 0, 7) + end end + +local function dungeons_nodes(minp, maxp, blockseed) + local ymin, ymax = math_max(min_y, minp.y), math_min(max_y, maxp.y) + if ymax < ymin then return false end + 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}) + end +end + +function mcl_dungeons.spawn_dungeon(p1, _, pr) + if not p1 or not pr or not p1.x or not p1.y or not p1.z then return end + local dim = dungeonsizes[pr:next(1, #dungeonsizes)] + local p2 = {x = p1.x+dim.x+1, y = p1.y+dim.y+1, z = p1.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, dontcheck=true}) +end + +mcl_mapgen_core.register_generator("dungeons", nil, dungeons_nodes, 999999) diff --git a/mods/MAPGEN/mcl_dungeons/mod.conf b/mods/MAPGEN/mcl_dungeons/mod.conf index d6af72a27..fe02286fa 100644 --- a/mods/MAPGEN/mcl_dungeons/mod.conf +++ b/mods/MAPGEN/mcl_dungeons/mod.conf @@ -1 +1,4 @@ name = mcl_dungeons +author = Wuzzy +description = Generates random dungeons in the world +depends = mcl_init, mcl_core, mcl_chests, mcl_mobs, mcl_mobspawners, mcl_mapgen_core, mobs_mc diff --git a/mods/MAPGEN/mcl_end_island/init.lua b/mods/MAPGEN/mcl_end_island/init.lua new file mode 100644 index 000000000..434c3c6ef --- /dev/null +++ b/mods/MAPGEN/mcl_end_island/init.lua @@ -0,0 +1,40 @@ +local width = 200 + +local noisemap = PerlinNoiseMap({ + offset = 0.5, + scale = 0.5, + spread = {x = width + 10, y = width + 10, z = width + 10}, + seed = minetest.get_mapgen_setting("seed") + 99999, + octaves = 4, + persist = 0.85, +}, {x = (width*2)+1, y = 30, z = (width * 2) + 1}):get_3d_map({x = 0, y = 0, z = 0}) + +local c_end_stone = minetest.get_content_id("mcl_end:end_stone") +local y_offset = -2 + +mcl_mapgen_core.register_generator("end_island", function(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -width or minp.x > width or maxp.z < -width or minp.z > width then + return + end + + for idx in area:iter(math.max(minp.x, -width), math.max(minp.y, -27025 + y_offset + 4), math.max(minp.z, -width), math.min(maxp.x, width), math.min(maxp.y, -27000 + y_offset), math.min(maxp.z, width)) do + local pos = area:position(idx) + local y = 27025 + pos.y - y_offset + if noisemap[pos.x + width + 1][y + 1][pos.z + width + 1] > (math.abs(1 - y / 25) ^ 2 + math.abs(pos.x / width) ^ 2 + math.abs(pos.z / width) ^ 2) then + data[idx] = c_end_stone + end + end + return true,false,false +end, function(minp,maxp,blockseed) + if maxp.y < (-27025 + y_offset) or minp.y > (-27000 + y_offset + 4) or maxp.x < -width or minp.x > width or maxp.z < -width or minp.z > width then + return + end + local nn = minetest.find_nodes_in_area_under_air(minp,maxp,{"mcl_end:end_stone"}) + local pr = PseudoRandom(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") + end + end +end, 15, true) diff --git a/mods/MAPGEN/mcl_end_island/mod.conf b/mods/MAPGEN/mcl_end_island/mod.conf new file mode 100644 index 000000000..1d39622d6 --- /dev/null +++ b/mods/MAPGEN/mcl_end_island/mod.conf @@ -0,0 +1,4 @@ +name = mcl_end_island +author = Fleckenstein +depends = mcl_mapgen_core, mcl_end, mcl_mobs +description = Generate the end main island for MCL2 diff --git a/mods/MAPGEN/mcl_mapgen_core/api.lua b/mods/MAPGEN/mcl_mapgen_core/api.lua new file mode 100644 index 000000000..978fb7cda --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/api.lua @@ -0,0 +1,147 @@ +local registered_generators = {} + +local lvm, nodes, param2 = 0, 0, 0 +local lvm_buffer = {} + +local logging = minetest.settings:get_bool("mcl_logging_mapgen",false) + +local function roundN(n, d) + if type(n) ~= "number" then return n end + local m = 10^d + return math.floor(n * m + 0.5) / m +end + +local function run_generators (p1, p2, blockseed) + if nodes > 0 then + for _, rec in ipairs(registered_generators) do + if rec.nf then + rec.nf(p1, p2, blockseed) + end + end + end +end + +local function update_data (vm, data, data2) + -- Write stuff + vm:set_data(data) + if param2 > 0 then + vm:set_param2_data(data2) + end +end + +local function post_generator_processing(vm, minp, maxp, deco_used, deco_table, ore_used, ore_table) + if deco_table then + minetest.generate_decorations(vm,vector.new(minp.x,deco_table.min,minp.z),vector.new(maxp.x,deco_table.max,maxp.z)) + elseif deco_used then + minetest.generate_decorations(vm) + end + if ore_table then + minetest.generate_ores(vm,vector.new(minp.x,ore_table.min,minp.z),vector.new(maxp.x,ore_table.max,maxp.z)) + elseif ore_used then + minetest.generate_ores(vm) + end +end + +local function post_generator_processing_2(vm, p1, p2, shadow) + vm:calc_lighting(p1, p2, shadow) + vm:write_to_map() + vm:update_liquids() +end + +minetest.register_on_generated(function(minp, maxp, blockseed) + local t1 = os.clock() + local p1, p2 = {x=minp.x, y=minp.y, z=minp.z}, {x=maxp.x, y=maxp.y, z=maxp.z} + if lvm > 0 then + local lvm_used, shadow, deco_used, deco_table, ore_used, ore_table = false, false, false, false, false, false + local lb2 = {} -- param2 + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local e1, e2 = {x=emin.x, y=emin.y, z=emin.z}, {x=emax.x, y=emax.y, z=emax.z} + local data2 + local data = vm:get_data(lvm_buffer) + if param2 > 0 then + data2 = vm:get_param2_data(lb2) + end + local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2}) + + for _, rec in ipairs(registered_generators) do + if rec.vf then + local lvm_used0, shadow0, deco, ore = rec.vf(vm, data, data2, e1, e2, area, p1, p2, blockseed) + if lvm_used0 then + lvm_used = true + end + if shadow0 then + shadow = true + end + if deco and type(deco) == "table" then + deco_table = deco + elseif deco then + deco_used = true + end + if ore and type(ore) == "table" then + ore_table = ore + elseif deco then + ore_used = true + end + end + end + + if lvm_used then + update_data (vm, data, data2) + post_generator_processing(vm, minp, maxp, deco_used, deco_table, ore_used, ore_table) + post_generator_processing_2(vm, p1, p2, shadow) + end + end + + run_generators (p1, p2, blockseed) + + mcl_vars.add_chunk(minp) + if logging then + minetest.log("action", "[mcl_mapgen_core] Generating chunk " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp).."..."..tostring(roundN(((os.clock() - t1)*1000),2)).."ms") + end +end) + + + +function minetest.register_on_generated(node_function) + mcl_mapgen_core.register_generator("mod_"..minetest.get_current_modname().."_"..tostring(#registered_generators+1), nil, node_function) +end + +function mcl_mapgen_core.register_generator(id, lvm_function, node_function, priority, needs_param2) + if not id then return end + + local priority = priority or 5000 + + if lvm_function then lvm = lvm + 1 end + if node_function then nodes = nodes + 1 end + if needs_param2 then param2 = param2 + 1 end + + local new_record = { + id = id, + i = priority, + vf = lvm_function, + nf = node_function, + needs_param2 = needs_param2, + } + + table.insert(registered_generators, new_record) + table.sort(registered_generators, function(a, b) + return (a.i < b.i) or ((a.i == b.i) and a.vf and (b.vf == nil)) + end) +end + +function mcl_mapgen_core.unregister_generator(id) + local index + for i, gen in ipairs(registered_generators) do + if gen.id == id then + index = i + break + end + end + if not index then return end + local rec = registered_generators[index] + table.remove(registered_generators, index) + if rec.vf then lvm = lvm - 1 end + if rec.nf then nodes = nodes - 1 end + if rec.needs_param2 then param2 = param2 - 1 end + --if rec.needs_level0 then level0 = level0 - 1 end +end diff --git a/mods/MAPGEN/mcl_mapgen_core/depends.txt b/mods/MAPGEN/mcl_mapgen_core/depends.txt deleted file mode 100644 index 4aa96f053..000000000 --- a/mods/MAPGEN/mcl_mapgen_core/depends.txt +++ /dev/null @@ -1,11 +0,0 @@ -mcl_init -mcl_core -biomeinfo -mclx_core? -mcl_worlds -mcl_cocoas -mcl_sponges -mcl_ocean -mcl_stairs -mcl_monster_eggs -mcl_structures diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index e292ac25d..c3eef6a26 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -1,3 +1,13 @@ +mcl_mapgen_core = {} +local registered_generators = {} + +local lvm, nodes, param2 = 0, 0, 0 +local lvm_used = false +local lvm_buffer = {} + +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + -- -- Aliases for map generator outputs -- @@ -43,18 +53,13 @@ minetest.register_alias("mapgen_stair_sandstonebrick", "mcl_stairs:stair_sandsto minetest.register_alias("mapgen_stair_sandstone_block", "mcl_stairs:stair_sandstone") minetest.register_alias("mapgen_stair_desert_stone", "mcl_stairs:stair_sandstone") +dofile(modpath.."/api.lua") +dofile(modpath.."/ores.lua") + local mg_name = minetest.get_mapgen_setting("mg_name") +local sea_level = tonumber(minetest.get_mapgen_setting("water_level")) local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" -local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor - --- End exit portal position. This is temporary. --- TODO: Remove the exit portal generation when the ender dragon has been implemented. -local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos) -END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30 -END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3 -END_EXIT_PORTAL_POS.y = END_EXIT_PORTAL_POS.y - 3 - -- Content IDs local c_bedrock = minetest.get_content_id("mcl_core:bedrock") local c_obsidian = minetest.get_content_id("mcl_core:obsidian") @@ -62,1021 +67,29 @@ local c_stone = minetest.get_content_id("mcl_core:stone") local c_dirt = minetest.get_content_id("mcl_core:dirt") local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") local c_dirt_with_grass_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow") +local c_reeds = minetest.get_content_id("mcl_core:reeds") local c_sand = minetest.get_content_id("mcl_core:sand") -local c_sandstone = minetest.get_content_id("mcl_core:sandstone") +--local c_sandstone = minetest.get_content_id("mcl_core:sandstone") local c_void = minetest.get_content_id("mcl_core:void") local c_lava = minetest.get_content_id("mcl_core:lava_source") local c_water = minetest.get_content_id("mcl_core:water_source") local c_soul_sand = minetest.get_content_id("mcl_nether:soul_sand") local c_netherrack = minetest.get_content_id("mcl_nether:netherrack") local c_nether_lava = minetest.get_content_id("mcl_nether:nether_lava_source") -local c_end_stone = minetest.get_content_id("mcl_end:end_stone") +--local c_end_stone = minetest.get_content_id("mcl_end:end_stone") local c_realm_barrier = minetest.get_content_id("mcl_core:realm_barrier") local c_top_snow = minetest.get_content_id("mcl_core:snow") local c_snow_block = minetest.get_content_id("mcl_core:snowblock") local c_clay = minetest.get_content_id("mcl_core:clay") local c_leaves = minetest.get_content_id("mcl_core:leaves") local c_jungleleaves = minetest.get_content_id("mcl_core:jungleleaves") -local c_jungletree = minetest.get_content_id("mcl_core:jungletree") +--local c_jungletree = minetest.get_content_id("mcl_core:jungletree") local c_cocoa_1 = minetest.get_content_id("mcl_cocoas:cocoa_1") local c_cocoa_2 = minetest.get_content_id("mcl_cocoas:cocoa_2") local c_cocoa_3 = minetest.get_content_id("mcl_cocoas:cocoa_3") local c_vine = minetest.get_content_id("mcl_core:vine") local c_air = minetest.CONTENT_AIR --- --- Ore generation --- - --- Diorite, andesite and granite -local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } -for s=1, #specialstones do - local node = specialstones[s] - minetest.register_ore({ - ore_type = "blob", - ore = node, - wherein = {"mcl_core:stone"}, - clust_scarcity = 15*15*15, - clust_num_ores = 33, - clust_size = 5, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - }) - minetest.register_ore({ - ore_type = "blob", - ore = node, - wherein = {"mcl_core:stone"}, - clust_scarcity = 10*10*10, - clust_num_ores = 58, - clust_size = 7, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, - }) -end - -local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"} - --- Dirt -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:dirt", - wherein = stonelike, - clust_scarcity = 15*15*15, - clust_num_ores = 33, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_vars.mg_overworld_max, -}) - --- Gravel -minetest.register_ore({ - ore_type = "blob", - ore = "mcl_core:gravel", - wherein = stonelike, - clust_scarcity = 14*14*14, - clust_num_ores = 33, - clust_size = 5, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(111), -}) - --- --- Coal --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 510*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 12, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(50), -}) - --- Medium-rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 525*3, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(51), - y_max = mcl_worlds.layer_to_y(80), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 600*3, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 550*3, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_coal", - wherein = stonelike, - clust_scarcity = 500*3, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(81), - y_max = mcl_worlds.layer_to_y(128), -}) - --- --- Iron --- -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 830, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(39), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_iron", - wherein = stonelike, - clust_scarcity = 1660, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(40), - y_max = mcl_worlds.layer_to_y(63), -}) - --- --- Gold --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 4775, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 6560, - clust_num_ores = 7, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(30), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_gold", - wherein = stonelike, - clust_scarcity = 13000, - clust_num_ores = 4, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(33), -}) - --- --- Diamond --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 5000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 8, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(12), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_diamond", - wherein = stonelike, - clust_scarcity = 20000, - clust_num_ores = 2, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) - --- --- Redstone --- - --- Common spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 500, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 800, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(13), -}) - --- Rare spawn -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_redstone", - wherein = stonelike, - clust_scarcity = 1600, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(13), - y_max = mcl_worlds.layer_to_y(15), -}) - --- --- Emerald --- - -if mg_name == "v6" then - -- Generate everywhere in v6, but rarely. - - -- Common spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, - clust_scarcity = 14340, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_vars.mg_overworld_min, - y_max = mcl_worlds.layer_to_y(29), - }) - -- Rare spawn - minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_emerald", - wherein = stonelike, - clust_scarcity = 21510, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(30), - y_max = mcl_worlds.layer_to_y(32), - }) -end - --- --- Lapis Lazuli --- - --- Common spawn (in the center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 10000, - clust_num_ores = 7, - clust_size = 4, - y_min = mcl_worlds.layer_to_y(14), - y_max = mcl_worlds.layer_to_y(16), -}) - --- Rare spawn (below center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(10), - y_max = mcl_worlds.layer_to_y(13), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(6), - y_max = mcl_worlds.layer_to_y(9), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(2), - y_max = mcl_worlds.layer_to_y(5), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(0), - y_max = mcl_worlds.layer_to_y(2), -}) - --- Rare spawn (above center) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 12000, - clust_num_ores = 6, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(17), - y_max = mcl_worlds.layer_to_y(20), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 14000, - clust_num_ores = 5, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(21), - y_max = mcl_worlds.layer_to_y(24), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 16000, - clust_num_ores = 4, - clust_size = 3, - y_min = mcl_worlds.layer_to_y(25), - y_max = mcl_worlds.layer_to_y(28), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 18000, - clust_num_ores = 3, - clust_size = 2, - y_min = mcl_worlds.layer_to_y(29), - y_max = mcl_worlds.layer_to_y(32), -}) -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:stone_with_lapis", - wherein = stonelike, - clust_scarcity = 32000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(31), - y_max = mcl_worlds.layer_to_y(32), -}) - -if not superflat then --- Water and lava springs (single blocks of lava/water source) --- Water appears at nearly every height, but not near the bottom -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:water_source", - wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"}, - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(5), - y_max = mcl_worlds.layer_to_y(128), -}) - --- Lava springs are rather common at -31 and below -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 2000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(1), - y_max = mcl_worlds.layer_to_y(10), -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 9000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(11), - y_max = mcl_worlds.layer_to_y(31), -}) - --- Lava springs will become gradually rarer with increasing height -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 32000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(32), - y_max = mcl_worlds.layer_to_y(47), -}) - -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 72000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(48), - y_max = mcl_worlds.layer_to_y(61), -}) - --- Lava may even appear above surface, but this is very rare -minetest.register_ore({ - ore_type = "scatter", - ore = "mcl_core:lava_source", - wherein = stonelike, - clust_scarcity = 96000, - clust_num_ores = 1, - clust_size = 1, - y_min = mcl_worlds.layer_to_y(62), - y_max = mcl_worlds.layer_to_y(127), -}) -end - -local function register_mgv6_decorations() - - -- Cacti - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:sand"}, - sidelen = 16, - noise_params = { - offset = -0.012, - scale = 0.024, - spread = {x = 100, y = 100, z = 100}, - seed = 257, - octaves = 3, - persist = 0.6 - }, - y_min = 4, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:cactus", - height = 1, - height_max = 3, - }) - - -- Sugar canes - minetest.register_decoration({ - deco_type = "simple", - place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"}, - sidelen = 16, - noise_params = { - offset = -0.3, - scale = 0.7, - spread = {x = 100, y = 100, z = 100}, - seed = 465, - octaves = 3, - persist = 0.7 - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:reeds", - height = 1, - height_max = 3, - spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, - num_spawn_by = 1, - }) - - -- Doubletall grass - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_grass", param1 = 255, }, - { name = "mcl_flowers:double_grass_top", param1 = 255, }, - }, - }, - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = -0.0025, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.0, - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - }) - - -- Large ferns - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:double_fern", param1=255, }, - { name = "mcl_flowers:double_fern_top", param1=255, }, - }, - }, - -- v6 hack: This makes sure large ferns only appear in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - place_on = {"group:grass_block_no_snow"}, - - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.01, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 2, - persist = 0.66, - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - }) - - -- Large flowers - local register_large_flower = function(name, seed, offset) - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "air", prob = 0 }, - { name = "mcl_flowers:"..name, param1=255, }, - { name = "mcl_flowers:"..name.."_top", param1=255, }, - }, - }, - place_on = {"group:grass_block_no_snow"}, - - sidelen = 16, - noise_params = { - offset = offset, - scale = 0.01, - spread = {x = 300, y = 300, z = 300}, - seed = seed, - octaves = 5, - persist = 0.62, - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - flags = "", - }) - end - - register_large_flower("rose_bush", 9350, -0.008) - register_large_flower("peony", 10450, -0.008) - register_large_flower("lilac", 10600, -0.007) - register_large_flower("sunflower", 2940, -0.005) - - -- Lily pad - minetest.register_decoration({ - deco_type = "schematic", - schematic = { - size = { x=1, y=3, z=1 }, - data = { - { name = "mcl_core:water_source", prob = 0 }, - { name = "mcl_core:water_source" }, - { name = "mcl_flowers:waterlily", param1 = 255 }, - }, - }, - place_on = "mcl_core:dirt", - sidelen = 16, - noise_params = { - offset = -0.12, - scale = 0.3, - spread = {x = 200, y = 200, z = 200}, - seed = 503, - octaves = 6, - persist = 0.7, - }, - y_min = 0, - y_max = 0, - rotation = "random", - }) - - -- Pumpkin - minetest.register_decoration({ - deco_type = "simple", - decoration = "mcl_farming:pumpkin_face", - param2 = 0, - param2_max = 3, - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = -0.008, - scale = 0.00666, - spread = {x = 250, y = 250, z = 250}, - seed = 666, - octaves = 6, - persist = 0.666 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - }) - - -- Melon - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = 0.002, - scale = 0.006, - spread = {x = 250, y = 250, z = 250}, - seed = 333, - octaves = 3, - persist = 0.6 - }, - -- Small trick to make sure melon spawn in jungles - spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, - num_spawn_by = 1, - y_min = 1, - y_max = 40, - decoration = "mcl_farming:melon", - }) - - -- Tall grass - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = 0.01, - scale = 0.3, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - noise_params = { - offset = 0.04, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 420, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - - -- Seagrass and kelp - local materials = {"dirt","sand"} - for i=1, #materials do - local mat = materials[i] - - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 8, - noise_params = { - offset = 0.04, - scale = 0.3, - spread = {x = 100, y = 100, z = 100}, - seed = 421, - octaves = 3, - persist = 0.6 - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = 0, - decoration = "mcl_ocean:seagrass_"..mat, - }) - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:mat"}, - sidelen = 8, - noise_params = { - offset = 0.08, - scale = 0.03, - spread = {x = 100, y = 100, z = 100}, - seed = 421, - octaves = 3, - persist = 0.6 - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -5, - decoration = "mcl_ocean:seagrass_"..mat, - }) - - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 16, - noise_params = { - offset = 0.01, - scale = 0.01, - spread = {x = 300, y = 300, z = 300}, - seed = 505, - octaves = 5, - persist = 0.62, - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -6, - decoration = "mcl_ocean:kelp_"..mat, - param2 = 16, - param2_max = 96, - }) - minetest.register_decoration({ - deco_type = "simple", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:"..mat}, - sidelen = 16, - noise_params = { - offset = 0.01, - scale = 0.01, - spread = {x = 100, y = 100, z = 100}, - seed = 506, - octaves = 5, - persist = 0.62, - }, - flags = "force_placement", - place_offset_y = -1, - y_min = mcl_vars.overworld_min, - y_max = -15, - decoration = "mcl_ocean:kelp_"..mat, - param2 = 32, - param2_max = 160, - }) - - end - - -- Wet Sponge - -- TODO: Remove this when we got ocean monuments - minetest.register_decoration({ - deco_type = "simple", - decoration = "mcl_sponges:sponge_wet", - spawn_by = {"group:water"}, - num_spawn_by = 1, - place_on = {"mcl_core:dirt","mcl_core:sand"}, - sidelen = 16, - noise_params = { - offset = 0.00295, - scale = 0.006, - spread = {x = 250, y = 250, z = 250}, - seed = 999, - octaves = 3, - persist = 0.666 - }, - flags = "force_placement", - y_min = mcl_vars.mg_lava_overworld_max + 5, - y_max = -20, - }) - - -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 8, - fill_ratio = 0.004, - y_min = 1, - y_max = mcl_vars.overworld_max, - decoration = "mcl_flowers:tallgrass", - }) - - local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} - local mseeds = { 7133, 8244 } - for m=1, #mushrooms do - -- Mushrooms next to trees - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, - sidelen = 16, - noise_params = { - offset = 0.04, - scale = 0.04, - spread = {x = 100, y = 100, z = 100}, - seed = mseeds[m], - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = mushrooms[m], - spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", }, - num_spawn_by = 1, - }) - end - - -- Dead bushes - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, - sidelen = 16, - noise_params = { - offset = 0, - scale = 0.035, - spread = {x = 100, y = 100, z = 100}, - seed = 1972, - octaves = 3, - persist = 0.6 - }, - y_min = 4, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:deadbush", - }) - - local function register_mgv6_flower(name, seed, offset, y_max) - if offset == nil then - offset = 0 - end - if y_max == nil then - y_max = mcl_vars.mg_overworld_max - end - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_no_snow"}, - sidelen = 16, - noise_params = { - offset = offset, - scale = 0.006, - spread = {x = 100, y = 100, z = 100}, - seed = seed, - octaves = 3, - persist = 0.6 - }, - y_min = 1, - y_max = y_max, - decoration = "mcl_flowers:"..name, - }) - end - - register_mgv6_flower("tulip_red", 436) - register_mgv6_flower("tulip_orange", 536) - register_mgv6_flower("tulip_pink", 636) - register_mgv6_flower("tulip_white", 736) - register_mgv6_flower("azure_bluet", 800) - register_mgv6_flower("dandelion", 8) - -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6. - -- We compensate by making it slightly rarer in v6. - register_mgv6_flower("allium", 0, -0.001) - --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6. - We emulate swamplands by limiting the height to 5 levels above sea level, - which should be close to the water. ]] - register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds.layer_to_y(67)) - register_mgv6_flower("oxeye_daisy", 3490) - register_mgv6_flower("poppy", 9439) - - -- Put top snow on snowy grass blocks. The v6 mapgen does not generate the top snow on its own. - minetest.register_decoration({ - deco_type = "simple", - place_on = {"group:grass_block_snow"}, - sidelen = 16, - fill_ratio = 11.0, -- complete coverage - y_min = 1, - y_max = mcl_vars.mg_overworld_max, - decoration = "mcl_core:snow", - }) - -end - local mg_flags = minetest.settings:get_flags("mg_flags") -- Inform other mods of dungeon setting for MCL2-style dungeons @@ -1085,16 +98,32 @@ mcl_vars.mg_dungeons = mg_flags.dungeons and not superflat -- Disable builtin dungeons, we provide our own dungeons mg_flags.dungeons = false --- Apply mapgen-specific mapgen code -if mg_name == "v6" then - register_mgv6_decorations() -elseif superflat then +if superflat then -- Enforce superflat-like mapgen: no caves, decor, lakes and hills mg_flags.caves = false mg_flags.decorations = false minetest.set_mapgen_setting("mgflat_spflags", "nolakes,nohills", true) end +if mg_name == "v7" then + minetest.set_mapgen_setting("mgv7_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "valleys" then + minetest.set_mapgen_setting("mgvalleys_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "carpathian" then + minetest.set_mapgen_setting("mgcarpathian_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "v5" then + minetest.set_mapgen_setting("mgv5_cavern_threshold", "0.20", true) + mg_flags.caverns = true +elseif mg_name == "fractal" then + minetest.set_mapgen_setting("mgfractal_cavern_threshold", "0.20", true) + mg_flags.caverns = true +end + + + local mg_flags_str = "" for k,v in pairs(mg_flags) do if v == false then @@ -1107,6 +136,37 @@ if string.len(mg_flags_str) > 0 then end minetest.set_mapgen_setting("mg_flags", mg_flags_str, true) +local function between(x, y, z) -- x is between y and z (inclusive) + return y <= x and x <= z +end + +local function in_cube(tpos,wpos1,wpos2) + local xmax=wpos2.x + local xmin=wpos1.x + + local ymax=wpos2.y + local ymin=wpos1.y + + local zmax=wpos2.z + local zmin=wpos1.z + if wpos1.x > wpos2.x then + xmax=wpos1.x + xmin=wpos2.x + end + if wpos1.y > wpos2.y then + ymax=wpos1.y + ymin=wpos2.y + end + if wpos1.z > wpos2.z then + zmax=wpos1.z + zmin=wpos2.z + end + if between(tpos.x,xmin,xmax) and between(tpos.y,ymin,ymax) and between(tpos.z,zmin,zmax) then + return true + end + return false +end + -- Helper function for converting a MC probability to MT, with -- regards to MapBlocks. -- Some MC generated structures are generated on per-chunk @@ -1121,22 +181,10 @@ local function minecraft_chunk_probability(x, minp, maxp) return x * (((maxp.x-minp.x+1)*(maxp.z-minp.z+1)) / 256) end --- Takes an index of a biomemap table (from minetest.get_mapgen_object), --- minp and maxp (from an on_generated callback) and returns the real world coordinates --- as X, Z. --- Inverse function of xz_to_biomemap -local biomemap_to_xz = function(index, minp, maxp) - local xwidth = maxp.x - minp.x + 1 - local zwidth = maxp.z - minp.z + 1 - local x = ((index-1) % xwidth) + minp.x - local z = ((index-1) / zwidth) + minp.z - return x, z -end - -- Takes x and z coordinates and minp and maxp of a generated chunk -- (in on_generated callback) and returns a biomemap index) -- Inverse function of biomemap_to_xz -local xz_to_biomemap_index = function(x, z, minp, maxp) +local function xz_to_biomemap_index(x, z, minp, maxp) local xwidth = maxp.x - minp.x + 1 local zwidth = maxp.z - minp.z + 1 local minix = x % xwidth @@ -1145,911 +193,418 @@ local xz_to_biomemap_index = function(x, z, minp, maxp) return (minix + miniz * zwidth) + 1 end --- Perlin noise objects -local perlin_structures -local perlin_vines, perlin_vines_fine, perlin_vines_upwards, perlin_vines_length, perlin_vines_density -local perlin_clay -local function generate_clay(minp, maxp, seed, voxelmanip_data, voxelmanip_area, lvm_used) - -- TODO: Make clay generation reproducible for same seed. - if maxp.y < -5 or minp.y > 0 then - return lvm_used - end +-- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. +-- Also perform some basic node replacements. - perlin_clay = perlin_clay or minetest.get_perlin({ - offset = 0.5, - scale = 0.2, - spread = {x = 5, y = 5, z = 5}, - seed = -316, - octaves = 1, - persist = 0.0 - }) +local bedrock_check +if mcl_vars.mg_bedrock_is_rough then + function bedrock_check(pos, _, pr) + local y = pos.y + -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer + -- This code assumes a bedrock height of 5 layers. - for y=math.max(minp.y, 0), math.min(maxp.y, -8), -1 do - -- Assume X and Z lengths are equal - local divlen = 4 - local divs = (maxp.x-minp.x)/divlen+1; - for divx=0+1,divs-2 do - for divz=0+1,divs-2 do - -- Get position and shift it a bit randomly so the clay do not obviously appear in a grid - local cx = minp.x + math.floor((divx+0.5)*divlen) + math.random(-1,1) - local cz = minp.z + math.floor((divz+0.5)*divlen) + math.random(-1,1) + local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock + local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom + local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling - local water_pos = voxelmanip_area:index(cx, y+1, cz) - local waternode = voxelmanip_data[water_pos] - local surface_pos = voxelmanip_area:index(cx, y, cz) - local surfacenode = voxelmanip_data[surface_pos] - - local genrnd = math.random(1, 20) - if genrnd == 1 and perlin_clay:get_3d({x=cx,y=y,z=cz}) > 0 and waternode == c_water and - (surfacenode == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(surfacenode), "sand") == 1) then - local diamondsize = math.random(1, 3) - for x1 = -diamondsize, diamondsize do - for z1 = -(diamondsize - math.abs(x1)), diamondsize - math.abs(x1) do - local ccpos = voxelmanip_area:index(cx+x1, y, cz+z1) - local claycandidate = voxelmanip_data[ccpos] - if voxelmanip_data[ccpos] == c_dirt or minetest.get_item_group(minetest.get_name_from_content_id(claycandidate), "sand") == 1 then - voxelmanip_data[ccpos] = c_clay - lvm_used = true - end - end - end - end + local top + if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then + -- 50% bedrock chance + top = 2 + elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then + -- 66.666...% + top = 3 + elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then + -- 75% + top = 4 + elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then + -- 90% + top = 10 + elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then + -- 100% + return true + else + -- Not in bedrock layer + return false end - end - end - return lvm_used -end --- TODO: Try to use more efficient structure generating code -local function generate_structures(minp, maxp, seed, biomemap) - local chunk_has_desert_well = false - local chunk_has_desert_temple = false - local chunk_has_igloo = false - local struct_min, struct_max = -3, 64 - if maxp.y >= struct_min and minp.y <= struct_max then - -- Generate structures - - perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) - -- Assume X and Z lengths are equal - local divlen = 5 - local divs = (maxp.x-minp.x)/divlen+1; - for divx=0,divs-1 do - for divz=0,divs-1 do - local x0 = minp.x + math.floor((divx+0)*divlen) - local z0 = minp.z + math.floor((divz+0)*divlen) - local x1 = minp.x + math.floor((divx+1)*divlen) - local z1 = minp.z + math.floor((divz+1)*divlen) - -- Determine amount from perlin noise - local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9) - -- Find random positions based on this random - local pr = PseudoRandom(seed+1) - for i=0, amount do - local x = pr:next(x0, x1) - local z = pr:next(z0, z1) - -- Find ground level - local ground_y = nil - for y = struct_max, struct_min, -1 do - local checknode = minetest.get_node_or_nil({x=x,y=y,z=z}) - if checknode then - local def = minetest.registered_nodes[checknode.name] - if def and def.walkable then - ground_y = y - break - end - end - end - - if ground_y then - local p = {x=x,y=ground_y+1,z=z} - local nn = minetest.get_node(p).name - -- Check if the node can be replaced - if minetest.registered_nodes[nn] and - minetest.registered_nodes[nn].buildable_to then - nn = minetest.get_node({x=x,y=ground_y,z=z}).name - local struct = false - - -- Desert temples and desert wells - if nn == "mcl_core:sand" or (nn == "mcl_core:sandstone") then - if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then - -- Spawn desert temple - -- TODO: Check surface - if math.random(1,12000) == 1 then - mcl_structures.call_struct(p, "desert_temple") - chunk_has_desert_temple = true - end - end - if not chunk_has_desert_temple and not chunk_has_desert_well and ground_y > 3 then - local desert_well_prob = minecraft_chunk_probability(1000, minp, maxp) - - -- Spawn desert well - if math.random(1, desert_well_prob) == 1 then - -- Check surface - local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, {x=p.x+5, y=p.y-1, z=p.z+5}, "mcl_core:sand") - if #surface >= 25 then - mcl_structures.call_struct(p, "desert_well") - chunk_has_desert_well = true - end - end - end - - -- Igloos - elseif not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then - if math.random(1, 4400) == 1 then - -- Check surface - local floor = {x=p.x+9, y=p.y-1, z=p.z+9} - local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock") - local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow") - if #surface + #surface2 >= 63 then - mcl_structures.call_struct(p, "igloo") - chunk_has_igloo = true - end - end - end - - -- Fossil - if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then - local fossil_prob = minecraft_chunk_probability(64, minp, maxp) - - if math.random(1, fossil_prob) == 1 then - -- Spawn fossil below desert surface between layers 40 and 49 - local p1 = {x=p.x, y=math.random(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} - -- Very rough check of the environment (we expect to have enough stonelike nodes). - -- Fossils may still appear partially exposed in caves, but this is O.K. - local p2 = vector.add(p1, 4) - local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}) - - if #nodes >= 100 then -- >= 80% - mcl_structures.call_struct(p1, "fossil") - end - end - end - - -- Witch hut - if ground_y <= 0 and nn == "mcl_core:dirt" then - local prob = minecraft_chunk_probability(48, minp, maxp) - if math.random(1, prob) == 1 then - - local swampland = minetest.get_biome_id("Swampland") - local swampland_shore = minetest.get_biome_id("Swampland_shore") - - -- Where do witches live? - - local here_be_witches = false - if mg_name == "v6" then - -- v6: In Normal biome - if biomeinfo.get_v6_biome(p) == "Normal" then - here_be_witches = true - end - else - -- Other mapgens: In swampland biome - local bi = xz_to_biomemap_index(p.x, p.z, minp, maxp) - if biomemap[bi] == swampland or biomemap[bi] == swampland_shore then - here_be_witches = true - end - end - - if here_be_witches then - local r = tostring(math.random(0, 3) * 90) -- "0", "90", "180" or 270" - local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} - local size - if r == "0" or r == "180" then - size = {x=10, y=4, z=8} - else - size = {x=8, y=4, z=10} - end - local p2 = vector.add(p1, size) - - -- This checks free space at the “body” of the hut and a bit around. - -- ALL nodes must be free for the placement to succeed. - local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"}) - if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then - local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z} - - -- FIXME: For some mysterious reason (black magic?) this - -- function does sometimes NOT spawn the witch hut. One can only see the - -- oak wood nodes in the water, but no hut. :-/ - mcl_structures.call_struct(place, "witch_hut", r) - - -- TODO: Spawn witch in or around hut when the mob sucks less. - - local place_tree_if_free = function(pos, prev_result) - local nn = minetest.get_node(pos).name - if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then - minetest.set_node(pos, {name="mcl_core:tree", param2=0}) - return prev_result - else - return false - end - end - local offsets - if r == "0" then - offsets = { - {x=1, y=0, z=1}, - {x=1, y=0, z=5}, - {x=6, y=0, z=1}, - {x=6, y=0, z=5}, - } - elseif r == "180" then - offsets = { - {x=2, y=0, z=1}, - {x=2, y=0, z=5}, - {x=7, y=0, z=1}, - {x=7, y=0, z=5}, - } - elseif r == "270" then - offsets = { - {x=1, y=0, z=1}, - {x=5, y=0, z=1}, - {x=1, y=0, z=6}, - {x=5, y=0, z=6}, - } - elseif r == "90" then - offsets = { - {x=1, y=0, z=2}, - {x=5, y=0, z=2}, - {x=1, y=0, z=7}, - {x=5, y=0, z=7}, - } - end - for o=1, #offsets do - local ok = true - for y=place.y-1, place.y-64, -1 do - local tpos = vector.add(place, offsets[o]) - tpos.y = y - ok = place_tree_if_free(tpos, ok) - if not ok then - break - end - end - end - end - end - end - end - - -- Ice spikes in v6 - -- In other mapgens, ice spikes are generated as decorations. - if mg_name == "v6" and not chunk_has_igloo and nn == "mcl_core:snowblock" then - local spike = math.random(1, 58000) - if spike < 3 then - -- Check surface - local floor = {x=p.x+4, y=p.y-1, z=p.z+4} - local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock"}) - -- Check for collision with spruce - local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) - - if #surface >= 9 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_large") - end - elseif spike < 100 then - -- Check surface - local floor = {x=p.x+6, y=p.y-1, z=p.z+6} - local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"}) - - -- Check for collision with spruce - local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) - - if #surface >= 25 and #spruce_collisions == 0 then - mcl_structures.call_struct(p, "ice_spike_small") - end - end - end - end - end - - end - end - end - -- End exit portal - elseif minp.y <= END_EXIT_PORTAL_POS.y and maxp.y >= END_EXIT_PORTAL_POS.y and - minp.x <= END_EXIT_PORTAL_POS.x and maxp.x >= END_EXIT_PORTAL_POS.x and - minp.z <= END_EXIT_PORTAL_POS.z and maxp.z >= END_EXIT_PORTAL_POS.z then - local built = false - for y=maxp.y, minp.y, -1 do - local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z} - if minetest.get_node(p).name == "mcl_end:end_stone" then - mcl_structures.call_struct(p, "end_exit_portal") - built = true - break - end - end - if not built then - mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal") - end + return pr:next(1, top) <= top-1 end end --- Buffers for LuaVoxelManip -local lvm_buffer = {} -local lvm_buffer_param2 = {} --- Generate tree decorations in the bounding box. This adds: --- * Cocoa at jungle trees --- * Jungle tree vines --- * Oak vines in swamplands -local function generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used) - if maxp.y < 0 then - return lvm_used - end - - local oaktree, oakleaves, jungletree, jungleleaves = {}, {}, {}, {} - local swampland = minetest.get_biome_id("Swampland") - local swampland_shore = minetest.get_biome_id("Swampland_shore") - local jungle = minetest.get_biome_id("Jungle") - local jungle_shore = minetest.get_biome_id("Jungle_shore") - local jungle_m = minetest.get_biome_id("JungleM") - local jungle_m_shore = minetest.get_biome_id("JungleM_shore") - local jungle_edge = minetest.get_biome_id("JungleEdge") - local jungle_edge_shore = minetest.get_biome_id("JungleEdge_shore") - local jungle_edge_m = minetest.get_biome_id("JungleEdgeM") - local jungle_edge_m_shore = minetest.get_biome_id("JungleEdgeM_shore") - - -- Modifier for Jungle M biome: More vines and cocoas - local dense_vegetation = false - - if biomemap then - -- Biome map available: Check if the required biome (jungle or swampland) - -- is in this mapchunk. We are only interested in trees in the correct biome. - -- The nodes are added if the correct biome is *anywhere* in the mapchunk. - -- TODO: Strictly generate vines in the correct biomes only. - local swamp_biome_found, jungle_biome_found = false, false - for b=1, #biomemap do - local id = biomemap[b] - - if not swamp_biome_found and (id == swampland or id == swampland_shore) then - oaktree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:tree"}) - oakleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:leaves"}) - swamp_biome_found = true - end - if not jungle_biome_found and (id == jungle or id == jungle_shore or id == jungle_m or id == jungle_m_shore or id == jungle_edge or id == jungle_edge_shore or id == jungle_edge_m or id == jungle_edge_m_shore) then - jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"}) - jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"}) - jungle_biome_found = true - end - if not dense_vegetation and (id == jungle_m or id == jungle_m_shore) then - dense_vegetation = true - end - if swamp_biome_found and jungle_biome_found and dense_vegetation then - break - end - end - else - -- If there is no biome map, we just count all jungle things we can find. - -- Oak vines will not be generated. - jungletree = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungletree"}) - jungleleaves = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:jungleleaves"}) - end - - local pos, treepos, dir - - local cocoachance = 40 - if dense_vegetation then - cocoachance = 32 - end - - -- Pass 1: Generate cocoas at jungle trees - for n = 1, #jungletree do - - pos = table.copy(jungletree[n]) - treepos = table.copy(pos) - - if minetest.find_node_near(pos, 1, {"mcl_core:jungleleaves"}) then - - dir = math.random(1, cocoachance) - - if dir == 1 then - pos.z = pos.z + 1 - elseif dir == 2 then - pos.z = pos.z - 1 - elseif dir == 3 then - pos.x = pos.x + 1 - elseif dir == 4 then - pos.x = pos.x -1 - end - - local p_pos = area:index(pos.x, pos.y, pos.z) - local l = minetest.get_node_light(pos) - - if dir < 5 - and data[p_pos] == c_air - and l ~= nil and l > 12 then - local c = math.random(1, 3) - if c == 1 then - data[p_pos] = c_cocoa_1 - elseif c == 2 then - data[p_pos] = c_cocoa_2 - else - data[p_pos] = c_cocoa_3 - end - param2_data[p_pos] = minetest.dir_to_facedir(vector.subtract(treepos, pos)) - lvm_used = true - end - - end - end - - -- Pass 2: Generate vines at jungle wood, jungle leaves in jungle and oak wood, oak leaves in swampland - perlin_vines = perlin_vines or minetest.get_perlin(555, 4, 0.6, 500) - perlin_vines_fine = perlin_vines_fine or minetest.get_perlin(43000, 3, 0.6, 1) - perlin_vines_length = perlin_vines_length or minetest.get_perlin(435, 4, 0.6, 75) - perlin_vines_upwards = perlin_vines_upwards or minetest.get_perlin(436, 3, 0.6, 10) - perlin_vines_density = perlin_vines_density or minetest.get_perlin(436, 3, 0.6, 500) - - -- Extra long vines in Jungle M - local maxvinelength = 7 - if dense_vegetation then - maxvinelength = 14 - end - local treething - for i=1, 4 do - if i==1 then - treething = jungletree - elseif i == 2 then - treething = jungleleaves - elseif i == 3 then - treething = oaktree - elseif i == 4 then - treething = oakleaves - end - - for n = 1, #treething do - pos = treething[n] - - treepos = table.copy(pos) - - local dirs = { - {x=1,y=0,z=0}, - {x=-1,y=0,z=0}, - {x=0,y=0,z=1}, - {x=0,y=0,z=-1}, - } - - for d = 1, #dirs do - local pos = vector.add(pos, dirs[d]) - local p_pos = area:index(pos.x, pos.y, pos.z) - - local vine_threshold = math.max(0.33333, perlin_vines_density:get_2d(pos)) - if dense_vegetation then - vine_threshold = vine_threshold * (2/3) - end - - if perlin_vines:get_2d(pos) > -1.0 and perlin_vines_fine:get_3d(pos) > vine_threshold and data[p_pos] == c_air then - - local rdir = {} - rdir.x = -dirs[d].x - rdir.y = dirs[d].y - rdir.z = -dirs[d].z - local param2 = minetest.dir_to_wallmounted(rdir) - - -- Determine growth direction - local grow_upwards = false - -- Only possible on the wood, not on the leaves - if i == 1 then - grow_upwards = perlin_vines_upwards:get_3d(pos) > 0.8 - end - if grow_upwards then - -- Grow vines up 1-4 nodes, even through jungleleaves. - -- This may give climbing access all the way to the top of the tree :-) - -- But this will be fairly rare. - local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * 4) - for l=0, length-1 do - local t_pos = area:index(treepos.x, treepos.y, treepos.z) - - if (data[p_pos] == c_air or data[p_pos] == c_jungleleaves or data[p_pos] == c_leaves) and mcl_core.supports_vines(minetest.get_name_from_content_id(data[t_pos])) then - data[p_pos] = c_vine - param2_data[p_pos] = param2 +-- Helper function to set all nodes in the layers between min and max. +-- content_id: Node to set +-- check: optional. +-- If content_id, node will be set only if it is equal to check. +-- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true. +-- min, max: Minimum and maximum Y levels of the layers to set +-- minp, maxp: minp, maxp of the on_generated +-- lvm_used: Set to true if any node in this on_generated has been set before. +-- +-- returns true if any node was set and lvm_used otherwise +local function set_layers(data, area, content_id, check, min, max, minp, maxp, lvm_used, pr) + if (maxp.y >= min and minp.y <= max) then + for y = math.max(min, minp.y), math.min(max, maxp.y) do + for x = minp.x, maxp.x do + for z = minp.z, maxp.z do + local p_pos = area:index(x, y, z) + if check then + if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos], pr) then + data[p_pos] = content_id lvm_used = true - - else - break - end - pos.y = pos.y + 1 - p_pos = area:index(pos.x, pos.y, pos.z) - treepos.y = treepos.y + 1 - end - else - -- Grow vines down, length between 1 and maxvinelength - local length = math.ceil(math.abs(perlin_vines_length:get_3d(pos)) * maxvinelength) - for l=0, length-1 do - if data[p_pos] == c_air then - data[p_pos] = c_vine - param2_data[p_pos] = param2 - lvm_used = true - - else - break - end - pos.y = pos.y - 1 - p_pos = area:index(pos.x, pos.y, pos.z) - end - end - end - end - - end - end - return lvm_used -end - -local pr_shroom = PseudoRandom(os.time()-24359) --- Generate mushrooms in caves manually. --- Minetest's API does not support decorations in caves yet. :-( -local generate_underground_mushrooms = function(minp, maxp, seed) - -- Generate rare underground mushrooms - -- TODO: Make them appear in groups, use Perlin noise - local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 - if minp.y > max or maxp.y < min then - return - end - - local bpos - local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) - - for n = 1, #stone do - bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } - - local l = minetest.get_node_light(bpos, 0.5) - if bpos.y >= min and bpos.y <= max and l ~= nil and l <= 12 and pr_shroom:next(1,1000) < 4 then - if pr_shroom:next(1,2) == 1 then - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) - else - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) - end - end - end -end - -local pr_nether = PseudoRandom(os.time()+667) -local nether_wart_chance -if mg_name == "v6" then - nether_wart_chance = 85 -else - nether_wart_chance = 170 -end --- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart --- Minetest's API does not support decorations in caves yet. :-( -local generate_nether_decorations = function(minp, maxp, seed) - if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then - return - end - - -- TODO: Generate everything based on Perlin noise instead of PseudoRandom - - local bpos - local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"}) - local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"}) - local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"}) - - -- Helper function to spawn “fake” decoration - local special_deco = function(nodes, spawn_func) - for n = 1, #nodes do - bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z } - - spawn_func(bpos) - end - - end - - -- Eternal fire on netherrack - special_deco(rack, function(bpos) - -- Eternal fire on netherrack - if pr_nether:next(1,100) <= 3 then - minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) - end - end) - - -- Eternal fire on magma cubes - special_deco(magma, function(bpos) - if pr_nether:next(1,150) == 1 then - minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) - end - end) - - -- Mushrooms on netherrack - -- Note: Spawned *after* the fire because of light level checks - special_deco(rack, function(bpos) - local l = minetest.get_node_light(bpos, 0.5) - if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l ~= nil and l <= 12 and pr_nether:next(1,1000) <= 4 then - -- TODO: Make mushrooms appear in groups, use Perlin noise - if pr_nether:next(1,2) == 1 then - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) - else - minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) - end - end - end) - - -- Nether wart on soul sand - -- TODO: Spawn in Nether fortresses - special_deco(ssand, function(bpos) - if pr_nether:next(1, nether_wart_chance) == 1 then - minetest.set_node(bpos, {name = "mcl_nether:nether_wart"}) - end - end) - -end - --- Below the bedrock, generate air/void -minetest.register_on_generated(function(minp, maxp, seed) - local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") - local data = vm:get_data(lvm_buffer) - local param2_data = vm:get_param2_data(lvm_buffer_param2) - local area = VoxelArea:new({MinEdge=emin, MaxEdge=emax}) - local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) - local lvm_used = false - local biomemap - - local ymin, ymax - - -- Generate basic layer-based nodes: void, bedrock, realm barrier, lava seas, etc. - -- Also perform some basic node replacements. - - -- Helper function to set all nodes in the layers between min and max. - -- content_id: Node to set - -- check: optional. - -- If content_id, node will be set only if it is equal to check. - -- If function(pos_to_check, content_id_at_this_pos), will set node only if returns true. - -- min, max: Minimum and maximum Y levels of the layers to set - -- minp, maxp: minp, maxp of the on_generated - -- lvm_used: Set to true if any node in this on_generated has been set before. - -- - -- returns true if any node was set and lvm_used otherwise - local function set_layers(content_id, check, min, max, minp, maxp, lvm_used) - if (maxp.y >= min and minp.y <= max) then - for y = math.max(min, minp.y), math.min(max, maxp.y) do - for x = minp.x, maxp.x do - for z = minp.z, maxp.z do - local p_pos = area:index(x, y, z) - if check then - if type(check) == "function" and check({x=x,y=y,z=z}, data[p_pos]) then - data[p_pos] = content_id - lvm_used = true - elseif check == data[p_pos] then - data[p_pos] = content_id - lvm_used = true - end - else + elseif check == data[p_pos] then data[p_pos] = content_id lvm_used = true end + else + data[p_pos] = content_id + lvm_used = true end end end end - return lvm_used end + return lvm_used +end - -- The Void - lvm_used = set_layers(c_void, nil, -31000, mcl_vars.mg_nether_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_nether_max+1, mcl_vars.mg_end_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_end_max+1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used) - lvm_used = set_layers(c_void, nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_vars.mg_overworld_min-1, minp, maxp, lvm_used) +local function set_grass_palette(minp,maxp,data2,area,biomemap,nodes) + -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: + if not biomemap then return end + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) + local nodes = minetest.find_nodes_in_area(minp, maxp, nodes) + for n=1, #nodes do + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + local b_pos = aream:index(n.x, 0, n.z) + local bn = minetest.get_biome_name(biomemap[b_pos]) + if bn then + local biome = minetest.registered_biomes[bn] + if biome and biome._mcl_biome_type and biome._mcl_grass_palette_index then + data2[p_pos] = biome._mcl_grass_palette_index + lvm_used = true + end + end + end + return lvm_used +end +local function set_foliage_palette(minp,maxp,data2,area,biomemap,nodes) + -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: + if not biomemap then return end + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) + local nodes = minetest.find_nodes_in_area(minp, maxp, nodes) + for n=1, #nodes do + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + local b_pos = aream:index(n.x, 0, n.z) + local bn = minetest.get_biome_name(biomemap[b_pos]) + if bn then + local biome = minetest.registered_biomes[bn] + if biome and biome._mcl_biome_type and biome._mcl_foliage_palette_index and data2[p_pos] <= 1 then + data2[p_pos] = biome._mcl_foliage_palette_index + lvm_used = true + elseif biome and biome._mcl_biome_type and biome._mcl_foliage_palette_index and data2[p_pos] > 1 then + data2[p_pos] = (biome._mcl_foliage_palette_index * 8) + data2[p_pos] + lvm_used = true + end + end + end + return lvm_used +end + +local function set_water_palette(minp,maxp,data2,area,biomemap,nodes) + -- Flat area at y=0 to read biome 3 times faster than 5.3.0.get_biome_data(pos).biome: 43us vs 125us per iteration: + if not biomemap then return end + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) + local nodes = minetest.find_nodes_in_area(minp, maxp, nodes) + for n=1, #nodes do + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + local b_pos = aream:index(n.x, 0, n.z) + local bn = minetest.get_biome_name(biomemap[b_pos]) + if bn then + local biome = minetest.registered_biomes[bn] + if biome and biome._mcl_biome_type and biome._mcl_water_palette_index then + data2[p_pos] = biome._mcl_water_palette_index + lvm_used = true + end + end + end + return lvm_used +end + +local function set_seagrass_param2(minp,maxp,data2,area,nodes) + local aream = VoxelArea:new({MinEdge={x=minp.x, y=0, z=minp.z}, MaxEdge={x=maxp.x, y=0, z=maxp.z}}) + local nodes = minetest.find_nodes_in_area(minp, maxp, nodes) + for n=1, #nodes do + local n = nodes[n] + local p_pos = area:index(n.x, n.y, n.z) + data2[p_pos] = 3 + lvm_used = true + end + return lvm_used +end + +-- Below the bedrock, generate air/void +local function world_structure(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap --ymin, ymax + local lvm_used = false + local pr = PseudoRandom(blockseed) + + -- The Void below the Nether: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mapgen_edge_min , mcl_vars.mg_nether_min -1, minp, maxp, lvm_used, pr) + + -- [[ 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 + 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) + + -- [[ THE END: mcl_vars.mg_end_min mcl_vars.mg_end_max ]] + + -- The Void above the End below the Realm barrier: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_end_max +1, mcl_vars.mg_realm_barrier_overworld_end_min-1, minp, maxp, lvm_used, pr) -- Realm barrier between the Overworld void and the End - lvm_used = set_layers(c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min, mcl_vars.mg_realm_barrier_overworld_end_max, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_realm_barrier, nil, mcl_vars.mg_realm_barrier_overworld_end_min , mcl_vars.mg_realm_barrier_overworld_end_max , minp, maxp, lvm_used, pr) + -- The Void above Realm barrier below the Overworld: + lvm_used = set_layers(data, area, c_void , nil, mcl_vars.mg_realm_barrier_overworld_end_max+1, mcl_vars.mg_overworld_min -1, minp, maxp, lvm_used, pr) + if mg_name ~= "singlenode" then -- Bedrock - local bedrock_check - if mcl_vars.mg_bedrock_is_rough then - bedrock_check = function(pos) - local y = pos.y - -- Bedrock layers with increasing levels of roughness, until a perfecly flat bedrock later at the bottom layer - -- This code assumes a bedrock height of 5 layers. - - local diff = mcl_vars.mg_bedrock_overworld_max - y -- Overworld bedrock - local ndiff1 = mcl_vars.mg_bedrock_nether_bottom_max - y -- Nether bedrock, bottom - local ndiff2 = mcl_vars.mg_bedrock_nether_top_max - y -- Nether bedrock, ceiling - - local top - if diff == 0 or ndiff1 == 0 or ndiff2 == 4 then - -- 50% bedrock chance - top = 2 - elseif diff == 1 or ndiff1 == 1 or ndiff2 == 3 then - -- 66.666...% - top = 3 - elseif diff == 2 or ndiff1 == 2 or ndiff2 == 2 then - -- 75% - top = 4 - elseif diff == 3 or ndiff1 == 3 or ndiff2 == 1 then - -- 90% - top = 10 - elseif diff == 4 or ndiff1 == 4 or ndiff2 == 0 then - -- 100% - return true - else - -- Not in bedrock layer - return false - end - - return math.random(1, top) <= top-1 - end - else - bedrock_check = nil - end - - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used) - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used) - lvm_used = set_layers(c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_overworld_min, mcl_vars.mg_bedrock_overworld_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_bottom_min, mcl_vars.mg_bedrock_nether_bottom_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_bedrock, bedrock_check, mcl_vars.mg_bedrock_nether_top_min, mcl_vars.mg_bedrock_nether_top_max, minp, maxp, lvm_used, pr) -- Flat Nether if mg_name == "flat" then - lvm_used = set_layers(c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used) + lvm_used = set_layers(data, area, c_air, nil, mcl_vars.mg_flat_nether_floor, mcl_vars.mg_flat_nether_ceiling, minp, maxp, lvm_used, pr) end -- Big lava seas by replacing air below a certain height if mcl_vars.mg_lava then - lvm_used = set_layers(c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, emin, emax, lvm_used) - lvm_used = set_layers(c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, emin, emax, lvm_used) + lvm_used = set_layers(data, area, c_lava, c_air, mcl_vars.mg_overworld_min, mcl_vars.mg_lava_overworld_max, minp, maxp, lvm_used, pr) + lvm_used = set_layers(data, area, c_nether_lava, c_air, mcl_vars.mg_nether_min, mcl_vars.mg_lava_nether_max, minp, maxp, lvm_used, pr) end + end + local deco = false + local ores = false + if minp.y > mcl_vars.mg_nether_deco_max - 64 and maxp.y < mcl_vars.mg_nether_max + 128 then + deco = {min=mcl_vars.mg_nether_deco_max,max=mcl_vars.mg_nether_max} + end + if minp.y < mcl_vars.mg_nether_min + 10 or maxp.y < mcl_vars.mg_nether_min + 60 then + deco = {min=mcl_vars.mg_nether_min - 10,max=mcl_vars.mg_nether_min + 20} + ores = {min=mcl_vars.mg_nether_min - 10,max=mcl_vars.mg_nether_min + 20} + end + return lvm_used, lvm_used, deco, ores +end - -- Clay, vines, cocoas - lvm_used = generate_clay(minp, maxp, seed, data, area, lvm_used) +local function block_fixes_grass(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap = minetest.get_mapgen_object("biomemap") + local lvm_used = false + local pr = PseudoRandom(blockseed) + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then + -- Set param2 (=color) of nodes which use the grass colour palette. + lvm_used = set_grass_palette(minp,maxp,data2,area,biomemap,{"group:grass_palette"}) + end + return lvm_used +end - biomemap = minetest.get_mapgen_object("biomemap") - lvm_used = generate_tree_decorations(minp, maxp, seed, data, param2_data, area, biomemap, lvm_used) +local function block_fixes_foliage(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap = minetest.get_mapgen_object("biomemap") + local lvm_used = false + local pr = PseudoRandom(blockseed) + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then + -- Set param2 (=color) of nodes which use the foliage colour palette. + lvm_used = set_foliage_palette(minp,maxp,data2,area,biomemap,{"group:foliage_palette", "group:foliage_palette_wallmounted"}) + end + return lvm_used +end - ----- Interactive block fixing section ----- - ----- The section to perform basic block overrides of the core mapgen generated world. ----- +local function block_fixes_water(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local biomemap = minetest.get_mapgen_object("biomemap") + local lvm_used = false + local pr = PseudoRandom(blockseed) + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then + -- Set param2 (=color) of nodes which use the water colour palette. + lvm_used = set_water_palette(minp,maxp,data2,area,biomemap,{"group:water_palette"}) + end + return lvm_used +end - -- Snow and sand fixes. This code implements snow consistency - -- and fixes floating sand and cut plants. - -- A snowy grass block must be below a top snow or snow block at all times. - if emin.y <= mcl_vars.mg_overworld_max and emax.y >= mcl_vars.mg_overworld_min then - -- v6 mapgen: - if mg_name == "v6" then +local function block_fixes_seagrass(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + local lvm_used = false + local pr = PseudoRandom(blockseed) + if minp.y <= mcl_vars.mg_overworld_max and maxp.y >= mcl_vars.mg_overworld_min then + -- Set param2 of seagrass to 3. + lvm_used = set_seagrass_param2(minp, maxp, data2, area, {"group:seagrass"}) + end + return lvm_used +end - --[[ Remove broken double plants caused by v6 weirdness. - v6 might break the bottom part of double plants because of how it works. - There are 3 possibilities: - 1) Jungle: Top part is placed on top of a jungle tree or fern (=v6 jungle grass). - This is because the schematic might be placed even if some nodes of it - could not be placed because the destination was already occupied. - TODO: A better fix for this would be if schematics could abort placement - altogether if ANY of their nodes could not be placed. - 2) Cavegen: Removes the bottom part, the upper part floats - 3) Mudflow: Same as 2) ]] - local plants = minetest.find_nodes_in_area(emin, emax, "group:double_plant") - for n = 1, #plants do - local node = vm:get_node_at(plants[n]) - local is_top = minetest.get_item_group(node.name, "double_plant") == 2 - if is_top then - local p_pos = area:index(plants[n].x, plants[n].y-1, plants[n].z) - if p_pos then - node = vm:get_node_at({x=plants[n].x, y=plants[n].y-1, z=plants[n].z}) - local is_bottom = minetest.get_item_group(node.name, "double_plant") == 1 - if not is_bottom then - p_pos = area:index(plants[n].x, plants[n].y, plants[n].z) - data[p_pos] = c_air - lvm_used = true - end - end - end - end - - - -- Non-v6 mapgens: - else - -- Set param2 (=color) of grass blocks. - -- Clear snowy grass blocks without snow above to ensure consistency. - local nodes = minetest.find_nodes_in_area(minp, maxp, {"mcl_core:dirt_with_grass", "mcl_core:dirt_with_grass_snow"}) - for n=1, #nodes do - local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) - local p_pos_above = area:index(nodes[n].x, nodes[n].y+1, nodes[n].z) - local p_pos_below = area:index(nodes[n].x, nodes[n].y-1, nodes[n].z) - local b_pos = aream:index(nodes[n].x, 0, nodes[n].z) - local bn = minetest.get_biome_name(biomemap[b_pos]) - if bn then - local biome = minetest.registered_biomes[bn] - if biome then - if biome._mcl_biome_type then - param2_data[p_pos] = biome._mcl_palette_index - lvm_used = true - end - end - end - if data[p_pos] == c_dirt_with_grass_snow and p_pos_above and data[p_pos_above] ~= c_top_snow and data[p_pos_above] ~= c_snow_block then - data[p_pos] = c_dirt_with_grass - lvm_used = true - end - end - end - - -- Nether block fixes: - -- * Replace water with Nether lava. - -- * Replace stone, sand dirt in v6 so the Nether works in v6. - elseif emin.y <= mcl_vars.mg_nether_max and emax.y >= mcl_vars.mg_nether_min then - local nodes - if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) - else - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) - end - for n=1, #nodes do - local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) - if data[p_pos] == c_water then - data[p_pos] = c_nether_lava - lvm_used = true - elseif data[p_pos] == c_stone then - data[p_pos] = c_netherrack - lvm_used = true - elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then - data[p_pos] = c_soul_sand - lvm_used = true - end - end - - -- End block fixes: - -- * Replace water with end stone or air (depending on height). - -- * Remove stone, sand, dirt in v6 so our End map generator works in v6. - -- * Generate spawn platform (End portal destination) - elseif emin.y <= mcl_vars.mg_end_max and emax.y >= mcl_vars.mg_end_min then - local nodes - if mg_name == "v6" then - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) - else - nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) - end - for n=1, #nodes do - local y = nodes[n].y - local p_pos = area:index(nodes[n].x, y, nodes[n].z) - - if data[p_pos] == c_water or data[p_pos] == c_stone or data[p_pos] == c_dirt or data[p_pos] == c_sand then - data[p_pos] = c_air - lvm_used = true - end - - end - - -- Obsidian spawn platform - if minp.y <= mcl_vars.mg_end_platform_pos.y and maxp.y >= mcl_vars.mg_end_platform_pos.y and - minp.x <= mcl_vars.mg_end_platform_pos.x and maxp.x >= mcl_vars.mg_end_platform_pos.z and - minp.z <= mcl_vars.mg_end_platform_pos.z and maxp.z >= mcl_vars.mg_end_platform_pos.z then - for x=math.max(minp.x, mcl_vars.mg_end_platform_pos.x-2), math.min(maxp.x, mcl_vars.mg_end_platform_pos.x+2) do - for z=math.max(minp.z, mcl_vars.mg_end_platform_pos.z-2), math.min(maxp.z, mcl_vars.mg_end_platform_pos.z+2) do - for y=math.max(minp.y, mcl_vars.mg_end_platform_pos.y), math.min(maxp.y, mcl_vars.mg_end_platform_pos.y+2) do - local p_pos = area:index(x, y, z) - if y == mcl_vars.mg_end_platform_pos.y then - data[p_pos] = c_obsidian - else - data[p_pos] = c_air - end - end - end - end - lvm_used = true +-- End block fixes: +local function end_basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if maxp.y < mcl_vars.mg_end_min or minp.y > mcl_vars.mg_end_max then return end + local biomemap --ymin, ymax + local lvm_used = false + local pr = PseudoRandom(blockseed) + local nodes + if mg_name ~= "v6" then + nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source"}) + if #nodes > 0 then + lvm_used = true + for _,n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air end end end + return true, false +end - -- Final hackery: Set sun light level in the End. - -- -26912 is at a mapchunk border. - local shadow - if minp.y >= -26912 and maxp.y <= mcl_vars.mg_end_max then - vm:set_lighting({day=15, night=15}) - lvm_used = true - end - if minp.y >= mcl_vars.mg_end_min and maxp.y <= -26911 then - shadow = false - lvm_used = true - end - -- Write stuff - if lvm_used then - vm:set_data(data) - vm:set_param2_data(param2_data) - vm:calc_lighting(nil, nil, shadow) - vm:write_to_map() - vm:update_liquids() - end +mcl_mapgen_core.register_generator("world_structure", world_structure, nil, 1, true) +mcl_mapgen_core.register_generator("end_fixes", end_basic, function(minp,maxp) + if maxp.y < mcl_vars.mg_end_min or minp.y > mcl_vars.mg_end_max then return end +end, 9999, true) - if mg_name ~= "singlenode" then - -- Generate special decorations - generate_underground_mushrooms(minp, maxp, seed) - generate_nether_decorations(minp, maxp, seed) - generate_structures(minp, maxp, seed, biomemap) +if mg_name ~= "v6" and mg_name ~= "singlenode" then + mcl_mapgen_core.register_generator("block_fixes_grass", block_fixes_grass, nil, 9999, true) + mcl_mapgen_core.register_generator("block_fixes_foliage", block_fixes_foliage, nil, 9999, true) + mcl_mapgen_core.register_generator("block_fixes_water", block_fixes_water, nil, 9999, true) + mcl_mapgen_core.register_generator("block_fixes_seagrass", block_fixes_seagrass, nil, 9999, true) +end + +if mg_name == "v6" then + dofile(modpath.."/v6.lua") +end + +-- This should be moved to mcl_structures eventually if the dependencies can be sorted out. +mcl_mapgen_core.register_generator("structures",nil, function(minp, maxp, blockseed) + local gennotify = minetest.get_mapgen_object("gennotify") + local has_struct = {} + local has = false + local poshash = minetest.hash_node_position(minp) + for _,struct in pairs(mcl_structures.registered_structures) do + local pr = PseudoRandom(blockseed + 42) + if struct.deco_id then + for _, pos in pairs(gennotify["decoration#"..struct.deco_id] or {}) do + local realpos = vector.offset(pos,0,1,0) + minetest.remove_node(realpos) + minetest.fix_light(vector.offset(pos,-1,-1,-1),vector.offset(pos,1,3,1)) + if struct.chunk_probability == nil or (not has and pr:next(1,struct.chunk_probability) == 1 ) then + mcl_structures.place_structure(realpos,struct,pr,blockseed) + has=true + end + end + elseif struct.static_pos then + for _,p in pairs(struct.static_pos) do + if in_cube(p,minp,maxp) then + mcl_structures.place_structure(p,struct,pr,blockseed) + end + end + end end + return false, false, false +end, 100, true) + +minetest.register_lbm({ + label = "Fix grass palette indexes", -- This LBM fixes any incorrect grass palette indexes. + name = "mcl_mapgen_core:fix_grass_palette_indexes", + nodenames = {"group:grass_palette"}, + run_at_every_load = false, + action = function(pos, node) + local grass_palette_index = mcl_util.get_palette_indexes_from_pos(pos).grass_palette_index + if node.param2 ~= grass_palette_index then + node.param2 = grass_palette_index + minetest.set_node(pos, node) + end + end +}) + +minetest.register_lbm({ + label = "Fix foliage palette indexes", -- Set correct palette indexes of foliage in old mapblocks. + name = "mcl_mapgen_core:fix_foliage_palette_indexes", + nodenames = {"group:foliage_palette", "group:foliage_palette_wallmounted"}, + run_at_every_load = false, + action = function(pos, node) + local foliage_palette_index = mcl_util.get_palette_indexes_from_pos(pos).foliage_palette_index + local noplconvert = {"mcl_mangrove:mangroveleaves", "mcl_core:vine"} -- These do not convert into player leaves. + if node.param2 == 1 and node.name ~= noplconvert then -- Convert old player leaves into the new versions. + node.param2 = foliage_palette_index + minetest.remove_node(pos) -- Required, since otherwise this conversion won't work. + minetest.place_node(vector.offset(pos, 0, 1, 0), node) -- Offset required, since otherwise the leaves sink one node for some reason. + elseif node.param2 ~= foliage_palette_index and node.name ~= "mcl_core:vine" then + node.param2 = foliage_palette_index + minetest.set_node(pos, node) + elseif node.name == "mcl_core:vine" then + local biome_param2 = foliage_palette_index + local rotation_param2 = mcl_util.get_colorwallmounted_rotation(pos) + local final_param2 = (biome_param2 * 8) + rotation_param2 + if node.param2 ~= final_param2 then + node.param2 = final_param2 + minetest.set_node(pos, node) + end + end + end +}) + +minetest.register_lbm({ + label = "Fix water palette indexes", -- Set correct palette indexes of water in old mapblocks. + name = "mcl_mapgen_core:fix_water_palette_indexes", + nodenames = {"group:water_palette"}, + run_at_every_load = false, + action = function(pos, node) + local water_palette_index = mcl_util.get_palette_indexes_from_pos(pos).water_palette_index + if node.param2 ~= water_palette_index then + node.param2 = water_palette_index + minetest.set_node(pos, node) + end + end +}) + +minetest.register_lbm({ + label = "Fix incorrect seagrass", -- Set correct param2 of seagrass in old mapblocks. + name = "mcl_mapgen_core:fix_incorrect_seagrass", + nodenames = {"group:seagrass"}, + run_at_every_load = false, + action = function(pos, node) + if node.param2 ~= 3 then + node.param2 = 3 + minetest.set_node(pos, node) + end + end +}) + +-- We go outside x and y for where trees are placed next to a biome that has already been generated. +-- We go above maxp.y because trees can often get placed close to the top of a generated area and folliage may not +-- be coloured correctly. +local function fix_folliage_missed (minp, maxp) + local pos1, pos2 = vector.offset(minp, -6, 0, -6), vector.offset(maxp, 6, 14, 6) + local foliage = minetest.find_nodes_in_area(pos1, pos2, {"group:foliage_palette", "group:foliage_palette_wallmounted"}) + for _, fpos in pairs(foliage) do + local fnode = minetest.get_node(fpos) + local foliage_palette_index = mcl_util.get_palette_indexes_from_pos(fpos).foliage_palette_index + if fnode.param2 ~= foliage_palette_index and fnode.name ~= "mcl_core:vine" then + fnode.param2 = foliage_palette_index + minetest.set_node(fpos, fnode) + elseif fnode.name == "mcl_core:vine" then + local biome_param2 = foliage_palette_index + local rotation_param2 = mcl_util.get_colorwallmounted_rotation(fpos) + local final_param2 = (biome_param2 * 8) + rotation_param2 + if fnode.param2 ~= final_param2 then + fnode.param2 = final_param2 + minetest.set_node(fpos, fnode) + end + end + end +end + +minetest.register_on_generated(function(minp, maxp, blockseed) -- Set correct palette indexes of missed foliage. + if maxp.y < 0 then + return + end + fix_folliage_missed (minp, maxp) end) - - diff --git a/mods/MAPGEN/mcl_mapgen_core/mod.conf b/mods/MAPGEN/mcl_mapgen_core/mod.conf index 5b5419c32..6c001c1e3 100644 --- a/mods/MAPGEN/mcl_mapgen_core/mod.conf +++ b/mods/MAPGEN/mcl_mapgen_core/mod.conf @@ -1 +1,5 @@ name = mcl_mapgen_core +author = Wuzzy +description = The core of the MCL2 mapgen +depends = mcl_init, mcl_core, mcl_deepslate, biomeinfo, mcl_worlds, mcl_cocoas, mcl_sponges, mcl_ocean, mcl_stairs, mcl_monster_eggs, mcl_structures +optional_depends = mclx_core, mcl_copper diff --git a/mods/MAPGEN/mcl_mapgen_core/ores.lua b/mods/MAPGEN/mcl_mapgen_core/ores.lua new file mode 100644 index 000000000..403c0333d --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/ores.lua @@ -0,0 +1,816 @@ + +local deepslate_max = mcl_worlds.layer_to_y(16) +local deepslate_min = mcl_vars.mg_overworld_min + +local copper_mod = minetest.get_modpath("mcl_copper") + +local mg_name = minetest.get_mapgen_setting("mg_name") +local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" + +local mountains = { + "ExtremeHills", "ExtremeHills_beach", "ExtremeHills_ocean", "ExtremeHills_deep_ocean", "ExtremeHills_underground", + "ExtremeHills+", "ExtremeHills+_ocean", "ExtremeHills+_deep_ocean", "ExtremeHills+_underground", + "ExtremeHillsM", "ExtremeHillsM_ocean", "ExtremeHillsM_deep_ocean", "ExtremeHillsM_underground", +} + +--Clay +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:clay", + wherein = {"mcl_core:sand","mcl_core:stone","mcl_core:gravel"}, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 5, + y_min = -5, + y_max = 0, + noise_params = { + offset = 0, + scale = 1, + spread = {x=250, y=250, z=250}, + seed = 34843, + octaves = 3, + persist = 0.6, + lacunarity = 2, + flags = "defaults", + } +}) + +-- Diorite, andesite and granite +local specialstones = { "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } +for s=1, #specialstones do + local node = specialstones[s] + minetest.register_ore({ + ore_type = "blob", + ore = node, + wherein = {"mcl_core:stone"}, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 5, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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 = node, + wherein = {"mcl_core:stone"}, + clust_scarcity = 10*10*10, + clust_num_ores = 58, + clust_size = 7, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + } + }) +end + +local stonelike = {"mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite"} + +-- Dirt +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:dirt", + wherein = stonelike, + clust_scarcity = 15*15*15, + clust_num_ores = 33, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_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", + } +}) + +-- Gravel +minetest.register_ore({ + ore_type = "blob", + ore = "mcl_core:gravel", + wherein = stonelike, + clust_scarcity = 14*14*14, + clust_num_ores = 33, + clust_size = 5, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(111), + 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: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", + wherein = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_deepslate:deepslate" }, + clust_scarcity = 10*10*10, + clust_num_ores = 58, + clust_size = 7, + 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", + } +}) + +-- DEEPSLATE +if minetest.settings:get_bool("mcl_generate_deepslate", true) then + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_deepslate:infested_deepslate", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 26 * 26 * 26, + clust_num_ores = 3, + clust_size = 2, + y_min = deepslate_min, + y_max = deepslate_max, + biomes = mountains, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:water_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(5), + y_max = deepslate_max, + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 2000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(1), + y_max = mcl_worlds.layer_to_y(10), + }) + + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = "mcl_deepslate:deepslate", + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(11), + y_max = deepslate_max, + }) + +end + +if minetest.settings:get_bool("mcl_generate_ores", true) then + -- + -- Coal + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 525*3, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 510*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 12, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(50), + }) + + -- Medium-rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 525*3, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(51), + y_max = mcl_worlds.layer_to_y(80), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 600*3, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 550*3, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_coal", + wherein = stonelike, + clust_scarcity = 500*3, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(81), + y_max = mcl_worlds.layer_to_y(128), + }) + + -- + -- Iron + -- + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(39), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_iron", + wherein = stonelike, + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(40), + y_max = mcl_worlds.layer_to_y(63), + }) + + -- + -- Gold + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 4775, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 6560, + clust_num_ores = 7, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(30), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_gold", + wherein = stonelike, + clust_scarcity = 13000, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(31), + y_max = mcl_worlds.layer_to_y(33), + }) + + -- + -- Diamond + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 5000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 8, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(12), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_diamond", + wherein = stonelike, + clust_scarcity = 20000, + clust_num_ores = 2, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Ancient debris + -- + local ancient_debris_wherein = {"mcl_nether:netherrack","mcl_blackstone:blackstone","mcl_blackstone:basalt"} + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 25000, -- 0.004% chance + clust_num_ores = 3, + clust_size = 3, + y_min = mcl_vars.mg_nether_min + 8, + y_max = mcl_vars.mg_nether_min + 22, + }) + + -- Rare spawn (below) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 32000, + clust_num_ores = 2, + clust_size = 3, + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_min + 8, + }) + + -- Rare spawn (above) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_nether:ancient_debris", + wherein = ancient_debris_wherein, + clust_scarcity = 32000, + clust_num_ores = 2, + clust_size = 3, + y_min = mcl_vars.mg_nether_min + 22, + y_max = mcl_vars.mg_nether_min + 119, + }) + + -- + -- Redstone + -- + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 500, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 800, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(13), + }) + + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_redstone", + wherein = stonelike, + clust_scarcity = 1600, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(13), + y_max = mcl_worlds.layer_to_y(15), + }) + + -- + -- Emerald + -- + + if mg_name == "v6" then + -- Generate everywhere in v6, but rarely. + + -- Common spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 14340, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(29), + }) + -- Rare spawn + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_emerald", + wherein = stonelike, + clust_scarcity = 21510, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(30), + y_max = mcl_worlds.layer_to_y(32), + }) + end + + -- + -- Lapis Lazuli + -- + + -- Common spawn (in the center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 7000, + clust_num_ores = 7, + clust_size = 4, + y_min = mcl_worlds.layer_to_y(14), + y_max = mcl_worlds.layer_to_y(16), + }) + + -- Rare spawn (below center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(10), + y_max = mcl_worlds.layer_to_y(13), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(6), + y_max = mcl_worlds.layer_to_y(9), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 16000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(2), + y_max = mcl_worlds.layer_to_y(5), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(0), + y_max = mcl_worlds.layer_to_y(2), + }) + + -- Rare spawn (above center) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 10000, + clust_num_ores = 6, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(17), + y_max = mcl_worlds.layer_to_y(20), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 12000, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(21), + y_max = mcl_worlds.layer_to_y(24), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 14000, + clust_num_ores = 4, + clust_size = 3, + y_min = mcl_worlds.layer_to_y(25), + y_max = mcl_worlds.layer_to_y(28), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 18000, + clust_num_ores = 3, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(29), + y_max = mcl_worlds.layer_to_y(32), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:stone_with_lapis", + wherein = stonelike, + clust_scarcity = 28000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(31), + y_max = mcl_worlds.layer_to_y(32), + }) + + if minetest.settings:get_bool("mcl_generate_deepslate", true) then + local stonelike = { "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite" } + local function register_ore_mg(ore, scarcity, num, size, y_min, y_max, biomes) + biomes = biomes or "" + minetest.register_ore({ + ore_type = "scatter", + ore = ore, + wherein = { "mcl_deepslate:deepslate", "mcl_deepslate:tuff" }, + clust_scarcity = scarcity, + clust_num_ores = num, + clust_size = size, + y_min = y_min, + y_max = y_max, + biomes = biomes, + }) + end + local ore_mapgen = { + { "coal", 1575, 5, 3, deepslate_min, deepslate_max }, + { "coal", 1530, 8, 3, deepslate_min, deepslate_max }, + { "coal", 1500, 12, 3, deepslate_min, deepslate_max }, + { "iron", 830, 5, 3, deepslate_min, deepslate_max }, + { "gold", 4775, 5, 3, deepslate_min, deepslate_max }, + { "gold", 6560, 7, 3, deepslate_min, deepslate_max }, + { "diamond", 10000, 4, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 5000, 2, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 10000, 8, 3, deepslate_min, mcl_worlds.layer_to_y(12) }, + { "diamond", 20000, 1, 1, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "diamond", 20000, 2, 2, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "redstone", 500, 4, 3, deepslate_min, mcl_worlds.layer_to_y(13) }, + { "redstone", 800, 7, 4, deepslate_min, mcl_worlds.layer_to_y(13) }, + { "redstone", 1000, 4, 3, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "redstone", 1600, 7, 4, mcl_worlds.layer_to_y(13), mcl_worlds.layer_to_y(15) }, + { "lapis", 10000, 7, 4, mcl_worlds.layer_to_y(14), deepslate_max }, + { "lapis", 12000, 6, 3, mcl_worlds.layer_to_y(10), mcl_worlds.layer_to_y(13) }, + { "lapis", 14000, 5, 3, mcl_worlds.layer_to_y(6), mcl_worlds.layer_to_y(9) }, + { "lapis", 16000, 4, 3, mcl_worlds.layer_to_y(2), mcl_worlds.layer_to_y(5) }, + { "lapis", 18000, 3, 2, mcl_worlds.layer_to_y(0), mcl_worlds.layer_to_y(2) }, + } + for _, o in pairs(ore_mapgen) do + register_ore_mg("mcl_deepslate:deepslate_with_"..o[1], o[2], o[3], o[4], o[5], o[6]) + end + if minetest.get_mapgen_setting("mg_name") == "v6" then + register_ore_mg("mcl_deepslate:deepslate_with_emerald", 14340, 1, 1, deepslate_min, deepslate_max) + else + register_ore_mg("mcl_deepslate:deepslate_with_emerald", 16384, 1, 1, mcl_worlds.layer_to_y(4), deepslate_max, mountains) + end + if copper_mod then + register_ore_mg("mcl_deepslate:deepslate_with_copper", 830, 5, 3, deepslate_min, deepslate_max) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_copper:stone_with_copper", + wherein = stonelike, + clust_scarcity = 830, + clust_num_ores = 5, + clust_size = 3, + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_worlds.layer_to_y(39), + }) + minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_copper:stone_with_copper", + wherein = stonelike, + clust_scarcity = 1660, + clust_num_ores = 4, + clust_size = 2, + y_min = mcl_worlds.layer_to_y(40), + y_max = mcl_worlds.layer_to_y(63), + }) + end + end +end + +if not superflat then +-- Water and lava springs (single blocks of lava/water source) +-- Water appears at nearly every height, but not near the bottom +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:water_source", + wherein = {"mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:dirt"}, + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(5), + y_max = mcl_worlds.layer_to_y(128), +}) + +-- Lava springs are rather common at -31 and below +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 2000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(1), + y_max = mcl_worlds.layer_to_y(10), +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 9000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(11), + y_max = mcl_worlds.layer_to_y(31), +}) + +-- Lava springs will become gradually rarer with increasing height +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 32000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(32), + y_max = mcl_worlds.layer_to_y(47), +}) + +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 72000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(48), + y_max = mcl_worlds.layer_to_y(61), +}) + +-- Lava may even appear above surface, but this is very rare +minetest.register_ore({ + ore_type = "scatter", + ore = "mcl_core:lava_source", + wherein = stonelike, + clust_scarcity = 96000, + clust_num_ores = 1, + clust_size = 1, + y_min = mcl_worlds.layer_to_y(62), + y_max = mcl_worlds.layer_to_y(127), +}) +end diff --git a/mods/MAPGEN/mcl_mapgen_core/v6.lua b/mods/MAPGEN/mcl_mapgen_core/v6.lua new file mode 100644 index 000000000..bfdc14c06 --- /dev/null +++ b/mods/MAPGEN/mcl_mapgen_core/v6.lua @@ -0,0 +1,832 @@ +local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor + +local function register_mgv6_decorations() + -- Cacti + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand"}, + sidelen = 16, + noise_params = { + offset = -0.012, + scale = 0.024, + spread = {x = 100, y = 100, z = 100}, + seed = 257, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:cactus", + height = 1, + height_max = 3, + }) + + -- Sugar canes + minetest.register_decoration({ + deco_type = "simple", + place_on = {"mcl_core:dirt", "mcl_core:coarse_dirt", "group:grass_block_no_snow", "group:sand", "mcl_core:podzol", "mcl_core:reeds"}, + sidelen = 16, + noise_params = { + offset = -0.3, + scale = 0.7, + spread = {x = 100, y = 100, z = 100}, + seed = 465, + octaves = 3, + persist = 0.7 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:reeds", + height = 1, + height_max = 3, + spawn_by = { "mcl_core:water_source", "group:frosted_ice" }, + num_spawn_by = 1, + }) + + -- Doubletall grass + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_grass", param1 = 255, }, + { name = "mcl_flowers:double_grass_top", param1 = 255, }, + }, + }, + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = -0.0025, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.0, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + }) + + -- Large ferns + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:double_fern", param1=255, }, + { name = "mcl_flowers:double_fern_top", param1=255, }, + }, + }, + -- v6 hack: This makes sure large ferns only appear in jungles + spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, + num_spawn_by = 1, + place_on = {"group:grass_block_no_snow"}, + + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.01, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 2, + persist = 0.66, + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + }) + + -- Large flowers + local function register_large_flower(name, seed, offset) + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "air", prob = 0 }, + { name = "mcl_flowers:"..name, param1=255, }, + { name = "mcl_flowers:"..name.."_top", param1=255, }, + }, + }, + place_on = {"group:grass_block_no_snow"}, + + sidelen = 16, + noise_params = { + offset = offset, + scale = 0.01, + spread = {x = 300, y = 300, z = 300}, + seed = seed, + octaves = 5, + persist = 0.62, + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + flags = "", + }) + end + + register_large_flower("rose_bush", 9350, -0.008) + register_large_flower("peony", 10450, -0.008) + register_large_flower("lilac", 10600, -0.007) + register_large_flower("sunflower", 2940, -0.005) + + -- Lily pad + minetest.register_decoration({ + deco_type = "schematic", + schematic = { + size = { x=1, y=3, z=1 }, + data = { + { name = "mcl_core:water_source", prob = 0 }, + { name = "mcl_core:water_source" }, + { name = "mcl_flowers:waterlily", param1 = 255 }, + }, + }, + place_on = "mcl_core:dirt", + sidelen = 16, + noise_params = { + offset = -0.12, + scale = 0.3, + spread = {x = 200, y = 200, z = 200}, + seed = 503, + octaves = 6, + persist = 0.7, + }, + y_min = 0, + y_max = 0, + rotation = "random", + }) + + -- Pumpkin + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_farming:pumpkin", + param2 = 0, + param2_max = 3, + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = -0.008, + scale = 0.00666, + spread = {x = 250, y = 250, z = 250}, + seed = 666, + octaves = 6, + persist = 0.666 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + }) + + -- Melon + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = 0.002, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 333, + octaves = 3, + persist = 0.6 + }, + -- Small trick to make sure melon spawn in jungles + spawn_by = { "mcl_core:jungletree", "mcl_flowers:fern" }, + num_spawn_by = 1, + y_min = 1, + y_max = 40, + decoration = "mcl_farming:melon", + }) + + -- Tall grass + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = 0.01, + scale = 0.3, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + noise_params = { + offset = 0.04, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 420, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + + -- Seagrass and kelp + local materials = {"dirt","sand"} + for i=1, #materials do + local mat = materials[i] + + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 8, + noise_params = { + offset = 0.04, + scale = 0.3, + spread = {x = 100, y = 100, z = 100}, + seed = 421, + octaves = 3, + persist = 0.6 + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = 0, + decoration = "mcl_ocean:seagrass_"..mat, + }) + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:mat"}, + sidelen = 8, + noise_params = { + offset = 0.08, + scale = 0.03, + spread = {x = 100, y = 100, z = 100}, + seed = 421, + octaves = 3, + persist = 0.6 + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -5, + decoration = "mcl_ocean:seagrass_"..mat, + }) + + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.01, + spread = {x = 300, y = 300, z = 300}, + seed = 505, + octaves = 5, + persist = 0.62, + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -6, + decoration = "mcl_ocean:kelp_"..mat, + param2 = 16, + param2_max = 96, + }) + minetest.register_decoration({ + deco_type = "simple", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:"..mat}, + sidelen = 16, + noise_params = { + offset = 0.01, + scale = 0.01, + spread = {x = 100, y = 100, z = 100}, + seed = 506, + octaves = 5, + persist = 0.62, + }, + flags = "force_placement", + place_offset_y = -1, + y_min = mcl_vars.overworld_min, + y_max = -15, + decoration = "mcl_ocean:kelp_"..mat, + param2 = 32, + param2_max = 160, + }) + + end + + -- Wet Sponge + -- TODO: Remove this when we got ocean monuments + minetest.register_decoration({ + deco_type = "simple", + decoration = "mcl_sponges:sponge_wet", + spawn_by = {"group:water"}, + num_spawn_by = 1, + place_on = {"mcl_core:dirt","mcl_core:sand"}, + sidelen = 16, + noise_params = { + offset = 0.00295, + scale = 0.006, + spread = {x = 250, y = 250, z = 250}, + seed = 999, + octaves = 3, + persist = 0.666 + }, + flags = "force_placement", + y_min = mcl_vars.mg_lava_overworld_max + 5, + y_max = -20, + }) + + -- Add a small amount of tall grass everywhere to avoid areas completely empty devoid of tall grass + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 8, + fill_ratio = 0.004, + y_min = 1, + y_max = mcl_vars.overworld_max, + decoration = "mcl_flowers:tallgrass", + }) + + local mushrooms = {"mcl_mushrooms:mushroom_red", "mcl_mushrooms:mushroom_brown"} + local mseeds = { 7133, 8244 } + for m=1, #mushrooms do + -- Mushrooms next to trees + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow", "mcl_core:dirt", "mcl_core:podzol", "mcl_core:mycelium", "mcl_core:stone", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite"}, + sidelen = 16, + noise_params = { + offset = 0.04, + scale = 0.04, + spread = {x = 100, y = 100, z = 100}, + seed = mseeds[m], + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = mushrooms[m], + spawn_by = { "mcl_core:tree", "mcl_core:sprucetree", "mcl_core:darktree", "mcl_core:birchtree", }, + num_spawn_by = 1, + }) + end + + -- Dead bushes + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:sand", "mcl_core:podzol", "mcl_core:dirt", "mcl_core:coarse_dirt", "group:hardened_clay"}, + sidelen = 16, + noise_params = { + offset = 0, + scale = 0.035, + spread = {x = 100, y = 100, z = 100}, + seed = 1972, + octaves = 3, + persist = 0.6 + }, + y_min = 4, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:deadbush", + }) + + local function register_mgv6_flower(name, seed, offset, y_max) + if offset == nil then + offset = 0 + end + if y_max == nil then + y_max = mcl_vars.mg_overworld_max + end + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_no_snow"}, + sidelen = 16, + noise_params = { + offset = offset, + scale = 0.006, + spread = {x = 100, y = 100, z = 100}, + seed = seed, + octaves = 3, + persist = 0.6 + }, + y_min = 1, + y_max = y_max, + decoration = "mcl_flowers:"..name, + }) + end + + register_mgv6_flower("tulip_red", 436) + register_mgv6_flower("tulip_orange", 536) + register_mgv6_flower("tulip_pink", 636) + register_mgv6_flower("tulip_white", 736) + register_mgv6_flower("azure_bluet", 800) + register_mgv6_flower("dandelion", 8) + -- Allium is supposed to only appear in flower forest in MC. There are no flower forests in v6. + -- We compensate by making it slightly rarer in v6. + register_mgv6_flower("allium", 0, -0.001) + --[[ Blue orchid is supposed to appear in swamplands. There are no swamplands in v6. + We emulate swamplands by limiting the height to 5 levels above sea level, + which should be close to the water. ]] + register_mgv6_flower("blue_orchid", 64500, nil, mcl_worlds.layer_to_y(67)) + register_mgv6_flower("oxeye_daisy", 3490) + register_mgv6_flower("poppy", 9439) + + -- Put top snow on snowy grass blocks. The v6 mapgen does not generate the top snow on its own. + minetest.register_decoration({ + deco_type = "simple", + place_on = {"group:grass_block_snow"}, + sidelen = 16, + fill_ratio = 11.0, -- complete coverage + y_min = 1, + y_max = mcl_vars.mg_overworld_max, + decoration = "mcl_core:snow", + }) + +end +register_mgv6_decorations() + +local function generate_mgv6_structures() + local chunk_has_igloo = false + local struct_min, struct_max = -3, 111 --64 + --except end exit portall all v6 + if maxp.y >= struct_min and minp.y <= struct_max then + -- Generate structures + local pr = PcgRandom(blockseed) + perlin_structures = perlin_structures or minetest.get_perlin(329, 3, 0.6, 100) + -- Assume X and Z lengths are equal + local divlen = 5 + for x0 = minp.x, maxp.x, divlen do for z0 = minp.z, maxp.z, divlen do + -- Determine amount from perlin noise + local amount = math.floor(perlin_structures:get_2d({x=x0, y=z0}) * 9) + -- Find random positions based on this random + local p, ground_y + for i=0, amount do + p = {x = pr:next(x0, x0+divlen-1), y = 0, z = pr:next(z0, z0+divlen-1)} + -- Find ground level + ground_y = nil + local nn + for y = struct_max, struct_min, -1 do + p.y = y + local checknode = minetest.get_node(p) + if checknode then + nn = checknode.name + local def = minetest.registered_nodes[nn] + if def and def.walkable then + ground_y = y + break + end + end + end + + if ground_y then + p.y = ground_y+1 + local nn0 = minetest.get_node(p).name + -- Check if the node can be replaced + if minetest.registered_nodes[nn0] and minetest.registered_nodes[nn0].buildable_to then + -- Igloos + if not chunk_has_igloo and (nn == "mcl_core:snowblock" or nn == "mcl_core:snow" or (minetest.get_item_group(nn, "grass_block_snow") == 1)) then + if pr:next(1, 4400) == 1 then + -- Check surface + local floor = {x=p.x+9, y=p.y-1, z=p.z+9} + local surface = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:snowblock") + local surface2 = minetest.find_nodes_in_area({x=p.x,y=p.y-1,z=p.z}, floor, "mcl_core:dirt_with_grass_snow") + if #surface + #surface2 >= 63 then + mcl_structures.call_struct(p, "igloo", nil, pr) + chunk_has_igloo = true + end + end + end + + -- Fossil + if nn == "mcl_core:sandstone" or nn == "mcl_core:sand" and not chunk_has_desert_temple and ground_y > 3 then + local fossil_prob = minecraft_chunk_probability(64, minp, maxp) + + if pr:next(1, fossil_prob) == 1 then + -- Spawn fossil below desert surface between layers 40 and 49 + local p1 = {x=p.x, y=pr:next(mcl_worlds.layer_to_y(40), mcl_worlds.layer_to_y(49)), z=p.z} + -- Very rough check of the environment (we expect to have enough stonelike nodes). + -- Fossils may still appear partially exposed in caves, but this is O.K. + local p2 = vector.add(p1, 4) + local nodes = minetest.find_nodes_in_area(p1, p2, {"mcl_core:sandstone", "mcl_core:stone", "mcl_core:diorite", "mcl_core:andesite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:dirt", "mcl_core:gravel"}) + + if #nodes >= 100 then -- >= 80% + mcl_structures.call_struct(p1, "fossil", nil, pr) + end + end + end + + -- Witch hut (v6) + if ground_y <= 0 and nn == "mcl_core:dirt" then + local prob = minecraft_chunk_probability(48, minp, maxp) + if pr:next(1, prob) == 1 then + + local swampland = minetest.get_biome_id("Swampland") + local swampland_shore = minetest.get_biome_id("Swampland_shore") + + -- Where do witches live? + -- v6: In Normal biome + if biomeinfo.get_v6_biome(p) == "Normal" then + here_be_witches = true + end + local here_be_witches = false + if here_be_witches then + + local r = tostring(pr:next(0, 3) * 90) -- "0", "90", "180" or 270" + local p1 = {x=p.x-1, y=WITCH_HUT_HEIGHT+2, z=p.z-1} + local size + if r == "0" or r == "180" then + size = {x=10, y=4, z=8} + else + size = {x=8, y=4, z=10} + end + local p2 = vector.add(p1, size) + + -- This checks free space at the “body” of the hut and a bit around. + -- ALL nodes must be free for the placement to succeed. + local free_nodes = minetest.find_nodes_in_area(p1, p2, {"air", "mcl_core:water_source", "mcl_flowers:waterlily"}) + if #free_nodes >= ((size.x+1)*(size.y+1)*(size.z+1)) then + local place = {x=p.x, y=WITCH_HUT_HEIGHT-1, z=p.z} + + -- FIXME: For some mysterious reason (black magic?) this + -- function does sometimes NOT spawn the witch hut. One can only see the + -- oak wood nodes in the water, but no hut. :-/ + mcl_structures.place_structure(place,mcl_structures.registered_structures["witch_hut"],pr) + + local function place_tree_if_free(pos, prev_result) + local nn = minetest.get_node(pos).name + if nn == "mcl_flowers:waterlily" or nn == "mcl_core:water_source" or nn == "mcl_core:water_flowing" or nn == "air" then + minetest.set_node(pos, {name="mcl_core:tree", param2=0}) + return prev_result + else + return false + end + end + local offsets + if r == "0" then + offsets = { + {x=1, y=0, z=1}, + {x=1, y=0, z=5}, + {x=6, y=0, z=1}, + {x=6, y=0, z=5}, + } + elseif r == "180" then + offsets = { + {x=2, y=0, z=1}, + {x=2, y=0, z=5}, + {x=7, y=0, z=1}, + {x=7, y=0, z=5}, + } + elseif r == "270" then + offsets = { + {x=1, y=0, z=1}, + {x=5, y=0, z=1}, + {x=1, y=0, z=6}, + {x=5, y=0, z=6}, + } + elseif r == "90" then + offsets = { + {x=1, y=0, z=2}, + {x=5, y=0, z=2}, + {x=1, y=0, z=7}, + {x=5, y=0, z=7}, + } + end + for o=1, #offsets do + local ok = true + for y=place.y-1, place.y-64, -1 do + local tpos = vector.add(place, offsets[o]) + tpos.y = y + ok = place_tree_if_free(tpos, ok) + if not ok then + break + end + end + end + end + end + end + end + + -- Ice spikes in v6 + -- In other mapgens, ice spikes are generated as decorations. + if nn == "mcl_core:snowblock" then + local spike = pr:next(1,58000) + if spike < 3 then + -- Check surface + local floor = {x=p.x+4, y=p.y-1, z=p.z+4} + local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock"}) + -- Check for collision with spruce + local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+2,z=p.z+1}, {x=p.x+4, y=p.y+6, z=p.z+4}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) + + if #surface >= 9 and #spruce_collisions == 0 then + mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_large"],pr) + end + elseif spike < 100 then + -- Check surface + local floor = {x=p.x+6, y=p.y-1, z=p.z+6} + local surface = minetest.find_nodes_in_area({x=p.x+1,y=p.y-1,z=p.z+1}, floor, {"mcl_core:snowblock", "mcl_core:dirt_with_grass_snow"}) + + -- Check for collision with spruce + local spruce_collisions = minetest.find_nodes_in_area({x=p.x+1,y=p.y+1,z=p.z+1}, {x=p.x+6, y=p.y+6, z=p.z+6}, {"mcl_core:sprucetree", "mcl_core:spruceleaves"}) + + if #surface >= 25 and #spruce_collisions == 0 then + mcl_structures.place_structure(p,mcl_structures.registered_structures["ice_spike_small"],pr) + end + end + end + end + end + end + end end + end +end + +-- Generate mushrooms in caves manually. +-- only v6. minetest supports cave decos via "all_floors" flag now +local function generate_underground_mushrooms(minp, maxp, seed) + local pr_shroom = PseudoRandom(seed-24359) + -- Generate rare underground mushrooms + -- TODO: Make them appear in groups, use Perlin noise + local min, max = mcl_vars.mg_lava_overworld_max + 4, 0 + if minp.y > max or maxp.y < min then + return + end + + local bpos + local stone = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_core:stone", "mcl_core:dirt", "mcl_core:mycelium", "mcl_core:podzol", "mcl_core:andesite", "mcl_core:diorite", "mcl_core:granite", "mcl_core:stone_with_coal", "mcl_core:stone_with_iron", "mcl_core:stone_with_gold"}) + + for n = 1, #stone do + bpos = {x = stone[n].x, y = stone[n].y + 1, z = stone[n].z } + + local l = minetest.get_node_light(bpos, 0.5) + if bpos.y >= min and bpos.y <= max and l and l <= 12 and pr_shroom:next(1,1000) < 4 then + if pr_shroom:next(1,2) == 1 then + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) + else + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) + end + end + end +end + +-- Generate Nether decorations manually: Eternal fire, mushrooms, nether wart +-- (only v6) +local nether_wart_chance = 85 +local function generate_nether_decorations(minp, maxp, seed) + local pr_nether = PseudoRandom(seed+667) + + if minp.y > mcl_vars.mg_nether_max or maxp.y < mcl_vars.mg_nether_min then + return + end + + minetest.log("action", "[mcl_mapgen_core] Nether decorations " .. minetest.pos_to_string(minp) .. " ... " .. minetest.pos_to_string(maxp)) + + -- TODO: Generate everything based on Perlin noise instead of PseudoRandom + + local bpos + local rack = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:netherrack"}) + local magma = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:magma"}) + local ssand = minetest.find_nodes_in_area_under_air(minp, maxp, {"mcl_nether:soul_sand"}) + + -- Helper function to spawn “fake” decoration + local function special_deco(nodes, spawn_func) + for n = 1, #nodes do + bpos = {x = nodes[n].x, y = nodes[n].y + 1, z = nodes[n].z } + + spawn_func(bpos) + end + end + -- Eternal fire on netherrack + special_deco(rack, function(bpos) + -- Eternal fire on netherrack + if pr_nether:next(1,100) <= 3 then + minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) + end + end) + + -- Eternal fire on magma cubes + special_deco(magma, function(bpos) + if pr_nether:next(1,150) == 1 then + minetest.set_node(bpos, {name = "mcl_fire:eternal_fire"}) + end + end) + + -- Mushrooms on netherrack + -- Note: Spawned *after* the fire because of light level checks + special_deco(rack, function(bpos) + local l = minetest.get_node_light(bpos, 0.5) + if bpos.y > mcl_vars.mg_lava_nether_max + 6 and l and l <= 12 and pr_nether:next(1,1000) <= 4 then + -- TODO: Make mushrooms appear in groups, use Perlin noise + if pr_nether:next(1,2) == 1 then + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_brown"}) + else + minetest.set_node(bpos, {name = "mcl_mushrooms:mushroom_red"}) + end + end + end) + + -- Nether wart on soul sand + -- TODO: Spawn in Nether fortresses + special_deco(ssand, function(bpos) + if pr_nether:next(1, nether_wart_chance) == 1 then + minetest.set_node(bpos, {name = "mcl_nether:nether_wart"}) + end + end) +end + +local function remove_mgv6_broken_plants(minp,maxp) + --[[ Remove broken double plants caused by v6 weirdness. + v6 might break the bottom part of double plants because of how it works. + There are 3 possibilities: + 1) Jungle: Top part is placed on top of a jungle tree or fern (=v6 jungle grass). + This is because the schematic might be placed even if some nodes of it + could not be placed because the destination was already occupied. + TODO: A better fix for this would be if schematics could abort placement + altogether if ANY of their nodes could not be placed. + 2) Cavegen: Removes the bottom part, the upper part floats + 3) Mudflow: Same as 2) ]] + + local plants = minetest.find_nodes_in_area(minp, maxp, "group:double_plant") + for n = 1, #plants do + local node = vm:get_node_at(plants[n]) + local is_top = minetest.get_item_group(node.name, "double_plant") == 2 + if is_top then + local p_pos = area:index(plants[n].x, plants[n].y-1, plants[n].z) + if p_pos then + node = vm:get_node_at({x=plants[n].x, y=plants[n].y-1, z=plants[n].z}) + local is_bottom = minetest.get_item_group(node.name, "double_plant") == 1 + if not is_bottom then + p_pos = area:index(plants[n].x, plants[n].y, plants[n].z) + data[p_pos] = c_air + lvm_used = true + end + end + end + end +end + +local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) + if not (minp.y <= mcl_vars.mg_nether_max and maxp.y >= mcl_vars.mg_nether_min) then + return + end + -- Nether block fixes: + -- * Replace water with Nether lava. + -- * Replace stone, sand dirt in v6 so the Nether works in v6. + local nodes = minetest.find_nodes_in_area(emin, emax, {"group:water"}) + for _, n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_nether_lava + lvm_used = true + end + nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + for n=1, #nodes do + local p_pos = area:index(nodes[n].x, nodes[n].y, nodes[n].z) + if data[p_pos] == c_water then + data[p_pos] = c_nether_lava + lvm_used = true + elseif data[p_pos] == c_stone then + data[p_pos] = c_netherrack + lvm_used = true + elseif data[p_pos] == c_sand or data[p_pos] == c_dirt then + data[p_pos] = c_soul_sand + lvm_used = true + end + end +end + +local function end_fixes(minp,maxp) + if not ( minp.y <= mcl_vars.mg_end_max and maxp.y >= mcl_vars.mg_end_min ) then + return + end + local nodes = minetest.find_nodes_in_area(emin, emax, {"mcl_core:water_source", "mcl_core:stone", "mcl_core:sand", "mcl_core:dirt"}) + if #nodes > 0 then + lvm_used = true + for _,n in pairs(nodes) do + data[area:index(n.x, n.y, n.z)] = c_air + end + end +end + +local function basic_node(minp, maxp, blockseed) + if mg_name ~= "singlenode" then + -- Generate special decorations + if mg_name == "v6" then + generate_underground_mushrooms(minp, maxp, blockseed) + generate_nether_decorations(minp, maxp, blockseed) + end_fixes(minp,maxp) + remove_mgv6_broken_plants(minp,maxp,blockseed) + generate_mgv6_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap")) + end + end +end + +mcl_mapgen_core.register_generator("mgv6-fixes", basic, basic_node, 10, true) diff --git a/mods/MAPGEN/mcl_nether_fortresses/init.lua b/mods/MAPGEN/mcl_nether_fortresses/init.lua new file mode 100644 index 000000000..b736ff133 --- /dev/null +++ b/mods/MAPGEN/mcl_nether_fortresses/init.lua @@ -0,0 +1,214 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local BLAZE_SPAWNER_MAX_LIGHT = 11 + +mcl_structures.register_structure("nether_outpost",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"}, + fill_ratio = 0.01, + chunk_probability = 900, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"}, + sidelen = 24, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { modpath.."/schematics/mcl_nether_fortresses_nether_outpost.mts" }, + y_offset = 0, + after_place = function(pos) + local sp = minetest.find_nodes_in_area(pos,vector.offset(pos,0,20,0),{"mcl_mobspawners:spawner"}) + if not sp[1] then return end + mcl_mobspawners.setup_spawner(sp[1], "mobs_mc:blaze", 0, BLAZE_SPAWNER_MAX_LIGHT, 10, 8, 0) + end +}) +local nbridges = { + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bridge_4.mts", +} +mcl_structures.register_structure("nether_bridge",{ + place_on = {"mcl_nether:nether_lava_source","mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand","mcl_core:bedrock"}, + fill_ratio = 0.01, + chunk_probability = 500, + flags = "all_floors", + sidelen = 38, + solid_ground = false, + make_foundation = false, + y_min = mcl_vars.mg_nether_min - 4, + y_max = mcl_vars.mg_lava_nether_max - 20, + filenames = nbridges, + y_offset = function(pr) return pr:next(15,20) end, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-14,0,-14) + local p2 = vector.offset(pos,14,24,14) + mcl_structures.spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5) + end +}) + +mcl_structures.register_structure("nether_outpost_with_bridges",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand","mcl_nether:nether_lava_source"}, + fill_ratio = 0.01, + chunk_probability = 1300, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest","BasaltDelta"}, + sidelen = 24, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { modpath.."/schematics/mcl_nether_fortresses_nether_outpost.mts" }, + daughters = {{ + files = { nbridges[1] }, + pos = vector.new(0,-2,-24), + rot = 180, + }, + { + files = { nbridges[1] }, + pos = vector.new(0,-2,24), + rot = 0, + }, + { + files = { nbridges[1] }, + pos = vector.new(-24,-2,0), + rot = 270, + }, + { + files = { nbridges[1] }, + pos = vector.new(24,-2,0), + rot = 90, + }, + }, + after_place = function(pos,def,pr) + local sp = minetest.find_nodes_in_area(pos,vector.offset(pos,0,20,0),{"mcl_mobspawners:spawner"}) + if not sp[1] then return end + mcl_mobspawners.setup_spawner(sp[1], "mobs_mc:blaze", 0, BLAZE_SPAWNER_MAX_LIGHT, 10, 8, 0) + + local legs = minetest.find_nodes_in_area(vector.offset(pos,-45,-2,-45),vector.offset(pos,45,0,45), "mcl_nether:nether_brick") + local bricks = {} + for _,leg in pairs(legs) do + while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "solid") == 0 do + leg = vector.offset(leg,0,-1,0) + table.insert(bricks,leg) + end + end + minetest.bulk_set_node(bricks, {name = "mcl_nether:nether_brick", param2 = 2}) + + local p1 = vector.offset(pos,-45,13,-45) + local p2 = vector.offset(pos,45,13,45) + mcl_structures.spawn_mobs("mobs_mc:witherskeleton",{"mcl_blackstone:blackstone_chiseled_polished"},p1,p2,pr,5) + end +},true) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:witherskeleton", + y_min = mcl_vars.mg_lava_nether_max, + y_max = mcl_vars.mg_nether_max, + chance = 15, + interval = 60, + limit = 4, + spawnon = { "mcl_blackstone:blackstone_chiseled_polished" }, +}) + +mcl_structures.register_structure("nether_bulwark",{ + place_on = {"mcl_nether:netherrack","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium","mcl_blackstone:basalt","mcl_blackstone:soul_soil","mcl_blackstone:blackstone","mcl_nether:soul_sand"}, + fill_ratio = 0.01, + chunk_probability = 900, + flags = "all_floors", + biomes = {"Nether","SoulsandValley","WarpedForest","CrimsonForest"}, + sidelen = 36, + solid_ground = true, + make_foundation = true, + y_min = mcl_vars.mg_lava_nether_max - 1, + y_max = mcl_vars.mg_nether_max - 30, + filenames = { + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_4.mts", + }, + daughters = {{ + files = { + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts", + modpath.."/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts", + }, + pos = vector.new(0,0,0), + }, + }, + y_offset = 0, + construct_nodes = {"group:wall"}, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-14,0,-14) + local p2 = vector.offset(pos,14,24,14) + mcl_structures.spawn_mobs("mobs_mc:piglin",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:piglin_brute",{"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"},p1,p2,pr) + mcl_structures.spawn_mobs("mobs_mc:hoglin",{"mcl_blackstone:nether_gold"},p1,p2,pr,4) + end, + loot = { + ["mcl_chests:chest_small" ] ={ + { + stacks_min = 1, + stacks_max = 2, + items = { + --{ itemstring = "FIXME:spectral_arrow", weight = 1, amount_min = 10, amount_max=28 }, + { itemstring = "mcl_blackstone:blackstone_gilded", weight = 1, amount_min = 8, amount_max=12 }, + { itemstring = "mcl_core:iron_ingot", weight = 1, amount_min = 4, amount_max=9 }, + { itemstring = "mcl_core:gold_ingot", weight = 1, amount_min = 4, amount_max=9 }, + { itemstring = "mcl_core:crying_obsidian", weight = 1, amount_min = 3, amount_max=8 }, + { itemstring = "mcl_bows:crossbow", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_core:goldblock", weight = 1, }, + { itemstring = "mcl_tools:sword_gold", weight = 1, }, + { itemstring = "mcl_tools:axe_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_gold", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + } + }, + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_bows:arrow", weight = 4, amount_min = 5, amount_max=17 }, + { itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max=6 }, + { itemstring = "mcl_core:iron_nugget", weight = 1, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_core:gold_nugget", weight = 1, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_mobitems:leather", weight = 1, amount_min = 1, amount_max = 3 }, + } + }, + { + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_compass:lodestone" }, + } + }} + }, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:piglin", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = {"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"}, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:piglin_brute", + y_min = mcl_vars.mg_nether_min, + y_max = mcl_vars.mg_nether_max, + chance = 20, + interval = 60, + limit = 4, + spawnon = {"mcl_blackstone:blackstone_brick_polished","mcl_stairs:slab_blackstone_polished"}, +}) diff --git a/mods/MAPGEN/mcl_nether_fortresses/mod.conf b/mods/MAPGEN/mcl_nether_fortresses/mod.conf new file mode 100644 index 000000000..7d1565ff3 --- /dev/null +++ b/mods/MAPGEN/mcl_nether_fortresses/mod.conf @@ -0,0 +1,3 @@ +name = mcl_nether_fortresses +author = cora +depends = mcl_init, mcl_structures, mcl_mobspawners diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts new file mode 100644 index 000000000..6923f6edb Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts new file mode 100644 index 000000000..ba04dfd2d Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts new file mode 100644 index 000000000..e62e298fd Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts new file mode 100644 index 000000000..6b66ac6a0 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bridge_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts new file mode 100644 index 000000000..a9522cce0 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts new file mode 100644 index 000000000..7cf4c0722 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts new file mode 100644 index 000000000..01f893dd7 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts new file mode 100644 index 000000000..1fc74c18b Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts new file mode 100644 index 000000000..9c09c3edb Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_1.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts new file mode 100644 index 000000000..b73a5a590 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_2.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts new file mode 100644 index 000000000..0a4c05425 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_3.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts new file mode 100644 index 000000000..d7e23f027 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_bulwark_interior_4.mts differ diff --git a/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts new file mode 100644 index 000000000..4fa3f1935 Binary files /dev/null and b/mods/MAPGEN/mcl_nether_fortresses/schematics/mcl_nether_fortresses_nether_outpost.mts differ diff --git a/mods/MAPGEN/mcl_strongholds/depends.txt b/mods/MAPGEN/mcl_strongholds/depends.txt deleted file mode 100644 index 76570fa33..000000000 --- a/mods/MAPGEN/mcl_strongholds/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_init -mcl_structures -mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_strongholds/description.txt b/mods/MAPGEN/mcl_strongholds/description.txt deleted file mode 100644 index 2f761edbe..000000000 --- a/mods/MAPGEN/mcl_strongholds/description.txt +++ /dev/null @@ -1 +0,0 @@ -Generates strongholds with end portals in the Overworld diff --git a/mods/MAPGEN/mcl_strongholds/init.lua b/mods/MAPGEN/mcl_strongholds/init.lua index 92313bee7..d5bc87963 100644 --- a/mods/MAPGEN/mcl_strongholds/init.lua +++ b/mods/MAPGEN/mcl_strongholds/init.lua @@ -16,25 +16,17 @@ local stronghold_rings = { } local strongholds = {} -local strongholds_inited = false local mg_name = minetest.get_mapgen_setting("mg_name") local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superflat_classic") == "true" +local seed = tonumber(minetest.get_mapgen_setting("seed")) --- Determine the stronghold positions and store them into the strongholds table. --- The stronghold positions are based on the world seed. --- The actual position might be offset by a few blocks because it might be shifted --- to make sure the end portal room is completely within the boundaries of a mapchunk. -local init_strongholds = function() - if strongholds_inited then - return - end +local function init_strongholds() + local stronghold_positions = {} -- Don't generate strongholds in singlenode if mg_name == "singlenode" then - strongholds_inited = true - return + return {} end - local seed = tonumber(minetest.get_mapgen_setting("seed")) local pr = PseudoRandom(seed) for s=1, #stronghold_rings do local ring = stronghold_rings[s] @@ -53,21 +45,19 @@ local init_strongholds = function() end local pos = { x = math.cos(angle) * dist, y = y, z = math.sin(angle) * dist } pos = vector.round(pos) - table.insert(strongholds, { pos = pos, generated = false }) + table.insert(stronghold_positions, pos) -- Rotate angle by (360 / amount) degrees. -- This will cause the angles to be evenly distributed in the stronghold ring angle = math.fmod(angle + ((math.pi*2) / ring.amount), math.pi*2) end end - - mcl_structures.register_structures("stronghold", table.copy(strongholds)) - - strongholds_inited = true + return stronghold_positions end -- Stronghold generation for register_on_generated. -local generate_strongholds = function(minp, maxp) +local function generate_strongholds(minp, maxp, blockseed) + local pr = PseudoRandom(blockseed) for s=1, #strongholds do if not strongholds[s].generated then local pos = strongholds[s].pos @@ -80,6 +70,12 @@ local generate_strongholds = function(minp, maxp) if pos.x + 6 > maxp.x then pos.x = maxp.x - 7 end + if pos.y - 4 < minp.y then + pos.y = minp.y + 5 + end + if pos.y + 4 > maxp.y then + pos.y = maxp.y - 5 + end if pos.z - 6 < minp.z then pos.z = minp.z + 7 end @@ -87,18 +83,94 @@ local generate_strongholds = function(minp, maxp) pos.z = maxp.z - 7 end - mcl_structures.call_struct(pos, "end_portal_shrine") + --mcl_structures.call_struct(pos, "end_portal_shrine", nil, pr) strongholds[s].generated = true end end end end -init_strongholds() +mcl_structures.register_structure("end_shrine",{ + static_pos = init_strongholds(), + filenames = { + minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" + }, + after_place = function(pos,def,pr,blockseed,p1,p2,size,rotation) + local p1 = vector.subtract(pos,size) + local p2 = vector.add(pos,size) + local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") + for s=1, #spawners do + --local meta = minetest.get_meta(spawners[s]) + mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") + end ---[[ Note this mod depends on mcl_mapgen_core to make sure the core mapgen runs FIRST. -This is important because we need this to make sure the stronghold isn't instantly -overwritten by the core mapgen (since it uses LuaVoxelManip). ]] -minetest.register_on_generated(function(minp, maxp, blockseed) - generate_strongholds(minp, maxp) -end) + -- Shuffle stone brick types + local bricks = minetest.find_nodes_in_area(p1, p2, "mcl_core:stonebrick") + for b=1, #bricks do + local r_bricktype = pr:next(1, 100) + local r_infested = pr:next(1, 100) + local bricktype + if r_infested <= 5 then + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" + else -- 50% + bricktype = "mcl_monster_eggs:monster_egg_stonebrick" + end + else + if r_bricktype <= 30 then -- 30% + bricktype = "mcl_core:stonebrickmossy" + elseif r_bricktype <= 50 then -- 20% + bricktype = "mcl_core:stonebrickcracked" + end + -- 50% stonebrick (no change necessary) + end + if bricktype then + minetest.set_node(bricks[b], { name = bricktype }) + end + end + + -- Also replace stairs + local stairs = minetest.find_nodes_in_area(p1, p2, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) + for s=1, #stairs do + local stair = minetest.get_node(stairs[s]) + local r_type = pr:next(1, 100) + if r_type <= 30 then -- 30% mossy + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickmossy" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickmossy_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickmossy_inner" + end + minetest.set_node(stairs[s], stair) + elseif r_type <= 50 then -- 20% cracky + if stair.name == "mcl_stairs:stair_stonebrick" then + stair.name = "mcl_stairs:stair_stonebrickcracked" + elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then + stair.name = "mcl_stairs:stair_stonebrickcracked_outer" + elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then + stair.name = "mcl_stairs:stair_stonebrickcracked_inner" + end + minetest.set_node(stairs[s], stair) + end + -- 50% no change + end + + -- Randomly add ender eyes into end portal frames, but never fill the entire frame + local frames = minetest.find_nodes_in_area(p1, p2, "mcl_portals:end_portal_frame") + local eyes = 0 + for f=1, #frames do + local r_eye = pr:next(1, 10) + if r_eye == 1 then + eyes = eyes + 1 + if eyes < #frames then + local frame_node = minetest.get_node(frames[f]) + frame_node.name = "mcl_portals:end_portal_frame_eye" + minetest.set_node(frames[f], frame_node) + end + end + end + end, +}) diff --git a/mods/MAPGEN/mcl_strongholds/mod.conf b/mods/MAPGEN/mcl_strongholds/mod.conf index 22c99de4f..8edec9a51 100644 --- a/mods/MAPGEN/mcl_strongholds/mod.conf +++ b/mods/MAPGEN/mcl_strongholds/mod.conf @@ -1 +1,4 @@ name = mcl_strongholds +author = Wuzzy +description = Generates strongholds with end portals in the Overworld +depends = mcl_init, mcl_structures, mcl_mapgen_core diff --git a/mods/MAPGEN/mcl_structures/API.md b/mods/MAPGEN/mcl_structures/API.md new file mode 100644 index 000000000..074810186 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/API.md @@ -0,0 +1,38 @@ +# mcl_structures +Structure placement API for MCL2. + +## mcl_structures.register_structure(name,structure definition,nospawn) +If nospawn is truthy the structure will not be placed by mapgen and the decoration parameters can be omitted. This is intended for secondary structures the placement of which gets triggered by the placement of other structures. It can also be used to register testing structures so they can be used with /spawnstruct. + +### structure definition +{ + fill_ratio = OR noise = {}, + biomes = {}, + y_min =, + y_max =, + place_on = {}, + spawn_by = {}, + num_spawn_by =, + flags = (default: "place_center_x, place_center_z, force_placement") + (same as decoration def) + y_offset =, --can be a number or a function returning a number + filenames = {} OR place_func = function(pos,def,pr) + -- filenames can be a list of any schematics accepted by mcl_structures.place_schematic / minetest.place_schematic + on_place = function(pos,def,pr) end, + -- called before placement. denies placement when returning falsy. + after_place = function(pos,def,pr) + -- executed after successful placement + sidelen = int, --length of one side of the structure. used for foundations. + solid_ground = bool, -- structure requires solid ground + make_foundation = bool, -- a foundation is automatically built for the structure. needs the sidelen param + loot = , + --a table of loot tables for mcl_loot indexed by node names + -- e.g. { ["mcl_chests:chest_small"] = {loot},... } +} +## mcl_structures.registered_structures +Table of the registered structure defintions indexed by name. + +## mcl_structures.place_structure(pos, def, pr) +Places a structure using the mapgen placement function + +## mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) diff --git a/mods/MAPGEN/mcl_structures/api.lua b/mods/MAPGEN/mcl_structures/api.lua new file mode 100644 index 000000000..cf47b4e30 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/api.lua @@ -0,0 +1,422 @@ +mcl_structures.registered_structures = {} + +local place_queue = {} +local disabled_structures = minetest.settings:get("mcl_disabled_structures") +if disabled_structures then disabled_structures = disabled_structures:split(",") +else disabled_structures = {} end + +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) +local mob_cap_player = tonumber(minetest.settings:get("mcl_mob_cap_player")) or 75 +local mob_cap_animal = tonumber(minetest.settings:get("mcl_mob_cap_animal")) or 10 + +local logging = minetest.settings:get_bool("mcl_logging_structures",true) + +local mg_name = minetest.get_mapgen_setting("mg_name") + +local rotations = { + "0", + "90", + "180", + "270" +} + +function mcl_structures.is_disabled(structname) + return table.indexof(disabled_structures,structname) ~= -1 +end + +local function ecb_place(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + minetest.place_schematic(param.pos, param.schematic, param.rotation, param.replacements, param.force_placement, param.flags) + if param.after_placement_callback and param.p1 and param.p2 then + param.after_placement_callback(param.p1, param.p2, param.size, param.rotation, param.pr, param.callback_param) + end +end + +function mcl_structures.place_schematic(pos, schematic, rotation, replacements, force_placement, flags, after_placement_callback, pr, callback_param) + if type(schematic) ~= "table" and not mcl_util.file_exists(schematic) then + minetest.log("warning","[mcl_structures] schematic file "..tostring(schematic).." does not exist.") + return end + local s = loadstring(minetest.serialize_schematic(schematic, "lua", {lua_use_comments = false, lua_num_indent_spaces = 0}) .. " return schematic")() + if s and s.size then + local x, z = s.size.x, s.size.z + if rotation then + if rotation == "random" and pr then + rotation = rotations[pr:next(1,#rotations)] + end + if rotation == "random" then + x = math.max(x, z) + z = x + elseif rotation == "90" or rotation == "270" then + x, z = z, x + end + end + local p1 = {x=pos.x , y=pos.y , z=pos.z } + local p2 = {x=pos.x+x-1, y=pos.y+s.size.y-1, z=pos.z+z-1} + minetest.log("verbose", "[mcl_structures] size=" ..minetest.pos_to_string(s.size) .. ", rotation=" .. tostring(rotation) .. ", emerge from "..minetest.pos_to_string(p1) .. " to " .. minetest.pos_to_string(p2)) + local param = {pos=vector.new(pos), schematic=s, rotation=rotation, replacements=replacements, force_placement=force_placement, flags=flags, p1=p1, p2=p2, after_placement_callback = after_placement_callback, size=vector.new(s.size), pr=pr, callback_param=callback_param} + minetest.emerge_area(p1, p2, ecb_place, param) + return true + end +end + +function mcl_structures.get_struct(file) + local localfile = modpath.."/schematics/"..file + local file, errorload = io.open(localfile, "rb") + if errorload then + minetest.log("error", "[mcl_structures] Could not open this struct: "..localfile) + return nil + end + + local allnode = file:read("*a") + file:close() + + return allnode +end + +-- Call on_construct on pos. +-- Useful to init chests from formspec. +local function init_node_construct(pos) + local node = minetest.get_node(pos) + local def = minetest.registered_nodes[node.name] + if def and def.on_construct then + def.on_construct(pos) + return true + end + return false +end +mcl_structures.init_node_construct = init_node_construct + +function mcl_structures.fill_chests(p1,p2,loot,pr) + for it,lt in pairs(loot) do + local nodes = minetest.find_nodes_in_area(p1, p2, it) + for _,p in pairs(nodes) do + local lootitems = mcl_loot.get_multi_loot(lt, pr) + mcl_structures.init_node_construct(p) + local meta = minetest.get_meta(p) + local inv = meta:get_inventory() + mcl_loot.fill_inventory(inv, "main", lootitems, pr) + end + end +end + +local function generate_loot(pos, def, pr) + local hl = def.sidelen + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + if def.loot then mcl_structures.fill_chests(p1,p2,def.loot,pr) end +end + +function mcl_structures.construct_nodes(p1,p2,nodes) + local nn=minetest.find_nodes_in_area(p1,p2,nodes) + for _,p in pairs(nn) do + mcl_structures.init_node_construct(p) + end +end + +local function construct_nodes(pos,def,pr) + return mcl_structures.construct_nodes(vector.offset(pos,-def.sidelen/2,0,-def.sidelen/2),vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2),def.construct_nodes) +end + + +function mcl_structures.find_lowest_y(pp) + local y = 31000 + for _,p in pairs(pp) do + if p.y < y then y = p.y end + end + return y +end + +function mcl_structures.find_highest_y(pp) + local y = -31000 + for _,p in pairs(pp) do + if p.y > y then y = p.y end + end + return y +end + +local function smooth_cube(nn,pos,plane,amnt) + local r = {} + local amnt = amnt or 9 + table.sort(nn,function(a, b) + if false or plane then + return vector.distance(vector.new(pos.x,0,pos.z), vector.new(a.x,0,a.z)) < vector.distance(vector.new(pos.x,0,pos.z), vector.new(b.x,0,b.z)) + else + return vector.distance(pos, a) < vector.distance(pos, b) + end + end) + for i=1,math.max(1,#nn-amnt) do table.insert(r,nn[i]) end + return r +end + +local function find_ground(pos,nn,gn) + local r = 0 + for _,v in pairs(nn) do + local p=vector.new(v) + repeat + local n = minetest.get_node(p).name + p = vector.offset(p,0,-1,0) + until not n or n == "mcl_core:bedrock" or n == "ignore" or n == gn + --minetest.log(tostring(pos.y - p.y)) + if pos.y - p.y > r then r = pos.y - p.y end + end + return r +end + +local function get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) + local replace = {"air","group:liquid","mcl_core:snow","group:tree","group:leaves","group:plant","grass_block","group:dirt"} + local depth = find_ground(pos,minetest.find_nodes_in_area(ground_p1,ground_p2,replace),node_stone) + local nn = smooth_cube(minetest.find_nodes_in_area(vector.offset(ground_p1,0,-1,0),vector.offset(ground_p2,0,-depth,0),replace),vector.offset(pos,0,-depth,0),true,sidelen * 64) + local stone = {} + local filler = {} + local top = {} + local dust = {} + for l,v in pairs(nn) do + if v.y == ground_p1.y - 1 then + table.insert(filler,v) + table.insert(top,vector.offset(v,0,1,0)) + table.insert(dust,vector.offset(v,0,2,0)) + elseif v.y < ground_p1.y -1 and v.y > ground_p2.y -4 then table.insert(filler,v) + elseif v.y < ground_p2.y - 3 and v.y > ground_p2.y -5 then + if math.random(3) == 1 then + table.insert(filler,v) + else + table.insert(stone,v) + end + else + table.insert(stone,v) + end + end + return stone,filler,top,dust +end + +local function foundation(ground_p1,ground_p2,pos,sidelen) + local node_stone = "mcl_core:stone" + local node_filler = "mcl_core:dirt" + local node_top = "mcl_core:dirt_with_grass" or minetest.get_node(ground_p1).name + local node_dust = nil + + if mg_name ~= "v6" then + local b = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)] + --minetest.log(dump(b.node_top)) + if b then + if b.node_top then node_top = b.node_top end + if b.node_filler then node_filler = b.node_filler end + if b.node_stone then node_stone = b.node_stone end + if b.node_dust then node_dust = b.node_dust end + end + end + + local stone,filler,top,dust = get_foundation_nodes(ground_p1,ground_p2,pos,sidelen,node_stone) + minetest.bulk_set_node(top,{name=node_top},node_stone) + + if node_dust then + minetest.bulk_set_node(dust,{name=node_dust}) + end + minetest.bulk_set_node(filler,{name=node_filler}) + minetest.bulk_set_node(stone,{name=node_stone}) +end + +local function process_queue() + if #place_queue < 1 then return end + local s = table.remove(place_queue) + mcl_structures.place_schematic(s.pos, s.file, s.rot, nil, true, "place_center_x,place_center_z",function(s) + if s.after_place then + s.after_place(s.pos,s.def,s.pr) + end + end,s.pr) + minetest.after(0.5,process_queue) +end + +function mcl_structures.spawn_mobs(mob,spawnon,p1,p2,pr,n,water) + n = n or 1 + local sp = {} + if water then + local nn = minetest.find_nodes_in_area(p1,p2,spawnon) + for k,v in pairs(nn) do + if minetest.get_item_group(minetest.get_node(vector.offset(v,0,1,0)).name,"water") > 0 then + table.insert(sp,v) + end + end + else + sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon) + end + table.shuffle(sp) + for i,node in pairs(sp) do + if not peaceful and i <= n then + local pos = vector.offset(node,0,1,0) + if pos then + minetest.add_entity(pos,mob) + end + end + minetest.get_meta(node):set_string("spawnblock","yes") + end +end + +function mcl_structures.place_structure(pos, def, pr, blockseed, rot) + if not def then return end + if not rot then rot = "random" end + local log_enabled = logging and not def.terrain_feature + local y_offset = 0 + if type(def.y_offset) == "function" then + y_offset = def.y_offset(pr) + elseif def.y_offset then + y_offset = def.y_offset + end + local pp = vector.offset(pos,0,y_offset,0) + if def.solid_ground and def.sidelen then + local ground_p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) + local ground_p2 = vector.offset(pos,def.sidelen/2,-1,def.sidelen/2) + + local solid = minetest.find_nodes_in_area(ground_p1,ground_p2,{"group:solid"}) + if #solid < ( def.sidelen * def.sidelen ) then + if def.make_foundation then + foundation(vector.offset(pos,-def.sidelen/2 - 3,-1,-def.sidelen/2 - 3),vector.offset(pos,def.sidelen/2 + 3,-1,def.sidelen/2 + 3),pos,def.sidelen) + else + if log_enabled then + minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. No solid ground.") + end + return false + end + end + end + if def.on_place and not def.on_place(pos,def,pr,blockseed) then + if log_enabled then + minetest.log("warning","[mcl_structures] "..def.name.." at "..minetest.pos_to_string(pp).." not placed. Conditions not satisfied.") + end + return false + end + if def.filenames then + if #def.filenames <= 0 then return false end + local r = pr:next(1,#def.filenames) + local file = def.filenames[r] + if file then + local rot = rotations[pr:next(1,#rotations)] + local ap = function(pos,def,pr,blockseed) end + + if def.daughters then + ap = function(pos,def,pr,blockseed) + for _,d in pairs(def.daughters) do + local p = vector.add(pos,d.pos) + local rot = d.rot or 0 + mcl_structures.place_schematic(p, d.files[pr:next(1,#d.files)], rot, nil, true, "place_center_x,place_center_z",function() + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + if def.after_place then + def.after_place(pos,def,pr) + end + end,pr) + end + end + elseif def.after_place then + ap = def.after_place + end + mcl_structures.place_schematic(pp, file, rot, def.replacements, true, "place_center_x,place_center_z",function(p1, p2, size, rotation) + if not def.daughters then + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + end + return ap(pp,def,pr,blockseed,p1,p2,size,rotation) + end,pr) + if log_enabled then + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) + end + return true + end + elseif def.place_func and def.place_func(pp,def,pr,blockseed) then + if not def.after_place or ( def.after_place and def.after_place(pp,def,pr,blockseed) ) then + if def.loot then generate_loot(pp,def,pr,blockseed) end + if def.construct_nodes then construct_nodes(pp,def,pr,blockseed) end + if log_enabled then + minetest.log("action","[mcl_structures] "..def.name.." placed at "..minetest.pos_to_string(pp)) + end + return true + end + end + if log_enabled then + minetest.log("warning","[mcl_structures] placing "..def.name.." failed at "..minetest.pos_to_string(pos)) + end +end + +function mcl_structures.register_structure(name,def,nospawn) --nospawn means it will be placed by another (non-nospawn) structure that contains it's structblock i.e. it will not be placed by mapgen directly + if mcl_structures.is_disabled(name) then return end + local structblock = "mcl_structures:structblock_"..name + local flags = "place_center_x, place_center_z, force_placement" + local y_offset = 0 + local sbgroups = { structblock = 1, not_in_creative_inventory=1 } + if def.flags then flags = def.flags end + def.name = name + if nospawn then + sbgroups.structblock = nil + sbgroups.structblock_lbm = 1 + else + if def.place_on then + minetest.register_on_mods_loaded(function() --make sure all previous decorations and biomes have been registered + def.deco = minetest.register_decoration({ + name = "mcl_structures:deco_"..name, + decoration = structblock, + deco_type = "simple", + place_on = def.place_on, + spawn_by = def.spawn_by, + num_spawn_by = def.num_spawn_by, + sidelen = 80, + fill_ratio = def.fill_ratio, + noise_params = def.noise_params, + flags = flags, + biomes = def.biomes, + y_max = def.y_max, + y_min = def.y_min + }) + minetest.register_node(":"..structblock, {drawtype="airlike", walkable = false, pointable = false,groups = sbgroups,sunlight_propagates = true,}) + def.structblock = structblock + def.deco_id = minetest.get_decoration_id("mcl_structures:deco_"..name) + minetest.set_gen_notify({decoration=true}, { def.deco_id }) + --catching of gennotify happens in mcl_mapgen_core + + end) + end + end + mcl_structures.registered_structures[name] = def +end + +local structure_spawns = {} +function mcl_structures.register_structure_spawn(def) + --name,y_min,y_max,spawnon,biomes,chance,interval,limit + minetest.register_abm({ + label = "Spawn "..def.name, + nodenames = def.spawnon, + min_y = def.y_min or -31000, + max_y = def.y_max or 31000, + interval = def.interval or 60, + chance = def.chance or 5, + action = function(pos, node, active_object_count, active_object_count_wider) + local limit = def.limit or 7 + if active_object_count_wider > limit + mob_cap_animal then return end + if active_object_count_wider > mob_cap_player then return end + local p = vector.offset(pos,0,1,0) + if minetest.get_node(p).name ~= "air" then return end + if minetest.get_meta(pos):get_string("spawnblock") == "" then return end + if mg_name ~= "v6" and mg_name ~= "singlenode" and def.biomes then + if table.indexof(def.biomes,minetest.get_biome_name(minetest.get_biome_data(p).biome)) == -1 then + return + end + end + local mobdef = minetest.registered_entities[def.name] + if mobdef.can_spawn and not mobdef.can_spawn(p) then return end + minetest.add_entity(p,def.name) + end, + }) +end + +--lbm for secondary structures (structblock included in base structure) +minetest.register_lbm({ + name = "mcl_structures:struct_lbm", + run_at_every_load = true, + nodenames = {"group:structblock_lbm"}, + action = function(pos, node) + minetest.remove_node(pos) + local name = node.name:gsub("mcl_structures:structblock_","") + local def = mcl_structures.registered_structures[name] + if not def then return end + mcl_structures.place_structure(pos) + end +}) diff --git a/mods/MAPGEN/mcl_structures/depends.txt b/mods/MAPGEN/mcl_structures/depends.txt deleted file mode 100644 index dc513fc7b..000000000 --- a/mods/MAPGEN/mcl_structures/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_loot diff --git a/mods/MAPGEN/mcl_structures/desert_temple.lua b/mods/MAPGEN/mcl_structures/desert_temple.lua new file mode 100644 index 000000000..75c170ab1 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/desert_temple.lua @@ -0,0 +1,86 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local function temple_placement_callback(pos,def, pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + -- Delete cacti leftovers: + local cactus_nodes = minetest.find_nodes_in_area_under_air(p1, p2, "mcl_core:cactus") + if cactus_nodes and #cactus_nodes > 0 then + for _, pos in pairs(cactus_nodes) do + local node_below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z}) + if node_below and node_below.name == "mcl_core:sandstone" then + minetest.swap_node(pos, {name="air"}) + end + end + end + + -- Initialize pressure plates and randomly remove up to 5 plates + local pplates = minetest.find_nodes_in_area(p1, p2, "mesecons_pressureplates:pressure_plate_stone_off") + local pplates_remove = 5 + for p=1, #pplates do + if pplates_remove > 0 and pr:next(1, 100) >= 50 then + -- Remove plate + minetest.remove_node(pplates[p]) + pplates_remove = pplates_remove - 1 + else + -- Initialize plate + minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p]) + end + end +end + +mcl_structures.register_structure("desert_temple",{ + place_on = {"group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + sidelen = 18, + y_offset = -12, + chunk_probability = 300, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Desert" }, + filenames = { modpath.."/schematics/mcl_structures_desert_temple.mts" }, + after_place = temple_placement_callback, + loot = { + ["mcl_chests:chest" ] ={ + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, + { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, + { itemstring = "mcl_books:book", weight = 20, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_mobitems:saddle", weight = 20, }, + { itemstring = "mcl_core:apple_gold", weight = 20, }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 }, + { itemstring = "", weight = 15, }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 15, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 10, }, + { 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, }, + } + }, + { + stacks_min = 4, + stacks_max = 4, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, + } + }} + } +}) diff --git a/mods/MAPGEN/mcl_structures/end_city.lua b/mods/MAPGEN/mcl_structures/end_city.lua new file mode 100644 index 000000000..5f432a0eb --- /dev/null +++ b/mods/MAPGEN/mcl_structures/end_city.lua @@ -0,0 +1,144 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local spawnon = {"mcl_end:purpur_block"} + +local function spawn_shulkers(pos,def,pr) + local p1 = vector.offset(pos,-def.sidelen/2,-1,-def.sidelen/2) + local p2 = vector.offset(pos,def.sidelen/2,def.sidelen,def.sidelen/2) + mcl_structures.spawn_mobs("mobs_mc:shulker",spawnon,p1,p2,pr,1) + + local guard = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) + if guard then + minetest.add_entity(vector.offset(guard,0,-1.5,0),"mobs_mc:shulker") + end +end + +mcl_structures.register_structure("end_shipwreck",{ + place_on = {"mcl_end:end_stone"}, + fill_ratio = 0.001, + flags = "place_center_x, place_center_z, all_floors", + y_offset = function(pr) return pr:next(-50,-20) end, + chunk_probability = 800, + --y_max = mcl_vars.mg_end_max, + --y_min = mcl_vars.mg_end_min -100, + biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, + sidelen = 32, + filenames = { + modpath.."/schematics/mcl_structures_end_shipwreck_1.mts", + }, + construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, + after_place = function(pos,def,pr) + local fr = minetest.find_node_near(pos,def.sidelen,{"mcl_itemframes:item_frame"}) + if fr then + if mcl_itemframes then + mcl_itemframes.update_item_entity(fr,minetest.get_node(fr)) + end + end + return spawn_shulkers(pos,def,pr) + end, + loot = { + [ "mcl_itemframes:item_frame" ] ={{ + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_armor:elytra", weight = 100 }, + }, + }}, + [ "mcl_chests:chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, + { 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_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure("end_boat",{ + place_on = {"mcl_end:end_stone"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, all_floors", + y_offset = function(pr) return pr:next(15,30) end, + chunk_probability = 900, + --y_max = mcl_vars.mg_end_max, + --y_min = mcl_vars.mg_end_min -100, + biomes = { "End", "EndHighlands", "EndMidlands", "EndBarrens", "EndSmallIslands" }, + sidelen = 20, + filenames = { + modpath.."/schematics/mcl_structures_end_boat.mts", + }, + after_place = spawn_shulkers, + construct_nodes = {"mcl_chests:ender_chest_small","mcl_chests:ender_chest","mcl_brewing:stand_000","mcl_chests:violet_shulker_box_small"}, + loot = { + [ "mcl_chests:chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 16, amount_min = 1, amount_max=10 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 4, amount_max = 8 }, + { 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_tools:pick_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:sword_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_iron_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:pick_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_tools:shovel_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:helmet_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:leggings_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:boots_diamond_enchanted", weight = 3,func = function(stack, pr) mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:shulker", + y_min = mcl_vars.mg_end_min, + y_max = mcl_vars.mg_end_max, + chance = 10, + interval = 60, + limit = 6, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/end_spawn.lua b/mods/MAPGEN/mcl_structures/end_spawn.lua new file mode 100644 index 000000000..5769ac487 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/end_spawn.lua @@ -0,0 +1,123 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + + +mcl_structures.register_structure("end_spawn_obsidian_platform",{ + static_pos ={mcl_vars.mg_end_platform_pos}, + place_func = function(pos,def,pr) + local obby = minetest.find_nodes_in_area(vector.offset(pos,-2,0,-2),vector.offset(pos,2,0,2),{"air","mcl_end:end_stone"}) + local air = minetest.find_nodes_in_area(vector.offset(pos,-2,1,-2),vector.offset(pos,2,3,2),{"air","mcl_end:end_stone"}) + minetest.bulk_set_node(obby,{name="mcl_core:obsidian"}) + minetest.bulk_set_node(air,{name="air"}) + return true + end, +}) + +mcl_structures.register_structure("end_exit_portal",{ + static_pos = { mcl_vars.mg_end_exit_portal_pos }, + filenames = { + modpath.."/schematics/mcl_structures_end_exit_portal.mts" + }, + after_place = function(pos,def,pr,blockseed) + if minetest.settings:get_bool("only_peaceful_mobs", false) then + return + end + local p1 = vector.offset(pos,-16,-16,-16) + local p2 = vector.offset(pos,16,21,16) + minetest.emerge_area(p1,p2,function(blockpos, action, calls_remaining, param) + if calls_remaining > 0 then return end + minetest.bulk_set_node(minetest.find_nodes_in_area(p1,p2,{"mcl_portals:portal_end"}),{name="air"}) + local obj = minetest.add_entity(vector.offset(pos,3, 11, 3), "mobs_mc:enderdragon") + if obj then + local dragon_entity = obj:get_luaentity() + dragon_entity._portal_pos = pos + if blockseed ~= -1 then + dragon_entity._initial = true + end + else + minetest.log("error", "[mcl_mapgen_core] ERROR! Ender dragon doesn't want to spawn") + end + minetest.fix_light(p1,p2) + end) + end +}) +mcl_structures.register_structure("end_exit_portal_open",{ + filenames = { + modpath.."/schematics/mcl_structures_end_exit_portal.mts" + }, + after_place = function(pos,def,pr) + local p1 = vector.offset(pos,-16,-16,-16) + local p2 = vector.offset(pos,16,16,16) + minetest.fix_light(p1,p2) + end +}) +mcl_structures.register_structure("end_gateway_portal",{ + filenames = { + modpath.."/schematics/mcl_structures_end_gateway_portal.mts" + }, +}) + +local function get_tower(p,h,tbl) + for i = 1,h do + table.insert(tbl,vector.offset(p,0,i,0)) + end +end + +local function make_endspike(pos,width,height) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-width/2,0,-width/2),vector.offset(pos,width/2,0,width/2),{"air","group:solid"}) + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + local nodes = {} + for i = 1,math.ceil(#nn*0.55) do + get_tower(nn[i],height,nodes) + end + minetest.bulk_set_node(nodes,{ name="mcl_core:obsidian"} ) + return vector.offset(pos,0,height,0) +end + +function make_cage(pos,width) + local nodes = {} + local nodes2 = {} + local r = math.max(1,math.floor(width/2) - 2) + for x=-r,r do for y = 0,width do for z = -r,r do + if x == r or x == -r or z==r or z == -r then + table.insert(nodes,vector.add(pos,vector.new(x,y,z))) + end + end end end + if xpanes then + minetest.bulk_set_node(nodes,{ name="xpanes:bar_flat"} ) + for _,p in pairs(nodes) do + xpanes.update_pane(p) + end + end +end + +local function get_points_on_circle(pos,r,n) + local rt = {} + for i=1, n do + table.insert(rt,vector.offset(pos,r * math.cos(((i-1)/n) * (2*math.pi)),0, r* math.sin(((i-1)/n) * (2*math.pi)) )) + end + return rt +end + +mcl_structures.register_structure("end_spike",{ + static_pos =get_points_on_circle(vector.offset(mcl_vars.mg_end_exit_portal_pos,0,-20,0),43,10), + place_func = function(pos,def,pr) + local d = pr:next(6,12) + local h = d * pr:next(4,6) + local p1 = vector.offset(pos, -d / 2, 0, -d / 2) + local p2 = vector.offset(pos, d / 2, h + d, d / 2) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local s = make_endspike(pos,d,h) + minetest.set_node(vector.offset(s,0,1,0),{name="mcl_core:bedrock"}) + minetest.add_entity(vector.offset(s,0,2,0),"mcl_end:crystal") + if pr:next(1,3) == 1 then + make_cage(vector.offset(s,0,1,0),d) + end + end) + return true + end, +}) diff --git a/mods/MAPGEN/mcl_structures/geode.lua b/mods/MAPGEN/mcl_structures/geode.lua new file mode 100644 index 000000000..56453ee60 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/geode.lua @@ -0,0 +1,95 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,1,0), + vector.new(0,-1,0) +} + +local function set_node_no_bedrock(pos, node) + if not pos then return end + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function makegeode(pos,def,pr) + local size = pr:next(5,7) + local p1 = vector.offset(pos,-size,-size,-size) + local p2 = vector.offset(pos,size,size,size) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local calcite = {} + local nn = minetest.find_nodes_in_area(p1,p2,{"group:material_stone","group:dirt","mcl_core:gravel"}) + + if not nn or #nn < 2 then + minetest.log("action", "Not enough valid space to generate geode at pos: " .. minetest.pos_to_string(pos)) + return + end + + table.sort(nn,function(a, b) + return vector.distance(pos, a) < vector.distance(pos, b) + end) + --if not nn[1] then return end + + for i=1,pr:next(1, math.max(2, #nn - math.ceil(#nn/5) )) do + set_node_no_bedrock(nn[i],{name="mcl_amethyst:amethyst_block"}) + end + + for k,v in pairs(minetest.find_nodes_in_area(p1,p2,{"mcl_amethyst:amethyst_block"})) do + local all_amethyst = true + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + if an.name ~= "mcl_amethyst:amethyst_block" then + if minetest.get_item_group(an.name,"material_stone") > 0 then + set_node_no_bedrock(pp,{name="mcl_amethyst:calcite"}) + table.insert(calcite,pp) + if pr:next(1,5) == 1 then + set_node_no_bedrock(v,{name="mcl_amethyst:budding_amethyst_block"}) + end + all_amethyst = false + elseif an.name ~= "mcl_amethyst:amethyst_block" and an.name ~= "air" and an.name ~= "mcl_amethyst:budding_amethyst_block" then + all_amethyst = false + end + end + end + if all_amethyst then set_node_no_bedrock(v,{name="air"}) end + end + + for _,v in pairs(calcite) do + for _,vv in pairs(minetest.find_nodes_in_area(vector.offset(v,-1,-1,-1),vector.offset(v,1,1,1),{"group:material_stone"})) do + set_node_no_bedrock(vv,{name="mcl_blackstone:basalt_smooth"}) + end + end + + for k,v in pairs(minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_amethyst:amethyst_block","mcl_amethyst:budding_amethyst_block"})) do + local r = pr:next(1,50) + if r < 10 then + set_node_no_bedrock(vector.offset(v,0,1,0),{name="mcl_amethyst:amethyst_cluster",param2=1}) + end + end + return true + end) + return true +end + +mcl_structures.register_structure("geode",{ + place_on = {"group:material_stone"}, + noise_params = { + offset = 0, + scale = 0.00022, + spread = {x = 250, y = 250, z = 250}, + seed = 7894353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "force_placement", + terrain_feature = true, + y_max = -24, + y_min = mcl_vars.mg_overworld_min, + y_offset = function(pr) return pr:next(-4,-2) end, + place_func = makegeode, +}) diff --git a/mods/MAPGEN/mcl_structures/igloo.lua b/mods/MAPGEN/mcl_structures/igloo.lua new file mode 100644 index 000000000..0fd8c6217 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/igloo.lua @@ -0,0 +1,180 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +function mcl_structures.generate_igloo_top(pos, pr) + -- Furnace does ot work atm because apparently meta is not set. Need a bit of help with fixing this for furnaces, bookshelves, and brewing stands. + local newpos = {x=pos.x,y=pos.y-2,z=pos.z} + local path = modpath.."/schematics/mcl_structures_igloo_top.mts" + local rotation = tostring(pr:next(0,3)*90) + return mcl_structures.place_schematic(newpos, path, rotation, nil, true, nil, function() + local p1 = vector.offset(pos,-5,-5,-5) + local p2 = vector.offset(pos,5,5,5) + mcl_structures.construct_nodes(p1,p2,{"mcl_furnaces:furnace","mcl_books:bookshelf"}) + end), rotation +end + +local function spawn_mobs(p1,p2,vi,zv) + local mc = minetest.find_nodes_in_area_under_air(p1,p2,{"mcl_core:stonebrickmossy"}) + if #mc == 2 then + local vp = mc[1] + local zp = mc[2] + if not vi and zv and zv:get_pos() and vector.distance(mc[1],zv:get_pos()) < 2 then + vp = mc[2] + elseif not zv and vi and vi:get_pos() and vector.distance(mc[2],vi:get_pos()) < 2 then + zp = mc[1] + elseif zv and vi then + return + end + vi = minetest.add_entity(vector.offset(mc[1],0,1,0),"mobs_mc:villager") + zv = minetest.add_entity(vector.offset(mc[2],0,1,0),"mobs_mc:villager_zombie") + minetest.after(1,spawn_mobs,p1,p2,vi,zv) + end +end + +function mcl_structures.generate_igloo_basement(pos, orientation, loot, pr) + -- TODO: Add monster eggs + local path = modpath.."/schematics/mcl_structures_igloo_basement.mts" + mcl_structures.place_schematic(pos, path, orientation, nil, true, nil, function() + local p1 = vector.offset(pos,-5,-5,-5) + local p2 = vector.offset(pos,5,5,5) + mcl_structures.fill_chests(p1,p2,loot,pr) + mcl_structures.construct_nodes(p1,p2,{"mcl_brewing:stand_000","mcl_books:bookshelf"}) + spawn_mobs(p1,p2) + end, pr) +end + +function mcl_structures.generate_igloo(pos, def, pr) + -- Place igloo + local success, rotation = mcl_structures.generate_igloo_top(pos, pr) + -- Place igloo basement with 50% chance + local r = pr:next(1,2) + if r == 1 then + -- Select basement depth + local dim = mcl_worlds.pos_to_dimension(pos) + --local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) + local buffer + if dim == "nether" then + buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10) + elseif dim == "end" then + buffer = pos.y - (mcl_vars.mg_end_min + 1) + elseif dim == "overworld" then + buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) + else + return success + end + if buffer <= 19 then + return success + end + local depth = pr:next(19, buffer) + local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} + -- trapdoor position + local tpos + local dir, tdir + if rotation == "0" then + dir = {x=-1, y=0, z=0} + tdir = {x=1, y=0, z=0} + tpos = {x=pos.x+7, y=pos.y-2, z=pos.z+3} + elseif rotation == "90" then + dir = {x=0, y=0, z=-1} + tdir = {x=0, y=0, z=-1} + tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+1} + elseif rotation == "180" then + dir = {x=1, y=0, z=0} + tdir = {x=-1, y=0, z=0} + tpos = {x=pos.x+1, y=pos.y-2, z=pos.z+3} + elseif rotation == "270" then + dir = {x=0, y=0, z=1} + tdir = {x=0, y=0, z=1} + tpos = {x=pos.x+3, y=pos.y-2, z=pos.z+7} + else + return success + end + local function set_brick(pos) + local c = pr:next(1, 3) -- cracked chance + local m = pr:next(1, 10) -- chance for monster egg + local brick + if m == 1 then + if c == 1 then + brick = "mcl_monster_eggs:monster_egg_stonebrickcracked" + else + brick = "mcl_monster_eggs:monster_egg_stonebrick" + end + else + if c == 1 then + brick = "mcl_core:stonebrickcracked" + else + brick = "mcl_core:stonebrick" + end + end + minetest.set_node(pos, {name=brick}) + end + local ladder_param2 = minetest.dir_to_wallmounted(tdir) + local real_depth = 0 + -- Check how deep we can actuall dig + for y=1, depth-5 do + real_depth = real_depth + 1 + local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z}) + local def = minetest.registered_nodes[node.name] + if not (def and def.walkable and def.liquidtype == "none" and def.is_ground_content) then + bpos.y = tpos.y-y+1 + break + end + end + if real_depth <= 6 then + return success + end + -- Generate ladder to basement + for y=1, real_depth-1 do + set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) + set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z }) + set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1}) + set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1}) + minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) + end + -- Place basement + mcl_structures.generate_igloo_basement(bpos, rotation, def.loot, pr) + -- Place hidden trapdoor + minetest.after(5, function(tpos, dir) + minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 + end, tpos, dir) + end + return success +end + +mcl_structures.register_structure("igloo",{ + place_on = {"mcl_core:snowblock","mcl_core:snow","group:grass_block_snow"}, + fill_ratio = 0.01, + sidelen = 16, + chunk_probability = 250, + solid_ground = true, + make_foundation = true, + y_max = mcl_vars.mg_overworld_max, + y_min = 0, + y_offset = 0, + biomes = { "ColdTaiga", "IcePlainsSpikes", "IcePlains" }, + place_func = mcl_structures.generate_igloo, + loot = { + ["mcl_chests:chest_small"] = {{ + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_core:apple_gold", weight = 1 }, + } + }, + { + stacks_min = 2, + stacks_max = 8, + items = { + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, + { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, + { itemstring = "mcl_tools:axe_stone", weight = 2 }, + { itemstring = "mcl_core:emerald", weight = 1 }, + { itemstring = "mcl_core:apple_gold", weight = 1 }, + } + }}, + } +}) diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index bc3b1b1a7..cd5691fca 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -1,521 +1,122 @@ -local S = minetest.get_translator("mcl_structures") -mcl_structures ={} +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) -mcl_structures.get_struct = function(file) - local localfile = minetest.get_modpath("mcl_structures").."/schematics/"..file - local file, errorload = io.open(localfile, "rb") - if errorload ~= nil then - minetest.log("error", '[mcl_structures] Could not open this struct: ' .. localfile) - return nil - end +mcl_structures = {} - local allnode = file:read("*a") - file:close() +dofile(modpath.."/api.lua") +dofile(modpath.."/shipwrecks.lua") +dofile(modpath.."/desert_temple.lua") +dofile(modpath.."/jungle_temple.lua") +dofile(modpath.."/ocean_ruins.lua") +dofile(modpath.."/witch_hut.lua") +dofile(modpath.."/igloo.lua") +dofile(modpath.."/woodland_mansion.lua") +dofile(modpath.."/ruined_portal.lua") +dofile(modpath.."/geode.lua") +dofile(modpath.."/pillager_outpost.lua") +dofile(modpath.."/end_spawn.lua") +dofile(modpath.."/end_city.lua") - return allnode -end -local mapseed = tonumber(minetest.get_mapgen_setting("seed")) --- Random number generator for all generated structures -local pr = PseudoRandom(mapseed) +mcl_structures.register_structure("desert_well",{ + place_on = {"group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + not_near = { "desert_temple_new" }, + solid_ground = true, + sidelen = 4, + chunk_probability = 600, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + y_offset = -2, + biomes = { "Desert" }, + filenames = { modpath.."/schematics/mcl_structures_desert_well.mts" }, +}) --- Call on_construct on pos. --- Useful to init chests from formspec. -local init_node_construct = function(pos) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - if def and def.on_construct then - def.on_construct(pos) - return true - end - return false -end +mcl_structures.register_structure("fossil",{ + place_on = {"group:material_stone","group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + sidelen = 13, + chunk_probability = 1000, + y_offset = function(pr) return ( pr:next(1,16) * -1 ) -16 end, + y_max = 15, + y_min = mcl_vars.mg_overworld_min + 35, + biomes = { "Desert" }, + filenames = { + modpath.."/schematics/mcl_structures_fossil_skull_1.mts", -- 4×5×5 + modpath.."/schematics/mcl_structures_fossil_skull_2.mts", -- 5×5×5 + modpath.."/schematics/mcl_structures_fossil_skull_3.mts", -- 5×5×7 + modpath.."/schematics/mcl_structures_fossil_skull_4.mts", -- 7×5×5 + modpath.."/schematics/mcl_structures_fossil_spine_1.mts", -- 3×3×13 + modpath.."/schematics/mcl_structures_fossil_spine_2.mts", -- 5×4×13 + modpath.."/schematics/mcl_structures_fossil_spine_3.mts", -- 7×4×13 + modpath.."/schematics/mcl_structures_fossil_spine_4.mts", -- 8×5×13 + }, +}) --- The call of Struct -mcl_structures.call_struct = function(pos, struct_style, rotation) - if not rotation then - rotation = "random" - end - if struct_style == "desert_temple" then - return mcl_structures.generate_desert_temple(pos, rotation) - elseif struct_style == "desert_well" then - return mcl_structures.generate_desert_well(pos, rotation) - elseif struct_style == "igloo" then - return mcl_structures.generate_igloo(pos, rotation) - elseif struct_style == "witch_hut" then - return mcl_structures.generate_witch_hut(pos, rotation) - elseif struct_style == "ice_spike_small" then - return mcl_structures.generate_ice_spike_small(pos, rotation) - elseif struct_style == "ice_spike_large" then - return mcl_structures.generate_ice_spike_large(pos, rotation) - elseif struct_style == "boulder" then - return mcl_structures.generate_boulder(pos, rotation) - elseif struct_style == "fossil" then - return mcl_structures.generate_fossil(pos, rotation) - elseif struct_style == "end_exit_portal" then - return mcl_structures.generate_end_exit_portal(pos, rotation) - elseif struct_style == "end_portal_shrine" then - return mcl_structures.generate_end_portal_shrine(pos, rotation) - end -end +mcl_structures.register_structure("boulder",{ + filenames = { + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder_small.mts", + modpath.."/schematics/mcl_structures_boulder.mts", + -- small boulder 3x as likely + }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct -mcl_structures.generate_desert_well = function(pos) - local newpos = {x=pos.x,y=pos.y-2,z=pos.z} - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_well.mts" - return minetest.place_schematic(newpos, path, "0", nil, true) -end - -mcl_structures.generate_igloo = function(pos) - -- Place igloo - local success, rotation = mcl_structures.generate_igloo_top(pos) - -- Place igloo basement with 50% chance - local r = math.random(1,2) - if success and r == 1 then - -- Select basement depth - local dim = mcl_worlds.pos_to_dimension(pos) - local buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) - if dim == "nether" then - buffer = pos.y - (mcl_vars.mg_lava_nether_max + 10) - elseif dim == "end" then - buffer = pos.y - (mcl_vars.mg_end_min + 1) - elseif dim == "overworld" then - buffer = pos.y - (mcl_vars.mg_lava_overworld_max + 10) - else - return success - end - if buffer <= 19 then - return success - end - local depth = math.random(19, buffer) - local bpos = {x=pos.x, y=pos.y-depth, z=pos.z} - -- trapdoor position - local tpos - local dir, tdir - if rotation == "0" then - dir = {x=-1, y=0, z=0} - tdir = {x=1, y=0, z=0} - tpos = {x=pos.x+7, y=pos.y-1, z=pos.z+3} - elseif rotation == "90" then - dir = {x=0, y=0, z=-1} - tdir = {x=0, y=0, z=-1} - tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+1} - elseif rotation == "180" then - dir = {x=1, y=0, z=0} - tdir = {x=-1, y=0, z=0} - tpos = {x=pos.x+1, y=pos.y-1, z=pos.z+3} - elseif rotation == "270" then - dir = {x=0, y=0, z=1} - tdir = {x=0, y=0, z=1} - tpos = {x=pos.x+3, y=pos.y-1, z=pos.z+7} - else - return success - end - local set_brick = function(pos) - local c = math.random(1, 3) -- cracked chance - local m = math.random(1, 10) -- chance for monster egg - local brick - if m == 1 then - if c == 1 then - brick = "mcl_monster_eggs:monster_egg_stonebrickcracked" - else - brick = "mcl_monster_eggs:monster_egg_stonebrick" - end - else - if c == 1 then - brick = "mcl_core:stonebrickcracked" - else - brick = "mcl_core:stonebrick" - end - end - minetest.set_node(pos, {name=brick}) - end - local ladder_param2 = minetest.dir_to_wallmounted(tdir) - local real_depth = 0 - -- Check how deep we can actuall dig - for y=1, depth-5 do - real_depth = real_depth + 1 - local node = minetest.get_node({x=tpos.x,y=tpos.y-y,z=tpos.z}) - local def = minetest.registered_nodes[node.name] - if (not def) or (not def.walkable) or (def.liquidtype ~= "none") or (not def.is_ground_content) then - bpos.y = tpos.y-y+1 - break - end - end - if real_depth <= 6 then - return success - end - -- Place hidden trapdoor - minetest.set_node(tpos, {name="mcl_doors:trapdoor", param2=20+minetest.dir_to_facedir(dir)}) -- TODO: more reliable param2 - -- Generate ladder to basement - for y=1, real_depth-1 do - set_brick({x=tpos.x-1,y=tpos.y-y,z=tpos.z }) - set_brick({x=tpos.x+1,y=tpos.y-y,z=tpos.z }) - set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z-1}) - set_brick({x=tpos.x ,y=tpos.y-y,z=tpos.z+1}) - minetest.set_node({x=tpos.x,y=tpos.y-y,z=tpos.z}, {name="mcl_core:ladder", param2=ladder_param2}) - end - -- Place basement - mcl_structures.generate_igloo_basement(bpos, rotation) - end - return success -end - -mcl_structures.generate_igloo_top = function(pos) - -- FIXME: This spawns bookshelf instead of furnace. Fix this! - -- Furnace does ot work atm because apparently meta is not set. :-( - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_igloo_top.mts" - local rotation = tostring(math.random(0,3)*90) - return minetest.place_schematic(newpos, path, rotation, nil, true), rotation -end - -mcl_structures.generate_igloo_basement = function(pos, orientation) - -- TODO: Add brewing stand - -- TODO: Add monster eggs - -- TODO: Spawn villager and zombie villager - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_igloo_basement.mts" - - local success = minetest.place_schematic(pos, path, orientation, nil, true) - if success then - local chest_offset - if orientation == "0" then - chest_offset = {x=5, y=1, z=5} - elseif orientation == "90" then - chest_offset = {x=5, y=1, z=3} - elseif orientation == "180" then - chest_offset = {x=3, y=1, z=1} - elseif orientation == "270" then - chest_offset = {x=1, y=1, z=5} - else - return success - end - local size = {x=9,y=5,z=7} - local lootitems = mcl_loot.get_multi_loot({ - { - stacks_min = 1, - stacks_max = 1, - items = { - { itemstring = "mcl_core:apple_gold", weight = 1 }, - } - }, - { - stacks_min = 2, - stacks_max = 8, - items = { - { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, - { itemstring = "mcl_core:apple", weight = 15, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_farming:wheat_item", weight = 10, amount_min = 2, amount_max = 3 }, - { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 3 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10 }, - { itemstring = "mcl_tools:axe_stone", weight = 2 }, - { itemstring = "mcl_core:emerald", weight = 1 }, - } - }}, pr) - - local chest_pos = vector.add(pos, chest_offset) - init_node_construct(chest_pos) - local meta = minetest.get_meta(chest_pos) - local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems) - end - return success -end - -mcl_structures.generate_boulder = function(pos) - -- Choose between 2 boulder sizes (2×2×2 or 3×3×3) - local r = math.random(1, 10) - local path - if r <= 3 then - path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_boulder_small.mts" - else - path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_boulder.mts" - end - - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - return minetest.place_schematic(newpos, path) -end - -mcl_structures.generate_witch_hut = function(pos, rotation) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_witch_hut.mts" - return minetest.place_schematic(pos, path, rotation, nil, true) -end - -mcl_structures.generate_ice_spike_small = function(pos) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_small.mts" - return minetest.place_schematic(pos, path, "random", nil, false) -end - -mcl_structures.generate_ice_spike_large = function(pos) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_ice_spike_large.mts" - return minetest.place_schematic(pos, path, "random", nil, false) -end - -mcl_structures.generate_fossil = function(pos) - -- Generates one out of 8 possible fossil pieces - local newpos = {x=pos.x,y=pos.y-1,z=pos.z} - local fossils = { - "mcl_structures_fossil_skull_1.mts", -- 4×5×5 - "mcl_structures_fossil_skull_2.mts", -- 5×5×5 - "mcl_structures_fossil_skull_3.mts", -- 5×5×7 - "mcl_structures_fossil_skull_4.mts", -- 7×5×5 - "mcl_structures_fossil_spine_1.mts", -- 3×3×13 - "mcl_structures_fossil_spine_2.mts", -- 5×4×13 - "mcl_structures_fossil_spine_3.mts", -- 7×4×13 - "mcl_structures_fossil_spine_4.mts", -- 8×5×13 - } - local r = math.random(1, #fossils) - local path = minetest.get_modpath("mcl_structures").."/schematics/"..fossils[r] - return minetest.place_schematic(newpos, path, "random", nil, true) -end - -mcl_structures.generate_end_exit_portal = function(pos) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts" - return minetest.place_schematic(pos, path, "0", nil, true) -end - -local generate_end_portal_shrine_no_delay = function(newpos) - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_portal_room_simple.mts" - local size = {x=13, y=8, z=13} - local ret = minetest.place_schematic(newpos, path, "0", nil, true) - if ret == nil then - return ret - end - - local area_start, area_end = newpos, vector.add(newpos, size) - -- Find and setup spawner with silverfish - local spawners = minetest.find_nodes_in_area(area_start, area_end, "mcl_mobspawners:spawner") - for s=1, #spawners do - local meta = minetest.get_meta(spawners[s]) - mcl_mobspawners.setup_spawner(spawners[s], "mobs_mc:silverfish") - end - - -- Shuffle stone brick types - local bricks = minetest.find_nodes_in_area(area_start, area_end, "mcl_core:stonebrick") - for b=1, #bricks do - local r_bricktype = pr:next(1, 100) - local r_infested = pr:next(1, 100) - local bricktype - if r_infested <= 5 then - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_monster_eggs:monster_egg_stonebrickcracked" - else -- 50% - bricktype = "mcl_monster_eggs:monster_egg_stonebrick" - end - else - if r_bricktype <= 30 then -- 30% - bricktype = "mcl_core:stonebrickmossy" - elseif r_bricktype <= 50 then -- 20% - bricktype = "mcl_core:stonebrickcracked" - end - -- 50% stonebrick (no change necessary) - end - if bricktype ~= nil then - minetest.set_node(bricks[b], { name = bricktype }) - end - end - - -- Also replace stairs - local stairs = minetest.find_nodes_in_area(area_start, area_end, {"mcl_stairs:stair_stonebrick", "mcl_stairs:stair_stonebrick_outer", "mcl_stairs:stair_stonebrick_inner"}) - for s=1, #stairs do - local stair = minetest.get_node(stairs[s]) - local r_type = pr:next(1, 100) - if r_type <= 30 then -- 30% mossy - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickmossy" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickmossy_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickmossy_inner" - end - minetest.set_node(stairs[s], stair) - elseif r_type <= 50 then -- 20% cracky - if stair.name == "mcl_stairs:stair_stonebrick" then - stair.name = "mcl_stairs:stair_stonebrickcracked" - elseif stair.name == "mcl_stairs:stair_stonebrick_outer" then - stair.name = "mcl_stairs:stair_stonebrickcracked_outer" - elseif stair.name == "mcl_stairs:stair_stonebrick_inner" then - stair.name = "mcl_stairs:stair_stonebrickcracked_inner" - end - minetest.set_node(stairs[s], stair) - end - -- 50% no change - end - - -- Randomly add ender eyes into end portal frames, but never fill the entire frame - local frames = minetest.find_nodes_in_area(area_start, area_end, "mcl_portals:end_portal_frame") - local eyes = 0 - for f=1, #frames do - local r_eye = pr:next(1, 10) - if r_eye == 1 then - eyes = eyes + 1 - if eyes < #frames then - local frame_node = minetest.get_node(frames[f]) - frame_node.name = "mcl_portals:end_portal_frame_eye" - minetest.set_node(frames[f], frame_node) - end - end - end - - return ret -end - -local function ecb_generate_end_portal_shrine(blockpos, action, calls_remaining, param) - if calls_remaining <= 0 then - generate_end_portal_shrine_no_delay({x=param.x, y=param.y, z=param.z}) - end -end - -mcl_structures.generate_end_portal_shrine = function(pos) - local offset = {x=6, y=8, z=6} - local size = {x=13, y=8, z=13} - local newpos = { x = pos.x - offset.x, y = pos.y, z = pos.z - offset.z } - minetest.emerge_area(vector.subtract(newpos,10), vector.add(vector.add(newpos, size),10), ecb_generate_end_portal_shrine, {x=newpos.x, y=newpos.y, z=newpos.z}) -end - -mcl_structures.generate_desert_temple = function(pos) - -- No Generating for the temple ... Why using it ? No Change - local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_desert_temple.mts" - local newpos = {x=pos.x,y=pos.y-12,z=pos.z} - local size = {x=22, y=24, z=22} - if newpos == nil then - return - end - local ret = minetest.place_schematic(newpos, path, "random", nil, true) - if ret == nil then - return ret - end - - -- Find chests. - -- FIXME: Searching this large area just for the chets is not efficient. Need a better way to find the chests; - -- probably let's just infer it from newpos because the schematic always the same. - local chests = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mcl_chests:chest") - - -- Add desert temple loot into chests - for c=1, #chests do - local lootitems = mcl_loot.get_multi_loot({ - { - stacks_min = 2, - stacks_max = 4, - items = { - { itemstring = "mcl_mobitems:bone", weight = 25, amount_min = 4, amount_max=6 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 25, amount_min = 3, amount_max=7 }, - { itemstring = "mcl_mobitems:spider_eye", weight = 25, amount_min = 1, amount_max=3 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 20, }, - { itemstring = "mcl_mobitems:saddle", weight = 20, }, - { itemstring = "mcl_core:apple_gold", weight = 20, }, - { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, - { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, - { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 3 }, - { itemstring = "", weight = 15, }, - { itemstring = "mobs_mc:iron_horse_armor", weight = 15, }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 10, }, - { itemstring = "mobs_mc: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, }, - } - }, - { - stacks_min = 4, - stacks_max = 4, - items = { - { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_core:sand", weight = 10, amount_min = 1, amount_max = 8 }, - { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max = 8 }, - } - }}, pr) - - local meta = minetest.get_meta(chests[c]) - init_node_construct(chests[c]) - local meta = minetest.get_meta(chests[c]) - local inv = meta:get_inventory() - mcl_loot.fill_inventory(inv, "main", lootitems) - end - - -- Initialize pressure plates and randomly remove up to 5 plates - local pplates = minetest.find_nodes_in_area({x=newpos.x-size.x, y=newpos.y, z=newpos.z-size.z}, vector.add(newpos, size), "mesecons_pressureplates:pressure_plate_stone_off") - local pplates_remove = 5 - for p=1, #pplates do - if pplates_remove > 0 and pr:next(1, 100) >= 50 then - -- Remove plate - minetest.remove_node(pplates[p]) - pplates_remove = pplates_remove - 1 - else - -- Initialize plate - minetest.registered_nodes["mesecons_pressureplates:pressure_plate_stone_off"].on_construct(pplates[p]) - end - end - - return ret -end - -local registered_structures = {} - ---[[ Returns a table of structure of the specified type. -Currently the only valid parameter is "stronghold". -Format of return value: -{ - { pos = , generated= }, -- first structure - { pos = , generated= }, -- second structure - -- and so on -} - -TODO: Implement this function for all other structure types as well. -]] -mcl_structures.get_registered_structures = function(structure_type) - if registered_structures[structure_type] then - return table.copy(registered_structures[structure_type]) - else - return {} - end -end - --- Register a structures table for the given type. The table format is the same as for --- mcl_structures.get_registered_structures. -mcl_structures.register_structures = function(structure_type, structures) - registered_structures[structure_type] = structures -end +mcl_structures.register_structure("ice_spike_small",{ + filenames = { modpath.."/schematics/mcl_structures_ice_spike_small.mts" }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct +mcl_structures.register_structure("ice_spike_large",{ + sidelen = 6, + filenames = { modpath.."/schematics/mcl_structures_ice_spike_large.mts" }, +},true) --is spawned as a normal decoration. this is just for /spawnstruct -- Debug command +local function dir_to_rotation(dir) + local ax, az = math.abs(dir.x), math.abs(dir.z) + if ax > az then + if dir.x < 0 then + return "270" + end + return "90" + end + if dir.z < 0 then + return "180" + end + return "0" +end + minetest.register_chatcommand("spawnstruct", { - params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine", + params = "dungeon", description = S("Generate a pre-defined structure near your position."), privs = {debug = true}, func = function(name, param) - local pos = minetest.get_player_by_name(name):get_pos() - if not pos then - return - end + local player = minetest.get_player_by_name(name) + if not player then return end + local pos = player:get_pos() + if not pos then return end pos = vector.round(pos) + local dir = minetest.yaw_to_dir(player:get_look_horizontal()) + local rot = dir_to_rotation(dir) + local pr = PseudoRandom(pos.x+pos.y+pos.z) local errord = false local message = S("Structure placed.") - if param == "desert_temple" then - mcl_structures.generate_desert_temple(pos) - elseif param == "desert_well" then - mcl_structures.generate_desert_well(pos) - elseif param == "igloo" then - mcl_structures.generate_igloo(pos) - elseif param == "witch_hut" then - mcl_structures.generate_witch_hut(pos) - elseif param == "boulder" then - mcl_structures.generate_boulder(pos) - elseif param == "fossil" then - mcl_structures.generate_fossil(pos) - elseif param == "ice_spike_small" then - mcl_structures.generate_ice_spike_small(pos) - elseif param == "ice_spike_large" then - mcl_structures.generate_ice_spike_large(pos) - elseif param == "end_exit_portal" then - mcl_structures.generate_end_exit_portal(pos) - elseif param == "end_portal_shrine" then - mcl_structures.generate_end_portal_shrine(pos) + if param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then + mcl_dungeons.spawn_dungeon(pos, rot, pr) elseif param == "" then message = S("Error: No structure type given. Please use “/spawnstruct ”.") errord = true else + for n,d in pairs(mcl_structures.registered_structures) do + if n == param then + mcl_structures.place_structure(pos,d,pr,math.random(),rot) + return true,message + end + end message = S("Error: Unknown structure type. Please use “/spawnstruct ”.") errord = true end @@ -525,3 +126,10 @@ minetest.register_chatcommand("spawnstruct", { end end }) +minetest.register_on_mods_loaded(function() + local p = "" + for n,_ in pairs(mcl_structures.registered_structures) do + p = p .. " | "..n + end + minetest.registered_chatcommands["spawnstruct"].params = minetest.registered_chatcommands["spawnstruct"].params .. p +end) diff --git a/mods/MAPGEN/mcl_structures/jungle_temple.lua b/mods/MAPGEN/mcl_structures/jungle_temple.lua new file mode 100644 index 000000000..843dec04d --- /dev/null +++ b/mods/MAPGEN/mcl_structures/jungle_temple.lua @@ -0,0 +1,44 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +mcl_structures.register_structure("jungle_temple",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + y_offset = function(pr) return pr:next(-3,0) -5 end, + chunk_probability = 200, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Jungle" }, + sidelen = 18, + filenames = { + modpath.."/schematics/mcl_structures_jungle_temple.mts", + modpath.."/schematics/mcl_structures_jungle_temple_nice.mts", + }, + loot = { + ["mcl_chests:trapped_chest_small" ] ={{ + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_mobitems:bone", weight = 20, amount_min = 4, amount_max=6 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 16, amount_min = 3, amount_max=7 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + --{ itemstring = "mcl_bamboo:bamboo", weight = 15, amount_min = 1, amount_max=3 }, --FIXME BAMBOO + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_mobitems:saddle", weight = 3, }, + { itemstring = "mcl_core:emerald", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr new file mode 100644 index 000000000..12ad5c643 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.ja.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_structures +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 " を使用してください。 +Use /help spawnstruct to see a list of avaiable types.=使用可能なタイプのリストを見るには、 /help spawnstruct を使用してください。 diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.pl.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.pl.tr new file mode 100644 index 000000000..a0a1c69f2 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.pl.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_structures +Generate a pre-defined structure near your position.=Wygeneruj predefiniowaną strukturę nieopodal twojej pozycji. +Structure placed.=Struktura postawiona. +Village built. WARNING: Villages are experimental and might have bugs.=Wioska zbudowana. UWAGA: Wioski są eksperymentalne i mogą występować błędy. +Error: No structure type given. Please use “/spawnstruct ”.=Błąd: Nie podano typu struktury. Użyj "/spawnstruct ". +Error: Unknown structure type. Please use “/spawnstruct ”.=Błąd: Nieznany typ struktury. Użyj "/spawnstruct ". +Use /help spawnstruct to see a list of avaiable types.=Użyj /help spawnstruct aby zobaczyć listę dostępnych typów. + diff --git a/mods/MAPGEN/mcl_structures/locale/mcl_structures.zh_TW.tr b/mods/MAPGEN/mcl_structures/locale/mcl_structures.zh_TW.tr new file mode 100644 index 000000000..49796e520 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/locale/mcl_structures.zh_TW.tr @@ -0,0 +1,7 @@ +# textdomain: mcl_structures +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 <種類>」。 +Use /help spawnstruct to see a list of avaiable types.=使用「/help spawnstruct」以查看可用結構列表。 diff --git a/mods/MAPGEN/mcl_structures/mod.conf b/mods/MAPGEN/mcl_structures/mod.conf index 862441905..823714aad 100644 --- a/mods/MAPGEN/mcl_structures/mod.conf +++ b/mods/MAPGEN/mcl_structures/mod.conf @@ -1 +1,4 @@ name = mcl_structures +author = Wuzzy, cora +description = Structure placement for MCL2 +depends = mcl_init, mcl_loot diff --git a/mods/MAPGEN/mcl_structures/ocean_ruins.lua b/mods/MAPGEN/mcl_structures/ocean_ruins.lua new file mode 100644 index 000000000..0b609aee7 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/ocean_ruins.lua @@ -0,0 +1,132 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local cold_oceans = { + "RoofedForest_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "ExtremeHillsM_deep_ocean", + "SunflowerPlains_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "StoneBeach_ocean", + "ColdTaiga_deep_ocean", + "Forest_deep_ocean", + "FlowerForest_deep_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", +} + +local warm_oceans = { + "JungleEdgeM_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "Swampland_ocean", + "Mesa_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "MushroomIsland_ocean", + "SavannaM_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "Jungle_ocean", + "Desert_ocean", + "JungleM_ocean", + "JungleEdgeM_deep_ocean", + "Jungle_deep_ocean", + "Savanna_deep_ocean", + "MesaPlateauF_deep_ocean", + "Swampland_deep_ocean", + "Mesa_deep_ocean", + "Plains_deep_ocean", + "MesaPlateauFM_deep_ocean", + "MushroomIsland_deep_ocean", + "SavannaM_deep_ocean", + "JungleEdge_deep_ocean", + "MesaBryce_deep_ocean", + "Jungle_deep_ocean", + "Desert_deep_ocean", + "JungleM_deep_ocean", +} + +local cold = { + place_on = {"group:sand","mcl_core:gravel","mcl_core:dirt","mcl_core:clay","group:material_stone"}, + spawn_by = {"mcl_core:water_source"}, + num_spawn_by = 2, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, force_placement", + solid_ground = true, + make_foundation = true, + y_offset = -1, + y_min = mcl_vars.mg_overworld_min, + y_max = -2, + biomes = cold_oceans, + chunk_probability = 400, + sidelen = 20, + filenames = { + modpath.."/schematics/mcl_structures_ocean_ruins_cold_1.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_cold_2.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_cold_3.mts", + }, + loot = { + ["mcl_chests:chest_small" ] = { + { + stacks_min = 2, + stacks_max = 4, + items = { + { itemstring = "mcl_core:coal_lump", weight = 25, amount_min = 1, amount_max=4 }, + { itemstring = "mcl_farming:wheat_item", weight = 25, amount_min = 2, amount_max=3 }, + { itemstring = "mcl_core:gold_nugget", weight = 25, amount_min = 1, amount_max=3 }, + --{ itemstring = "mcl_maps:treasure_map", weight = 20, }, --FIXME Treasure map + + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_fishing:fishing_rod_enchanted", weight = 20, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_core:emerald", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_armor:chestplate_leather", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:apple_gold", weight = 20, }, + { itemstring = "mcl_armor:helmet_gold", weight = 15, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + { itemstring = "mcl_core:iron_ingot", weight = 15, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + } + } + }, +} + +local warm = table.copy(cold) +warm.biomes = warm_oceans +warm.filenames = { + modpath.."/schematics/mcl_structures_ocean_ruins_warm_1.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_2.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_3.mts", + modpath.."/schematics/mcl_structures_ocean_ruins_warm_4.mts", +} + +mcl_structures.register_structure("cold_ocean_ruins",cold) +mcl_structures.register_structure("warm_ocean_ruins",warm) diff --git a/mods/MAPGEN/mcl_structures/pillager_outpost.lua b/mods/MAPGEN/mcl_structures/pillager_outpost.lua new file mode 100644 index 000000000..53652d4fb --- /dev/null +++ b/mods/MAPGEN/mcl_structures/pillager_outpost.lua @@ -0,0 +1,87 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local spawnon = {"mcl_core:stripped_oak","mcl_stairs:slab_birchwood_top"} + +mcl_structures.register_structure("pillager_outpost",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass","group:sand"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + sidelen = 32, + y_offset = 0, + chunk_probability = 600, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "Desert", "Plains", "Savanna", "IcePlains", "Taiga" }, + construct_nodes = {"mcl_anvils:anvil_damage_2"}, + filenames = { + modpath.."/schematics/mcl_structures_pillager_outpost.mts", + modpath.."/schematics/mcl_structures_pillager_outpost_2.mts" + }, + loot = { + ["mcl_chests:chest_small" ] ={ + { + stacks_min = 2, + stacks_max = 3, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 3, amount_max=5 }, + { itemstring = "mcl_farming:carrot_item", weight = 5, amount_min = 3, amount_max=5 }, + { itemstring = "mcl_farming:potato_item", weight = 5, amount_min = 2, amount_max=5 }, + } + }, + { + stacks_min = 1, + stacks_max = 2, + items = { + { itemstring = "mcl_experience:bottle", weight = 6, amount_min = 0, amount_max=1 }, + { itemstring = "mcl_bows:arrow", weight = 4, amount_min = 2, amount_max=7 }, + { itemstring = "mcl_mobitems:string", weight = 4, amount_min = 1, amount_max=6 }, + { itemstring = "mcl_core:iron_ingot", weight = 3, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + } + }, + { + stacks_min = 1, + stacks_max = 3, + items = { + { itemstring = "mcl_core:darktree", amount_min = 2, amount_max=3 }, + } + }, + { + stacks_min = 1, + stacks_max = 1, + items = { + { itemstring = "mcl_bows:crossbow" }, + } + }} + }, + after_place = function(p,def,pr) + local p1 = vector.offset(p,-9,0,-9) + local p2 = vector.offset(p,9,32,9) + mcl_structures.spawn_mobs("mobs_mc:pillager",spawnon,p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:parrot",{"mesecons_pressureplates:pressure_plate_stone_off"},p1,p2,pr,3) + mcl_structures.spawn_mobs("mobs_mc:iron_golem",{"mesecons_button:button_stone_off"},p1,p2,pr,1) + for _,n in pairs(minetest.find_nodes_in_area(p1,p2,{"group:wall"})) do + local def = minetest.registered_nodes[minetest.get_node(n).name:gsub("_%d+$","")] + if def and def.on_construct then + def.on_construct(n) + end + end + end +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:pillager", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/ruined_portal.lua b/mods/MAPGEN/mcl_structures/ruined_portal.lua new file mode 100644 index 000000000..0f7df6686 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/ruined_portal.lua @@ -0,0 +1,110 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local function get_replacements(b,c,pr) + local r = {} + if not b then return r end + for k,v in pairs(b) do + if pr:next(1,100) < c then table.insert(r,v) end + end + return r +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, + flags = "place_center_x, place_center_z, all_floors", + solid_ground = true, + make_foundation = true, + chunk_probability = 800, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + sidelen = 10, + y_offset = -5, + filenames = { + modpath.."/schematics/mcl_structures_ruined_portal_1.mts", + modpath.."/schematics/mcl_structures_ruined_portal_2.mts", + modpath.."/schematics/mcl_structures_ruined_portal_3.mts", + modpath.."/schematics/mcl_structures_ruined_portal_4.mts", + modpath.."/schematics/mcl_structures_ruined_portal_5.mts", + modpath.."/schematics/mcl_structures_ruined_portal_99.mts", + }, + after_place = function(pos,def,pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + local gold = minetest.find_nodes_in_area(p1,p2,{"mcl_core:goldblock"}) + local lava = minetest.find_nodes_in_area(p1,p2,{"mcl_core:lava_source"}) + local rack = minetest.find_nodes_in_area(p1,p2,{"mcl_nether:netherrack"}) + local brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) + local obby = minetest.find_nodes_in_area(p1,p2,{"mcl_core:obsidian"}) + minetest.bulk_set_node(get_replacements(gold,30,pr),{name="air"}) + minetest.bulk_set_node(get_replacements(lava,20,pr),{name="mcl_nether:magma"}) + minetest.bulk_set_node(get_replacements(rack,7,pr),{name="mcl_nether:magma"}) + minetest.bulk_set_node(get_replacements(obby,30,pr),{name="mcl_core:crying_obsidian"}) + minetest.bulk_set_node(get_replacements(obby,10,pr),{name="air"}) + minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickcracked"}) + brick = minetest.find_nodes_in_area(p1,p2,{"mcl_core:stonebrick"}) + minetest.bulk_set_node(get_replacements(brick,50,pr),{name="mcl_core:stonebrickmossy"}) + end, + loot = { + ["mcl_chests:chest_small" ] ={{ + stacks_min = 4, + stacks_max = 8, + items = { + { itemstring = "mcl_core:iron_nugget", weight = 40, amount_min = 9, amount_max = 18 }, + { itemstring = "mcl_core:flint", weight = 40, amount_min = 1, amount_max=4 }, + { itemstring = "mcl_core:obsidian", weight = 40, amount_min = 1, amount_max=2 }, + { itemstring = "mcl_fire:fire_charge", weight = 40, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_fire:flint_and_steel", weight = 40, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_nugget", weight = 15, amount_min = 4, amount_max = 24 }, + { itemstring = "mcl_core:apple_gold", weight = 15, }, + + { itemstring = "mcl_tools:axe_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_farming:hoe_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_tools:pick_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_tools:shovel_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_tools:sword_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + + { itemstring = "mcl_armor:helmet_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_armor:chestplate_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_armor:leggings_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + { itemstring = "mcl_armor:boots_gold", weight = 15, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, + + { itemstring = "mcl_potions:speckled_melon", weight = 5, amount_min = 4, amount_max = 12 }, + { itemstring = "mcl_farming:carrot_item_gold", weight = 5, amount_min = 4, amount_max = 12 }, + + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 2, amount_max = 8 }, + { itemstring = "mcl_clock:clock", weight = 5, }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1, }, + { itemstring = "mcl_core:goldblock", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_bells:bell", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 1, }, + } + }} + } +} +mcl_structures.register_structure("ruined_portal_overworld",def) +local ndef = table.copy(def) +ndef.y_min=mcl_vars.mg_lava_nether_max +10 +ndef.y_max=mcl_vars.mg_nether_max - 15 +ndef.place_on = {"mcl_nether:netherrack","group:soul_block","mcl_blackstone:basalt,mcl_blackstone:blackstone","mcl_crimson:crimson_nylium","mcl_crimson:warped_nylium"}, +mcl_structures.register_structure("ruined_portal_nether",ndef) diff --git a/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts b/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts new file mode 100644 index 000000000..8ee971820 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/coral_cora.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts new file mode 100644 index 000000000..03e1ddfb6 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts new file mode 100644 index 000000000..f40af2ec3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_brain_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts new file mode 100644 index 000000000..1111368e8 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts new file mode 100644 index 000000000..c3cf1012e Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_bubble_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts new file mode 100644 index 000000000..fffbfb26f Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts new file mode 100644 index 000000000..a55b3995f Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_fire_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts new file mode 100644 index 000000000..03c8f0e85 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts new file mode 100644 index 000000000..8d2ec7f2b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_horn_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts new file mode 100644 index 000000000..89d08e9ea Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts new file mode 100644 index 000000000..cd4372f95 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_coral_tube_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts new file mode 100644 index 000000000..a334a4bdc Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_boat.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts new file mode 100644 index 000000000..24b06a1c8 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_gateway_portal.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts new file mode 100644 index 000000000..5daad2f3d Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_shipwreck_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts index c2a774e78..2bc92ae5d 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_basement.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts index e3705236e..5a2a96dea 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_igloo_top.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts new file mode 100644 index 000000000..ec98a83ea Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts new file mode 100644 index 000000000..8a9babb9b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_jungle_temple_nice.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts new file mode 100644 index 000000000..1b2c8d1f3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts new file mode 100644 index 000000000..d7437d7ce Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts new file mode 100644 index 000000000..67cb5c9ac Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_cold_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts new file mode 100644 index 000000000..072931b13 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts new file mode 100644 index 000000000..9834226fa Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts new file mode 100644 index 000000000..eb43cdf1c Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts new file mode 100644 index 000000000..0eb5bacf0 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_ruins_warm_4.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts new file mode 100644 index 000000000..0a16fa9b2 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts new file mode 100644 index 000000000..8a5a6a313 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ocean_temple_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts new file mode 100644 index 000000000..35424ad76 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts new file mode 100644 index 000000000..4a7727acf Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_pillager_outpost_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts new file mode 100644 index 000000000..55a6f2ae3 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_1.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts new file mode 100644 index 000000000..9da16e2ed Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_2.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts new file mode 100644 index 000000000..88c0acb28 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_3.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts new file mode 100644 index 000000000..404256ed9 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_4.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts new file mode 100644 index 000000000..f14105154 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_5.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts new file mode 100644 index 000000000..463bf19df Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_ruined_portal_99.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts new file mode 100644 index 000000000..12f3c9b13 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_back_damaged.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts new file mode 100644 index 000000000..5c8a3e105 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_damaged.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts new file mode 100644 index 000000000..3d997c83b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_full_normal.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts new file mode 100644 index 000000000..f58376f30 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_back.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts new file mode 100644 index 000000000..41efb386b Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_shipwreck_half_front.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts new file mode 100644 index 000000000..f654da926 Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_cabin.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts new file mode 100644 index 000000000..8ee1daffa Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_woodland_outpost.mts differ diff --git a/mods/MAPGEN/mcl_structures/shipwrecks.lua b/mods/MAPGEN/mcl_structures/shipwrecks.lua new file mode 100644 index 000000000..a9c48e0b5 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/shipwrecks.lua @@ -0,0 +1,263 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +--local S = minetest.get_translator(modname) + +local seed = minetest.get_mapgen_setting("seed") +local water_level = minetest.get_mapgen_setting("water_level") +local pr = PseudoRandom(seed) + +--schematics by chmodsayshello +local schems = { + modpath.."/schematics/mcl_structures_shipwreck_full_damaged.mts", + modpath.."/schematics/mcl_structures_shipwreck_full_normal.mts", + modpath.."/schematics/mcl_structures_shipwreck_full_back_damaged.mts", + modpath.."/schematics/mcl_structures_shipwreck_half_front.mts", + modpath.."/schematics/mcl_structures_shipwreck_half_back.mts", +} + +local ocean_biomes = { + "RoofedForest_ocean", + "JungleEdgeM_ocean", + "BirchForestM_ocean", + "BirchForest_ocean", + "IcePlains_deep_ocean", + "Jungle_deep_ocean", + "Savanna_ocean", + "MesaPlateauF_ocean", + "ExtremeHillsM_deep_ocean", + "Savanna_deep_ocean", + "SunflowerPlains_ocean", + "Swampland_deep_ocean", + "Swampland_ocean", + "MegaSpruceTaiga_deep_ocean", + "ExtremeHillsM_ocean", + "JungleEdgeM_deep_ocean", + "SunflowerPlains_deep_ocean", + "BirchForest_deep_ocean", + "IcePlainsSpikes_ocean", + "Mesa_ocean", + "StoneBeach_ocean", + "Plains_deep_ocean", + "JungleEdge_deep_ocean", + "SavannaM_deep_ocean", + "Desert_deep_ocean", + "Mesa_deep_ocean", + "ColdTaiga_deep_ocean", + "Plains_ocean", + "MesaPlateauFM_ocean", + "Forest_deep_ocean", + "JungleM_deep_ocean", + "FlowerForest_deep_ocean", + "MushroomIsland_ocean", + "MegaTaiga_ocean", + "StoneBeach_deep_ocean", + "IcePlainsSpikes_deep_ocean", + "ColdTaiga_ocean", + "SavannaM_ocean", + "MesaPlateauF_deep_ocean", + "MesaBryce_deep_ocean", + "ExtremeHills+_deep_ocean", + "ExtremeHills_ocean", + "MushroomIsland_deep_ocean", + "Forest_ocean", + "MegaTaiga_deep_ocean", + "JungleEdge_ocean", + "MesaBryce_ocean", + "MegaSpruceTaiga_ocean", + "ExtremeHills+_ocean", + "Jungle_ocean", + "RoofedForest_deep_ocean", + "IcePlains_ocean", + "FlowerForest_ocean", + "ExtremeHills_deep_ocean", + "MesaPlateauFM_deep_ocean", + "Desert_ocean", + "Taiga_ocean", + "BirchForestM_deep_ocean", + "Taiga_deep_ocean", + "JungleM_ocean" +} + +local beach_biomes = { + "FlowerForest_beach", + "Forest_beach", + "StoneBeach", + "ColdTaiga_beach_water", + "Taiga_beach", + "Savanna_beach", + "Plains_beach", + "ExtremeHills_beach", + "ColdTaiga_beach", + "Swampland_shore", + "MushroomIslandShore", + "JungleM_shore", + "Jungle_shore" +} + +mcl_structures.register_structure("shipwreck",{ + place_on = {"group:sand","mcl_core:gravel"}, + spawn_by = {"group:water"}, + num_spawn_by = 4, + noise_params = { + offset = 0, + scale = 0.000022, + spread = {x = 250, y = 250, z = 250}, + seed = 3, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + sidelen = 16, + flags = "force_placement", + biomes = ocean_biomes, + y_max = water_level-4, + y_min = mcl_vars.mg_overworld_min, + filenames = schems, + y_offset = function(pr) return pr:next(-4,-2) end, + loot = { + ["mcl_chests:chest_small"] = { + stacks_min = 3, + stacks_max = 10, + items = { + { itemstring = "mcl_sus_stew:stew", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 }, + { itemstring = "mcl_farming:wheat_item", weight = 7, amount_min = 8, amount_max = 21 }, + { itemstring = "mcl_farming:carrot_item", weight = 7, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_farming:potato_item_poison", weight = 7, amount_min = 2, amount_max = 6 }, + { itemstring = "mcl_farming:potato_item", weight = 7, amount_min = 2, amount_max = 6 }, + --{ itemstring = "TODO:moss_block", weight = 7, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_core:coal_lump", weight = 6, amount_min = 2, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 5, amount_min = 5, amount_max = 24 }, + { itemstring = "mcl_farming:potato_item", weight = 3, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_armor:helmet_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:chestplate_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:leggings_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + { itemstring = "mcl_armor:boots_leather_enchanted", weight = 3, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}) end }, + --{ itemstring = "TODO:bamboo", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_farming:pumpkin", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, + + }, + { + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_core:iron_ingot", weight = 90, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:iron_nugget", weight = 50, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_core:emerald", weight = 40, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:lapis", weight = 20, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_core:gold_ingot", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:gold_nugget", weight = 10, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 }, + } + },{ + stacks_min = 3, + stacks_max = 3, + items = { + --{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:paper", weight = 20, amount_min = 1, amount_max = 10 }, + { itemstring = "mcl_mobitems:feather", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_books:book", weight = 5, amount_min = 1, amount_max = 5 }, + { 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 }, + + } + }, + } + } +}) + +local spawnon = { "mcl_stairs:slab_prismarine_dark"} + +mcl_structures.register_structure("ocean_temple",{ + place_on = {"group:sand","mcl_core:gravel"}, + spawn_by = {"group:water"}, + num_spawn_by = 4, + noise_params = { + offset = 0, + scale = 0.0000122, + spread = {x = 250, y = 250, z = 250}, + seed = 32345, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + sidelen = 32, + flags = "force_placement", + biomes = ocean_biomes, + y_max = water_level-4, + y_min = mcl_vars.mg_overworld_min, + filenames = { + modpath .. "/schematics/mcl_structures_ocean_temple.mts", + modpath .. "/schematics/mcl_structures_ocean_temple_2.mts", + }, + y_offset = function(pr) return pr:next(-2,0) end, + after_place = function(p,def,pr) + local p1 = vector.offset(p,-9,0,-9) + local p2 = vector.offset(p,9,32,9) + mcl_structures.spawn_mobs("mobs_mc:guardian",spawnon,p1,p2,pr,5,true) + mcl_structures.spawn_mobs("mobs_mc:guardian_elder",spawnon,p1,p2,pr,1,true) + mcl_structures.construct_nodes(p1,p2,{"group:wall"}) + end, + loot = { + ["mcl_chests:chest_small"] = { + stacks_min = 3, + stacks_max = 10, + items = { + { itemstring = "mcl_sus_stew:stew", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:paper", weight = 8, amount_min = 1, amount_max = 12 }, + { itemstring = "mcl_fishing:fish_raw", weight = 5, amount_min = 8, amount_max = 21 }, + { itemstring = "mcl_fishing:salmon_raw", weight = 7, amount_min = 4, amount_max = 8 }, + { itemstring = "mcl_tnt:tnt", weight = 1, amount_min = 1, amount_max = 2 }, + }, + { + stacks_min = 2, + stacks_max = 6, + items = { + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_core:goldblock", weight = 1, amount_min = 1, amount_max = 2 }, + { itemstring = "mcl_experience:bottle", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:diamond", weight = 5, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_fishing:fishing_rod", weight = 1, amount_min = 1, amount_max = 1 }, + } + }, + { + stacks_min = 4, + stacks_max = 4, + items = { + --{ itemstring = "FIXME TREASURE MAP", weight = 8, amount_min = 1, amount_max = 5 }, + { itemstring = "mcl_books:book", weight = 1, amount_min = 1, amount_max = 5 }, + { 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 }, + } + }, + } + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:guardian", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 9, + spawnon = spawnon, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:guardian_elder", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 100, + interval = 60, + limit = 4, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_structures/witch_hut.lua b/mods/MAPGEN/mcl_structures/witch_hut.lua new file mode 100644 index 000000000..5ac23b144 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/witch_hut.lua @@ -0,0 +1,54 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) + +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local function spawn_witch(p1,p2) + local c = minetest.find_node_near(p1,15,{"mcl_cauldrons:cauldron"}) + if c then + local nn = minetest.find_nodes_in_area_under_air(vector.new(p1.x,c.y-1,p1.z),vector.new(p2.x,c.y-1,p2.z),{"mcl_core:sprucewood"}) + local witch + if not peaceful then + witch = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:witch"):get_luaentity() + witch._home = c + witch.can_despawn = false + end + local cat = minetest.add_entity(vector.offset(nn[math.random(#nn)],0,1,0),"mobs_mc:cat"):get_luaentity() + cat.object:set_properties({textures = {"mobs_mc_cat_black.png"}}) + cat.owner = "!witch!" --so it's not claimable by player + cat._home = c + cat.can_despawn = false + return + end +end + +local function hut_placement_callback(pos,def,pr) + local hl = def.sidelen / 2 + local p1 = vector.offset(pos,-hl,-hl,-hl) + local p2 = vector.offset(pos,hl,hl,hl) + local legs = minetest.find_nodes_in_area(vector.offset(pos,-hl,0,-hl),vector.offset(pos,hl,0,hl), "mcl_core:tree") + local tree = {} + for _,leg in pairs(legs) do + while minetest.get_item_group(mcl_vars.get_node(vector.offset(leg,0,-1,0), true, 333333).name, "water") ~= 0 do + leg = vector.offset(leg,0,-1,0) + table.insert(tree,leg) + end + end + minetest.bulk_set_node(tree, {name = "mcl_core:tree", param2 = 2}) + spawn_witch(p1,p2) +end + +mcl_structures.register_structure("witch_hut",{ + place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z, liquid_surface, force_placement", + sidelen = 8, + chunk_probability = 300, + y_max = mcl_vars.mg_overworld_max, + y_min = -4, + y_offset = 0, + biomes = { "Swampland", "Swampland_ocean", "Swampland_shore" }, + filenames = { modpath.."/schematics/mcl_structures_witch_hut.mts" }, + after_place = hut_placement_callback, +}) diff --git a/mods/MAPGEN/mcl_structures/woodland_mansion.lua b/mods/MAPGEN/mcl_structures/woodland_mansion.lua new file mode 100644 index 000000000..5429e4892 --- /dev/null +++ b/mods/MAPGEN/mcl_structures/woodland_mansion.lua @@ -0,0 +1,89 @@ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) +local modpath = minetest.get_modpath(modname) +local peaceful = minetest.settings:get_bool("only_peaceful_mobs", false) + +local spawnon = {"mcl_deepslate:deepslate","mcl_core:birchwood","mcl_wool:red_carpet","mcl_wool:brown_carpet"} + +mcl_structures.register_structure("woodland_cabin",{ + place_on = {"group:grass_block","group:dirt","mcl_core:dirt_with_grass"}, + fill_ratio = 0.01, + flags = "place_center_x, place_center_z", + solid_ground = true, + make_foundation = true, + chunk_probability = 800, + y_max = mcl_vars.mg_overworld_max, + y_min = 1, + biomes = { "RoofedForest" }, + sidelen = 32, + filenames = { + modpath.."/schematics/mcl_structures_woodland_cabin.mts", + modpath.."/schematics/mcl_structures_woodland_outpost.mts", + }, + construct_nodes = {"mcl_barrels:barrel_closed","mcl_books:bookshelf"}, + after_place = function(p,def,pr) + local p1=vector.offset(p,-def.sidelen,-1,-def.sidelen) + local p2=vector.offset(p,def.sidelen,def.sidelen,def.sidelen) + mcl_structures.spawn_mobs("mobs_mc:vindicator",spawnon,p1,p2,pr,5) + mcl_structures.spawn_mobs("mobs_mc:evoker",spawnon,p1,p2,pr,1) + mcl_structures.spawn_mobs("mobs_mc:parrot",{"mcl_heads:wither_skeleton"},p1,p2,pr,1) + end, + loot = { + ["mcl_chests:chest_small" ] ={{ + stacks_min = 3, + stacks_max = 3, + items = { + { itemstring = "mcl_mobitems:bone", weight = 10, amount_min = 1, amount_max=8 }, + { itemstring = "mcl_mobitems:gunpowder", weight = 10, amount_min = 1, amount_max = 8 }, + { itemstring = "mcl_mobitems:rotten_flesh", weight = 10, amount_min = 1, amount_max=8 }, + { itemstring = "mcl_mobitems:string", weight = 10, amount_min = 1, amount_max=8 }, + + { itemstring = "mcl_core:gold_ingot", weight = 15, amount_min = 2, amount_max = 7 }, + }},{ + stacks_min = 1, + stacks_max = 4, + items = { + { itemstring = "mcl_farming:wheat_item", weight = 20, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:bread", weight = 20, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:coal_lump", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mesecons:mesecon", weight = 15, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_farming:beetroot_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, + { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 4 }, + { itemstring = "mcl_buckets:bucket_empty", weight = 10, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 4 }, + }},{ + stacks_min = 1, + stacks_max = 4, + items = { + --{ itemstring = "FIXME:lead", weight = 20, amount_min = 1, amount_max = 1 }, + { itemstring = "mcl_mobs:nametag", weight = 2, amount_min = 1, amount_max = 3 }, + { itemstring = "mcl_books:book", weight = 1, func = function(stack, pr)mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) end }, + { itemstring = "mcl_armor:chestplate_chain", weight = 1, }, + { itemstring = "mcl_armor:chestplate_diamond", weight = 1, }, + { itemstring = "mcl_core:apple_gold_enchanted", weight = 2, }, + } + }} + } +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:vindicator", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 10, + interval = 60, + limit = 6, + spawnon = spawnon, +}) + +mcl_structures.register_structure_spawn({ + name = "mobs_mc:evoker", + y_min = mcl_vars.mg_overworld_min, + y_max = mcl_vars.mg_overworld_max, + chance = 50, + interval = 60, + limit = 6, + spawnon = spawnon, +}) diff --git a/mods/MAPGEN/mcl_terrain_features/init.lua b/mods/MAPGEN/mcl_terrain_features/init.lua new file mode 100644 index 000000000..eab33e78e --- /dev/null +++ b/mods/MAPGEN/mcl_terrain_features/init.lua @@ -0,0 +1,374 @@ +local adjacents = { + vector.new(1,0,0), + vector.new(1,0,1), + vector.new(1,0,-1), + vector.new(-1,0,0), + vector.new(-1,0,1), + vector.new(-1,0,-1), + vector.new(0,0,1), + vector.new(0,0,-1), + vector.new(0,-1,0) +} + +local plane_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +local function set_node_no_bedrock(pos,node) + local n = minetest.get_node(pos) + if n.name == "mcl_core:bedrock" then return end + return minetest.set_node(pos,node) +end + +local function airtower(pos,tbl,h) + for i=1,h do + table.insert(tbl,vector.offset(pos,0,i,0)) + end +end + +local function makelake(pos,size,liquid,placein,border,pr,noair) + local node_under = minetest.get_node(vector.offset(pos,0,-1,0)) + local p1 = vector.offset(pos,-size,-1,-size) + local p2 = vector.offset(pos,size,-1,size) + minetest.emerge_area(p1, p2, function(blockpos, action, calls_remaining, param) + if calls_remaining ~= 0 then return end + local nn = minetest.find_nodes_in_area(p1,p2,placein) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if not nn[1] then return end + local y = pos.y - pr:next(1,2) + local lq = {} + local air = {} + local r = pr:next(1,#nn) + if r > #nn then return end + for i=1,r do + if nn[i].y == y then + airtower(nn[i],air,55) + table.insert(lq,nn[i]) + end + end + minetest.bulk_set_node(lq,{name=liquid}) + minetest.bulk_set_node(air,{name="air"}) + air = {} + local br = {} + for k,v in pairs(lq) do + for kk,vv in pairs(adjacents) do + local pp = vector.add(v,vv) + local an = minetest.get_node(pp) + local un = minetest.get_node(vector.offset(pp,0,1,0)) + if not border then + if minetest.get_item_group(an.name,"solid") > 0 then + border = an.name + elseif minetest.get_item_group(minetest.get_node(nn[1]).name,"solid") > 0 then + border = minetest.get_node_or_nil(nn[1]).name + else + border = "mcl_core:stone" + end + if border == nil or border == "mcl_core:dirt" then border = "mcl_core:dirt_with_grass" end + end + if not noair and an.name ~= liquid then + table.insert(br,pp) + if un.name ~= liquid then + airtower(pp,air,55) + end + end + end + end + minetest.bulk_set_node(br,{name=border}) + minetest.bulk_set_node(air,{name="air"}) + return true + end) + return true +end + +local mushrooms = {"mcl_mushrooms:mushroom_brown","mcl_mushrooms:mushroom_red"} + +local function get_fallen_tree_schematic(pos,pr) + local tree = minetest.find_node_near(pos,15,{"group:tree"}) + if not tree then return end + tree = minetest.get_node(tree).name + local maxlen = 8 + local minlen = 2 + local vprob = 120 + local mprob = 160 + local len = pr:next(minlen,maxlen) + local schem = { + size = {x = len + 2, y = 2, z = 3}, + data = { + {name = "air", prob=0}, + {name = "air", prob=0}, + } + } + for i = 1,len do + table.insert(schem.data,{name = "mcl_core:vine",param2=4, prob=vprob}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "air", prob=0}) + end + + table.insert(schem.data,{name = tree, param2 = 0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = tree, param2 = 12}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = mushrooms[pr:next(1,#mushrooms)], param2 = 12, prob=mprob}) + end + + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "mcl_core:vine",param2=5, prob=vprob}) + end + table.insert(schem.data,{name = "air", prob=0}) + table.insert(schem.data,{name = "air", prob=0}) + for i = 1,len do + table.insert(schem.data,{name = "air", prob=0}) + end + + return schem +end + +mcl_structures.register_structure("fallen_tree",{ + place_on = {"group:grass_block"}, + terrain_feature = true, + noise_params = { + offset = 0.00018, + scale = 0.01011, + spread = {x = 250, y = 250, z = 250}, + seed = 24533, + octaves = 3, + persist = 0.66 + }, + flags = "place_center_x, place_center_z", + sidelen = 18, + solid_ground = true, + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + on_place = function(pos,def,pr) + local air_p1 = vector.offset(pos,-def.sidelen/2,1,-def.sidelen/2) + local air_p2 = vector.offset(pos,def.sidelen/2,1,def.sidelen/2) + local air = minetest.find_nodes_in_area(air_p1,air_p2,{"air"}) + if #air < ( def.sidelen * def.sidelen ) / 2 then + return false + end + return true + end, + place_func = function(pos,def,pr) + local schem=get_fallen_tree_schematic(pos,pr) + if not schem then return end + return minetest.place_schematic(pos,schem,"random") + end +}) + +mcl_structures.register_structure("lavapool",{ + place_on = {"group:sand", "group:dirt", "group:stone"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.0000022, + spread = {x = 250, y = 250, z = 250}, + seed = 78375213, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:lava_source",{"group:material_stone", "group:sand", "group:dirt"},"mcl_core:stone",pr) + end +}) + +mcl_structures.register_structure("water_lake",{ + place_on = {"group:dirt","group:stone"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.000032, + spread = {x = 250, y = 250, z = 250}, + seed = 756641353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,5,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block"},"mcl_core:dirt_with_grass",pr) + end +}) + +mcl_structures.register_structure("water_lake_mangrove_swamp",{ + place_on = {"mcl_mud:mud"}, + biomes = { "MangroveSwamp" }, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.0032, + spread = {x = 250, y = 250, z = 250}, + seed = 6343241353, + octaves = 3, + persist = 0.001, + flags = "absvalue", + }, + flags = "place_center_x, place_center_z, force_placement", + y_max = mcl_vars.mg_overworld_max, + y_min = minetest.get_mapgen_setting("water_level"), + place_func = function(pos,def,pr) + return makelake(pos,3,"mcl_core:water_source",{"group:material_stone", "group:sand", "group:dirt","group:grass_block","mcl_mud:mud"},"mcl_mud:mud",pr,true) + end +}) + +local pool_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,-1,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + +mcl_structures.register_structure("basalt_column",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + terrain_feature = true, + spawn_by = {"air"}, + num_spawn_by = 2, + noise_params = { + offset = 0, + scale = 0.003, + spread = {x = 250, y = 250, z = 250}, + seed = 72235213, + octaves = 5, + persist = 0.3, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max - 20, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-5,-1,-5),vector.offset(pos,5,-1,5),{"air","mcl_blackstone:basalt","mcl_blackstone:blackstone"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local basalt = {} + local magma = {} + for i=1,pr:next(1,#nn) do + if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then + local dst=vector.distance(pos,nn[i]) + local r = pr:next(1,14)-dst + for ii=0,r do + if pr:next(1,25) == 1 then + table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + else + table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + end + end + end + end + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + return true + end +}) +mcl_structures.register_structure("basalt_pillar",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.001, + spread = {x = 250, y = 250, z = 250}, + seed = 7113, + octaves = 5, + persist = 0.1, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max-40, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area(vector.offset(pos,-2,-1,-2),vector.offset(pos,2,-1,2),{"air","mcl_blackstone:basalt","mcl_blackstone:blackstone"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local basalt = {} + local magma = {} + for i=1,pr:next(1,#nn) do + if minetest.get_node(vector.offset(nn[i],0,-1,0)).name ~= "air" then + local dst=vector.distance(pos,nn[i]) + for ii=0,pr:next(19,35)-dst do + if pr:next(1,20) == 1 then + table.insert(magma,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + else + table.insert(basalt,vector.new(nn[i].x,nn[i].y + ii,nn[i].z)) + end + end + end + end + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + return true + end +}) + +mcl_structures.register_structure("lavadelta",{ + place_on = {"mcl_blackstone:blackstone","mcl_blackstone:basalt"}, + spawn_by = {"mcl_blackstone:basalt","mcl_blackstone:blackstone"}, + num_spawn_by = 2, + terrain_feature = true, + noise_params = { + offset = 0, + scale = 0.005, + spread = {x = 250, y = 250, z = 250}, + seed = 78375213, + octaves = 5, + persist = 0.1, + flags = "absvalue", + }, + flags = "all_floors", + y_max = mcl_vars.mg_nether_max, + y_min = mcl_vars.mg_lava_nether_max + 1, + biomes = { "BasaltDelta" }, + place_func = function(pos,def,pr) + local nn = minetest.find_nodes_in_area_under_air(vector.offset(pos,-10,-1,-10),vector.offset(pos,10,-2,10),{"mcl_blackstone:basalt","mcl_blackstone:blackstone","mcl_nether:netherrack"}) + table.sort(nn,function(a, b) + return vector.distance(vector.new(pos.x,0,pos.z), a) < vector.distance(vector.new(pos.x,0,pos.z), b) + end) + if #nn < 1 then return false end + local lava = {} + for i=1,pr:next(1,#nn) do + table.insert(lava,nn[i]) + end + minetest.bulk_set_node(lava,{name="mcl_nether:nether_lava_source"}) + local basalt = {} + local magma = {} + for _,v in pairs(lava) do + for _,vv in pairs(adjacents) do + local p = vector.add(v,vv) + if minetest.get_node(p).name ~= "mcl_nether:nether_lava_source" then + table.insert(basalt,p) + + end + end + if math.random(3) == 1 then + table.insert(magma,v) + end + end + minetest.bulk_set_node(basalt,{name="mcl_blackstone:basalt"}) + minetest.bulk_set_node(magma,{name="mcl_nether:magma"}) + return true + end +}) diff --git a/mods/MAPGEN/mcl_terrain_features/mod.conf b/mods/MAPGEN/mcl_terrain_features/mod.conf new file mode 100644 index 000000000..008e370cc --- /dev/null +++ b/mods/MAPGEN/mcl_terrain_features/mod.conf @@ -0,0 +1,3 @@ +name = mcl_terrain_features +author = cora +depends = mcl_init, mcl_structures diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 05f08bdcc..1b8ce3cba 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -4,27 +4,27 @@ ------------------------------------------------------------------------------- function settlements.build_schematic(vm, data, va, pos, building, replace_wall, name) -- get building node material for better integration to surrounding - local platform_material = minetest.get_node_or_nil(pos) - if not platform_material then + local platform_material = mcl_vars.get_node(pos) + if not platform_material or (platform_material.name == "air" or platform_material.name == "ignore") then return end platform_material = platform_material.name -- pick random material local material = wallmaterial[math.random(1,#wallmaterial)] -- schematic conversion to lua - local schem_lua = minetest.serialize_schematic(building, - "lua", - {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)" + local schem_lua = minetest.serialize_schematic(building, + "lua", + {lua_use_comments = false, lua_num_indent_spaces = 0}).." return schematic" -- replace material if replace_wall == "y" then schem_lua = schem_lua:gsub("mcl_core:cobble", material) end - schem_lua = schem_lua:gsub("mcl_core:dirt_with_grass", + schem_lua = schem_lua:gsub("mcl_core:dirt_with_grass", platform_material) -- Disable special junglewood for now. -- special material for spawning npcs - -- schem_lua = schem_lua:gsub("mcl_core:junglewood", + -- schem_lua = schem_lua:gsub("mcl_core:junglewood", -- "settlements:junglewood") -- @@ -37,25 +37,25 @@ function settlements.build_schematic(vm, data, va, pos, building, replace_wall, local possible_rotations = {"0", "90", "180", "270"} local rotation = possible_rotations[ math.random( #possible_rotations ) ] settlements.foundation( - pos, - width, - depth, - height, + pos, + width, + depth, + height, rotation) vm:set_data(data) -- place schematic minetest.place_schematic_on_vmanip( - vm, - pos, - schematic, - rotation, - nil, + vm, + pos, + schematic, + rotation, + nil, true) vm:write_to_map(true) end]] ------------------------------------------------------------------------------- --- initialize settlement_info +-- initialize settlement_info ------------------------------------------------------------------------------- function settlements.initialize_settlement_info(pr) local count_buildings = {} @@ -79,21 +79,28 @@ function settlements.create_site_plan(maxp, minp, pr) local settlement_info = {} local building_all_info local possible_rotations = {"0", "90", "180", "270"} + -- find center of chunk local center = { - x=maxp.x-half_map_chunk_size, - y=maxp.y, - z=maxp.z-half_map_chunk_size - } - -- find center_surface of chunk - local center_surface , surface_material = settlements.find_surface(center) - -- go build settlement around center - if not center_surface then return false end + x=math.floor((minp.x+maxp.x)/2), + y=maxp.y, + z=math.floor((minp.z+maxp.z)/2) + } + + -- find center_surface of chunk + local center_surface , surface_material = settlements.find_surface(center, true) + local chunks = {} + chunks[mcl_vars.get_chunk_number(center)] = true + + -- go build settlement around center + if not center_surface then + minetest.log("action", "Cannot build village at: " .. minetest.pos_to_string(center)) + return false + else + minetest.log("action", "Village built.") + --minetest.log("action", "Build village at: " .. minetest.pos_to_string(center) .. " with surface material: " .. surface_material) + end - -- add settlement to list - table.insert(settlements_in_world, center_surface) - -- save list to file - settlements.save() -- initialize all settlement_info table local count_buildings, number_of_buildings, number_built = settlements.initialize_settlement_info(pr) -- first building is townhall in the center @@ -102,8 +109,8 @@ function settlements.create_site_plan(maxp, minp, pr) -- add to settlement info table local index = 1 settlement_info[index] = { - pos = center_surface, - name = building_all_info["name"], + pos = center_surface, + name = building_all_info["name"], hsize = building_all_info["hsize"], rotat = rotation, surface_mat = surface_material @@ -114,49 +121,57 @@ function settlements.create_site_plan(maxp, minp, pr) local x, z, r = center_surface.x, center_surface.z, building_all_info["hsize"] -- draw j circles around center and increase radius by math.random(2,5) for j = 1,20 do - if number_built < number_of_buildings then - -- set position on imaginary circle - for j = 0, 360, 15 do - local angle = j * math.pi / 180 - local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) - ptx = settlements.round(ptx, 0) - ptz = settlements.round(ptz, 0) - local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} - local pos_surface, surface_material = settlements.find_surface(pos1) - if not pos_surface then break end + -- set position on imaginary circle + for j = 0, 360, 15 do + local angle = j * math.pi / 180 + local ptx, ptz = x + r * math.cos( angle ), z + r * math.sin( angle ) + ptx = settlements.round(ptx, 0) + ptz = settlements.round(ptz, 0) + local pos1 = { x=ptx, y=center_surface.y+50, z=ptz} + local chunk_number = mcl_vars.get_chunk_number(pos1) + local pos_surface, surface_material + if chunks[chunk_number] then + pos_surface, surface_material = settlements.find_surface(pos1) + else + chunks[chunk_number] = true + pos_surface, surface_material = settlements.find_surface(pos1, true) + end + if not pos_surface then break end - local randomized_schematic_table = shuffle(settlements.schematic_table, pr) - -- pick schematic - local size = #randomized_schematic_table - for i = size, 1, -1 do - -- already enough buildings of that type? - if count_buildings[randomized_schematic_table[i]["name"]] < randomized_schematic_table[i]["max_num"]*number_of_buildings then - building_all_info = randomized_schematic_table[i] - -- check distance to other buildings - local distance_to_other_buildings_ok = settlements.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) - if distance_to_other_buildings_ok then - -- count built houses - count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1 - rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] - number_built = number_built + 1 - settlement_info[index] = { - pos = pos_surface, - name = building_all_info["name"], - hsize = building_all_info["hsize"], - rotat = rotation, - surface_mat = surface_material - } - index = index + 1 - break - end + local randomized_schematic_table = shuffle(settlements.schematic_table, pr) + -- pick schematic + local size = #randomized_schematic_table + for i = size, 1, -1 do + -- already enough buildings of that type? + if count_buildings[randomized_schematic_table[i]["name"]] < randomized_schematic_table[i]["max_num"]*number_of_buildings then + building_all_info = randomized_schematic_table[i] + -- check distance to other buildings + local distance_to_other_buildings_ok = settlements.check_distance(settlement_info, pos_surface, building_all_info["hsize"]) + if distance_to_other_buildings_ok then + -- count built houses + count_buildings[building_all_info["name"]] = count_buildings[building_all_info["name"]] +1 + rotation = possible_rotations[ pr:next(1, #possible_rotations ) ] + number_built = number_built + 1 + settlement_info[index] = { + pos = pos_surface, + name = building_all_info["name"], + hsize = building_all_info["hsize"], + rotat = rotation, + surface_mat = surface_material + } + index = index + 1 + break end end - if number_of_buildings == number_built then - break - end end - r = r + pr:next(2,5) + if number_of_buildings == number_built then + break + end end + if number_built >= number_of_buildings then + break + end + r = r + pr:next(2,5) end settlements.debug("really ".. number_built) return settlement_info @@ -164,9 +179,83 @@ end ------------------------------------------------------------------------------- -- evaluate settlement_info and place schematics ------------------------------------------------------------------------------- +-- Initialize node +local function construct_node(p1, p2, name) + local r = minetest.registered_nodes[name] + if r then + if r.on_construct then + local nodes = minetest.find_nodes_in_area(p1, p2, name) + for p=1, #nodes do + local pos = nodes[p] + r.on_construct(pos) + end + return nodes + end + minetest.log("warning", "[mcl_villages] No on_construct defined for node name " .. name) + return + end + minetest.log("warning", "[mcl_villages] Attempt to 'construct' inexistant nodes: " .. name) +end + +local function spawn_iron_golem(pos) + --minetest.log("action", "Attempt to spawn iron golem.") + local p = minetest.find_node_near(pos,50,"mcl_core:grass_path") + if p then + local l=minetest.add_entity(p,"mobs_mc:iron_golem"):get_luaentity() + if l then + l._home = p + end + end +end + +local function spawn_villagers(minp,maxp) + --minetest.log("action", "Attempt to spawn villagers.") + local beds=minetest.find_nodes_in_area(vector.offset(minp,-20,-20,-20),vector.offset(maxp,20,20,20),{"mcl_beds:bed_red_bottom"}) + for _,bed in pairs(beds) do + local m = minetest.get_meta(bed) + if m:get_string("villager") == "" then + local v=minetest.add_entity(bed,"mobs_mc:villager") + if v then + local l=v:get_luaentity() + l._bed = bed + m:set_string("villager",l._id) + end + end + end +end + +local function fix_village_water(minp,maxp) + local palettenodes = minetest.find_nodes_in_area(vector.offset(minp,-20,-20,-20),vector.offset(maxp,20,20,20), "group:water_palette") + for _, palettenodepos in pairs(palettenodes) do + local palettenode = minetest.get_node(palettenodepos) + minetest.set_node(palettenodepos, {name = palettenode.name}) + end +end + +local function init_nodes(p1, p2, size, rotation, pr) + construct_node(p1, p2, "mcl_itemframes:item_frame") + construct_node(p1, p2, "mcl_furnaces:furnace") + construct_node(p1, p2, "mcl_anvils:anvil") + + construct_node(p1, p2, "mcl_smoker:smoker") + construct_node(p1, p2, "mcl_barrels:barrel_closed") + construct_node(p1, p2, "mcl_blast_furnace:blast_furnace") + construct_node(p1, p2, "mcl_brewing:stand_000") + local nodes = construct_node(p1, p2, "mcl_chests:chest") + if nodes and #nodes > 0 then + for p=1, #nodes do + local pos = nodes[p] + settlements.fill_chest(pos, pr) + end + end +end + function settlements.place_schematics(settlement_info, pr) local building_all_info + for i, built_house in ipairs(settlement_info) do + local is_last = i == #settlement_info + for j, schem in ipairs(settlements.schematic_table) do if settlement_info[i]["name"] == schem["name"] then building_all_info = schem @@ -174,10 +263,13 @@ function settlements.place_schematics(settlement_info, pr) end end - local pos = settlement_info[i]["pos"] - local rotation = settlement_info[i]["rotat"] + + + + local pos = settlement_info[i]["pos"] + local rotation = settlement_info[i]["rotat"] -- get building node material for better integration to surrounding - local platform_material = settlement_info[i]["surface_mat"] + local platform_material = settlement_info[i]["surface_mat"] --platform_material_name = minetest.get_name_from_content_id(platform_material) -- pick random material --local material = wallmaterial[pr:next(1,#wallmaterial)] @@ -185,9 +277,10 @@ function settlements.place_schematics(settlement_info, pr) local building = building_all_info["mts"] local replace_wall = building_all_info["rplc"] -- schematic conversion to lua - local schem_lua = minetest.serialize_schematic(building, - "lua", - {lua_use_comments = false, lua_num_indent_spaces = 0}).." return(schematic)" + local schem_lua = minetest.serialize_schematic(building, + "lua", + {lua_use_comments = false, lua_num_indent_spaces = 0}).." return schematic" + schem_lua = schem_lua:gsub("mcl_core:stonebrickcarved", "mcl_villages:stonebrickcarved") -- replace material if replace_wall then --Note, block substitution isn't matching node names exactly; so nodes that are to be substituted that have the same prefixes cause bugs. @@ -224,13 +317,28 @@ function settlements.place_schematics(settlement_info, pr) -- format schematic string local schematic = loadstring(schem_lua)() + + local is_belltower = building_all_info["name"] == "belltower" + -- build foundation for the building an make room above - -- place schematic - minetest.place_schematic( - pos, - schematic, - rotation, - nil, - true) + + mcl_structures.place_schematic( + pos, + schematic, + rotation, + nil, + true, + nil, + function(p1, p2, size, rotation, pr) + if is_belltower then + spawn_iron_golem(p1) + else + init_nodes(p1, p2, size, rotation, pr) + spawn_villagers(p1,p2) + fix_village_water(p1,p2) + end + end, + pr + ) end end diff --git a/mods/MAPGEN/mcl_villages/const.lua b/mods/MAPGEN/mcl_villages/const.lua index 4e2b39136..feff6a1d2 100644 --- a/mods/MAPGEN/mcl_villages/const.lua +++ b/mods/MAPGEN/mcl_villages/const.lua @@ -1,5 +1,5 @@ -- switch for debugging -settlements.debug = function(message) +function settlements.debug(message) -- minetest.chat_send_all(message) -- minetest.log("warning", "[mcl_villages] "..message) minetest.log("verbose", "[mcl_villages] "..message) @@ -7,16 +7,16 @@ end --[[ Manually set in 'buildings.lua' -- material to replace cobblestone with -wallmaterial = { - "mcl_core:junglewood", - "mcl_core:sprucewood", - "mcl_core:wood", - "mcl_core:birchwood", - "mcl_core:acaciawood", - "mcl_core:stonebrick", - "mcl_core:cobble", - "mcl_core:sandstonecarved", - "mcl_core:sandstone", +local wallmaterial = { + "mcl_core:junglewood", + "mcl_core:sprucewood", + "mcl_core:wood", + "mcl_core:birchwood", + "mcl_core:acaciawood", + "mcl_core:stonebrick", + "mcl_core:cobble", + "mcl_core:sandstonecarved", + "mcl_core:sandstone", "mcl_core:sandstonesmooth2" } --]] @@ -52,24 +52,20 @@ schem_path = settlements.modpath.."/schematics/" local basic_pseudobiome_villages = minetest.settings:get_bool("basic_pseudobiome_villages", true) settlements.schematic_table = { - {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 11, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, - {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages }, - {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 11, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages }, + {name = "belltower", mts = schem_path.."belltower.mts", hwidth = 5, hdepth = 5, hheight = 9, hsize = 14, max_num = 0 , rplc = basic_pseudobiome_villages }, + {name = "large_house", mts = schem_path.."large_house.mts", hwidth = 12, hdepth = 12, hheight = 9, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "blacksmith", mts = schem_path.."blacksmith.mts", hwidth = 8, hdepth = 11, hheight = 13, hsize = 13, max_num = 0.055, rplc = basic_pseudobiome_villages }, + {name = "butcher", mts = schem_path.."butcher.mts", hwidth = 12, hdepth = 8, hheight = 10, hsize = 14, max_num = 0.03 , rplc = basic_pseudobiome_villages }, {name = "church", mts = schem_path.."church.mts", hwidth = 13, hdepth = 13, hheight = 14, hsize = 15, max_num = 0.04 , rplc = basic_pseudobiome_villages }, - {name = "farm", mts = schem_path.."farm.mts", hwidth = 7, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages }, - {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 3, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false }, + {name = "farm", mts = schem_path.."farm.mts", hwidth = 9, hdepth = 7, hheight = 13, hsize = 13, max_num = 0.1 , rplc = basic_pseudobiome_villages }, + {name = "lamp", mts = schem_path.."lamp.mts", hwidth = 3, hdepth = 4, hheight = 13, hsize = 10, max_num = 0.1 , rplc = false }, {name = "library", mts = schem_path.."library.mts", hwidth = 12, hdepth = 12, hheight = 8, hsize = 13, max_num = 0.04 , rplc = basic_pseudobiome_villages }, - {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 8, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, - {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 7, hheight = 8, hsize = 13, max_num = 0.7 , rplc = basic_pseudobiome_villages }, - {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 11, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = basic_pseudobiome_villages }, + {name = "medium_house", mts = schem_path.."medium_house.mts", hwidth = 9, hdepth = 12, hheight = 8, hsize = 14, max_num = 0.08 , rplc = basic_pseudobiome_villages }, + {name = "small_house", mts = schem_path.."small_house.mts", hwidth = 9, hdepth = 8, hheight = 8, hsize = 13, max_num = 0.7 , rplc = basic_pseudobiome_villages }, + {name = "tavern", mts = schem_path.."tavern.mts", hwidth = 12, hdepth = 10, hheight = 10, hsize = 13, max_num = 0.050, rplc = basic_pseudobiome_villages }, {name = "well", mts = schem_path.."well.mts", hwidth = 6, hdepth = 8, hheight = 6, hsize = 10, max_num = 0.045, rplc = basic_pseudobiome_villages }, } --- --- list of settlements, load on server start up --- -settlements_in_world = {} --- -- -- maximum allowed difference in height for building a sttlement -- @@ -78,4 +74,4 @@ max_height_difference = 56 -- -- half_map_chunk_size = 40 -quarter_map_chunk_size = 20 +--quarter_map_chunk_size = 20 diff --git a/mods/MAPGEN/mcl_villages/depends.txt b/mods/MAPGEN/mcl_villages/depends.txt deleted file mode 100644 index 9ba29f3ee..000000000 --- a/mods/MAPGEN/mcl_villages/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_core -mcl_loot -mcl_farming? -mobs_mc? diff --git a/mods/MAPGEN/mcl_villages/foundation.lua b/mods/MAPGEN/mcl_villages/foundation.lua index 15936ef4c..e53a4a3ce 100644 --- a/mods/MAPGEN/mcl_villages/foundation.lua +++ b/mods/MAPGEN/mcl_villages/foundation.lua @@ -1,23 +1,41 @@ +local function mcl_log (message) + mcl_util.mcl_log (message, "[Village - Foundation]") +end + +local foundation_materials = {} + +foundation_materials["mcl_core:sand"] = "mcl_core:sandstone" +--"mcl_core:sandstonecarved" + ------------------------------------------------------------------------------- -- function to fill empty space below baseplate when building on a hill ------------------------------------------------------------------------------- -function settlements.ground(pos, pr) -- role model: Wendelsteinkircherl, Brannenburg +function settlements.ground(pos, pr, platform_material) -- role model: Wendelsteinkircherl, Brannenburg local p2 = vector.new(pos) local cnt = 0 + local mat = "mcl_core:dirt" + if not platform_material then + mat = "mcl_core:dirt" + else + mat = platform_material + end + p2.y = p2.y-1 while true do cnt = cnt+1 if cnt > 20 then break end - if cnt>pr:next(2,4) then - mat = "mcl_core:stone" + if cnt>pr:next(2,4) then + if not platform_material then + mat = "mcl_core:stone" + end end minetest.swap_node(p2, {name=mat}) p2.y = p2.y-1 end end ------------------------------------------------------------------------------- --- function clear space above baseplate +-- function clear space above baseplate ------------------------------------------------------------------------------- function settlements.terraform(settlement_info, pr) local fheight, fwidth, fdepth, schematic_data @@ -30,7 +48,7 @@ function settlements.terraform(settlement_info, pr) break end end - local pos = settlement_info[i]["pos"] + local pos = settlement_info[i]["pos"] if settlement_info[i]["rotat"] == "0" or settlement_info[i]["rotat"] == "180" then fwidth = schematic_data["hwidth"] fdepth = schematic_data["hdepth"] @@ -40,6 +58,12 @@ function settlements.terraform(settlement_info, pr) end --fheight = schematic_data["hheight"] * 3 -- remove trees and leaves above fheight = schematic_data["hheight"] -- remove trees and leaves above + + local surface_mat = settlement_info[i]["surface_mat"] + mcl_log("Surface material: " .. tostring(surface_mat)) + local platform_mat = foundation_materials[surface_mat] + mcl_log("Foundation material: " .. tostring(platform_mat)) + -- -- now that every info is available -> create platform and clear space above -- @@ -48,15 +72,16 @@ function settlements.terraform(settlement_info, pr) for yi = 0,fheight *3 do if yi == 0 then local p = {x=pos.x+xi, y=pos.y, z=pos.z+zi} - settlements.ground(p, pr) + -- Pass in biome info and make foundations of same material (seed: apple for desert) + settlements.ground(p, pr, platform_mat) else -- write ground - local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} - minetest.forceload_block(p) - local node = minetest.get_node_or_nil(p) - if node and node.name ~= "air" then - minetest.swap_node(p,{name="air"}) - end +-- local p = {x=pos.x+xi, y=pos.y+yi, z=pos.z+zi} +-- local node = mcl_vars.get_node(p) +-- if node and node.name ~= "air" then +-- minetest.swap_node(p,{name="air"}) +-- end + minetest.swap_node({x=pos.x+xi, y=pos.y+yi, z=pos.z+zi},{name="air"}) end end end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 5ee3b054a..0cb0712b5 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -1,5 +1,5 @@ settlements = {} -settlements.modpath = minetest.get_modpath("mcl_villages") +settlements.modpath = minetest.get_modpath(minetest.get_current_modname()) dofile(settlements.modpath.."/const.lua") dofile(settlements.modpath.."/utils.lua") @@ -10,29 +10,36 @@ dofile(settlements.modpath.."/paths.lua") -- -- load settlements on server -- -settlements_in_world = settlements.load() settlements.grundstellungen() ---[[ Disable custom node spawning. +local S = minetest.get_translator(minetest.get_current_modname()) + +local villagegen={} -- -- register block for npc spawn -- -minetest.register_node("settlements:junglewood", { - description = "special junglewood floor", - tiles = {"default_junglewood.png"}, - groups = {choppy=3, wood=2}, - sounds = default.node_sound_wood_defaults(), - }) +minetest.register_node("mcl_villages:stonebrickcarved", { + description = S("Chiseled Stone Village Bricks"), + _doc_items_longdesc = doc.sub.items.temp.build, + tiles = {"mcl_core_stonebrick_carved.png"}, + drop = "mcl_core:stonebrickcarved", + groups = {pickaxey=1, stone=1, stonebrick=1, building_block=1, material_stone=1}, + sounds = mcl_sounds.node_sound_stone_defaults(), + is_ground_content = false, + _mcl_blast_resistance = 6, + _mcl_hardness = 1.5, +}) + +minetest.register_node("mcl_villages:structblock", {drawtype="airlike",groups = {not_in_creative_inventory=1},}) ---]] --[[ Enable for testing, but use MineClone2's own spawn code if/when merging. -- -- register inhabitants -- -if minetest.get_modpath("mobs_mc") ~= nil then - mobs:register_spawn("mobs_mc:villager", --name +if minetest.get_modpath("mobs_mc") then + mcl_mobs:register_spawn("mobs_mc:villager", --name {"mcl_core:stonebrickcarved"}, --nodes 15, --max_light 0, --min_light @@ -40,13 +47,13 @@ if minetest.get_modpath("mobs_mc") ~= nil then 7, --active_object_count 31000, --max_height nil) --day_toggle -end +end --]] -- -- on map generation, try to build a settlement -- -local function build_a_settlement_no_delay(minp, maxp, blockseed) +local function build_a_settlement(minp, maxp, blockseed) local pr = PseudoRandom(blockseed) -- fill settlement_info with buildings and their data @@ -61,51 +68,70 @@ local function build_a_settlement_no_delay(minp, maxp, blockseed) -- evaluate settlement_info and place schematics settlements.place_schematics(settlement_info, pr) - - -- evaluate settlement_info and initialize furnaces and chests - settlements.initialize_nodes(settlement_info, pr) end -local function ecb_build_a_settlement(blockpos, action, calls_remaining, param) - if calls_remaining <= 0 then - build_a_settlement_no_delay(param.minp, param.maxp, param.blockseed) - end +local function ecb_village(blockpos, action, calls_remaining, param) + if calls_remaining >= 1 then return end + local minp, maxp, blockseed = param.minp, param.maxp, param.blockseed + build_a_settlement(minp, maxp, blockseed) end -- Disable natural generation in singlenode. local mg_name = minetest.get_mapgen_setting("mg_name") if mg_name ~= "singlenode" then - minetest.register_on_generated(function(minp, maxp, blockseed) - -- needed for manual and automated settlement building - local heightmap = minetest.get_mapgen_object("heightmap") + mcl_mapgen_core.register_generator("villages", nil, function(minp, maxp, blockseed) + if maxp.y < 0 then return end -- randomly try to build settlements if blockseed % 77 ~= 17 then return end + --minetest.log("Rng good. Generate attempt") - -- don't build settlement underground - if maxp.y < 0 then return end - + -- needed for manual and automated settlement building -- don't build settlements on (too) uneven terrain - local height_difference = settlements.evaluate_heightmap(minp, maxp) - if height_difference > max_height_difference then return end + local n=minetest.get_node_or_nil(minp) + if n and n.name == "mcl_villages:structblock" then return end + --minetest.log("No existing village attempt here") - -- new way - slow :((((( - minetest.emerge_area(vector.subtract(minp,24), vector.add(maxp,24), ecb_build_a_settlement, {minp = vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}) - -- old way - wait 3 seconds: - -- minetest.after(3, ecb_build_a_settlement, nil, 1, 0, {minp = vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed}) + if villagegen[minetest.pos_to_string(minp)] ~= nil then return end + + --minetest.log("Not in village gen. Put down placeholder: " .. minetest.pos_to_string(minp) .. " || " .. minetest.pos_to_string(maxp)) + minetest.set_node(minp,{name="mcl_villages:structblock"}) + + local height_difference = settlements.evaluate_heightmap() + if not height_difference or height_difference > max_height_difference then + minetest.log("action", "Do not spawn village here as heightmap not good") + return + end + --minetest.log("Build me a village: " .. minetest.pos_to_string(minp) .. " || " .. minetest.pos_to_string(maxp)) + villagegen[minetest.pos_to_string(minp)]={minp=vector.new(minp), maxp=vector.new(maxp), blockseed=blockseed} end) end + +minetest.register_lbm({ + name = "mcl_villages:structblock", + run_at_every_load = true, + nodenames = {"mcl_villages:structblock"}, + action = function(pos, node) + minetest.set_node(pos, {name = "air"}) + if not villagegen[minetest.pos_to_string(pos)] then return end + local minp=villagegen[minetest.pos_to_string(pos)].minp + local maxp=villagegen[minetest.pos_to_string(pos)].maxp + minetest.emerge_area(minp, maxp, ecb_village, villagegen[minetest.pos_to_string(minp)]) + villagegen[minetest.pos_to_string(minp)]=nil + end +}) -- manually place villages if minetest.is_creative_enabled("") then minetest.register_craftitem("mcl_villages:tool", { - description = "mcl_villages build tool", + description = S("mcl_villages build tool"), inventory_image = "default_tool_woodshovel.png", -- build ssettlement on_place = function(itemstack, placer, pointed_thing) if not pointed_thing.under then 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_no_delay(minp, maxp, math.random(0,32767)) + build_a_settlement(minp, maxp, math.random(0,32767)) end }) + mcl_wip.register_experimental_item("mcl_villages:tool") end diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr new file mode 100644 index 000000000..b648cd36c --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.fr.tr @@ -0,0 +1,3 @@ +# 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 diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr new file mode 100644 index 000000000..4d0e4794f --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ja.tr @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=模様入り石村レンガ +mcl_villages build tool=mcl_villages 構築ツール \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr new file mode 100644 index 000000000..467f31121 --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/mcl_villages.ru.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks=Точёный каменный блок из деревни diff --git a/mods/MAPGEN/mcl_villages/locale/template.txt b/mods/MAPGEN/mcl_villages/locale/template.txt new file mode 100644 index 000000000..464daea9b --- /dev/null +++ b/mods/MAPGEN/mcl_villages/locale/template.txt @@ -0,0 +1,3 @@ +# textdomain: mcl_villages +Chiseled Stone Village Bricks= +mcl_villages build tool= \ No newline at end of file diff --git a/mods/MAPGEN/mcl_villages/mod.conf b/mods/MAPGEN/mcl_villages/mod.conf new file mode 100644 index 000000000..d8e2aa7d4 --- /dev/null +++ b/mods/MAPGEN/mcl_villages/mod.conf @@ -0,0 +1,5 @@ +name = mcl_villages +author = Rochambeau +description = This mod adds settlements on world generation. +depends = mcl_util, mcl_mapgen_core, mcl_structures, mcl_core, mcl_loot +optional_depends = mcl_farming, mobs_mc diff --git a/mods/MAPGEN/mcl_villages/paths.lua b/mods/MAPGEN/mcl_villages/paths.lua index 4973171a6..63f2ba146 100644 --- a/mods/MAPGEN/mcl_villages/paths.lua +++ b/mods/MAPGEN/mcl_villages/paths.lua @@ -6,10 +6,10 @@ function settlements.paths(settlement_info) local end_point local distance --for k,v in pairs(settlement_info) do - starting_point = settlement_info[1]["pos"] + starting_point = settlement_info[1]["pos"] for o,p in pairs(settlement_info) do - end_point = settlement_info[o]["pos"] + end_point = settlement_info[o]["pos"] if starting_point ~= end_point then -- loop until end_point is reched (distance == 0) @@ -40,35 +40,35 @@ function settlements.paths(settlement_info) -- evaluate which pos is closer to the end_point if dist_north_p_to_end <= dist_south_p_to_end and dist_north_p_to_end <= dist_west_p_to_end and - dist_north_p_to_end <= dist_east_p_to_end + dist_north_p_to_end <= dist_east_p_to_end then starting_point = north_p distance = dist_north_p_to_end elseif dist_south_p_to_end <= dist_north_p_to_end and dist_south_p_to_end <= dist_west_p_to_end and - dist_south_p_to_end <= dist_east_p_to_end + dist_south_p_to_end <= dist_east_p_to_end then starting_point = south_p distance = dist_south_p_to_end elseif dist_west_p_to_end <= dist_north_p_to_end and dist_west_p_to_end <= dist_south_p_to_end and - dist_west_p_to_end <= dist_east_p_to_end + dist_west_p_to_end <= dist_east_p_to_end then starting_point = west_p distance = dist_west_p_to_end elseif dist_east_p_to_end <= dist_north_p_to_end and dist_east_p_to_end <= dist_south_p_to_end and - dist_east_p_to_end <= dist_west_p_to_end + dist_east_p_to_end <= dist_west_p_to_end then starting_point = east_p distance = dist_east_p_to_end end -- find surface of new starting point local surface_point, surface_mat = settlements.find_surface(starting_point) - -- replace surface node with mcl_core:grass_path + -- replace surface node with mcl_core:grass_path if surface_point then if surface_mat == "mcl_core:sand" or surface_mat == "mcl_core:redsand" then diff --git a/mods/MAPGEN/mcl_villages/schematics/belltower.mts b/mods/MAPGEN/mcl_villages/schematics/belltower.mts new file mode 100644 index 000000000..8eb524312 Binary files /dev/null and b/mods/MAPGEN/mcl_villages/schematics/belltower.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts b/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts index d7fb66593..d4e26fb26 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts and b/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/butcher.mts b/mods/MAPGEN/mcl_villages/schematics/butcher.mts index 251033b1e..06dd25112 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/butcher.mts and b/mods/MAPGEN/mcl_villages/schematics/butcher.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/church.mts b/mods/MAPGEN/mcl_villages/schematics/church.mts index dbf022cb4..e59f90f1f 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/church.mts and b/mods/MAPGEN/mcl_villages/schematics/church.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/farm.mts b/mods/MAPGEN/mcl_villages/schematics/farm.mts index 9094c8681..b45ff1d6f 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/farm.mts and b/mods/MAPGEN/mcl_villages/schematics/farm.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/lamp.mts b/mods/MAPGEN/mcl_villages/schematics/lamp.mts index c8d907eba..8da0e8355 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/lamp.mts and b/mods/MAPGEN/mcl_villages/schematics/lamp.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/large_house.mts b/mods/MAPGEN/mcl_villages/schematics/large_house.mts index 36be603f4..6cc19543e 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/large_house.mts and b/mods/MAPGEN/mcl_villages/schematics/large_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/library.mts b/mods/MAPGEN/mcl_villages/schematics/library.mts index b47e0b413..521ee9fb6 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/library.mts and b/mods/MAPGEN/mcl_villages/schematics/library.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/medium_house.mts b/mods/MAPGEN/mcl_villages/schematics/medium_house.mts index 43ce2391b..6a90a0cfa 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/medium_house.mts and b/mods/MAPGEN/mcl_villages/schematics/medium_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/small_house.mts b/mods/MAPGEN/mcl_villages/schematics/small_house.mts index d7b62529c..92c0c150d 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/small_house.mts and b/mods/MAPGEN/mcl_villages/schematics/small_house.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/tavern.mts b/mods/MAPGEN/mcl_villages/schematics/tavern.mts index 5eae8ae23..32b905261 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/tavern.mts and b/mods/MAPGEN/mcl_villages/schematics/tavern.mts differ diff --git a/mods/MAPGEN/mcl_villages/schematics/well.mts b/mods/MAPGEN/mcl_villages/schematics/well.mts index 6ea47fea4..ff8785fde 100644 Binary files a/mods/MAPGEN/mcl_villages/schematics/well.mts and b/mods/MAPGEN/mcl_villages/schematics/well.mts differ diff --git a/mods/MAPGEN/mcl_villages/utils.lua b/mods/MAPGEN/mcl_villages/utils.lua index 96d540b57..5ed3cbbe0 100644 --- a/mods/MAPGEN/mcl_villages/utils.lua +++ b/mods/MAPGEN/mcl_villages/utils.lua @@ -1,28 +1,5 @@ -local c_dirt_with_grass = minetest.get_content_id("mcl_core:dirt_with_grass") -local c_dirt_with_snow = minetest.get_content_id("mcl_core:dirt_with_grass_snow") ---local c_dirt_with_dry_grass = minetest.get_content_id("mcl_core:dirt_with_dry_grass") -local c_podzol = minetest.get_content_id("mcl_core:podzol") -local c_sand = minetest.get_content_id("mcl_core:sand") -local c_desert_sand = minetest.get_content_id("mcl_core:redsand") ---local c_silver_sand = minetest.get_content_id("mcl_core:silver_sand") --- -local c_air = minetest.get_content_id("air") -local c_snow = minetest.get_content_id("mcl_core:snow") -local c_fern_1 = minetest.get_content_id("mcl_flowers:fern") -local c_fern_2 = minetest.get_content_id("mcl_flowers:fern") -local c_fern_3 = minetest.get_content_id("mcl_flowers:fern") -local c_rose = minetest.get_content_id("mcl_flowers:poppy") -local c_viola = minetest.get_content_id("mcl_flowers:blue_orchid") -local c_geranium = minetest.get_content_id("mcl_flowers:allium") -local c_tulip = minetest.get_content_id("mcl_flowers:tulip_orange") -local c_dandelion_y = minetest.get_content_id("mcl_flowers:dandelion") -local c_dandelion_w = minetest.get_content_id("mcl_flowers:oxeye_daisy") -local c_bush_leaves = minetest.get_content_id("mcl_core:leaves") -local c_bush_stem = minetest.get_content_id("mcl_core:tree") -local c_a_bush_leaves = minetest.get_content_id("mcl_core:acacialeaves") -local c_a_bush_stem = minetest.get_content_id("mcl_core:acaciatree") -local c_water_source = minetest.get_content_id("mcl_core:water_source") -local c_water_flowing = minetest.get_content_id("mcl_core:water_flowing") +local get_node = mcl_vars.get_node + ------------------------------------------------------------------------------- -- function to copy tables ------------------------------------------------------------------------------- @@ -45,60 +22,50 @@ end -- function to find surface block y coordinate -- returns surface postion ------------------------------------------------------------------------------- -function settlements.find_surface(pos) +function settlements.find_surface(pos, wait) local p6 = vector.new(pos) local cnt = 0 - local itter -- count up or down + local itter = 1 -- count up or down local cnt_max = 200 -- check, in which direction to look for surface - local surface_node = minetest.get_node_or_nil(p6) - if surface_node and string.find(surface_node.name,"air") then - itter = -1 + local surface_node + if wait then + surface_node = get_node(p6, true, 10000000) else - itter = 1 + surface_node = get_node(p6) + end + if surface_node.name=="air" or surface_node.name=="ignore" then + itter = -1 end -- go through nodes an find surface while cnt < cnt_max do - cnt = cnt+1 - minetest.forceload_block(p6) - surface_node = minetest.get_node_or_nil(p6) - - if not surface_node then - -- Load the map at pos and try again - minetest.get_voxel_manip():read_from_map(p6, p6) - surface_node = minetest.get_node(p6) - if surface_node.name == "ignore" then - settlements.debug("find_surface1: nil or ignore") - return nil - end - end - - -- if surface_node == nil or surface_node.name == "ignore" then - -- --return nil - -- local fl = minetest.forceload_block(p6) - -- if not fl then - -- - -- return nil - -- end - -- end - -- -- Check Surface_node and Node above - -- - if settlements.surface_mat[surface_node.name] then - local surface_node_plus_1 = minetest.get_node_or_nil({ x=p6.x, y=p6.y+1, z=p6.z}) - if surface_node_plus_1 and surface_node and - (string.find(surface_node_plus_1.name,"air") or - string.find(surface_node_plus_1.name,"snow") or - string.find(surface_node_plus_1.name,"fern") or - string.find(surface_node_plus_1.name,"flower") or - string.find(surface_node_plus_1.name,"bush") or - string.find(surface_node_plus_1.name,"tree") or - string.find(surface_node_plus_1.name,"grass")) + if surface_node and settlements.surface_mat[surface_node.name] then + local surface_node_plus_1 = get_node({ x=p6.x, y=p6.y+1, z=p6.z}) + + if surface_node_plus_1 then + + local surface_node_minus_1 = get_node({ x=p6.x, y=p6.y-1, z=p6.z}) + local is_leaf_below = minetest.get_item_group(surface_node_minus_1, "leaves") ~= 0 or + string.find(surface_node_minus_1.name,"leaves") + + if not is_leaf_below and ((string.find(surface_node_plus_1.name,"air") or + string.find(surface_node_plus_1.name,"fern") or + string.find(surface_node_plus_1.name,"flower") or + string.find(surface_node_plus_1.name,"bush") or + string.find(surface_node_plus_1.name,"tree") or + string.find(surface_node_plus_1.name,"grass")) or + string.find(surface_node_plus_1.name,"snow")) then - settlements.debug("find_surface7: " ..surface_node.name.. " " .. surface_node_plus_1.name) + settlements.debug("find_surface success: " ..surface_node.name.. " " .. surface_node_plus_1.name) + settlements.debug("node below: " .. tostring(surface_node_minus_1.name)) + settlements.debug("node below leaves group: " .. tostring(minetest.get_item_group(surface_node_minus_1, "leaves"))) return p6, surface_node.name + else + settlements.debug("find_surface2: wrong surface+1") + end else - settlements.debug("find_surface2: wrong surface+1") + settlements.debug("find_surface8: missing node or plus_1") end else settlements.debug("find_surface3: wrong surface "..surface_node.name.." at pos "..minetest.pos_to_string(p6)) @@ -109,6 +76,8 @@ function settlements.find_surface(pos) settlements.debug("find_surface4: y<0") return nil end + cnt = cnt+1 + surface_node = get_node(p6) end settlements.debug("find_surface5: cnt_max overflow") return nil @@ -129,29 +98,6 @@ function settlements.check_distance(settlement_info, building_pos, building_size return true end ------------------------------------------------------------------------------- --- save list of generated settlements -------------------------------------------------------------------------------- -function settlements.save() - local file = io.open(minetest.get_worldpath().."/settlements.txt", "w") - if file then - file:write(minetest.serialize(settlements_in_world)) - file:close() - end -end -------------------------------------------------------------------------------- --- load list of generated settlements -------------------------------------------------------------------------------- -function settlements.load() - local file = io.open(minetest.get_worldpath().."/settlements.txt", "r") - if file then - local table = minetest.deserialize(file:read("*all")) - if type(table) == "table" then - return table - end - end - return {} -end -------------------------------------------------------------------------------- -- fill chests ------------------------------------------------------------------------------- function settlements.fill_chest(pos, pr) @@ -167,7 +113,7 @@ function settlements.fill_chest(pos, pr) -- fill chest local inv = minetest.get_inventory( {type="node", pos=pos} ) - local function get_treasures(pr) + local function get_treasures(prand) local loottable = {{ stacks_min = 3, stacks_max = 8, @@ -186,17 +132,17 @@ function settlements.fill_chest(pos, pr) { itemstring = "mcl_core:obsidian", weight = 5, amount_min = 3, amount_max = 7 }, { itemstring = "mcl_core:sapling", weight = 5, amount_min = 3, amount_max = 7 }, { itemstring = "mcl_mobitems:saddle", weight = 3 }, - { itemstring = "mobs_mc:iron_horse_armor", weight = 1 }, - { itemstring = "mobs_mc:gold_horse_armor", weight = 1 }, - { itemstring = "mobs_mc:diamond_horse_armor", weight = 1 }, + { itemstring = "mcl_mobitems:iron_horse_armor", weight = 1 }, + { itemstring = "mcl_mobitems:gold_horse_armor", weight = 1 }, + { itemstring = "mcl_mobitems:diamond_horse_armor", weight = 1 }, } }} - local items = mcl_loot.get_multi_loot(loottable, pr) + local items = mcl_loot.get_multi_loot(loottable, prand) return items end local items = get_treasures(pr) - mcl_loot.fill_inventory(inv, "main", items) + mcl_loot.fill_inventory(inv, "main", items, pr) end ------------------------------------------------------------------------------- @@ -204,14 +150,14 @@ end ------------------------------------------------------------------------------- function settlements.initialize_furnace(pos) -- find chests within radius - local furnacepos = minetest.find_node_near(pos, + local furnacepos = minetest.find_node_near(pos, 7, --radius {"mcl_furnaces:furnace"}) -- initialize furnacepos (mts furnacepos don't have meta) - if furnacepos + if furnacepos then local meta = minetest.get_meta(furnacepos) - if meta:get_string("infotext") ~= "furnace" + if meta:get_string("infotext") ~= "furnace" then minetest.registered_nodes["mcl_furnaces:furnace"].on_construct(furnacepos) end @@ -222,57 +168,20 @@ end ------------------------------------------------------------------------------- function settlements.initialize_anvil(pos) -- find chests within radius - local anvilpos = minetest.find_node_near(pos, + local anvilpos = minetest.find_node_near(pos, 7, --radius {"mcl_anvils:anvil"}) -- initialize anvilpos (mts anvilpos don't have meta) - if anvilpos + if anvilpos then local meta = minetest.get_meta(anvilpos) - if meta:get_string("infotext") ~= "anvil" + if meta:get_string("infotext") ~= "anvil" then minetest.registered_nodes["mcl_anvils:anvil"].on_construct(anvilpos) end end end ------------------------------------------------------------------------------- --- initialize furnace, chests, anvil -------------------------------------------------------------------------------- -local building_all_info -function settlements.initialize_nodes(settlement_info, pr) - for i, built_house in ipairs(settlement_info) do - for j, schem in ipairs(settlements.schematic_table) do - if settlement_info[i]["name"] == schem["name"] then - building_all_info = schem - break - end - end - - local width = building_all_info["hwidth"] - local depth = building_all_info["hdepth"] - local height = building_all_info["hheight"] - - local p = settlement_info[i]["pos"] - for yi = 1,height do - for xi = 0,width do - for zi = 0,depth do - local ptemp = {x=p.x+xi, y=p.y+yi, z=p.z+zi} - local node = minetest.get_node(ptemp) - if node.name == "mcl_furnaces:furnace" or - node.name == "mcl_chests:chest" or - node.name == "mcl_anvils:anvil" then - minetest.registered_nodes[node.name].on_construct(ptemp) - end - -- when chest is found -> fill with stuff - if node.name == "mcl_chests:chest" then - minetest.after(3, settlements.fill_chest, ptemp, pr) - end - end - end - end - end -end -------------------------------------------------------------------------------- -- randomize table ------------------------------------------------------------------------------- function shuffle(tbl, pr) @@ -288,44 +197,67 @@ end -- evaluate heightmap ------------------------------------------------------------------------------- function settlements.evaluate_heightmap() - local heightmap = minetest.get_mapgen_object("heightmap") - -- max height and min height, initialize with impossible values for easier first time setting - local max_y = -50000 - local min_y = 50000 - -- only evaluate the center square of heightmap 40 x 40 - local square_start = 1621 - local square_end = 1661 - for j = 1 , 40, 1 do - for i = square_start, square_end, 1 do - -- skip buggy heightmaps, return high value - if heightmap[i] == -31000 or - heightmap[i] == 31000 - then - return max_height_difference + 1 - end - if heightmap[i] < min_y - then - min_y = heightmap[i] - end - if heightmap[i] > max_y - then - max_y = heightmap[i] - end - end - -- set next line - square_start = square_start + 80 - square_end = square_end + 80 - end - -- return the difference between highest and lowest pos in chunk - local height_diff = max_y - min_y - -- filter buggy heightmaps - if height_diff <= 1 - then - return max_height_difference + 1 - end - -- debug info - settlements.debug("heightdiff ".. height_diff) - return height_diff + local heightmap = minetest.get_mapgen_object("heightmap") + + if not heightmap then + minetest.log("action", "No heightmap. That should not happen") + return max_height_difference + 1 + end + + --minetest.log("action", "heightmap size: " .. tostring(#heightmap)) + + -- max height and min height, initialize with impossible values for easier first time setting + local max_y = -50000 + local min_y = 50000 + -- only evaluate the center square of heightmap 40 x 40 + local square_start = 1621 + local square_end = 1661 + for j = 1 , 40, 1 do + if square_start >= #heightmap then + --minetest.log("action", "Heightmap size reached. Go no further outside") + break + end + for i = square_start, square_end, 1 do + --minetest.log("action", "current hm index: " .. tostring(i) .. "current hm entry: " .. tostring(heightmap[i])) + + if i >= #heightmap then + --minetest.log("action", "Heightmap size reached. Go no further") + break + end + local current_hm_entry = heightmap[i] + if current_hm_entry then + -- skip buggy heightmaps, return high value. Converted mcl5 maps can be -31007 + if current_hm_entry == -31000 or heightmap[i] == 31000 then + --minetest.log("action", "incorrect heighmap values. abandon") + return max_height_difference + 1 + end + if current_hm_entry < min_y then + min_y = current_hm_entry + end + if current_hm_entry > max_y then + max_y = current_hm_entry + end + else + --minetest.log("action", "Failed to get hm index: " .. tostring(i) .. "and ... " .. tostring(#heightmap)) + end + end + -- set next line + square_start = square_start + 80 + square_end = square_end + 80 + end + -- return the difference between highest and lowest pos in chunk + local height_diff = max_y - min_y + + --minetest.log("action", "height_diff = " .. tostring(height_diff)) + + -- filter buggy heightmaps + if height_diff <= 1 then + return max_height_difference + 1 + end + --minetest.log("action", "return heigh diff = " .. tostring(height_diff)) + -- debug info + settlements.debug("heightdiff ".. height_diff) + return height_diff end ------------------------------------------------------------------------------- -- Set array to list diff --git a/mods/MAPGEN/tsm_railcorridors/depends.txt b/mods/MAPGEN/tsm_railcorridors/depends.txt deleted file mode 100644 index a22565d76..000000000 --- a/mods/MAPGEN/tsm_railcorridors/depends.txt +++ /dev/null @@ -1,8 +0,0 @@ -mcl_init -mcl_worlds -mcl_core -mcl_loot -mcl_tnt -mcl_farming -mcl_mobspawners -mcl_minecarts diff --git a/mods/MAPGEN/tsm_railcorridors/description.txt b/mods/MAPGEN/tsm_railcorridors/description.txt deleted file mode 100644 index 33bfd506a..000000000 --- a/mods/MAPGEN/tsm_railcorridors/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds simple underground mines with railways and occasional treasure chests. diff --git a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua index 00e2af687..4a27586a2 100644 --- a/mods/MAPGEN/tsm_railcorridors/gameconfig.lua +++ b/mods/MAPGEN/tsm_railcorridors/gameconfig.lua @@ -27,7 +27,7 @@ if mg_name == "v6" then } else -- This generates dark oak wood in mesa biomes and oak wood everywhere else. - tsm_railcorridors.nodes.corridor_woods_function = function(pos, node) + function tsm_railcorridors.nodes.corridor_woods_function(pos, node) if minetest.get_item_group(node.name, "hardened_clay") ~= 0 then return "mcl_core:darkwood", "mcl_fences:dark_oak_fence" else @@ -42,6 +42,14 @@ tsm_railcorridors.carts = { "mcl_minecarts:minecart" } function tsm_railcorridors.on_construct_cart(pos, cart) -- TODO: Fill cart with treasures + + -- This is it? There's this giant hack announced in + -- the other file and I grep for the function and it's + -- a stub? :) + + -- The path here using some minetest.after hackery was + -- deactivated in init.lua - reactivate when this does + -- something the function is called RecheckCartHack. end -- Fallback function. Returns a random treasure. This function is called for chests @@ -66,7 +74,9 @@ function tsm_railcorridors.get_treasures(pr) items = { { itemstring = "mcl_mobs:nametag", weight = 30 }, { itemstring = "mcl_core:apple_gold", weight = 20 }, - { itemstack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}), weight = 10 }, + { itemstring = "mcl_books:book", weight = 10, func = function(stack, pr) + mcl_enchanting.enchant_uniform_randomly(stack, {"soul_speed"}, pr) + end }, { itemstring = "", weight = 5}, { itemstring = "mcl_core:pick_iron", weight = 5 }, { itemstring = "mcl_core:apple_gold_enchanted", weight = 1 }, @@ -82,7 +92,7 @@ function tsm_railcorridors.get_treasures(pr) { itemstring = "mcl_farming:melon_seeds", weight = 10, amount_min = 2, amount_max = 4 }, { itemstring = "mcl_farming:pumpkin_seeds", weight = 10, amount_min = 2, amount_max = 4 }, { itemstring = "mcl_core:iron_ingot", weight = 10, amount_min = 1, amount_max = 5 }, - { itemstring = "mcl_dye:blue", weight = 5, amount_min = 4, amount_max = 9 }, + { itemstring = "mcl_core:lapis", weight = 5, amount_min = 4, amount_max = 9 }, { itemstring = "mesecons:redstone", weight = 5, amount_min = 4, amount_max = 9 }, { itemstring = "mcl_core:gold_ingot", weight = 5, amount_min = 1, amount_max = 3 }, { itemstring = "mcl_core:diamond", weight = 3, amount_min = 1, amount_max = 2 }, diff --git a/mods/MAPGEN/tsm_railcorridors/init.lua b/mods/MAPGEN/tsm_railcorridors/init.lua index f2e02d997..d68c58aa3 100644 --- a/mods/MAPGEN/tsm_railcorridors/init.lua +++ b/mods/MAPGEN/tsm_railcorridors/init.lua @@ -1,3 +1,6 @@ +local pairs = pairs +local tonumber = tonumber + tsm_railcorridors = {} -- Load node names @@ -8,7 +11,7 @@ local setting -- Probability function -- TODO: Check if this is correct -local P = function (float) +local function P(float) return math.floor(32767 * float) end @@ -80,14 +83,14 @@ end -- Enable cobwebs local place_cobwebs = true setting = minetest.settings:get_bool("tsm_railcorridors_place_cobwebs") -if setting ~= nil then +if setting then place_cobwebs = setting end -- Enable mob spawners local place_mob_spawners = true setting = minetest.settings:get_bool("tsm_railcorridors_place_mob_spawners") -if setting ~= nil then +if setting then place_mob_spawners = setting end @@ -114,7 +117,8 @@ if not tsm_railcorridors.nodes.corridor_woods_function then end -- Random Perlin noise generators -local pr, pr_carts, pr_treasures, pr_deco, webperlin_major, webperlin_minor +local pr, pr_carts, pr_deco, webperlin_major, webperlin_minor +--local pr_treasures local function InitRandomizer(seed) -- Mostly used for corridor gen. @@ -124,7 +128,7 @@ local function InitRandomizer(seed) -- Separate randomizer for carts because spawning carts is very timing-dependent pr_carts = PseudoRandom(seed-654) -- Chest contents randomizer - pr_treasures = PseudoRandom(seed+777) + --pr_treasures = PseudoRandom(seed+777) -- Used for cobweb generation, both noises have to reach a high value for cobwebs to appear webperlin_major = PerlinNoise(934, 3, 0.6, 500) webperlin_minor = PerlinNoise(834, 3, 0.6, 50) @@ -150,16 +154,16 @@ local function SetNodeIfCanBuild(pos, node, check_above, can_replace_rail) local abovename = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z}).name local abovedef = minetest.registered_nodes[abovename] if abovename == "unknown" or abovename == "ignore" or - (abovedef.groups and abovedef.groups.attached_node) or + (abovedef and abovedef.groups and abovedef.groups.attached_node) or -- This is done because cobwebs are often fake liquids - (abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then + (abovedef and abovedef.liquidtype ~= "none" and abovename ~= tsm_railcorridors.nodes.cobweb) then return false end end local name = minetest.get_node(pos).name local def = minetest.registered_nodes[name] if name ~= "unknown" and name ~= "ignore" and - ((def.is_ground_content and def.liquidtype == "none") or + ((def and def.is_ground_content and def.liquidtype == "none") or name == tsm_railcorridors.nodes.cobweb or name == tsm_railcorridors.nodes.torch_wall or name == tsm_railcorridors.nodes.torch_floor or @@ -174,7 +178,7 @@ end -- Tries to place a rail, taking the damage chance into account local function PlaceRail(pos, damage_chance) - if damage_chance ~= nil and damage_chance > 0 then + if damage_chance and damage_chance > 0 then local x = pr:next(0,100) if x <= damage_chance then return false @@ -188,7 +192,7 @@ end local function IsGround(pos) local nodename = minetest.get_node(pos).name local nodedef = minetest.registered_nodes[nodename] - return nodename ~= "unknown" and nodename ~= "ignore" and nodedef.is_ground_content and nodedef.walkable and nodedef.liquidtype == "none" + return nodename ~= "unknown" and nodename ~= "ignore" and nodedef and nodedef.is_ground_content and nodedef.walkable and nodedef.liquidtype == "none" end -- Returns true if rails are allowed to be placed on top of this node @@ -196,7 +200,7 @@ local function IsRailSurface(pos) local nodename = minetest.get_node(pos).name local nodename_above = minetest.get_node({x=pos.x,y=pos.y+2,z=pos.z}).name local nodedef = minetest.registered_nodes[nodename] - return nodename ~= "unknown" and nodename ~= "ignore" and nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodename_above ~= tsm_railcorridors.nodes.rail + return nodename ~= "unknown" and nodename ~= "ignore" and nodedef and nodedef.walkable and (nodedef.node_box == nil or nodedef.node_box.type == "regular") and nodename_above ~= tsm_railcorridors.nodes.rail end -- Checks if the node is empty space which requires to be filled by a platform @@ -207,7 +211,7 @@ local function NeedsPlatform(pos) local falling = minetest.get_item_group(node.name, "falling_node") == 1 return -- Node can be replaced if ground content or rail - (node.name ~= "ignore" and node.name ~= "unknown" and nodedef.is_ground_content) and + (node.name ~= "ignore" and node.name ~= "unknown" and nodedef and nodedef.is_ground_content) and -- Node needs platform if node below is not walkable. -- Unless 2 nodes below there is dirt: This is a special case for the starter cube. ((nodedef.walkable == false and node2.name ~= tsm_railcorridors.nodes.dirt) or @@ -249,7 +253,7 @@ local function Cube(p, radius, node, replace_air_only, wood, post) if yi == y_top then local topnode = minetest.get_node({x=xi,y=yi+1,z=zi}) local topdef = minetest.registered_nodes[topnode.name] - if minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef.liquidtype == "none" then + if minetest.get_item_group(topnode.name, "attached_node") ~= 1 and topdef and topdef.liquidtype == "none" then ok = true end elseif column_last_attached and yi == column_last_attached - 1 then @@ -273,7 +277,7 @@ local function Cube(p, radius, node, replace_air_only, wood, post) elseif wood and (xi == p.x or zi == p.z) and thisnode.name == wood then local topnode = minetest.get_node({x=xi,y=yi+1,z=zi}) local topdef = minetest.registered_nodes[topnode.name] - if topdef.walkable and topnode.name ~= wood then + if topdef and topdef.walkable and topnode.name ~= wood then minetest.set_node({x=xi,y=yi,z=zi}, node) -- Check for torches around the wood and schedule them -- for removal @@ -360,18 +364,24 @@ local function Platform(p, radius, node, node2) if not node2 then node2 = { name = tsm_railcorridors.nodes.dirt } end + local n1 = {} + local n2 = {} for zi = p.z-radius, p.z+radius do for xi = p.x-radius, p.x+radius do local np, np2 = NeedsPlatform({x=xi,y=p.y,z=zi}) if np then if np2 then - minetest.set_node({x=xi,y=p.y-1,z=zi}, node2) + --minetest.set_node({x=xi,y=p.y-1,z=zi}, node2) + table.insert(n1,{x=xi,y=p.y-1,z=zi}) else - minetest.set_node({x=xi,y=p.y-1,z=zi}, node) + --minetest.set_node({x=xi,y=p.y-1,z=zi}, node) + table.insert(n2,{x=xi,y=p.y-1,z=zi}) end end end end + minetest.bulk_set_node(n1,node) + minetest.bulk_set_node(n2,node2) end -- Chests @@ -380,21 +390,26 @@ local function PlaceChest(pos, param2) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() local items = tsm_railcorridors.get_treasures(pr) - mcl_loot.fill_inventory(inv, "main", items) + mcl_loot.fill_inventory(inv, "main", items, pr) end end + -- This function checks if a cart has ACTUALLY been spawned. -- To be calld by minetest.after. -- This is a workaround thanks to the fact that minetest.add_entity is unreliable as fuck -- See: https://github.com/minetest/minetest/issues/4759 -- FIXME: Kill this horrible hack with fire as soon you can. + +-- Why did anyone activate it in the first place? It doesn't +-- have a function seeing as there are no chest minecarts yet. +--[[ local function RecheckCartHack(params) local pos = params[1] local cart_id = params[2] -- Find cart - for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do - if obj ~= nil and obj:get_luaentity().name == cart_id then + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do + if obj and obj:get_luaentity().name == cart_id then -- Cart found! We can now safely call the callback func. -- (calling it earlier has the danger of failing) minetest.log("info", "[tsm_railcorridors] Cart spawn succeeded: "..minetest.pos_to_string(pos)) @@ -404,6 +419,8 @@ local function RecheckCartHack(params) end minetest.log("info", "[tsm_railcorridors] Cart spawn FAILED: "..minetest.pos_to_string(pos)) end +--]] + -- Try to place a cobweb. -- pos: Position of cobweb @@ -425,7 +442,7 @@ local function TryPlaceCobweb(pos, needs_check, side_vector) local cpos = vector.add(pos, check_vectors[c]) local cname = minetest.get_node(cpos).name local cdef = minetest.registered_nodes[cname] - if cname ~= "ignore" and cdef.walkable then + if cname ~= "ignore" and cdef and cdef.walkable then check_passed = true break end @@ -519,12 +536,12 @@ local function WoodSupport(p, wood, post, torches, dir, torchdir) local nodedef1 = minetest.registered_nodes[minetest.get_node(pos1).name] local nodedef2 = minetest.registered_nodes[minetest.get_node(pos2).name] - if nodedef1.walkable then + if nodedef1 and nodedef1.walkable then pos1.y = pos1.y + 1 end SetNodeIfCanBuild(pos1, node, true) - if nodedef2.walkable then + if nodedef2 and nodedef2.walkable then pos2.y = pos2.y + 1 end SetNodeIfCanBuild(pos2, node, true) @@ -680,11 +697,11 @@ local function create_corridor_section(waypoint, axis, sign, up_or_down, up_or_d railsegcount = segcount end for i=1,railsegcount do - local p = {x=waypoint.x+vek.x*i, y=waypoint.y+vek.y*i-1, z=waypoint.z+vek.z*i} + local p = {x = waypoint.x + vek.x * i, y = waypoint.y + vek.y * i-1, z = waypoint.z + vek.z * i} -- Randomly returns either the left or right side of the main rail. -- Also returns offset as second return value. - local left_or_right = function(pos, vek) + local function left_or_right(pos, vek) local off if pr:next(1, 2) == 1 then -- left @@ -764,7 +781,7 @@ local function create_corridor_section(waypoint, axis, sign, up_or_down, up_or_d -- Place cobwebs left and right in the corridor if place_cobwebs and tsm_railcorridors.nodes.cobweb then -- Helper function to place a cobweb at the side (based on chance an Perlin noise) - local cobweb_at_side = function(basepos, vek) + local function cobweb_at_side(basepos, vek) if pr:next(1,5) == 1 then local h = pr:next(0, 2) -- 3 possible cobweb heights local cpos = {x=basepos.x+vek.x, y=basepos.y+h, z=basepos.z+vek.z} @@ -823,7 +840,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da local s = sign local ud = false -- Up or down local udn = false -- Up or down is next - local udp = false -- Up or down was previous + local udp -- Up or down was previous local up = false -- true if going up local upp = false -- true if was going up previously for i=1,length do @@ -911,7 +928,7 @@ local function create_corridor_line(waypoint, axis, sign, length, wood, post, da a="z" elseif a=="z" then a="x" - end; + end; s = pr:next(1, 2) == 1 end end @@ -933,7 +950,10 @@ local function spawn_carts() -- Note that the callback function is also called there. -- TODO: Move callback function to this position when the -- minetest.add_entity bug has been fixed. - minetest.after(3, RecheckCartHack, {cpos, cart_id}) + + -- minetest.after(3, RecheckCartHack, {cpos, cart_id}) + -- This whole recheck logic leads to a stub right now + -- it can be reenabled when chest carts are a thing. end end carts_table = {} @@ -1088,8 +1108,30 @@ local function create_corridor_system(main_cave_coords) return true end +mcl_structures.register_structure("mineshaft",{ + place_on = {"group:sand","group:grass_block","mcl_core:water_source","group:dirt","mcl_core:dirt_with_grass","mcl_core:gravel","group:material_stone","mcl_core:snow"}, + fill_ratio = 0.0001, + flags = "place_center_x, place_center_z, force_placement, all_floors", + sidelen = 32, + y_max = 40, + y_min = mcl_vars.mg_overworld_min, + place_func = function(pos,def,pr,blockseed) + local r = pr:next(-50,-10) + local p = vector.offset(pos,0,r,0) + if p.y < mcl_vars.mg_overworld_min + 5 then + p.y = mcl_vars.mg_overworld_min + 5 + end + if p.y > -10 then return true end + InitRandomizer(blockseed) + create_corridor_system(p, pr) + return true + end, + +}) + +--[[ Old Generation code this is VERY slow -- The rail corridor algorithm starts here -minetest.register_on_generated(function(minp, maxp, blockseed) +mcl_mapgen_core.register_generator("railcorridors", nil, function(minp, maxp, blockseed, _pr) -- We re-init the randomizer for every mapchunk as we start generating in the middle of each mapchunk. -- We can't use the mapgen seed as this would make the algorithm depending on the order the mapchunk generate. InitRandomizer(blockseed) @@ -1115,4 +1157,5 @@ minetest.register_on_generated(function(minp, maxp, blockseed) end end end -end) +end, 10) +--]] diff --git a/mods/MAPGEN/tsm_railcorridors/mod.conf b/mods/MAPGEN/tsm_railcorridors/mod.conf index db3b9740b..d1a9ada4a 100644 --- a/mods/MAPGEN/tsm_railcorridors/mod.conf +++ b/mods/MAPGEN/tsm_railcorridors/mod.conf @@ -1 +1,4 @@ name = tsm_railcorridors +author = UgnilJoZ +description = Adds simple underground mines with railways and occasional treasure chests. +depends = mcl_init, mcl_worlds, mcl_core, mcl_mapgen_core, mcl_loot, mcl_tnt, mcl_farming, mcl_mobspawners, mcl_minecarts, mcl_structures diff --git a/mods/MISC/findbiome/init.lua b/mods/MISC/findbiome/init.lua index ce7fd9799..8560d1607 100644 --- a/mods/MISC/findbiome/init.lua +++ b/mods/MISC/findbiome/init.lua @@ -1,6 +1,6 @@ -local S = minetest.get_translator("findbiome") +local S = minetest.get_translator(minetest.get_current_modname()) -local mod_biomeinfo = minetest.get_modpath("biomeinfo") ~= nil +local mod_biomeinfo = minetest.get_modpath("biomeinfo") local mg_name = minetest.get_mapgen_setting("mg_name") local water_level = tonumber(minetest.get_mapgen_setting("water_level")) @@ -119,7 +119,7 @@ local function find_biome(pos, biomes) local edge_dist = 0 local dir_step = 0 local dir_ind = 1 - local success = false + local success local spawn_pos local biome_ids @@ -166,7 +166,7 @@ local function find_biome(pos, biomes) spawn_pos = {x = spos.x, y = spos.y, z = spos.z} end if spawn_pos then - local adjusted_pos, outside = adjust_pos_to_biome_limits(spawn_pos, biome_id) + local _,outside = adjust_pos_to_biome_limits(spawn_pos, biome_id) if is_in_world(spawn_pos) and not outside then return true end diff --git a/mods/MISC/findbiome/locale/findbiome.ja.tr b/mods/MISC/findbiome/locale/findbiome.ja.tr new file mode 100644 index 000000000..60eb7e3c8 --- /dev/null +++ b/mods/MISC/findbiome/locale/findbiome.ja.tr @@ -0,0 +1,10 @@ +# textdomain: findbiome +Find and teleport to biome=バイオームを探し、テレポート +=<バイオーム> +No player.=プレイヤーがいません。 +Biome does not exist!=バイオームが存在しません! +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 mapgen のサポートには "biomeinfo" モッドが必要です! diff --git a/mods/MISC/findbiome/locale/findbiome.pl.tr b/mods/MISC/findbiome/locale/findbiome.pl.tr new file mode 100644 index 000000000..bc25b5758 --- /dev/null +++ b/mods/MISC/findbiome/locale/findbiome.pl.tr @@ -0,0 +1,10 @@ +# textdomain: findbiome +Find and teleport to biome=Znajdź i teleportuj do biomu += +No player.=Brak gracza. +Biome does not exist!=Biom nie istnieje! +Biome found at @1.=Nie znaleziono biomu w @1. +No biome found!=Nie znaleziono biomu! +List all biomes=Lista biomów. +No biomes.=Brak biomów. +Not supported. The “biomeinfo” mod is required for v6 mapgen support!=Nie wspierane. Aby wspierać generator map v6 wymagany jest mod "biomeinfo"! diff --git a/mods/MISC/findbiome/locale/findbiome.zh_TW.tr b/mods/MISC/findbiome/locale/findbiome.zh_TW.tr new file mode 100644 index 000000000..d84abda86 --- /dev/null +++ b/mods/MISC/findbiome/locale/findbiome.zh_TW.tr @@ -0,0 +1,10 @@ +# textdomain: findbiome +Find and teleport to biome=找尋和傳送至生態域 +=<生態域> +No player.=沒有玩家。 +Biome does not exist!=生態域不存在! +Biome found at @1.=生態域在 @1 找到。 +No biome found!=生態域找不到! +List all biomes=列出所有生態域 +No biomes.=沒有生態域。 +Not supported. The “biomeinfo” mod is required for v6 mapgen support!=不支援。「biomeinfo」MOD要求v6世界生成器! diff --git a/mods/MISC/findbiome/mod.conf b/mods/MISC/findbiome/mod.conf index a8ab4e3c1..918f18436 100644 --- a/mods/MISC/findbiome/mod.conf +++ b/mods/MISC/findbiome/mod.conf @@ -1,3 +1,4 @@ -name=findbiome -description=Add commands to list and find biomes -optional_depends=biomeinfo +name = findbiome +author = paramat +description = Add commands to list and find biomes +optional_depends = biomeinfo diff --git a/mods/MISC/mcl_commands/alias.lua b/mods/MISC/mcl_commands/alias.lua new file mode 100644 index 000000000..5c9ee9f3c --- /dev/null +++ b/mods/MISC/mcl_commands/alias.lua @@ -0,0 +1,30 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local function register_chatcommand_alias(alias, cmd) + local def = minetest.chatcommands[cmd] + minetest.register_chatcommand(alias, def) +end + +local function rename_chatcommand(newname, cmd) + local def = minetest.chatcommands[cmd] + minetest.register_chatcommand(newname, def) + minetest.unregister_chatcommand(cmd) +end + +if minetest.settings:get_bool("mcl_builtin_commands_overide", true) then + register_chatcommand_alias("?", "help") + register_chatcommand_alias("pardon", "unban") + rename_chatcommand("stop", "shutdown") + register_chatcommand_alias("tell", "msg") + register_chatcommand_alias("w", "msg") + register_chatcommand_alias("tp", "teleport") + rename_chatcommand("clear", "clearinv") + + minetest.register_chatcommand("banlist", { + description = S("List bans"), + privs = minetest.chatcommands["ban"].privs, + func = function(name) + return true, S("Ban list: @1", minetest.get_ban_list()) + end, + }) +end \ No newline at end of file diff --git a/mods/MISC/mcl_commands/depends.txt b/mods/MISC/mcl_commands/depends.txt deleted file mode 100644 index 6e14ff130..000000000 --- a/mods/MISC/mcl_commands/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_death_messages? diff --git a/mods/MISC/mcl_commands/init.lua b/mods/MISC/mcl_commands/init.lua index 8b931d0b8..a287c2926 100644 --- a/mods/MISC/mcl_commands/init.lua +++ b/mods/MISC/mcl_commands/init.lua @@ -1,163 +1,11 @@ -local minecraftaliases = true +local modpath = minetest.get_modpath(minetest.get_current_modname()) -local S = minetest.get_translator("mcl_commands") - -local mod_death_messages = minetest.get_modpath("mcl_death_messages") - -local function handle_kill_command(suspect, victim) - if minetest.settings:get_bool("enable_damage") == false then - return false, S("Players can't be killed right now, damage has been disabled.") - end - local victimref = minetest.get_player_by_name(victim) - if victimref == nil then - return false, S("Player @1 does not exist.", victim) - elseif victimref:get_hp() <= 0 then - if suspect == victim then - return false, S("You are already dead") - else - return false, S("@1 is already dead", victim) - end - end - -- If player holds a totem of undying, destroy it before killing, - -- so it doesn't rescue the player. - local wield = victimref:get_wielded_item() - if wield:get_name() == "mobs_mc:totem" then - victimref:set_wielded_item("") - end - if mod_death_messages then - local msg - if suspect == victim then - msg = S("@1 committed suicide.", victim) - else - msg = S("@1 was killed by @2.", victim, suspect) - end - mcl_death_messages.player_damage(victimref, msg) - end - -- DIE! - victimref:set_hp(0) - -- Log - if not suspect == victim then - minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) - else - minetest.log("action", string.format("%s committed suicide using /kill", victim)) - end - return true -end - -if minetest.registered_chatcommands["kill"] then - minetest.unregister_chatcommand("kill") -end -minetest.register_chatcommand("kill", { - params = S("[]"), - description = S("Kill player or yourself"), - privs = {server=true}, - func = function(name, param) - if(param == "") then - -- Selfkill - return handle_kill_command(name, name) - else - return handle_kill_command(name, param) - end - end, -}) - -minetest.register_privilege("announce", { - description = S("Can use /say"), - give_to_singleplayer = false, -}) -minetest.register_chatcommand("say", { - params = S(""), - description = S("Send a message to every player"), - privs = {announce=true}, - func = function(name, param) - if not param then - return false, S("Invalid usage, see /help say.") - end - minetest.chat_send_all(("["..name.."] "..param)) - return true - end, -}) - -minetest.register_chatcommand("setblock", { - params = S(",, "), - description = S("Set node at given position"), - privs = {give=true, interact=true}, - func = function(name, param) - local p = {} - local nodestring = nil - p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$") - p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z) - if p.x and p.y and p.z and nodestring then - local itemstack = ItemStack(nodestring) - if itemstack:is_empty() or not minetest.registered_nodes[itemstack:get_name()] then - return false, S("Invalid node") - end - minetest.set_node(p, {name=nodestring}) - return true, S("@1 spawned.", nodestring) - end - return false, S("Invalid parameters (see /help setblock)") - end, -}) - -minetest.register_chatcommand("list", { - description = S("Show who is logged on"), - params = "", - privs = {}, - func = function(name) - local players = "" - for _, player in ipairs(minetest.get_connected_players()) do - players = players..player:get_player_name().."\n" - end - minetest.chat_send_player(name, players) - end -}) - -minetest.register_chatcommand("seed", { - description = S("Displays the world seed"), - params = "", - privs = {}, - func = function(name) - minetest.chat_send_player(name, minetest.get_mapgen_setting("seed")) - end -}) - -local function register_chatcommand_alias(alias, cmd) - local def = minetest.chatcommands[cmd] - minetest.register_chatcommand(alias, def) -end - --- Replace spawnentity cmd to disallow spawning of hostile mobs if disabled -local orig_func = minetest.registered_chatcommands["spawnentity"].func -local cmd = table.copy(minetest.registered_chatcommands["spawnentity"]) -cmd.func = function(name, param) - local ent = minetest.registered_entities[param] - if minetest.settings:get_bool("only_peaceful_mobs", false) and ent and ent._cmi_is_mob and ent.type == "monster" then - return false, S("Only peaceful mobs allowed!") - else - local bool, msg = orig_func(name, param) - return bool, msg - end -end -minetest.unregister_chatcommand("spawnentity") -minetest.register_chatcommand("spawnentity", cmd) - -if minecraftaliases then - register_chatcommand_alias("?", "help") - register_chatcommand_alias("who", "list") - register_chatcommand_alias("pardon", "unban") - register_chatcommand_alias("stop", "shutdown") - register_chatcommand_alias("summon", "spawnentity") - register_chatcommand_alias("tell", "msg") - register_chatcommand_alias("w", "msg") - register_chatcommand_alias("tp", "teleport") - register_chatcommand_alias("clear", "clearinv") - - minetest.register_chatcommand("banlist", { - description = S("List bans"), - privs = minetest.chatcommands["ban"].privs, - func = function(name) - return true, S("Ban list: @1", minetest.get_ban_list()) - end, - }) -end +dofile(modpath.."/kill.lua") +dofile(modpath.."/setblock.lua") +dofile(modpath.."/seed.lua") +dofile(modpath.."/summon.lua") +dofile(modpath.."/say.lua") +dofile(modpath.."/list.lua") +dofile(modpath.."/sound.lua") +dofile(modpath.."/alias.lua") \ No newline at end of file diff --git a/mods/MISC/mcl_commands/kill.lua b/mods/MISC/mcl_commands/kill.lua new file mode 100644 index 000000000..5478e6bf6 --- /dev/null +++ b/mods/MISC/mcl_commands/kill.lua @@ -0,0 +1,43 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local function handle_kill_command(suspect, victim) + if minetest.settings:get_bool("enable_damage") == false then + return false, S("Players can't be killed right now, damage has been disabled.") + end + local victimref = minetest.get_player_by_name(victim) + if victimref == nil then + return false, S("Player @1 does not exist.", victim) + elseif victimref:get_hp() <= 0 then + if suspect == victim then + return false, S("You are already dead") + else + return false, S("@1 is already dead", victim) + end + end + -- DIE! + victimref:set_hp(0, {_mcl_type = "out_of_world"}) + -- Log + if not suspect == victim then + minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) + else + minetest.log("action", string.format("%s committed suicide using /kill", victim)) + end + return true +end + +if minetest.registered_chatcommands["kill"] then + minetest.unregister_chatcommand("kill") +end +minetest.register_chatcommand("kill", { + params = S("[]"), + description = S("Kill player or yourself"), + privs = {server=true}, + func = function(name, param) + if(param == "") then + -- Selfkill + return handle_kill_command(name, name) + else + return handle_kill_command(name, param) + end + end, +}) diff --git a/mods/MISC/mcl_commands/list.lua b/mods/MISC/mcl_commands/list.lua new file mode 100644 index 000000000..5661454b4 --- /dev/null +++ b/mods/MISC/mcl_commands/list.lua @@ -0,0 +1,14 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("list", { + description = S("Show who is logged on"), + params = "", + privs = {}, + func = function(name) + local players = "" + for _, player in ipairs(minetest.get_connected_players()) do + players = players..player:get_player_name().."\n" + end + minetest.chat_send_player(name, players) + end +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr b/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr new file mode 100644 index 000000000..16f7d357c --- /dev/null +++ b/mods/MISC/mcl_commands/locale/mcl_commands.ja.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_commands +Players can't be killed right now, damage has been disabled.=今、プレイヤーを殺ることはできません。ダメージは無効になっています。 +Player @1 does not exist.=プレイヤー @1 は存在しません。 +You are already dead=あなたはもう死んでいる +@1 is already dead=@1 はもう死んでいる +@1 committed suicide.=@1 は自害しました。 +@1 was killed by @2.=@1 は @2 に殺られました。 +[]=[<名前>] +Kill player or yourself=プレイヤーまたは自分自身を殺害 +Can use /say= /say を使用可能 +=<メッセージ> +Send a message to every player=全プレイヤーにメッセージを送信 +Invalid usage, see /help say.=無効な使用方法です、 /help say を参照してください。 +,, =,, <ノード文字列> +Set node at given position=指定された位置にノードを設定 +Invalid node=無効なノード +@1 spawned.=@1 がスポーンしました。 +Invalid parameters (see /help setblock)=無効なパラメータ ( /help setblock を参照の事) +List bans=BANのリスト +Ban list: @1=BANリスト: @1 +Show who is logged on=誰がログオンしているかを表示 +Displays the world seed=ワールドのシードを表示 +Only peaceful mobs allowed!=平和的なモブのみ許されます! diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.pl.tr b/mods/MISC/mcl_commands/locale/mcl_commands.pl.tr new file mode 100644 index 000000000..4a3ad181c --- /dev/null +++ b/mods/MISC/mcl_commands/locale/mcl_commands.pl.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_commands +Players can't be killed right now, damage has been disabled.=Gracze nie mogą się zabić, obrażenia zostały wyłączone. +Player @1 does not exist.=Gracz @1 nie istnieje. +You are already dead=Już nie żyjesz +@1 is already dead=@1 już nie żyje +@1 committed suicide.=@1 popełniła samobójstwo. +@1 was killed by @2.=@1 została zabita przez @2. +[]=[] +Kill player or yourself=Zabij gracza lub siebie +Can use /say=Może używać /say += +Send a message to every player=Wyślij wiadomość do każdego gracza +Invalid usage, see /help say.=Niepoprawne użyciu, zobacz /help say. +,, =,, +Set node at given position=Ustaw node w danej pozycji +Invalid node=Niepoprawny node +@1 spawned.=@1 przywołany. +Invalid parameters (see /help setblock)=Niepoprawne parametry (zobacz /help setblock) +List bans=Pokaż zbanowanych +Ban list: @1=Lista zbanowanych: @1 +Show who is logged on=Pokaż zalogowanych +Displays the world seed=Wyświetl ziarno świata +Only peaceful mobs allowed!=Tylko pokojowe moby dozwolone! diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr b/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr index 686c8067c..77ff7d4f9 100644 --- a/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr +++ b/mods/MISC/mcl_commands/locale/mcl_commands.ru.tr @@ -3,7 +3,7 @@ Players can't be killed right now, damage has been disabled.=Игроки не Player @1 does not exist.=Игрок @1 не существует. You are already dead=Вы уже мертвы @1 is already dead=@1 уже мертв(а) -@1 committed suicide.=@1 совершил(а) роскомнадзор. +@1 committed suicide.=@1 совершил(а) самоубийство. @1 was killed by @2.=@1 был(а) убит(а) @2. []=[<имя>] Kill player or yourself=Убить игрока или себя @@ -11,13 +11,13 @@ Can use /say=Можно использовать /say =<сообщение> Send a message to every player=Отправляет сообщение всем игрокам Invalid usage, see /help say.=Недопустимое использование, см. /help say. -,, =,, <СтрокаУзла> -Set node at given position=Устанавливает узел в заданной позиции -Invalid node=Неправильный узел +,, =,, <ИмяБлока> +Set node at given position=Устанавливает блок в заданном месте +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=Показывает значение зерна мира (seed) -Only peaceful mobs allowed!=Включены только мирные мобы! +Displays the world seed=Показывает значение зерна мира +Only peaceful mobs allowed!=Разрешены только мирные сущности! diff --git a/mods/MISC/mcl_commands/locale/mcl_commands.zh_TW.tr b/mods/MISC/mcl_commands/locale/mcl_commands.zh_TW.tr new file mode 100644 index 000000000..0f3885cfe --- /dev/null +++ b/mods/MISC/mcl_commands/locale/mcl_commands.zh_TW.tr @@ -0,0 +1,23 @@ +# textdomain: mcl_commands +Players can't be killed right now, damage has been disabled.=玩家現在不能被殺死,傷害已被禁用。 +Player @1 does not exist.=玩家 @1 不存在。 +You are already dead=你已經死了 +@1 is already dead=@1 已經死了。 +@1 committed suicide.=@1 自殺了。 +@1 was killed by @2.=@1 被 @2 殺死了。 +[]=[<名字>] +Kill player or yourself=殺死玩家或自己 +Can use /say=可以使用 /say +=<信息> +Send a message to every player=廣播信息給每個玩家 +Invalid usage, see /help say.=無效用法,見 /help say +,, =,, <方塊名稱> +Set node at given position=在指定位置放置指定方塊 +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=顯示種子碼 +Only peaceful mobs allowed!=只允許和平生物! diff --git a/mods/MISC/mcl_commands/mod.conf b/mods/MISC/mcl_commands/mod.conf new file mode 100644 index 000000000..dba130564 --- /dev/null +++ b/mods/MISC/mcl_commands/mod.conf @@ -0,0 +1,4 @@ +name = mcl_commands +author = Wuzzy +description = MCL2 commands +depends = mcl_colors diff --git a/mods/MISC/mcl_commands/say.lua b/mods/MISC/mcl_commands/say.lua new file mode 100644 index 000000000..9fd53c174 --- /dev/null +++ b/mods/MISC/mcl_commands/say.lua @@ -0,0 +1,18 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_privilege("announce", { + description = S("Can use /say"), + give_to_singleplayer = false, +}) +minetest.register_chatcommand("say", { + params = S(""), + description = S("Send a message to every player"), + privs = {announce=true}, + func = function(name, param) + if not param then + return false, S("Invalid usage, see /help say.") + end + minetest.chat_send_all(("["..name.."] "..param)) + return true + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/seed.lua b/mods/MISC/mcl_commands/seed.lua new file mode 100644 index 000000000..2ebb04474 --- /dev/null +++ b/mods/MISC/mcl_commands/seed.lua @@ -0,0 +1,10 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("seed", { + description = S("Displays the world seed"), + params = "", + privs = {}, + func = function(name) + minetest.chat_send_player(name, "Seed: ["..minetest.colorize(mcl_colors.GREEN, ""..minetest.get_mapgen_setting("seed")).."]") + end +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/setblock.lua b/mods/MISC/mcl_commands/setblock.lua new file mode 100644 index 000000000..95acdd35d --- /dev/null +++ b/mods/MISC/mcl_commands/setblock.lua @@ -0,0 +1,22 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("setblock", { + params = S(",, "), + description = S("Set node at given position"), + privs = {give=true, interact=true}, + func = function(name, param) + local p = {} + local nodestring + p.x, p.y, p.z, nodestring = param:match("^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+) +(.+)$") + p.x, p.y, p.z = tonumber(p.x), tonumber(p.y), tonumber(p.z) + if p.x and p.y and p.z and nodestring then + local itemstack = ItemStack(nodestring) + if itemstack:is_empty() or not minetest.registered_nodes[itemstack:get_name()] then + return false, S("Invalid node") + end + minetest.set_node(p, {name=nodestring}) + return true, S("@1 spawned.", nodestring) + end + return false, S("Invalid parameters (see /help setblock)") + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/sound.lua b/mods/MISC/mcl_commands/sound.lua new file mode 100644 index 000000000..5833676f3 --- /dev/null +++ b/mods/MISC/mcl_commands/sound.lua @@ -0,0 +1,43 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +minetest.register_chatcommand("playsound",{ + params = S(" "), --TODO:add source + description = S("Play a sound. Arguments: : name of the sound. : Target."), + privs = {server = true}, + func = function(name, rawparams) + local P = {} + local i = 0 + for str in string.gmatch(rawparams, "([^ ]+)") do + i = i + 1 + P[i] = str + end + local params = {} + if P[1] == tostring(P[1]) then + params.name = P[1] + else + return false, S("Sound name is invalid!") --TODO: add mc chat message + end + if P[2] == tostring(P[2]) and minetest.player_exists(P[2]) then + params.target = P[2] + else + return false, S("Target is invalid!!") + end + -- if P[3] then + -- params.pos = nil --TODO:position + -- else + -- params.pos = nil + -- end + -- if P[4] == tonumber(P[4]) then + -- params.gain = P[4] + -- else + -- params.gain = 1.0 + -- end + -- if P[5] == tonumber(P[5]) then + -- params.pitch = P[5] + -- else + -- params.pitch = 1.0 + -- end + minetest.sound_play({name = params.name}, {to_player = params.target}, true) --TODO: /stopsound + return true + end, +}) \ No newline at end of file diff --git a/mods/MISC/mcl_commands/summon.lua b/mods/MISC/mcl_commands/summon.lua new file mode 100644 index 000000000..118d3e23b --- /dev/null +++ b/mods/MISC/mcl_commands/summon.lua @@ -0,0 +1,15 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local orig_func = minetest.registered_chatcommands["spawnentity"].func +local cmd = table.copy(minetest.registered_chatcommands["spawnentity"]) +cmd.func = function(name, param) + local ent = minetest.registered_entities[param] + if minetest.settings:get_bool("only_peaceful_mobs", false) and ent and ent.is_mob and ent.type == "monster" then + return false, S("Only peaceful mobs allowed!") + else + local bool, msg = orig_func(name, param) + return bool, msg + end +end +minetest.unregister_chatcommand("spawnentity") +minetest.register_chatcommand("summon", cmd) \ No newline at end of file diff --git a/mods/MISC/mcl_privs/description.txt b/mods/MISC/mcl_privs/description.txt deleted file mode 100644 index 23beb168b..000000000 --- a/mods/MISC/mcl_privs/description.txt +++ /dev/null @@ -1 +0,0 @@ -Shared privileges in MineClone 2 diff --git a/mods/MISC/mcl_privs/init.lua b/mods/MISC/mcl_privs/init.lua index 00670db1c..ddca9f946 100644 --- a/mods/MISC/mcl_privs/init.lua +++ b/mods/MISC/mcl_privs/init.lua @@ -1,5 +1,46 @@ -local S = minetest.get_translator("mcl_privs") +local S = minetest.get_translator(minetest.get_current_modname()) minetest.register_privilege("maphack", { description = S("Can place and use advanced blocks like mob spawners, command blocks and barriers."), }) + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + local meta = player:get_meta() + if meta:get_int("mcl_privs:fly_changed") == 1 then return end + + local fly = nil + if minetest.is_creative_enabled(name) then + fly = true + end + local player_privs = minetest.get_player_privs(name) + player_privs.fly = fly + minetest.set_player_privs(name, player_privs) +end) + +for _, action in pairs({"grant", "revoke"}) do + minetest["register_on_priv_" .. action](function(name, _, priv) + local player = minetest.get_player_by_name(name) + if not player then + return + end + + local meta = player:get_meta() + + if priv == "fly" then + meta:set_int("mcl_privs:fly_changed", 1) + end + + --[[ + so e.g. hackers who have been revoked of the interact privilege + will not automatically get the interact privilege through the mcl shields code back + ]] + if priv == "interact" then + if action == "revoke" then + meta:set_int("mcl_privs:interact_revoked", 1) + else + meta:set_int("mcl_privs:interact_revoked", 0) + end + end + end) +end \ No newline at end of file diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr b/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr new file mode 100644 index 000000000..7b8a9fbc7 --- /dev/null +++ b/mods/MISC/mcl_privs/locale/mcl_privs.ja.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_privs +Can place and use advanced blocks like mob spawners, command blocks and barriers.=モブスポナー、コマンドブロック、バリアなどの高度なブロックを配置・使用できます。 diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.pl.tr b/mods/MISC/mcl_privs/locale/mcl_privs.pl.tr new file mode 100644 index 000000000..10984ef54 --- /dev/null +++ b/mods/MISC/mcl_privs/locale/mcl_privs.pl.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_privs +Can place and use advanced blocks like mob spawners, command blocks and barriers.=Może kłaść i używać zaawansowane bloki takie jak spawnery, bloki poleceń czy bariery. diff --git a/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr b/mods/MISC/mcl_privs/locale/mcl_privs.ru.tr index a3f37c365..678ebf4e0 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_privs/locale/mcl_privs.zh_TW.tr b/mods/MISC/mcl_privs/locale/mcl_privs.zh_TW.tr new file mode 100644 index 000000000..d4e3f96f6 --- /dev/null +++ b/mods/MISC/mcl_privs/locale/mcl_privs.zh_TW.tr @@ -0,0 +1,2 @@ +# textdomain: mcl_privs +Can place and use advanced blocks like mob spawners, command blocks and barriers.=可以放置和使用高級方塊,如生怪磚、命令方塊和屏障 diff --git a/mods/MISC/mcl_privs/mod.conf b/mods/MISC/mcl_privs/mod.conf new file mode 100644 index 000000000..ab1f61877 --- /dev/null +++ b/mods/MISC/mcl_privs/mod.conf @@ -0,0 +1,4 @@ +name = mcl_privs +author = Wuzzy +description = Shared privileges in MineClone 2 + diff --git a/mods/MISC/mcl_temp_helper_recipes/depends.txt b/mods/MISC/mcl_temp_helper_recipes/depends.txt deleted file mode 100644 index 71556b9ae..000000000 --- a/mods/MISC/mcl_temp_helper_recipes/depends.txt +++ /dev/null @@ -1,7 +0,0 @@ -mcl_core -mcl_mobitems -mcl_end -mcl_nether -mcl_ocean -mcl_stairs -xpanes diff --git a/mods/MISC/mcl_temp_helper_recipes/init.lua b/mods/MISC/mcl_temp_helper_recipes/init.lua index f9a6ec0e9..b7607946d 100644 --- a/mods/MISC/mcl_temp_helper_recipes/init.lua +++ b/mods/MISC/mcl_temp_helper_recipes/init.lua @@ -4,7 +4,7 @@ minetest.register_craft({ type = "shapeless", - output = 'mcl_chests:trapped_chest', + output = "mcl_chests:trapped_chest", recipe = {"mcl_core:iron_ingot", "mcl_core:stick", "group:wood", "mcl_chests:chest"}, }) @@ -27,50 +27,12 @@ minetest.register_craft({ minetest.register_craft({ type = "shapeless", output = "mcl_ocean:prismarine_crystals", - recipe = { "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_ocean:prismarine_shard", "mcl_core:gold_ingot" }, -}) - -minetest.register_craft({ - output = "mcl_mobitems:shulker_shell", recipe = { - { "mcl_end:purpur_block", "mcl_end:purpur_block", "mcl_end:purpur_block", }, - { "mcl_end:purpur_block", "mcl_core:goldblock", "mcl_end:purpur_block", }, - { "mcl_end:purpur_block", "", "mcl_end:purpur_block", }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:helmet_chain", - recipe = { - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:leggings_chain", - recipe = { - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:boots_chain", - recipe = { - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - } -}) - -minetest.register_craft({ - output = "mcl_armor:chestplate_chain", - recipe = { - { "xpanes:bar_flat", "", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" }, - { "xpanes:bar_flat", "xpanes:bar_flat", "xpanes:bar_flat" }, - } + "mcl_ocean:prismarine_shard", + "mcl_ocean:prismarine_shard", + "mcl_ocean:prismarine_shard", + "mcl_core:gold_ingot", + }, }) -- Make red sand, red sandstone and more craftable in v6 @@ -112,11 +74,6 @@ minetest.register_craft({ }, }) -minetest.register_craft({ - output = "mcl_core:gold_ingot 9", - recipe = {{ "mcl_core:emerald" }}, -}) - minetest.register_craft({ output = "mcl_potions:dragon_breath 3", recipe = { diff --git a/mods/MISC/mcl_temp_helper_recipes/mod.conf b/mods/MISC/mcl_temp_helper_recipes/mod.conf new file mode 100644 index 000000000..8fff70ece --- /dev/null +++ b/mods/MISC/mcl_temp_helper_recipes/mod.conf @@ -0,0 +1,5 @@ +name = mcl_temp_helper_recipes +author = Wuzzy +description = Temporary helper recipes. +depends = mcl_core, mcl_mobitems, mcl_end, mcl_nether, mcl_ocean, mcl_stairs, xpanes + diff --git a/mods/MISC/mcl_wip/API.md b/mods/MISC/mcl_wip/API.md new file mode 100644 index 000000000..e3439af77 --- /dev/null +++ b/mods/MISC/mcl_wip/API.md @@ -0,0 +1,16 @@ +# mcl_wip +Used to mark items or nodes as WIP. + +## mcl_wip.register_wip_item(itemname) +Register as a WIP item. +If isn't a valid itemname, an error will be shown after mods loaded. + +## mcl_wip.register_experimental_item(itemname) +Register as a experimental item. +If isn't a valid itemname, an error will be shown after mods loaded. + +## mcl_wip.registered_wip_items +Table containing WIP items names. + +## mcl_wip.registered_experimental_items +Table containing experimental items names. \ No newline at end of file diff --git a/mods/MISC/mcl_wip/depends.txt b/mods/MISC/mcl_wip/depends.txt deleted file mode 100644 index 4f2001472..000000000 --- a/mods/MISC/mcl_wip/depends.txt +++ /dev/null @@ -1,10 +0,0 @@ -mcl_core -mcl_fishing -mcl_maps -mcl_minecarts -doc_identifier -mobs_mc -mcl_comparators -mcl_minecarts -mcl_paintings -mcl_potions diff --git a/mods/MISC/mcl_wip/description.txt b/mods/MISC/mcl_wip/description.txt deleted file mode 100644 index d90115acf..000000000 --- a/mods/MISC/mcl_wip/description.txt +++ /dev/null @@ -1 +0,0 @@ -Development mod for MineClone 2 which add a “WIP” (Work In Progress) comment to items which are considered to be very unfinished. diff --git a/mods/MISC/mcl_wip/init.lua b/mods/MISC/mcl_wip/init.lua index 22785d85a..54fd81c1d 100644 --- a/mods/MISC/mcl_wip/init.lua +++ b/mods/MISC/mcl_wip/init.lua @@ -1,69 +1,45 @@ --- Mod to mark WIP (Work In Progress) content +-- Allow items or nodes to be marked as WIP (Work In Progress) or Experimental -local S = minetest.get_translator("mcl_wip") +local S = minetest.get_translator(minetest.get_current_modname()) -local wip_items = { - "mcl_maps:empty_map", - "mcl_comparators:comparator_off_comp", - "mcl_minecarts:hopper_minecart", - "mcl_minecarts:command_block_minecart", - "mcl_minecarts:chest_minecart", - "mcl_minecarts:furnace_minecart", - "mobs_mc:enderdragon", - "mobs_mc:wither", - "mobs_mc:witch", - "screwdriver:screwdriver", - "mcl_paintings:painting", - "mcl_potions:night_vision", - "mcl_potions:night_vision_plus", - -- "mcl_potions:weakness", - -- "mcl_potions:weakness_plus", - -- "mcl_potions:strength", - -- "mcl_potions:strength_plus", - -- "mcl_potions:strength_2", - "mcl_potions:night_vision_splash", - "mcl_potions:night_vision_plus_splash", - -- "mcl_potions:weakness_splash", - -- "mcl_potions:weakness_plus_splash", - -- "mcl_potions:strength_splash", - -- "mcl_potions:strength_plus_splash", - -- "mcl_potions:strength_2_splash", - "mcl_potions:night_vision_lingering", - "mcl_potions:night_vision_plus_lingering", - -- "mcl_potions:weakness_lingering", - -- "mcl_potions:weakness_plus_lingering", - -- "mcl_potions:strength_lingering", - -- "mcl_potions:strength_plus_lingering", - -- "mcl_potions:strength_2_lingering", - "mcl_potions:night_vision_arrow", - "mcl_potions:night_vision_plus_arrow", -} -local experimental_items = { -} +mcl_wip = {} +mcl_wip.registered_wip_items = {} +mcl_wip.registered_experimental_items = {} -for i=1,#wip_items do - local def = minetest.registered_items[wip_items[i]] - if not def then - minetest.log("error", "[mcl_wip] Unknown item: "..wip_items[i]) - break - end - local new_description = def.description - local new_groups = table.copy(def.groups) - if new_description == "" then - new_description = wip_items[i] - end - new_description = new_description .. "\n"..core.colorize("#FF0000", S("(WIP)")) - --new_groups.not_in_craft_guide = 1 - minetest.override_item(wip_items[i], { description = new_description, groups = new_groups }) +function mcl_wip.register_wip_item(itemname) + table.insert(mcl_wip.registered_wip_items, itemname) --Only check for valid node name after mods loaded end -for i=1,#experimental_items do - local def = minetest.registered_items[experimental_items[i]] - if not def then - minetest.log("error", "[mcl_wip] Unknown item: "..experimental_items[i]) - break - end - local new_description = def.description - new_description = new_description .. "\n"..core.colorize("#FFFF00", S("(Temporary)")) - minetest.override_item(experimental_items[i], { description = new_description }) +function mcl_wip.register_experimental_item(itemname) + table.insert(mcl_wip.registered_experimental_items, itemname) end + +minetest.register_on_mods_loaded(function() + for _,name in pairs(mcl_wip.registered_wip_items) do + local def = minetest.registered_items[name] + if not def then + minetest.log("error", "[mcl_wip] Unknown item: "..name) + break + end + local new_description = def.description + if new_description == "" then + new_description = name + end + new_description = new_description .. "\n"..minetest.colorize(mcl_colors.RED, S("(WIP)")) + minetest.override_item(name, {description = new_description}) + end + + for _,name in pairs(mcl_wip.registered_experimental_items) do + local def = minetest.registered_items[name] + if not def then + minetest.log("error", "[mcl_wip] Unknown item: "..name) + break + end + local new_description = def.description + if new_description == "" then + new_description = name + end + new_description = new_description .. "\n"..minetest.colorize(mcl_colors.YELLOW, S("(Temporary)")) + minetest.override_item(name, {description = new_description}) + end +end) diff --git a/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr b/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr new file mode 100644 index 000000000..7c3b3d14d --- /dev/null +++ b/mods/MISC/mcl_wip/locale/mcl_wip.ja.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_wip +# WIP means “Work in Progress” +(WIP)=(制作途中) +(Temporary)=(仮) diff --git a/mods/MISC/mcl_wip/locale/mcl_wip.pl.tr b/mods/MISC/mcl_wip/locale/mcl_wip.pl.tr new file mode 100644 index 000000000..83c273a96 --- /dev/null +++ b/mods/MISC/mcl_wip/locale/mcl_wip.pl.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_wip +# WIP means “Work in Progress” +(WIP)=(Niedokończone) +(Temporary)=(Tymczasowe) diff --git a/mods/MISC/mcl_wip/locale/mcl_wip.zh_TW.tr b/mods/MISC/mcl_wip/locale/mcl_wip.zh_TW.tr new file mode 100644 index 000000000..e4b36ff07 --- /dev/null +++ b/mods/MISC/mcl_wip/locale/mcl_wip.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_wip +# WIP means “Work in Progress” +(WIP)=(WIP) +(Temporary)=(暫時) diff --git a/mods/MISC/mcl_wip/mod.conf b/mods/MISC/mcl_wip/mod.conf index 2af1d4592..e705379a1 100644 --- a/mods/MISC/mcl_wip/mod.conf +++ b/mods/MISC/mcl_wip/mod.conf @@ -1 +1,4 @@ name = mcl_wip +author = Wuzzy +description = Development mod for MineClone 2 which add a “WIP” (Work In Progress) comment to items which are considered to be very unfinished. +depends = mcl_colors diff --git a/mods/PLAYER/mcl_criticals/init.lua b/mods/PLAYER/mcl_criticals/init.lua new file mode 100644 index 000000000..27d09abb2 --- /dev/null +++ b/mods/PLAYER/mcl_criticals/init.lua @@ -0,0 +1,30 @@ +mcl_damage.register_modifier(function(obj, damage, reason) + if reason.type == "player" then + local hitter = reason.direct + if mcl_sprint.is_sprinting(hitter) then + obj:add_velocity(hitter:get_velocity()) + elseif (hitter:get_velocity() or hitter:get_player_velocity()).y < 0 then + local pos = mcl_util.get_object_center(obj) + minetest.add_particlespawner({ + amount = 15, + time = 0.1, + minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, + maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, + minvel = {x=-0.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + 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)) + end + end +end, -100) diff --git a/mods/PLAYER/mcl_criticals/mod.conf b/mods/PLAYER/mcl_criticals/mod.conf new file mode 100644 index 000000000..5b0b91330 --- /dev/null +++ b/mods/PLAYER/mcl_criticals/mod.conf @@ -0,0 +1,2 @@ +name = mcl_criticals +depends = mcl_damage diff --git a/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg new file mode 100644 index 000000000..8184d1076 Binary files /dev/null and b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg differ diff --git a/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.1.ogg b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.1.ogg new file mode 100644 index 000000000..aed998162 Binary files /dev/null and b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.1.ogg differ diff --git a/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg new file mode 100644 index 000000000..6d573b9f2 Binary files /dev/null and b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg differ diff --git a/mods/PLAYER/mcl_death_drop/API.md b/mods/PLAYER/mcl_death_drop/API.md new file mode 100644 index 000000000..3fc5163e5 --- /dev/null +++ b/mods/PLAYER/mcl_death_drop/API.md @@ -0,0 +1,14 @@ +# mcl_death_drop +Drop registered inventories on player death. + +## mcl_death_drop.register_dropped_list(inv, listname, drop) +* inv: can be: + * "PLAYER": will be interpreted like player inventory (to avoid multiple calling to get_inventory()) + * function(player): must return inventory +* listname: string +* drop: bool + * true: the list will be dropped + * false: the list will only be cleared + +## mcl_death_drop.registered_dropped_lists +Table containing dropped list inventory, name and drop state. \ No newline at end of file diff --git a/mods/PLAYER/mcl_death_drop/depends.txt b/mods/PLAYER/mcl_death_drop/depends.txt deleted file mode 100644 index 4c2d1c21f..000000000 --- a/mods/PLAYER/mcl_death_drop/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_armor -mcl_enchanting diff --git a/mods/PLAYER/mcl_death_drop/description.txt b/mods/PLAYER/mcl_death_drop/description.txt deleted file mode 100644 index 761832f6e..000000000 --- a/mods/PLAYER/mcl_death_drop/description.txt +++ /dev/null @@ -1 +0,0 @@ -Makes all items in inventory drop after player death. diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 56e6ea522..9b1bad75f 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -1,42 +1,56 @@ -minetest.register_on_dieplayer(function(player) - local keep = minetest.settings:get_bool("mcl_keepInventory", false) - if keep == false then - -- Drop inventory, crafting grid and armor - local inv = player:get_inventory() - local pos = player:get_pos() - local name, player_armor_inv, armor_armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]") - -- No item drop if in deep void - local void, void_deadly = mcl_worlds.is_in_void(pos) - local lists = { - { inv = inv, listname = "main", drop = true }, - { inv = inv, listname = "craft", drop = true }, - { inv = player_armor_inv, listname = "armor", drop = true }, - { inv = armor_armor_inv, listname = "armor", drop = false }, - } - for l=1,#lists do - local inv = lists[l].inv - local listname = lists[l].listname - local drop = lists[l].drop - if inv ~= nil then - for i, stack in ipairs(inv:get_list(listname)) do - local x = math.random(0, 9)/3 - local z = math.random(0, 9)/3 - pos.x = pos.x + x - pos.z = pos.z + z - if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then - local def = minetest.registered_items[stack:get_name()] - if def and def.on_drop then - stack = def.on_drop(stack, player, pos) - end - minetest.add_item(pos, stack) - end - pos.x = pos.x - x - pos.z = pos.z - z - end - inv:set_list(listname, {}) - end - end - armor:set_player_armor(player) - armor:update_inventory(player) - end -end) +local random = math.random + +local ipairs = ipairs + +mcl_death_drop = {} + +mcl_death_drop.registered_dropped_lists = {} + +function mcl_death_drop.register_dropped_list(inv, listname, drop) + table.insert(mcl_death_drop.registered_dropped_lists, {inv = inv, listname = listname, drop = drop}) +end + +mcl_death_drop.register_dropped_list("PLAYER", "main", true) +mcl_death_drop.register_dropped_list("PLAYER", "craft", true) +mcl_death_drop.register_dropped_list("PLAYER", "armor", true) +mcl_death_drop.register_dropped_list("PLAYER", "offhand", true) + +minetest.register_on_dieplayer(function(player) + local keep = minetest.settings:get_bool("mcl_keepInventory", false) + if keep == false then + -- Drop inventory, crafting grid and armor + local playerinv = player:get_inventory() + local pos = player:get_pos() + -- No item drop if in deep void + local _, void_deadly = mcl_worlds.is_in_void(pos) + + for l=1,#mcl_death_drop.registered_dropped_lists do + local inv = mcl_death_drop.registered_dropped_lists[l].inv + if inv == "PLAYER" then + inv = playerinv + elseif type(inv) == "function" then + inv = inv(player) + end + local listname = mcl_death_drop.registered_dropped_lists[l].listname + local drop = mcl_death_drop.registered_dropped_lists[l].drop + local dropspots = minetest.find_nodes_in_area(vector.offset(pos,-3,0,-3),vector.offset(pos,3,0,3),{"air"}) + if #dropspots == 0 then + table.insert(dropspots,pos) + end + if inv then + for i, stack in ipairs(inv:get_list(listname)) do + local p = vector.offset(dropspots[math.random(#dropspots)],math.random()-0.5,math.random()-0.5,math.random()-0.5) + if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then + local def = minetest.registered_items[stack:get_name()] + if def and def.on_drop then + stack = def.on_drop(stack, player, p) + end + minetest.add_item(p, stack) + end + end + inv:set_list(listname, {}) + end + end + mcl_armor.update(player) + end +end) diff --git a/mods/PLAYER/mcl_death_drop/mod.conf b/mods/PLAYER/mcl_death_drop/mod.conf index 93ed70ad4..09a8c61fa 100644 --- a/mods/PLAYER/mcl_death_drop/mod.conf +++ b/mods/PLAYER/mcl_death_drop/mod.conf @@ -1 +1,4 @@ name = mcl_death_drop +author = Wuzzy +description = Makes all items in inventory drop after player death. +depends = mcl_armor, mcl_enchanting diff --git a/mods/PLAYER/mcl_hunger/api.lua b/mods/PLAYER/mcl_hunger/api.lua index 55153b9bf..3c9cd97e9 100644 --- a/mods/PLAYER/mcl_hunger/api.lua +++ b/mods/PLAYER/mcl_hunger/api.lua @@ -67,7 +67,7 @@ if mcl_hunger.active then local satuchanged = false local s = mcl_hunger.get_saturation(player) if s > 0 then - mcl_hunger.set_saturation(player, math.max(s - 1.0, 0)) + mcl_hunger.set_saturation(player, math.max(s - 1.5, 0)) satuchanged = true elseif s <= 0.0001 then h = mcl_hunger.get_hunger(player) @@ -76,7 +76,7 @@ if mcl_hunger.active then satuchanged = true end if satuchanged then - if h ~= nil then h = h end + if h then h = h end mcl_hunger.update_saturation_hud(player, mcl_hunger.get_saturation(player), h) end end @@ -86,7 +86,8 @@ if mcl_hunger.active then function mcl_hunger.saturate(playername, increase, update_hudbar) local player = minetest.get_player_by_name(playername) - local ok = mcl_hunger.set_saturation(player, math.min(mcl_hunger.get_saturation(player) + increase, mcl_hunger.get_hunger(player))) + local ok = mcl_hunger.set_saturation(player, + math.min(mcl_hunger.get_saturation(player) + increase, mcl_hunger.get_hunger(player))) if update_hudbar ~= false then mcl_hunger.update_saturation_hud(player, mcl_hunger.get_saturation(player), mcl_hunger.get_hunger(player)) end @@ -105,7 +106,7 @@ if mcl_hunger.active then -- otherwise the following poison/exhaust fields are ignored food[name].poison = poison -- poison damage per tick for poisonous food food[name].exhaust = exhaust -- exhaustion per tick for poisonous food - food[name].poisonchance = poisonchance -- chance percentage that this item poisons the player (default: 100% if poisoning is enabled) + food[name].poisonchance = poisonchance -- chance percentage that this item poisons the player (default: 100%) food[name].sound = sound -- special sound that is played when eating end diff --git a/mods/PLAYER/mcl_hunger/depends.txt b/mods/PLAYER/mcl_hunger/depends.txt deleted file mode 100644 index ed8cc4236..000000000 --- a/mods/PLAYER/mcl_hunger/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -hudbars -mcl_death_messages? diff --git a/mods/PLAYER/mcl_hunger/description.txt b/mods/PLAYER/mcl_hunger/description.txt deleted file mode 100644 index 77e6159d5..000000000 --- a/mods/PLAYER/mcl_hunger/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds a simple hunger meachanic with satiation, food poisoning and different healing. diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index 393bdc9a9..d9a6fd5fe 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -1,10 +1,7 @@ -local S = minetest.get_translator("mcl_hunger") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") +--local S = minetest.get_translator(minetest.get_current_modname()) -- wrapper for minetest.item_eat (this way we make sure other mods can't break this one) -local org_eat = minetest.do_item_eat -minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing) - +function minetest.do_item_eat(hp_change, replace_with_item, itemstack, user, pointed_thing) if not user or user:is_player() == false then return itemstack end @@ -38,7 +35,8 @@ minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, p -- FIXME: In singleplayer, there's a cheat to circumvent this, simply by pausing the game between eats. -- This is because os.time() obviously does not care about the pause. A fix needs a different timer mechanism. if no_eat_delay or (mcl_hunger.last_eat[name] < 0) or (os.difftime(os.time(), mcl_hunger.last_eat[name]) >= 2) then - local can_eat_when_full = creative or (mcl_hunger.active == false) or minetest.get_item_group(itemstack:get_name(), "can_eat_when_full") == 1 + 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 itemstack = mcl_hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_thing) @@ -67,7 +65,8 @@ function mcl_hunger.eat(hp_change, replace_with_item, itemstack, user, pointed_t def.saturation = hp_change def.replace = replace_with_item end - local func = mcl_hunger.item_eat(def.saturation, def.replace, def.poisontime, def.poison, def.exhaust, def.poisonchance, def.sound) + local func = mcl_hunger.item_eat(def.saturation, def.replace, def.poisontime, + def.poison, def.exhaust, def.poisonchance, def.sound) return func(itemstack, user, pointed_thing) end @@ -90,7 +89,6 @@ local function poisonp(tick, time, time_left, damage, exhaustion, name) if not player then return end - local name = player:get_player_name() -- Abort if food poisonings have been stopped if mcl_hunger.poison_hunger[name] == 0 then return @@ -110,10 +108,7 @@ local function poisonp(tick, time, time_left, damage, exhaustion, name) -- Deal damage and exhaust player -- TODO: Introduce fatal poison at higher difficulties if player:get_hp()-damage > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 succumbed to the poison.", name)) - end - player:set_hp(player:get_hp()-damage) + mcl_util.deal_damage(player, damage, {type = "hunger"}) end mcl_hunger.exhaust(name, exhaustion) @@ -126,12 +121,12 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso return function(itemstack, user, pointed_thing) local itemname = itemstack:get_name() local creative = minetest.is_creative_enabled(user:get_player_name()) - if itemstack:peek_item() ~= nil and user ~= nil then + if itemstack:peek_item() and user then if not creative then itemstack:take_item() end local name = user:get_player_name() - local hp = user:get_hp() + --local hp = user:get_hp() local pos = user:get_pos() -- player height @@ -157,26 +152,18 @@ function mcl_hunger.item_eat(hunger_change, replace_with_item, poisontime, poiso -- 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() - local minvel = vector.add(v, {x=-1, y=1, z=-1}) - local maxvel = vector.add(v, {x=1, y=2, z=1}) - - minetest.add_particlespawner({ - amount = math.min(math.max(8, hunger_change*2), 25), - time = 0.1, - minpos = {x=pos.x, y=pos.y, z=pos.z}, - maxpos = {x=pos.x, y=pos.y, z=pos.z}, - minvel = minvel, - maxvel = maxvel, - minacc = {x=0, y=-5, z=0}, - maxacc = {x=0, y=-9, z=0}, - minexptime = 1, - maxexptime = 1, - minsize = 1, - maxsize = 2, - collisiondetection = true, - vertical = false, - texture = texture, - }) + 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, diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 01d74a80d..321139c5f 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -1,5 +1,7 @@ -local S = minetest.get_translator("mcl_hunger") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local S = minetest.get_translator(modname) mcl_hunger = {} @@ -9,10 +11,9 @@ Hunger is enabled when damage is enabled. If the damage setting is changed within the game, this does NOT update the hunger mechanic, so the game must be restarted for this to take effect. ]] -if minetest.settings:get_bool("enable_damage") == true then +mcl_hunger.active = false +if minetest.settings:get_bool("enable_damage") == true and minetest.settings:get_bool("mcl_enable_hunger") ~= false then mcl_hunger.active = true -else - mcl_hunger.active = false end mcl_hunger.HUD_TICK = 0.1 @@ -26,6 +27,7 @@ mcl_hunger.EXHAUST_SWIM = 10 -- player movement in water mcl_hunger.EXHAUST_SPRINT = 100 -- sprint (per node) mcl_hunger.EXHAUST_DAMAGE = 100 -- taking damage (protected by armor) 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.SATURATION_INIT = 5 -- Initial saturation for new/respawning players @@ -37,9 +39,9 @@ mcl_hunger.debug = false -- Cooldown timers for each player, to force a short delay between consuming 2 food items mcl_hunger.last_eat = {} -dofile(minetest.get_modpath("mcl_hunger").."/api.lua") -dofile(minetest.get_modpath("mcl_hunger").."/hunger.lua") -dofile(minetest.get_modpath("mcl_hunger").."/register_foods.lua") +dofile(modpath.."/api.lua") +dofile(modpath.."/hunger.lua") +dofile(modpath.."/register_foods.lua") --[[ IF HUNGER IS ENABLED ]] if mcl_hunger.active == true then @@ -65,9 +67,7 @@ end -- Count number of poisonings a player has at once mcl_hunger.poison_hunger = {} -- food poisoning, increasing hunger --- HUD item ids -local hunger_hud = {} - +-- HUD local function init_hud(player) hb.init_hudbar(player, "hunger", mcl_hunger.get_hunger(player)) if mcl_hunger.debug then @@ -84,15 +84,18 @@ function mcl_hunger.update_saturation_hud(player, saturation, hunger) end function mcl_hunger.update_exhaustion_hud(player, exhaustion) if mcl_hunger.debug then + if not exhaustion then + exhaustion = mcl_hunger.get_exhaustion(player) + end hb.change_hudbar(player, "exhaustion", exhaustion) end end -- register saturation hudbar -hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 20, 20, false) +hb.register_hudbar("hunger", 0xFFFFFF, S("Food"), { icon = "hbhunger_icon.png", bgicon = "hbhunger_bgicon.png", bar = "hbhunger_bar.png" }, 1, 20, 20, false) if mcl_hunger.debug then - hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, mcl_hunger.SATURATION_INIT, 200, false, S("%s: %.1f/%d")) - hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 0, mcl_hunger.EXHAUST_LVL, false, S("%s: %d/%d")) + hb.register_hudbar("saturation", 0xFFFFFF, S("Saturation"), { icon = "mcl_hunger_icon_saturation.png", bgicon = "mcl_hunger_bgicon_saturation.png", bar = "mcl_hunger_bar_saturation.png" }, 1, mcl_hunger.SATURATION_INIT, 200, false) + hb.register_hudbar("exhaustion", 0xFFFFFF, S("Exhaust."), { icon = "mcl_hunger_icon_exhaustion.png", bgicon = "mcl_hunger_bgicon_exhaustion.png", bar = "mcl_hunger_bar_exhaustion.png" }, 1, 0, mcl_hunger.EXHAUST_LVL, false) end minetest.register_on_joinplayer(function(player) @@ -134,50 +137,52 @@ minetest.register_on_player_hpchange(function(player, hp_change) end end) -local main_timer = 0 -local timer = 0 -- Half second timer -local timerMult = 1 -- Cycles from 0 to 7, each time when timer hits half a second +local food_tick_timers = {} -- one food_tick_timer per player, keys are the player-objects minetest.register_globalstep(function(dtime) - main_timer = main_timer + dtime - timer = timer + dtime - if main_timer > mcl_hunger.HUD_TICK or timer > 0.5 then - if main_timer > mcl_hunger.HUD_TICK then main_timer = 0 end - for _,player in ipairs(minetest.get_connected_players()) do - local name = player:get_player_name() + for _,player in pairs(minetest.get_connected_players()) do - local h = tonumber(mcl_hunger.get_hunger(player)) - local hp = player:get_hp() - if timer > 0.5 then - -- Slow health regeneration, and hunger damage (every 4s). - -- Regeneration rate based on tutorial video . - -- Minecraft Wiki seems to be wrong in claiming that full hunger gives 0.5s regen rate. - if timerMult == 0 then - if h >= 18 and hp > 0 and hp < 20 then - -- +1 HP, +exhaustion - player:set_hp(hp+1) - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_REGEN) - mcl_hunger.update_exhaustion_hud(player, mcl_hunger.get_exhaustion(player)) - elseif h == 0 then - -- Damage hungry player down to 1 HP - -- TODO: Allow starvation at higher difficulty levels - if hp-1 > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 starved to death.", name)) - end - player:set_hp(hp-1) - end + local food_tick_timer = food_tick_timers[player] and food_tick_timers[player] + dtime or 0 + local player_name = player:get_player_name() + local food_level = mcl_hunger.get_hunger(player) + local food_saturation_level = mcl_hunger.get_saturation(player) + local player_health = player:get_hp() + + if food_tick_timer > 4.0 then + food_tick_timer = 0 + + -- let hunger work always + if player_health > 0 and player_health <= 20 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 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player) + end + + elseif food_level == 0 then -- starvation + -- the amount of health at which a player will stop to get + -- harmed by starvation (10 for Easy, 1 for Normal, 0 for Hard) + local maximum_starvation = 1 + -- TODO: implement Minecraft-like difficulty modes and the update maximumStarvation here + if player_health > maximum_starvation then + mcl_util.deal_damage(player, 1, {type = "starve"}) 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 + food_tick_timer = 0 + player:set_hp(player_health+1) + mcl_hunger.exhaust(player_name, mcl_hunger.EXHAUST_REGEN) + mcl_hunger.update_exhaustion_hud(player) + end end - end - end - if timer > 0.5 then - timer = 0 - timerMult = timerMult + 1 - if timerMult > 7 then - timerMult = 0 - end + + food_tick_timers[player] = food_tick_timer -- update food_tick_timer table end end) diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.fr.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.fr.tr index 811868b3a..04f809c58 100644 --- a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.fr.tr +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.fr.tr @@ -2,7 +2,7 @@ @1 succumbed to the poison.=@1 a succombé au poison. Food=Nourriture Saturation=Saturation -%s: %.1f/%d=%s: %.1f/%d +%s: %.1f/%d=%s : %.1f/%d Exhaust.=Échappement. -%s: %d/%d=%s: %d/%d +%s: %d/%d=%s : %d/%d @1 starved to death.=@1 est mort de faim. diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr new file mode 100644 index 000000000..8e5fe234a --- /dev/null +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.ja.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_hunger +@1 succumbed to the poison.=@1 は毒にやられました。 +Food=食料 +Saturation=満腹状態 +%s: %.1f/%d= +Exhaust.=尽きた。 +%s: %d/%d= +@1 starved to death.=@1 は餓死しました。 diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pl.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pl.tr new file mode 100644 index 000000000..be20c6d85 --- /dev/null +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.pl.tr @@ -0,0 +1,9 @@ +# textdomain: mcl_hunger +@1 succumbed to the poison.=@1 uległa truciźnie. +Food=Jedzenie +Saturation=Nasycenie +%s: %.1f/%d=%s: %.1f/%d +Exhaust.=Wyczerpanie. +%s: %d/%d=%s: %d/%d +@1 starved to death.=@1 umarła z wygłodzenia. + diff --git a/mods/PLAYER/mcl_hunger/locale/mcl_hunger.zh_TW.tr b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.zh_TW.tr new file mode 100644 index 000000000..18d265ef4 --- /dev/null +++ b/mods/PLAYER/mcl_hunger/locale/mcl_hunger.zh_TW.tr @@ -0,0 +1,8 @@ +# textdomain: mcl_hunger +@1 succumbed to the poison.= +Food=食物 +Saturation=飽食度 +%s: %.1f/%d= +Exhaust.=飢餓值 +%s: %d/%d= +@1 starved to death.=@1 餓死了。 diff --git a/mods/PLAYER/mcl_hunger/mod.conf b/mods/PLAYER/mcl_hunger/mod.conf index a1a3d1cc2..99ab71ff3 100644 --- a/mods/PLAYER/mcl_hunger/mod.conf +++ b/mods/PLAYER/mcl_hunger/mod.conf @@ -1 +1,4 @@ name = mcl_hunger +author = BlockMen +description = Adds a simple hunger meachanic with satiation, food poisoning and different healing. +depends = hudbars diff --git a/mods/PLAYER/mcl_hunger/screenshot.png b/mods/PLAYER/mcl_hunger/screenshot.png deleted file mode 100644 index 5af658366..000000000 Binary files a/mods/PLAYER/mcl_hunger/screenshot.png and /dev/null differ diff --git a/mods/PLAYER/mcl_hunger/textures/hbhunger_bgicon.png b/mods/PLAYER/mcl_hunger/textures/hbhunger_bgicon.png deleted file mode 100644 index e02778a27..000000000 Binary files a/mods/PLAYER/mcl_hunger/textures/hbhunger_bgicon.png and /dev/null differ diff --git a/mods/PLAYER/mcl_hunger/textures/hbhunger_icon.png b/mods/PLAYER/mcl_hunger/textures/hbhunger_icon.png deleted file mode 100644 index 9c1bb63e4..000000000 Binary files a/mods/PLAYER/mcl_hunger/textures/hbhunger_icon.png and /dev/null differ diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_foodpoison.png b/mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_foodpoison.png deleted file mode 100644 index 141b4b44d..000000000 Binary files a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_foodpoison.png and /dev/null differ diff --git a/mods/PLAYER/mcl_meshhand/depends.txt b/mods/PLAYER/mcl_meshhand/depends.txt deleted file mode 100644 index c86b5f93b..000000000 --- a/mods/PLAYER/mcl_meshhand/depends.txt +++ /dev/null @@ -1,2 +0,0 @@ -mcl_tools -mcl_skins? diff --git a/mods/PLAYER/mcl_meshhand/description.txt b/mods/PLAYER/mcl_meshhand/description.txt deleted file mode 100644 index 7a4daae59..000000000 --- a/mods/PLAYER/mcl_meshhand/description.txt +++ /dev/null @@ -1 +0,0 @@ -Applies the player skin texture to the hand. diff --git a/mods/PLAYER/mcl_meshhand/init.lua b/mods/PLAYER/mcl_meshhand/init.lua index 14bf10090..a28efd502 100644 --- a/mods/PLAYER/mcl_meshhand/init.lua +++ b/mods/PLAYER/mcl_meshhand/init.lua @@ -1,49 +1,102 @@ -local has_mcl_skins = minetest.get_modpath("mcl_skins") ~= nil +local mcl_skins_enabled = minetest.global_exists("mcl_skins") +mcl_meshhand = { } -local def = minetest.registered_items[""] +---This is a fake node that should never be placed in the world +---@type node_definition +local node_def = { + use_texture_alpha = "opaque", + paramtype = "light", + drawtype = "mesh", + node_placement_prediction = "", + on_construct = function(pos) + local name = minetest.get_node(pos).name + local message = "[mcl_meshhand] Trying to construct " .. name .. " at " .. minetest.pos_to_string(pos) + minetest.log("error", message) + minetest.remove_node(pos) + end, + drop = "", + on_drop = function(_, _, _) return ItemStack() end, + groups = { + dig_immediate = 3, + not_in_creative_inventory = 1, + dig_speed_class = 1, + }, + tool_capabilities = { + full_punch_interval = 0.25, + max_drop_level = 0, + groupcaps = { }, + damage_groups = { fleshy = 1 }, + }, + _mcl_diggroups = { + handy = { speed = 1, level = 1, uses = 0 }, + axey = { speed = 1, level = 1, uses = 0 }, + shovely = { speed = 1, level = 1, uses = 0 }, + hoey = { speed = 1, level = 1, uses = 0 }, + pickaxey = { speed = 1, level = 0, uses = 0 }, + swordy = { speed = 1, level = 0, uses = 0 }, + swordy_cobweb = { speed = 1, level = 0, uses = 0 }, + shearsy = { speed = 1, level = 0, uses = 0 }, + shearsy_wool = { speed = 1, level = 0, uses = 0 }, + shearsy_cobweb = { speed = 1, level = 0, uses = 0 }, + }, + range = tonumber(minetest.settings:get("mcl_hand_range")) or 4.5 +} -local list --- mcl_skins is enabled -if has_mcl_skins == true then - list = mcl_skins.list +-- This is for _mcl_autogroup to know about the survival hand tool capabilites +mcl_meshhand.survival_hand_tool_caps = node_def.tool_capabilities + +local creative_dig_speed = tonumber(minetest.settings:get("mcl_creative_dig_speed")) or 0.2 +local creative_hand_range = tonumber(minetest.settings:get("mcl_hand_range_creative")) or 10 +if mcl_skins_enabled then + -- Generate a node for every skin + local list = mcl_skins.get_skin_list() + for _, skin in pairs(list) do + local node_def = table.copy(node_def) + node_def._mcl_hand_id = skin.id + node_def.tiles = { skin.texture } + node_def.mesh = skin.slim_arms and "mcl_meshhand_female.b3d" or "mcl_meshhand.b3d" + if skin.creative then + node_def.range = creative_hand_range + node_def.groups.dig_speed_class = 7 + node_def.tool_capabilities.groupcaps.creative_breakable = { times = { creative_dig_speed }, uses = 0 } + end + minetest.register_node("mcl_meshhand:" .. skin.id, node_def) + end else - list = { "hand" } + node_def._mcl_hand_id = "hand" + node_def.mesh = "mcl_meshhand.b3d" + node_def.tiles = { "character.png" } + minetest.register_node("mcl_meshhand:hand_surv", node_def) + + node_def = table.copy(node_def) + node_def.range = creative_hand_range + node_def.groups.dig_speed_class = 7 + node_def.tool_capabilities.groupcaps.creative_breakable = { times = { creative_dig_speed }, uses = 0 } + minetest.register_node("mcl_meshhand:hand_crea", node_def) end ---generate a node for every skin -for _,texture in pairs(list) do - -- This is a fake node that should never be placed in the world - minetest.register_node("mcl_meshhand:"..texture, { - description = "", - tiles = {texture..".png"}, - visual_scale = 1, - wield_scale = {x=1,y=1,z=1}, - paramtype = "light", - drawtype = "mesh", - mesh = "mcl_meshhand.b3d", - -- Prevent construction - node_placement_prediction = "", - on_construct = function(pos) - minetest.log("error", "[mcl_meshhand] Trying to construct mcl_meshhand:"..texture.." at "..minetest.pos_to_string(pos)) - minetest.remove_node(pos) - end, - drop = "", - on_drop = function() - return "" - end, - groups = { dig_immediate = 3, not_in_creative_inventory = 1 }, - range = def.range, - }) +function mcl_meshhand.update_player(player) + 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) + 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")) + end end -if has_mcl_skins == true then - --change the player's hand to their skin - mcl_skins.register_on_set_skin(function(player, skin) - local name = player:get_player_name() - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:"..skin) - end) +if mcl_skins_enabled then + mcl_player.register_on_visual_change(mcl_meshhand.update_player) else - minetest.register_on_joinplayer(function(player) - player:get_inventory():set_stack("hand", 1, "mcl_meshhand:hand") - end) + 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("", { + tool_capabilities = mcl_meshhand.survival_hand_tool_caps +}) diff --git a/mods/PLAYER/mcl_meshhand/mod.conf b/mods/PLAYER/mcl_meshhand/mod.conf index 6b57f4a49..687932514 100644 --- a/mods/PLAYER/mcl_meshhand/mod.conf +++ b/mods/PLAYER/mcl_meshhand/mod.conf @@ -1 +1,5 @@ name = mcl_meshhand +author = jordan4ibanez +description = Applies the player skin texture to the hand. +depends = mcl_tools, mcl_player +optional_depends = mcl_skins, mcl_custom_skins diff --git a/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d new file mode 100644 index 000000000..b2ec6efcf Binary files /dev/null and b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.b3d differ diff --git a/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend new file mode 100644 index 000000000..be642496f Binary files /dev/null and b/mods/PLAYER/mcl_meshhand/models/mcl_meshhand_female.blend differ diff --git a/mods/PLAYER/mcl_music/init.lua b/mods/PLAYER/mcl_music/init.lua new file mode 100644 index 000000000..7f8be5acf --- /dev/null +++ b/mods/PLAYER/mcl_music/init.lua @@ -0,0 +1,222 @@ +local S = minetest.get_translator(minetest.get_current_modname()) + +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) + +local music_enabled = minetest.settings:get_bool("mcl_game_music", true) + +local pianowtune = "diminixed-pianowtune02" +local end_tune = "diminixed-ambientwip02" +local never_grow_up = "diminixed-nevergrowup04" +local nether_tune = "horizonchris96-traitor" +local odd_block = "Jester-0dd-BL0ck" +local flock_of_one = "Jester-Flock-of-One" +local gift = "Jester-Gift" +local hailing_forest = "Jester-Hailing_Forest" +local lonely_blossom = "exhale_and_tim_unwin-lonely_blossom" +local valley_of_ghosts = "exhale_and_tim_unwin-valley_of_ghosts" +local farmer = "exhale_and_tim_unwin-farmer" + +local dimension_to_base_track = { + ["overworld"] = {pianowtune, never_grow_up, flock_of_one, gift, hailing_forest, lonely_blossom, farmer}, + ["nether"] = {nether_tune, valley_of_ghosts}, + ["end"] = {end_tune}, + ["mining"] = {odd_block}, +} + +local listeners = {} + +local function pick_track(dimension, underground) + local track_key + + if dimension == "overworld" and underground then + track_key = "mining" + else + -- Pick random dimension song + track_key = dimension + end + + local dimension_tracks = dimension_to_base_track[track_key] + + if dimension_tracks and #dimension_tracks >= 1 then + local index = 1 + if #dimension_tracks > 1 then + index = math.random(1, #dimension_tracks) + end + local chosen_track = dimension_tracks[index] + --minetest.log("chosen_track: " .. chosen_track) + minetest.log("action", "[mcl_music] Playing track: " .. chosen_track .. ", for context: " .. track_key) + return chosen_track + else + -- ? + end + + return nil +end + + +local function stop_music_for_listener_name(listener_name) + if not listener_name then return end + local listener = listeners[listener_name] + if not listener then return end + local handle = listener.handle + if not handle then return end + + minetest.log("action", "[mcl_music] Stopping music") + minetest.sound_stop(handle) + listeners[listener_name].handle = nil +end + +local function stop_music_for_all() + for _, player in pairs(minetest.get_connected_players()) do + local player_name = player:get_player_name() + stop_music_for_listener_name(player_name) + end +end + +local function play_song(track, player_name, dimension, day_count) + local spec = { + name = track, + gain = 0.3, + pitch = 1.0, + } + local parameters = { + to_player = player_name, + gain = 1.0, + fade = 0.0, + pitch = 1.0, + } + local handle = minetest.sound_play(spec, parameters, false) + listeners[player_name] = { + handle = handle, + dimension = dimension, + day_count = day_count, + } +end + +local function play() + local time = minetest.get_timeofday() + if time < 0.25 or time >= 0.75 then + stop_music_for_all() + minetest.after(10, play) + return + end + + local day_count = minetest.get_day_count() + for _, player in pairs(minetest.get_connected_players()) do + if not player:get_meta():get("mcl_music:disable") then + local player_name = player:get_player_name() + local hp = player:get_hp() + local pos = player:get_pos() + local dimension = mcl_worlds.pos_to_dimension(pos) + + local listener = listeners[player_name] + local handle = listener and listener.handle + + --local old_hp = listener and listener.hp + --local is_hp_changed = old_hp and (math.abs(old_hp - hp) > 0.00001) or false + + local old_dimension = listener and listener.dimension + local is_dimension_changed = old_dimension and (old_dimension ~= dimension) or false + + -- minetest.log("handle: " .. dump (handle)) + if is_dimension_changed then + stop_music_for_listener_name(player_name) + if not listeners[player_name] then + listeners[player_name] = {} + end + listeners[player_name].hp = hp + listeners[player_name].dimension = dimension + elseif not handle and (not listener or (listener.day_count ~= day_count)) then + local underground = dimension == "overworld" and pos and pos.y < 0 + local track = pick_track(dimension, underground) + if track then + play_song(track, player_name, dimension, day_count) + else + --minetest.log("no track found. weird") + end + else + --minetest.log("else") + end + end + end + + minetest.after(7, play) +end + +if music_enabled then + minetest.log("action", "[mcl_music] In-game music is activated") + minetest.after(15, play) + + minetest.register_on_joinplayer(function(player, last_login) + local player_name = player:get_player_name() + stop_music_for_listener_name(player_name) + end) + + minetest.register_on_leaveplayer(function(player, timed_out) + listeners[player:get_player_name()] = nil + end) + + minetest.register_on_respawnplayer(function(player) + local player_name = player:get_player_name() + stop_music_for_listener_name(player_name) + end) +else + minetest.log("action", "[mcl_music] In-game music is deactivated") +end + +minetest.register_chatcommand("music", { + params = "[on|off|invert []]", + description = S("Turns music for yourself or another player on or off."), + func = function(sender_name, params) + local argtable = {} + for str in string.gmatch(params, "([^%s]+)") do + table.insert(argtable, str) + end + + local action = argtable[1] + local playername = argtable[2] + + local sender = minetest.get_player_by_name(sender_name) + local target_player = nil + + if not action or action == "" then action = "invert" end + + if not playername or playername == "" or sender_name == playername then + target_player = sender + playername =sender_name + elseif not minetest.check_player_privs(sender, "debug") then -- Self-use handled above + minetest.chat_send_player(sender_name, S("You need the debug privilege in order to turn ingame music on or off for somebody else!")) + return + else -- Admin + target_player = minetest.get_player_by_name(playername) + end + + if not target_player then + minetest.chat_send_player(sender_name, S("Couldn't find player @1!", playername)) + return + end + + local meta = target_player:get_meta() + local display_new_state = "unknown" -- Should never be displayed -> no translation + + if action == "invert" then + if not meta:get("mcl_music:disable") then + meta:set_int("mcl_music:disable", 1) + display_new_state = S("off") + else + meta:set_string("mcl_music:disable", "") -- This deletes the meta value! + display_new_state = S("on") + end + elseif action == "on" then + meta:set_string("mcl_music:disable", "") -- Delete + display_new_state = S("on") + else + meta:set_int("mcl_music:disable", 1) + display_new_state = S("off") + end + + stop_music_for_listener_name(playername) + minetest.chat_send_player(sender_name, S("Set music for @1 to: @2", playername, display_new_state)) + end, +}) \ No newline at end of file diff --git a/mods/PLAYER/mcl_music/locale/mcl_music.de.tr b/mods/PLAYER/mcl_music/locale/mcl_music.de.tr new file mode 100644 index 000000000..83621545f --- /dev/null +++ b/mods/PLAYER/mcl_music/locale/mcl_music.de.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!=Sie benötigen das „debug“ Privileg, um die Musik (im Spiel) für jemand anders ein oder aus zu schalten! +Couldn't find player @1!= Spieler @1 konnte nicht gefunden werden! +Set music for @1 to: @2=Musik für @1 auf @2 gesetzt +Turns music for yourself or another player on or off.=Schaltet die Musik für Sie selbst oder jemand anders ein oder aus. +on=an +off=aus \ No newline at end of file diff --git a/mods/PLAYER/mcl_music/locale/template.txt b/mods/PLAYER/mcl_music/locale/template.txt new file mode 100644 index 000000000..66d60e9f5 --- /dev/null +++ b/mods/PLAYER/mcl_music/locale/template.txt @@ -0,0 +1,7 @@ +# textdomain: mcl_music +You need the debug privilege in order to turn ingame music on or off for somebody else!= +Couldn't find player @1!= +Set music for @1 to: @2= +Turns music for yourself or another player on or off.= +on= +off= \ No newline at end of file diff --git a/mods/PLAYER/mcl_music/mod.conf b/mods/PLAYER/mcl_music/mod.conf new file mode 100644 index 000000000..74493b42d --- /dev/null +++ b/mods/PLAYER/mcl_music/mod.conf @@ -0,0 +1,4 @@ +name = mcl_music +author = diminixed, horizonchris96, kay27 +description = Mod check some conditions and plays music +depends = mcl_player, mcl_weather, mcl_worlds diff --git a/mods/PLAYER/mcl_music/sounds/Jester-0dd-BL0ck.ogg b/mods/PLAYER/mcl_music/sounds/Jester-0dd-BL0ck.ogg new file mode 100644 index 000000000..9e4c25fec Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/Jester-0dd-BL0ck.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/Jester-Flock-of-One.ogg b/mods/PLAYER/mcl_music/sounds/Jester-Flock-of-One.ogg new file mode 100644 index 000000000..5835fbfd4 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/Jester-Flock-of-One.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/Jester-Gift.ogg b/mods/PLAYER/mcl_music/sounds/Jester-Gift.ogg new file mode 100644 index 000000000..69b9ec675 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/Jester-Gift.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/Jester-Hailing_Forest.ogg b/mods/PLAYER/mcl_music/sounds/Jester-Hailing_Forest.ogg new file mode 100644 index 000000000..70fcab2f9 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/Jester-Hailing_Forest.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/diminixed-ambientwip02.ogg b/mods/PLAYER/mcl_music/sounds/diminixed-ambientwip02.ogg new file mode 100644 index 000000000..d484d92d2 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/diminixed-ambientwip02.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/diminixed-nevergrowup04.ogg b/mods/PLAYER/mcl_music/sounds/diminixed-nevergrowup04.ogg new file mode 100644 index 000000000..c6f2ccabd Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/diminixed-nevergrowup04.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/diminixed-pianowtune02.ogg b/mods/PLAYER/mcl_music/sounds/diminixed-pianowtune02.ogg new file mode 100644 index 000000000..cc9492e70 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/diminixed-pianowtune02.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-farmer.ogg b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-farmer.ogg new file mode 100644 index 000000000..d919a5bf3 Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-farmer.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-lonely_blossom.ogg b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-lonely_blossom.ogg new file mode 100644 index 000000000..53c32178a Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-lonely_blossom.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-valley_of_ghosts.ogg b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-valley_of_ghosts.ogg new file mode 100644 index 000000000..7430a516e Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/exhale_and_tim_unwin-valley_of_ghosts.ogg differ diff --git a/mods/PLAYER/mcl_music/sounds/horizonchris96-traitor.ogg b/mods/PLAYER/mcl_music/sounds/horizonchris96-traitor.ogg new file mode 100644 index 000000000..c7eb103bc Binary files /dev/null and b/mods/PLAYER/mcl_music/sounds/horizonchris96-traitor.ogg differ diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index f58c58fe0..084fe48a1 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -1,3 +1,5 @@ +local sf = string.format + -- Minetest 0.4 mod: player -- See README.txt for licensing and other information. mcl_player = {} @@ -6,6 +8,17 @@ mcl_player = {} -- Note: This is currently broken due to a bug in Irrlicht, leave at 0 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 + return true + else + return false + end +end + mcl_player.registered_player_models = { } -- Local for speed. @@ -15,41 +28,60 @@ function mcl_player.player_register_model(name, def) models[name] = def end --- Default player appearance -mcl_player.player_register_model("character.b3d", { - animation_speed = 30, - textures = {"character.png", }, - animations = { - -- Standard animations. - stand = {x= 0, y= 79}, - lay = {x=162, y=166}, - walk = {x=168, y=187}, - mine = {x=189, y=198}, - walk_mine = {x=200, y=219}, - sit = {x= 81, y=160}, - sneak_stand = {x=222, y=302}, - sneak_mine = {x=346, y=366}, - sneak_walk = {x=304, y=323}, - sneak_walk_mine = {x=325, y=344}, - }, -}) - -- Player stats and animations local player_model = {} local player_textures = {} local player_anim = {} local player_sneak = {} +local player_visible = {} mcl_player.player_attached = {} function mcl_player.player_get_animation(player) local name = player:get_player_name() + local textures = player_textures[name] + + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" + end + return { model = player_model[name], - textures = player_textures[name], + textures = textures, animation = player_anim[name], + visibility = player_visibility[name] } end +local registered_on_visual_change = {} + +function mcl_player.register_on_visual_change(func) + table.insert(registered_on_visual_change, func) +end + +local function update_player_textures(player) + local name = player:get_player_name() + local textures = player_textures[name] + + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" + end + + player:set_properties({ textures = textures }) + + -- Delay calling the callbacks because mods (including mcl_player) + -- need to fully initialize player data from minetest.register_on_joinplayer + -- before callbacks run + minetest.after(0.1, function() + if player:is_player() then + for i, func in ipairs(registered_on_visual_change) do + func(player) + end + end + end) +end + -- Called when a player's appearance needs to be updated function mcl_player.player_set_model(player, model_name) local name = player:get_player_name() @@ -58,39 +90,60 @@ function mcl_player.player_set_model(player, model_name) if player_model[name] == model_name then return end + player_model[name] = model_name player:set_properties({ mesh = model_name, - textures = player_textures[name] or model.textures, visual = "mesh", visual_size = model.visual_size or {x=1, y=1}, damage_texture_modifier = "^[colorize:red:130", }) - mcl_player.player_set_animation(player, "stand") + update_player_textures(player) + + local new_anim = "stand" + local model_animations = models[model_name].animations + local old_anim = player_anim[name] + if model_animations and old_anim and model_animations[old_anim] then + new_anim = old_anim + end + mcl_player.player_set_animation(player, new_anim) else player:set_properties({ textures = { "player.png", "player_back.png", }, visual = "upright_sprite", }) end - player_model[name] = model_name end -function mcl_player.player_set_textures(player, textures, preview) +function mcl_player.player_set_visibility(player, visible) local name = player:get_player_name() - player_textures[name] = textures - player:set_properties({textures = textures,}) - if preview then - player:get_meta():set_string("mcl_player:preview", preview) - end + if player_visible[name] == visible then return end + player_visible[name] = visible + update_player_textures(player) end -function mcl_player.player_get_preview(player) - local preview = player:get_meta():get_string("mcl_player:preview") - if preview == nil or preview == "" then - return "player.png" - else - return preview +function mcl_player.player_set_skin(player, texture) + local name = player:get_player_name() + player_textures[name][1] = texture + update_player_textures(player) +end + +function mcl_player.player_set_armor(player, texture) + local name = player:get_player_name() + player_textures[name][2] = texture + update_player_textures(player) +end + +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] + if not player_visible[name] then + textures = table.copy(textures) + textures[1] = "blank.png" end + return sf("model[%s,%s;%s,%s;%s;%s;%s;0,180;false;false;%s,%s]", x, y, w, h, fsname, model, + table.concat(textures, ","), anim.x, anim.y) end function mcl_player.player_set_animation(player, anim_name, speed) @@ -109,8 +162,10 @@ end -- Update appearance when the player joins minetest.register_on_joinplayer(function(player) - mcl_player.player_attached[player:get_player_name()] = false - mcl_player.player_set_model(player, "character.b3d") + 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"} --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 >>> end) @@ -120,6 +175,8 @@ minetest.register_on_leaveplayer(function(player) player_model[name] = nil player_anim[name] = nil player_textures[name] = nil + player_sneak[name] = nil + player_visible[name] = nil end) -- Localize for better performance. @@ -147,39 +204,64 @@ minetest.register_globalstep(function(dtime) animation_speed_mod = animation_speed_mod / 2 end + if mcl_shields.is_blocking(player) then + animation_speed_mod = animation_speed_mod / 2 + end + -- ask if player is swiming - local standing_on_water = minetest.get_item_group(mcl_playerinfo[name].node_stand, "water") ~= 0 + local head_in_water = minetest.get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 + -- ask if player is sprinting + local is_sprinting = mcl_sprint.is_sprinting(name) + + local velocity = player:get_velocity() or player:get_player_velocity() -- Apply animations based on what the player is doing if player:get_hp() == 0 then - player_set_animation(player, "lay") - elseif walking then + player_set_animation(player, "die") + 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 + 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) if player_sneak[name] ~= controls.sneak then player_anim[name] = nil player_sneak[name] = controls.sneak end - if controls.LMB and not controls.sneak and standing_on_water then + if get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk_mine", animation_speed_mod) - elseif not controls.sneak and standing_on_water then + elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_walk", animation_speed_mod) - elseif controls.LMB and not controls.sneak and not standing_on_water 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) + elseif is_sprinting == true and get_mouse_button(player) == true and not controls.sneak and not head_in_water then + player_set_animation(player, "run_walk_mine", animation_speed_mod) + elseif get_mouse_button(player) == true and not controls.sneak then player_set_animation(player, "walk_mine", animation_speed_mod) - elseif controls.LMB and controls.sneak and not standing_on_water then + elseif get_mouse_button(player) == true and controls.sneak and is_sprinting ~= true then player_set_animation(player, "sneak_walk_mine", animation_speed_mod) - elseif not controls.sneak and not standing_on_water then - player_set_animation(player, "walk", animation_speed_mod) - else + elseif is_sprinting == true and not controls.sneak and not head_in_water then + player_set_animation(player, "run_walk", animation_speed_mod) + elseif controls.sneak and not get_mouse_button(player) == true then player_set_animation(player, "sneak_walk", animation_speed_mod) + else + player_set_animation(player, "walk", animation_speed_mod) end - elseif controls.LMB and not controls.sneak and standing_on_water then + elseif get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_mine") - elseif controls.LMB and not controls.sneak and not standing_on_water then + elseif not get_mouse_button(player) == true and not controls.sneak and head_in_water and is_sprinting == true then + player_set_animation(player, "swim_stand") + elseif get_mouse_button(player) == true and not controls.sneak then player_set_animation(player, "mine") - elseif controls.LMB and controls.sneak then + elseif get_mouse_button(player) == true and controls.sneak then player_set_animation(player, "sneak_mine") - elseif not controls.sneak and standing_on_water then + elseif not controls.sneak and head_in_water and is_sprinting == true then player_set_animation(player, "swim_stand", animation_speed_mod) - elseif not controls.sneak and not standing_on_water then + elseif not controls.sneak then player_set_animation(player, "stand", animation_speed_mod) else player_set_animation(player, "sneak_stand", animation_speed_mod) @@ -187,37 +269,3 @@ minetest.register_globalstep(function(dtime) end end end) - --- Don't change HP if the player falls in the water or through End Portal: -minetest.register_on_player_hpchange(function(player, hp_change, reason) - if reason and reason.type == "fall" and player then - local pos = player:get_pos() - local node = minetest.get_node(pos) - local velocity = player:get_velocity() or player:get_player_velocity() or {x=0,y=-10,z=0} - local v_axis_max = math.max(math.abs(velocity.x), math.abs(velocity.y), math.abs(velocity.z)) - local step = {x = velocity.x / v_axis_max, y = velocity.y / v_axis_max, z = velocity.z / v_axis_max} - for i = 1, math.ceil(v_axis_max/5)+1 do -- trace at least 1/5 of the way per second - if not node or node.name == "ignore" then - minetest.get_voxel_manip():read_from_map(pos, pos) - node = minetest.get_node(pos) - end - if node then - if minetest.registered_nodes[node.name].walkable then - return hp_change - end - if minetest.get_item_group(node.name, "water") ~= 0 then - return 0 - end - if node.name == "mcl_portals:portal_end" then - if mcl_portals and mcl_portals.end_teleport then - mcl_portals.end_teleport(player) - end - return 0 - end - end - pos = vector.add(pos, step) - node = minetest.get_node(pos) - end - end - return hp_change -end, true) diff --git a/mods/PLAYER/mcl_player/mod.conf b/mods/PLAYER/mcl_player/mod.conf new file mode 100644 index 000000000..7cc5d14fa --- /dev/null +++ b/mods/PLAYER/mcl_player/mod.conf @@ -0,0 +1,4 @@ +name = mcl_player +author = celeron55 +description = Adds the 3D player model, taken from Minetest Game 0.4.16. +depends = mcl_shields \ No newline at end of file diff --git a/mods/PLAYER/mcl_player/models/character.b3d b/mods/PLAYER/mcl_player/models/character.b3d deleted file mode 100644 index f5482f4c7..000000000 Binary files a/mods/PLAYER/mcl_player/models/character.b3d and /dev/null differ diff --git a/mods/PLAYER/mcl_player/models/character.blend b/mods/PLAYER/mcl_player/models/character.blend deleted file mode 100644 index f77f49f40..000000000 Binary files a/mods/PLAYER/mcl_player/models/character.blend and /dev/null differ diff --git a/mods/PLAYER/mcl_player/models/character.png b/mods/PLAYER/mcl_player/models/character.png deleted file mode 100644 index 8bf839e71..000000000 Binary files a/mods/PLAYER/mcl_player/models/character.png and /dev/null differ diff --git a/mods/PLAYER/mcl_player/textures/player.png b/mods/PLAYER/mcl_player/textures/player.png deleted file mode 100644 index 007727519..000000000 Binary files a/mods/PLAYER/mcl_player/textures/player.png and /dev/null differ diff --git a/mods/PLAYER/mcl_player/textures/player_back.png b/mods/PLAYER/mcl_player/textures/player_back.png deleted file mode 100644 index 4bd5366fa..000000000 Binary files a/mods/PLAYER/mcl_player/textures/player_back.png and /dev/null differ diff --git a/mods/PLAYER/mcl_player_init/init.lua b/mods/PLAYER/mcl_player_init/init.lua deleted file mode 100644 index 52967a441..000000000 --- a/mods/PLAYER/mcl_player_init/init.lua +++ /dev/null @@ -1,4 +0,0 @@ -minetest.register_on_joinplayer(function(player) - -- Settable hand - player:get_inventory():set_size("hand", 1) -end) diff --git a/mods/PLAYER/mcl_player_init/mod.conf b/mods/PLAYER/mcl_player_init/mod.conf deleted file mode 100644 index 8d559910c..000000000 --- a/mods/PLAYER/mcl_player_init/mod.conf +++ /dev/null @@ -1,2 +0,0 @@ -name = mcl_player_init -description = Initialize player gameplay stuff that are neither model nor HUD-related diff --git a/mods/PLAYER/mcl_playerinfo/depends.txt b/mods/PLAYER/mcl_playerinfo/depends.txt deleted file mode 100644 index d0334ff54..000000000 --- a/mods/PLAYER/mcl_playerinfo/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_init -mcl_core -mcl_particles -mcl_death_messages diff --git a/mods/PLAYER/mcl_playerinfo/init.lua b/mods/PLAYER/mcl_playerinfo/init.lua index 31dad39a6..1f1b84749 100644 --- a/mods/PLAYER/mcl_playerinfo/init.lua +++ b/mods/PLAYER/mcl_playerinfo/init.lua @@ -1,91 +1,98 @@ --- Player state for public API -mcl_playerinfo = {} - --- Get node but use fallback for nil or unknown -local function node_ok(pos, fallback) - - fallback = fallback or "air" - - local node = minetest.get_node_or_nil(pos) - - if not node then - return fallback - end - - if minetest.registered_nodes[node.name] then - return node.name - end - - return fallback -end - -local time = 0 - -local get_player_nodes = function(player_pos) - local work_pos = table.copy(player_pos) - - -- what is around me? - work_pos.y = work_pos.y - 0.1 -- standing on - local node_stand = node_ok(work_pos) - local node_stand_below = node_ok({x=work_pos.x, y=work_pos.y-1, z=work_pos.z}) - - work_pos.y = work_pos.y + 1.5 -- head level - local node_head = node_ok(work_pos) - - work_pos.y = work_pos.y - 1.2 -- feet level - local node_feet = node_ok(work_pos) - - return node_stand, node_stand_below, node_head, node_feet -end - -minetest.register_globalstep(function(dtime) - - time = time + dtime - - -- Run the rest of the code every 0.5 seconds - if time < 0.5 then - return - end - - -- reset time for next check - -- FIXME: Make sure a regular check interval applies - time = 0 - - -- check players - for _,player in pairs(minetest.get_connected_players()) do - -- who am I? - local name = player:get_player_name() - - -- where am I? - local pos = player:get_pos() - - -- what is around me? - local node_stand, node_stand_below, node_head, node_feet = get_player_nodes(pos) - mcl_playerinfo[name].node_stand = node_stand - mcl_playerinfo[name].node_stand_below = node_stand_below - mcl_playerinfo[name].node_head = node_head - mcl_playerinfo[name].node_feet = node_feet - - end - -end) - --- set to blank on join (for 3rd party mods) -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - - mcl_playerinfo[name] = { - node_head = "", - node_feet = "", - node_stand = "", - node_stand_below = "", - } - -end) - --- clear when player leaves -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - - mcl_playerinfo[name] = nil -end) +local table = table + +-- Player state for public API +mcl_playerinfo = {} + +-- Get node but use fallback for nil or unknown +local function node_ok(pos, fallback) + + fallback = fallback or "air" + + local node = minetest.get_node_or_nil(pos) + + if not node then + return fallback + end + + if minetest.registered_nodes[node.name] then + return node.name + end + + return fallback +end + +local time = 0 + +local function get_player_nodes(player_pos) + local work_pos = table.copy(player_pos) + + -- what is around me? + work_pos.y = work_pos.y - 0.1 -- standing on + local node_stand = node_ok(work_pos) + local node_stand_below = node_ok({x=work_pos.x, y=work_pos.y-1, z=work_pos.z}) + + work_pos.y = work_pos.y + 1.5 -- head level + local node_head = node_ok(work_pos) + work_pos.y = work_pos.y + 0.5 -- top of head level, at collision box height + local node_head_top = node_ok(work_pos) + work_pos.y = work_pos.y - 0.5 + + work_pos.y = work_pos.y - 1.2 -- feet level + local node_feet = node_ok(work_pos) + + return node_stand, node_stand_below, node_head, node_feet, node_head_top +end + +minetest.register_globalstep(function(dtime) + + time = time + dtime + + -- Run the rest of the code every 0.5 seconds + if time < 0.5 then + return + end + + -- reset time for next check + -- FIXME: Make sure a regular check interval applies + time = 0 + + -- check players + for _,player in pairs(minetest.get_connected_players()) do + -- who am I? + local name = player:get_player_name() + + -- where am I? + local pos = player:get_pos() + + -- what is around me? + local node_stand, node_stand_below, node_head, node_feet, node_head_top = get_player_nodes(pos) + mcl_playerinfo[name].node_stand = node_stand + mcl_playerinfo[name].node_stand_below = node_stand_below + mcl_playerinfo[name].node_head = node_head + mcl_playerinfo[name].node_feet = node_feet + mcl_playerinfo[name].node_head_top = node_head_top + + end + +end) + +-- set to blank on join (for 3rd party mods) +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + + mcl_playerinfo[name] = { + node_head = "", + node_feet = "", + node_stand = "", + node_stand_below = "", + node_head_top = "", + } + +end) + +-- clear when player leaves +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + + mcl_playerinfo[name] = nil +end) diff --git a/mods/PLAYER/mcl_playerinfo/mod.conf b/mods/PLAYER/mcl_playerinfo/mod.conf index ee2b80e7e..25c05f03e 100644 --- a/mods/PLAYER/mcl_playerinfo/mod.conf +++ b/mods/PLAYER/mcl_playerinfo/mod.conf @@ -1 +1,4 @@ name = mcl_playerinfo +author = TenPlus1 +description = This is a helper mod for other mod to query the nodes around the player. +depends = mcl_init, mcl_core, mcl_particles diff --git a/mods/PLAYER/mcl_playerplus/depends.txt b/mods/PLAYER/mcl_playerplus/depends.txt deleted file mode 100644 index 7a259f8c1..000000000 --- a/mods/PLAYER/mcl_playerplus/depends.txt +++ /dev/null @@ -1,10 +0,0 @@ -mcl_init -mcl_core -mcl_particles -mcl_hunger -mcl_death_messages -playerphysics -mcl_playerinfo -mcl_weather -mcl_spawn -mcl_enchanting diff --git a/mods/PLAYER/mcl_playerplus/description.txt b/mods/PLAYER/mcl_playerplus/description.txt deleted file mode 100644 index 4664d5f8c..000000000 --- a/mods/PLAYER/mcl_playerplus/description.txt +++ /dev/null @@ -1 +0,0 @@ -Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 62f91fb15..69cb00d07 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -1,294 +1,747 @@ -local S = minetest.get_translator("mcl_playerplus") - --- Internal player state -local mcl_playerplus_internal = {} - -local def = {} -local time = 0 - --- converts yaw to degrees -local function degrees(rad) - return rad * 180.0 / math.pi -end - -local pitch, name, node_stand, node_stand_below, node_head, node_feet, pos - -minetest.register_globalstep(function(dtime) - - time = time + dtime - - -- Update jump status immediately since we need this info in real time. - -- WARNING: This section is HACKY as hell since it is all just based on heuristics. - for _,player in pairs(minetest.get_connected_players()) do - local controls = player:get_player_control() - name = player:get_player_name() - - -- controls head bone - pitch = degrees(player:get_look_vertical()) * -1 - - if controls.LMB then - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch,0,0)) - else - player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(0,0,0)) - end - - if controls.sneak and player:get_attach() == nil then - -- controls head pitch when sneaking - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+36,0,0)) - -- sets collisionbox, eye height, and nametag color accordingly - if player:get_properties().collisionbox ~= {-0.35,0,-0.35,0.35,1.35,0.35} then - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.35,0.35}, eye_height = 1.35, nametag_color = { r = 255, b = 225, a = 0, g = 225 }}) - end - elseif minetest.get_item_group(mcl_playerinfo[name].node_stand, "water") ~= 0 then - -- controls head pitch when swiming - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch+90,0,0)) - -- sets collisionbox, eye height, and nametag color accordingly - if player:get_properties().collisionbox ~= {-0.35,0.2,-0.35,0.35,1.8,0.35} then - player:set_properties({collisionbox = {-0.35,0.2,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 255, b = 225, a = 225, g = 225 }}) - end - else - -- controls head pitch when not sneaking - player:set_bone_position("Head", vector.new(0,6.3,0), vector.new(pitch,0,0)) - -- sets collisionbox, eye height, and nametag color accordingly - if player:get_properties().collisionbox ~= {-0.35,0,-0.35,0.35,1.8,0.35} then - player:set_properties({collisionbox = {-0.35,0,-0.35,0.35,1.8,0.35}, eye_height = 1.65, nametag_color = { r = 255, b = 225, a = 225, g = 225 }}) - end - end - - if mcl_playerplus_internal[name].jump_cooldown > 0 then - mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime - end - if player:get_player_control().jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then - - pos = player:get_pos() - - node_stand = mcl_playerinfo[name].node_stand - node_stand_below = mcl_playerinfo[name].node_stand_below - node_head = mcl_playerinfo[name].node_head - node_feet = mcl_playerinfo[name].node_feet - if not node_stand or not node_stand_below or not node_head or not node_feet then - return - end - if not minetest.registered_nodes[node_stand] or not minetest.registered_nodes[node_stand_below] or not minetest.registered_nodes[node_head] or not minetest.registered_nodes[node_feet] then - return - end - - -- Cause buggy exhaustion for jumping - - --[[ Checklist we check to know the player *actually* jumped: - * Not on or in liquid - * Not on or at climbable - * On walkable - * Not on disable_jump - FIXME: This code is pretty hacky and it is possible to miss some jumps or detect false - jumps because of delays, rounding errors, etc. - What this code *really* needs is some kind of jumping “callback” which this engine lacks - as of 0.4.15. - ]] - - if minetest.get_item_group(node_feet, "liquid") == 0 and - minetest.get_item_group(node_stand, "liquid") == 0 and - not minetest.registered_nodes[node_feet].climbable and - not minetest.registered_nodes[node_stand].climbable and - (minetest.registered_nodes[node_stand].walkable or minetest.registered_nodes[node_stand_below].walkable) - and minetest.get_item_group(node_stand, "disable_jump") == 0 - and minetest.get_item_group(node_stand_below, "disable_jump") == 0 then - -- Cause exhaustion for jumping - if mcl_sprint.is_sprinting(name) then - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP) - else - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_JUMP) - end - - -- Reset cooldown timer - mcl_playerplus_internal[name].jump_cooldown = 0.45 - end - end - end - - -- Run the rest of the code every 0.5 seconds - if time < 0.5 then - return - end - - -- reset time for next check - -- FIXME: Make sure a regular check interval applies - time = 0 - - -- check players - for _,player in pairs(minetest.get_connected_players()) do - -- who am I? - local name = player:get_player_name() - - -- where am I? - local pos = player:get_pos() - - -- what is around me? - local node_stand = mcl_playerinfo[name].node_stand - local node_stand_below = mcl_playerinfo[name].node_stand_below - local node_head = mcl_playerinfo[name].node_head - local node_feet = mcl_playerinfo[name].node_feet - if not node_stand or not node_stand_below or not node_head or not node_feet then - return - end - - -- set defaults - def.speed = 1 - - -- Standing on soul sand? If so, walk slower (unless player wears Soul Speed boots) - if node_stand == "mcl_nether:soul_sand" then - -- TODO: Tweak walk speed - -- TODO: Also slow down mobs - -- Slow down even more when soul sand is above certain block - local boots = player:get_inventory():get_stack("armor", 5) - local soul_speed = mcl_enchanting.get_enchantment(boots, "soul_speed") - if soul_speed > 0 then - playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", soul_speed * 0.105 + 1.3) - else - if node_stand_below == "mcl_core:ice" or node_stand_below == "mcl_core:packed_ice" or node_stand_below == "mcl_core:slimeblock" or node_stand_below == "mcl_core:water_source" then - playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", 0.1) - else - playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", 0.4) - end - end - else - -- Reset speed decrease - playerphysics.remove_physics_factor(player, "speed", "mcl_playerplus:surface") - end - - -- Is player suffocating inside node? (Only for solid full opaque cube type nodes - -- without group disable_suffocation=1) - local ndef = minetest.registered_nodes[node_head] - - if (ndef.walkable == nil or ndef.walkable == true) - and (ndef.collision_box == nil or ndef.collision_box.type == "regular") - and (ndef.node_box == nil or ndef.node_box.type == "regular") - and (ndef.groups.disable_suffocation ~= 1) - and (ndef.groups.opaque == 1) - and (node_head ~= "ignore") - -- Check privilege, too - and (not minetest.check_player_privs(name, {noclip = true})) then - if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name)) - player:set_hp(player:get_hp() - 1) - end - end - - -- Am I near a cactus? - local near = minetest.find_node_near(pos, 1, "mcl_core:cactus") - if not near then - near = minetest.find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus") - end - if near then - -- Am I touching the cactus? If so, it hurts - local dist = vector.distance(pos, near) - local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near) - if dist < 1.1 or dist_feet < 1.1 then - if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name)) - player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" }) - end - end - end - - --[[ Swimming: Cause exhaustion. - NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid! - Head alone does not count. We respect that for now. ]] - if minetest.get_item_group(node_feet, "liquid") ~= 0 or - minetest.get_item_group(node_stand, "liquid") ~= 0 then - local lastPos = mcl_playerplus_internal[name].lastPos - if lastPos then - local dist = vector.distance(lastPos, pos) - mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance + dist - if mcl_playerplus_internal[name].swimDistance >= 1 then - local superficial = math.floor(mcl_playerplus_internal[name].swimDistance) - mcl_hunger.exhaust(name, mcl_hunger.EXHAUST_SWIM * superficial) - mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance - superficial - end - end - - end - - -- Underwater: Spawn bubble particles - if minetest.get_item_group(node_head, "water") ~= 0 then - - minetest.add_particlespawner({ - amount = 10, - time = 0.15, - minpos = { x = -0.25, y = 0.3, z = -0.25 }, - maxpos = { x = 0.25, y = 0.7, z = 0.75 }, - attached = player, - minvel = {x = -0.2, y = 0, z = -0.2}, - maxvel = {x = 0.5, y = 0, z = 0.5}, - minacc = {x = -0.4, y = 4, z = -0.4}, - maxacc = {x = 0.5, y = 1, z = 0.5}, - minexptime = 0.3, - maxexptime = 0.8, - minsize = 0.7, - maxsize = 2.4, - texture = "mcl_particles_bubble.png" - }) - end - - -- Show positions of barriers when player is wielding a barrier - local wi = player:get_wielded_item():get_name() - if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" then - local pos = vector.round(player:get_pos()) - local r = 8 - local vm = minetest.get_voxel_manip() - local emin, emax = vm:read_from_map({x=pos.x-r, y=pos.y-r, z=pos.z-r}, {x=pos.x+r, y=pos.y+r, z=pos.z+r}) - local area = VoxelArea:new{ - MinEdge = emin, - MaxEdge = emax, - } - local data = vm:get_data() - for x=pos.x-r, pos.x+r do - for y=pos.y-r, pos.y+r do - for z=pos.z-r, pos.z+r do - local vi = area:indexp({x=x, y=y, z=z}) - local nodename = minetest.get_name_from_content_id(data[vi]) - local tex - if nodename == "mcl_core:barrier" then - tex = "mcl_core_barrier.png" - elseif nodename == "mcl_core:realm_barrier" then - tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX" - end - if tex then - minetest.add_particle({ - pos = {x=x, y=y, z=z}, - expirationtime = 1, - size = 8, - texture = tex, - glow = 14, - playername = name - }) - end - end - end - end - end - - -- Update internal values - mcl_playerplus_internal[name].lastPos = pos - - end - -end) - --- set to blank on join (for 3rd party mods) -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - - 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 - } -end) - --- clear when player leaves -minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - - mcl_playerplus_internal[name] = nil -end) +mcl_playerplus = { + elytra = {}, + is_pressing_jump = {}, +} + +local get_connected_players = minetest.get_connected_players +local dir_to_yaw = minetest.dir_to_yaw +local get_item_group = minetest.get_item_group +local check_player_privs = minetest.check_player_privs +local find_node_near = minetest.find_node_near +local get_name_from_content_id = minetest.get_name_from_content_id +local get_voxel_manip = minetest.get_voxel_manip +local add_particle = minetest.add_particle +local add_particlespawner = minetest.add_particlespawner + +local is_sprinting = mcl_sprint.is_sprinting +local exhaust = mcl_hunger.exhaust +local playerphysics = playerphysics + +local vector = vector +local math = math +-- Internal player state +local mcl_playerplus_internal = {} + +-- Could occassionally hit about 4.6 but servers and high power machines struggle to keep up with this. +-- Until mapgen can keep up, it's best to limit for server performance etc. +local elytra_vars = { + slowdown_mult = 0.0, -- amount of vel to take per sec + fall_speed = 0.2, -- amount of vel to fall down per sec + speedup_mult = 2, -- amount of speed to add based on look dir + max_speed = tonumber(minetest.settings:get("mcl_elytra_max_speed")) or 4.0, -- was 6 max amount to multiply against look direction when flying + pitch_penalty = 1.3, -- if pitching up, slow down at this rate as a multiplier + rocket_speed = tonumber(minetest.settings:get("mcl_elytra_rocket_speed")) or 3.5, --was 5.5 +} + +--minetest.log("action", "elytra_vars.max_speed: " .. dump(elytra_vars.max_speed)) +--minetest.log("action", "elytra_vars.rocket_speed: " .. dump(elytra_vars.rocket_speed)) + +local time = 0 +local look_pitch = 0 + +local function player_collision(player) + + local pos = player:get_pos() + --local vel = player:get_velocity() + local x = 0 + local z = 0 + local width = .75 + + for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do + + local ent = object:get_luaentity() + if (object:is_player() or (ent and ent.is_mob and object ~= player)) then + + local pos2 = object:get_pos() + local vec = {x = pos.x - pos2.x, z = pos.z - pos2.z} + local force = (width + 0.5) - vector.distance( + {x = pos.x, y = 0, z = pos.z}, + {x = pos2.x, y = 0, z = pos2.z}) + + x = x + (vec.x * force) + z = z + (vec.z * force) + end + end + return {x,z} +end + +local function walking_player(player, control) + if control.up or control.down or control.left or control.right then + return true + else + return false + end +end + + +-- converts yaw to degrees +local function degrees(rad) + return rad * 180.0 / math.pi +end + +local function dir_to_pitch(dir) + --local dir2 = vector.normalize(dir) + local xz = math.abs(dir.x) + math.abs(dir.z) + return -math.atan2(-dir.y, xz) +end + +local player_vel_yaws = {} + +function limit_vel_yaw(player_vel_yaw, yaw) + if player_vel_yaw < 0 then + player_vel_yaw = player_vel_yaw + 360 + end + + if yaw < 0 then + yaw = yaw + 360 + end + + if math.abs(player_vel_yaw - yaw) > 40 then + local player_vel_yaw_nm, yaw_nm = player_vel_yaw, yaw + if player_vel_yaw > yaw then + player_vel_yaw_nm = player_vel_yaw - 360 + else + yaw_nm = yaw - 360 + end + if math.abs(player_vel_yaw_nm - yaw_nm) > 40 then + local diff = math.abs(player_vel_yaw - yaw) + if diff > 180 and diff < 185 or diff < 180 and diff > 175 then + player_vel_yaw = yaw + elseif diff < 180 then + if player_vel_yaw < yaw then + player_vel_yaw = yaw - 40 + else + player_vel_yaw = yaw + 40 + end + else + if player_vel_yaw < yaw then + player_vel_yaw = yaw + 40 + else + player_vel_yaw = yaw - 40 + end + end + end + end + + if player_vel_yaw < 0 then + player_vel_yaw = player_vel_yaw + 360 + elseif player_vel_yaw > 360 then + player_vel_yaw = player_vel_yaw - 360 + end + + return player_vel_yaw +end + +local node_stand, node_stand_below, node_head, node_feet, node_head_top +local is_swimming + +local set_bone_pos = mcl_util.set_bone_position +local set_properties = mcl_util.set_properties + +local function get_overall_velocity(vector) + local v = math.sqrt(vector.x^2 + vector.y^2 + vector.z^2) + return v +end +local function anglediff(a1, a2) + local a = a1 - a2 + return math.abs((a + math.pi) % (math.pi*2) - math.pi) +end +local function clamp(num, min, max) + return math.min(max, math.max(num, min)) +end + + + +local player_props_elytra = { + collisionbox = { -0.35, 0, -0.35, 0.35, 0.8, 0.35 }, + eye_height = 0.5, + 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, + 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, + 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, + 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, + nametag_color = { r = 225, b = 225, a = 225, g = 225 } +} + +minetest.register_globalstep(function(dtime) + + time = time + dtime + + for _,player in pairs(get_connected_players()) do + + --[[ + + _ _ _ + __ _ _ __ (_)_ __ ___ __ _| |_(_) ___ _ __ ___ + / _` | '_ \| | '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| + | (_| | | | | | | | | | | (_| | |_| | (_) | | | \__ \ + \__,_|_| |_|_|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/ + + ]]-- + + local control = player:get_player_control() + local name = player:get_player_name() + --local meta = player:get_meta() + local parent = player:get_attach() + local wielded = player:get_wielded_item() + local player_velocity = player:get_velocity() or player:get_player_velocity() + local wielded_def = wielded:get_definition() + + local c_x, c_y = unpack(player_collision(player)) + + if player_velocity.x + player_velocity.y < .5 and c_x + c_y > 0 then + player:add_velocity({x = c_x, y = 0, z = c_y}) + player_velocity = player:get_velocity() or player:get_player_velocity() + end + + -- control head bone + local pitch = - degrees(player:get_look_vertical()) + local yaw = degrees(player:get_look_horizontal()) + + local player_vel_yaw = degrees(dir_to_yaw(player_velocity)) + if player_vel_yaw == 0 then + player_vel_yaw = player_vel_yaws[name] or yaw + end + player_vel_yaw = limit_vel_yaw(player_vel_yaw, yaw) + player_vel_yaws[name] = player_vel_yaw + + local fly_pos = player:get_pos() + local fly_node = minetest.get_node({x = fly_pos.x, y = fly_pos.y - 0.1, z = fly_pos.z}).name + local elytra = mcl_playerplus.elytra[player] + + if not elytra.active then + elytra.speed = 0 + end + + if not elytra.last_yaw then + elytra.last_yaw = player:get_look_horizontal() + end + + local is_just_jumped = control.jump and not mcl_playerplus.is_pressing_jump[name] and not elytra.active + mcl_playerplus.is_pressing_jump[name] = control.jump + if is_just_jumped and not elytra.active then + local direction = player:get_look_dir() + elytra.speed = 1 - (direction.y/2 + 0.5) + end + + local fly_node_walkable = minetest.registered_nodes[fly_node] and minetest.registered_nodes[fly_node].walkable + elytra.active = minetest.get_item_group(player:get_inventory():get_stack("armor", 3):get_name(), "elytra") ~= 0 + and not parent + and (elytra.active or (is_just_jumped and player_velocity.y < -0)) + and ((not fly_node_walkable) or fly_node == "ignore") + + if elytra.active then + if is_just_jumped then -- move the player up when they start flying to give some clearance + player:set_pos(vector.offset(player:get_pos(), 0, 0.8, 0)) + end + mcl_player.player_set_animation(player, "fly") + local direction = player:get_look_dir() + local player_vel = player:get_velocity() + local turn_amount = anglediff(minetest.dir_to_yaw(direction), minetest.dir_to_yaw(player_vel)) + local direction_mult = clamp(-(direction.y+0.1), -1, 1) + if direction_mult < 0 then direction_mult = direction_mult * elytra_vars.pitch_penalty end + + local speed_mult = elytra.speed + local block_below = minetest.get_node(vector.offset(fly_pos, 0, -0.9, 0)).name + local reg_node_below = minetest.registered_nodes[block_below] + if (reg_node_below and not reg_node_below.walkable) and (player_vel.y ~= 0) then + speed_mult = speed_mult + direction_mult * elytra_vars.speedup_mult * dtime + end + speed_mult = speed_mult - elytra_vars.slowdown_mult * clamp(dtime, 0.09, 0.2) -- slow down but don't overdo it + speed_mult = clamp(speed_mult, -elytra_vars.max_speed, elytra_vars.max_speed) + if turn_amount > 0.3 and math.abs(direction.y) < 0.98 then -- don't do this if looking straight up / down + speed_mult = speed_mult - (speed_mult * (turn_amount / (math.pi*8))) + end + + playerphysics.add_physics_factor(player, "gravity", "mcl_playerplus:elytra", elytra_vars.fall_speed) + if elytra.rocketing > 0 then + elytra.rocketing = elytra.rocketing - dtime + if vector.length(player_velocity) < 40 then + -- player:add_velocity(vector.multiply(player:get_look_dir(), 4)) + speed_mult = elytra_vars.rocket_speed + + if mcl_util.check_dtime_timer(name, dtime, "ely_rocket_particle_spawn", 0.3) then + add_particle({ + pos = fly_pos, + velocity = vector.zero(), + acceleration = vector.zero(), + expirationtime = math.random(0.3, 0.5), + size = math.random(1, 2), + collisiondetection = false, + vertical = false, + texture = "mcl_particles_bonemeal.png^[colorize:#bc7a57:127", + glow = 5, + }) + end + end + end + + elytra.speed = speed_mult -- set the speed so you can keep track of it and add to it + + local new_vel = vector.multiply(direction, speed_mult * dtime * 30) -- use the look dir and speed as a mult + -- new_vel.y = new_vel.y - elytra_vars.fall_speed * dtime -- make the player fall a set amount + + -- slow the player down so less spongy movement by applying some of the inverse velocity + -- NOTE: do not set this higher than about 0.2 or the game will get the wrong vel and it will be broken + -- this is far from ideal, but there's no good way to set_velocity or slow down the player + player_vel = vector.multiply(player_vel, -0.1) + -- if speed_mult < 1 then player_vel.y = player_vel.y * 0.1 end + new_vel = vector.add(new_vel, player_vel) + + player:add_velocity(new_vel) + else -- reset things when you stop flying with elytra + elytra.rocketing = 0 + playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") + end + + if wielded_def and wielded_def._mcl_toollike_wield then + set_bone_pos(player, "Wield_Item", vector.new(0, 4.7, 3.1), vector.new(-90, 225, 90)) + elseif string.find(wielded:get_name(), "mcl_bows:bow") then + set_bone_pos(player, "Wield_Item", vector.new(1, 4, 0), vector.new(90, 130, 115)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 73)) + elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then + set_bone_pos(player, "Wield_Item", vector.new(0, 5.2, 1.2), vector.new(0, 180, 45)) + elseif wielded_def.inventory_image == "" then + set_bone_pos(player,"Wield_Item", vector.new(0, 6, 2), vector.new(180, -45, 0)) + else + set_bone_pos(player, "Wield_Item", vector.new(0, 5.3, 2), vector.new(90, 0, 0)) + end + + -- controls right and left arms pitch when shooting a bow or blocking + if mcl_shields.is_blocking(player) == 2 then + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, -20, 0)) + elseif mcl_shields.is_blocking(player) == 1 then + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(20, 20, 0)) + elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then + local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) + local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) + -- controls right and left arms pitch when holing a loaded crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then + local right_arm_rot = vector.new(pitch + 90, -30, pitch * -1 * .35) + local left_arm_rot = vector.new(pitch + 90, 43, pitch * .35) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, right_arm_rot) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, left_arm_rot) + -- controls right and left arms pitch when loading a crossbow + elseif string.find(wielded:get_name(), "mcl_bows:crossbow_") then + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(45, -20, 25)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.new(55, 20, -45)) + -- when punching + elseif control.LMB and not parent then + set_bone_pos(player,"Arm_Right_Pitch_Control", nil, vector.new(pitch, 0, 0)) + set_bone_pos(player,"Arm_Left_Pitch_Control", nil, vector.zero()) + -- when holding an item. + elseif wielded:get_name() ~= "" then + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.new(20, 0, 0)) + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero()) + -- resets arms pitch + else + set_bone_pos(player, "Arm_Left_Pitch_Control", nil, vector.zero()) + set_bone_pos(player, "Arm_Right_Pitch_Control", nil, vector.zero()) + end + + if elytra.active then + -- set head pitch and yaw when flying + local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 50, player_vel_yaw - yaw, 0) + set_bone_pos(player,"Head_Control", nil, head_rot) + + -- sets eye height, and nametag color accordingly + 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) + set_bone_pos(player, "Body_Control", nil, body_rot) + elseif parent then + set_properties(player, player_props_riding) + + local parent_yaw = degrees(parent:get_yaw()) + local head_rot = vector.new(pitch, -limit_vel_yaw(yaw, parent_yaw) + parent_yaw, 0) + set_bone_pos(player, "Head_Control", nil, head_rot) + set_bone_pos(player,"Body_Control", nil, vector.zero()) + elseif control.sneak then + -- controls head pitch when sneaking + local head_rot = vector.new(pitch, player_vel_yaw - yaw, player_vel_yaw - yaw) + set_bone_pos(player, "Head_Control", nil, head_rot) + + -- sets eye height, and nametag color accordingly + set_properties(player, player_props_sneaking) + + -- sneaking body conrols + set_bone_pos(player, "Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0)) + elseif get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and is_sprinting(name) == true then + -- set head pitch and yaw when swimming + is_swimming = true + local head_rot = vector.new(pitch - degrees(dir_to_pitch(player_velocity)) + 20, player_vel_yaw - yaw, 0) + set_bone_pos(player, "Head_Control", nil, head_rot) + + -- sets eye height, and nametag color accordingly + set_properties(player, player_props_swimming) + + -- control body bone when swimming + local body_rot = vector.new((75 + degrees(dir_to_pitch(player_velocity))), player_vel_yaw - yaw, 180) + set_bone_pos(player,"Body_Control", nil, body_rot) + elseif get_item_group(mcl_playerinfo[name].node_head, "solid") == 0 + and get_item_group(mcl_playerinfo[name].node_head_top, "solid") == 0 then + -- sets eye height, and nametag color accordingly + is_swimming = false + set_properties(player, player_props_normal) + + set_bone_pos(player,"Head_Control", nil, vector.new(pitch, player_vel_yaw - yaw, 0)) + set_bone_pos(player,"Body_Control", nil, vector.new(0, -player_vel_yaw + yaw, 0)) + end + + local underwater + if get_item_group(mcl_playerinfo[name].node_head, "water") ~= 0 and underwater ~= true then + mcl_weather.skycolor.update_sky_color() + local underwater = true + elseif get_item_group(mcl_playerinfo[name].node_head, "water") == 0 and underwater == true then + mcl_weather.skycolor.update_sky_color() + local underwater = false + end + + elytra.last_yaw = player:get_look_horizontal() + -- Update jump status immediately since we need this info in real time. + -- WARNING: This section is HACKY as hell since it is all just based on heuristics. + + if mcl_playerplus_internal[name].jump_cooldown > 0 then + mcl_playerplus_internal[name].jump_cooldown = mcl_playerplus_internal[name].jump_cooldown - dtime + end + + if control.jump and mcl_playerplus_internal[name].jump_cooldown <= 0 then + + --pos = player:get_pos() + + node_stand = mcl_playerinfo[name].node_stand + node_stand_below = mcl_playerinfo[name].node_stand_below + node_head = mcl_playerinfo[name].node_head + node_feet = mcl_playerinfo[name].node_feet + node_head_top = mcl_playerinfo[name].node_head_top + if not node_stand or not node_stand_below or not node_head or not node_feet then + return + end + if (not minetest.registered_nodes[node_stand] + or not minetest.registered_nodes[node_stand_below] + or not minetest.registered_nodes[node_head] + or not minetest.registered_nodes[node_feet] + or not minetest.registered_nodes[node_head_top]) then + return + end + + -- Cause buggy exhaustion for jumping + + --[[ Checklist we check to know the player *actually* jumped: + * Not on or in liquid + * Not on or at climbable + * On walkable + * Not on disable_jump + FIXME: This code is pretty hacky and it is possible to miss some jumps or detect false + jumps because of delays, rounding errors, etc. + What this code *really* needs is some kind of jumping “callback” which this engine lacks + as of 0.4.15. + ]] + + if get_item_group(node_feet, "liquid") == 0 and + get_item_group(node_stand, "liquid") == 0 and + not minetest.registered_nodes[node_feet].climbable and + not minetest.registered_nodes[node_stand].climbable and + (minetest.registered_nodes[node_stand].walkable or minetest.registered_nodes[node_stand_below].walkable) + and get_item_group(node_stand, "disable_jump") == 0 + and get_item_group(node_stand_below, "disable_jump") == 0 then + -- Cause exhaustion for jumping + if is_sprinting(name) then + exhaust(name, mcl_hunger.EXHAUST_SPRINT_JUMP) + else + exhaust(name, mcl_hunger.EXHAUST_JUMP) + end + + -- Reset cooldown timer + mcl_playerplus_internal[name].jump_cooldown = 0.45 + end + end + end + + -- Run the rest of the code every 0.5 seconds + if time < 0.5 then + return + end + + -- reset time for next check + -- FIXME: Make sure a regular check interval applies + time = 0 + + -- check players + for _,player in pairs(get_connected_players()) do + -- who am I? + local name = player:get_player_name() + + -- where am I? + local pos = player:get_pos() + + -- what is around me? + local node_stand = mcl_playerinfo[name].node_stand + local node_stand_below = mcl_playerinfo[name].node_stand_below + local node_head = mcl_playerinfo[name].node_head + local node_feet = mcl_playerinfo[name].node_feet + local node_head_top = mcl_playerinfo[name].node_head_top + if not node_stand or not node_stand_below or not node_head or not node_feet or not node_head_top then + return + end + + -- Standing on soul sand? If so, walk slower (unless player wears Soul Speed boots) + if node_stand == "mcl_nether:soul_sand" then + -- TODO: Tweak walk speed + -- TODO: Also slow down mobs + -- Slow down even more when soul sand is above certain block + local boots = player:get_inventory():get_stack("armor", 5) + local soul_speed = mcl_enchanting.get_enchantment(boots, "soul_speed") + if soul_speed > 0 then + playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", soul_speed * 0.105 + 1.3) + else + if node_stand_below == "mcl_core:ice" or node_stand_below == "mcl_core:packed_ice" or node_stand_below == "mcl_core:slimeblock" or node_stand_below == "mcl_core:water_source" then + playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", 0.1) + else + playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", 0.4) + end + end + elseif get_item_group(node_feet, "liquid") ~= 0 and mcl_enchanting.get_enchantment(player:get_inventory():get_stack("armor", 5), "depth_strider") then + local boots = player:get_inventory():get_stack("armor", 5) + local depth_strider = mcl_enchanting.get_enchantment(boots, "depth_strider") + + if depth_strider > 0 then + playerphysics.add_physics_factor(player, "speed", "mcl_playerplus:surface", (depth_strider / 3) + 0.75) + end + else + playerphysics.remove_physics_factor(player, "speed", "mcl_playerplus:surface") + end + + -- Is player suffocating inside node? (Only for solid full opaque cube type nodes + -- without group disable_suffocation=1) + -- if swimming, check the feet node instead, because the head node will be above the player when swimming + local ndef = minetest.registered_nodes[node_head] + if is_swimming then + ndef = minetest.registered_nodes[node_feet] + end + if (ndef.walkable == nil or ndef.walkable == true) + and (ndef.collision_box == nil or ndef.collision_box.type == "regular") + and (ndef.node_box == nil or ndef.node_box.type == "regular") + and (ndef.groups.disable_suffocation ~= 1) + and (ndef.groups.opaque == 1) + and (node_head ~= "ignore") + -- Check privilege, too + and (not check_player_privs(name, {noclip = true})) then + if player:get_hp() > 0 then + mcl_util.deal_damage(player, 1, {type = "in_wall"}) + end + end + + -- Am I near a cactus? + local near = find_node_near(pos, 1, "mcl_core:cactus") + if not near then + near = find_node_near({x=pos.x, y=pos.y-1, z=pos.z}, 1, "mcl_core:cactus") + end + if near then + -- Am I touching the cactus? If so, it hurts + local dist = vector.distance(pos, near) + local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near) + if dist < 1.1 or dist_feet < 1.1 then + if player:get_hp() > 0 then + mcl_util.deal_damage(player, 1, {type = "cactus"}) + end + end + end + + --[[ Swimming: Cause exhaustion. + NOTE: As of 0.4.15, it only counts as swimming when you are with the feet inside the liquid! + Head alone does not count. We respect that for now. ]] + if not player:get_attach() and (get_item_group(node_feet, "liquid") ~= 0 or + get_item_group(node_stand, "liquid") ~= 0) then + local lastPos = mcl_playerplus_internal[name].lastPos + if lastPos then + local dist = vector.distance(lastPos, pos) + mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance + dist + if mcl_playerplus_internal[name].swimDistance >= 1 then + local superficial = math.floor(mcl_playerplus_internal[name].swimDistance) + exhaust(name, mcl_hunger.EXHAUST_SWIM * superficial) + mcl_playerplus_internal[name].swimDistance = mcl_playerplus_internal[name].swimDistance - superficial + end + end + + end + + -- Underwater: Spawn bubble particles + if get_item_group(node_head, "water") ~= 0 then + add_particlespawner({ + amount = 10, + time = 0.15, + minpos = { x = -0.25, y = 0.3, z = -0.25 }, + maxpos = { x = 0.25, y = 0.7, z = 0.75 }, + attached = player, + minvel = {x = -0.2, y = 0, z = -0.2}, + maxvel = {x = 0.5, y = 0, z = 0.5}, + minacc = {x = -0.4, y = 4, z = -0.4}, + maxacc = {x = 0.5, y = 1, z = 0.5}, + minexptime = 0.3, + maxexptime = 0.8, + minsize = 0.7, + maxsize = 2.4, + texture = "mcl_particles_bubble.png" + }) + end + + -- Show positions of barriers when player is wielding a barrier + local wi = player:get_wielded_item():get_name() + if wi == "mcl_core:barrier" or wi == "mcl_core:realm_barrier" or minetest.get_item_group(wi, "light_block") ~= 0 then + local pos = vector.round(player:get_pos()) + local r = 8 + local vm = get_voxel_manip() + local emin, emax = vm:read_from_map({x=pos.x-r, y=pos.y-r, z=pos.z-r}, {x=pos.x+r, y=pos.y+r, z=pos.z+r}) + local area = VoxelArea:new{ + MinEdge = emin, + MaxEdge = emax, + } + local data = vm:get_data() + for x=pos.x-r, pos.x+r do + for y=pos.y-r, pos.y+r do + for z=pos.z-r, pos.z+r do + local vi = area:indexp({x=x, y=y, z=z}) + local nodename = get_name_from_content_id(data[vi]) + local light_block_group = minetest.get_item_group(nodename, "light_block") + + local tex + if nodename == "mcl_core:barrier" then + tex = "mcl_core_barrier.png" + elseif nodename == "mcl_core:realm_barrier" then + tex = "mcl_core_barrier.png^[colorize:#FF00FF:127^[transformFX" + elseif light_block_group ~= 0 then + tex = "mcl_core_light_" .. (light_block_group - 1) .. ".png" + end + if tex then + add_particle({ + pos = {x=x, y=y, z=z}, + expirationtime = 1, + size = 8, + texture = tex, + glow = 14, + playername = name + }) + end + end + end + end + end + + -- Update internal values + mcl_playerplus_internal[name].lastPos = pos + + end + +end) + +-- set to blank on join (for 3rd party mods) +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + + 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 + } + mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0} + + -- Minetest bug: get_bone_position() returns all zeros vectors. + -- Workaround: call set_bone_position() one time first. + player:set_bone_position("Head_Control", vector.new(0, 6.75, 0)) + 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)) +end) + +-- clear when player leaves +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + + mcl_playerplus_internal[name] = nil + mcl_playerplus.elytra[player] = nil +end) + +-- Don't change HP if the player falls in the water or through End Portal: +mcl_damage.register_modifier(function(obj, damage, reason) + if reason.type == "fall" then + local pos = obj:get_pos() + local node = minetest.get_node(pos) + local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0} + local v_axis_max = math.max(math.abs(velocity.x), math.abs(velocity.y), math.abs(velocity.z)) + local step = {x = velocity.x / v_axis_max, y = velocity.y / v_axis_max, z = velocity.z / v_axis_max} + for i = 1, math.ceil(v_axis_max/5)+1 do -- trace at least 1/5 of the way per second + if not node or node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node(pos) + end + if node then + local def = minetest.registered_nodes[node.name] + if not def or def.walkable then + return + end + if minetest.get_item_group(node.name, "water") ~= 0 then + return 0 + end + if node.name == "mcl_portals:portal_end" then + if mcl_portals and mcl_portals.end_teleport then + mcl_portals.end_teleport(obj) + end + return 0 + end + if node.name == "mcl_core:cobweb" then + return 0 + end + if node.name == "mcl_core:vine" then + return 0 + end + end + pos = vector.add(pos, step) + node = minetest.get_node(pos) + end + end +end, -200) + +minetest.register_on_respawnplayer(function(player) + local pos = player:get_pos() + minetest.add_particlespawner({ + amount = 50, + time = 0.001, + minpos = vector.add(pos, 0), + maxpos = vector.add(pos, 0), + minvel = vector.new(-5,-5,-5), + maxvel = vector.new(5,5,5), + minexptime = 1.1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_mob_death.png^[colorize:#000000:255", + }) + + minetest.sound_play("mcl_mobs_mob_poof", { + pos = pos, + gain = 1.0, + max_hear_distance = 8, + }, true) +end) diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.de.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.de.tr deleted file mode 100644 index 44d486d08..000000000 --- a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.de.tr +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_playerplus -@1 suffocated to death.=@1 erstickte zu Tode. -@1 was prickled to death by a cactus.=@1 wurde von einem Kaktus zu Tode gepiekst. diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.es.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.es.tr deleted file mode 100644 index ef7705bce..000000000 --- a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.es.tr +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_playerplus -@1 suffocated to death.=@1 ahogado hasta la muerte. -@1 was prickled to death by a cactus.=@1 fue herido de muerte por un cactus. diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.fr.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.fr.tr deleted file mode 100644 index 6482bd736..000000000 --- a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.fr.tr +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_playerplus -@1 suffocated to death.=@1 étouffé à mort. -@1 was prickled to death by a cactus.=@1 a été piqué à mort par un cactus. diff --git a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ru.tr b/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ru.tr deleted file mode 100644 index a75bd4bd6..000000000 --- a/mods/PLAYER/mcl_playerplus/locale/mcl_playerplus.ru.tr +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_playerplus -@1 suffocated to death.=@1 задохнулся(ась). -@1 was prickled to death by a cactus.=@1 был(а) до смерти заколот(а) кактусом. diff --git a/mods/PLAYER/mcl_playerplus/locale/template.txt b/mods/PLAYER/mcl_playerplus/locale/template.txt deleted file mode 100644 index 49b1f96ac..000000000 --- a/mods/PLAYER/mcl_playerplus/locale/template.txt +++ /dev/null @@ -1,3 +0,0 @@ -# textdomain: mcl_playerplus -@1 suffocated to death.= -@1 was prickled to death by a cactus.= diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 660def45e..953ea9403 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1 +1,5 @@ name = mcl_playerplus +author = TenPlus1 +description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. +depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage, mcl_sprint, mcl_util, mcl_shields + diff --git a/mods/PLAYER/mcl_skins/.gitignore b/mods/PLAYER/mcl_skins/.gitignore new file mode 100644 index 000000000..6edbd2834 --- /dev/null +++ b/mods/PLAYER/mcl_skins/.gitignore @@ -0,0 +1,4 @@ +!textures/mcl_skins_character_1.png +textures/mcl_skins_character_* +!meta/mcl_skins_character_1.txt +meta/mcl_skins_character_* \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/LICENSE.txt b/mods/PLAYER/mcl_skins/LICENSE.txt index fec6f6aa5..da582622b 100644 --- a/mods/PLAYER/mcl_skins/LICENSE.txt +++ b/mods/PLAYER/mcl_skins/LICENSE.txt @@ -1,5 +1,6 @@ The MIT License (MIT) +Copyright (c) 2022 MrRar Copyright (c) 2016 TenPlus1 Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/mods/PLAYER/mcl_skins/README.md b/mods/PLAYER/mcl_skins/README.md index bbe5309ab..303dcf424 100644 --- a/mods/PLAYER/mcl_skins/README.md +++ b/mods/PLAYER/mcl_skins/README.md @@ -1,13 +1,118 @@ -= Skins for MineClone 2 = +# Mineclone Skins -Simple mod to allow players to select a skin. -Use the chat command /setskin to change skin. +This mod allows advanced skin customization. +Use the /skin command to open the skin configuration screen. -Forked from Simple Skins by TenPlus1. -https://forum.minetest.net/viewtopic.php?id=9100 +To include custom skins in MineClone2, please download [mcl_custom_skins](https://git.minetest.land/mineclone2/mcl_custom_skins) -== License == +## License Code under MIT license -Origial authors: -- TenPlus1 -- Zeg9 +Author: MrRar + +See image_credits.txt for image licensing. + +## API + +### `mcl_skins.register_item(item)` +Register a skin item. `item` is a table with item properties listed below. + +### Item properties + +`type` +Set the item type. Valid values are: "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear" + +`texture` +Set to the image file that will be used. If this property is omitted "blank.png" is used. + +`mask` +Set the color mask texture. Coloring is only applied to non transparent areas of the texture. +Coloring only works for "base", "bottom, "top", and "hair". + +`preview_rotation` +A table containing properties x and y. x and y represent the x and y rotation of the item preview. + +`template2` +If set to true the item will be default for female template. + +`template1` +If set to true the item will be default for male template. + +`rank` +This property is used to change the application order of the skin item when applied to a player. +The default ranks for each item type are: + +base: 10 + +footwear: 20 + +eye: 30 + +mouth: 40 + +bottom: 50 + +top: 60 + +hair: 70 + +headwear: 80 + +Lower ranks are applied to the player first and can thus be covered by higher rank items. + + +### `mcl_skins.show_formspec(player, active_tab, page_num)` +Show the skin configuration screen. + +`player` is a player ObjectRef. + +`active_tab` is the tab that will be displayed. This parameter is optional. +Can be one of: "arm", "base", "footwear", "eye", "mouth", "bottom", "top", "hair", "headwear" + +`page_num` The page number to display of there are multiple pages of items. +This parameter is optional. Must be a number. If it is not a valid page number the closest page number will be shown. + +### `mcl_skins.get_skin_list()` +This function is used by mods that want a list of skins to register nodes that use the player skin as a texture. +Returns an array of tables containing information about each skin. +Each table contains the following properties: + +`id`: A string representing the node ID. A node can be registered using this node ID. + +`texture`: A texture string that can be used in the node defintion. + +`slim_arms`: A boolean value. If true, this texture is used with the "female" player mesh. Otherwise the regular mesh is to be used. + +### `mcl_skins.get_node_id_by_player(player)` +`player` is a player ObjectRef. +Returns a string node ID based on players current skin for use by mods that want to register nodes that use the player skin. + +### `mcl_skins.save(player)` +Save player skin. `player` is a player ObjectRef. + +### `mcl_skins.update_player_skin(player)` +Update a player based on skin data in mcl_skins.players. +`player` is a player ObjectRef. + +### `mcl_skins.base_color` +A table of ColorSpec integers that the player can select to color the base item. +These colors are separate from `mcl_skins.color` because some mods register two nodes per base color so the amount of base colors needs to be limited. + +### `mcl_skins.color` +A table of ColorSpec integers that the player can select to color colorable skin items. + +### `mcl_skins.player_skins` +A table mapped by player ObjectRef containing tables holding the player's selected skin items and colors. +Only stores skin information for logged in users. + +### `mcl_skins.compile_skin(skin)` +`skin` is a table with skin item properties. +Returns an image string. + +### `mcl_skins.register_simple_skin(skin)` +`skin` is a table with the following properties: + +`texture` +The texture of the skin. + +`slim_arms` +A boolean value. If set to true, the slim armed player mesh will be used with this skin. diff --git a/mods/PLAYER/mcl_skins/depends.txt b/mods/PLAYER/mcl_skins/depends.txt deleted file mode 100644 index 09bdf5205..000000000 --- a/mods/PLAYER/mcl_skins/depends.txt +++ /dev/null @@ -1,4 +0,0 @@ -mcl_player -mcl_inventory? -intllib? -mcl_armor? diff --git a/mods/PLAYER/mcl_skins/description.txt b/mods/PLAYER/mcl_skins/description.txt deleted file mode 100644 index 61c7bff64..000000000 --- a/mods/PLAYER/mcl_skins/description.txt +++ /dev/null @@ -1 +0,0 @@ -Mod that allows players to set their individual skins. \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/edit_skin.lua b/mods/PLAYER/mcl_skins/edit_skin.lua new file mode 100644 index 000000000..706c08461 --- /dev/null +++ b/mods/PLAYER/mcl_skins/edit_skin.lua @@ -0,0 +1,621 @@ +local S = minetest.get_translator("mcl_skins") +local color_to_string = minetest.colorspec_to_colorstring +local EDIT_SKIN_KEY = -1 -- The key used for edit skin in the mcl_skins.simple_skins table + +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"}, + tab_descriptions = { + template = S("Templates"), + arm = S("Arm size"), + base = S("Bases"), + footwear = S("Footwears"), + eye = S("Eyes"), + mouth = S("Mouths"), + bottom = S("Bottoms"), + top = S("Tops"), + hair = S("Hairs"), + headwear = S("Headwears"), + skin = S("Skins"), + }, + 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 = { + 0xff613915, -- 1 Dark brown + 0xff97491b, -- 2 Medium brown + 0xffb17050, -- 3 Light brown + 0xffe2bc7b, -- 4 Beige + 0xff706662, -- 5 Gray + 0xff151515, -- 6 Black + 0xffc21c1c, -- 7 Red + 0xff178c32, -- 8 Green + 0xffae2ad3, -- 9 Plum + 0xffebe8e4, -- 10 White + 0xffe3dd26, -- 11 Yellow + 0xff449acc, -- 12 Light blue + 0xff124d87, -- 13 Dark blue + 0xfffc0eb3, -- 14 Pink + 0xffd0672a, -- 15 Orange + }, + footwear = {}, + mouth = {}, + eye = {}, + bottom = {}, + top = {}, + hair = {}, + headwear = {}, + masks = {}, + preview_rotations = {}, + ranks = {}, + player_skins = {}, + player_formspecs = {}, +} + +function mcl_skins.register_item(item) + assert(mcl_skins[item.type], "Skin item type " .. item.type .. " does not exist.") + 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 + mcl_skins.ranks[texture] = item.rank +end + +function mcl_skins.register_simple_skin(skin) + if skin.index then + mcl_skins.simple_skins[skin.index] = skin + else + table.insert(mcl_skins.simple_skins, skin) + end + mcl_skins.texture_to_simple_skin[skin.texture] = skin +end + +function mcl_skins.save(player) + local skin = mcl_skins.player_skins[player] + if not skin then return end + + local meta = player:get_meta() + meta:set_string("mcl_skins:skin", minetest.serialize(skin)) + + -- Clear out the old way of storing the simple skin ID + meta:set_string("mcl_skins:skin_id", "") +end + +minetest.register_chatcommand("skin", { + description = S("Open skin configuration screen."), + privs = {}, + func = function(name, param) + local player = minetest.get_player_by_name(name) + local formspec_data = mcl_skins.player_formspecs[player] + local active_tab = formspec_data.active_tab + local page_num = formspec_data.page_num + mcl_skins.show_formspec(player, active_tab, page_num) + end +}) + +function mcl_skins.compile_skin(skin) + if not skin then return "blank.png" end + + if skin.simple_skins_id then + return skin.simple_skins_id + end + + local ranks = {} + local layers = {} + for i, item in ipairs(mcl_skins.item_names) do + local texture = skin[item] + local layer = "" + local rank = mcl_skins.ranks[texture] or i * 10 + if texture and texture ~= "blank.png" then + if skin[item .. "_color"] and mcl_skins.masks[texture] then + local color = color_to_string(skin[item .. "_color"]) + layer = "(" .. mcl_skins.masks[texture] .. "^[colorize:" .. color .. ":alpha)" + end + if #layer > 0 then layer = layer .. "^" end + layer = layer .. texture + layers[rank] = layer + table.insert(ranks, rank) + end + end + table.sort(ranks) + local output = "" + for i, rank in ipairs(ranks) do + if #output > 0 then output = output .. "^" end + output = output .. layers[rank] + end + return output +end + +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 slim_arms + if skin.simple_skins_id then + slim_arms = mcl_skins.texture_to_simple_skin[skin.simple_skins_id].slim_arms + else + slim_arms = skin.slim_arms + end + local model = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" + mcl_player.player_set_model(player, model) +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) +end) + +minetest.register_on_leaveplayer(function(player) + mcl_skins.player_skins[player] = nil + mcl_skins.player_formspecs[player] = nil +end) + +local function calculate_page_count(tab) + if tab == "skin" then + return math.ceil((#mcl_skins.simple_skins + 2) / 8) + elseif mcl_skins[tab] then + return math.ceil(#mcl_skins[tab] / 16) + end + return 1 +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] + formspec_data.active_tab = active_tab + + local page_count = calculate_page_count(active_tab) + 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 .. "]" + + 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 + else + slim_arms = skin.slim_arms + end + local mesh = slim_arms and "mcl_armor_character_female.b3d" or "mcl_armor_character.b3d" + + formspec = formspec .. + "model[11,0.3;3,7;player_mesh;" .. mesh .. ";" .. + mcl_skins.compile_skin(skin) .. + ",blank.png,blank.png;0,180;false;true;0,0]" + + 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) + formspec = formspec .. + "style_type[button;bgcolor=#00000000]" + + local skin = table.copy(skin) + local simple_skins_id = skin.simple_skins_id + skin.simple_skins_id = nil + mcl_skins.simple_skins[EDIT_SKIN_KEY] = { + slim_arms = skin.slim_arms, + texture = mcl_skins.compile_skin(skin), + } + 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 .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;" .. + "bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]" + end + 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 + elseif active_tab == "template" then + formspec = formspec .. + "model[5,2;2,3;player_mesh;mcl_armor_character.b3d;" .. + mcl_skins.compile_skin(mcl_skins.template1) .. + ",blank.png,blank.png;0,180;false;true;0,0]" .. + + "button[5,5.2;2,0.8;template1;" .. S("Select") .. "]" .. + + "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 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] + local preview = mcl_skins.masks[skin.base] .. "^[colorize:gray^" .. skin.base + local color = color_to_string(skin[active_tab .. "_color"]) + local mask = mcl_skins.masks[texture] + if color and mask then + 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 + formspec = formspec .. + "model[" .. x .. "," .. y .. + ";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 .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;" .. + "bgimg_pressed=mcl_skins_select_overlay.png;bgimg_middle=14,14]" + end + formspec = formspec .. "button[" .. x .. "," .. y .. ";1.5,1.5;" .. texture .. ";]" + end + elseif active_tab == "arm" then + local x = skin.slim_arms and 5.7 or 4.6 + formspec = formspec .. + "image_button[4.6,0.3;1,1;mcl_skins_thick_arms.png;thick_arms;]" .. + "image_button[5.7,0.3;1,1;mcl_skins_slim_arms.png;slim_arms;]" .. + "style[arm;bgcolor=;bgimg=mcl_skins_select_overlay.png;" .. + "bgimg_middle=14,14;bgimg_pressed=mcl_skins_select_overlay.png]" .. + "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 + local color = color_to_string(colorspec) + i = i - 1 + local x = 4.6 + i % 6 * 0.9 + local y = 8 + math.floor(i / 6) * 0.9 + formspec = formspec .. + "image_button[" .. x .. "," .. y .. + ";0.8,0.8;blank.png^[noalpha^[colorize:" .. + color .. ":alpha;" .. colorspec .. ";]" + + if selected_color == colorspec then + formspec = formspec .. + "style[" .. color .. + ";bgcolor=;bgimg=mcl_skins_select_overlay.png;bgimg_middle=14,14;" .. + "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 + local green = math.floor(selected_color / 0x100) - 0xff0000 - red * 0x100 + local blue = selected_color - 0xff000000 - red * 0x10000 - green * 0x100 + 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;]" + end + + if page_num < page_count then + formspec = formspec .. + "image_button[9.8,6.7;1,1;mcl_skins_arrow.png;next_page;]" + end + + if page_count > 1 then + formspec = formspec .. + "label[7.3,7.2;" .. page_num .. " / " .. page_count .. "]" + end + + local player_name = player:get_player_name() + minetest.show_formspec(player_name, "mcl_skins:skins", formspec) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local formspec_data = mcl_skins.player_formspecs[player] + local active_tab = formspec_data.active_tab + local page_num = formspec_data.page_num + + if fields.__mcl_skins then + mcl_skins.show_formspec(player, active_tab, page_num) + return false + end + + if formname ~= "mcl_skins:skins" then return false end + + -- Cancel formspec resend after scrollbar move + if formspec_data.form_send_job then + formspec_data.form_send_job:cancel() + formspec_data.form_send_job = nil + end + + if fields.quit then + mcl_skins.save(player) + return true + end + + if fields.template2 then + mcl_skins.player_skins[player] = table.copy(mcl_skins.template2) + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + elseif fields.template1 then + mcl_skins.player_skins[player] = table.copy(mcl_skins.template1) + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + 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] + 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) + return true + elseif fields.previous_page then + page_num = page_num - 1 + 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 + elseif fields.slim_arms then + skin.slim_arms = true + end + mcl_skins.update_player_skin(player) + 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 + fields.green and fields.green:find("^CHG") or + fields.blue and fields.blue:find("^CHG") + ) + then + local red = fields.red:gsub("%a%a%a:", "") + local green = fields.green:gsub("%a%a%a:", "") + local blue = fields.blue:gsub("%a%a%a:", "") + 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 + formspec_data.form_send_job = minetest.after(0.2, function() + if player and player:is_player() then + skin[active_tab .. "_color"] = color + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + formspec_data.form_send_job = nil + end + end) + return true + end + end + + local field + for f, value in pairs(fields) do + if value == "" then + field = f + break + end + end + + if field and active_tab == "skin" then + local index = tonumber(field) + index = index and math.floor(index) or 0 + mcl_skins.simple_skins[EDIT_SKIN_KEY].texture = nil + if + #mcl_skins.simple_skins > 0 and + index >= EDIT_SKIN_KEY and index <= #mcl_skins.simple_skins + then + skin.simple_skins_id = mcl_skins.simple_skins[index].texture + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + end + return true + end + + -- See if field is a texture + if + field and mcl_skins[active_tab] and + table.indexof(mcl_skins[active_tab], field) ~= -1 + then + skin[active_tab] = field + mcl_skins.update_player_skin(player) + 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 + local color = math.floor(number) + if color and color >= 0 and color <= 0xffffffff then + skin[active_tab .. "_color"] = color + mcl_skins.update_player_skin(player) + mcl_skins.show_formspec(player, active_tab, page_num) + return true + end + end + + return true +end) + +local function init() + local f = io.open(minetest.get_modpath("mcl_skins") .. "/list.json") + assert(f, "Can't open the file list.json") + local data = f:read("*all") + assert(data, "Can't read data from list.json") + local json, error = minetest.parse_json(data) + assert(json, error) + f:close() + + for _, item in pairs(json) do + mcl_skins.register_item(item) + end + mcl_skins.template1.base_color = mcl_skins.base_color[2] + mcl_skins.template1.hair_color = 0xff5d473b + mcl_skins.template1.top_color = 0xff993535 + mcl_skins.template1.bottom_color = 0xff644939 + mcl_skins.template1.slim_arms = false + + 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.register_simple_skin({ + index = 0, + texture = "character.png" + }) + mcl_skins.register_simple_skin({ + index = 1, + texture = "mcl_skins_character_1.png", + slim_arms = true + }) +end + +init() diff --git a/mods/PLAYER/mcl_skins/init.lua b/mods/PLAYER/mcl_skins/init.lua index b1d1feef8..f1192ba16 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -1,287 +1,8 @@ --- Skins for MineClone 2 - -mcl_skins = { - skins = {}, list = {}, previews = {}, meta = {}, has_preview = {}, - modpath = minetest.get_modpath("mcl_skins"), - skin_count = 0, -- counter of _custom_ skins (all skins except character.png) -} - -local S = minetest.get_translator("mcl_skins") - --- load skin list and metadata -local id, f, data, skin = 0 - -while true do - - if id == 0 then - skin = "character" - mcl_skins.has_preview[id] = true - else - skin = "mcl_skins_character_" .. id - local preview = "mcl_skins_player_" .. id - - -- Does skin file exist? - f = io.open(mcl_skins.modpath .. "/textures/" .. skin .. ".png") - - -- escape loop if not found - if not f then - break - end - f:close() - - -- Does skin preview file exist? - local file_preview = io.open(mcl_skins.modpath .. "/textures/" .. preview .. ".png") - if file_preview == nil then - minetest.log("warning", "[mcl_skins] Player skin #"..id.." does not have preview image (player_"..id..".png)") - mcl_skins.has_preview[id] = false - else - mcl_skins.has_preview[id] = true - file_preview:close() - end - end - - mcl_skins.list[id] = skin - - -- does metadata exist for that skin file ? - if id == 0 then - metafile = "mcl_skins_character.txt" - else - metafile = "mcl_skins_character_"..id..".txt" - end - f = io.open(mcl_skins.modpath .. "/meta/" .. metafile) - - data = nil - if f then - data = minetest.deserialize("return {" .. f:read('*all') .. "}") - f:close() - end - - -- add metadata to list - mcl_skins.meta[skin] = { - name = data and data.name or "", - author = data and data.author or "", - } - - if id > 0 then - mcl_skins.skin_count = mcl_skins.skin_count + 1 - end - id = id + 1 -end - -mcl_skins.cycle_skin = function(player) - local skin_id = tonumber(player:get_meta():get_string("mcl_skins:skin_id")) - if not skin_id then - skin_id = 0 - end - skin_id = skin_id + 1 - if skin_id > mcl_skins.skin_count then - skin_id = 0 - end - mcl_skins.set_player_skin(player, skin_id) -end - -mcl_skins.set_player_skin = function(player, skin_id) - if not player then - return false - end - local playername = player:get_player_name() - local skin, skin_file, preview - if skin_id == nil or type(skin_id) ~= "number" or skin_id < 0 or skin_id > mcl_skins.skin_count then - return false - elseif skin_id == 0 then - skin = "character" - preview = "player" - else - skin = "mcl_skins_character_" .. tostring(skin_id) - if mcl_skins.has_preview[skin_id] then - preview = "mcl_skins_player_" .. tostring(skin_id) - else - -- Fallback preview image if preview image is missing - preview = "mcl_skins_player_dummy" - end - end - skin_file = skin .. ".png" - mcl_skins.skins[playername] = skin - mcl_skins.previews[playername] = preview - player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id)) - mcl_skins.update_player_skin(player) - if minetest.get_modpath("mcl_armor") then - armor.textures[playername].skin = skin_file - armor:update_player_visuals(player) - end - if minetest.get_modpath("mcl_inventory") then - mcl_inventory.update_inventory_formspec(player) - end - for i=1, #mcl_skins.registered_on_set_skins do - mcl_skins.registered_on_set_skins[i](player, skin) - end - minetest.log("action", "[mcl_skins] Player skin for "..playername.." set to skin #"..skin_id) - return true -end - -mcl_skins.update_player_skin = function(player) - if not player then - return - end - local playername = player:get_player_name() - mcl_player.player_set_textures(player, { mcl_skins.skins[playername] .. ".png" }, mcl_skins.previews[playername] .. ".png" ) -end - --- load player skin on join -minetest.register_on_joinplayer(function(player) - - local name = player:get_player_name() - local skin_id = player:get_meta():get_string("mcl_skins:skin_id") - local set_skin - -- do we already have a skin in player attributes? - if skin_id ~= nil and skin_id ~= "" then - set_skin = tonumber(skin_id) - -- otherwise use random skin if not set - end - if not set_skin then - set_skin = math.random(0, mcl_skins.skin_count) - end - local ok = mcl_skins.set_player_skin(player, set_skin) - if not ok then - set_skin = math.random(0, mcl_skins.skin_count) - minetest.log("warning", "[mcl_skins] Player skin for "..name.." not found, falling back to skin #"..set_skin) - mcl_skins.set_player_skin(player, set_skin) - end -end) - -mcl_skins.registered_on_set_skins = {} - -mcl_skins.register_on_set_skin = function(func) - table.insert(mcl_skins.registered_on_set_skins, func) -end - --- command to set player skin (usually for custom skins) -minetest.register_chatcommand("setskin", { - params = S("[] []"), - description = S("Select player skin of yourself or another player"), - privs = {}, - func = function(name, param) - - if param == "" and name ~= "" then - mcl_skins.show_formspec(name) - return true - end - local playername, skin_id = string.match(param, "([^ ]+) (%d+)") - if not playername or not skin_id then - skin_id = string.match(param, "(%d+)") - if not skin_id then - return false, S("Insufficient or wrong parameters") - end - playername = name - end - skin_id = tonumber(skin_id) - - local player = minetest.get_player_by_name(playername) - - if not player then - return false, S("Player @1 not online!", playername) - end - if name ~= playername then - local privs = minetest.get_player_privs(name) - if not privs.server then - return false, S("You need the “server” privilege to change the skin of other players!") - end - end - - local skin - local ok = mcl_skins.set_player_skin(player, skin_id) - if not ok then - return false, S("Invalid skin number! Valid numbers: 0 to @1", mcl_skins.skin_count) - end - local skinfile = "#"..skin_id - - local meta = mcl_skins.meta[mcl_skins.skins[playername]] - local your_msg - if not meta.name or meta.name == "" then - your_msg = S("Your skin has been set to: @1", skinfile) - else - your_msg = S("Your skin has been set to: @1 (@2)", meta.name, skinfile) - end - if name == playername then - return true, your_msg - else - minetest.chat_send_player(playername, your_msg) - return true, S("Skin of @1 set to: @2 (@3)", playername, meta.name, skinfile) - end - - end, -}) - -minetest.register_on_player_receive_fields(function(player, formname, fields) - if fields.__mcl_skins then - if mcl_skins.skin_count <= 6 then - -- Change skin immediately if there are not many skins - mcl_skins.cycle_skin(player) - else - -- Show skin selection formspec otherwise - mcl_skins.show_formspec(player:get_player_name()) - end - end -end) - -mcl_skins.show_formspec = function(playername) - local formspec = "size[7,8.5]" - - formspec = formspec .. "label[2,2;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Select player skin:"))) .. "]" - .. "textlist[0,2.5;6.8,6;skins_set;" - - local meta - local selected = 1 - - for i = 0, mcl_skins.skin_count do - - local label = S("@1 (@2)", mcl_skins.meta[mcl_skins.list[i]].name, "#"..i) - - formspec = formspec .. minetest.formspec_escape(label) - - if mcl_skins.skins[playername] == mcl_skins.list[i] then - selected = i + 1 - meta = mcl_skins.meta[mcl_skins.list[i]] - end - - if i < #mcl_skins.list then - formspec = formspec .."," - end - end - - formspec = formspec .. ";" .. selected .. ";false]" - - formspec = formspec .. "image[0,0;1.35,2.7;" .. mcl_skins.previews[playername] .. ".png]" - - if meta then - if meta.name and meta.name ~= "" then - formspec = formspec .. "label[2,0.5;" .. minetest.formspec_escape(minetest.colorize("#383838", S("Name: @1", meta.name))) .. "]" - end - end - - minetest.show_formspec(playername, "mcl_skins:skin_select", formspec) -end - -minetest.register_on_player_receive_fields(function(player, formname, fields) - - if formname == "mcl_skins:skin_select" then - - local name = player:get_player_name() - - local event = minetest.explode_textlist_event(fields["skins_set"]) - - if event.type == "CHG" or event.type == "DCL" then - - local skin_id = math.min(event.index - 1, mcl_skins.skin_count) - if not mcl_skins.list[skin_id] then - return -- Do not update wrong skin number - end - - mcl_skins.set_player_skin(player, skin_id) - mcl_skins.show_formspec(name) - end - end -end) - -minetest.log("action", "[mcl_skins] Mod initialized with "..mcl_skins.skin_count.." custom skin(s)") - +local mod_path = minetest.get_modpath(minetest.get_current_modname()) + +local mcl_skins_enabled = minetest.settings:get_bool("mcl_enable_skin_customization", true) +if mcl_skins_enabled then + dofile(mod_path .. "/edit_skin.lua") + dofile(mod_path .. "/simple_skins.lua") + dofile(mod_path .. "/mesh_hand.lua") +end diff --git a/mods/PLAYER/mcl_skins/intllib.lua b/mods/PLAYER/mcl_skins/intllib.lua deleted file mode 100644 index 6669d7202..000000000 --- a/mods/PLAYER/mcl_skins/intllib.lua +++ /dev/null @@ -1,45 +0,0 @@ - --- Fallback functions for when `intllib` is not installed. --- Code released under Unlicense . - --- Get the latest version of this file at: --- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua - -local function format(str, ...) - local args = { ... } - local function repl(escape, open, num, close) - if escape == "" then - local replacement = tostring(args[tonumber(num)]) - if open == "" then - replacement = replacement..close - end - return replacement - else - return "@"..open..num..close - end - end - return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) -end - -local gettext, ngettext -if minetest.get_modpath("intllib") then - if intllib.make_gettext_pair then - -- New method using gettext. - gettext, ngettext = intllib.make_gettext_pair() - else - -- Old method using text files. - gettext = intllib.Getter() - end -end - --- Fill in missing functions. - -gettext = gettext or function(msgid, ...) - return format(msgid, ...) -end - -ngettext = ngettext or function(msgid, msgid_plural, n, ...) - return format(n==1 and msgid or msgid_plural, ...) -end - -return gettext, ngettext diff --git a/mods/PLAYER/mcl_skins/list.json b/mods/PLAYER/mcl_skins/list.json new file mode 100644 index 000000000..dc7afbfe1 --- /dev/null +++ b/mods/PLAYER/mcl_skins/list.json @@ -0,0 +1,267 @@ +[ + { + "type": "footwear", + "texture": "mcl_skins_footwear_1.png", + "template1": true, + "template2": true, + "rank": 55 + }, + { + "type": "footwear", + "texture": "mcl_skins_footwear_2.png" + }, + { + "type": "footwear", + "texture": "mcl_skins_footwear_3.png" + }, + { + "type": "footwear" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_1.png", + "template2": true + }, + { + "type": "eye", + "texture": "mcl_skins_eye_2.png", + "template1": true + }, + { + "type": "eye", + "texture": "mcl_skins_eye_3.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_4.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_5.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_6.png" + }, + { + "type": "eye", + "texture": "mcl_skins_eye_7.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_1.png", + "template1": true + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_2.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_3.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_4.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_5.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_6.png" + }, + { + "type": "mouth", + "texture": "mcl_skins_mouth_7.png" + }, + { + "type": "mouth", + "template1": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_1.png", + "mask": "mcl_skins_hair_1_mask.png", + "template2": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_2.png", + "mask": "mcl_skins_hair_2_mask.png", + "template1": true + }, + { + "type": "hair", + "texture": "mcl_skins_hair_3.png", + "mask": "mcl_skins_hair_3_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_4.png", + "mask": "mcl_skins_hair_4_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_5.png", + "mask": "mcl_skins_hair_5_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_6.png", + "mask": "mcl_skins_hair_6_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_7.png", + "mask": "mcl_skins_hair_7_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_8.png", + "mask": "mcl_skins_hair_8_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_9.png", + "mask": "mcl_skins_hair_9_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_10.png", + "mask": "mcl_skins_hair_10_mask.png" + }, + { + "type": "hair", + "texture": "mcl_skins_hair_11.png", + "mask": "mcl_skins_hair_11_mask.png" + }, + { + "type": "hair" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_1.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_2.png", + "template2": true + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_3.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_4.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_5.png" + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_6.png", + "preview_rotation": { + "x": -10, + "y": 200 + } + }, + { + "type": "headwear", + "texture": "mcl_skins_headwear_7.png" + }, + { + "type": "headwear", + "template1": true + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_1.png", + "mask": "mcl_skins_bottom_1_mask.png", + "template1": true, + "template2": true + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_2.png", + "mask": "mcl_skins_bottom_2_mask.png" + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_3.png", + "mask": "mcl_skins_bottom_3_mask.png" + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_4.png", + "mask": "mcl_skins_bottom_4_mask.png" + }, + { + "type": "bottom", + "texture": "mcl_skins_bottom_5.png", + "mask": "mcl_skins_bottom_5_mask.png", + "rank": 65 + }, + { + "type": "top", + "texture": "mcl_skins_top_1.png", + "mask": "mcl_skins_top_1_mask.png", + "template1": true, + "template2": true + }, + { + "type": "top", + "texture": "mcl_skins_top_2.png", + "mask": "mcl_skins_top_2_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_3.png", + "mask": "mcl_skins_top_3_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_4.png", + "mask": "mcl_skins_top_4_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_5.png", + "mask": "mcl_skins_top_5_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_6.png", + "mask": "mcl_skins_top_6_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_7.png", + "mask": "mcl_skins_top_7_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_8.png", + "mask": "mcl_skins_top_8_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_9.png", + "mask": "mcl_skins_top_9_mask.png" + }, + { + "type": "top", + "texture": "mcl_skins_top_10.png", + "mask": "mcl_skins_top_10_mask.png" + }, + { + "type": "base", + "texture": "mcl_skins_base_1.png", + "mask": "mcl_skins_base_1_mask.png", + "template1": true, + "template2": true + } +] diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr deleted file mode 100644 index 8f9b488db..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.de.tr +++ /dev/null @@ -1,13 +0,0 @@ -# textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Spieleraussehen von Ihnen oder einem anderen Spieler auswählen -Insufficient or wrong parameters=Unzureichende oder falsche Parameter -Player @1 not online!=Spieler @1 ist nicht online! -You need the “server” privilege to change the skin of other players!=Sie brauchen das „server“-Privileg, um das Aussehen anderer Spieler zu ändern! -Invalid skin number! Valid numbers: 0 to @1=Ungültige Aussehens-Nummer! Gültige Nummern: 0 bis @1 -Your skin has been set to: @1=Ihr Aussehen wurde geändert auf: @1 -Your skin has been set to: @1 (@2)=Ihr Aussehen wurde geändert auf: @1 (@2) -Skin of @1 set to: @2 (@3)=Aussehen von @1 gesetzt auf: @2 (@3) -Select player skin:=Spieleraussehen wählen: -@1 (@2)=@1 (@2) -Name: @1=Name: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr index dcd5c8438..840d1a520 100644 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.es.tr @@ -1,13 +1,14 @@ # textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Selecciona el skin tuyo o de otro jugador -Insufficient or wrong parameters=Parámetros insuficientes o incorrectos -Player @1 not online!=¡El jugador @1 no está en línea! -You need the “server” privilege to change the skin of other players!=¡Necesitas el privilegio de "servidor" para cambiar el aspecto de otros jugadores! -Invalid skin number! Valid numbers: 0 to @1=¡Número de piel no válido! Números válidos: 0 a @1 -Your skin has been set to: @1=Su skin se ha configurado a: @1 -Your skin has been set to: @1 (@2)=Su skin se ha configurado a: @1 (@2) -Skin of @1 set to: @2 (@3)=El skin de @1 se ha configurado a: @2 (@3) -Select player skin:=Selecciona el skin del jugador: -@1 (@2)=@1 (@2) -Name: @1=Nombre: @1 +Skins=Aspectos +Templates=Plantillas +Arm size=Tamaño de los brazos +Bases=Bases +Footwears=Calzado +Eyes=Ojos +Mouths=Bocas +Bottoms=Parte inferior +Tops=Parte superior +Hairs=Cabellos +Headwears=Accesorios para la cabeza +Open skin configuration screen.=Abrir pantalla de configuración de aspectos +Select=Seleccionar diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr index 146c6be5f..6eb0a17c2 100644 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.fr.tr @@ -1,14 +1,14 @@ # textdomain: mcl_skins -[] []=[] [] -Select player skin of yourself or another player=Sélectionner une apparence pour vous même ou un autre joueur -Insufficient or wrong parameters=Paramètres insuffisants ou incorrects -Player @1 not online!=Le joueur @1 n'est pas en ligne! -You need the “server” privilege to change the skin of other players!=Vous avez besoin du privilège “server” pour changer l'apparence des autres joueurs! -Invalid skin number! Valid numbers: 0 to @1=Numéro d'apparence incorrect! Numéros valides : 0 à @1 -Your skin has been set to: @1=Votre apparence a été définie à: @1 -Your skin has been set to: @1 (@2)=Votre apparence a été définie à: @1 (@2) -Skin of @1 set to: @2 (@3)=Apparence of @1 set to: @2 (@3)= -Select player skin:=Sélectionner l'apparence du joueur : -@1 (@2)=@1 (@2) -Name: @1=Nom : @ - +Skins=Costumes +Templates=Modèles +Arm size=Taille des bras +Bases=Teints +Footwears=Chaussures +Eyes=Yeux +Mouths=Bouches +Bottoms=Bas +Tops=Hauts +Hairs=Cheveux +Headwears=Coiffes +Open skin configuration screen.=Ouvrir l'écran de configuration du costume. +Select=Sélectionner \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr new file mode 100644 index 000000000..87361bb75 --- /dev/null +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.ja.tr @@ -0,0 +1,14 @@ +# textdomain: mcl_skins +Skins=スキン +Templates=テンプレート +Arm size=腕の大きさ +Bases=ベース +Footwears=靴 +Eyes=目 +Mouths=口 +Bottoms=下衣 +Tops=上衣 +Hairs=髪 +Headwears=帽子 +Open skin configuration screen.=スキン設定画面を開きます。 +Select=選択 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr deleted file mode 100644 index 58946f605..000000000 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.ms.tr +++ /dev/null @@ -1,16 +0,0 @@ -# textdomain: mcl_skins -# UNFINISHED translation! -# TODO: Remove the # sign from the translations below and add the missing translations. - -[] []= -Select player skin of yourself or another player= -Insufficient or wrong parameters= -Player @1 not online!= -You need the “server” privilege to change the skin of other players!= -Invalid skin number! Valid numbers: 0 to @1= -Your skin has been set to: @1= -Your skin has been set to: @1 (@2)= -Skin of @1 set to: @2 (@3)= -Select player skin:=Pilih Kulit Pemain: -@1 (@2)= -Name: @1=Nama: @1 diff --git a/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr b/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr index 64eab0e3f..fda9330d6 100644 --- a/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr +++ b/mods/PLAYER/mcl_skins/locale/mcl_skins.ru.tr @@ -1,13 +1,14 @@ # textdomain: mcl_skins -[] []=[<игрок>] [<номер скина>] -Select player skin of yourself or another player=Выберите скин для себя или для другого игрока -Insufficient or wrong parameters=Недопустимые или неправильные параметры -Player @1 not online!=Игрок @1 не в сети! -You need the “server” privilege to change the skin of other players!=Для смены скинов другим игрокам у вас должна быть привилегия “server”! -Invalid skin number! Valid numbers: 0 to @1=Недопустимый номер скина! Правильные номера: от 0 до @1 -Your skin has been set to: @1=Ваш скин выбран: @1 -Your skin has been set to: @1 (@2)=Ваш скин установлен: @1 (@2) -Skin of @1 set to: @2 (@3)=Скин игрока @1 установлен: @2 (@3) -Select player skin:=Выбор скина игрока: -@1 (@2)=@1 (@2) -Name: @1=Имя: @1 +Skins=Облики +Templates=Образцы +Arm size=Толщина рук +Bases=Цвета кожи +Footwears=Обувь +Eyes=Глаза +Mouths=Рты +Bottoms=Ноги +Tops=Туловища +Hairs=Причёски +Headwears=Головные уборы +Open skin configuration screen.=Открыть экран настройки облика. +Select=Выбрать diff --git a/mods/PLAYER/mcl_skins/locale/template.txt b/mods/PLAYER/mcl_skins/locale/template.txt index c683fa4e4..c39d4066d 100644 --- a/mods/PLAYER/mcl_skins/locale/template.txt +++ b/mods/PLAYER/mcl_skins/locale/template.txt @@ -1,13 +1,14 @@ # textdomain: mcl_skins -[] []= -Select player skin of yourself or another player= -Insufficient or wrong parameters= -Player @1 not online!= -You need the “server” privilege to change the skin of other players!= -Invalid skin number! Valid numbers: 0 to @1= -Your skin has been set to: @1= -Your skin has been set to: @1 (@2)= -Skin of @1 set to: @2 (@3)= -Select player skin:= -@1 (@2)= -Name: @1= +Skins= +Templates= +Arm size= +Bases= +Footwears= +Eyes= +Mouths= +Bottoms= +Tops= +Hairs= +Headwears= +Open skin configuration screen.= +Select= \ No newline at end of file diff --git a/mods/PLAYER/mcl_skins/media_credits.txt b/mods/PLAYER/mcl_skins/media_credits.txt new file mode 100644 index 000000000..de32368e9 --- /dev/null +++ b/mods/PLAYER/mcl_skins/media_credits.txt @@ -0,0 +1,111 @@ +mcl_skins_base_1.png +mcl_skins_button.png +mcl_skins_footwear_3.png +mcl_skins_headgear_1.png +mcl_skins_headgear_3.png +mcl_skins_headgear_4.png +mcl_skins_headgear_5.png +mcl_skins_mouth_2.png +mcl_skins_mouth_3.png +mcl_skins_mouth_4.png +mcl_skins_mouth_5.png +mcl_skins_select_overlay.png +mcl_skins_slim_arms.png +mcl_skins_thick_arms.png +mcl_skins_top_2.png +mcl_skins_top_5.png +mcl_skins_eye_5.png +mcl_skins_hair_8.png +mcl_skins_top_6.png +mcl_skins_bottom_3.png +mcl_skins_eye_7.png +mcl_skins_mouth_7.png +mcl_skins_hair_10.png +mcl_skins_hair_6.png +mcl_skins_eye_6.png +mcl_skins_bottom_5.png +Original work by MrRar +License: CC BY-SA 4.0 + +mcl_skins_top_1.png +mcl_skins_mouth_1.png +mcl_skins_hair_1.png +mcl_skins_hair_2.png +mcl_skins_eye_1.png +mcl_skins_eye_2.png +mcl_skins_footwear_1.png +mcl_skins_headgear_2.png +mcl_skins_mouth_1.png +mcl_skins_top_1.png +mcl_skins_mouth_2.png +Name: Pixel Perfection resource pack for Minecraft 1.11 +Author: XSSheep. Adapted for mcl_skins by MrRar. +License: CC BY-SA 4.0 +Source: https://www.planetminecraft.com/texture_pack/131pixel-perfection/ + +mcl_skins_hair_3.png +mcl_skins_eye_3.png +mcl_skins_footwear_2.png +Name: the 10the doctor +Author: lovehart. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:367 + +mcl_skins_hair_4.png +Blonde Girl +Author: Rin. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=918 + +mcl_skins_hair_5.png +Name: hobbit from lottmob +Author: lovehart. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=336 + +mcl_skins_top_4.png +Name: Oliver_MV +Author: hansuke123. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:291 + +mcl_skins_eye_4.png +Name: lisa +Author: hansuke123 +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#!page:1,filtertype:Id,filter:88 + +mcl_skins_headwear_7.png +Name: Ryu +Author: Ginsu23. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=464 + +mcl_skins_top_8.png +Name: Hoodie Enderman +Author: Kpenguin. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=962 + +mcl_skins_hair_9.png +Name: Trader 1 +Author: TenPlus1. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: http://minetest.fensta.bplaced.net/#id=1258 + +mcl_skins_bottom_4.png +mcl_skins_top_9.png +mcl_skins_top_10.png +mcl_skins_hair_11.png +Name: Pixel Perfection Legacy 1.19 +Author: Nova_Wostra. Adapted for mcl_skins by MrRar. +License: CC BY-SA 4.0 +Source: https://www.planetminecraft.com/texture-pack/pixel-perfection-chorus-edit/ + +mcl_skins_bottom.obj +mcl_skins_head.obj +mcl_skins_top.obj +Name: character.blend in player_api mod from Minetest Game +Author: celeron55, MirceaKitsune, Jordach, kilbith, sofar, xunto, Rogier-5, TeTpaAka, Desour, stujones11, An0n3m0us. Adapted for mcl_skins by MrRar. +License: CC BY-SA 3.0 +Source: https://github.com/minetest/minetest_game diff --git a/mods/PLAYER/mcl_skins/mesh_hand.lua b/mods/PLAYER/mcl_skins/mesh_hand.lua new file mode 100644 index 000000000..a1d6c0903 --- /dev/null +++ b/mods/PLAYER/mcl_skins/mesh_hand.lua @@ -0,0 +1,64 @@ +local function make_texture(base, colorspec) + local output = "" + if mcl_skins.masks[base] then + output = mcl_skins.masks[base] .. + "^[colorize:" .. minetest.colorspec_to_colorstring(colorspec) .. ":alpha" + end + if #output > 0 then output = output .. "^" end + output = output .. base + return output +end + +function mcl_skins.get_skin_list() + local list = {} + for _, game_mode in pairs({"_crea", "_surv"}) do + for _, base in pairs(mcl_skins.base) do + for _, base_color in pairs(mcl_skins.base_color) do + local id = base:gsub(".png$", "") + .. minetest.colorspec_to_colorstring(base_color):gsub("#", "") + + local female = { + texture = make_texture(base, base_color), + slim_arms = true, + id = id .. "_female" .. game_mode, + creative = game_mode == "_crea" + } + table.insert(list, female) + + local male = { + texture = make_texture(base, base_color), + slim_arms = false, + id = id .. "_male" .. game_mode, + creative = game_mode == "_crea" + } + table.insert(list, male) + end + end + for _, skin in pairs(mcl_skins.simple_skins) do + table.insert(list, { + texture = skin.texture, + slim_arms = skin.slim_arms, + id = skin.texture:gsub(".png$", "") + .. (skin.slim_arms and "_female" or "_male") .. game_mode, + creative = game_mode == "_crea" + }) + end + end + return list +end + +function mcl_skins.get_node_id_by_player(player) + local skin = mcl_skins.player_skins[player] + local simple_skin = skin.simple_skins_id + if simple_skin then + skin = mcl_skins.texture_to_simple_skin[skin.simple_skins_id] + end + local creative = minetest.is_creative_enabled(player:get_player_name()) + local append = (skin.slim_arms and "_female" or "_male") .. (creative and "_crea" or "_surv") + if simple_skin then + return skin.texture:gsub(".png$", "") .. append + else + return skin.base:gsub(".png$", "") .. + minetest.colorspec_to_colorstring(skin.base_color):gsub("#", "") .. append + end +end diff --git a/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt b/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt deleted file mode 100644 index 00061a654..000000000 --- a/mods/PLAYER/mcl_skins/meta/mcl_skins_character.txt +++ /dev/null @@ -1,2 +0,0 @@ -name = "Steve", -author = "%TEXTURE_PACK_AUTHOR%", diff --git a/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt b/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt deleted file mode 100644 index f96b13f68..000000000 --- a/mods/PLAYER/mcl_skins/meta/mcl_skins_character_1.txt +++ /dev/null @@ -1,2 +0,0 @@ -name = "Alex", -author = "%TEXTURE_PACK_AUTHOR%", diff --git a/mods/PLAYER/mcl_skins/mod.conf b/mods/PLAYER/mcl_skins/mod.conf index 96f827646..bd2191097 100644 --- a/mods/PLAYER/mcl_skins/mod.conf +++ b/mods/PLAYER/mcl_skins/mod.conf @@ -1 +1,4 @@ name = mcl_skins +author = MrRar +description = Advanced player skin customization. +depends = mcl_player diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj new file mode 100644 index 000000000..bc12779af --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_bottom.obj @@ -0,0 +1,108 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib bottom.mtl +o bottom +v -2.100000 4.358421 1.050001 +v -2.100000 1.648314 1.049999 +v 2.100000 1.648314 1.049999 +v 2.100000 4.358421 1.050001 +v -2.100000 1.648314 -1.050001 +v -2.100000 4.358421 -1.049998 +v 2.100000 1.648314 -1.050001 +v 2.100000 4.358421 -1.049998 +v 0.000000 1.648314 -1.050001 +v 0.000000 -4.651686 -1.050003 +v 0.000000 -4.651686 1.049997 +v 0.000000 1.648314 1.049999 +v 0.000000 -4.651686 -1.050003 +v 0.000000 -4.651686 1.049997 +v -2.100000 -4.651685 1.049997 +v -2.100000 -4.651685 -1.050003 +v -2.100000 1.648315 1.049999 +v -2.100000 1.648315 -1.050001 +v 0.000000 1.648314 1.049999 +v 2.100000 1.648315 -1.050001 +v 2.100000 -4.651685 -1.050003 +v 0.000000 1.648314 -1.050001 +v 2.100000 -4.651685 1.049997 +v 2.100000 1.648315 1.049999 +vt 0.500000 0.161316 +vt 0.500000 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.161316 +vt 0.437500 0.000000 +vt 0.437500 0.161316 +vt 0.312500 0.000000 +vt 0.312500 0.161316 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.187500 0.000000 +vt 0.187500 0.375000 +vt 0.187500 0.375000 +vt 0.187500 0.500000 +vt 0.125000 0.500000 +vt 0.125000 0.375000 +vt 0.000000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.000000 0.000000 +vt 0.187500 0.375000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.187500 0.000000 +vt 0.062500 0.375000 +vt 0.062500 0.000000 +vt 0.125000 0.375000 +vt 0.125000 0.000000 +vt 0.250000 0.000000 +vt 0.250000 0.375000 +vt 0.000000 0.375000 +vt 0.000000 0.000000 +vt 0.250000 0.161316 +vt 0.250000 0.000000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.062500 0.500000 +vt 0.062500 0.375000 +vt 0.187500 0.375000 +vt 0.125000 0.375000 +vt 0.125000 0.500000 +vt 0.187500 0.500000 +vt 0.125000 0.375000 +vt 0.062500 0.375000 +vt 0.062500 0.500000 +vt 0.125000 0.500000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +vt 0.000000 1.000000 +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 1.0000 0.0000 0.0000 +vn 0.0000 1.0000 0.0000 +usemtl Character +s 1 +f 1/1/1 2/2/1 3/3/1 4/4/1 +f 5/5/2 2/2/2 1/1/2 6/6/2 +f 7/7/3 5/5/3 6/6/3 8/8/3 +f 7/9/4 3/10/4 2/11/4 5/12/4 +f 9/13/2 10/14/2 11/15/2 12/16/2 +f 13/17/4 14/18/4 15/19/4 16/20/4 +f 17/21/2 18/22/2 16/23/2 15/24/2 +f 19/25/1 17/26/1 15/27/1 14/28/1 +f 20/29/3 21/30/3 10/14/3 9/13/3 +f 18/22/3 22/31/3 13/32/3 16/23/3 +f 12/16/1 11/15/1 23/33/1 24/34/1 +f 22/31/5 19/25/5 14/28/5 13/32/5 +f 24/35/5 23/36/5 21/30/5 20/29/5 +f 4/37/5 3/38/5 7/7/5 8/8/5 +f 18/39/6 17/40/6 19/41/6 22/42/6 +f 10/43/4 21/44/4 23/45/4 11/46/4 +f 20/47/6 9/48/6 12/49/6 24/50/6 +f 4/51/6 8/52/6 6/53/6 1/54/6 diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj new file mode 100644 index 000000000..226a0d9bb --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_head.obj @@ -0,0 +1,72 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib head.mtl +o head +v -2.100000 -2.100004 2.099999 +v 2.100000 2.099997 -2.100001 +v 2.100000 2.099997 2.099999 +v 2.300000 -2.300003 -2.300001 +v 2.300000 2.299997 2.299999 +v 2.100000 -2.100004 2.099999 +v 2.100000 -2.100004 -2.100001 +v -2.100000 2.099997 2.099999 +v -2.100000 2.099997 -2.100001 +v -2.100000 -2.100004 -2.100001 +v 2.300000 2.299997 -2.300001 +v 2.300000 -2.300003 2.299999 +v -2.300000 2.299997 2.299999 +v -2.300000 -2.300003 2.299999 +v -2.300000 2.299997 -2.300001 +v -2.300000 -2.300003 -2.300001 +vt 0.500000 0.750000 +vt 0.375000 0.750000 +vt 0.375000 0.500000 +vt 0.500000 0.500000 +vt 0.250000 0.750000 +vt 0.250000 0.500000 +vt 0.125000 0.750000 +vt 0.125000 0.500000 +vt 0.375000 0.750000 +vt 0.375000 1.000000 +vt 0.250000 1.000000 +vt 0.250000 0.750000 +vt 0.250000 1.000000 +vt 0.125000 1.000000 +vt 0.000000 0.750000 +vt 0.000000 0.500000 +vt 1.000000 0.750000 +vt 0.875000 0.750000 +vt 0.875000 0.500000 +vt 1.000000 0.500000 +vt 0.750000 0.750000 +vt 0.750000 0.500000 +vt 0.625000 0.750000 +vt 0.625000 0.500000 +vt 0.875000 0.750000 +vt 0.875000 1.000000 +vt 0.750000 1.000000 +vt 0.750000 0.750000 +vt 0.750000 1.000000 +vt 0.625000 1.000000 +vt 0.500000 0.750000 +vt 0.500000 0.500000 +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 +vn 1.0000 0.0000 0.0000 +usemtl Character +s off +f 3/1/1 8/2/1 1/3/1 6/4/1 +f 8/2/2 9/5/2 10/6/2 1/3/2 +f 9/5/3 2/7/3 7/8/3 10/6/3 +f 7/9/4 6/10/4 1/11/4 10/12/4 +f 9/5/5 8/13/5 3/14/5 2/7/5 +f 3/15/6 6/16/6 7/8/6 2/7/6 +f 5/17/1 13/18/1 14/19/1 12/20/1 +f 13/18/2 15/21/2 16/22/2 14/19/2 +f 15/21/3 11/23/3 4/24/3 16/22/3 +f 4/25/4 12/26/4 14/27/4 16/28/4 +f 15/21/5 13/29/5 5/30/5 11/23/5 +f 5/31/6 12/32/6 4/24/6 11/23/6 diff --git a/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj b/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj new file mode 100644 index 000000000..845c7019a --- /dev/null +++ b/mods/PLAYER/mcl_skins/models/mcl_skins_top.obj @@ -0,0 +1,174 @@ +# Blender v2.93.5 OBJ File: '' +# www.blender.org +mtllib top.mtl +o top +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 -1.050001 +v -2.100000 3.150004 1.049999 +v -2.100000 3.150004 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 3.150003 1.049999 +v -2.100000 3.150003 1.049999 +v -2.100000 3.150003 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -4.200000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 1.049999 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 -3.149994 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 1.049999 +v 4.200000 3.150003 1.049999 +v 4.200000 3.150003 -1.050001 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 -1.050001 +v 2.100000 3.150004 1.049999 +v 2.100000 3.150004 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v -2.100000 3.150004 1.049999 +v -2.100000 3.150004 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 3.150004 -1.050001 +v -2.100000 3.150004 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 3.150003 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -4.200000 -3.149994 -1.050001 +v -2.100000 3.150003 1.049999 +v -2.100000 3.150003 1.049999 +v -2.100000 -3.149994 1.049999 +v -2.100000 -3.149994 1.049999 +v -4.200000 3.150003 1.049999 +v -4.200000 3.150003 1.049999 +v -4.200000 -3.149994 1.049999 +v -4.200000 -3.149994 1.049999 +v -2.100000 3.150003 -1.050001 +v -2.100000 3.150003 -1.050001 +v -2.100000 -3.149994 -1.050001 +v -2.100000 -3.149994 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 -1.050001 +v 2.100000 3.150003 1.049999 +v 2.100000 3.150003 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 1.049999 +v 2.100000 -3.149994 -1.050001 +v 2.100000 -3.149994 -1.050001 +v 4.200000 3.150003 1.049999 +v 4.200000 3.150003 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 -3.149994 1.049999 +v 4.200000 3.150003 -1.050001 +v 4.200000 3.150003 -1.050001 +v 4.200000 -3.149994 -1.050001 +v 4.200000 -3.149994 -1.050001 +vt 0.625000 0.375000 +vt 0.500000 0.375000 +vt 0.500000 0.000000 +vt 0.625000 0.000000 +vt 0.500000 0.375000 +vt 0.437500 0.375000 +vt 0.437500 0.000000 +vt 0.500000 0.000000 +vt 0.437500 0.375000 +vt 0.312500 0.375000 +vt 0.312500 0.000000 +vt 0.437500 0.000000 +vt 0.562500 0.375000 +vt 0.562500 0.500000 +vt 0.437500 0.500000 +vt 0.437500 0.375000 +vt 0.437500 0.375000 +vt 0.437500 0.500000 +vt 0.312500 0.500000 +vt 0.312500 0.375000 +vt 0.812500 0.375000 +vt 0.875000 0.375000 +vt 0.875000 0.000000 +vt 0.812500 0.000000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.750000 0.000000 +vt 0.750000 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.500000 +vt 0.750000 0.500000 +vt 0.687500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.687500 0.500000 +vt 0.250000 0.375000 +vt 0.250000 0.000000 +vt 0.312500 0.000000 +vt 0.312500 0.375000 +vt 0.687500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.000000 +vt 0.687500 0.000000 +vt 0.625000 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.625000 0.000000 +vt 0.625000 0.375000 +vt 0.625000 0.000000 +vt 0.687500 0.000000 +vt 0.687500 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.500000 +vt 0.750000 0.500000 +vt 0.750000 0.375000 +vt 0.687500 0.375000 +vt 0.687500 0.000000 +vt 0.750000 0.000000 +vt 0.750000 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.000000 +vt 0.812500 0.000000 +vt 0.812500 0.375000 +vt 0.750000 0.375000 +vt 0.750000 0.500000 +vt 0.812500 0.500000 +vt 0.812500 0.375000 +vt 0.812500 0.375000 +vt 0.812500 0.000000 +vt 0.875000 0.000000 +vt 0.875000 0.375000 +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 +vn 1.0000 0.0000 0.0000 +usemtl Character +s off +f 27/1/1 3/2/1 1/3/1 14/4/1 +f 33/5/2 4/6/2 2/7/2 35/8/2 +f 37/9/3 25/10/3 31/11/3 39/12/3 +f 13/13/4 29/14/4 36/15/4 40/16/4 +f 38/17/5 34/18/5 16/19/5 15/20/5 +f 7/21/1 6/22/1 10/23/1 11/24/1 +f 8/25/6 45/26/6 47/27/6 12/28/6 +f 17/29/4 20/30/4 19/31/4 18/32/4 +f 24/33/5 21/34/5 22/35/5 23/36/5 +f 28/37/6 30/38/6 32/39/6 26/40/6 +f 5/41/3 53/42/3 55/43/3 9/44/3 +f 49/45/2 41/46/2 43/47/2 51/48/2 +f 65/49/6 67/50/6 71/51/6 69/52/6 +f 42/53/5 50/54/5 46/55/5 54/56/5 +f 70/57/3 72/58/3 63/59/3 57/60/3 +f 58/61/2 64/62/2 61/63/2 59/64/2 +f 56/65/4 48/66/4 52/67/4 44/68/4 +f 60/69/1 62/70/1 68/71/1 66/72/1 diff --git a/mods/PLAYER/mcl_skins/simple_skins.lua b/mods/PLAYER/mcl_skins/simple_skins.lua new file mode 100644 index 000000000..3e08c0cb7 --- /dev/null +++ b/mods/PLAYER/mcl_skins/simple_skins.lua @@ -0,0 +1,47 @@ +local function init_simple_skins() + local id, f, data, skin = 2 + local mod_path = minetest.get_modpath("mcl_skins") + while true do + + if id == 0 then + skin = "character.png" + else + skin = "mcl_skins_character_" .. id .. ".png" + + -- Does skin file exist? + f = io.open(mod_path .. "/textures/" .. skin) + + -- escape loop if not found + if not f then + break + end + f:close() + end + + local metafile + + -- does metadata exist for that skin file ? + if id == 0 then + metafile = "mcl_skins_character.txt" + else + metafile = "mcl_skins_character_"..id..".txt" + end + f = io.open(mod_path .. "/meta/" .. metafile) + + data = nil + if f then + data = minetest.deserialize("return {" .. f:read("*all") .. "}") + f:close() + end + + -- add metadata to list + mcl_skins.register_simple_skin({ + index = id, + texture = skin, + slim_arms = data and data.gender == "female", + }) + id = id + 1 + end +end + +init_simple_skins() diff --git a/mods/PLAYER/mcl_skins/textures/README.txt b/mods/PLAYER/mcl_skins/textures/README.txt new file mode 100644 index 000000000..8b50278d3 --- /dev/null +++ b/mods/PLAYER/mcl_skins/textures/README.txt @@ -0,0 +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. diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png deleted file mode 100644 index 49acf8550..000000000 Binary files a/mods/PLAYER/mcl_skins/textures/mcl_skins_button.png and /dev/null differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_character_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_character_1.png deleted file mode 100644 index 71f02471d..000000000 Binary files a/mods/PLAYER/mcl_skins/textures/mcl_skins_character_1.png and /dev/null differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_player_1.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_player_1.png deleted file mode 100644 index 3d7af2a98..000000000 Binary files a/mods/PLAYER/mcl_skins/textures/mcl_skins_player_1.png and /dev/null differ diff --git a/mods/PLAYER/mcl_skins/textures/mcl_skins_player_dummy.png b/mods/PLAYER/mcl_skins/textures/mcl_skins_player_dummy.png deleted file mode 100644 index d1f7dc20a..000000000 Binary files a/mods/PLAYER/mcl_skins/textures/mcl_skins_player_dummy.png and /dev/null differ diff --git a/mods/PLAYER/mcl_spawn/depends.txt b/mods/PLAYER/mcl_spawn/depends.txt deleted file mode 100644 index 3b355984e..000000000 --- a/mods/PLAYER/mcl_spawn/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_init diff --git a/mods/PLAYER/mcl_spawn/description.txt b/mods/PLAYER/mcl_spawn/description.txt deleted file mode 100644 index 6712e4432..000000000 --- a/mods/PLAYER/mcl_spawn/description.txt +++ /dev/null @@ -1 +0,0 @@ -Set and get the player's respawn position diff --git a/mods/PLAYER/mcl_spawn/init.lua b/mods/PLAYER/mcl_spawn/init.lua index 5a4f3d634..eb0208dcb 100644 --- a/mods/PLAYER/mcl_spawn/init.lua +++ b/mods/PLAYER/mcl_spawn/init.lua @@ -1,9 +1,13 @@ mcl_spawn = {} -local S = minetest.get_translator("mcl_spawn") +local S = minetest.get_translator(minetest.get_current_modname()) local mg_name = minetest.get_mapgen_setting("mg_name") local storage = minetest.get_mod_storage() +local function mcl_log (message) + mcl_util.mcl_log (message, "[Spawn]") +end + -- Parameters ------------- @@ -81,13 +85,7 @@ local dir_step = storage:get_int("mcl_spawn_dir_step") or 0 local dir_ind = storage:get_int("mcl_spawn_dir_ind") or 1 local emerge_pos1, emerge_pos2 --- Get world 'mapgen_limit' and 'chunksize' to calculate 'spawn_limit'. --- This accounts for how mapchunks are not generated if they or their shell exceed --- 'mapgen_limit'. - -local mapgen_limit = tonumber(minetest.get_mapgen_setting("mapgen_limit")) -local chunksize = tonumber(minetest.get_mapgen_setting("chunksize")) -local spawn_limit = math.max(mapgen_limit - (chunksize + 1) * 16, 0) +local spawn_limit = mcl_vars.mapgen_edge_max --Functions @@ -385,7 +383,11 @@ function mcl_spawn.search() end -mcl_spawn.get_world_spawn_pos = function() +function mcl_spawn.get_world_spawn_pos() + local ssp = minetest.setting_get_pos("static_spawnpoint") + if ssp then + return ssp + end if success then return wsp end @@ -397,11 +399,11 @@ end -- If player is nil or not a player, a world spawn point is returned. -- The second return value is true if returned spawn point is player-chosen, -- false otherwise. -mcl_spawn.get_bed_spawn_pos = function(player) +function mcl_spawn.get_bed_spawn_pos(player) local spawn, custom_spawn = nil, false - if player ~= nil and player:is_player() then + if player and player:is_player() then local attr = player:get_meta():get_string("mcl_beds:spawn") - if attr ~= nil and attr ~= "" then + if attr and attr ~= "" then spawn = minetest.string_to_pos(attr) custom_spawn = true end @@ -417,7 +419,7 @@ end -- Set pos to nil to clear the spawn position. -- If message is set, informs the player with a chat message when the spawn position -- changed. -mcl_spawn.set_spawn_pos = function(player, pos, message) +function mcl_spawn.set_spawn_pos(player, pos, message) local spawn_changed = false local meta = player:get_meta() if pos == nil then @@ -431,6 +433,43 @@ mcl_spawn.set_spawn_pos = function(player, pos, message) else local oldpos = minetest.string_to_pos(meta:get_string("mcl_beds:spawn")) meta:set_string("mcl_beds:spawn", minetest.pos_to_string(pos)) + + -- Set player ownership on bed + local bed_node = minetest.get_node(pos) + local bed_meta = minetest.get_meta(pos) + + local bed_bottom = mcl_beds.get_bed_bottom (pos) + local bed_bottom_meta = minetest.get_meta(bed_bottom) + + if bed_meta then + if bed_node then + mcl_log("Bed name: " .. bed_node.name) + end + + mcl_log("Setting bed meta: " .. player:get_player_name()) + bed_meta:set_string("player", player:get_player_name()) + + -- Pass in villager as arg. Shouldn't know about villagers + if bed_bottom_meta then + mcl_log("Removing villager from bed bottom meta") + bed_bottom_meta:set_string("villager", nil) + else + mcl_log("Cannot remove villager from bed bottom meta") + end + + + + if oldpos and oldpos ~= pos then + local old_bed_meta = minetest.get_meta(oldpos) + if old_bed_meta then + mcl_log("Removing old bed meta") + old_bed_meta:set_string("player", "") + end + else + mcl_log("No old bed meta to remove or same as current") + end + end + if oldpos then -- We don't bother sending a message if the new spawn pos is basically the same spawn_changed = vector.distance(pos, oldpos) > 0.1 @@ -445,7 +484,7 @@ mcl_spawn.set_spawn_pos = function(player, pos, message) return spawn_changed end -mcl_spawn.get_player_spawn_pos = function(player) +function mcl_spawn.get_player_spawn_pos(player) local pos, custom_spawn = mcl_spawn.get_bed_spawn_pos(player) if pos and custom_spawn then -- Check if bed is still there @@ -453,13 +492,34 @@ mcl_spawn.get_player_spawn_pos = function(player) local bgroup = minetest.get_item_group(node_bed.name, "bed") if bgroup ~= 1 and bgroup ~= 2 then -- Bed is destroyed: - if player ~= nil and player:is_player() then - player:get_meta():set_string("mcl_beds:spawn", "") + if player and player:is_player() then + local checkpos = minetest.string_to_pos(player:get_meta():get_string("mcl_beds:spawn")) + local checknode = minetest.get_node(checkpos) + + 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 + 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!")) + return mcl_spawn.get_world_spawn_pos(), false + elseif charge_level ~= 1 then + minetest.set_node(checkpos, {name="mcl_beds:respawn_anchor_charged_".. charge_level-1}) + return checkpos, false + else + minetest.set_node(checkpos, {name="mcl_beds:respawn_anchor"}) + return checkpos, false + end + else + 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 + end end - minetest.chat_send_player(player:get_player_name(), S("Your spawn bed was missing or blocked.")) - return mcl_spawn.get_world_spawn_pos(), false end + + -- Find spawning position on/near the bed free of solid or damaging blocks iterating a square spiral 15x15: local dir = minetest.facedir_to_dir(minetest.get_node(pos).param2) @@ -484,7 +544,7 @@ mcl_spawn.get_player_spawn_pos = function(player) return mcl_spawn.get_world_spawn_pos(), false end -mcl_spawn.spawn = function(player) +function mcl_spawn.spawn(player) local pos, in_bed = mcl_spawn.get_player_spawn_pos(player) player:set_pos(pos) return in_bed or success @@ -499,10 +559,15 @@ function mcl_spawn.shadow_worker() mcl_spawn.search() minetest.log("action", "[mcl_spawn] Started world spawn point search") end - if success and ((not good_for_respawn(wsp)) or (not can_find_tree(wsp))) then - success = false - minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp)) - mcl_spawn.search() + + if success then + local wsp_node = minetest.get_node(wsp) + if not (wsp_node and wsp_node.name == "ignore") + and ((not good_for_respawn(wsp)) or ((no_trees_area_counter >= 0) and not can_find_tree(wsp))) then + success = false + minetest.log("action", "[mcl_spawn] World spawn position isn't safe anymore: "..minetest.pos_to_string(wsp)) + mcl_spawn.search() + end end minetest.after(respawn_search_interval, mcl_spawn.shadow_worker) diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.de.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.de.tr index e30a71650..57d32a5f7 100644 --- a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.de.tr +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.de.tr @@ -1,4 +1,5 @@ # textdomain: mcl_spawn New respawn position set!=Neue Wiedereinstiegsposition gesetzt! Respawn position cleared!=Wiedereinstiegsposition gelöscht! -Your spawn bed was missing or blocked.=Ihr Startbett fehlte oder war blockiert. +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=Ihr Startbett fehlte oder war blockiert, und Sie hatten keinen geladenen Seelenanker! +Couldn't get level of your respawn anchor!=Das Füllstand ihres Seelenankers konnte nicht erkannt werden! \ No newline at end of file diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr index f1fab2bf1..a833f8ad0 100644 --- a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.fr.tr @@ -1,4 +1,5 @@ # textdomain: mcl_spawn -New respawn position set!=Nouvelle position de réapparition définie! -Respawn position cleared!=Position de réapparition supprimée! -Your spawn bed was missing or blocked.=Votre lit d'apparition était manquant ou bloqué. +New respawn position set!=Nouvelle position de réapparition définie ! +Respawn position cleared!=Position de réapparition supprimée ! +Couldn't get level of your respawn anchor!=Impossible d'obtenir le niveau de votre ancre de réapparition ! +Your spawn bed was missing or blocked, and you had no charged respawn anchor!=Votre lit d'apparition était manquant ou bloqué, et vous n'avez pas d'ancre de réapparition chargée ! diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr new file mode 100644 index 000000000..079683f68 --- /dev/null +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.ja.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_spawn +New respawn position set!=新しいリスポーン位置を設定しました! +Respawn position cleared!=リスポーン位置をクリアしました! +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_spawn/locale/mcl_spawn.pl.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.pl.tr new file mode 100644 index 000000000..df97a3d72 --- /dev/null +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.pl.tr @@ -0,0 +1,5 @@ +# textdomain: mcl_spawn +New respawn position set!=Ustawiono nową pozycję odradzania! +Respawn position cleared!=Usunięto pozycję odradzania! +Your spawn bed was missing or blocked.=Twoje łóżko odradzania zginęło lub zostało zablokowane. + diff --git a/mods/PLAYER/mcl_spawn/locale/mcl_spawn.zh_TW.tr b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.zh_TW.tr new file mode 100644 index 000000000..f47d22c2d --- /dev/null +++ b/mods/PLAYER/mcl_spawn/locale/mcl_spawn.zh_TW.tr @@ -0,0 +1,4 @@ +# textdomain: mcl_spawn +New respawn position set!=新重生點已設定! +Respawn position cleared!=重生點已清除! +Your spawn bed was missing or blocked.=你的床被破壞或被堵住了。 diff --git a/mods/PLAYER/mcl_spawn/locale/template.txt b/mods/PLAYER/mcl_spawn/locale/template.txt index 8906d18f9..aa8aafe8d 100644 --- a/mods/PLAYER/mcl_spawn/locale/template.txt +++ b/mods/PLAYER/mcl_spawn/locale/template.txt @@ -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_spawn/mod.conf b/mods/PLAYER/mcl_spawn/mod.conf index ff54191b2..954f831db 100644 --- a/mods/PLAYER/mcl_spawn/mod.conf +++ b/mods/PLAYER/mcl_spawn/mod.conf @@ -1 +1,4 @@ name = mcl_spawn +author = Wuzzy +description = Set and get the player's respawn position +depends = mcl_init diff --git a/mods/PLAYER/mcl_sprint/depends.txt b/mods/PLAYER/mcl_sprint/depends.txt deleted file mode 100644 index aa6711ef0..000000000 --- a/mods/PLAYER/mcl_sprint/depends.txt +++ /dev/null @@ -1,3 +0,0 @@ -mcl_playerinfo -playerphysics -mcl_hunger diff --git a/mods/PLAYER/mcl_sprint/init.lua b/mods/PLAYER/mcl_sprint/init.lua index 9e7690f4b..7449ad18c 100644 --- a/mods/PLAYER/mcl_sprint/init.lua +++ b/mods/PLAYER/mcl_sprint/init.lua @@ -7,6 +7,22 @@ to this software to the public domain worldwide. This software is distributed without any warranty. ]] +local math = math +local vector = vector + +local pairs = pairs + +local get_node = minetest.get_node +local get_gametime = minetest.get_gametime +local add_particlespawner = minetest.add_particlespawner +local get_player_by_name = minetest.get_player_by_name + +local registered_nodes = minetest.registered_nodes + +local get_hunger = mcl_hunger.get_hunger +local exhaust = mcl_hunger.exhaust + + --Configuration variables, these are all explained in README.md mcl_sprint = {} @@ -16,7 +32,7 @@ local players = {} -- Returns true if the player with the given name is sprinting, false if not. -- Returns nil if player does not exist. -mcl_sprint.is_sprinting = function(playername) +function mcl_sprint.is_sprinting(playername) if players[playername] then return players[playername].sprinting else @@ -31,9 +47,11 @@ minetest.register_on_joinplayer(function(player) sprinting = false, timeOut = 0, shouldSprint = false, + clientSprint = false, lastPos = player:get_pos(), sprintDistance = 0, - fov = 1.0 + fov = 1.0, + channel = minetest.mod_channel_join("mcl_sprint:" .. playerName), } end) minetest.register_on_leaveplayer(function(player) @@ -41,18 +59,45 @@ minetest.register_on_leaveplayer(function(player) players[playerName] = nil end) +local function cancelClientSprinting(name) + players[name].channel:send_all("") + players[name].clientSprint = false +end + 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 - if sprinting == true then - players[playerName].fov = math.min(players[playerName].fov + 0.05, 1.2) - player:set_fov(players[playerName].fov, true, 0.15) - playerphysics.add_physics_factor(player, "speed", "mcl_sprint:sprint", mcl_sprint.SPEED) - elseif sprinting == false then - players[playerName].fov = math.max(players[playerName].fov - 0.05, 1.0) - player:set_fov(players[playerName].fov, true, 0.15) - playerphysics.remove_physics_factor(player, "speed", "mcl_sprint:sprint") + 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) end return true end @@ -97,17 +142,27 @@ local function get_top_node_tile(param2, paramtype2) end end +minetest.register_on_modchannel_message(function(channel_name, sender, message) + if channel_name == "mcl_sprint:" .. sender then + players[sender].clientSprint = minetest.is_yes(message) + end +end) + +minetest.register_on_respawnplayer(function(player) + cancelClientSprinting(player:get_player_name()) +end) + minetest.register_globalstep(function(dtime) --Get the gametime - local gameTime = minetest.get_gametime() + local gameTime = get_gametime() --Loop through all connected players - for playerName,playerInfo in pairs(players) do - local player = minetest.get_player_by_name(playerName) - if player ~= nil then + for playerName, playerInfo in pairs(players) do + local player = get_player_by_name(playerName) + if player then local ctrl = player:get_player_control() --Check if the player should be sprinting - if ctrl.aux1 and ctrl.up and not ctrl.sneak then + if players[playerName]["clientSprint"] or ctrl.aux1 and ctrl.up and not ctrl.sneak then players[playerName]["shouldSprint"] = true else players[playerName]["shouldSprint"] = false @@ -115,23 +170,22 @@ minetest.register_globalstep(function(dtime) local playerPos = player:get_pos() --If the player is sprinting, create particles behind and cause exhaustion - if playerInfo["sprinting"] == true and gameTime % 0.1 == 0 then - + if playerInfo["sprinting"] == true and not player:get_attach() and gameTime % 0.1 == 0 then -- Exhaust player for sprinting local lastPos = players[playerName].lastPos local dist = vector.distance({x=lastPos.x, y=0, z=lastPos.z}, {x=playerPos.x, y=0, z=playerPos.z}) players[playerName].sprintDistance = players[playerName].sprintDistance + dist if players[playerName].sprintDistance >= 1 then local superficial = math.floor(players[playerName].sprintDistance) - mcl_hunger.exhaust(playerName, mcl_hunger.EXHAUST_SPRINT * superficial) + exhaust(playerName, mcl_hunger.EXHAUST_SPRINT * superficial) players[playerName].sprintDistance = players[playerName].sprintDistance - superficial end -- Sprint node particles - local playerNode = minetest.get_node({x=playerPos["x"], y=playerPos["y"]-1, z=playerPos["z"]}) - local def = minetest.registered_nodes[playerNode.name] + local playerNode = get_node({x=playerPos["x"], y=playerPos["y"]-1, z=playerPos["z"]}) + local def = registered_nodes[playerNode.name] if def and def.walkable then - minetest.add_particlespawner({ + add_particlespawner({ amount = math.random(1, 2), time = 1, minpos = {x=-0.5, y=0.1, z=-0.5}, @@ -158,8 +212,10 @@ minetest.register_globalstep(function(dtime) if players[playerName]["shouldSprint"] == true then --Stopped local sprinting -- Prevent sprinting if hungry or sleeping - if (mcl_hunger.active and mcl_hunger.get_hunger(player) <= 6) or (player:get_meta():get_string("mcl_beds:sleeping") == "true")then + if (mcl_hunger.active and get_hunger(player) <= 6) + or (player:get_meta():get_string("mcl_beds:sleeping") == "true") then sprinting = false + cancelClientSprinting(playerName) else sprinting = true end diff --git a/mods/PLAYER/mcl_sprint/mod.conf b/mods/PLAYER/mcl_sprint/mod.conf index 7a3692459..0d20f80a3 100644 --- a/mods/PLAYER/mcl_sprint/mod.conf +++ b/mods/PLAYER/mcl_sprint/mod.conf @@ -1 +1,4 @@ name = mcl_sprint +author = GunshipPenguin +description = Allows the player to sprint by pressing the “Use” key (default: E). +depends = mcl_playerinfo, playerphysics, mcl_hunger diff --git a/mods/PLAYER/wieldview/LICENSE.txt b/mods/PLAYER/mcl_wieldview/LICENSE.txt similarity index 100% rename from mods/PLAYER/wieldview/LICENSE.txt rename to mods/PLAYER/mcl_wieldview/LICENSE.txt diff --git a/mods/PLAYER/mcl_wieldview/README.txt b/mods/PLAYER/mcl_wieldview/README.txt new file mode 100644 index 000000000..b6de5b208 --- /dev/null +++ b/mods/PLAYER/mcl_wieldview/README.txt @@ -0,0 +1,13 @@ +[mod] visible wielded items [mcl_wieldview] +======================================= + +Makes hand wielded items visible to other players. + + +Info for modders +################ + +Register an item with the property "_mcl_wieldview_item" to change the third person wield view appearance of the item. +"_mcl_wieldview_item" should be set to an item name that will be shown by the wield view instead of the item. +If you use an empty string, nothing will be shown. + diff --git a/mods/PLAYER/mcl_wieldview/init.lua b/mods/PLAYER/mcl_wieldview/init.lua new file mode 100644 index 000000000..3a646a18a --- /dev/null +++ b/mods/PLAYER/mcl_wieldview/init.lua @@ -0,0 +1,64 @@ +minetest.register_entity("mcl_wieldview:wieldview", { + initial_properties = { + hp_max = 1, + visual = "wielditem", + physical = false, + is_visible = false, + pointable = false, + collide_with_objects = false, + static_save = false, + collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + visual_size = {x = 0.21, y = 0.21}, + } +}) + +local wieldview_luaentites = {} + +local function update_wieldview_entity(player) + local luaentity = wieldview_luaentites[player] + if luaentity and luaentity.object:get_yaw() then + local item = player:get_wielded_item():get_name() + + if item == luaentity._item then return end + + luaentity._item = item + + local def = player:get_wielded_item():get_definition() + if def and def._mcl_wieldview_item then + item = def._mcl_wieldview_item + end + + local item_def = minetest.registered_items[item] + luaentity.object:set_properties({ + glow = item_def and item_def.light_source or 0, + wield_item = item, + is_visible = item ~= "" + }) + else + -- If the player is running through an unloaded area, + -- the wieldview entity will sometimes get unloaded. + -- This code path is also used to initalize the wieldview. + -- Creating entites from minetest.register_on_joinplayer + -- is unreliable as of Minetest 5.6 + local obj_ref = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldview") + if not obj_ref then return end + obj_ref:set_attach(player, "Wield_Item") + --obj_ref:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 45, 90)) + wieldview_luaentites[player] = obj_ref:get_luaentity() + end +end + +minetest.register_on_leaveplayer(function(player) + if wieldview_luaentites[player] then + wieldview_luaentites[player].object:remove() + end + wieldview_luaentites[player] = nil +end) + +minetest.register_globalstep(function(dtime) + local players = minetest.get_connected_players() + for i, player in pairs(players) do + update_wieldview_entity(player) + end +end) diff --git a/mods/PLAYER/mcl_wieldview/mod.conf b/mods/PLAYER/mcl_wieldview/mod.conf new file mode 100644 index 000000000..7ed41eeb4 --- /dev/null +++ b/mods/PLAYER/mcl_wieldview/mod.conf @@ -0,0 +1,4 @@ +name = mcl_wieldview +author = stujones11 +description = Makes hand wielded items visible to other players. +depends = mcl_armor, mcl_playerplus diff --git a/mods/PLAYER/playerphysics/description.txt b/mods/PLAYER/playerphysics/description.txt deleted file mode 100644 index c692c5cdb..000000000 --- a/mods/PLAYER/playerphysics/description.txt +++ /dev/null @@ -1 +0,0 @@ -This mod makes it possible for multiple mods to modify player physics (speed, jumping strength, gravity) without conflict. diff --git a/mods/PLAYER/playerphysics/mod.conf b/mods/PLAYER/playerphysics/mod.conf index da01bf07e..1c2f2fa07 100644 --- a/mods/PLAYER/playerphysics/mod.conf +++ b/mods/PLAYER/playerphysics/mod.conf @@ -1 +1,3 @@ name = playerphysics +author = Wuzzy +description = This mod makes it possible for multiple mods to modify player physics (speed, jumping strength, gravity) without conflict. diff --git a/mods/PLAYER/wieldview/README.txt b/mods/PLAYER/wieldview/README.txt deleted file mode 100644 index 183e8c6d5..000000000 --- a/mods/PLAYER/wieldview/README.txt +++ /dev/null @@ -1,21 +0,0 @@ -[mod] visible wielded items [wieldview] -======================================= - -Makes hand wielded items visible to other players. - -default settings: [minetest.conf] - -# Set number of seconds between visible wielded item updates. -wieldview_update_time = 2 - -# Show nodes as tiles, disabled by default -wieldview_node_tiles = false - - -Info for modders -################ - -Wield image transformation: To apply a simple transformation to the item in -hand, add the group “wieldview_transform” to the item definition. The group -rating equals one of the numbers used for the [transform texture modifier -of the Lua API. diff --git a/mods/PLAYER/wieldview/depends.txt b/mods/PLAYER/wieldview/depends.txt deleted file mode 100644 index 2bbf820fd..000000000 --- a/mods/PLAYER/wieldview/depends.txt +++ /dev/null @@ -1 +0,0 @@ -mcl_armor diff --git a/mods/PLAYER/wieldview/description.txt b/mods/PLAYER/wieldview/description.txt deleted file mode 100644 index 0d51ad954..000000000 --- a/mods/PLAYER/wieldview/description.txt +++ /dev/null @@ -1 +0,0 @@ -Makes hand wielded items visible to other players. diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua deleted file mode 100644 index 7835cc38f..000000000 --- a/mods/PLAYER/wieldview/init.lua +++ /dev/null @@ -1,86 +0,0 @@ -local time = 0 -local update_time = tonumber(minetest.settings:get("wieldview_update_time")) -if not update_time then - update_time = 2 - minetest.settings:set("wieldview_update_time", tostring(update_time)) -end -local node_tiles = minetest.settings:get_bool("wieldview_node_tiles") -if not node_tiles then - node_tiles = false - minetest.settings:set("wieldview_node_tiles", "false") -end - -wieldview = { - wielded_item = {}, - transform = {}, -} - -dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua") - -wieldview.get_item_texture = function(self, item) - local texture = "blank.png" - if item ~= "" then - if minetest.registered_items[item] then - if minetest.registered_items[item].inventory_image ~= "" then - texture = minetest.registered_items[item].inventory_image - elseif node_tiles == true and minetest.registered_items[item].tiles - and type(minetest.registered_items[item].tiles[1]) == "string" - and minetest.registered_items[item].tiles[1] ~= "" then - texture = minetest.inventorycube(minetest.registered_items[item].tiles[1]) - end - end - -- Get item image transformation, first from group, then from transform.lua - local transform = minetest.get_item_group(item, "wieldview_transform") - if transform == 0 then - transform = wieldview.transform[item] - end - if transform then - -- This actually works with groups ratings because transform1, transform2, etc. - -- have meaning and transform0 is used for identidy, so it can be ignored - texture = texture.."^[transform"..tostring(transform) - end - end - return texture -end - -wieldview.update_wielded_item = function(self, player) - if not player then - return - end - local name = player:get_player_name() - local stack = player:get_wielded_item() - local item = stack:get_name() - if not item then - return - end - if self.wielded_item[name] then - if self.wielded_item[name] == item then - return - end - if not armor.textures[name] then - return - end - armor.textures[name].wielditem = self:get_item_texture(item) - armor:update_player_visuals(player) - end - self.wielded_item[name] = item -end - -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - wieldview.wielded_item[name] = "" - minetest.after(0, function(player) - wieldview:update_wielded_item(player) - end, player) -end) - -minetest.register_globalstep(function(dtime) - time = time + dtime - if time > update_time then - for _,player in ipairs(minetest.get_connected_players()) do - wieldview:update_wielded_item(player) - end - time = 0 - end -end) - diff --git a/mods/PLAYER/wieldview/transform.lua b/mods/PLAYER/wieldview/transform.lua deleted file mode 100644 index 0b0145c7f..000000000 --- a/mods/PLAYER/wieldview/transform.lua +++ /dev/null @@ -1,42 +0,0 @@ --- Wielded Item Transformations - http://dev.minetest.net/texture - -wieldview.transform = { - ["mcl_core:torch"]="R270", - ["mesecons_torch:mesecon_torch_on"]="R270", - ["mcl_core:sapling"]="R270", - ["mcl_core:junglesapling"]="R270", - ["mcl_core:darksapling"]="R270", - ["mcl_core:acaciasapling"]="R270", - ["mcl_core:birchsapling"]="R270", - ["mcl_core:sprucesapling"]="R270", - ["mcl_core:deadbush"]="R270", - ["mcl_flowers:dandelion"]="R270", - ["mcl_flowers:tulip_orange"]="R270", - ["mcl_flowers:tulip_white"]="R270", - ["mcl_flowers:tulip_pink"]="R270", - ["mcl_flowers:tulip_red"]="R270", - ["mcl_flowers:allium"]="R270", - ["mcl_flowers:azure_bluet"]="R270", - ["mcl_flowers:poppy"]="R270", - ["mcl_flowers:blue_orchid"]="R270", - ["mcl_flowers:oxeye_daisy"]="R270", - ["mcl_flowers:fern"]="R270", - ["mcl_flowers:tallgrass"]="R270", - ["mcl_buckets:bucket_empty"]="R270", - ["mcl_buckets:bucket_water"]="R270", - ["mcl_buckets:bucket_river_water"]="R270", - ["mcl_buckets:bucket_lava"]="R270", - ["mcl_mobitems:milk_bucket"]="R270", - ["mcl_potions:glass_bottle"]="R270", - ["mcl_potions:water"]="R270", - ["mcl_potions:awkward"]="R270", - ["mcl_potions:thick"]="R270", - ["mcl_potions:mundane"]="R270", - - ["screwdriver:screwdriver"]="R270", - ["screwdriver:screwdriver1"]="R270", - ["screwdriver:screwdriver2"]="R270", - ["screwdriver:screwdriver3"]="R270", - ["screwdriver:screwdriver4"]="R270", -} - diff --git a/screenshot.png b/screenshot.png index a92bd53e5..12cc5db22 100644 Binary files a/screenshot.png and b/screenshot.png differ diff --git a/settingtypes.txt b/settingtypes.txt index 394749fd7..c5d5d32c1 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,4 +1,4 @@ -# This file contains settings of MineClone 2that can be changed in +# This file contains settings of MineClone 2 that can be changed in # minetest.conf [World] @@ -20,12 +20,30 @@ enable_fire (Destructive and spreading fire) bool true # If enabled, the weather will change naturally over time. mcl_doWeatherCycle (Change weather) bool true +# Amount of rain particles. You can reduce this to get better FPS (default: 500) +mcl_weather_rain_particles (Rain particles) int 500 0 + +# Amount of thunderstorm rain particles. You can reduce this to get better FPS (default: 900) +mcl_weather_thunder_particles (Thunderstorm rain particles) int 900 0 + +# Amount of snow particles. You can reduce this to get better FPS (default: 100) +mcl_weather_snow_particles (Snow particles) int 100 0 + +# Amount of nether dust particles. You can reduce this to get better FPS (default: 150) +mcl_weather_dust_particles (Nether dust particles) int 150 0 + # If enabled, breaking blocks will cause them to drop as item. # Note that blocks never have drops when in Creative Mode. mcl_doTileDrops (Blocks have drops) bool true -# If enabled, TNT explosions destroy blocks. -mcl_tnt_griefing (TNT destroys blocks) bool true +# If enabled, explosions destroy blocks. +mcl_explosions_griefing (Explosions destroy blocks) bool true + +# Comma separated list of disabled structure names +mcl_disabled_structures (Disabled structures) string + +# Comma separated list of disabled event names +mcl_disabled_events (Disabled events) string [Players] # If enabled, players respawn at the bed they last lay on instead of normal @@ -33,13 +51,22 @@ mcl_tnt_griefing (TNT destroys blocks) bool true # This setting is only read at startup. enable_bed_respawn (Respawn at bed) bool true -# If enabled, the night can be skipped if all players are in bed. -# This setting is only read at startup. -enable_bed_night_skip (Skip night when sleeping) 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. +# The setting can be changed ingame using `/set mcl_playersSleepingPercentage ` +mcl_playersSleepingPercentage (Players Sleeping Percentage) int 100 + # Normally, players drop all their items when they die. Enable this # setting, so players always keep their inventory on death. mcl_keepInventory (Keep inventory on death) bool false +# Elytra maximum speed cap +mcl_elytra_max_speed (Elytra maximum speed cap) float 4.0 2.5 6.0 + +# Elytra rocket speed cap +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 @@ -48,16 +75,29 @@ mcl_showDeathMessages (Show death messages) bool true # If disabled, all recipes will be shown. mcl_craftguide_progressive_mode (Learn crafting recipes progressively) bool true +# If disabled, the skin of all players will be character.png +mcl_enable_skin_customization (Enable player skin customization) bool true + +# How far the player hand can reach +# Default:4.5 +mcl_hand_range (Hand range) float 4.5 1 128 + +# How far the player hand can reach in creative mode +# Default:10 +mcl_hand_range_creative (Creative mode hand range) float 10 1 128 + +# Creative mode dig speed in seconds +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 + [Mobs] # If enabled, mobs will spawn naturally. This does not affect # affect mob spawners. # This setting is only read at startup. mobs_spawn (Spawn mobs naturally) bool true -# Controls the overall amount of mobs that spawn. The higher the number, -# the less often mobs will spawn. This does not affect mob spawners. -mobs_spawn_chance (Mob spawn chance) float 2.5 0.0 - # If enabled, only peaceful mobs will appear naturally. This does not # affect mob spawners. # This setting is only read at startup. @@ -81,10 +121,65 @@ mobs_griefing (Mobs change blocks) bool true # If enabled, mobs won't damage particles when they got hurt. mobs_disable_blood (Disable mob damage particles) bool false +#Percentage of peaceful spawn attempts that succeed (default:30) +mcl_mob_peaceful_percentage_spawned (Peaceful percentage success) int 30 0 100 + +#Percentage of peaceful spawn attempts that are group spawns (default:15) +mcl_mob_peaceful_group_percentage_spawned (Peaceful group percentage) int 15 0 100 + +#Percentage of hostile spawn attempts that are group spawns (default:20) +mcl_mob_hostile_group_percentage_spawned (Hostile group percentage) int 20 0 100 + +#Maximum amount of mobs (default:500) +mcl_mob_cap_total (Global mob cap) int 500 0 2048 + +#Maximum amount of hostile mobs (default:300) +mcl_mob_cap_hostile (Global hostile mob cap) int 300 0 2048 + +#Maximum amount of non-hostile mobs (default:300) +mcl_mob_cap_non_hostile (Global non-hostile mob cap) int 300 0 2048 + +#Maximum amount of mobs per player (default:75) +mcl_mob_cap_player (Mob cap per player) int 75 0 2048 + +#Maximum amount of monsters that will spawn near a player (default:70) +mcl_mob_cap_monster (Mob cap monsters) int 70 0 2048 + +#Maximum amount of animals that will spawn near a player (default:10) +mcl_mob_cap_animal (Mob cap animals) int 10 0 1024 + +#Maximum amount of water mobs that will spawn near a player (default:8) +mcl_mob_cap_water (Mob cap water) int 8 0 1024 + +#Maximum amount of ambient water mobs that will spawn near a player (default:20) +mcl_mob_cap_water_ambient (Mob cap ambient water) int 20 0 1024 + +#Maximum amount of underground water mobs that will spawn near a player (default:5) +mcl_mob_cap_water_underground (Mob cap underground water) int 5 0 1024 + +#Maximum amount of axolotl mobs that will spawn near a player (default:5) +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 + +#Display mob icons in inventory instead of mc-like spawn eggs +mcl_old_spawn_icons (Old spawn icons instead of eggs) bool false + +# How far from players should mobs stop moving +# Larger values will have a larger performance impact (default:48) +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 + [Audio] # Enable flame sound. flame_sound (Flame sound) bool true +# Enable the in-game music. +mcl_game_music (In-game music) bool true + [Graphics] # How many vertical animation frames the fire texture (fire_basic_flame_animated.png) has. # This may vary depending on the texture pack you use. @@ -94,6 +189,16 @@ fire_animation_frames (Fire Animation Frames) int 8 # Whether to animate chests when open / close animated_chests (Animated chests) bool true +# The maximum number of boss bars to simultaniously display on the screen +max_bossbars (Maximum Boss bars) int 5 + +# Default intensity of shadows (default: 0.33) +mcl_default_shadow_intensity (Default shadow intensity) float 0.33 0.0 1.0 + +# When enabled, when a player holds a bucket, a select box will be shown around liquid nodes. +# Selecting liquid nodes on clients without a cross hair will not work correctly if this setting is disabled. +mcl_buckets_use_select_box (Buckets use select box) bool false + [Experimental] # Whether ice is translucent. If disabled, ice is fully opaque. # @@ -123,6 +228,15 @@ mcl_generate_fallen_logs (Generate fallen logs) bool false # But creating new flat worlds after changing this setting should be safe. mcl_superflat_classic (Classic superflat map generation) bool false +# If disabled, no deepslate will be generated. +mcl_generate_deepslate (Generate Deepslate) bool true + +# If disabled, no ores will be generated. +mcl_generate_ores (Generate Ores) bool true + +# If disabled, command blocks will be unusuable (but still present). +mcl_enable_commandblocks (Enable Command Blocks) bool true + # Make some blocks emit decorative particles like flames. This setting # specifies the detail level of particles, with higher levels being # more CPU demanding. @@ -130,8 +244,49 @@ mcl_superflat_classic (Classic superflat map generation) bool false # game by a lot. mcl_node_particles (Block particles detail level) enum none high,medium,low,none +# Enable hard overiding of builtin commands. +mcl_builtin_commands_overide (Enable hard overiding of builtin commands.) bool true + # If enabled, this will substitute a few blocks in village schematics so they blend into normal, snowy, and sandy areas. Defaults to true. basic_pseudobiome_villages (Enables very basic, and experimental "pseudobiome-based" villages) bool true # If enabled, will run an LBM to fix the top 1/2 of double plants in mcimported worlds; defaults to true. fix_doubleplants (Mcimport double plant fixes) bool true + +# Allow players to create Minecraft-like maps. +enable_real_maps (Enable Real Maps) bool true + +[Additional Features] +# Enable Bookshelf inventories +mcl_bookshelf_inventories (Enable bookshelf inventories) bool true + +# Enable swiftness on enchanted golden apples +mcl_enable_fapples (Enable swiftness on enchanted golden apples) bool true + +# All tameable mobs listen to the "sit" righclick like dogs +mcl_extended_pet_control (Extended pet control) bool true + +# Enable hamburgers for villagers to follow +mcl_enable_hamburger (Enable Hamburger) bool true + +# Starting Inventory contents (given directly to the new player) type: bool +give_starting_inv (Player Starter Pack) bool false + +[Debugging] +# If enabled, this will show the itemstring of an item in the description. +mcl_item_id_debug (Item ID Debug) bool false + +#Log mob spawning and despawning events +mcl_logging_mobs_spawn (Log Mob Spawning) bool true + +# If enabled mapgen timings will be dumped to log +mcl_logging_mapgen (Chunk generation logging) bool false + +# If enabled generated structures will be logged +mcl_logging_structures (Structure generation logging) bool true + +#Complete debug logging for mcl_signs events. Use this if you have issues with signs. +mcl_logging_mcl_signs (Complete debug logging for mcl_signs) bool false + +#Debug logging for mcl_events. +mcl_logging_event_api (Debug logging for mcl_events) bool false diff --git a/textures/_0.png b/textures/_0.png new file mode 100644 index 000000000..9cef8949b Binary files /dev/null and b/textures/_0.png differ diff --git a/textures/_1.png b/textures/_1.png new file mode 100644 index 000000000..f14f751c8 Binary files /dev/null and b/textures/_1.png differ diff --git a/textures/_1_2.png b/textures/_1_2.png new file mode 100644 index 000000000..1791ed1f2 Binary files /dev/null and b/textures/_1_2.png differ diff --git a/textures/_1_4.png b/textures/_1_4.png new file mode 100644 index 000000000..6cfd6dd65 Binary files /dev/null and b/textures/_1_4.png differ diff --git a/textures/_1_sup.png b/textures/_1_sup.png new file mode 100644 index 000000000..1e1dd18b9 Binary files /dev/null and b/textures/_1_sup.png differ diff --git a/textures/_2.png b/textures/_2.png new file mode 100644 index 000000000..66b7b9557 Binary files /dev/null and b/textures/_2.png differ diff --git a/textures/_2_sup.png b/textures/_2_sup.png new file mode 100644 index 000000000..9e9f12c1b Binary files /dev/null and b/textures/_2_sup.png differ diff --git a/textures/_3.png b/textures/_3.png new file mode 100644 index 000000000..9c06dba5d Binary files /dev/null and b/textures/_3.png differ diff --git a/textures/_3_4.png b/textures/_3_4.png new file mode 100644 index 000000000..4a65a0f73 Binary files /dev/null and b/textures/_3_4.png differ diff --git a/textures/_3_sup.png b/textures/_3_sup.png new file mode 100644 index 000000000..29fc9831c Binary files /dev/null and b/textures/_3_sup.png differ diff --git a/textures/_4.png b/textures/_4.png new file mode 100644 index 000000000..1784c4749 Binary files /dev/null and b/textures/_4.png differ diff --git a/textures/_5.png b/textures/_5.png new file mode 100644 index 000000000..85e0703b7 Binary files /dev/null and b/textures/_5.png differ diff --git a/textures/_6.png b/textures/_6.png new file mode 100644 index 000000000..0abc2a4bb Binary files /dev/null and b/textures/_6.png differ diff --git a/textures/_7.png b/textures/_7.png new file mode 100644 index 000000000..711076c2f Binary files /dev/null and b/textures/_7.png differ diff --git a/textures/_8.png b/textures/_8.png new file mode 100644 index 000000000..136a41414 Binary files /dev/null and b/textures/_8.png differ diff --git a/textures/_9.png b/textures/_9.png new file mode 100644 index 000000000..5a15bfc4e Binary files /dev/null and b/textures/_9.png differ diff --git a/textures/_a.png b/textures/_a.png new file mode 100644 index 000000000..60bb5e342 Binary files /dev/null and b/textures/_a.png differ diff --git a/textures/_a_.png b/textures/_a_.png new file mode 100644 index 000000000..10262ddac Binary files /dev/null and b/textures/_a_.png differ diff --git a/textures/_a_acute.png b/textures/_a_acute.png new file mode 100644 index 000000000..60f8c4dac Binary files /dev/null and b/textures/_a_acute.png differ diff --git a/textures/_a_acute_.png b/textures/_a_acute_.png new file mode 100644 index 000000000..c61dd6c4c Binary files /dev/null and b/textures/_a_acute_.png differ diff --git a/textures/_a_circumflex.png b/textures/_a_circumflex.png new file mode 100644 index 000000000..625997df9 Binary files /dev/null and b/textures/_a_circumflex.png differ diff --git a/textures/_a_circumflex_.png b/textures/_a_circumflex_.png new file mode 100644 index 000000000..b751738a7 Binary files /dev/null and b/textures/_a_circumflex_.png differ diff --git a/textures/_a_grave.png b/textures/_a_grave.png new file mode 100644 index 000000000..e8d0dcfb6 Binary files /dev/null and b/textures/_a_grave.png differ diff --git a/textures/_a_grave_.png b/textures/_a_grave_.png new file mode 100644 index 000000000..d61f6654b Binary files /dev/null and b/textures/_a_grave_.png differ diff --git a/textures/_a_ring.png b/textures/_a_ring.png new file mode 100644 index 000000000..a74786313 Binary files /dev/null and b/textures/_a_ring.png differ diff --git a/textures/_a_ring_.png b/textures/_a_ring_.png new file mode 100644 index 000000000..73db3807c Binary files /dev/null and b/textures/_a_ring_.png differ diff --git a/textures/_a_sup.png b/textures/_a_sup.png new file mode 100644 index 000000000..80e0123ec Binary files /dev/null and b/textures/_a_sup.png differ diff --git a/textures/_a_tilde.png b/textures/_a_tilde.png new file mode 100644 index 000000000..83a429517 Binary files /dev/null and b/textures/_a_tilde.png differ diff --git a/textures/_a_tilde_.png b/textures/_a_tilde_.png new file mode 100644 index 000000000..88b8cca83 Binary files /dev/null and b/textures/_a_tilde_.png differ diff --git a/textures/_acute.png b/textures/_acute.png new file mode 100644 index 000000000..509e830cb Binary files /dev/null and b/textures/_acute.png differ diff --git a/textures/_ae.png b/textures/_ae.png new file mode 100644 index 000000000..f46b7e689 Binary files /dev/null and b/textures/_ae.png differ diff --git a/textures/_ae_.png b/textures/_ae_.png new file mode 100644 index 000000000..d1050341a Binary files /dev/null and b/textures/_ae_.png differ diff --git a/textures/_ae_lig.png b/textures/_ae_lig.png new file mode 100644 index 000000000..b18693e19 Binary files /dev/null and b/textures/_ae_lig.png differ diff --git a/textures/_ae_lig_.png b/textures/_ae_lig_.png new file mode 100644 index 000000000..08c1a8976 Binary files /dev/null and b/textures/_ae_lig_.png differ diff --git a/textures/_am.png b/textures/_am.png new file mode 100644 index 000000000..72d9dd68c Binary files /dev/null and b/textures/_am.png differ diff --git a/textures/_ap.png b/textures/_ap.png new file mode 100644 index 000000000..15f8abe05 Binary files /dev/null and b/textures/_ap.png differ diff --git a/textures/_as.png b/textures/_as.png new file mode 100644 index 000000000..f9eec0c6d Binary files /dev/null and b/textures/_as.png differ diff --git a/textures/_at.png b/textures/_at.png new file mode 100644 index 000000000..f4f36f12c Binary files /dev/null and b/textures/_at.png differ diff --git a/textures/_b.png b/textures/_b.png new file mode 100644 index 000000000..0947e6618 Binary files /dev/null and b/textures/_b.png differ diff --git a/textures/_b_.png b/textures/_b_.png new file mode 100644 index 000000000..db47fcac8 Binary files /dev/null and b/textures/_b_.png differ diff --git a/textures/_bl.png b/textures/_bl.png new file mode 100644 index 000000000..5706ff380 Binary files /dev/null and b/textures/_bl.png differ diff --git a/textures/_br.png b/textures/_br.png new file mode 100644 index 000000000..d8cf11980 Binary files /dev/null and b/textures/_br.png differ diff --git a/textures/_broken_bar.png b/textures/_broken_bar.png new file mode 100644 index 000000000..3461d4d9a Binary files /dev/null and b/textures/_broken_bar.png differ diff --git a/textures/_c.png b/textures/_c.png new file mode 100644 index 000000000..12fce7b20 Binary files /dev/null and b/textures/_c.png differ diff --git a/textures/_c_.png b/textures/_c_.png new file mode 100644 index 000000000..33b85221b Binary files /dev/null and b/textures/_c_.png differ diff --git a/textures/_c_cedille.png b/textures/_c_cedille.png new file mode 100644 index 000000000..acc701201 Binary files /dev/null and b/textures/_c_cedille.png differ diff --git a/textures/_c_cedille_.png b/textures/_c_cedille_.png new file mode 100644 index 000000000..865a951d6 Binary files /dev/null and b/textures/_c_cedille_.png differ diff --git a/textures/_ca.png b/textures/_ca.png new file mode 100644 index 000000000..73013c6a9 Binary files /dev/null and b/textures/_ca.png differ diff --git a/textures/_cedille.png b/textures/_cedille.png new file mode 100644 index 000000000..1335b2759 Binary files /dev/null and b/textures/_cedille.png differ diff --git a/textures/_cent.png b/textures/_cent.png new file mode 100644 index 000000000..28180dbf3 Binary files /dev/null and b/textures/_cent.png differ diff --git a/textures/_cl.png b/textures/_cl.png new file mode 100644 index 000000000..0850d9b8f Binary files /dev/null and b/textures/_cl.png differ diff --git a/textures/_cm.png b/textures/_cm.png new file mode 100644 index 000000000..5cf8c7dab Binary files /dev/null and b/textures/_cm.png differ diff --git a/textures/_co.png b/textures/_co.png new file mode 100644 index 000000000..5a606c06a Binary files /dev/null and b/textures/_co.png differ diff --git a/textures/_copyright.png b/textures/_copyright.png new file mode 100644 index 000000000..17e6c1916 Binary files /dev/null and b/textures/_copyright.png differ diff --git a/textures/_cr.png b/textures/_cr.png new file mode 100644 index 000000000..1d7366f4c Binary files /dev/null and b/textures/_cr.png differ diff --git a/textures/_currency.png b/textures/_currency.png new file mode 100644 index 000000000..196ffa0a0 Binary files /dev/null and b/textures/_currency.png differ diff --git a/textures/_d.png b/textures/_d.png new file mode 100644 index 000000000..33a5a3cae Binary files /dev/null and b/textures/_d.png differ diff --git a/textures/_d_.png b/textures/_d_.png new file mode 100644 index 000000000..d64d854a4 Binary files /dev/null and b/textures/_d_.png differ diff --git a/textures/_d_dash.png b/textures/_d_dash.png new file mode 100644 index 000000000..275495cb2 Binary files /dev/null and b/textures/_d_dash.png differ diff --git a/textures/_d_dash_.png b/textures/_d_dash_.png new file mode 100644 index 000000000..0d718e705 Binary files /dev/null and b/textures/_d_dash_.png differ diff --git a/textures/_degree.png b/textures/_degree.png new file mode 100644 index 000000000..d1dfc83c7 Binary files /dev/null and b/textures/_degree.png differ diff --git a/textures/_diaresis.png b/textures/_diaresis.png new file mode 100644 index 000000000..13fb9abb9 Binary files /dev/null and b/textures/_diaresis.png differ diff --git a/textures/_div.png b/textures/_div.png new file mode 100644 index 000000000..c5399cd19 Binary files /dev/null and b/textures/_div.png differ diff --git a/textures/_dl.png b/textures/_dl.png new file mode 100644 index 000000000..8da436340 Binary files /dev/null and b/textures/_dl.png differ diff --git a/textures/_dt.png b/textures/_dt.png new file mode 100644 index 000000000..349c18334 Binary files /dev/null and b/textures/_dt.png differ diff --git a/textures/_dv.png b/textures/_dv.png new file mode 100644 index 000000000..dbafa7278 Binary files /dev/null and b/textures/_dv.png differ diff --git a/textures/_e.png b/textures/_e.png new file mode 100644 index 000000000..e30d28ebf Binary files /dev/null and b/textures/_e.png differ diff --git a/textures/_e_.png b/textures/_e_.png new file mode 100644 index 000000000..ceba83a14 Binary files /dev/null and b/textures/_e_.png differ diff --git a/textures/_e_acute.png b/textures/_e_acute.png new file mode 100644 index 000000000..abef4fc53 Binary files /dev/null and b/textures/_e_acute.png differ diff --git a/textures/_e_acute_.png b/textures/_e_acute_.png new file mode 100644 index 000000000..49cddaff0 Binary files /dev/null and b/textures/_e_acute_.png differ diff --git a/textures/_e_circumflex.png b/textures/_e_circumflex.png new file mode 100644 index 000000000..684bd07d4 Binary files /dev/null and b/textures/_e_circumflex.png differ diff --git a/textures/_e_circumflex_.png b/textures/_e_circumflex_.png new file mode 100644 index 000000000..79f35a128 Binary files /dev/null and b/textures/_e_circumflex_.png differ diff --git a/textures/_e_grave.png b/textures/_e_grave.png new file mode 100644 index 000000000..5239e04fc Binary files /dev/null and b/textures/_e_grave.png differ diff --git a/textures/_e_grave_.png b/textures/_e_grave_.png new file mode 100644 index 000000000..9fe0283b7 Binary files /dev/null and b/textures/_e_grave_.png differ diff --git a/textures/_ee.png b/textures/_ee.png new file mode 100644 index 000000000..642b6ede3 Binary files /dev/null and b/textures/_ee.png differ diff --git a/textures/_ee_.png b/textures/_ee_.png new file mode 100644 index 000000000..23d096195 Binary files /dev/null and b/textures/_ee_.png differ diff --git a/textures/_eq.png b/textures/_eq.png new file mode 100644 index 000000000..0a9681e09 Binary files /dev/null and b/textures/_eq.png differ diff --git a/textures/_ex.png b/textures/_ex.png new file mode 100644 index 000000000..6bc2b589b Binary files /dev/null and b/textures/_ex.png differ diff --git a/textures/_ex_inv.png b/textures/_ex_inv.png new file mode 100644 index 000000000..39dfc2b4f Binary files /dev/null and b/textures/_ex_inv.png differ diff --git a/textures/_f.png b/textures/_f.png new file mode 100644 index 000000000..10e49a56e Binary files /dev/null and b/textures/_f.png differ diff --git a/textures/_f_.png b/textures/_f_.png new file mode 100644 index 000000000..688c327f0 Binary files /dev/null and b/textures/_f_.png differ diff --git a/textures/_g.png b/textures/_g.png new file mode 100644 index 000000000..cc7a2edea Binary files /dev/null and b/textures/_g.png differ diff --git a/textures/_g_.png b/textures/_g_.png new file mode 100644 index 000000000..7fddf4857 Binary files /dev/null and b/textures/_g_.png differ diff --git a/textures/_gr.png b/textures/_gr.png new file mode 100644 index 000000000..117772d03 Binary files /dev/null and b/textures/_gr.png differ diff --git a/textures/_gt.png b/textures/_gt.png new file mode 100644 index 000000000..115f61e6a Binary files /dev/null and b/textures/_gt.png differ diff --git a/textures/_guill_left.png b/textures/_guill_left.png new file mode 100644 index 000000000..8eada6edb Binary files /dev/null and b/textures/_guill_left.png differ diff --git a/textures/_guill_right.png b/textures/_guill_right.png new file mode 100644 index 000000000..02e2b8597 Binary files /dev/null and b/textures/_guill_right.png differ diff --git a/textures/_h.png b/textures/_h.png new file mode 100644 index 000000000..6ddb4a845 Binary files /dev/null and b/textures/_h.png differ diff --git a/textures/_h_.png b/textures/_h_.png new file mode 100644 index 000000000..b1379d1ad Binary files /dev/null and b/textures/_h_.png differ diff --git a/textures/_ha.png b/textures/_ha.png new file mode 100644 index 000000000..94622fbcb Binary files /dev/null and b/textures/_ha.png differ diff --git a/textures/_hs.png b/textures/_hs.png new file mode 100644 index 000000000..f75e24b7b Binary files /dev/null and b/textures/_hs.png differ diff --git a/textures/_i.png b/textures/_i.png new file mode 100644 index 000000000..0677f7b7e Binary files /dev/null and b/textures/_i.png differ diff --git a/textures/_i_.png b/textures/_i_.png new file mode 100644 index 000000000..9e4ed0241 Binary files /dev/null and b/textures/_i_.png differ diff --git a/textures/_i_acute.png b/textures/_i_acute.png new file mode 100644 index 000000000..171248658 Binary files /dev/null and b/textures/_i_acute.png differ diff --git a/textures/_i_acute_.png b/textures/_i_acute_.png new file mode 100644 index 000000000..b916f512d Binary files /dev/null and b/textures/_i_acute_.png differ diff --git a/textures/_i_circumflex.png b/textures/_i_circumflex.png new file mode 100644 index 000000000..ea7b9667a Binary files /dev/null and b/textures/_i_circumflex.png differ diff --git a/textures/_i_circumflex_.png b/textures/_i_circumflex_.png new file mode 100644 index 000000000..7b75690e6 Binary files /dev/null and b/textures/_i_circumflex_.png differ diff --git a/textures/_i_grave.png b/textures/_i_grave.png new file mode 100644 index 000000000..a0d98cb3a Binary files /dev/null and b/textures/_i_grave.png differ diff --git a/textures/_i_grave_.png b/textures/_i_grave_.png new file mode 100644 index 000000000..b2dfe3600 Binary files /dev/null and b/textures/_i_grave_.png differ diff --git a/textures/_j.png b/textures/_j.png new file mode 100644 index 000000000..17ce331ed Binary files /dev/null and b/textures/_j.png differ diff --git a/textures/_j_.png b/textures/_j_.png new file mode 100644 index 000000000..2e1c04d3c Binary files /dev/null and b/textures/_j_.png differ diff --git a/textures/_k.png b/textures/_k.png new file mode 100644 index 000000000..c636b068d Binary files /dev/null and b/textures/_k.png differ diff --git a/textures/_k_.png b/textures/_k_.png new file mode 100644 index 000000000..51f5b5fe5 Binary files /dev/null and b/textures/_k_.png differ diff --git a/textures/_l.png b/textures/_l.png new file mode 100644 index 000000000..5dcadd5e4 Binary files /dev/null and b/textures/_l.png differ diff --git a/textures/_l_.png b/textures/_l_.png new file mode 100644 index 000000000..4df616eb1 Binary files /dev/null and b/textures/_l_.png differ diff --git a/textures/_lt.png b/textures/_lt.png new file mode 100644 index 000000000..3984033c9 Binary files /dev/null and b/textures/_lt.png differ diff --git a/textures/_m.png b/textures/_m.png new file mode 100644 index 000000000..39c197161 Binary files /dev/null and b/textures/_m.png differ diff --git a/textures/_m_.png b/textures/_m_.png new file mode 100644 index 000000000..22c2b29ac Binary files /dev/null and b/textures/_m_.png differ diff --git a/textures/_macron.png b/textures/_macron.png new file mode 100644 index 000000000..5cae02c83 Binary files /dev/null and b/textures/_macron.png differ diff --git a/textures/_mn.png b/textures/_mn.png new file mode 100644 index 000000000..6eefea63f Binary files /dev/null and b/textures/_mn.png differ diff --git a/textures/_mu.png b/textures/_mu.png new file mode 100644 index 000000000..af8bf8564 Binary files /dev/null and b/textures/_mu.png differ diff --git a/textures/_n.png b/textures/_n.png new file mode 100644 index 000000000..54e554542 Binary files /dev/null and b/textures/_n.png differ diff --git a/textures/_n_.png b/textures/_n_.png new file mode 100644 index 000000000..0c1b3ebfa Binary files /dev/null and b/textures/_n_.png differ diff --git a/textures/_n_tilde.png b/textures/_n_tilde.png new file mode 100644 index 000000000..7c2bc7145 Binary files /dev/null and b/textures/_n_tilde.png differ diff --git a/textures/_n_tilde_.png b/textures/_n_tilde_.png new file mode 100644 index 000000000..330ed22ab Binary files /dev/null and b/textures/_n_tilde_.png differ diff --git a/textures/_not.png b/textures/_not.png new file mode 100644 index 000000000..b37fdf57b Binary files /dev/null and b/textures/_not.png differ diff --git a/textures/_o.png b/textures/_o.png new file mode 100644 index 000000000..d6c786bd5 Binary files /dev/null and b/textures/_o.png differ diff --git a/textures/_o_.png b/textures/_o_.png new file mode 100644 index 000000000..accf9cafb Binary files /dev/null and b/textures/_o_.png differ diff --git a/textures/_o_acute.png b/textures/_o_acute.png new file mode 100644 index 000000000..17a7ea383 Binary files /dev/null and b/textures/_o_acute.png differ diff --git a/textures/_o_acute_.png b/textures/_o_acute_.png new file mode 100644 index 000000000..3f3143532 Binary files /dev/null and b/textures/_o_acute_.png differ diff --git a/textures/_o_circumflex.png b/textures/_o_circumflex.png new file mode 100644 index 000000000..4cc23702f Binary files /dev/null and b/textures/_o_circumflex.png differ diff --git a/textures/_o_circumflex_.png b/textures/_o_circumflex_.png new file mode 100644 index 000000000..d47a35520 Binary files /dev/null and b/textures/_o_circumflex_.png differ diff --git a/textures/_o_dash.png b/textures/_o_dash.png new file mode 100644 index 000000000..801843df7 Binary files /dev/null and b/textures/_o_dash.png differ diff --git a/textures/_o_dash_.png b/textures/_o_dash_.png new file mode 100644 index 000000000..1be4ca862 Binary files /dev/null and b/textures/_o_dash_.png differ diff --git a/textures/_o_grave.png b/textures/_o_grave.png new file mode 100644 index 000000000..76c3ac2b5 Binary files /dev/null and b/textures/_o_grave.png differ diff --git a/textures/_o_grave_.png b/textures/_o_grave_.png new file mode 100644 index 000000000..e1c18b3f5 Binary files /dev/null and b/textures/_o_grave_.png differ diff --git a/textures/_o_sup.png b/textures/_o_sup.png new file mode 100644 index 000000000..b2b95ac37 Binary files /dev/null and b/textures/_o_sup.png differ diff --git a/textures/_o_tilde.png b/textures/_o_tilde.png new file mode 100644 index 000000000..9c562e8e3 Binary files /dev/null and b/textures/_o_tilde.png differ diff --git a/textures/_o_tilde_.png b/textures/_o_tilde_.png new file mode 100644 index 000000000..3d43e407e Binary files /dev/null and b/textures/_o_tilde_.png differ diff --git a/textures/_oe.png b/textures/_oe.png new file mode 100644 index 000000000..4ffbb2fc6 Binary files /dev/null and b/textures/_oe.png differ diff --git a/textures/_oe_.png b/textures/_oe_.png new file mode 100644 index 000000000..b5ea6654f Binary files /dev/null and b/textures/_oe_.png differ diff --git a/textures/_p.png b/textures/_p.png new file mode 100644 index 000000000..aa3330b73 Binary files /dev/null and b/textures/_p.png differ diff --git a/textures/_p_.png b/textures/_p_.png new file mode 100644 index 000000000..cf253ed9b Binary files /dev/null and b/textures/_p_.png differ diff --git a/textures/_paragraph.png b/textures/_paragraph.png new file mode 100644 index 000000000..b8ae4e721 Binary files /dev/null and b/textures/_paragraph.png differ diff --git a/textures/_pilcrow.png b/textures/_pilcrow.png new file mode 100644 index 000000000..1cea42388 Binary files /dev/null and b/textures/_pilcrow.png differ diff --git a/textures/_plus_minus.png b/textures/_plus_minus.png new file mode 100644 index 000000000..c001b52a8 Binary files /dev/null and b/textures/_plus_minus.png differ diff --git a/textures/_pound.png b/textures/_pound.png new file mode 100644 index 000000000..a9d030d6a Binary files /dev/null and b/textures/_pound.png differ diff --git a/textures/_pr.png b/textures/_pr.png new file mode 100644 index 000000000..479641fbe Binary files /dev/null and b/textures/_pr.png differ diff --git a/textures/_ps.png b/textures/_ps.png new file mode 100644 index 000000000..7a10f9f86 Binary files /dev/null and b/textures/_ps.png differ diff --git a/textures/_q.png b/textures/_q.png new file mode 100644 index 000000000..a9d4d7248 Binary files /dev/null and b/textures/_q.png differ diff --git a/textures/_q_.png b/textures/_q_.png new file mode 100644 index 000000000..0dc1c50cb Binary files /dev/null and b/textures/_q_.png differ diff --git a/textures/_qo.png b/textures/_qo.png new file mode 100644 index 000000000..e649307ec Binary files /dev/null and b/textures/_qo.png differ diff --git a/textures/_qu.png b/textures/_qu.png new file mode 100644 index 000000000..b41fc936b Binary files /dev/null and b/textures/_qu.png differ diff --git a/textures/_qu_inv.png b/textures/_qu_inv.png new file mode 100644 index 000000000..abfb3d610 Binary files /dev/null and b/textures/_qu_inv.png differ diff --git a/textures/_r.png b/textures/_r.png new file mode 100644 index 000000000..935ad7d94 Binary files /dev/null and b/textures/_r.png differ diff --git a/textures/_r_.png b/textures/_r_.png new file mode 100644 index 000000000..93b4d9221 Binary files /dev/null and b/textures/_r_.png differ diff --git a/textures/_rc.png b/textures/_rc.png new file mode 100644 index 000000000..2f52a5c7b Binary files /dev/null and b/textures/_rc.png differ diff --git a/textures/_re.png b/textures/_re.png new file mode 100644 index 000000000..6e5dad984 Binary files /dev/null and b/textures/_re.png differ diff --git a/textures/_registered.png b/textures/_registered.png new file mode 100644 index 000000000..24e1119b7 Binary files /dev/null and b/textures/_registered.png differ diff --git a/textures/_s.png b/textures/_s.png new file mode 100644 index 000000000..3cf477191 Binary files /dev/null and b/textures/_s.png differ diff --git a/textures/_s_.png b/textures/_s_.png new file mode 100644 index 000000000..019cf9d61 Binary files /dev/null and b/textures/_s_.png differ diff --git a/textures/_sl.png b/textures/_sl.png new file mode 100644 index 000000000..6eaa52234 Binary files /dev/null and b/textures/_sl.png differ diff --git a/textures/_sm.png b/textures/_sm.png new file mode 100644 index 000000000..ad98a7f04 Binary files /dev/null and b/textures/_sm.png differ diff --git a/textures/_sp.png b/textures/_sp.png new file mode 100644 index 000000000..33a32d27e Binary files /dev/null and b/textures/_sp.png differ diff --git a/textures/_sr.png b/textures/_sr.png new file mode 100644 index 000000000..1e1b2d71d Binary files /dev/null and b/textures/_sr.png differ diff --git a/textures/_sz.png b/textures/_sz.png new file mode 100644 index 000000000..30eda6b56 Binary files /dev/null and b/textures/_sz.png differ diff --git a/textures/_t.png b/textures/_t.png new file mode 100644 index 000000000..71ca6641c Binary files /dev/null and b/textures/_t.png differ diff --git a/textures/_t_.png b/textures/_t_.png new file mode 100644 index 000000000..19e54f609 Binary files /dev/null and b/textures/_t_.png differ diff --git a/textures/_thorn.png b/textures/_thorn.png new file mode 100644 index 000000000..88984e0a1 Binary files /dev/null and b/textures/_thorn.png differ diff --git a/textures/_thorn_.png b/textures/_thorn_.png new file mode 100644 index 000000000..72045237b Binary files /dev/null and b/textures/_thorn_.png differ diff --git a/textures/_times_cross.png b/textures/_times_cross.png new file mode 100644 index 000000000..94a510358 Binary files /dev/null and b/textures/_times_cross.png differ diff --git a/textures/_times_dot.png b/textures/_times_dot.png new file mode 100644 index 000000000..b6de2d2d6 Binary files /dev/null and b/textures/_times_dot.png differ diff --git a/textures/_tl.png b/textures/_tl.png new file mode 100644 index 000000000..67fe49939 Binary files /dev/null and b/textures/_tl.png differ diff --git a/textures/_u.png b/textures/_u.png new file mode 100644 index 000000000..226ea15d9 Binary files /dev/null and b/textures/_u.png differ diff --git a/textures/_u_.png b/textures/_u_.png new file mode 100644 index 000000000..acc65373d Binary files /dev/null and b/textures/_u_.png differ diff --git a/textures/_u_acute.png b/textures/_u_acute.png new file mode 100644 index 000000000..fbbf2b439 Binary files /dev/null and b/textures/_u_acute.png differ diff --git a/textures/_u_acute_.png b/textures/_u_acute_.png new file mode 100644 index 000000000..0aec6b5ee Binary files /dev/null and b/textures/_u_acute_.png differ diff --git a/textures/_u_circumflex.png b/textures/_u_circumflex.png new file mode 100644 index 000000000..fae539b48 Binary files /dev/null and b/textures/_u_circumflex.png differ diff --git a/textures/_u_circumflex_.png b/textures/_u_circumflex_.png new file mode 100644 index 000000000..62dacca99 Binary files /dev/null and b/textures/_u_circumflex_.png differ diff --git a/textures/_u_grave.png b/textures/_u_grave.png new file mode 100644 index 000000000..c082d50de Binary files /dev/null and b/textures/_u_grave.png differ diff --git a/textures/_u_grave_.png b/textures/_u_grave_.png new file mode 100644 index 000000000..9c3cbb7c0 Binary files /dev/null and b/textures/_u_grave_.png differ diff --git a/textures/_ue.png b/textures/_ue.png new file mode 100644 index 000000000..6eb803eb4 Binary files /dev/null and b/textures/_ue.png differ diff --git a/textures/_ue_.png b/textures/_ue_.png new file mode 100644 index 000000000..36be264ab Binary files /dev/null and b/textures/_ue_.png differ diff --git a/textures/_un.png b/textures/_un.png new file mode 100644 index 000000000..fba75e8f3 Binary files /dev/null and b/textures/_un.png differ diff --git a/textures/_v.png b/textures/_v.png new file mode 100644 index 000000000..0ce495aab Binary files /dev/null and b/textures/_v.png differ diff --git a/textures/_v_.png b/textures/_v_.png new file mode 100644 index 000000000..0c8988900 Binary files /dev/null and b/textures/_v_.png differ diff --git a/textures/_vb.png b/textures/_vb.png new file mode 100644 index 000000000..941b2b84a Binary files /dev/null and b/textures/_vb.png differ diff --git a/textures/_w.png b/textures/_w.png new file mode 100644 index 000000000..2987f046c Binary files /dev/null and b/textures/_w.png differ diff --git a/textures/_w_.png b/textures/_w_.png new file mode 100644 index 000000000..f1db20d3d Binary files /dev/null and b/textures/_w_.png differ diff --git a/textures/_x.png b/textures/_x.png new file mode 100644 index 000000000..899cf15a4 Binary files /dev/null and b/textures/_x.png differ diff --git a/textures/_x_.png b/textures/_x_.png new file mode 100644 index 000000000..56121585d Binary files /dev/null and b/textures/_x_.png differ diff --git a/textures/_y.png b/textures/_y.png new file mode 100644 index 000000000..458e3bedf Binary files /dev/null and b/textures/_y.png differ diff --git a/textures/_y_.png b/textures/_y_.png new file mode 100644 index 000000000..99a96ad49 Binary files /dev/null and b/textures/_y_.png differ diff --git a/textures/_y_acute.png b/textures/_y_acute.png new file mode 100644 index 000000000..27c478f55 Binary files /dev/null and b/textures/_y_acute.png differ diff --git a/textures/_y_acute_.png b/textures/_y_acute_.png new file mode 100644 index 000000000..45d53337e Binary files /dev/null and b/textures/_y_acute_.png differ diff --git a/textures/_y_diaresis.png b/textures/_y_diaresis.png new file mode 100644 index 000000000..74807b40c Binary files /dev/null and b/textures/_y_diaresis.png differ diff --git a/textures/_yen.png b/textures/_yen.png new file mode 100644 index 000000000..f3f915948 Binary files /dev/null and b/textures/_yen.png differ diff --git a/textures/_z.png b/textures/_z.png new file mode 100644 index 000000000..9bb1200f3 Binary files /dev/null and b/textures/_z.png differ diff --git a/textures/_z_.png b/textures/_z_.png new file mode 100644 index 000000000..ba1d79333 Binary files /dev/null and b/textures/_z_.png differ diff --git a/textures/awards_bg_default.png b/textures/awards_bg_default.png new file mode 100644 index 000000000..7fddfce80 Binary files /dev/null and b/textures/awards_bg_default.png differ diff --git a/textures/awards_bg_mining.png b/textures/awards_bg_mining.png new file mode 100644 index 000000000..fb77b388a Binary files /dev/null and b/textures/awards_bg_mining.png differ diff --git a/mods/HUD/awards/textures/awards_progress_gray.png b/textures/awards_progress_gray.png similarity index 100% rename from mods/HUD/awards/textures/awards_progress_gray.png rename to textures/awards_progress_gray.png diff --git a/mods/HUD/awards/textures/awards_progress_green.png b/textures/awards_progress_green.png similarity index 100% rename from mods/HUD/awards/textures/awards_progress_green.png rename to textures/awards_progress_green.png diff --git a/textures/awards_template.png b/textures/awards_template.png new file mode 100644 index 000000000..159a3bc77 Binary files /dev/null and b/textures/awards_template.png differ diff --git a/textures/awards_ui_icon.png b/textures/awards_ui_icon.png new file mode 100644 index 000000000..c8163008f Binary files /dev/null and b/textures/awards_ui_icon.png differ diff --git a/textures/awards_unknown.png b/textures/awards_unknown.png new file mode 100644 index 000000000..159a3bc77 Binary files /dev/null and b/textures/awards_unknown.png differ diff --git a/textures/beacon_UV.png b/textures/beacon_UV.png new file mode 100644 index 000000000..0f309df34 Binary files /dev/null and b/textures/beacon_UV.png differ diff --git a/textures/beacon_achievement_icon.png b/textures/beacon_achievement_icon.png new file mode 100644 index 000000000..384c48cf7 Binary files /dev/null and b/textures/beacon_achievement_icon.png differ diff --git a/textures/beacon_beam_palette.png b/textures/beacon_beam_palette.png new file mode 100644 index 000000000..bae63d622 Binary files /dev/null and b/textures/beacon_beam_palette.png differ diff --git a/textures/blast_furnace_front.png b/textures/blast_furnace_front.png new file mode 100644 index 000000000..921f58193 Binary files /dev/null and b/textures/blast_furnace_front.png differ diff --git a/textures/blast_furnace_front_on.png b/textures/blast_furnace_front_on.png new file mode 100644 index 000000000..2b2883517 Binary files /dev/null and b/textures/blast_furnace_front_on.png differ diff --git a/textures/blast_furnace_side.png b/textures/blast_furnace_side.png new file mode 100644 index 000000000..f7a419823 Binary files /dev/null and b/textures/blast_furnace_side.png differ diff --git a/textures/blast_furnace_top.png b/textures/blast_furnace_top.png new file mode 100644 index 000000000..42dda0ba4 Binary files /dev/null and b/textures/blast_furnace_top.png differ diff --git a/textures/bubble.png b/textures/bubble.png new file mode 100644 index 000000000..cbbb6705a Binary files /dev/null and b/textures/bubble.png differ diff --git a/textures/cake.png b/textures/cake.png new file mode 100644 index 000000000..db340bd7c Binary files /dev/null and b/textures/cake.png differ diff --git a/textures/cake_bottom.png b/textures/cake_bottom.png new file mode 100644 index 000000000..d7f8602b7 Binary files /dev/null and b/textures/cake_bottom.png differ diff --git a/mods/ITEMS/mcl_cake/textures/cake_inner.png b/textures/cake_inner.png similarity index 100% rename from mods/ITEMS/mcl_cake/textures/cake_inner.png rename to textures/cake_inner.png diff --git a/textures/cake_side.png b/textures/cake_side.png new file mode 100644 index 000000000..f69be02c6 Binary files /dev/null and b/textures/cake_side.png differ diff --git a/textures/cake_top.png b/textures/cake_top.png new file mode 100644 index 000000000..667a5b32a Binary files /dev/null and b/textures/cake_top.png differ diff --git a/textures/character.png b/textures/character.png new file mode 100644 index 000000000..38e8d352b Binary files /dev/null and b/textures/character.png differ diff --git a/textures/crack_anylength.png b/textures/crack_anylength.png new file mode 100644 index 000000000..95d26306c Binary files /dev/null and b/textures/crack_anylength.png differ diff --git a/textures/craftguide_arrow.png b/textures/craftguide_arrow.png new file mode 100644 index 000000000..c27a807c0 Binary files /dev/null and b/textures/craftguide_arrow.png differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_book.png b/textures/craftguide_book.png similarity index 100% rename from mods/HELP/mcl_craftguide/textures/craftguide_book.png rename to textures/craftguide_book.png diff --git a/textures/craftguide_clear_icon.png b/textures/craftguide_clear_icon.png new file mode 100644 index 000000000..12d88f558 Binary files /dev/null and b/textures/craftguide_clear_icon.png differ diff --git a/textures/craftguide_furnace.png b/textures/craftguide_furnace.png new file mode 100644 index 000000000..3b6e10567 Binary files /dev/null and b/textures/craftguide_furnace.png differ diff --git a/textures/craftguide_next_icon.png b/textures/craftguide_next_icon.png new file mode 100644 index 000000000..03f960917 Binary files /dev/null and b/textures/craftguide_next_icon.png differ diff --git a/textures/craftguide_prev_icon.png b/textures/craftguide_prev_icon.png new file mode 100644 index 000000000..71509e71a Binary files /dev/null and b/textures/craftguide_prev_icon.png differ diff --git a/textures/craftguide_search_icon.png b/textures/craftguide_search_icon.png new file mode 100644 index 000000000..9caa134c9 Binary files /dev/null and b/textures/craftguide_search_icon.png differ diff --git a/mods/HELP/mcl_craftguide/textures/craftguide_shapeless.png b/textures/craftguide_shapeless.png similarity index 100% rename from mods/HELP/mcl_craftguide/textures/craftguide_shapeless.png rename to textures/craftguide_shapeless.png diff --git a/textures/craftguide_zoomin_icon.png b/textures/craftguide_zoomin_icon.png new file mode 100644 index 000000000..01d1db597 Binary files /dev/null and b/textures/craftguide_zoomin_icon.png differ diff --git a/textures/craftguide_zoomout_icon.png b/textures/craftguide_zoomout_icon.png new file mode 100644 index 000000000..35a932734 Binary files /dev/null and b/textures/craftguide_zoomout_icon.png differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_active.png b/textures/crafting_creative_active.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_active.png rename to textures/crafting_creative_active.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_active_down.png b/textures/crafting_creative_active_down.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_active_down.png rename to textures/crafting_creative_active_down.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_bg.png b/textures/crafting_creative_bg.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_bg.png rename to textures/crafting_creative_bg.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_bg_dark.png b/textures/crafting_creative_bg_dark.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_bg_dark.png rename to textures/crafting_creative_bg_dark.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_inactive.png b/textures/crafting_creative_inactive.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_inactive.png rename to textures/crafting_creative_inactive.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_inactive_down.png b/textures/crafting_creative_inactive_down.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_inactive_down.png rename to textures/crafting_creative_inactive_down.png diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_marker.png b/textures/crafting_creative_marker.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_marker.png rename to textures/crafting_creative_marker.png diff --git a/textures/crafting_creative_next.png b/textures/crafting_creative_next.png new file mode 100644 index 000000000..35a0ad720 Binary files /dev/null and b/textures/crafting_creative_next.png differ diff --git a/textures/crafting_creative_prev.png b/textures/crafting_creative_prev.png new file mode 100644 index 000000000..309f5c772 Binary files /dev/null and b/textures/crafting_creative_prev.png differ diff --git a/mods/HUD/mcl_inventory/textures/crafting_creative_trash.png b/textures/crafting_creative_trash.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/crafting_creative_trash.png rename to textures/crafting_creative_trash.png diff --git a/textures/crafting_formspec_bg.png b/textures/crafting_formspec_bg.png new file mode 100644 index 000000000..d88e959e4 Binary files /dev/null and b/textures/crafting_formspec_bg.png differ diff --git a/textures/crafting_inventory_creative.png b/textures/crafting_inventory_creative.png new file mode 100644 index 000000000..43664452b Binary files /dev/null and b/textures/crafting_inventory_creative.png differ diff --git a/textures/crafting_inventory_creative_survival.png b/textures/crafting_inventory_creative_survival.png new file mode 100644 index 000000000..ad53b5f4f Binary files /dev/null and b/textures/crafting_inventory_creative_survival.png differ diff --git a/mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_front.png b/textures/crafting_workbench_front.png similarity index 100% rename from mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_front.png rename to textures/crafting_workbench_front.png diff --git a/mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_side.png b/textures/crafting_workbench_side.png similarity index 100% rename from mods/ITEMS/mcl_crafting_table/textures/crafting_workbench_side.png rename to textures/crafting_workbench_side.png diff --git a/textures/crafting_workbench_top.png b/textures/crafting_workbench_top.png new file mode 100644 index 000000000..0a7083366 Binary files /dev/null and b/textures/crafting_workbench_top.png differ diff --git a/textures/credits_bg.png b/textures/credits_bg.png new file mode 100644 index 000000000..280f29def Binary files /dev/null and b/textures/credits_bg.png differ diff --git a/textures/crosshair.png b/textures/crosshair.png new file mode 100644 index 000000000..da9938670 Binary files /dev/null and b/textures/crosshair.png differ diff --git a/textures/custom_beacom_symbol_1.png b/textures/custom_beacom_symbol_1.png new file mode 100644 index 000000000..7e013873b Binary files /dev/null and b/textures/custom_beacom_symbol_1.png differ diff --git a/textures/custom_beacom_symbol_2.png b/textures/custom_beacom_symbol_2.png new file mode 100644 index 000000000..308636a40 Binary files /dev/null and b/textures/custom_beacom_symbol_2.png differ diff --git a/textures/custom_beacom_symbol_3.png b/textures/custom_beacom_symbol_3.png new file mode 100644 index 000000000..395beddb1 Binary files /dev/null and b/textures/custom_beacom_symbol_3.png differ diff --git a/textures/custom_beacom_symbol_4.png b/textures/custom_beacom_symbol_4.png new file mode 100644 index 000000000..1b11f3b3e Binary files /dev/null and b/textures/custom_beacom_symbol_4.png differ diff --git a/textures/default_acacia_leaves.png b/textures/default_acacia_leaves.png new file mode 100644 index 000000000..41b4532f2 Binary files /dev/null and b/textures/default_acacia_leaves.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_acacia_sapling.png b/textures/default_acacia_sapling.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_acacia_sapling.png rename to textures/default_acacia_sapling.png diff --git a/textures/default_acacia_tree.png b/textures/default_acacia_tree.png new file mode 100644 index 000000000..97ac9575a Binary files /dev/null and b/textures/default_acacia_tree.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_acacia_tree_top.png b/textures/default_acacia_tree_top.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_acacia_tree_top.png rename to textures/default_acacia_tree_top.png diff --git a/mods/ITEMS/mcl_core/textures/default_acacia_wood.png b/textures/default_acacia_wood.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_acacia_wood.png rename to textures/default_acacia_wood.png diff --git a/mods/ITEMS/mcl_core/textures/default_apple.png b/textures/default_apple.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_apple.png rename to textures/default_apple.png diff --git a/mods/ITEMS/mcl_books/textures/default_book.png b/textures/default_book.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/default_book.png rename to textures/default_book.png diff --git a/mods/ITEMS/mcl_books/textures/default_bookshelf.png b/textures/default_bookshelf.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/default_bookshelf.png rename to textures/default_bookshelf.png diff --git a/textures/default_brick.png b/textures/default_brick.png new file mode 100644 index 000000000..af999b9c3 Binary files /dev/null and b/textures/default_brick.png differ diff --git a/textures/default_clay.png b/textures/default_clay.png new file mode 100644 index 000000000..1e412de3b Binary files /dev/null and b/textures/default_clay.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_clay_brick.png b/textures/default_clay_brick.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_clay_brick.png rename to textures/default_clay_brick.png diff --git a/mods/ITEMS/mcl_core/textures/default_clay_lump.png b/textures/default_clay_lump.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_clay_lump.png rename to textures/default_clay_lump.png diff --git a/textures/default_coal_block.png b/textures/default_coal_block.png new file mode 100644 index 000000000..c99e4a589 Binary files /dev/null and b/textures/default_coal_block.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_coal_lump.png b/textures/default_coal_lump.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_coal_lump.png rename to textures/default_coal_lump.png diff --git a/textures/default_cobble.png b/textures/default_cobble.png new file mode 100644 index 000000000..4fcae123f Binary files /dev/null and b/textures/default_cobble.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_diamond.png b/textures/default_diamond.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_diamond.png rename to textures/default_diamond.png diff --git a/mods/ITEMS/mcl_core/textures/default_diamond_block.png b/textures/default_diamond_block.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_diamond_block.png rename to textures/default_diamond_block.png diff --git a/textures/default_dirt.png b/textures/default_dirt.png new file mode 100644 index 000000000..3c57e2cb8 Binary files /dev/null and b/textures/default_dirt.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_dry_shrub.png b/textures/default_dry_shrub.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_dry_shrub.png rename to textures/default_dry_shrub.png diff --git a/mods/ITEMS/mcl_core/textures/default_flint.png b/textures/default_flint.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_flint.png rename to textures/default_flint.png diff --git a/textures/default_furnace_bottom.png b/textures/default_furnace_bottom.png new file mode 100644 index 000000000..c8efce2fe Binary files /dev/null and b/textures/default_furnace_bottom.png differ diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_fire_bg.png b/textures/default_furnace_fire_bg.png similarity index 100% rename from mods/ITEMS/mcl_furnaces/textures/default_furnace_fire_bg.png rename to textures/default_furnace_fire_bg.png diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_fire_fg.png b/textures/default_furnace_fire_fg.png similarity index 100% rename from mods/ITEMS/mcl_furnaces/textures/default_furnace_fire_fg.png rename to textures/default_furnace_fire_fg.png diff --git a/mods/ITEMS/mcl_furnaces/textures/default_furnace_front.png b/textures/default_furnace_front.png similarity index 100% rename from mods/ITEMS/mcl_furnaces/textures/default_furnace_front.png rename to textures/default_furnace_front.png diff --git a/textures/default_furnace_front_active.png b/textures/default_furnace_front_active.png new file mode 100644 index 000000000..3b6e10567 Binary files /dev/null and b/textures/default_furnace_front_active.png differ diff --git a/textures/default_furnace_side.png b/textures/default_furnace_side.png new file mode 100644 index 000000000..2c364db5d Binary files /dev/null and b/textures/default_furnace_side.png differ diff --git a/textures/default_furnace_top.png b/textures/default_furnace_top.png new file mode 100644 index 000000000..c8efce2fe Binary files /dev/null and b/textures/default_furnace_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_glass.png b/textures/default_glass.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_glass.png rename to textures/default_glass.png diff --git a/textures/default_glass_detail.png b/textures/default_glass_detail.png new file mode 100644 index 000000000..6205f84a5 Binary files /dev/null and b/textures/default_glass_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_gold_block.png b/textures/default_gold_block.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_gold_block.png rename to textures/default_gold_block.png diff --git a/mods/ITEMS/mcl_core/textures/default_gold_ingot.png b/textures/default_gold_ingot.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_gold_ingot.png rename to textures/default_gold_ingot.png diff --git a/textures/default_gravel.png b/textures/default_gravel.png new file mode 100644 index 000000000..d1934221b Binary files /dev/null and b/textures/default_gravel.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/default_gunpowder.png b/textures/default_gunpowder.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/default_gunpowder.png rename to textures/default_gunpowder.png diff --git a/textures/default_ice.png b/textures/default_ice.png new file mode 100644 index 000000000..71da475ef Binary files /dev/null and b/textures/default_ice.png differ diff --git a/textures/default_jungleleaves.png b/textures/default_jungleleaves.png new file mode 100644 index 000000000..0e48272af Binary files /dev/null and b/textures/default_jungleleaves.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_junglesapling.png b/textures/default_junglesapling.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_junglesapling.png rename to textures/default_junglesapling.png diff --git a/mods/ITEMS/mcl_core/textures/default_jungletree.png b/textures/default_jungletree.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_jungletree.png rename to textures/default_jungletree.png diff --git a/textures/default_jungletree_top.png b/textures/default_jungletree_top.png new file mode 100644 index 000000000..1bfadcf1e Binary files /dev/null and b/textures/default_jungletree_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_junglewood.png b/textures/default_junglewood.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_junglewood.png rename to textures/default_junglewood.png diff --git a/mods/ITEMS/mcl_core/textures/default_ladder.png b/textures/default_ladder.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_ladder.png rename to textures/default_ladder.png diff --git a/mods/ITEMS/mcl_core/textures/default_lava_flowing_animated.png b/textures/default_lava_flowing_animated.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_lava_flowing_animated.png rename to textures/default_lava_flowing_animated.png diff --git a/mods/ITEMS/mcl_core/textures/default_lava_source_animated.png b/textures/default_lava_source_animated.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_lava_source_animated.png rename to textures/default_lava_source_animated.png diff --git a/textures/default_leaves.png b/textures/default_leaves.png new file mode 100644 index 000000000..a1d8c76a7 Binary files /dev/null and b/textures/default_leaves.png differ diff --git a/textures/default_mossycobble.png b/textures/default_mossycobble.png new file mode 100644 index 000000000..c1c3a61e5 Binary files /dev/null and b/textures/default_mossycobble.png differ diff --git a/textures/default_obsidian.png b/textures/default_obsidian.png new file mode 100644 index 000000000..9dea64f06 Binary files /dev/null and b/textures/default_obsidian.png differ diff --git a/textures/default_paper.png b/textures/default_paper.png new file mode 100644 index 000000000..0e8b1f604 Binary files /dev/null and b/textures/default_paper.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/default_rail.png b/textures/default_rail.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/default_rail.png rename to textures/default_rail.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/default_rail_crossing.png b/textures/default_rail_crossing.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/default_rail_crossing.png rename to textures/default_rail_crossing.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/default_rail_curved.png b/textures/default_rail_curved.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/default_rail_curved.png rename to textures/default_rail_curved.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/default_rail_t_junction.png b/textures/default_rail_t_junction.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/default_rail_t_junction.png rename to textures/default_rail_t_junction.png diff --git a/textures/default_sand.png b/textures/default_sand.png new file mode 100644 index 000000000..4d6071fd0 Binary files /dev/null and b/textures/default_sand.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_sapling.png b/textures/default_sapling.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_sapling.png rename to textures/default_sapling.png diff --git a/mods/ITEMS/mcl_core/textures/default_snow.png b/textures/default_snow.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_snow.png rename to textures/default_snow.png diff --git a/mods/ITEMS/mcl_core/textures/default_steel_block.png b/textures/default_steel_block.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_steel_block.png rename to textures/default_steel_block.png diff --git a/mods/ITEMS/mcl_core/textures/default_steel_ingot.png b/textures/default_steel_ingot.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_steel_ingot.png rename to textures/default_steel_ingot.png diff --git a/mods/ITEMS/mcl_core/textures/default_stick.png b/textures/default_stick.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_stick.png rename to textures/default_stick.png diff --git a/textures/default_stone.png b/textures/default_stone.png new file mode 100644 index 000000000..9e9145af9 Binary files /dev/null and b/textures/default_stone.png differ diff --git a/textures/default_stone_brick.png b/textures/default_stone_brick.png new file mode 100644 index 000000000..62a22c8d1 Binary files /dev/null and b/textures/default_stone_brick.png differ diff --git a/textures/default_tnt_bottom.png b/textures/default_tnt_bottom.png new file mode 100644 index 000000000..6f1f6ec56 Binary files /dev/null and b/textures/default_tnt_bottom.png differ diff --git a/textures/default_tnt_side.png b/textures/default_tnt_side.png new file mode 100644 index 000000000..d5eb0ca9f Binary files /dev/null and b/textures/default_tnt_side.png differ diff --git a/textures/default_tnt_top.png b/textures/default_tnt_top.png new file mode 100644 index 000000000..5dea7c67a Binary files /dev/null and b/textures/default_tnt_top.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_diamondaxe.png b/textures/default_tool_diamondaxe.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_diamondaxe.png rename to textures/default_tool_diamondaxe.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_diamondpick.png b/textures/default_tool_diamondpick.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_diamondpick.png rename to textures/default_tool_diamondpick.png diff --git a/textures/default_tool_diamondshovel.png b/textures/default_tool_diamondshovel.png new file mode 100644 index 000000000..9763dcb28 Binary files /dev/null and b/textures/default_tool_diamondshovel.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_diamondsword.png b/textures/default_tool_diamondsword.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_diamondsword.png rename to textures/default_tool_diamondsword.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_goldaxe.png b/textures/default_tool_goldaxe.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_goldaxe.png rename to textures/default_tool_goldaxe.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_goldpick.png b/textures/default_tool_goldpick.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_goldpick.png rename to textures/default_tool_goldpick.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_goldshovel.png b/textures/default_tool_goldshovel.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_goldshovel.png rename to textures/default_tool_goldshovel.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_goldsword.png b/textures/default_tool_goldsword.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_goldsword.png rename to textures/default_tool_goldsword.png diff --git a/textures/default_tool_netheriteaxe.png b/textures/default_tool_netheriteaxe.png new file mode 100644 index 000000000..19f607e3f Binary files /dev/null and b/textures/default_tool_netheriteaxe.png differ diff --git a/textures/default_tool_netheritepick.png b/textures/default_tool_netheritepick.png new file mode 100644 index 000000000..aabafe591 Binary files /dev/null and b/textures/default_tool_netheritepick.png differ diff --git a/textures/default_tool_netheriteshovel.png b/textures/default_tool_netheriteshovel.png new file mode 100644 index 000000000..7561e1d34 Binary files /dev/null and b/textures/default_tool_netheriteshovel.png differ diff --git a/textures/default_tool_netheritesword.png b/textures/default_tool_netheritesword.png new file mode 100644 index 000000000..baadc8ba9 Binary files /dev/null and b/textures/default_tool_netheritesword.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_shears.png b/textures/default_tool_shears.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_shears.png rename to textures/default_tool_shears.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_steelaxe.png b/textures/default_tool_steelaxe.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_steelaxe.png rename to textures/default_tool_steelaxe.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_steelpick.png b/textures/default_tool_steelpick.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_steelpick.png rename to textures/default_tool_steelpick.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_steelshovel.png b/textures/default_tool_steelshovel.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_steelshovel.png rename to textures/default_tool_steelshovel.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_steelsword.png b/textures/default_tool_steelsword.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_steelsword.png rename to textures/default_tool_steelsword.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_stoneaxe.png b/textures/default_tool_stoneaxe.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_stoneaxe.png rename to textures/default_tool_stoneaxe.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_stonepick.png b/textures/default_tool_stonepick.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_stonepick.png rename to textures/default_tool_stonepick.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_stoneshovel.png b/textures/default_tool_stoneshovel.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_stoneshovel.png rename to textures/default_tool_stoneshovel.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_stonesword.png b/textures/default_tool_stonesword.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_stonesword.png rename to textures/default_tool_stonesword.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_woodaxe.png b/textures/default_tool_woodaxe.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_woodaxe.png rename to textures/default_tool_woodaxe.png diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_woodpick.png b/textures/default_tool_woodpick.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_woodpick.png rename to textures/default_tool_woodpick.png diff --git a/textures/default_tool_woodshovel.png b/textures/default_tool_woodshovel.png new file mode 100644 index 000000000..905050565 Binary files /dev/null and b/textures/default_tool_woodshovel.png differ diff --git a/mods/ITEMS/mcl_tools/textures/default_tool_woodsword.png b/textures/default_tool_woodsword.png similarity index 100% rename from mods/ITEMS/mcl_tools/textures/default_tool_woodsword.png rename to textures/default_tool_woodsword.png diff --git a/textures/default_torch_on_floor.png b/textures/default_torch_on_floor.png new file mode 100644 index 000000000..935bb71a6 Binary files /dev/null and b/textures/default_torch_on_floor.png differ diff --git a/textures/default_torch_on_floor_animated.png b/textures/default_torch_on_floor_animated.png new file mode 100644 index 000000000..3760d3639 Binary files /dev/null and b/textures/default_torch_on_floor_animated.png differ diff --git a/mods/ITEMS/mcl_core/textures/default_tree.png b/textures/default_tree.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_tree.png rename to textures/default_tree.png diff --git a/mods/ITEMS/mcl_core/textures/default_tree_top.png b/textures/default_tree_top.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/default_tree_top.png rename to textures/default_tree_top.png diff --git a/textures/default_water_flowing_animated.png b/textures/default_water_flowing_animated.png new file mode 100644 index 000000000..bf1140668 Binary files /dev/null and b/textures/default_water_flowing_animated.png differ diff --git a/textures/default_water_source_animated.png b/textures/default_water_source_animated.png new file mode 100644 index 000000000..e148da244 Binary files /dev/null and b/textures/default_water_source_animated.png differ diff --git a/textures/default_wood.png b/textures/default_wood.png new file mode 100644 index 000000000..aaaa2b48e Binary files /dev/null and b/textures/default_wood.png differ diff --git a/textures/doc_awards_icon_generic.png b/textures/doc_awards_icon_generic.png new file mode 100644 index 000000000..6d1ddfac4 Binary files /dev/null and b/textures/doc_awards_icon_generic.png differ diff --git a/textures/doc_basics_build.png b/textures/doc_basics_build.png new file mode 100644 index 000000000..8394eef19 Binary files /dev/null and b/textures/doc_basics_build.png differ diff --git a/textures/doc_basics_camera_behind.png b/textures/doc_basics_camera_behind.png new file mode 100644 index 000000000..1bc9cddf1 Binary files /dev/null and b/textures/doc_basics_camera_behind.png differ diff --git a/textures/doc_basics_camera_ego.png b/textures/doc_basics_camera_ego.png new file mode 100644 index 000000000..7c95c512f Binary files /dev/null and b/textures/doc_basics_camera_ego.png differ diff --git a/textures/doc_basics_camera_front.png b/textures/doc_basics_camera_front.png new file mode 100644 index 000000000..124c19afa Binary files /dev/null and b/textures/doc_basics_camera_front.png differ diff --git a/textures/doc_basics_craft_grid.png b/textures/doc_basics_craft_grid.png new file mode 100644 index 000000000..d66786511 Binary files /dev/null and b/textures/doc_basics_craft_grid.png differ diff --git a/textures/doc_basics_craft_groups_1.png b/textures/doc_basics_craft_groups_1.png new file mode 100644 index 000000000..4093c50b1 Binary files /dev/null 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 new file mode 100644 index 000000000..a70bdde42 Binary files /dev/null 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 new file mode 100644 index 000000000..60a568be0 Binary files /dev/null and b/textures/doc_basics_craft_groups_3.png differ diff --git a/textures/doc_basics_craft_repair.png b/textures/doc_basics_craft_repair.png new file mode 100644 index 000000000..8b5420784 Binary files /dev/null and b/textures/doc_basics_craft_repair.png differ diff --git a/textures/doc_basics_craft_shaped.png b/textures/doc_basics_craft_shaped.png new file mode 100644 index 000000000..950c55d79 Binary files /dev/null and b/textures/doc_basics_craft_shaped.png differ diff --git a/textures/doc_basics_craft_shapeless_1.png b/textures/doc_basics_craft_shapeless_1.png new file mode 100644 index 000000000..684abfbfb Binary files /dev/null and b/textures/doc_basics_craft_shapeless_1.png differ diff --git a/textures/doc_basics_craft_shapeless_2.png b/textures/doc_basics_craft_shapeless_2.png new file mode 100644 index 000000000..aa40440da Binary files /dev/null and b/textures/doc_basics_craft_shapeless_2.png differ diff --git a/textures/doc_basics_gameplay_carbone_ng.png b/textures/doc_basics_gameplay_carbone_ng.png new file mode 100644 index 000000000..80a38a06b Binary files /dev/null and b/textures/doc_basics_gameplay_carbone_ng.png differ diff --git a/textures/doc_basics_gameplay_hades.png b/textures/doc_basics_gameplay_hades.png new file mode 100644 index 000000000..44b93872d Binary files /dev/null and b/textures/doc_basics_gameplay_hades.png differ diff --git a/textures/doc_basics_gameplay_lott.png b/textures/doc_basics_gameplay_lott.png new file mode 100644 index 000000000..e8340e6e5 Binary files /dev/null and b/textures/doc_basics_gameplay_lott.png differ diff --git a/textures/doc_basics_gameplay_moontest.png b/textures/doc_basics_gameplay_moontest.png new file mode 100644 index 000000000..82350d8cc Binary files /dev/null and b/textures/doc_basics_gameplay_moontest.png differ diff --git a/textures/doc_basics_gameplay_mtg_1.png b/textures/doc_basics_gameplay_mtg_1.png new file mode 100644 index 000000000..eaa55fe84 Binary files /dev/null and b/textures/doc_basics_gameplay_mtg_1.png differ diff --git a/textures/doc_basics_gameplay_mtg_2.png b/textures/doc_basics_gameplay_mtg_2.png new file mode 100644 index 000000000..68c8a5063 Binary files /dev/null and b/textures/doc_basics_gameplay_mtg_2.png differ diff --git a/textures/doc_basics_gameplay_outback.png b/textures/doc_basics_gameplay_outback.png new file mode 100644 index 000000000..e2f9f095c Binary files /dev/null and b/textures/doc_basics_gameplay_outback.png differ diff --git a/textures/doc_basics_gameplay_pixture.png b/textures/doc_basics_gameplay_pixture.png new file mode 100644 index 000000000..fe43163f7 Binary files /dev/null and b/textures/doc_basics_gameplay_pixture.png differ diff --git a/textures/doc_basics_gameplay_xtraores_xtension.png b/textures/doc_basics_gameplay_xtraores_xtension.png new file mode 100644 index 000000000..83a280a65 Binary files /dev/null and b/textures/doc_basics_gameplay_xtraores_xtension.png differ diff --git a/textures/doc_basics_hotbar.png b/textures/doc_basics_hotbar.png new file mode 100644 index 000000000..6a8f82ffc Binary files /dev/null and b/textures/doc_basics_hotbar.png differ diff --git a/textures/doc_basics_hotbar_relations.png b/textures/doc_basics_hotbar_relations.png new file mode 100644 index 000000000..b63943880 Binary files /dev/null and b/textures/doc_basics_hotbar_relations.png differ diff --git a/textures/doc_basics_inventory.png b/textures/doc_basics_inventory.png new file mode 100644 index 000000000..3001c0d81 Binary files /dev/null and b/textures/doc_basics_inventory.png differ diff --git a/textures/doc_basics_inventory_detail.png b/textures/doc_basics_inventory_detail.png new file mode 100644 index 000000000..da3111030 Binary files /dev/null and b/textures/doc_basics_inventory_detail.png differ diff --git a/textures/doc_basics_items_dropped.png b/textures/doc_basics_items_dropped.png new file mode 100644 index 000000000..2d4b92450 Binary files /dev/null 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 new file mode 100644 index 000000000..9b4a24f5a Binary files /dev/null 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 new file mode 100644 index 000000000..0fc840595 Binary files /dev/null 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 new file mode 100644 index 000000000..f38bbb316 Binary files /dev/null and b/textures/doc_basics_liquids_nonrenewable.png differ diff --git a/textures/doc_basics_liquids_range.png b/textures/doc_basics_liquids_range.png new file mode 100644 index 000000000..fef9edf6f Binary files /dev/null and b/textures/doc_basics_liquids_range.png differ diff --git a/textures/doc_basics_liquids_renewable_1.png b/textures/doc_basics_liquids_renewable_1.png new file mode 100644 index 000000000..67691081e Binary files /dev/null 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 new file mode 100644 index 000000000..63a5cea1b Binary files /dev/null and b/textures/doc_basics_liquids_renewable_2.png differ diff --git a/textures/doc_basics_liquids_types.png b/textures/doc_basics_liquids_types.png new file mode 100644 index 000000000..64484e17f Binary files /dev/null and b/textures/doc_basics_liquids_types.png differ diff --git a/textures/doc_basics_minimap_map.png b/textures/doc_basics_minimap_map.png new file mode 100644 index 000000000..63f4a9bac Binary files /dev/null and b/textures/doc_basics_minimap_map.png differ diff --git a/textures/doc_basics_minimap_radar.png b/textures/doc_basics_minimap_radar.png new file mode 100644 index 000000000..b2368d0a4 Binary files /dev/null and b/textures/doc_basics_minimap_radar.png differ diff --git a/textures/doc_basics_minimap_round.png b/textures/doc_basics_minimap_round.png new file mode 100644 index 000000000..4f6753dac Binary files /dev/null and b/textures/doc_basics_minimap_round.png differ diff --git a/textures/doc_basics_nodes.png b/textures/doc_basics_nodes.png new file mode 100644 index 000000000..0b3b22f64 Binary files /dev/null and b/textures/doc_basics_nodes.png differ diff --git a/textures/doc_basics_players_flat.png b/textures/doc_basics_players_flat.png new file mode 100644 index 000000000..a46fcb658 Binary files /dev/null and b/textures/doc_basics_players_flat.png differ diff --git a/textures/doc_basics_players_lott.png b/textures/doc_basics_players_lott.png new file mode 100644 index 000000000..13419b8e8 Binary files /dev/null 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 new file mode 100644 index 000000000..4281ca588 Binary files /dev/null and b/textures/doc_basics_players_sam.png differ diff --git a/textures/doc_basics_pointing.png b/textures/doc_basics_pointing.png new file mode 100644 index 000000000..dda1580f1 Binary files /dev/null and b/textures/doc_basics_pointing.png differ diff --git a/textures/doc_basics_sneak.png b/textures/doc_basics_sneak.png new file mode 100644 index 000000000..bcde6ce52 Binary files /dev/null and b/textures/doc_basics_sneak.png differ diff --git a/textures/doc_basics_tools.png b/textures/doc_basics_tools.png new file mode 100644 index 000000000..82af52d1a Binary files /dev/null and b/textures/doc_basics_tools.png differ diff --git a/textures/doc_basics_tools_mining.png b/textures/doc_basics_tools_mining.png new file mode 100644 index 000000000..1395b890c Binary files /dev/null and b/textures/doc_basics_tools_mining.png differ diff --git a/textures/doc_button_icon_hires.png b/textures/doc_button_icon_hires.png new file mode 100644 index 000000000..a580f657f Binary files /dev/null and b/textures/doc_button_icon_hires.png differ diff --git a/textures/doc_button_icon_lores.png b/textures/doc_button_icon_lores.png new file mode 100644 index 000000000..b3ebe6f4a Binary files /dev/null and b/textures/doc_button_icon_lores.png differ diff --git a/textures/doc_identifier_identifier.png b/textures/doc_identifier_identifier.png new file mode 100644 index 000000000..09480ef07 Binary files /dev/null and b/textures/doc_identifier_identifier.png differ diff --git a/mods/HELP/doc/doc_identifier/textures/doc_identifier_identifier_liquid.png b/textures/doc_identifier_identifier_liquid.png similarity index 100% rename from mods/HELP/doc/doc_identifier/textures/doc_identifier_identifier_liquid.png rename to textures/doc_identifier_identifier_liquid.png diff --git a/textures/doors_item_steel.png b/textures/doors_item_steel.png new file mode 100644 index 000000000..8235deace Binary files /dev/null and b/textures/doors_item_steel.png differ diff --git a/textures/doors_item_wood.png b/textures/doors_item_wood.png new file mode 100644 index 000000000..6a074e137 Binary files /dev/null and b/textures/doors_item_wood.png differ diff --git a/mods/ITEMS/mcl_doors/textures/doors_trapdoor.png b/textures/doors_trapdoor.png similarity index 100% rename from mods/ITEMS/mcl_doors/textures/doors_trapdoor.png rename to textures/doors_trapdoor.png diff --git a/textures/doors_trapdoor_side.png b/textures/doors_trapdoor_side.png new file mode 100644 index 000000000..acdd1e22f Binary files /dev/null and b/textures/doors_trapdoor_side.png differ diff --git a/textures/doors_trapdoor_steel.png b/textures/doors_trapdoor_steel.png new file mode 100644 index 000000000..eba795b31 Binary files /dev/null and b/textures/doors_trapdoor_steel.png differ diff --git a/textures/doors_trapdoor_steel_side.png b/textures/doors_trapdoor_steel_side.png new file mode 100644 index 000000000..54008f215 Binary files /dev/null and b/textures/doors_trapdoor_steel_side.png differ diff --git a/textures/extra_mobs_dolphin.png b/textures/extra_mobs_dolphin.png new file mode 100644 index 000000000..352cd8253 Binary files /dev/null and b/textures/extra_mobs_dolphin.png differ diff --git a/textures/extra_mobs_hoglin.png b/textures/extra_mobs_hoglin.png new file mode 100644 index 000000000..43f28d1db Binary files /dev/null and b/textures/extra_mobs_hoglin.png differ diff --git a/textures/extra_mobs_piglin.png b/textures/extra_mobs_piglin.png new file mode 100644 index 000000000..3be9eda37 Binary files /dev/null and b/textures/extra_mobs_piglin.png differ diff --git a/textures/extra_mobs_piglin_brute.png b/textures/extra_mobs_piglin_brute.png new file mode 100644 index 000000000..9554d5226 Binary files /dev/null and b/textures/extra_mobs_piglin_brute.png differ diff --git a/textures/extra_mobs_strider.png b/textures/extra_mobs_strider.png new file mode 100644 index 000000000..a608f5fd0 Binary files /dev/null and b/textures/extra_mobs_strider.png differ diff --git a/textures/extra_mobs_strider_cold.png b/textures/extra_mobs_strider_cold.png new file mode 100644 index 000000000..c952ed780 Binary files /dev/null and b/textures/extra_mobs_strider_cold.png differ diff --git a/textures/extra_mobs_tropical_fish_a.png b/textures/extra_mobs_tropical_fish_a.png new file mode 100644 index 000000000..1c30b9194 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_a.png differ diff --git a/textures/extra_mobs_tropical_fish_b.png b/textures/extra_mobs_tropical_fish_b.png new file mode 100644 index 000000000..97c9d2b3e Binary files /dev/null and b/textures/extra_mobs_tropical_fish_b.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_1.png b/textures/extra_mobs_tropical_fish_pattern_a_1.png new file mode 100644 index 000000000..89787fcce Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_1.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_2.png b/textures/extra_mobs_tropical_fish_pattern_a_2.png new file mode 100644 index 000000000..c7e9426b8 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_2.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_3.png b/textures/extra_mobs_tropical_fish_pattern_a_3.png new file mode 100644 index 000000000..6db48a7ce Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_3.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_4.png b/textures/extra_mobs_tropical_fish_pattern_a_4.png new file mode 100644 index 000000000..a56dc0f80 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_4.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_5.png b/textures/extra_mobs_tropical_fish_pattern_a_5.png new file mode 100644 index 000000000..1b7c96756 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_5.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_a_6.png b/textures/extra_mobs_tropical_fish_pattern_a_6.png new file mode 100644 index 000000000..0b2ce4f71 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_a_6.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_1.png b/textures/extra_mobs_tropical_fish_pattern_b_1.png new file mode 100644 index 000000000..f33aaa803 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_1.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_2.png b/textures/extra_mobs_tropical_fish_pattern_b_2.png new file mode 100644 index 000000000..edfb5a5e0 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_2.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_3.png b/textures/extra_mobs_tropical_fish_pattern_b_3.png new file mode 100644 index 000000000..4878e813a Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_3.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_4.png b/textures/extra_mobs_tropical_fish_pattern_b_4.png new file mode 100644 index 000000000..9a4315be6 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_4.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_5.png b/textures/extra_mobs_tropical_fish_pattern_b_5.png new file mode 100644 index 000000000..b5664eb38 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_5.png differ diff --git a/textures/extra_mobs_tropical_fish_pattern_b_6.png b/textures/extra_mobs_tropical_fish_pattern_b_6.png new file mode 100644 index 000000000..43204ece9 Binary files /dev/null and b/textures/extra_mobs_tropical_fish_pattern_b_6.png differ diff --git a/textures/extra_mobs_zoglin.png b/textures/extra_mobs_zoglin.png new file mode 100644 index 000000000..122e6f67a Binary files /dev/null and b/textures/extra_mobs_zoglin.png differ diff --git a/textures/extra_mobs_zombified_piglin.png b/textures/extra_mobs_zombified_piglin.png new file mode 100644 index 000000000..f514c54b8 Binary files /dev/null and b/textures/extra_mobs_zombified_piglin.png differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_bread.png b/textures/farming_bread.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_bread.png rename to textures/farming_bread.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot.png b/textures/farming_carrot.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_carrot.png rename to textures/farming_carrot.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot_1.png b/textures/farming_carrot_1.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_carrot_1.png rename to textures/farming_carrot_1.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot_2.png b/textures/farming_carrot_2.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_carrot_2.png rename to textures/farming_carrot_2.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot_3.png b/textures/farming_carrot_3.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_carrot_3.png rename to textures/farming_carrot_3.png diff --git a/textures/farming_carrot_4.png b/textures/farming_carrot_4.png new file mode 100644 index 000000000..403257f44 Binary files /dev/null and b/textures/farming_carrot_4.png differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_carrot_gold.png b/textures/farming_carrot_gold.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_carrot_gold.png rename to textures/farming_carrot_gold.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_cookie.png b/textures/farming_cookie.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_cookie.png rename to textures/farming_cookie.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_melon.png b/textures/farming_melon.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_melon.png rename to textures/farming_melon.png diff --git a/textures/farming_melon_side.png b/textures/farming_melon_side.png new file mode 100644 index 000000000..0979b7206 Binary files /dev/null and b/textures/farming_melon_side.png differ diff --git a/textures/farming_melon_top.png b/textures/farming_melon_top.png new file mode 100644 index 000000000..8738599c9 Binary files /dev/null and b/textures/farming_melon_top.png differ diff --git a/textures/farming_mushroom_brown.png b/textures/farming_mushroom_brown.png new file mode 100644 index 000000000..ae2d83cd1 Binary files /dev/null and b/textures/farming_mushroom_brown.png differ diff --git a/textures/farming_mushroom_red.png b/textures/farming_mushroom_red.png new file mode 100644 index 000000000..ac1725b3a Binary files /dev/null and b/textures/farming_mushroom_red.png differ diff --git a/mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_stew.png b/textures/farming_mushroom_stew.png similarity index 100% rename from mods/ITEMS/mcl_mushrooms/textures/farming_mushroom_stew.png rename to textures/farming_mushroom_stew.png diff --git a/textures/farming_potato.png b/textures/farming_potato.png new file mode 100644 index 000000000..70e3a7e03 Binary files /dev/null and b/textures/farming_potato.png differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_potato_baked.png b/textures/farming_potato_baked.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_potato_baked.png rename to textures/farming_potato_baked.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_potato_poison.png b/textures/farming_potato_poison.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_potato_poison.png rename to textures/farming_potato_poison.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_face.png b/textures/farming_pumpkin_face.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_pumpkin_face.png rename to textures/farming_pumpkin_face.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_pumpkin_face_light.png b/textures/farming_pumpkin_face_light.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_pumpkin_face_light.png rename to textures/farming_pumpkin_face_light.png diff --git a/textures/farming_pumpkin_side.png b/textures/farming_pumpkin_side.png new file mode 100644 index 000000000..a1a4fa9be Binary files /dev/null and b/textures/farming_pumpkin_side.png differ diff --git a/textures/farming_pumpkin_top.png b/textures/farming_pumpkin_top.png new file mode 100644 index 000000000..01cde9e90 Binary files /dev/null and b/textures/farming_pumpkin_top.png differ diff --git a/textures/farming_tool_diamondhoe.png b/textures/farming_tool_diamondhoe.png new file mode 100644 index 000000000..f74cc4afd Binary files /dev/null and b/textures/farming_tool_diamondhoe.png differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_goldhoe.png b/textures/farming_tool_goldhoe.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_tool_goldhoe.png rename to textures/farming_tool_goldhoe.png diff --git a/textures/farming_tool_netheritehoe.png b/textures/farming_tool_netheritehoe.png new file mode 100644 index 000000000..136f65fb9 Binary files /dev/null and b/textures/farming_tool_netheritehoe.png differ diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_steelhoe.png b/textures/farming_tool_steelhoe.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_tool_steelhoe.png rename to textures/farming_tool_steelhoe.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_stonehoe.png b/textures/farming_tool_stonehoe.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_tool_stonehoe.png rename to textures/farming_tool_stonehoe.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_tool_woodhoe.png b/textures/farming_tool_woodhoe.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_tool_woodhoe.png rename to textures/farming_tool_woodhoe.png diff --git a/mods/ITEMS/mcl_farming/textures/farming_wheat_harvested.png b/textures/farming_wheat_harvested.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/farming_wheat_harvested.png rename to textures/farming_wheat_harvested.png diff --git a/textures/fire_basic_flame.png b/textures/fire_basic_flame.png new file mode 100644 index 000000000..f87969a38 Binary files /dev/null and b/textures/fire_basic_flame.png differ diff --git a/mods/ITEMS/mcl_fire/textures/fire_basic_flame_animated.png b/textures/fire_basic_flame_animated.png similarity index 100% rename from mods/ITEMS/mcl_fire/textures/fire_basic_flame_animated.png rename to textures/fire_basic_flame_animated.png diff --git a/textures/fletching_table_bottom.png b/textures/fletching_table_bottom.png new file mode 100644 index 000000000..380b2e61c Binary files /dev/null and b/textures/fletching_table_bottom.png differ diff --git a/textures/fletching_table_front.png b/textures/fletching_table_front.png new file mode 100644 index 000000000..c5919daee Binary files /dev/null and b/textures/fletching_table_front.png differ diff --git a/textures/fletching_table_side.png b/textures/fletching_table_side.png new file mode 100644 index 000000000..649010fdf Binary files /dev/null and b/textures/fletching_table_side.png differ diff --git a/textures/fletching_table_top.png b/textures/fletching_table_top.png new file mode 100644 index 000000000..d74115b5a Binary files /dev/null and b/textures/fletching_table_top.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/flowers_dandelion_yellow.png b/textures/flowers_dandelion_yellow.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/flowers_dandelion_yellow.png rename to textures/flowers_dandelion_yellow.png diff --git a/mods/ITEMS/mcl_flowers/textures/flowers_tulip.png b/textures/flowers_tulip.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/flowers_tulip.png rename to textures/flowers_tulip.png diff --git a/textures/flowers_waterlily.png b/textures/flowers_waterlily.png new file mode 100644 index 000000000..1d5bc6849 Binary files /dev/null and b/textures/flowers_waterlily.png differ diff --git a/textures/footer.png b/textures/footer.png new file mode 100644 index 000000000..c57f5470b Binary files /dev/null and b/textures/footer.png differ diff --git a/textures/grindstone_front.png b/textures/grindstone_front.png new file mode 100644 index 000000000..33cf9c262 Binary files /dev/null and b/textures/grindstone_front.png differ diff --git a/textures/grindstone_side.png b/textures/grindstone_side.png new file mode 100644 index 000000000..b80dd639d Binary files /dev/null and b/textures/grindstone_side.png differ diff --git a/textures/grindstone_top.png b/textures/grindstone_top.png new file mode 100644 index 000000000..cc91db623 Binary files /dev/null and b/textures/grindstone_top.png differ diff --git a/mods/ITEMS/mcl_crafting_table/textures/gui_crafting_arrow.png b/textures/gui_crafting_arrow.png similarity index 100% rename from mods/ITEMS/mcl_crafting_table/textures/gui_crafting_arrow.png rename to textures/gui_crafting_arrow.png diff --git a/mods/ITEMS/mcl_furnaces/textures/gui_furnace_arrow_bg.png b/textures/gui_furnace_arrow_bg.png similarity index 100% rename from mods/ITEMS/mcl_furnaces/textures/gui_furnace_arrow_bg.png rename to textures/gui_furnace_arrow_bg.png diff --git a/mods/ITEMS/mcl_furnaces/textures/gui_furnace_arrow_fg.png b/textures/gui_furnace_arrow_fg.png similarity index 100% rename from mods/ITEMS/mcl_furnaces/textures/gui_furnace_arrow_fg.png rename to textures/gui_furnace_arrow_fg.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay.png b/textures/hardened_clay.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay.png rename to textures/hardened_clay.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_black.png b/textures/hardened_clay_stained_black.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_black.png rename to textures/hardened_clay_stained_black.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_blue.png b/textures/hardened_clay_stained_blue.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_blue.png rename to textures/hardened_clay_stained_blue.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_brown.png b/textures/hardened_clay_stained_brown.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_brown.png rename to textures/hardened_clay_stained_brown.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_cyan.png b/textures/hardened_clay_stained_cyan.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_cyan.png rename to textures/hardened_clay_stained_cyan.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_green.png b/textures/hardened_clay_stained_green.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_green.png rename to textures/hardened_clay_stained_green.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_grey.png b/textures/hardened_clay_stained_grey.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_grey.png rename to textures/hardened_clay_stained_grey.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_light_blue.png b/textures/hardened_clay_stained_light_blue.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_light_blue.png rename to textures/hardened_clay_stained_light_blue.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_lime.png b/textures/hardened_clay_stained_lime.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_lime.png rename to textures/hardened_clay_stained_lime.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_magenta.png b/textures/hardened_clay_stained_magenta.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_magenta.png rename to textures/hardened_clay_stained_magenta.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_orange.png b/textures/hardened_clay_stained_orange.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_orange.png rename to textures/hardened_clay_stained_orange.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_pink.png b/textures/hardened_clay_stained_pink.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_pink.png rename to textures/hardened_clay_stained_pink.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_purple.png b/textures/hardened_clay_stained_purple.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_purple.png rename to textures/hardened_clay_stained_purple.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_red.png b/textures/hardened_clay_stained_red.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_red.png rename to textures/hardened_clay_stained_red.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_silver.png b/textures/hardened_clay_stained_silver.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_silver.png rename to textures/hardened_clay_stained_silver.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_white.png b/textures/hardened_clay_stained_white.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_white.png rename to textures/hardened_clay_stained_white.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_yellow.png b/textures/hardened_clay_stained_yellow.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/hardened_clay_stained_yellow.png rename to textures/hardened_clay_stained_yellow.png diff --git a/textures/hbarmor_bar.png b/textures/hbarmor_bar.png new file mode 100644 index 000000000..74974117c Binary files /dev/null and b/textures/hbarmor_bar.png differ diff --git a/textures/hbarmor_bgicon.png b/textures/hbarmor_bgicon.png new file mode 100644 index 000000000..54a22d078 Binary files /dev/null and b/textures/hbarmor_bgicon.png differ diff --git a/textures/hbarmor_icon.png b/textures/hbarmor_icon.png new file mode 100644 index 000000000..1efe919c8 Binary files /dev/null and b/textures/hbarmor_icon.png differ diff --git a/mods/PLAYER/mcl_hunger/textures/hbhunger_bar.png b/textures/hbhunger_bar.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/hbhunger_bar.png rename to textures/hbhunger_bar.png diff --git a/mods/PLAYER/mcl_hunger/textures/hbhunger_bar_health_poison.png b/textures/hbhunger_bar_health_poison.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/hbhunger_bar_health_poison.png rename to textures/hbhunger_bar_health_poison.png diff --git a/textures/hbhunger_bgicon.png b/textures/hbhunger_bgicon.png new file mode 100644 index 000000000..97f69563c Binary files /dev/null and b/textures/hbhunger_bgicon.png differ diff --git a/textures/hbhunger_icon.png b/textures/hbhunger_icon.png new file mode 100644 index 000000000..07a5b352a Binary files /dev/null and b/textures/hbhunger_icon.png differ diff --git a/mods/PLAYER/mcl_hunger/textures/hbhunger_icon_health_poison.png b/textures/hbhunger_icon_health_poison.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/hbhunger_icon_health_poison.png rename to textures/hbhunger_icon_health_poison.png diff --git a/textures/hbhunger_icon_regen_poison.png b/textures/hbhunger_icon_regen_poison.png new file mode 100644 index 000000000..ee9339896 Binary files /dev/null and b/textures/hbhunger_icon_regen_poison.png differ diff --git a/textures/heart.png b/textures/heart.png new file mode 100644 index 000000000..7f1b66df4 Binary files /dev/null and b/textures/heart.png differ diff --git a/textures/hudbars_bar_background.png b/textures/hudbars_bar_background.png new file mode 100644 index 000000000..9a9513b08 Binary files /dev/null and b/textures/hudbars_bar_background.png differ diff --git a/textures/hudbars_bar_breath.png b/textures/hudbars_bar_breath.png new file mode 100644 index 000000000..f4f259910 Binary files /dev/null and b/textures/hudbars_bar_breath.png differ diff --git a/textures/hudbars_bar_health.png b/textures/hudbars_bar_health.png new file mode 100644 index 000000000..eed95e86f Binary files /dev/null and b/textures/hudbars_bar_health.png differ diff --git a/textures/hudbars_bgicon_breath.png b/textures/hudbars_bgicon_breath.png new file mode 100644 index 000000000..0297ededd Binary files /dev/null and b/textures/hudbars_bgicon_breath.png differ diff --git a/textures/hudbars_bgicon_health.png b/textures/hudbars_bgicon_health.png new file mode 100644 index 000000000..ebda3703f Binary files /dev/null and b/textures/hudbars_bgicon_health.png differ diff --git a/textures/hudbars_icon_breath.png b/textures/hudbars_icon_breath.png new file mode 100644 index 000000000..cbbb6705a Binary files /dev/null and b/textures/hudbars_icon_breath.png differ diff --git a/textures/hudbars_icon_health.png b/textures/hudbars_icon_health.png new file mode 100644 index 000000000..7f1b66df4 Binary files /dev/null and b/textures/hudbars_icon_health.png differ diff --git a/textures/hudbars_icon_regenerate.png b/textures/hudbars_icon_regenerate.png new file mode 100644 index 000000000..faa6485f5 Binary files /dev/null and b/textures/hudbars_icon_regenerate.png differ diff --git a/textures/inventory_plus_doc_inventory_plus.png b/textures/inventory_plus_doc_inventory_plus.png new file mode 100644 index 000000000..b3ebe6f4a Binary files /dev/null and b/textures/inventory_plus_doc_inventory_plus.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/textures/jeija_commandblock_off.png b/textures/jeija_commandblock_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_commandblock/textures/jeija_commandblock_off.png rename to textures/jeija_commandblock_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_commandblock/textures/jeija_commandblock_on.png b/textures/jeija_commandblock_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_commandblock/textures/jeija_commandblock_on.png rename to textures/jeija_commandblock_on.png diff --git a/textures/jeija_lightstone_gray_off.png b/textures/jeija_lightstone_gray_off.png new file mode 100644 index 000000000..c459c2265 Binary files /dev/null and b/textures/jeija_lightstone_gray_off.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_lightstone/textures/jeija_lightstone_gray_on.png b/textures/jeija_lightstone_gray_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_lightstone/textures/jeija_lightstone_gray_on.png rename to textures/jeija_lightstone_gray_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel.png b/textures/jeija_solar_panel.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel.png rename to textures/jeija_solar_panel.png diff --git a/mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel_inverted.png b/textures/jeija_solar_panel_inverted.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_solarpanel/textures/jeija_solar_panel_inverted.png rename to textures/jeija_solar_panel_inverted.png diff --git a/textures/jeija_solar_panel_side.png b/textures/jeija_solar_panel_side.png new file mode 100644 index 000000000..2dd2826b8 Binary files /dev/null and b/textures/jeija_solar_panel_side.png differ diff --git a/textures/jeija_torches_off.png b/textures/jeija_torches_off.png new file mode 100644 index 000000000..51f758cac Binary files /dev/null and b/textures/jeija_torches_off.png differ diff --git a/textures/jeija_torches_on.png b/textures/jeija_torches_on.png new file mode 100644 index 000000000..98e833a6d Binary files /dev/null and b/textures/jeija_torches_on.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/textures/jeija_wall_lever.png b/textures/jeija_wall_lever.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_walllever/textures/jeija_wall_lever.png rename to textures/jeija_wall_lever.png diff --git a/mods/ITEMS/REDSTONE/mesecons_walllever/models/jeija_wall_lever_lever_light_on.png b/textures/jeija_wall_lever_lever_light_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_walllever/models/jeija_wall_lever_lever_light_on.png rename to textures/jeija_wall_lever_lever_light_on.png diff --git a/textures/lantern.png b/textures/lantern.png new file mode 100644 index 000000000..e39d8a97c Binary files /dev/null and b/textures/lantern.png differ diff --git a/textures/lantern_bottom.png b/textures/lantern_bottom.png new file mode 100644 index 000000000..acee8b1c9 Binary files /dev/null and b/textures/lantern_bottom.png differ diff --git a/textures/lantern_top.png b/textures/lantern_top.png new file mode 100644 index 000000000..c7243f4af Binary files /dev/null and b/textures/lantern_top.png differ diff --git a/textures/lightning_lightning_1.png b/textures/lightning_lightning_1.png new file mode 100644 index 000000000..122948b63 Binary files /dev/null and b/textures/lightning_lightning_1.png differ diff --git a/textures/lightning_lightning_2.png b/textures/lightning_lightning_2.png new file mode 100644 index 000000000..2c2f6204b Binary files /dev/null and b/textures/lightning_lightning_2.png differ diff --git a/textures/lightning_lightning_3.png b/textures/lightning_lightning_3.png new file mode 100644 index 000000000..c2fa6003a Binary files /dev/null and b/textures/lightning_lightning_3.png differ diff --git a/textures/lodestone_bottom.png b/textures/lodestone_bottom.png new file mode 100644 index 000000000..8f47d57ed Binary files /dev/null and b/textures/lodestone_bottom.png differ diff --git a/textures/lodestone_side1.png b/textures/lodestone_side1.png new file mode 100644 index 000000000..643f636a7 Binary files /dev/null and b/textures/lodestone_side1.png differ diff --git a/textures/lodestone_side2.png b/textures/lodestone_side2.png new file mode 100644 index 000000000..1c649185e Binary files /dev/null and b/textures/lodestone_side2.png differ diff --git a/textures/lodestone_side3.png b/textures/lodestone_side3.png new file mode 100644 index 000000000..39054126a Binary files /dev/null and b/textures/lodestone_side3.png differ diff --git a/textures/lodestone_side4.png b/textures/lodestone_side4.png new file mode 100644 index 000000000..e700c6158 Binary files /dev/null and b/textures/lodestone_side4.png differ diff --git a/textures/lodestone_top.png b/textures/lodestone_top.png new file mode 100644 index 000000000..a3f1cfc60 Binary files /dev/null and b/textures/lodestone_top.png differ diff --git a/textures/loom_bottom.png b/textures/loom_bottom.png new file mode 100644 index 000000000..850868d55 Binary files /dev/null and b/textures/loom_bottom.png differ diff --git a/textures/loom_front.png b/textures/loom_front.png new file mode 100644 index 000000000..79915ae6f Binary files /dev/null and b/textures/loom_front.png differ diff --git a/textures/loom_side.png b/textures/loom_side.png new file mode 100644 index 000000000..50665d5a6 Binary files /dev/null and b/textures/loom_side.png differ diff --git a/textures/loom_top.png b/textures/loom_top.png new file mode 100644 index 000000000..5d74ab99b Binary files /dev/null and b/textures/loom_top.png differ diff --git a/textures/mcl_achievements_button.png b/textures/mcl_achievements_button.png new file mode 100644 index 000000000..9dab93575 Binary files /dev/null and b/textures/mcl_achievements_button.png differ diff --git a/textures/mcl_amethyst_amethyst_block.png b/textures/mcl_amethyst_amethyst_block.png new file mode 100644 index 000000000..3b21001fd Binary files /dev/null and b/textures/mcl_amethyst_amethyst_block.png differ diff --git a/textures/mcl_amethyst_amethyst_bud_large.png b/textures/mcl_amethyst_amethyst_bud_large.png new file mode 100644 index 000000000..f528ebf36 Binary files /dev/null and b/textures/mcl_amethyst_amethyst_bud_large.png differ diff --git a/textures/mcl_amethyst_amethyst_bud_medium.png b/textures/mcl_amethyst_amethyst_bud_medium.png new file mode 100644 index 000000000..e21b950d2 Binary files /dev/null and b/textures/mcl_amethyst_amethyst_bud_medium.png differ diff --git a/textures/mcl_amethyst_amethyst_bud_small.png b/textures/mcl_amethyst_amethyst_bud_small.png new file mode 100644 index 000000000..29697672a Binary files /dev/null and b/textures/mcl_amethyst_amethyst_bud_small.png differ diff --git a/textures/mcl_amethyst_amethyst_cluster.png b/textures/mcl_amethyst_amethyst_cluster.png new file mode 100644 index 000000000..dd0f05e58 Binary files /dev/null and b/textures/mcl_amethyst_amethyst_cluster.png differ diff --git a/textures/mcl_amethyst_amethyst_shard.png b/textures/mcl_amethyst_amethyst_shard.png new file mode 100644 index 000000000..ac7d83447 Binary files /dev/null and b/textures/mcl_amethyst_amethyst_shard.png differ diff --git a/textures/mcl_amethyst_budding_amethyst.png b/textures/mcl_amethyst_budding_amethyst.png new file mode 100644 index 000000000..6f9647350 Binary files /dev/null and b/textures/mcl_amethyst_budding_amethyst.png differ diff --git a/textures/mcl_amethyst_calcite_block.png b/textures/mcl_amethyst_calcite_block.png new file mode 100644 index 000000000..524d56264 Binary files /dev/null and b/textures/mcl_amethyst_calcite_block.png differ diff --git a/textures/mcl_amethyst_tinted_glass.png b/textures/mcl_amethyst_tinted_glass.png new file mode 100644 index 000000000..e0694d74e Binary files /dev/null and b/textures/mcl_amethyst_tinted_glass.png differ diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_base.png b/textures/mcl_anvils_anvil_base.png similarity index 100% rename from mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_base.png rename to textures/mcl_anvils_anvil_base.png diff --git a/mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_side.png b/textures/mcl_anvils_anvil_side.png similarity index 100% rename from mods/ITEMS/mcl_anvils/textures/mcl_anvils_anvil_side.png rename to textures/mcl_anvils_anvil_side.png diff --git a/textures/mcl_anvils_anvil_top_damaged_0.png b/textures/mcl_anvils_anvil_top_damaged_0.png new file mode 100644 index 000000000..bc049e400 Binary files /dev/null and b/textures/mcl_anvils_anvil_top_damaged_0.png differ diff --git a/textures/mcl_anvils_anvil_top_damaged_1.png b/textures/mcl_anvils_anvil_top_damaged_1.png new file mode 100644 index 000000000..52ee73485 Binary files /dev/null and b/textures/mcl_anvils_anvil_top_damaged_1.png differ diff --git a/textures/mcl_anvils_anvil_top_damaged_2.png b/textures/mcl_anvils_anvil_top_damaged_2.png new file mode 100644 index 000000000..716b1ba3e Binary files /dev/null and b/textures/mcl_anvils_anvil_top_damaged_2.png differ diff --git a/textures/mcl_anvils_inventory.png b/textures/mcl_anvils_inventory.png new file mode 100644 index 000000000..49421b3db Binary files /dev/null and b/textures/mcl_anvils_inventory.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_chain.png b/textures/mcl_armor_boots_chain.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_boots_chain.png rename to textures/mcl_armor_boots_chain.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_diamond.png b/textures/mcl_armor_boots_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_boots_diamond.png rename to textures/mcl_armor_boots_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_gold.png b/textures/mcl_armor_boots_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_boots_gold.png rename to textures/mcl_armor_boots_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_iron.png b/textures/mcl_armor_boots_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_boots_iron.png rename to textures/mcl_armor_boots_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_boots_leather.png b/textures/mcl_armor_boots_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_boots_leather.png rename to textures/mcl_armor_boots_leather.png diff --git a/textures/mcl_armor_boots_netherite.png b/textures/mcl_armor_boots_netherite.png new file mode 100644 index 000000000..fec25ae97 Binary files /dev/null and b/textures/mcl_armor_boots_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_chain.png b/textures/mcl_armor_chestplate_chain.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_chain.png rename to textures/mcl_armor_chestplate_chain.png diff --git a/textures/mcl_armor_chestplate_diamond.png b/textures/mcl_armor_chestplate_diamond.png new file mode 100644 index 000000000..51ece2458 Binary files /dev/null and b/textures/mcl_armor_chestplate_diamond.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_gold.png b/textures/mcl_armor_chestplate_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_gold.png rename to textures/mcl_armor_chestplate_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_iron.png b/textures/mcl_armor_chestplate_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_chestplate_iron.png rename to textures/mcl_armor_chestplate_iron.png diff --git a/textures/mcl_armor_chestplate_leather.png b/textures/mcl_armor_chestplate_leather.png new file mode 100644 index 000000000..6297859fc Binary files /dev/null and b/textures/mcl_armor_chestplate_leather.png differ diff --git a/textures/mcl_armor_chestplate_netherite.png b/textures/mcl_armor_chestplate_netherite.png new file mode 100644 index 000000000..b67403b1d Binary files /dev/null and b/textures/mcl_armor_chestplate_netherite.png differ diff --git a/textures/mcl_armor_elytra.png b/textures/mcl_armor_elytra.png new file mode 100644 index 000000000..e2c51810a Binary files /dev/null and b/textures/mcl_armor_elytra.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_chain.png b/textures/mcl_armor_helmet_chain.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_chain.png rename to textures/mcl_armor_helmet_chain.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_diamond.png b/textures/mcl_armor_helmet_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_diamond.png rename to textures/mcl_armor_helmet_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_gold.png b/textures/mcl_armor_helmet_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_gold.png rename to textures/mcl_armor_helmet_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_iron.png b/textures/mcl_armor_helmet_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_iron.png rename to textures/mcl_armor_helmet_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_leather.png b/textures/mcl_armor_helmet_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_helmet_leather.png rename to textures/mcl_armor_helmet_leather.png diff --git a/textures/mcl_armor_helmet_netherite.png b/textures/mcl_armor_helmet_netherite.png new file mode 100644 index 000000000..44814a907 Binary files /dev/null and b/textures/mcl_armor_helmet_netherite.png differ diff --git a/textures/mcl_armor_inv_boots_chain.png b/textures/mcl_armor_inv_boots_chain.png new file mode 100644 index 000000000..eaed6b6d1 Binary files /dev/null and b/textures/mcl_armor_inv_boots_chain.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_diamond.png b/textures/mcl_armor_inv_boots_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_diamond.png rename to textures/mcl_armor_inv_boots_diamond.png diff --git a/textures/mcl_armor_inv_boots_gold.png b/textures/mcl_armor_inv_boots_gold.png new file mode 100644 index 000000000..5c6d425b9 Binary files /dev/null and b/textures/mcl_armor_inv_boots_gold.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_iron.png b/textures/mcl_armor_inv_boots_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_iron.png rename to textures/mcl_armor_inv_boots_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_leather.png b/textures/mcl_armor_inv_boots_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_boots_leather.png rename to textures/mcl_armor_inv_boots_leather.png diff --git a/textures/mcl_armor_inv_boots_netherite.png b/textures/mcl_armor_inv_boots_netherite.png new file mode 100644 index 000000000..5fa1f91f8 Binary files /dev/null and b/textures/mcl_armor_inv_boots_netherite.png differ diff --git a/textures/mcl_armor_inv_chestplate_chain.png b/textures/mcl_armor_inv_chestplate_chain.png new file mode 100644 index 000000000..d8229d8de Binary files /dev/null and b/textures/mcl_armor_inv_chestplate_chain.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_diamond.png b/textures/mcl_armor_inv_chestplate_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_diamond.png rename to textures/mcl_armor_inv_chestplate_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_gold.png b/textures/mcl_armor_inv_chestplate_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_gold.png rename to textures/mcl_armor_inv_chestplate_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_iron.png b/textures/mcl_armor_inv_chestplate_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_iron.png rename to textures/mcl_armor_inv_chestplate_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_leather.png b/textures/mcl_armor_inv_chestplate_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_chestplate_leather.png rename to textures/mcl_armor_inv_chestplate_leather.png diff --git a/textures/mcl_armor_inv_chestplate_netherite.png b/textures/mcl_armor_inv_chestplate_netherite.png new file mode 100644 index 000000000..84a057c5c Binary files /dev/null and b/textures/mcl_armor_inv_chestplate_netherite.png differ diff --git a/textures/mcl_armor_inv_elytra.png b/textures/mcl_armor_inv_elytra.png new file mode 100644 index 000000000..88ce2818a Binary files /dev/null and b/textures/mcl_armor_inv_elytra.png differ diff --git a/textures/mcl_armor_inv_helmet_chain.png b/textures/mcl_armor_inv_helmet_chain.png new file mode 100644 index 000000000..92c1e4e0d Binary files /dev/null and b/textures/mcl_armor_inv_helmet_chain.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_diamond.png b/textures/mcl_armor_inv_helmet_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_diamond.png rename to textures/mcl_armor_inv_helmet_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_gold.png b/textures/mcl_armor_inv_helmet_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_gold.png rename to textures/mcl_armor_inv_helmet_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_iron.png b/textures/mcl_armor_inv_helmet_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_iron.png rename to textures/mcl_armor_inv_helmet_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_leather.png b/textures/mcl_armor_inv_helmet_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_helmet_leather.png rename to textures/mcl_armor_inv_helmet_leather.png diff --git a/textures/mcl_armor_inv_helmet_netherite.png b/textures/mcl_armor_inv_helmet_netherite.png new file mode 100644 index 000000000..7751f0411 Binary files /dev/null and b/textures/mcl_armor_inv_helmet_netherite.png differ diff --git a/textures/mcl_armor_inv_leggings_chain.png b/textures/mcl_armor_inv_leggings_chain.png new file mode 100644 index 000000000..7648cda27 Binary files /dev/null and b/textures/mcl_armor_inv_leggings_chain.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_diamond.png b/textures/mcl_armor_inv_leggings_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_diamond.png rename to textures/mcl_armor_inv_leggings_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_gold.png b/textures/mcl_armor_inv_leggings_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_gold.png rename to textures/mcl_armor_inv_leggings_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_iron.png b/textures/mcl_armor_inv_leggings_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_inv_leggings_iron.png rename to textures/mcl_armor_inv_leggings_iron.png diff --git a/textures/mcl_armor_inv_leggings_leather.png b/textures/mcl_armor_inv_leggings_leather.png new file mode 100644 index 000000000..b35086a97 Binary files /dev/null and b/textures/mcl_armor_inv_leggings_leather.png differ diff --git a/textures/mcl_armor_inv_leggings_netherite.png b/textures/mcl_armor_inv_leggings_netherite.png new file mode 100644 index 000000000..d6dd76095 Binary files /dev/null and b/textures/mcl_armor_inv_leggings_netherite.png differ diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_chain.png b/textures/mcl_armor_leggings_chain.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_chain.png rename to textures/mcl_armor_leggings_chain.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_diamond.png b/textures/mcl_armor_leggings_diamond.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_diamond.png rename to textures/mcl_armor_leggings_diamond.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_gold.png b/textures/mcl_armor_leggings_gold.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_gold.png rename to textures/mcl_armor_leggings_gold.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_iron.png b/textures/mcl_armor_leggings_iron.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_iron.png rename to textures/mcl_armor_leggings_iron.png diff --git a/mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_leather.png b/textures/mcl_armor_leggings_leather.png similarity index 100% rename from mods/ITEMS/mcl_armor/textures/mcl_armor_leggings_leather.png rename to textures/mcl_armor_leggings_leather.png diff --git a/textures/mcl_armor_leggings_netherite.png b/textures/mcl_armor_leggings_netherite.png new file mode 100644 index 000000000..c68eb4e9a Binary files /dev/null and b/textures/mcl_armor_leggings_netherite.png differ diff --git a/mods/ITEMS/mcl_armor_stand/textures/3d_armor_stand_item.png b/textures/mcl_armor_stand_item.png similarity index 100% rename from mods/ITEMS/mcl_armor_stand/textures/3d_armor_stand_item.png rename to textures/mcl_armor_stand_item.png diff --git a/textures/mcl_backstone_quartz_bricks.png b/textures/mcl_backstone_quartz_bricks.png new file mode 100644 index 000000000..94a328989 Binary files /dev/null and b/textures/mcl_backstone_quartz_bricks.png differ diff --git a/textures/mcl_bamboo_bamboo.png b/textures/mcl_bamboo_bamboo.png new file mode 100644 index 000000000..8fd0a8131 Binary files /dev/null and b/textures/mcl_bamboo_bamboo.png differ diff --git a/textures/mcl_bamboo_bamboo_block.png b/textures/mcl_bamboo_bamboo_block.png new file mode 100644 index 000000000..c5049c8ef Binary files /dev/null and b/textures/mcl_bamboo_bamboo_block.png differ diff --git a/textures/mcl_bamboo_bamboo_block_stripped.png b/textures/mcl_bamboo_bamboo_block_stripped.png new file mode 100644 index 000000000..530b4ce4b Binary files /dev/null and b/textures/mcl_bamboo_bamboo_block_stripped.png differ diff --git a/textures/mcl_bamboo_bamboo_bottom.png b/textures/mcl_bamboo_bamboo_bottom.png new file mode 100644 index 000000000..f98563131 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_bottom.png differ diff --git a/textures/mcl_bamboo_bamboo_bottom_stripped.png b/textures/mcl_bamboo_bamboo_bottom_stripped.png new file mode 100644 index 000000000..a2ff21295 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_bottom_stripped.png differ diff --git a/textures/mcl_bamboo_bamboo_fpm.png b/textures/mcl_bamboo_bamboo_fpm.png new file mode 100644 index 000000000..7c3f2b40d Binary files /dev/null and b/textures/mcl_bamboo_bamboo_fpm.png differ diff --git a/textures/mcl_bamboo_bamboo_plank.png b/textures/mcl_bamboo_bamboo_plank.png new file mode 100644 index 000000000..9f9c92bbe Binary files /dev/null and b/textures/mcl_bamboo_bamboo_plank.png differ diff --git a/textures/mcl_bamboo_bamboo_plank_mosaic.png b/textures/mcl_bamboo_bamboo_plank_mosaic.png new file mode 100644 index 000000000..f795def33 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_plank_mosaic.png differ diff --git a/textures/mcl_bamboo_bamboo_shoot.png b/textures/mcl_bamboo_bamboo_shoot.png new file mode 100644 index 000000000..0d1226cb3 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_shoot.png differ diff --git a/textures/mcl_bamboo_bamboo_sign.png b/textures/mcl_bamboo_bamboo_sign.png new file mode 100644 index 000000000..2f0fb5815 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_sign.png differ diff --git a/textures/mcl_bamboo_bamboo_sign_wield.png b/textures/mcl_bamboo_bamboo_sign_wield.png new file mode 100644 index 000000000..7739e3250 Binary files /dev/null and b/textures/mcl_bamboo_bamboo_sign_wield.png differ diff --git a/textures/mcl_bamboo_door_bottom.png b/textures/mcl_bamboo_door_bottom.png new file mode 100644 index 000000000..c203f4582 Binary files /dev/null and b/textures/mcl_bamboo_door_bottom.png differ diff --git a/textures/mcl_bamboo_door_bottom_bottompart.png b/textures/mcl_bamboo_door_bottom_bottompart.png new file mode 100644 index 000000000..beeedfa5e Binary files /dev/null and b/textures/mcl_bamboo_door_bottom_bottompart.png differ diff --git a/textures/mcl_bamboo_door_bottom_side.png b/textures/mcl_bamboo_door_bottom_side.png new file mode 100644 index 000000000..9e1600a99 Binary files /dev/null and b/textures/mcl_bamboo_door_bottom_side.png differ diff --git a/textures/mcl_bamboo_door_top.png b/textures/mcl_bamboo_door_top.png new file mode 100644 index 000000000..09fa5c7b8 Binary files /dev/null and b/textures/mcl_bamboo_door_top.png differ diff --git a/textures/mcl_bamboo_door_top_side.png b/textures/mcl_bamboo_door_top_side.png new file mode 100644 index 000000000..dbeb42b96 Binary files /dev/null and b/textures/mcl_bamboo_door_top_side.png differ diff --git a/textures/mcl_bamboo_door_top_toppart.png b/textures/mcl_bamboo_door_top_toppart.png new file mode 100644 index 000000000..f1977bf83 Binary files /dev/null and b/textures/mcl_bamboo_door_top_toppart.png differ diff --git a/textures/mcl_bamboo_door_wield.png b/textures/mcl_bamboo_door_wield.png new file mode 100644 index 000000000..2b56702fc Binary files /dev/null and b/textures/mcl_bamboo_door_wield.png differ diff --git a/textures/mcl_bamboo_endcap.png b/textures/mcl_bamboo_endcap.png new file mode 100644 index 000000000..c278fc62f Binary files /dev/null and b/textures/mcl_bamboo_endcap.png differ diff --git a/textures/mcl_bamboo_fence_bamboo.png b/textures/mcl_bamboo_fence_bamboo.png new file mode 100644 index 000000000..82340abd3 Binary files /dev/null and b/textures/mcl_bamboo_fence_bamboo.png differ diff --git a/textures/mcl_bamboo_fence_gate_bamboo.png b/textures/mcl_bamboo_fence_gate_bamboo.png new file mode 100644 index 000000000..82340abd3 Binary files /dev/null and b/textures/mcl_bamboo_fence_gate_bamboo.png differ diff --git a/textures/mcl_bamboo_flower_pot.png b/textures/mcl_bamboo_flower_pot.png new file mode 100644 index 000000000..599c17037 Binary files /dev/null and b/textures/mcl_bamboo_flower_pot.png differ diff --git a/textures/mcl_bamboo_scaffolding_bottom.png b/textures/mcl_bamboo_scaffolding_bottom.png new file mode 100644 index 000000000..386cc80be Binary files /dev/null and b/textures/mcl_bamboo_scaffolding_bottom.png differ diff --git a/textures/mcl_bamboo_scaffolding_top.png b/textures/mcl_bamboo_scaffolding_top.png new file mode 100644 index 000000000..cedb82811 Binary files /dev/null and b/textures/mcl_bamboo_scaffolding_top.png differ diff --git a/textures/mcl_bamboo_trapdoor_side.png b/textures/mcl_bamboo_trapdoor_side.png new file mode 100644 index 000000000..415dddc72 Binary files /dev/null and b/textures/mcl_bamboo_trapdoor_side.png differ diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_banner_base.png b/textures/mcl_banners_banner_base.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_banner_base.png rename to textures/mcl_banners_banner_base.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_base.png b/textures/mcl_banners_base.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_base.png rename to textures/mcl_banners_base.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_base_inverted.png b/textures/mcl_banners_base_inverted.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_base_inverted.png rename to textures/mcl_banners_base_inverted.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_border.png b/textures/mcl_banners_border.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_border.png rename to textures/mcl_banners_border.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_bricks.png b/textures/mcl_banners_bricks.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_bricks.png rename to textures/mcl_banners_bricks.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_circle.png b/textures/mcl_banners_circle.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_circle.png rename to textures/mcl_banners_circle.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_creeper.png b/textures/mcl_banners_creeper.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_creeper.png rename to textures/mcl_banners_creeper.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_cross.png b/textures/mcl_banners_cross.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_cross.png rename to textures/mcl_banners_cross.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_curly_border.png b/textures/mcl_banners_curly_border.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_curly_border.png rename to textures/mcl_banners_curly_border.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_left.png b/textures/mcl_banners_diagonal_left.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_left.png rename to textures/mcl_banners_diagonal_left.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_right.png b/textures/mcl_banners_diagonal_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_right.png rename to textures/mcl_banners_diagonal_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_up_left.png b/textures/mcl_banners_diagonal_up_left.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_up_left.png rename to textures/mcl_banners_diagonal_up_left.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_up_right.png b/textures/mcl_banners_diagonal_up_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_diagonal_up_right.png rename to textures/mcl_banners_diagonal_up_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_fallback_wood.png b/textures/mcl_banners_fallback_wood.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_fallback_wood.png rename to textures/mcl_banners_fallback_wood.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_flower.png b/textures/mcl_banners_flower.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_flower.png rename to textures/mcl_banners_flower.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_gradient.png b/textures/mcl_banners_gradient.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_gradient.png rename to textures/mcl_banners_gradient.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_gradient_up.png b/textures/mcl_banners_gradient_up.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_gradient_up.png rename to textures/mcl_banners_gradient_up.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_half_horizontal.png b/textures/mcl_banners_half_horizontal.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_half_horizontal.png rename to textures/mcl_banners_half_horizontal.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_half_horizontal_bottom.png b/textures/mcl_banners_half_horizontal_bottom.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_half_horizontal_bottom.png rename to textures/mcl_banners_half_horizontal_bottom.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_half_vertical.png b/textures/mcl_banners_half_vertical.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_half_vertical.png rename to textures/mcl_banners_half_vertical.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_half_vertical_right.png b/textures/mcl_banners_half_vertical_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_half_vertical_right.png rename to textures/mcl_banners_half_vertical_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_item_base.png b/textures/mcl_banners_item_base.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_item_base.png rename to textures/mcl_banners_item_base.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_item_overlay.png b/textures/mcl_banners_item_overlay.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_item_overlay.png rename to textures/mcl_banners_item_overlay.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_rhombus.png b/textures/mcl_banners_rhombus.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_rhombus.png rename to textures/mcl_banners_rhombus.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_skull.png b/textures/mcl_banners_skull.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_skull.png rename to textures/mcl_banners_skull.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_small_stripes.png b/textures/mcl_banners_small_stripes.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_small_stripes.png rename to textures/mcl_banners_small_stripes.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_square_bottom_left.png b/textures/mcl_banners_square_bottom_left.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_square_bottom_left.png rename to textures/mcl_banners_square_bottom_left.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_square_bottom_right.png b/textures/mcl_banners_square_bottom_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_square_bottom_right.png rename to textures/mcl_banners_square_bottom_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_square_top_left.png b/textures/mcl_banners_square_top_left.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_square_top_left.png rename to textures/mcl_banners_square_top_left.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_square_top_right.png b/textures/mcl_banners_square_top_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_square_top_right.png rename to textures/mcl_banners_square_top_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_straight_cross.png b/textures/mcl_banners_straight_cross.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_straight_cross.png rename to textures/mcl_banners_straight_cross.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_bottom.png b/textures/mcl_banners_stripe_bottom.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_bottom.png rename to textures/mcl_banners_stripe_bottom.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_center.png b/textures/mcl_banners_stripe_center.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_center.png rename to textures/mcl_banners_stripe_center.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_downleft.png b/textures/mcl_banners_stripe_downleft.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_downleft.png rename to textures/mcl_banners_stripe_downleft.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_downright.png b/textures/mcl_banners_stripe_downright.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_downright.png rename to textures/mcl_banners_stripe_downright.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_left.png b/textures/mcl_banners_stripe_left.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_left.png rename to textures/mcl_banners_stripe_left.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_middle.png b/textures/mcl_banners_stripe_middle.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_middle.png rename to textures/mcl_banners_stripe_middle.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_right.png b/textures/mcl_banners_stripe_right.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_right.png rename to textures/mcl_banners_stripe_right.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_top.png b/textures/mcl_banners_stripe_top.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_stripe_top.png rename to textures/mcl_banners_stripe_top.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_thing.png b/textures/mcl_banners_thing.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_thing.png rename to textures/mcl_banners_thing.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_triangle_bottom.png b/textures/mcl_banners_triangle_bottom.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_triangle_bottom.png rename to textures/mcl_banners_triangle_bottom.png diff --git a/textures/mcl_banners_triangle_top.png b/textures/mcl_banners_triangle_top.png new file mode 100644 index 000000000..1c72d7425 Binary files /dev/null and b/textures/mcl_banners_triangle_top.png differ diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_triangles_bottom.png b/textures/mcl_banners_triangles_bottom.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_triangles_bottom.png rename to textures/mcl_banners_triangles_bottom.png diff --git a/mods/ITEMS/mcl_banners/textures/mcl_banners_triangles_top.png b/textures/mcl_banners_triangles_top.png similarity index 100% rename from mods/ITEMS/mcl_banners/textures/mcl_banners_triangles_top.png rename to textures/mcl_banners_triangles_top.png diff --git a/textures/mcl_barrels_barrel_bottom.png b/textures/mcl_barrels_barrel_bottom.png new file mode 100644 index 000000000..59b25ae28 Binary files /dev/null and b/textures/mcl_barrels_barrel_bottom.png differ diff --git a/textures/mcl_barrels_barrel_side.png b/textures/mcl_barrels_barrel_side.png new file mode 100644 index 000000000..b5992a07a Binary files /dev/null and b/textures/mcl_barrels_barrel_side.png differ diff --git a/textures/mcl_barrels_barrel_top.png b/textures/mcl_barrels_barrel_top.png new file mode 100644 index 000000000..a8ec48f3d Binary files /dev/null and b/textures/mcl_barrels_barrel_top.png differ diff --git a/textures/mcl_barrels_barrel_top_open.png b/textures/mcl_barrels_barrel_top_open.png new file mode 100644 index 000000000..1559f7943 Binary files /dev/null and b/textures/mcl_barrels_barrel_top_open.png differ diff --git a/mods/HUD/mcl_base_textures/textures/mcl_base_textures_background.png b/textures/mcl_base_textures_background.png similarity index 100% rename from mods/HUD/mcl_base_textures/textures/mcl_base_textures_background.png rename to textures/mcl_base_textures_background.png diff --git a/mods/HUD/mcl_base_textures/textures/mcl_base_textures_background9.png b/textures/mcl_base_textures_background9.png similarity index 100% rename from mods/HUD/mcl_base_textures/textures/mcl_base_textures_background9.png rename to textures/mcl_base_textures_background9.png diff --git a/mods/HUD/mcl_base_textures/textures/mcl_base_textures_button9.png b/textures/mcl_base_textures_button9.png similarity index 100% rename from mods/HUD/mcl_base_textures/textures/mcl_base_textures_button9.png rename to textures/mcl_base_textures_button9.png diff --git a/mods/HUD/mcl_base_textures/textures/mcl_base_textures_button9_pressed.png b/textures/mcl_base_textures_button9_pressed.png similarity index 100% rename from mods/HUD/mcl_base_textures/textures/mcl_base_textures_button9_pressed.png rename to textures/mcl_base_textures_button9_pressed.png diff --git a/textures/mcl_beds_bed_black.png b/textures/mcl_beds_bed_black.png new file mode 100644 index 000000000..371468c54 Binary files /dev/null and b/textures/mcl_beds_bed_black.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png b/textures/mcl_beds_bed_black_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_black.png rename to textures/mcl_beds_bed_black_inv.png diff --git a/textures/mcl_beds_bed_blue.png b/textures/mcl_beds_bed_blue.png new file mode 100644 index 000000000..98b48b29a Binary files /dev/null and b/textures/mcl_beds_bed_blue.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png b/textures/mcl_beds_bed_blue_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_blue.png rename to textures/mcl_beds_bed_blue_inv.png diff --git a/textures/mcl_beds_bed_brown.png b/textures/mcl_beds_bed_brown.png new file mode 100644 index 000000000..30f7deec2 Binary files /dev/null and b/textures/mcl_beds_bed_brown.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png b/textures/mcl_beds_bed_brown_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_brown.png rename to textures/mcl_beds_bed_brown_inv.png diff --git a/textures/mcl_beds_bed_cyan.png b/textures/mcl_beds_bed_cyan.png new file mode 100644 index 000000000..d1b5ee703 Binary files /dev/null and b/textures/mcl_beds_bed_cyan.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png b/textures/mcl_beds_bed_cyan_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_cyan.png rename to textures/mcl_beds_bed_cyan_inv.png diff --git a/textures/mcl_beds_bed_green.png b/textures/mcl_beds_bed_green.png new file mode 100644 index 000000000..26302405a Binary files /dev/null and b/textures/mcl_beds_bed_green.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png b/textures/mcl_beds_bed_green_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_green.png rename to textures/mcl_beds_bed_green_inv.png diff --git a/textures/mcl_beds_bed_grey.png b/textures/mcl_beds_bed_grey.png new file mode 100644 index 000000000..4847f9265 Binary files /dev/null and b/textures/mcl_beds_bed_grey.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png b/textures/mcl_beds_bed_grey_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_grey.png rename to textures/mcl_beds_bed_grey_inv.png diff --git a/textures/mcl_beds_bed_light_blue.png b/textures/mcl_beds_bed_light_blue.png new file mode 100644 index 000000000..01a226bfb Binary files /dev/null and b/textures/mcl_beds_bed_light_blue.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png b/textures/mcl_beds_bed_light_blue_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_light_blue.png rename to textures/mcl_beds_bed_light_blue_inv.png diff --git a/textures/mcl_beds_bed_lime.png b/textures/mcl_beds_bed_lime.png new file mode 100644 index 000000000..2a6fc1c53 Binary files /dev/null and b/textures/mcl_beds_bed_lime.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png b/textures/mcl_beds_bed_lime_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_lime.png rename to textures/mcl_beds_bed_lime_inv.png diff --git a/textures/mcl_beds_bed_magenta.png b/textures/mcl_beds_bed_magenta.png new file mode 100644 index 000000000..c25b5d750 Binary files /dev/null and b/textures/mcl_beds_bed_magenta.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png b/textures/mcl_beds_bed_magenta_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_magenta.png rename to textures/mcl_beds_bed_magenta_inv.png diff --git a/textures/mcl_beds_bed_orange.png b/textures/mcl_beds_bed_orange.png new file mode 100644 index 000000000..a26be3a99 Binary files /dev/null and b/textures/mcl_beds_bed_orange.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png b/textures/mcl_beds_bed_orange_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_orange.png rename to textures/mcl_beds_bed_orange_inv.png diff --git a/textures/mcl_beds_bed_pink.png b/textures/mcl_beds_bed_pink.png new file mode 100644 index 000000000..6d6ea4e7b Binary files /dev/null and b/textures/mcl_beds_bed_pink.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png b/textures/mcl_beds_bed_pink_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_pink.png rename to textures/mcl_beds_bed_pink_inv.png diff --git a/textures/mcl_beds_bed_purple.png b/textures/mcl_beds_bed_purple.png new file mode 100644 index 000000000..f71764d9d Binary files /dev/null and b/textures/mcl_beds_bed_purple.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png b/textures/mcl_beds_bed_purple_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_purple.png rename to textures/mcl_beds_bed_purple_inv.png diff --git a/textures/mcl_beds_bed_red.png b/textures/mcl_beds_bed_red.png new file mode 100644 index 000000000..e4f5d3499 Binary files /dev/null and b/textures/mcl_beds_bed_red.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png b/textures/mcl_beds_bed_red_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_red.png rename to textures/mcl_beds_bed_red_inv.png diff --git a/textures/mcl_beds_bed_silver.png b/textures/mcl_beds_bed_silver.png new file mode 100644 index 000000000..e699971b0 Binary files /dev/null and b/textures/mcl_beds_bed_silver.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png b/textures/mcl_beds_bed_silver_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_silver.png rename to textures/mcl_beds_bed_silver_inv.png diff --git a/textures/mcl_beds_bed_white.png b/textures/mcl_beds_bed_white.png new file mode 100644 index 000000000..33e7d25c1 Binary files /dev/null and b/textures/mcl_beds_bed_white.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png b/textures/mcl_beds_bed_white_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_white.png rename to textures/mcl_beds_bed_white_inv.png diff --git a/textures/mcl_beds_bed_yellow.png b/textures/mcl_beds_bed_yellow.png new file mode 100644 index 000000000..1eb026fb1 Binary files /dev/null and b/textures/mcl_beds_bed_yellow.png differ diff --git a/mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png b/textures/mcl_beds_bed_yellow_inv.png similarity index 100% rename from mods/ITEMS/mcl_beds/textures/mcl_beds_bed_yellow.png rename to textures/mcl_beds_bed_yellow_inv.png diff --git a/textures/mcl_beehives_bee_nest_bottom.png b/textures/mcl_beehives_bee_nest_bottom.png new file mode 100644 index 000000000..f4fe0add6 Binary files /dev/null and b/textures/mcl_beehives_bee_nest_bottom.png differ diff --git a/textures/mcl_beehives_bee_nest_front.png b/textures/mcl_beehives_bee_nest_front.png new file mode 100644 index 000000000..c62ad9d68 Binary files /dev/null and b/textures/mcl_beehives_bee_nest_front.png differ diff --git a/textures/mcl_beehives_bee_nest_front_honey.png b/textures/mcl_beehives_bee_nest_front_honey.png new file mode 100644 index 000000000..692c11418 Binary files /dev/null and b/textures/mcl_beehives_bee_nest_front_honey.png differ diff --git a/textures/mcl_beehives_bee_nest_side.png b/textures/mcl_beehives_bee_nest_side.png new file mode 100644 index 000000000..36abc184d Binary files /dev/null and b/textures/mcl_beehives_bee_nest_side.png differ diff --git a/textures/mcl_beehives_bee_nest_top.png b/textures/mcl_beehives_bee_nest_top.png new file mode 100644 index 000000000..33c751d82 Binary files /dev/null and b/textures/mcl_beehives_bee_nest_top.png differ diff --git a/textures/mcl_beehives_beehive_end.png b/textures/mcl_beehives_beehive_end.png new file mode 100644 index 000000000..ffebc1b8f Binary files /dev/null and b/textures/mcl_beehives_beehive_end.png differ diff --git a/textures/mcl_beehives_beehive_front.png b/textures/mcl_beehives_beehive_front.png new file mode 100644 index 000000000..718fa2684 Binary files /dev/null and b/textures/mcl_beehives_beehive_front.png differ diff --git a/textures/mcl_beehives_beehive_front_honey.png b/textures/mcl_beehives_beehive_front_honey.png new file mode 100644 index 000000000..ba6926ced Binary files /dev/null and b/textures/mcl_beehives_beehive_front_honey.png differ diff --git a/textures/mcl_beehives_beehive_side.png b/textures/mcl_beehives_beehive_side.png new file mode 100644 index 000000000..ac8579faa Binary files /dev/null and b/textures/mcl_beehives_beehive_side.png differ diff --git a/textures/mcl_bells_bell.png b/textures/mcl_bells_bell.png new file mode 100644 index 000000000..2dc7c4c9b Binary files /dev/null and b/textures/mcl_bells_bell.png differ diff --git a/textures/mcl_bells_bell_bottom.png b/textures/mcl_bells_bell_bottom.png new file mode 100644 index 000000000..0f510df28 Binary files /dev/null and b/textures/mcl_bells_bell_bottom.png differ diff --git a/textures/mcl_bells_bell_side.png b/textures/mcl_bells_bell_side.png new file mode 100644 index 000000000..a75720e74 Binary files /dev/null and b/textures/mcl_bells_bell_side.png differ diff --git a/textures/mcl_bells_bell_top.png b/textures/mcl_bells_bell_top.png new file mode 100644 index 000000000..c57ba7332 Binary files /dev/null and b/textures/mcl_bells_bell_top.png differ diff --git a/textures/mcl_blackstone_basalt_side.png b/textures/mcl_blackstone_basalt_side.png new file mode 100644 index 000000000..cfb4dbdd1 Binary files /dev/null and b/textures/mcl_blackstone_basalt_side.png differ diff --git a/textures/mcl_blackstone_basalt_side_polished.png b/textures/mcl_blackstone_basalt_side_polished.png new file mode 100644 index 000000000..3f7175a25 Binary files /dev/null and b/textures/mcl_blackstone_basalt_side_polished.png differ diff --git a/textures/mcl_blackstone_basalt_smooth.png b/textures/mcl_blackstone_basalt_smooth.png new file mode 100644 index 000000000..ad04d5700 Binary files /dev/null and b/textures/mcl_blackstone_basalt_smooth.png differ diff --git a/textures/mcl_blackstone_basalt_top.png b/textures/mcl_blackstone_basalt_top.png new file mode 100644 index 000000000..c1981dfa4 Binary files /dev/null and b/textures/mcl_blackstone_basalt_top.png differ diff --git a/textures/mcl_blackstone_basalt_top_polished.png b/textures/mcl_blackstone_basalt_top_polished.png new file mode 100644 index 000000000..7386b20da Binary files /dev/null and b/textures/mcl_blackstone_basalt_top_polished.png differ diff --git a/textures/mcl_blackstone_chain.png b/textures/mcl_blackstone_chain.png new file mode 100644 index 000000000..993c44c93 Binary files /dev/null and b/textures/mcl_blackstone_chain.png differ diff --git a/textures/mcl_blackstone_chiseled_polished.png b/textures/mcl_blackstone_chiseled_polished.png new file mode 100644 index 000000000..3fc35d305 Binary files /dev/null and b/textures/mcl_blackstone_chiseled_polished.png differ diff --git a/textures/mcl_blackstone_gilded.png b/textures/mcl_blackstone_gilded.png new file mode 100644 index 000000000..4f9b84493 Binary files /dev/null and b/textures/mcl_blackstone_gilded.png differ diff --git a/textures/mcl_blackstone_polished.png b/textures/mcl_blackstone_polished.png new file mode 100644 index 000000000..42d22ad06 Binary files /dev/null and b/textures/mcl_blackstone_polished.png differ diff --git a/textures/mcl_blackstone_polished_bricks.png b/textures/mcl_blackstone_polished_bricks.png new file mode 100644 index 000000000..38440eff1 Binary files /dev/null and b/textures/mcl_blackstone_polished_bricks.png differ diff --git a/textures/mcl_blackstone_side.png b/textures/mcl_blackstone_side.png new file mode 100644 index 000000000..17f007bf1 Binary files /dev/null and b/textures/mcl_blackstone_side.png differ diff --git a/textures/mcl_blackstone_soul_soil.png b/textures/mcl_blackstone_soul_soil.png new file mode 100644 index 000000000..1cdf41fe2 Binary files /dev/null and b/textures/mcl_blackstone_soul_soil.png differ diff --git a/textures/mcl_blackstone_top.png b/textures/mcl_blackstone_top.png new file mode 100644 index 000000000..17f007bf1 Binary files /dev/null and b/textures/mcl_blackstone_top.png differ diff --git a/textures/mcl_boats_acacia_boat.png b/textures/mcl_boats_acacia_boat.png new file mode 100644 index 000000000..40f767c35 Binary files /dev/null and b/textures/mcl_boats_acacia_boat.png differ diff --git a/textures/mcl_boats_acacia_chest_boat.png b/textures/mcl_boats_acacia_chest_boat.png new file mode 100644 index 000000000..7acb4d132 Binary files /dev/null and b/textures/mcl_boats_acacia_chest_boat.png differ diff --git a/textures/mcl_boats_birch_boat.png b/textures/mcl_boats_birch_boat.png new file mode 100644 index 000000000..fed5be7cc Binary files /dev/null and b/textures/mcl_boats_birch_boat.png differ diff --git a/textures/mcl_boats_birch_chest_boat.png b/textures/mcl_boats_birch_chest_boat.png new file mode 100644 index 000000000..6c743ab4e Binary files /dev/null and b/textures/mcl_boats_birch_chest_boat.png differ diff --git a/textures/mcl_boats_cherry_boat.png b/textures/mcl_boats_cherry_boat.png new file mode 100644 index 000000000..118baddfd Binary files /dev/null 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 new file mode 100644 index 000000000..8bc3725e6 Binary files /dev/null and b/textures/mcl_boats_cherry_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_dark_oak_boat.png b/textures/mcl_boats_dark_oak_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_dark_oak_boat.png rename to textures/mcl_boats_dark_oak_boat.png diff --git a/textures/mcl_boats_dark_oak_chest_boat.png b/textures/mcl_boats_dark_oak_chest_boat.png new file mode 100644 index 000000000..7f2a346ec Binary files /dev/null and b/textures/mcl_boats_dark_oak_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_jungle_boat.png b/textures/mcl_boats_jungle_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_jungle_boat.png rename to textures/mcl_boats_jungle_boat.png diff --git a/textures/mcl_boats_jungle_chest_boat.png b/textures/mcl_boats_jungle_chest_boat.png new file mode 100644 index 000000000..05e544f4a Binary files /dev/null and b/textures/mcl_boats_jungle_chest_boat.png differ diff --git a/textures/mcl_boats_mangrove_boat.png b/textures/mcl_boats_mangrove_boat.png new file mode 100644 index 000000000..6ec7927c9 Binary files /dev/null and b/textures/mcl_boats_mangrove_boat.png differ diff --git a/textures/mcl_boats_mangrove_chest_boat.png b/textures/mcl_boats_mangrove_chest_boat.png new file mode 100644 index 000000000..85019881f Binary files /dev/null and b/textures/mcl_boats_mangrove_chest_boat.png differ diff --git a/textures/mcl_boats_oak_boat.png b/textures/mcl_boats_oak_boat.png new file mode 100644 index 000000000..75f27b219 Binary files /dev/null and b/textures/mcl_boats_oak_boat.png differ diff --git a/textures/mcl_boats_oak_chest_boat.png b/textures/mcl_boats_oak_chest_boat.png new file mode 100644 index 000000000..fd4f5a697 Binary files /dev/null and b/textures/mcl_boats_oak_chest_boat.png differ diff --git a/textures/mcl_boats_obsidian_boat.png b/textures/mcl_boats_obsidian_boat.png new file mode 100644 index 000000000..6ae10c0c4 Binary files /dev/null and b/textures/mcl_boats_obsidian_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_spruce_boat.png b/textures/mcl_boats_spruce_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_spruce_boat.png rename to textures/mcl_boats_spruce_boat.png diff --git a/textures/mcl_boats_spruce_chest_boat.png b/textures/mcl_boats_spruce_chest_boat.png new file mode 100644 index 000000000..67a7dce19 Binary files /dev/null and b/textures/mcl_boats_spruce_chest_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_acacia_boat.png b/textures/mcl_boats_texture_acacia_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_acacia_boat.png rename to textures/mcl_boats_texture_acacia_boat.png diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_birch_boat.png b/textures/mcl_boats_texture_birch_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_birch_boat.png rename to textures/mcl_boats_texture_birch_boat.png diff --git a/textures/mcl_boats_texture_cherry_boat.png b/textures/mcl_boats_texture_cherry_boat.png new file mode 100644 index 000000000..1c0febd9b Binary files /dev/null and b/textures/mcl_boats_texture_cherry_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_dark_oak_boat.png b/textures/mcl_boats_texture_dark_oak_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_dark_oak_boat.png rename to textures/mcl_boats_texture_dark_oak_boat.png diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_jungle_boat.png b/textures/mcl_boats_texture_jungle_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_jungle_boat.png rename to textures/mcl_boats_texture_jungle_boat.png diff --git a/textures/mcl_boats_texture_mangrove_boat.png b/textures/mcl_boats_texture_mangrove_boat.png new file mode 100644 index 000000000..be15f67a5 Binary files /dev/null and b/textures/mcl_boats_texture_mangrove_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_oak_boat.png b/textures/mcl_boats_texture_oak_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_oak_boat.png rename to textures/mcl_boats_texture_oak_boat.png diff --git a/textures/mcl_boats_texture_obsidian_boat.png b/textures/mcl_boats_texture_obsidian_boat.png new file mode 100644 index 000000000..af3c24b30 Binary files /dev/null and b/textures/mcl_boats_texture_obsidian_boat.png differ diff --git a/mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_spruce_boat.png b/textures/mcl_boats_texture_spruce_boat.png similarity index 100% rename from mods/ENTITIES/mcl_boats/textures/mcl_boats_texture_spruce_boat.png rename to textures/mcl_boats_texture_spruce_boat.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_white.png b/textures/mcl_bone_meal_bone_meal.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_white.png rename to textures/mcl_bone_meal_bone_meal.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_book_bg.png b/textures/mcl_books_book_bg.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_book_bg.png rename to textures/mcl_books_book_bg.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_book_writable.png b/textures/mcl_books_book_writable.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_book_writable.png rename to textures/mcl_books_book_writable.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_book_written.png b/textures/mcl_books_book_written.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_book_written.png rename to textures/mcl_books_book_written.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_bookshelf_top.png b/textures/mcl_books_bookshelf_top.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_bookshelf_top.png rename to textures/mcl_books_bookshelf_top.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_button9.png b/textures/mcl_books_button9.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_button9.png rename to textures/mcl_books_button9.png diff --git a/mods/ITEMS/mcl_books/textures/mcl_books_button9_pressed.png b/textures/mcl_books_button9_pressed.png similarity index 100% rename from mods/ITEMS/mcl_books/textures/mcl_books_button9_pressed.png rename to textures/mcl_books_button9_pressed.png diff --git a/textures/mcl_bossbars.png b/textures/mcl_bossbars.png new file mode 100644 index 000000000..cbb74e0df Binary files /dev/null and b/textures/mcl_bossbars.png differ diff --git a/textures/mcl_bossbars_empty.png b/textures/mcl_bossbars_empty.png new file mode 100644 index 000000000..eaa84172b Binary files /dev/null and b/textures/mcl_bossbars_empty.png differ diff --git a/textures/mcl_bows_arrow.png b/textures/mcl_bows_arrow.png new file mode 100644 index 000000000..65f4111ba Binary files /dev/null and b/textures/mcl_bows_arrow.png differ diff --git a/textures/mcl_bows_arrow_back.png b/textures/mcl_bows_arrow_back.png new file mode 100644 index 000000000..038cee470 Binary files /dev/null and b/textures/mcl_bows_arrow_back.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_front.png b/textures/mcl_bows_arrow_front.png similarity index 100% rename from mods/ITEMS/mcl_bows/textures/mcl_bows_arrow_front.png rename to textures/mcl_bows_arrow_front.png diff --git a/textures/mcl_bows_arrow_inv.png b/textures/mcl_bows_arrow_inv.png new file mode 100644 index 000000000..65dfb7f0d Binary files /dev/null and b/textures/mcl_bows_arrow_inv.png differ diff --git a/textures/mcl_bows_arrow_overlay.png b/textures/mcl_bows_arrow_overlay.png new file mode 100644 index 000000000..8e33f358f Binary files /dev/null and b/textures/mcl_bows_arrow_overlay.png differ diff --git a/textures/mcl_bows_bow.png b/textures/mcl_bows_bow.png new file mode 100644 index 000000000..6df5c5b81 Binary files /dev/null and b/textures/mcl_bows_bow.png differ diff --git a/textures/mcl_bows_bow_0.png b/textures/mcl_bows_bow_0.png new file mode 100644 index 000000000..f2867b2a8 Binary files /dev/null and b/textures/mcl_bows_bow_0.png differ diff --git a/textures/mcl_bows_bow_1.png b/textures/mcl_bows_bow_1.png new file mode 100644 index 000000000..881206eb0 Binary files /dev/null and b/textures/mcl_bows_bow_1.png differ diff --git a/mods/ITEMS/mcl_bows/textures/mcl_bows_bow_2.png b/textures/mcl_bows_bow_2.png similarity index 100% rename from mods/ITEMS/mcl_bows/textures/mcl_bows_bow_2.png rename to textures/mcl_bows_bow_2.png diff --git a/textures/mcl_bows_crossbow.png b/textures/mcl_bows_crossbow.png new file mode 100644 index 000000000..a3f4f8b36 Binary files /dev/null and b/textures/mcl_bows_crossbow.png differ diff --git a/textures/mcl_bows_crossbow_0.png b/textures/mcl_bows_crossbow_0.png new file mode 100644 index 000000000..337be27bf Binary files /dev/null and b/textures/mcl_bows_crossbow_0.png differ diff --git a/textures/mcl_bows_crossbow_1.png b/textures/mcl_bows_crossbow_1.png new file mode 100644 index 000000000..598a3f1a5 Binary files /dev/null and b/textures/mcl_bows_crossbow_1.png differ diff --git a/textures/mcl_bows_crossbow_2.png b/textures/mcl_bows_crossbow_2.png new file mode 100644 index 000000000..d9bf8ed86 Binary files /dev/null and b/textures/mcl_bows_crossbow_2.png differ diff --git a/textures/mcl_bows_crossbow_3.png b/textures/mcl_bows_crossbow_3.png new file mode 100644 index 000000000..d1e5a07f4 Binary files /dev/null and b/textures/mcl_bows_crossbow_3.png differ diff --git a/textures/mcl_bows_firework_blue.png b/textures/mcl_bows_firework_blue.png new file mode 100644 index 000000000..7dab41cc8 Binary files /dev/null and b/textures/mcl_bows_firework_blue.png differ diff --git a/textures/mcl_bows_firework_green.png b/textures/mcl_bows_firework_green.png new file mode 100644 index 000000000..302bba5b1 Binary files /dev/null and b/textures/mcl_bows_firework_green.png differ diff --git a/textures/mcl_bows_firework_red.png b/textures/mcl_bows_firework_red.png new file mode 100644 index 000000000..bc6889a18 Binary files /dev/null and b/textures/mcl_bows_firework_red.png differ diff --git a/textures/mcl_bows_firework_white.png b/textures/mcl_bows_firework_white.png new file mode 100644 index 000000000..c0a464389 Binary files /dev/null and b/textures/mcl_bows_firework_white.png differ diff --git a/textures/mcl_bows_firework_yellow.png b/textures/mcl_bows_firework_yellow.png new file mode 100644 index 000000000..9575566fe Binary files /dev/null and b/textures/mcl_bows_firework_yellow.png differ diff --git a/textures/mcl_bows_rocket.png b/textures/mcl_bows_rocket.png new file mode 100644 index 000000000..faf7fb576 Binary files /dev/null and b/textures/mcl_bows_rocket.png differ diff --git a/textures/mcl_bows_rocket_particle.png b/textures/mcl_bows_rocket_particle.png new file mode 100644 index 000000000..5dd5e2f3f Binary files /dev/null and b/textures/mcl_bows_rocket_particle.png differ diff --git a/textures/mcl_brewing_base.png b/textures/mcl_brewing_base.png new file mode 100644 index 000000000..9e9145af9 Binary files /dev/null and b/textures/mcl_brewing_base.png differ diff --git a/textures/mcl_brewing_bottle_bg.png b/textures/mcl_brewing_bottle_bg.png new file mode 100644 index 000000000..e6f9b1d91 Binary files /dev/null and b/textures/mcl_brewing_bottle_bg.png differ diff --git a/textures/mcl_brewing_bubble_sprite.png b/textures/mcl_brewing_bubble_sprite.png new file mode 100644 index 000000000..e945203f2 Binary files /dev/null and b/textures/mcl_brewing_bubble_sprite.png differ diff --git a/textures/mcl_brewing_bubbles.png b/textures/mcl_brewing_bubbles.png new file mode 100644 index 000000000..656252a7b Binary files /dev/null and b/textures/mcl_brewing_bubbles.png differ diff --git a/textures/mcl_brewing_bubbles_active.png b/textures/mcl_brewing_bubbles_active.png new file mode 100644 index 000000000..c4f74a2a2 Binary files /dev/null and b/textures/mcl_brewing_bubbles_active.png differ diff --git a/textures/mcl_brewing_burner.png b/textures/mcl_brewing_burner.png new file mode 100644 index 000000000..8df38ac93 Binary files /dev/null and b/textures/mcl_brewing_burner.png differ diff --git a/textures/mcl_brewing_burner_active.png b/textures/mcl_brewing_burner_active.png new file mode 100644 index 000000000..cd3c0105b Binary files /dev/null and b/textures/mcl_brewing_burner_active.png differ diff --git a/textures/mcl_brewing_fuel_bg.png b/textures/mcl_brewing_fuel_bg.png new file mode 100644 index 000000000..3e628e84d Binary files /dev/null and b/textures/mcl_brewing_fuel_bg.png differ diff --git a/textures/mcl_brewing_inventory.png b/textures/mcl_brewing_inventory.png new file mode 100644 index 000000000..4bd6538d8 Binary files /dev/null and b/textures/mcl_brewing_inventory.png differ diff --git a/textures/mcl_brewing_potion_bg.png b/textures/mcl_brewing_potion_bg.png new file mode 100644 index 000000000..05ef058a5 Binary files /dev/null and b/textures/mcl_brewing_potion_bg.png differ diff --git a/textures/mcl_brewing_side.png b/textures/mcl_brewing_side.png new file mode 100644 index 000000000..eba693d8b Binary files /dev/null and b/textures/mcl_brewing_side.png differ diff --git a/textures/mcl_brewing_top.png b/textures/mcl_brewing_top.png new file mode 100644 index 000000000..b21718390 Binary files /dev/null and b/textures/mcl_brewing_top.png differ diff --git a/textures/mcl_buckets_axolotl_bucket.png b/textures/mcl_buckets_axolotl_bucket.png new file mode 100644 index 000000000..9fadf68b1 Binary files /dev/null and b/textures/mcl_buckets_axolotl_bucket.png differ diff --git a/mods/ITEMS/mcl_buckets/textures/bucket.png b/textures/mcl_buckets_bucket.png similarity index 100% rename from mods/ITEMS/mcl_buckets/textures/bucket.png rename to textures/mcl_buckets_bucket.png diff --git a/textures/mcl_buckets_cod_bucket.png b/textures/mcl_buckets_cod_bucket.png new file mode 100644 index 000000000..bca265ef3 Binary files /dev/null and b/textures/mcl_buckets_cod_bucket.png differ diff --git a/mods/ITEMS/mcl_buckets/textures/bucket_lava.png b/textures/mcl_buckets_lava_bucket.png similarity index 100% rename from mods/ITEMS/mcl_buckets/textures/bucket_lava.png rename to textures/mcl_buckets_lava_bucket.png diff --git a/textures/mcl_buckets_pufferfish_bucket.png b/textures/mcl_buckets_pufferfish_bucket.png new file mode 100644 index 000000000..7461c1786 Binary files /dev/null and b/textures/mcl_buckets_pufferfish_bucket.png differ diff --git a/mods/ITEMS/mcl_buckets/textures/bucket_river_water.png b/textures/mcl_buckets_river_water_bucket.png similarity index 100% rename from mods/ITEMS/mcl_buckets/textures/bucket_river_water.png rename to textures/mcl_buckets_river_water_bucket.png diff --git a/textures/mcl_buckets_salmon_bucket.png b/textures/mcl_buckets_salmon_bucket.png new file mode 100644 index 000000000..ab30c26e4 Binary files /dev/null and b/textures/mcl_buckets_salmon_bucket.png differ diff --git a/textures/mcl_buckets_tropical_fish_bucket.png b/textures/mcl_buckets_tropical_fish_bucket.png new file mode 100644 index 000000000..d29f539d3 Binary files /dev/null and b/textures/mcl_buckets_tropical_fish_bucket.png differ diff --git a/mods/ITEMS/mcl_buckets/textures/bucket_water.png b/textures/mcl_buckets_water_bucket.png similarity index 100% rename from mods/ITEMS/mcl_buckets/textures/bucket_water.png rename to textures/mcl_buckets_water_bucket.png diff --git a/mods/ITEMS/mcl_fire/textures/mcl_burning_entity_flame_animated.png b/textures/mcl_burning_entity_flame_animated.png similarity index 100% rename from mods/ITEMS/mcl_fire/textures/mcl_burning_entity_flame_animated.png rename to textures/mcl_burning_entity_flame_animated.png diff --git a/mods/ITEMS/mcl_fire/textures/mcl_burning_hud_flame_animated.png b/textures/mcl_burning_hud_flame_animated.png similarity index 100% rename from mods/ITEMS/mcl_fire/textures/mcl_burning_hud_flame_animated.png rename to textures/mcl_burning_hud_flame_animated.png diff --git a/textures/mcl_campfires_campfire_fire.png b/textures/mcl_campfires_campfire_fire.png new file mode 100644 index 000000000..3894744c6 Binary files /dev/null and b/textures/mcl_campfires_campfire_fire.png differ diff --git a/textures/mcl_campfires_campfire_inv.png b/textures/mcl_campfires_campfire_inv.png new file mode 100644 index 000000000..04add6ca3 Binary files /dev/null and b/textures/mcl_campfires_campfire_inv.png differ diff --git a/textures/mcl_campfires_campfire_log_lit.png b/textures/mcl_campfires_campfire_log_lit.png new file mode 100644 index 000000000..117e78369 Binary files /dev/null and b/textures/mcl_campfires_campfire_log_lit.png differ diff --git a/textures/mcl_campfires_fire1.png b/textures/mcl_campfires_fire1.png new file mode 100644 index 000000000..2956e2e7c Binary files /dev/null and b/textures/mcl_campfires_fire1.png differ diff --git a/textures/mcl_campfires_log.png b/textures/mcl_campfires_log.png new file mode 100644 index 000000000..62de149a0 Binary files /dev/null and b/textures/mcl_campfires_log.png differ diff --git a/textures/mcl_campfires_soul_campfire_fire.png b/textures/mcl_campfires_soul_campfire_fire.png new file mode 100644 index 000000000..0f5580e5c Binary files /dev/null and b/textures/mcl_campfires_soul_campfire_fire.png differ diff --git a/textures/mcl_campfires_soul_campfire_inv.png b/textures/mcl_campfires_soul_campfire_inv.png new file mode 100644 index 000000000..6dd17614e Binary files /dev/null and b/textures/mcl_campfires_soul_campfire_inv.png differ diff --git a/textures/mcl_campfires_soul_campfire_log_lit.png b/textures/mcl_campfires_soul_campfire_log_lit.png new file mode 100644 index 000000000..aa7459bf5 Binary files /dev/null and b/textures/mcl_campfires_soul_campfire_log_lit.png differ diff --git a/textures/mcl_cartography_table_side1.png b/textures/mcl_cartography_table_side1.png new file mode 100644 index 000000000..0f31fb4b2 Binary files /dev/null and b/textures/mcl_cartography_table_side1.png differ diff --git a/textures/mcl_cartography_table_side2.png b/textures/mcl_cartography_table_side2.png new file mode 100644 index 000000000..68fc59706 Binary files /dev/null and b/textures/mcl_cartography_table_side2.png differ diff --git a/textures/mcl_cartography_table_side3.png b/textures/mcl_cartography_table_side3.png new file mode 100644 index 000000000..d7b27f04e Binary files /dev/null and b/textures/mcl_cartography_table_side3.png differ diff --git a/textures/mcl_cartography_table_top.png b/textures/mcl_cartography_table_top.png new file mode 100644 index 000000000..57c7a32e1 Binary files /dev/null and b/textures/mcl_cartography_table_top.png differ diff --git a/textures/mcl_cauldrons_cauldron.png b/textures/mcl_cauldrons_cauldron.png new file mode 100644 index 000000000..b4a51c313 Binary files /dev/null and b/textures/mcl_cauldrons_cauldron.png differ diff --git a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_bottom.png b/textures/mcl_cauldrons_cauldron_bottom.png similarity index 100% rename from mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_bottom.png rename to textures/mcl_cauldrons_cauldron_bottom.png diff --git a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_inner.png b/textures/mcl_cauldrons_cauldron_inner.png similarity index 100% rename from mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_inner.png rename to textures/mcl_cauldrons_cauldron_inner.png diff --git a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_side.png b/textures/mcl_cauldrons_cauldron_side.png similarity index 100% rename from mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_side.png rename to textures/mcl_cauldrons_cauldron_side.png diff --git a/mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_top.png b/textures/mcl_cauldrons_cauldron_top.png similarity index 100% rename from mods/ITEMS/mcl_cauldrons/textures/mcl_cauldrons_cauldron_top.png rename to textures/mcl_cauldrons_cauldron_top.png diff --git a/textures/mcl_cherry_blossom_door_bottom.png b/textures/mcl_cherry_blossom_door_bottom.png new file mode 100644 index 000000000..0a5b3661f Binary files /dev/null and b/textures/mcl_cherry_blossom_door_bottom.png differ diff --git a/textures/mcl_cherry_blossom_door_bottom_bottompart.png b/textures/mcl_cherry_blossom_door_bottom_bottompart.png new file mode 100644 index 000000000..5c65e6f46 Binary files /dev/null and b/textures/mcl_cherry_blossom_door_bottom_bottompart.png differ diff --git a/textures/mcl_cherry_blossom_door_bottom_side.png b/textures/mcl_cherry_blossom_door_bottom_side.png new file mode 100644 index 000000000..5c6109b6f Binary files /dev/null and b/textures/mcl_cherry_blossom_door_bottom_side.png differ diff --git a/textures/mcl_cherry_blossom_door_inv.png b/textures/mcl_cherry_blossom_door_inv.png new file mode 100644 index 000000000..f3a15c090 Binary files /dev/null and b/textures/mcl_cherry_blossom_door_inv.png differ diff --git a/textures/mcl_cherry_blossom_door_top.png b/textures/mcl_cherry_blossom_door_top.png new file mode 100644 index 000000000..b2ac87e14 Binary files /dev/null and b/textures/mcl_cherry_blossom_door_top.png differ diff --git a/textures/mcl_cherry_blossom_door_top_side.png b/textures/mcl_cherry_blossom_door_top_side.png new file mode 100644 index 000000000..5c6109b6f Binary files /dev/null and b/textures/mcl_cherry_blossom_door_top_side.png differ diff --git a/textures/mcl_cherry_blossom_door_top_toppart.png b/textures/mcl_cherry_blossom_door_top_toppart.png new file mode 100644 index 000000000..ed317fa2c Binary files /dev/null and b/textures/mcl_cherry_blossom_door_top_toppart.png differ diff --git a/textures/mcl_cherry_blossom_leaves.png b/textures/mcl_cherry_blossom_leaves.png new file mode 100644 index 000000000..94e223d5b Binary files /dev/null and b/textures/mcl_cherry_blossom_leaves.png differ diff --git a/textures/mcl_cherry_blossom_log.png b/textures/mcl_cherry_blossom_log.png new file mode 100644 index 000000000..05feb9721 Binary files /dev/null and b/textures/mcl_cherry_blossom_log.png differ diff --git a/textures/mcl_cherry_blossom_log_stripped.png b/textures/mcl_cherry_blossom_log_stripped.png new file mode 100644 index 000000000..33e84f7d6 Binary files /dev/null and b/textures/mcl_cherry_blossom_log_stripped.png differ diff --git a/textures/mcl_cherry_blossom_log_top.png b/textures/mcl_cherry_blossom_log_top.png new file mode 100644 index 000000000..48450e458 Binary files /dev/null and b/textures/mcl_cherry_blossom_log_top.png differ diff --git a/textures/mcl_cherry_blossom_log_top_stripped.png b/textures/mcl_cherry_blossom_log_top_stripped.png new file mode 100644 index 000000000..775e2664e Binary files /dev/null and b/textures/mcl_cherry_blossom_log_top_stripped.png differ diff --git a/textures/mcl_cherry_blossom_particle.png b/textures/mcl_cherry_blossom_particle.png new file mode 100644 index 000000000..eabdb097c Binary files /dev/null and b/textures/mcl_cherry_blossom_particle.png differ diff --git a/textures/mcl_cherry_blossom_planks.png b/textures/mcl_cherry_blossom_planks.png new file mode 100644 index 000000000..9d2306eb8 Binary files /dev/null and b/textures/mcl_cherry_blossom_planks.png differ diff --git a/textures/mcl_cherry_blossom_sapling.png b/textures/mcl_cherry_blossom_sapling.png new file mode 100644 index 000000000..9ef0d919c Binary files /dev/null and b/textures/mcl_cherry_blossom_sapling.png differ diff --git a/textures/mcl_cherry_blossom_sign.png b/textures/mcl_cherry_blossom_sign.png new file mode 100644 index 000000000..3ec1958c0 Binary files /dev/null and b/textures/mcl_cherry_blossom_sign.png differ diff --git a/textures/mcl_cherry_blossom_sign_inv.png b/textures/mcl_cherry_blossom_sign_inv.png new file mode 100644 index 000000000..f052d3643 Binary files /dev/null and b/textures/mcl_cherry_blossom_sign_inv.png differ diff --git a/textures/mcl_cherry_blossom_trapdoor.png b/textures/mcl_cherry_blossom_trapdoor.png new file mode 100644 index 000000000..ecf68e629 Binary files /dev/null and b/textures/mcl_cherry_blossom_trapdoor.png differ diff --git a/textures/mcl_cherry_blossom_trapdoor_side.png b/textures/mcl_cherry_blossom_trapdoor_side.png new file mode 100644 index 000000000..7f4a84a4c Binary files /dev/null and b/textures/mcl_cherry_blossom_trapdoor_side.png differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_ender.png b/textures/mcl_chests_ender.png similarity index 100% rename from mods/ITEMS/mcl_chests/textures/mcl_chests_ender.png rename to textures/mcl_chests_ender.png diff --git a/textures/mcl_chests_ender_present.png b/textures/mcl_chests_ender_present.png new file mode 100644 index 000000000..869e4b909 Binary files /dev/null and b/textures/mcl_chests_ender_present.png differ diff --git a/textures/mcl_chests_noise.png b/textures/mcl_chests_noise.png new file mode 100644 index 000000000..6e2ec933f Binary files /dev/null and b/textures/mcl_chests_noise.png differ diff --git a/textures/mcl_chests_noise_double.png b/textures/mcl_chests_noise_double.png new file mode 100644 index 000000000..ca7fa78e5 Binary files /dev/null and b/textures/mcl_chests_noise_double.png differ diff --git a/textures/mcl_chests_normal.png b/textures/mcl_chests_normal.png new file mode 100644 index 000000000..9974f60d5 Binary files /dev/null and b/textures/mcl_chests_normal.png differ diff --git a/textures/mcl_chests_normal_double.png b/textures/mcl_chests_normal_double.png new file mode 100644 index 000000000..f7357ddaa Binary files /dev/null and b/textures/mcl_chests_normal_double.png differ diff --git a/textures/mcl_chests_normal_double_present.png b/textures/mcl_chests_normal_double_present.png new file mode 100644 index 000000000..55139fcb2 Binary files /dev/null and b/textures/mcl_chests_normal_double_present.png differ diff --git a/textures/mcl_chests_normal_present.png b/textures/mcl_chests_normal_present.png new file mode 100644 index 000000000..182d7c358 Binary files /dev/null and b/textures/mcl_chests_normal_present.png differ diff --git a/textures/mcl_chests_trapped.png b/textures/mcl_chests_trapped.png new file mode 100644 index 000000000..ebbca8a6a Binary files /dev/null and b/textures/mcl_chests_trapped.png differ diff --git a/textures/mcl_chests_trapped_double.png b/textures/mcl_chests_trapped_double.png new file mode 100644 index 000000000..88ff45825 Binary files /dev/null and b/textures/mcl_chests_trapped_double.png differ diff --git a/textures/mcl_chests_trapped_double_present.png b/textures/mcl_chests_trapped_double_present.png new file mode 100644 index 000000000..2d10331f3 Binary files /dev/null and b/textures/mcl_chests_trapped_double_present.png differ diff --git a/textures/mcl_chests_trapped_present.png b/textures/mcl_chests_trapped_present.png new file mode 100644 index 000000000..c6e3690d1 Binary files /dev/null and b/textures/mcl_chests_trapped_present.png differ diff --git a/textures/mcl_chiseled_deepslate.png b/textures/mcl_chiseled_deepslate.png new file mode 100644 index 000000000..8150e5230 Binary files /dev/null and b/textures/mcl_chiseled_deepslate.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_00.png b/textures/mcl_clock_clock_00.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_00.png rename to textures/mcl_clock_clock_00.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_01.png b/textures/mcl_clock_clock_01.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_01.png rename to textures/mcl_clock_clock_01.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_02.png b/textures/mcl_clock_clock_02.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_02.png rename to textures/mcl_clock_clock_02.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_03.png b/textures/mcl_clock_clock_03.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_03.png rename to textures/mcl_clock_clock_03.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_04.png b/textures/mcl_clock_clock_04.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_04.png rename to textures/mcl_clock_clock_04.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_05.png b/textures/mcl_clock_clock_05.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_05.png rename to textures/mcl_clock_clock_05.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_06.png b/textures/mcl_clock_clock_06.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_06.png rename to textures/mcl_clock_clock_06.png diff --git a/textures/mcl_clock_clock_07.png b/textures/mcl_clock_clock_07.png new file mode 100644 index 000000000..ef1c59c7c Binary files /dev/null and b/textures/mcl_clock_clock_07.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_08.png b/textures/mcl_clock_clock_08.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_08.png rename to textures/mcl_clock_clock_08.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_09.png b/textures/mcl_clock_clock_09.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_09.png rename to textures/mcl_clock_clock_09.png diff --git a/textures/mcl_clock_clock_10.png b/textures/mcl_clock_clock_10.png new file mode 100644 index 000000000..0bc5290b1 Binary files /dev/null and b/textures/mcl_clock_clock_10.png differ diff --git a/textures/mcl_clock_clock_11.png b/textures/mcl_clock_clock_11.png new file mode 100644 index 000000000..ef8b924e9 Binary files /dev/null and b/textures/mcl_clock_clock_11.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_12.png b/textures/mcl_clock_clock_12.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_12.png rename to textures/mcl_clock_clock_12.png diff --git a/textures/mcl_clock_clock_13.png b/textures/mcl_clock_clock_13.png new file mode 100644 index 000000000..7125cde0b Binary files /dev/null and b/textures/mcl_clock_clock_13.png differ diff --git a/textures/mcl_clock_clock_14.png b/textures/mcl_clock_clock_14.png new file mode 100644 index 000000000..8ac416601 Binary files /dev/null and b/textures/mcl_clock_clock_14.png differ diff --git a/textures/mcl_clock_clock_15.png b/textures/mcl_clock_clock_15.png new file mode 100644 index 000000000..05ae6bb6b Binary files /dev/null and b/textures/mcl_clock_clock_15.png differ diff --git a/textures/mcl_clock_clock_16.png b/textures/mcl_clock_clock_16.png new file mode 100644 index 000000000..2fa294782 Binary files /dev/null and b/textures/mcl_clock_clock_16.png differ diff --git a/textures/mcl_clock_clock_17.png b/textures/mcl_clock_clock_17.png new file mode 100644 index 000000000..2c679d70e Binary files /dev/null and b/textures/mcl_clock_clock_17.png differ diff --git a/textures/mcl_clock_clock_18.png b/textures/mcl_clock_clock_18.png new file mode 100644 index 000000000..49ae5e714 Binary files /dev/null and b/textures/mcl_clock_clock_18.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_19.png b/textures/mcl_clock_clock_19.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_19.png rename to textures/mcl_clock_clock_19.png diff --git a/textures/mcl_clock_clock_20.png b/textures/mcl_clock_clock_20.png new file mode 100644 index 000000000..11c33c965 Binary files /dev/null and b/textures/mcl_clock_clock_20.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_21.png b/textures/mcl_clock_clock_21.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_21.png rename to textures/mcl_clock_clock_21.png diff --git a/textures/mcl_clock_clock_22.png b/textures/mcl_clock_clock_22.png new file mode 100644 index 000000000..9c613ea8f Binary files /dev/null and b/textures/mcl_clock_clock_22.png differ diff --git a/textures/mcl_clock_clock_23.png b/textures/mcl_clock_clock_23.png new file mode 100644 index 000000000..60a8986d4 Binary files /dev/null and b/textures/mcl_clock_clock_23.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_24.png b/textures/mcl_clock_clock_24.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_24.png rename to textures/mcl_clock_clock_24.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_25.png b/textures/mcl_clock_clock_25.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_25.png rename to textures/mcl_clock_clock_25.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_26.png b/textures/mcl_clock_clock_26.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_26.png rename to textures/mcl_clock_clock_26.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_27.png b/textures/mcl_clock_clock_27.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_27.png rename to textures/mcl_clock_clock_27.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_28.png b/textures/mcl_clock_clock_28.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_28.png rename to textures/mcl_clock_clock_28.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_29.png b/textures/mcl_clock_clock_29.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_29.png rename to textures/mcl_clock_clock_29.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_30.png b/textures/mcl_clock_clock_30.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_30.png rename to textures/mcl_clock_clock_30.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_31.png b/textures/mcl_clock_clock_31.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_31.png rename to textures/mcl_clock_clock_31.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_32.png b/textures/mcl_clock_clock_32.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_32.png rename to textures/mcl_clock_clock_32.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_33.png b/textures/mcl_clock_clock_33.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_33.png rename to textures/mcl_clock_clock_33.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_34.png b/textures/mcl_clock_clock_34.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_34.png rename to textures/mcl_clock_clock_34.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_35.png b/textures/mcl_clock_clock_35.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_35.png rename to textures/mcl_clock_clock_35.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_36.png b/textures/mcl_clock_clock_36.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_36.png rename to textures/mcl_clock_clock_36.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_37.png b/textures/mcl_clock_clock_37.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_37.png rename to textures/mcl_clock_clock_37.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_38.png b/textures/mcl_clock_clock_38.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_38.png rename to textures/mcl_clock_clock_38.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_39.png b/textures/mcl_clock_clock_39.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_39.png rename to textures/mcl_clock_clock_39.png diff --git a/textures/mcl_clock_clock_40.png b/textures/mcl_clock_clock_40.png new file mode 100644 index 000000000..72f0b83a5 Binary files /dev/null and b/textures/mcl_clock_clock_40.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_41.png b/textures/mcl_clock_clock_41.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_41.png rename to textures/mcl_clock_clock_41.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_42.png b/textures/mcl_clock_clock_42.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_42.png rename to textures/mcl_clock_clock_42.png diff --git a/textures/mcl_clock_clock_43.png b/textures/mcl_clock_clock_43.png new file mode 100644 index 000000000..9ebe0d6f7 Binary files /dev/null and b/textures/mcl_clock_clock_43.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_44.png b/textures/mcl_clock_clock_44.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_44.png rename to textures/mcl_clock_clock_44.png diff --git a/textures/mcl_clock_clock_45.png b/textures/mcl_clock_clock_45.png new file mode 100644 index 000000000..e3db7078e Binary files /dev/null and b/textures/mcl_clock_clock_45.png differ diff --git a/textures/mcl_clock_clock_46.png b/textures/mcl_clock_clock_46.png new file mode 100644 index 000000000..d0377cc14 Binary files /dev/null and b/textures/mcl_clock_clock_46.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_47.png b/textures/mcl_clock_clock_47.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_47.png rename to textures/mcl_clock_clock_47.png diff --git a/textures/mcl_clock_clock_48.png b/textures/mcl_clock_clock_48.png new file mode 100644 index 000000000..794167150 Binary files /dev/null and b/textures/mcl_clock_clock_48.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_49.png b/textures/mcl_clock_clock_49.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_49.png rename to textures/mcl_clock_clock_49.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_50.png b/textures/mcl_clock_clock_50.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_50.png rename to textures/mcl_clock_clock_50.png diff --git a/textures/mcl_clock_clock_51.png b/textures/mcl_clock_clock_51.png new file mode 100644 index 000000000..622859114 Binary files /dev/null and b/textures/mcl_clock_clock_51.png differ diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_52.png b/textures/mcl_clock_clock_52.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_52.png rename to textures/mcl_clock_clock_52.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_53.png b/textures/mcl_clock_clock_53.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_53.png rename to textures/mcl_clock_clock_53.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_54.png b/textures/mcl_clock_clock_54.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_54.png rename to textures/mcl_clock_clock_54.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_55.png b/textures/mcl_clock_clock_55.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_55.png rename to textures/mcl_clock_clock_55.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_56.png b/textures/mcl_clock_clock_56.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_56.png rename to textures/mcl_clock_clock_56.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_57.png b/textures/mcl_clock_clock_57.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_57.png rename to textures/mcl_clock_clock_57.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_58.png b/textures/mcl_clock_clock_58.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_58.png rename to textures/mcl_clock_clock_58.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_59.png b/textures/mcl_clock_clock_59.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_59.png rename to textures/mcl_clock_clock_59.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_60.png b/textures/mcl_clock_clock_60.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_60.png rename to textures/mcl_clock_clock_60.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_61.png b/textures/mcl_clock_clock_61.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_61.png rename to textures/mcl_clock_clock_61.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_62.png b/textures/mcl_clock_clock_62.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_62.png rename to textures/mcl_clock_clock_62.png diff --git a/mods/ITEMS/mcl_clock/textures/mcl_clock_clock_63.png b/textures/mcl_clock_clock_63.png similarity index 100% rename from mods/ITEMS/mcl_clock/textures/mcl_clock_clock_63.png rename to textures/mcl_clock_clock_63.png diff --git a/textures/mcl_cobbled_deepslate.png b/textures/mcl_cobbled_deepslate.png new file mode 100644 index 000000000..05f03f3e8 Binary files /dev/null and b/textures/mcl_cobbled_deepslate.png differ diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png b/textures/mcl_cocoas_cocoa_beans.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_brown.png rename to textures/mcl_cocoas_cocoa_beans.png diff --git a/textures/mcl_cocoas_cocoa_stage_0.png b/textures/mcl_cocoas_cocoa_stage_0.png new file mode 100644 index 000000000..7cbdee3f6 Binary files /dev/null and b/textures/mcl_cocoas_cocoa_stage_0.png differ diff --git a/mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_1.png b/textures/mcl_cocoas_cocoa_stage_1.png similarity index 100% rename from mods/ITEMS/mcl_cocoas/textures/mcl_cocoas_cocoa_stage_1.png rename to textures/mcl_cocoas_cocoa_stage_1.png diff --git a/textures/mcl_cocoas_cocoa_stage_2.png b/textures/mcl_cocoas_cocoa_stage_2.png new file mode 100644 index 000000000..c5f2c17fc Binary files /dev/null and b/textures/mcl_cocoas_cocoa_stage_2.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_black.png b/textures/mcl_colorblocks_concrete_black.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_black.png rename to textures/mcl_colorblocks_concrete_black.png diff --git a/textures/mcl_colorblocks_concrete_blue.png b/textures/mcl_colorblocks_concrete_blue.png new file mode 100644 index 000000000..bd3ef19ae Binary files /dev/null and b/textures/mcl_colorblocks_concrete_blue.png differ diff --git a/textures/mcl_colorblocks_concrete_brown.png b/textures/mcl_colorblocks_concrete_brown.png new file mode 100644 index 000000000..1214e7c61 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_brown.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_cyan.png b/textures/mcl_colorblocks_concrete_cyan.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_cyan.png rename to textures/mcl_colorblocks_concrete_cyan.png diff --git a/textures/mcl_colorblocks_concrete_green.png b/textures/mcl_colorblocks_concrete_green.png new file mode 100644 index 000000000..a7c54224f Binary files /dev/null and b/textures/mcl_colorblocks_concrete_green.png differ diff --git a/textures/mcl_colorblocks_concrete_grey.png b/textures/mcl_colorblocks_concrete_grey.png new file mode 100644 index 000000000..bf4a83367 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_grey.png differ diff --git a/textures/mcl_colorblocks_concrete_light_blue.png b/textures/mcl_colorblocks_concrete_light_blue.png new file mode 100644 index 000000000..21ddec3de Binary files /dev/null and b/textures/mcl_colorblocks_concrete_light_blue.png differ diff --git a/textures/mcl_colorblocks_concrete_lime.png b/textures/mcl_colorblocks_concrete_lime.png new file mode 100644 index 000000000..49067b6f8 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_lime.png differ diff --git a/textures/mcl_colorblocks_concrete_magenta.png b/textures/mcl_colorblocks_concrete_magenta.png new file mode 100644 index 000000000..0732c0bc5 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_magenta.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_orange.png b/textures/mcl_colorblocks_concrete_orange.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_orange.png rename to textures/mcl_colorblocks_concrete_orange.png diff --git a/textures/mcl_colorblocks_concrete_pink.png b/textures/mcl_colorblocks_concrete_pink.png new file mode 100644 index 000000000..3450015e3 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_pink.png differ diff --git a/textures/mcl_colorblocks_concrete_powder_black.png b/textures/mcl_colorblocks_concrete_powder_black.png new file mode 100644 index 000000000..caf718d05 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_black.png differ diff --git a/textures/mcl_colorblocks_concrete_powder_blue.png b/textures/mcl_colorblocks_concrete_powder_blue.png new file mode 100644 index 000000000..c71038dff Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_blue.png differ diff --git a/textures/mcl_colorblocks_concrete_powder_brown.png b/textures/mcl_colorblocks_concrete_powder_brown.png new file mode 100644 index 000000000..af4f2381f Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_brown.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_cyan.png b/textures/mcl_colorblocks_concrete_powder_cyan.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_cyan.png rename to textures/mcl_colorblocks_concrete_powder_cyan.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_green.png b/textures/mcl_colorblocks_concrete_powder_green.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_green.png rename to textures/mcl_colorblocks_concrete_powder_green.png diff --git a/textures/mcl_colorblocks_concrete_powder_grey.png b/textures/mcl_colorblocks_concrete_powder_grey.png new file mode 100644 index 000000000..da8ffb6fc Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_grey.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_light_blue.png b/textures/mcl_colorblocks_concrete_powder_light_blue.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_light_blue.png rename to textures/mcl_colorblocks_concrete_powder_light_blue.png diff --git a/textures/mcl_colorblocks_concrete_powder_lime.png b/textures/mcl_colorblocks_concrete_powder_lime.png new file mode 100644 index 000000000..d1b990295 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_lime.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_magenta.png b/textures/mcl_colorblocks_concrete_powder_magenta.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_magenta.png rename to textures/mcl_colorblocks_concrete_powder_magenta.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_orange.png b/textures/mcl_colorblocks_concrete_powder_orange.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_orange.png rename to textures/mcl_colorblocks_concrete_powder_orange.png diff --git a/textures/mcl_colorblocks_concrete_powder_pink.png b/textures/mcl_colorblocks_concrete_powder_pink.png new file mode 100644 index 000000000..4dd4dc9b2 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_pink.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_purple.png b/textures/mcl_colorblocks_concrete_powder_purple.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_purple.png rename to textures/mcl_colorblocks_concrete_powder_purple.png diff --git a/textures/mcl_colorblocks_concrete_powder_red.png b/textures/mcl_colorblocks_concrete_powder_red.png new file mode 100644 index 000000000..959fb89a0 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_red.png differ diff --git a/textures/mcl_colorblocks_concrete_powder_silver.png b/textures/mcl_colorblocks_concrete_powder_silver.png new file mode 100644 index 000000000..647c9e6d6 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_silver.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_white.png b/textures/mcl_colorblocks_concrete_powder_white.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_powder_white.png rename to textures/mcl_colorblocks_concrete_powder_white.png diff --git a/textures/mcl_colorblocks_concrete_powder_yellow.png b/textures/mcl_colorblocks_concrete_powder_yellow.png new file mode 100644 index 000000000..8e9562ea9 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_powder_yellow.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_purple.png b/textures/mcl_colorblocks_concrete_purple.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_purple.png rename to textures/mcl_colorblocks_concrete_purple.png diff --git a/textures/mcl_colorblocks_concrete_red.png b/textures/mcl_colorblocks_concrete_red.png new file mode 100644 index 000000000..35ab9b5cd Binary files /dev/null and b/textures/mcl_colorblocks_concrete_red.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_silver.png b/textures/mcl_colorblocks_concrete_silver.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_concrete_silver.png rename to textures/mcl_colorblocks_concrete_silver.png diff --git a/textures/mcl_colorblocks_concrete_white.png b/textures/mcl_colorblocks_concrete_white.png new file mode 100644 index 000000000..abb66f20f Binary files /dev/null and b/textures/mcl_colorblocks_concrete_white.png differ diff --git a/textures/mcl_colorblocks_concrete_yellow.png b/textures/mcl_colorblocks_concrete_yellow.png new file mode 100644 index 000000000..eb8d62044 Binary files /dev/null and b/textures/mcl_colorblocks_concrete_yellow.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_black.png b/textures/mcl_colorblocks_glazed_terracotta_black.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_black.png rename to textures/mcl_colorblocks_glazed_terracotta_black.png diff --git a/textures/mcl_colorblocks_glazed_terracotta_blue.png b/textures/mcl_colorblocks_glazed_terracotta_blue.png new file mode 100644 index 000000000..52b66b6db Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_blue.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_brown.png b/textures/mcl_colorblocks_glazed_terracotta_brown.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_brown.png rename to textures/mcl_colorblocks_glazed_terracotta_brown.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_cyan.png b/textures/mcl_colorblocks_glazed_terracotta_cyan.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_cyan.png rename to textures/mcl_colorblocks_glazed_terracotta_cyan.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_green.png b/textures/mcl_colorblocks_glazed_terracotta_green.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_green.png rename to textures/mcl_colorblocks_glazed_terracotta_green.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_grey.png b/textures/mcl_colorblocks_glazed_terracotta_grey.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_grey.png rename to textures/mcl_colorblocks_glazed_terracotta_grey.png diff --git a/textures/mcl_colorblocks_glazed_terracotta_light_blue.png b/textures/mcl_colorblocks_glazed_terracotta_light_blue.png new file mode 100644 index 000000000..079cfdd66 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_light_blue.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_lime.png b/textures/mcl_colorblocks_glazed_terracotta_lime.png new file mode 100644 index 000000000..0cc61b37b Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_lime.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_magenta.png b/textures/mcl_colorblocks_glazed_terracotta_magenta.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_magenta.png rename to textures/mcl_colorblocks_glazed_terracotta_magenta.png diff --git a/textures/mcl_colorblocks_glazed_terracotta_orange.png b/textures/mcl_colorblocks_glazed_terracotta_orange.png new file mode 100644 index 000000000..1892d825f Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_orange.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_pink.png b/textures/mcl_colorblocks_glazed_terracotta_pink.png new file mode 100644 index 000000000..76264befa Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_pink.png differ diff --git a/textures/mcl_colorblocks_glazed_terracotta_purple.png b/textures/mcl_colorblocks_glazed_terracotta_purple.png new file mode 100644 index 000000000..6912cd635 Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_purple.png differ diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_red.png b/textures/mcl_colorblocks_glazed_terracotta_red.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_red.png rename to textures/mcl_colorblocks_glazed_terracotta_red.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_silver.png b/textures/mcl_colorblocks_glazed_terracotta_silver.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_silver.png rename to textures/mcl_colorblocks_glazed_terracotta_silver.png diff --git a/mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_white.png b/textures/mcl_colorblocks_glazed_terracotta_white.png similarity index 100% rename from mods/ITEMS/mcl_colorblocks/textures/mcl_colorblocks_glazed_terracotta_white.png rename to textures/mcl_colorblocks_glazed_terracotta_white.png diff --git a/textures/mcl_colorblocks_glazed_terracotta_yellow.png b/textures/mcl_colorblocks_glazed_terracotta_yellow.png new file mode 100644 index 000000000..db5a3aa9c Binary files /dev/null and b/textures/mcl_colorblocks_glazed_terracotta_yellow.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_comp.png b/textures/mcl_comparators_comp.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_comp.png rename to textures/mcl_comparators_comp.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_comp.png b/textures/mcl_comparators_ends_comp.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_comp.png rename to textures/mcl_comparators_ends_comp.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_off.png b/textures/mcl_comparators_ends_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_off.png rename to textures/mcl_comparators_ends_off.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_on.png b/textures/mcl_comparators_ends_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_on.png rename to textures/mcl_comparators_ends_on.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_sub.png b/textures/mcl_comparators_ends_sub.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_ends_sub.png rename to textures/mcl_comparators_ends_sub.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_item.png b/textures/mcl_comparators_item.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_item.png rename to textures/mcl_comparators_item.png diff --git a/textures/mcl_comparators_off.png b/textures/mcl_comparators_off.png new file mode 100644 index 000000000..09689e96c Binary files /dev/null and b/textures/mcl_comparators_off.png differ diff --git a/textures/mcl_comparators_on.png b/textures/mcl_comparators_on.png new file mode 100644 index 000000000..740a16fa3 Binary files /dev/null and b/textures/mcl_comparators_on.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_comp.png b/textures/mcl_comparators_sides_comp.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_comp.png rename to textures/mcl_comparators_sides_comp.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_off.png b/textures/mcl_comparators_sides_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_off.png rename to textures/mcl_comparators_sides_off.png diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_on.png b/textures/mcl_comparators_sides_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sides_on.png rename to textures/mcl_comparators_sides_on.png diff --git a/textures/mcl_comparators_sides_sub.png b/textures/mcl_comparators_sides_sub.png new file mode 100644 index 000000000..56c15cae4 Binary files /dev/null and b/textures/mcl_comparators_sides_sub.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sub.png b/textures/mcl_comparators_sub.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_comparators/textures/mcl_comparators_sub.png rename to textures/mcl_comparators_sub.png diff --git a/textures/mcl_compass_compass_00.png b/textures/mcl_compass_compass_00.png new file mode 100644 index 000000000..9eb285cf8 Binary files /dev/null and b/textures/mcl_compass_compass_00.png differ diff --git a/textures/mcl_compass_compass_01.png b/textures/mcl_compass_compass_01.png new file mode 100644 index 000000000..f45768007 Binary files /dev/null and b/textures/mcl_compass_compass_01.png differ diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_02.png b/textures/mcl_compass_compass_02.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_02.png rename to textures/mcl_compass_compass_02.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_03.png b/textures/mcl_compass_compass_03.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_03.png rename to textures/mcl_compass_compass_03.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_04.png b/textures/mcl_compass_compass_04.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_04.png rename to textures/mcl_compass_compass_04.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_05.png b/textures/mcl_compass_compass_05.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_05.png rename to textures/mcl_compass_compass_05.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_06.png b/textures/mcl_compass_compass_06.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_06.png rename to textures/mcl_compass_compass_06.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_07.png b/textures/mcl_compass_compass_07.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_07.png rename to textures/mcl_compass_compass_07.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_08.png b/textures/mcl_compass_compass_08.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_08.png rename to textures/mcl_compass_compass_08.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_09.png b/textures/mcl_compass_compass_09.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_09.png rename to textures/mcl_compass_compass_09.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_10.png b/textures/mcl_compass_compass_10.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_10.png rename to textures/mcl_compass_compass_10.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_11.png b/textures/mcl_compass_compass_11.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_11.png rename to textures/mcl_compass_compass_11.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_12.png b/textures/mcl_compass_compass_12.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_12.png rename to textures/mcl_compass_compass_12.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_13.png b/textures/mcl_compass_compass_13.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_13.png rename to textures/mcl_compass_compass_13.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_14.png b/textures/mcl_compass_compass_14.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_14.png rename to textures/mcl_compass_compass_14.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_15.png b/textures/mcl_compass_compass_15.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_15.png rename to textures/mcl_compass_compass_15.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_16.png b/textures/mcl_compass_compass_16.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_16.png rename to textures/mcl_compass_compass_16.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_17.png b/textures/mcl_compass_compass_17.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_17.png rename to textures/mcl_compass_compass_17.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_18.png b/textures/mcl_compass_compass_18.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_18.png rename to textures/mcl_compass_compass_18.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_19.png b/textures/mcl_compass_compass_19.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_19.png rename to textures/mcl_compass_compass_19.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_20.png b/textures/mcl_compass_compass_20.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_20.png rename to textures/mcl_compass_compass_20.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_21.png b/textures/mcl_compass_compass_21.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_21.png rename to textures/mcl_compass_compass_21.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_22.png b/textures/mcl_compass_compass_22.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_22.png rename to textures/mcl_compass_compass_22.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_23.png b/textures/mcl_compass_compass_23.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_23.png rename to textures/mcl_compass_compass_23.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_24.png b/textures/mcl_compass_compass_24.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_24.png rename to textures/mcl_compass_compass_24.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_25.png b/textures/mcl_compass_compass_25.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_25.png rename to textures/mcl_compass_compass_25.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_26.png b/textures/mcl_compass_compass_26.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_26.png rename to textures/mcl_compass_compass_26.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_27.png b/textures/mcl_compass_compass_27.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_27.png rename to textures/mcl_compass_compass_27.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_28.png b/textures/mcl_compass_compass_28.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_28.png rename to textures/mcl_compass_compass_28.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_29.png b/textures/mcl_compass_compass_29.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_29.png rename to textures/mcl_compass_compass_29.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_30.png b/textures/mcl_compass_compass_30.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_30.png rename to textures/mcl_compass_compass_30.png diff --git a/mods/ITEMS/mcl_compass/textures/mcl_compass_compass_31.png b/textures/mcl_compass_compass_31.png similarity index 100% rename from mods/ITEMS/mcl_compass/textures/mcl_compass_compass_31.png rename to textures/mcl_compass_compass_31.png diff --git a/textures/mcl_compass_recovery_compass_00.png b/textures/mcl_compass_recovery_compass_00.png new file mode 100644 index 000000000..9dda90628 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_00.png differ diff --git a/textures/mcl_compass_recovery_compass_01.png b/textures/mcl_compass_recovery_compass_01.png new file mode 100644 index 000000000..ba039cef7 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_01.png differ diff --git a/textures/mcl_compass_recovery_compass_02.png b/textures/mcl_compass_recovery_compass_02.png new file mode 100644 index 000000000..08a4d4e92 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_02.png differ diff --git a/textures/mcl_compass_recovery_compass_03.png b/textures/mcl_compass_recovery_compass_03.png new file mode 100644 index 000000000..a96319988 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_03.png differ diff --git a/textures/mcl_compass_recovery_compass_04.png b/textures/mcl_compass_recovery_compass_04.png new file mode 100644 index 000000000..bb6bfa790 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_04.png differ diff --git a/textures/mcl_compass_recovery_compass_05.png b/textures/mcl_compass_recovery_compass_05.png new file mode 100644 index 000000000..a8f949154 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_05.png differ diff --git a/textures/mcl_compass_recovery_compass_06.png b/textures/mcl_compass_recovery_compass_06.png new file mode 100644 index 000000000..0c1789c3e Binary files /dev/null and b/textures/mcl_compass_recovery_compass_06.png differ diff --git a/textures/mcl_compass_recovery_compass_07.png b/textures/mcl_compass_recovery_compass_07.png new file mode 100644 index 000000000..c381d11a1 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_07.png differ diff --git a/textures/mcl_compass_recovery_compass_08.png b/textures/mcl_compass_recovery_compass_08.png new file mode 100644 index 000000000..c381d11a1 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_08.png differ diff --git a/textures/mcl_compass_recovery_compass_09.png b/textures/mcl_compass_recovery_compass_09.png new file mode 100644 index 000000000..c381d11a1 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_09.png differ diff --git a/textures/mcl_compass_recovery_compass_10.png b/textures/mcl_compass_recovery_compass_10.png new file mode 100644 index 000000000..effff9282 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_10.png differ diff --git a/textures/mcl_compass_recovery_compass_11.png b/textures/mcl_compass_recovery_compass_11.png new file mode 100644 index 000000000..a36646f1d Binary files /dev/null and b/textures/mcl_compass_recovery_compass_11.png differ diff --git a/textures/mcl_compass_recovery_compass_12.png b/textures/mcl_compass_recovery_compass_12.png new file mode 100644 index 000000000..dedc71610 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_12.png differ diff --git a/textures/mcl_compass_recovery_compass_13.png b/textures/mcl_compass_recovery_compass_13.png new file mode 100644 index 000000000..148ae68c3 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_13.png differ diff --git a/textures/mcl_compass_recovery_compass_14.png b/textures/mcl_compass_recovery_compass_14.png new file mode 100644 index 000000000..b461e4776 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_14.png differ diff --git a/textures/mcl_compass_recovery_compass_15.png b/textures/mcl_compass_recovery_compass_15.png new file mode 100644 index 000000000..bcb44e6c6 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_15.png differ diff --git a/textures/mcl_compass_recovery_compass_16.png b/textures/mcl_compass_recovery_compass_16.png new file mode 100644 index 000000000..bf3645cc6 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_16.png differ diff --git a/textures/mcl_compass_recovery_compass_17.png b/textures/mcl_compass_recovery_compass_17.png new file mode 100644 index 000000000..df432e124 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_17.png differ diff --git a/textures/mcl_compass_recovery_compass_18.png b/textures/mcl_compass_recovery_compass_18.png new file mode 100644 index 000000000..50444fdf0 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_18.png differ diff --git a/textures/mcl_compass_recovery_compass_19.png b/textures/mcl_compass_recovery_compass_19.png new file mode 100644 index 000000000..6bdd24461 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_19.png differ diff --git a/textures/mcl_compass_recovery_compass_20.png b/textures/mcl_compass_recovery_compass_20.png new file mode 100644 index 000000000..c2c2361d6 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_20.png differ diff --git a/textures/mcl_compass_recovery_compass_21.png b/textures/mcl_compass_recovery_compass_21.png new file mode 100644 index 000000000..1d5639777 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_21.png differ diff --git a/textures/mcl_compass_recovery_compass_22.png b/textures/mcl_compass_recovery_compass_22.png new file mode 100644 index 000000000..e5e7631fe Binary files /dev/null and b/textures/mcl_compass_recovery_compass_22.png differ diff --git a/textures/mcl_compass_recovery_compass_23.png b/textures/mcl_compass_recovery_compass_23.png new file mode 100644 index 000000000..6f0f59d27 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_23.png differ diff --git a/textures/mcl_compass_recovery_compass_24.png b/textures/mcl_compass_recovery_compass_24.png new file mode 100644 index 000000000..6f0f59d27 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_24.png differ diff --git a/textures/mcl_compass_recovery_compass_25.png b/textures/mcl_compass_recovery_compass_25.png new file mode 100644 index 000000000..6f0f59d27 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_25.png differ diff --git a/textures/mcl_compass_recovery_compass_26.png b/textures/mcl_compass_recovery_compass_26.png new file mode 100644 index 000000000..643101d73 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_26.png differ diff --git a/textures/mcl_compass_recovery_compass_27.png b/textures/mcl_compass_recovery_compass_27.png new file mode 100644 index 000000000..6e68a4b0c Binary files /dev/null and b/textures/mcl_compass_recovery_compass_27.png differ diff --git a/textures/mcl_compass_recovery_compass_28.png b/textures/mcl_compass_recovery_compass_28.png new file mode 100644 index 000000000..7949fcfc4 Binary files /dev/null and b/textures/mcl_compass_recovery_compass_28.png differ diff --git a/textures/mcl_compass_recovery_compass_29.png b/textures/mcl_compass_recovery_compass_29.png new file mode 100644 index 000000000..816aa18cd Binary files /dev/null and b/textures/mcl_compass_recovery_compass_29.png differ diff --git a/textures/mcl_compass_recovery_compass_30.png b/textures/mcl_compass_recovery_compass_30.png new file mode 100644 index 000000000..d90e6e4ce Binary files /dev/null and b/textures/mcl_compass_recovery_compass_30.png differ diff --git a/textures/mcl_compass_recovery_compass_31.png b/textures/mcl_compass_recovery_compass_31.png new file mode 100644 index 000000000..9fb2647ab Binary files /dev/null and b/textures/mcl_compass_recovery_compass_31.png differ diff --git a/textures/mcl_composter_bottom.png b/textures/mcl_composter_bottom.png new file mode 100644 index 000000000..cfed3a8a5 Binary files /dev/null and b/textures/mcl_composter_bottom.png differ diff --git a/textures/mcl_composter_compost.png b/textures/mcl_composter_compost.png new file mode 100644 index 000000000..40e7bb423 Binary files /dev/null and b/textures/mcl_composter_compost.png differ diff --git a/textures/mcl_composter_ready.png b/textures/mcl_composter_ready.png new file mode 100644 index 000000000..7caf79f96 Binary files /dev/null and b/textures/mcl_composter_ready.png differ diff --git a/textures/mcl_composter_side.png b/textures/mcl_composter_side.png new file mode 100644 index 000000000..c9e5a6fe3 Binary files /dev/null and b/textures/mcl_composter_side.png differ diff --git a/textures/mcl_composter_top.png b/textures/mcl_composter_top.png new file mode 100644 index 000000000..fc6e202d3 Binary files /dev/null and b/textures/mcl_composter_top.png differ diff --git a/textures/mcl_copper_anti_oxidation_particle.png b/textures/mcl_copper_anti_oxidation_particle.png new file mode 100644 index 000000000..3d918b0f8 Binary files /dev/null and b/textures/mcl_copper_anti_oxidation_particle.png differ diff --git a/textures/mcl_copper_block.png b/textures/mcl_copper_block.png new file mode 100644 index 000000000..ae4a33163 Binary files /dev/null and b/textures/mcl_copper_block.png differ diff --git a/textures/mcl_copper_block_cut.png b/textures/mcl_copper_block_cut.png new file mode 100644 index 000000000..c591322b2 Binary files /dev/null and b/textures/mcl_copper_block_cut.png differ diff --git a/textures/mcl_copper_block_raw.png b/textures/mcl_copper_block_raw.png new file mode 100644 index 000000000..9ca04bd81 Binary files /dev/null and b/textures/mcl_copper_block_raw.png differ diff --git a/textures/mcl_copper_exposed.png b/textures/mcl_copper_exposed.png new file mode 100644 index 000000000..46195b50c Binary files /dev/null and b/textures/mcl_copper_exposed.png differ diff --git a/textures/mcl_copper_exposed_cut.png b/textures/mcl_copper_exposed_cut.png new file mode 100644 index 000000000..728928222 Binary files /dev/null and b/textures/mcl_copper_exposed_cut.png differ diff --git a/textures/mcl_copper_ingot.png b/textures/mcl_copper_ingot.png new file mode 100644 index 000000000..ebd6a71c0 Binary files /dev/null and b/textures/mcl_copper_ingot.png differ diff --git a/textures/mcl_copper_ore.png b/textures/mcl_copper_ore.png new file mode 100644 index 000000000..2588566e9 Binary files /dev/null and b/textures/mcl_copper_ore.png differ diff --git a/textures/mcl_copper_oxidized.png b/textures/mcl_copper_oxidized.png new file mode 100644 index 000000000..900ebd181 Binary files /dev/null and b/textures/mcl_copper_oxidized.png differ diff --git a/textures/mcl_copper_oxidized_cut.png b/textures/mcl_copper_oxidized_cut.png new file mode 100644 index 000000000..5e04fce22 Binary files /dev/null and b/textures/mcl_copper_oxidized_cut.png differ diff --git a/textures/mcl_copper_raw.png b/textures/mcl_copper_raw.png new file mode 100644 index 000000000..107d00419 Binary files /dev/null and b/textures/mcl_copper_raw.png differ diff --git a/textures/mcl_copper_weathered.png b/textures/mcl_copper_weathered.png new file mode 100644 index 000000000..c459d0382 Binary files /dev/null and b/textures/mcl_copper_weathered.png differ diff --git a/textures/mcl_copper_weathered_cut.png b/textures/mcl_copper_weathered_cut.png new file mode 100644 index 000000000..8cf8ad78d Binary files /dev/null and b/textures/mcl_copper_weathered_cut.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_andesite.png b/textures/mcl_core_andesite.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_andesite.png rename to textures/mcl_core_andesite.png diff --git a/textures/mcl_core_andesite_smooth.png b/textures/mcl_core_andesite_smooth.png new file mode 100644 index 000000000..ff6915ff0 Binary files /dev/null and b/textures/mcl_core_andesite_smooth.png differ diff --git a/textures/mcl_core_apple_golden.png b/textures/mcl_core_apple_golden.png new file mode 100644 index 000000000..cfaacb02a Binary files /dev/null and b/textures/mcl_core_apple_golden.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_barrier.png b/textures/mcl_core_barrier.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_barrier.png rename to textures/mcl_core_barrier.png diff --git a/textures/mcl_core_bedrock.png b/textures/mcl_core_bedrock.png new file mode 100644 index 000000000..baed9bb5c Binary files /dev/null and b/textures/mcl_core_bedrock.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_bone_block_side.png b/textures/mcl_core_bone_block_side.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_bone_block_side.png rename to textures/mcl_core_bone_block_side.png diff --git a/textures/mcl_core_bone_block_top.png b/textures/mcl_core_bone_block_top.png new file mode 100644 index 000000000..7faf7b106 Binary files /dev/null and b/textures/mcl_core_bone_block_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_bowl.png b/textures/mcl_core_bowl.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_bowl.png rename to textures/mcl_core_bowl.png diff --git a/textures/mcl_core_cactus_bottom.png b/textures/mcl_core_cactus_bottom.png new file mode 100644 index 000000000..27dd14878 Binary files /dev/null and b/textures/mcl_core_cactus_bottom.png differ diff --git a/textures/mcl_core_cactus_side.png b/textures/mcl_core_cactus_side.png new file mode 100644 index 000000000..04ddc256a Binary files /dev/null and b/textures/mcl_core_cactus_side.png differ diff --git a/textures/mcl_core_cactus_top.png b/textures/mcl_core_cactus_top.png new file mode 100644 index 000000000..ddae5176b Binary files /dev/null and b/textures/mcl_core_cactus_top.png differ diff --git a/textures/mcl_core_charcoal.png b/textures/mcl_core_charcoal.png new file mode 100644 index 000000000..691a02bf8 Binary files /dev/null and b/textures/mcl_core_charcoal.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_coal_ore.png b/textures/mcl_core_coal_ore.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_coal_ore.png rename to textures/mcl_core_coal_ore.png diff --git a/textures/mcl_core_coarse_dirt.png b/textures/mcl_core_coarse_dirt.png new file mode 100644 index 000000000..5464763bb Binary files /dev/null and b/textures/mcl_core_coarse_dirt.png differ diff --git a/textures/mcl_core_crying_obsidian.png b/textures/mcl_core_crying_obsidian.png new file mode 100644 index 000000000..96b230a4d Binary files /dev/null and b/textures/mcl_core_crying_obsidian.png differ diff --git a/textures/mcl_core_crying_obsidian_tear.png b/textures/mcl_core_crying_obsidian_tear.png new file mode 100644 index 000000000..bd2c94ed3 Binary files /dev/null and b/textures/mcl_core_crying_obsidian_tear.png differ diff --git a/textures/mcl_core_crying_obsidian_tear2.png b/textures/mcl_core_crying_obsidian_tear2.png new file mode 100644 index 000000000..e0174d8e8 Binary files /dev/null and b/textures/mcl_core_crying_obsidian_tear2.png differ diff --git a/textures/mcl_core_crying_obsidian_tear3.png b/textures/mcl_core_crying_obsidian_tear3.png new file mode 100644 index 000000000..d75ffe2a5 Binary files /dev/null and b/textures/mcl_core_crying_obsidian_tear3.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_diamond_ore.png b/textures/mcl_core_diamond_ore.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_diamond_ore.png rename to textures/mcl_core_diamond_ore.png diff --git a/textures/mcl_core_diorite.png b/textures/mcl_core_diorite.png new file mode 100644 index 000000000..554299612 Binary files /dev/null and b/textures/mcl_core_diorite.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_diorite_smooth.png b/textures/mcl_core_diorite_smooth.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_diorite_smooth.png rename to textures/mcl_core_diorite_smooth.png diff --git a/textures/mcl_core_dirt_podzol_side.png b/textures/mcl_core_dirt_podzol_side.png new file mode 100644 index 000000000..f129d84b2 Binary files /dev/null and b/textures/mcl_core_dirt_podzol_side.png differ diff --git a/textures/mcl_core_dirt_podzol_top.png b/textures/mcl_core_dirt_podzol_top.png new file mode 100644 index 000000000..56fd114f0 Binary files /dev/null and b/textures/mcl_core_dirt_podzol_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_emerald.png b/textures/mcl_core_emerald.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_emerald.png rename to textures/mcl_core_emerald.png diff --git a/textures/mcl_core_emerald_block.png b/textures/mcl_core_emerald_block.png new file mode 100644 index 000000000..773c99cba Binary files /dev/null and b/textures/mcl_core_emerald_block.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_emerald_ore.png b/textures/mcl_core_emerald_ore.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_emerald_ore.png rename to textures/mcl_core_emerald_ore.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_0.png b/textures/mcl_core_frosted_ice_0.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_frosted_ice_0.png rename to textures/mcl_core_frosted_ice_0.png diff --git a/textures/mcl_core_frosted_ice_1.png b/textures/mcl_core_frosted_ice_1.png new file mode 100644 index 000000000..5a7dcaa92 Binary files /dev/null and b/textures/mcl_core_frosted_ice_1.png differ diff --git a/textures/mcl_core_frosted_ice_2.png b/textures/mcl_core_frosted_ice_2.png new file mode 100644 index 000000000..98cfa0a7e Binary files /dev/null and b/textures/mcl_core_frosted_ice_2.png differ diff --git a/textures/mcl_core_frosted_ice_3.png b/textures/mcl_core_frosted_ice_3.png new file mode 100644 index 000000000..d50bc63d5 Binary files /dev/null and b/textures/mcl_core_frosted_ice_3.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_black.png b/textures/mcl_core_glass_black.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_black.png rename to textures/mcl_core_glass_black.png diff --git a/textures/mcl_core_glass_black_detail.png b/textures/mcl_core_glass_black_detail.png new file mode 100644 index 000000000..9dac71149 Binary files /dev/null and b/textures/mcl_core_glass_black_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_blue.png b/textures/mcl_core_glass_blue.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_blue.png rename to textures/mcl_core_glass_blue.png diff --git a/textures/mcl_core_glass_blue_detail.png b/textures/mcl_core_glass_blue_detail.png new file mode 100644 index 000000000..13d0e83b2 Binary files /dev/null and b/textures/mcl_core_glass_blue_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_brown.png b/textures/mcl_core_glass_brown.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_brown.png rename to textures/mcl_core_glass_brown.png diff --git a/textures/mcl_core_glass_brown_detail.png b/textures/mcl_core_glass_brown_detail.png new file mode 100644 index 000000000..d342045b1 Binary files /dev/null and b/textures/mcl_core_glass_brown_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_cyan.png b/textures/mcl_core_glass_cyan.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_cyan.png rename to textures/mcl_core_glass_cyan.png diff --git a/textures/mcl_core_glass_cyan_detail.png b/textures/mcl_core_glass_cyan_detail.png new file mode 100644 index 000000000..6b907f54d Binary files /dev/null and b/textures/mcl_core_glass_cyan_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_gray.png b/textures/mcl_core_glass_gray.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_gray.png rename to textures/mcl_core_glass_gray.png diff --git a/textures/mcl_core_glass_gray_detail.png b/textures/mcl_core_glass_gray_detail.png new file mode 100644 index 000000000..4dbc15680 Binary files /dev/null and b/textures/mcl_core_glass_gray_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_green.png b/textures/mcl_core_glass_green.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_green.png rename to textures/mcl_core_glass_green.png diff --git a/textures/mcl_core_glass_green_detail.png b/textures/mcl_core_glass_green_detail.png new file mode 100644 index 000000000..03b9943f1 Binary files /dev/null and b/textures/mcl_core_glass_green_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_light_blue.png b/textures/mcl_core_glass_light_blue.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_light_blue.png rename to textures/mcl_core_glass_light_blue.png diff --git a/textures/mcl_core_glass_light_blue_detail.png b/textures/mcl_core_glass_light_blue_detail.png new file mode 100644 index 000000000..842441a2c Binary files /dev/null and b/textures/mcl_core_glass_light_blue_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_lime.png b/textures/mcl_core_glass_lime.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_lime.png rename to textures/mcl_core_glass_lime.png diff --git a/textures/mcl_core_glass_lime_detail.png b/textures/mcl_core_glass_lime_detail.png new file mode 100644 index 000000000..8b80407d3 Binary files /dev/null and b/textures/mcl_core_glass_lime_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_magenta.png b/textures/mcl_core_glass_magenta.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_magenta.png rename to textures/mcl_core_glass_magenta.png diff --git a/textures/mcl_core_glass_magenta_detail.png b/textures/mcl_core_glass_magenta_detail.png new file mode 100644 index 000000000..cd2d23458 Binary files /dev/null and b/textures/mcl_core_glass_magenta_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_orange.png b/textures/mcl_core_glass_orange.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_orange.png rename to textures/mcl_core_glass_orange.png diff --git a/textures/mcl_core_glass_orange_detail.png b/textures/mcl_core_glass_orange_detail.png new file mode 100644 index 000000000..930992769 Binary files /dev/null and b/textures/mcl_core_glass_orange_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_pink.png b/textures/mcl_core_glass_pink.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_pink.png rename to textures/mcl_core_glass_pink.png diff --git a/textures/mcl_core_glass_pink_detail.png b/textures/mcl_core_glass_pink_detail.png new file mode 100644 index 000000000..d06f90f6b Binary files /dev/null and b/textures/mcl_core_glass_pink_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_purple.png b/textures/mcl_core_glass_purple.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_purple.png rename to textures/mcl_core_glass_purple.png diff --git a/textures/mcl_core_glass_purple_detail.png b/textures/mcl_core_glass_purple_detail.png new file mode 100644 index 000000000..a5685731f Binary files /dev/null and b/textures/mcl_core_glass_purple_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_red.png b/textures/mcl_core_glass_red.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_red.png rename to textures/mcl_core_glass_red.png diff --git a/textures/mcl_core_glass_red_detail.png b/textures/mcl_core_glass_red_detail.png new file mode 100644 index 000000000..587fbdbdd Binary files /dev/null and b/textures/mcl_core_glass_red_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_silver.png b/textures/mcl_core_glass_silver.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_silver.png rename to textures/mcl_core_glass_silver.png diff --git a/textures/mcl_core_glass_silver_detail.png b/textures/mcl_core_glass_silver_detail.png new file mode 100644 index 000000000..49d444b80 Binary files /dev/null and b/textures/mcl_core_glass_silver_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_white.png b/textures/mcl_core_glass_white.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_white.png rename to textures/mcl_core_glass_white.png diff --git a/textures/mcl_core_glass_white_detail.png b/textures/mcl_core_glass_white_detail.png new file mode 100644 index 000000000..e7e0db92d Binary files /dev/null and b/textures/mcl_core_glass_white_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_glass_yellow.png b/textures/mcl_core_glass_yellow.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_glass_yellow.png rename to textures/mcl_core_glass_yellow.png diff --git a/textures/mcl_core_glass_yellow_detail.png b/textures/mcl_core_glass_yellow_detail.png new file mode 100644 index 000000000..b3fc7c893 Binary files /dev/null and b/textures/mcl_core_glass_yellow_detail.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_gold_nugget.png b/textures/mcl_core_gold_nugget.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_gold_nugget.png rename to textures/mcl_core_gold_nugget.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_gold_ore.png b/textures/mcl_core_gold_ore.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_gold_ore.png rename to textures/mcl_core_gold_ore.png diff --git a/textures/mcl_core_granite.png b/textures/mcl_core_granite.png new file mode 100644 index 000000000..23c65f368 Binary files /dev/null and b/textures/mcl_core_granite.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_granite_smooth.png b/textures/mcl_core_granite_smooth.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_granite_smooth.png rename to textures/mcl_core_granite_smooth.png diff --git a/textures/mcl_core_grass_block_side_overlay.png b/textures/mcl_core_grass_block_side_overlay.png new file mode 100644 index 000000000..e1aa70bda Binary files /dev/null and b/textures/mcl_core_grass_block_side_overlay.png differ diff --git a/textures/mcl_core_grass_block_top.png b/textures/mcl_core_grass_block_top.png new file mode 100644 index 000000000..26bdfdb70 Binary files /dev/null and b/textures/mcl_core_grass_block_top.png differ diff --git a/textures/mcl_core_grass_path_side.png b/textures/mcl_core_grass_path_side.png new file mode 100644 index 000000000..900d81e80 Binary files /dev/null and b/textures/mcl_core_grass_path_side.png differ diff --git a/textures/mcl_core_grass_path_top.png b/textures/mcl_core_grass_path_top.png new file mode 100644 index 000000000..e4c6dce82 Binary files /dev/null and b/textures/mcl_core_grass_path_top.png differ diff --git a/textures/mcl_core_grass_side_snowed.png b/textures/mcl_core_grass_side_snowed.png new file mode 100644 index 000000000..887d0ba19 Binary files /dev/null and b/textures/mcl_core_grass_side_snowed.png differ diff --git a/textures/mcl_core_ice_packed.png b/textures/mcl_core_ice_packed.png new file mode 100644 index 000000000..7dd7f3981 Binary files /dev/null and b/textures/mcl_core_ice_packed.png differ diff --git a/textures/mcl_core_iron_nugget.png b/textures/mcl_core_iron_nugget.png new file mode 100644 index 000000000..4f78bd0b2 Binary files /dev/null and b/textures/mcl_core_iron_nugget.png differ diff --git a/textures/mcl_core_iron_ore.png b/textures/mcl_core_iron_ore.png new file mode 100644 index 000000000..4a93ed270 Binary files /dev/null and b/textures/mcl_core_iron_ore.png differ diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png b/textures/mcl_core_lapis.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_blue.png rename to textures/mcl_core_lapis.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_lapis_block.png b/textures/mcl_core_lapis_block.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_lapis_block.png rename to textures/mcl_core_lapis_block.png diff --git a/textures/mcl_core_lapis_ore.png b/textures/mcl_core_lapis_ore.png new file mode 100644 index 000000000..8ed68dbfa Binary files /dev/null and b/textures/mcl_core_lapis_ore.png differ diff --git a/textures/mcl_core_leaves_big_oak.png b/textures/mcl_core_leaves_big_oak.png new file mode 100644 index 000000000..9c989aad4 Binary files /dev/null and b/textures/mcl_core_leaves_big_oak.png differ diff --git a/textures/mcl_core_leaves_birch.png b/textures/mcl_core_leaves_birch.png new file mode 100644 index 000000000..9fed93ef3 Binary files /dev/null and b/textures/mcl_core_leaves_birch.png differ diff --git a/textures/mcl_core_leaves_spruce.png b/textures/mcl_core_leaves_spruce.png new file mode 100644 index 000000000..bd614b7b1 Binary files /dev/null and b/textures/mcl_core_leaves_spruce.png differ diff --git a/textures/mcl_core_light_0.png b/textures/mcl_core_light_0.png new file mode 100644 index 000000000..e8d2d093b Binary files /dev/null and b/textures/mcl_core_light_0.png differ diff --git a/textures/mcl_core_light_1.png b/textures/mcl_core_light_1.png new file mode 100644 index 000000000..5ec1c11b4 Binary files /dev/null and b/textures/mcl_core_light_1.png differ diff --git a/textures/mcl_core_light_10.png b/textures/mcl_core_light_10.png new file mode 100644 index 000000000..bdea1d56c Binary files /dev/null and b/textures/mcl_core_light_10.png differ diff --git a/textures/mcl_core_light_11.png b/textures/mcl_core_light_11.png new file mode 100644 index 000000000..f5078cda6 Binary files /dev/null and b/textures/mcl_core_light_11.png differ diff --git a/textures/mcl_core_light_12.png b/textures/mcl_core_light_12.png new file mode 100644 index 000000000..4883ec2f6 Binary files /dev/null and b/textures/mcl_core_light_12.png differ diff --git a/textures/mcl_core_light_13.png b/textures/mcl_core_light_13.png new file mode 100644 index 000000000..df2f0330e Binary files /dev/null and b/textures/mcl_core_light_13.png differ diff --git a/textures/mcl_core_light_14.png b/textures/mcl_core_light_14.png new file mode 100644 index 000000000..1b58a8bc4 Binary files /dev/null and b/textures/mcl_core_light_14.png differ diff --git a/textures/mcl_core_light_2.png b/textures/mcl_core_light_2.png new file mode 100644 index 000000000..00451d9c6 Binary files /dev/null and b/textures/mcl_core_light_2.png differ diff --git a/textures/mcl_core_light_3.png b/textures/mcl_core_light_3.png new file mode 100644 index 000000000..4e178f3e8 Binary files /dev/null and b/textures/mcl_core_light_3.png differ diff --git a/textures/mcl_core_light_4.png b/textures/mcl_core_light_4.png new file mode 100644 index 000000000..23047affe Binary files /dev/null and b/textures/mcl_core_light_4.png differ diff --git a/textures/mcl_core_light_5.png b/textures/mcl_core_light_5.png new file mode 100644 index 000000000..a1c8c9a2f Binary files /dev/null and b/textures/mcl_core_light_5.png differ diff --git a/textures/mcl_core_light_6.png b/textures/mcl_core_light_6.png new file mode 100644 index 000000000..2ef86b8f5 Binary files /dev/null and b/textures/mcl_core_light_6.png differ diff --git a/textures/mcl_core_light_7.png b/textures/mcl_core_light_7.png new file mode 100644 index 000000000..2adfc2729 Binary files /dev/null and b/textures/mcl_core_light_7.png differ diff --git a/textures/mcl_core_light_8.png b/textures/mcl_core_light_8.png new file mode 100644 index 000000000..bf11f8384 Binary files /dev/null and b/textures/mcl_core_light_8.png differ diff --git a/textures/mcl_core_light_9.png b/textures/mcl_core_light_9.png new file mode 100644 index 000000000..12c4ee769 Binary files /dev/null and b/textures/mcl_core_light_9.png differ diff --git a/textures/mcl_core_log_big_oak.png b/textures/mcl_core_log_big_oak.png new file mode 100644 index 000000000..978ccf561 Binary files /dev/null and b/textures/mcl_core_log_big_oak.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_big_oak_top.png b/textures/mcl_core_log_big_oak_top.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_log_big_oak_top.png rename to textures/mcl_core_log_big_oak_top.png diff --git a/textures/mcl_core_log_birch.png b/textures/mcl_core_log_birch.png new file mode 100644 index 000000000..0261fd1f3 Binary files /dev/null and b/textures/mcl_core_log_birch.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_birch_top.png b/textures/mcl_core_log_birch_top.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_log_birch_top.png rename to textures/mcl_core_log_birch_top.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_spruce.png b/textures/mcl_core_log_spruce.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_log_spruce.png rename to textures/mcl_core_log_spruce.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_log_spruce_top.png b/textures/mcl_core_log_spruce_top.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_log_spruce_top.png rename to textures/mcl_core_log_spruce_top.png diff --git a/textures/mcl_core_mycelium_particle.png b/textures/mcl_core_mycelium_particle.png new file mode 100644 index 000000000..5494d9cc5 Binary files /dev/null and b/textures/mcl_core_mycelium_particle.png differ diff --git a/textures/mcl_core_mycelium_side.png b/textures/mcl_core_mycelium_side.png new file mode 100644 index 000000000..cab054adb Binary files /dev/null and b/textures/mcl_core_mycelium_side.png differ diff --git a/textures/mcl_core_mycelium_top.png b/textures/mcl_core_mycelium_top.png new file mode 100644 index 000000000..ed02e33b3 Binary files /dev/null and b/textures/mcl_core_mycelium_top.png differ diff --git a/textures/mcl_core_palette_foliage.png b/textures/mcl_core_palette_foliage.png new file mode 100644 index 000000000..5e41a7f34 Binary files /dev/null and b/textures/mcl_core_palette_foliage.png differ diff --git a/textures/mcl_core_palette_grass.png b/textures/mcl_core_palette_grass.png new file mode 100644 index 000000000..8bc4828ef Binary files /dev/null and b/textures/mcl_core_palette_grass.png differ diff --git a/textures/mcl_core_palette_water.png b/textures/mcl_core_palette_water.png new file mode 100644 index 000000000..c5ec09117 Binary files /dev/null and b/textures/mcl_core_palette_water.png differ diff --git a/textures/mcl_core_palette_water_alt.png b/textures/mcl_core_palette_water_alt.png new file mode 100644 index 000000000..91abb00d5 Binary files /dev/null and b/textures/mcl_core_palette_water_alt.png differ diff --git a/textures/mcl_core_papyrus.png b/textures/mcl_core_papyrus.png new file mode 100644 index 000000000..ca1850eaf Binary files /dev/null and b/textures/mcl_core_papyrus.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_planks_big_oak.png b/textures/mcl_core_planks_big_oak.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_planks_big_oak.png rename to textures/mcl_core_planks_big_oak.png diff --git a/textures/mcl_core_planks_birch.png b/textures/mcl_core_planks_birch.png new file mode 100644 index 000000000..840c2c6c9 Binary files /dev/null and b/textures/mcl_core_planks_birch.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_planks_spruce.png b/textures/mcl_core_planks_spruce.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_planks_spruce.png rename to textures/mcl_core_planks_spruce.png diff --git a/textures/mcl_core_red_sand.png b/textures/mcl_core_red_sand.png new file mode 100644 index 000000000..b8e8a7653 Binary files /dev/null and b/textures/mcl_core_red_sand.png differ diff --git a/textures/mcl_core_red_sandstone_bottom.png b/textures/mcl_core_red_sandstone_bottom.png new file mode 100644 index 000000000..d7e0e2922 Binary files /dev/null and b/textures/mcl_core_red_sandstone_bottom.png differ diff --git a/textures/mcl_core_red_sandstone_carved.png b/textures/mcl_core_red_sandstone_carved.png new file mode 100644 index 000000000..ef65c4af0 Binary files /dev/null and b/textures/mcl_core_red_sandstone_carved.png differ diff --git a/textures/mcl_core_red_sandstone_normal.png b/textures/mcl_core_red_sandstone_normal.png new file mode 100644 index 000000000..20be1dbc5 Binary files /dev/null and b/textures/mcl_core_red_sandstone_normal.png differ diff --git a/textures/mcl_core_red_sandstone_smooth.png b/textures/mcl_core_red_sandstone_smooth.png new file mode 100644 index 000000000..d7e0e2922 Binary files /dev/null and b/textures/mcl_core_red_sandstone_smooth.png differ diff --git a/textures/mcl_core_red_sandstone_top.png b/textures/mcl_core_red_sandstone_top.png new file mode 100644 index 000000000..42412eb8f Binary files /dev/null and b/textures/mcl_core_red_sandstone_top.png differ diff --git a/textures/mcl_core_redstone_ore.png b/textures/mcl_core_redstone_ore.png new file mode 100644 index 000000000..5d051bb57 Binary files /dev/null and b/textures/mcl_core_redstone_ore.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_reeds.png b/textures/mcl_core_reeds.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_reeds.png rename to textures/mcl_core_reeds.png diff --git a/textures/mcl_core_sandstone_bottom.png b/textures/mcl_core_sandstone_bottom.png new file mode 100644 index 000000000..4699e1e3e Binary files /dev/null and b/textures/mcl_core_sandstone_bottom.png differ diff --git a/textures/mcl_core_sandstone_carved.png b/textures/mcl_core_sandstone_carved.png new file mode 100644 index 000000000..6c51a27f4 Binary files /dev/null and b/textures/mcl_core_sandstone_carved.png differ diff --git a/textures/mcl_core_sandstone_normal.png b/textures/mcl_core_sandstone_normal.png new file mode 100644 index 000000000..f32bd274e Binary files /dev/null and b/textures/mcl_core_sandstone_normal.png differ diff --git a/textures/mcl_core_sandstone_smooth.png b/textures/mcl_core_sandstone_smooth.png new file mode 100644 index 000000000..4699e1e3e Binary files /dev/null and b/textures/mcl_core_sandstone_smooth.png differ diff --git a/textures/mcl_core_sandstone_top.png b/textures/mcl_core_sandstone_top.png new file mode 100644 index 000000000..36c292a8b Binary files /dev/null and b/textures/mcl_core_sandstone_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sapling_big_oak.png b/textures/mcl_core_sapling_big_oak.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_sapling_big_oak.png rename to textures/mcl_core_sapling_big_oak.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sapling_birch.png b/textures/mcl_core_sapling_birch.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_sapling_birch.png rename to textures/mcl_core_sapling_birch.png diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sapling_spruce.png b/textures/mcl_core_sapling_spruce.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_sapling_spruce.png rename to textures/mcl_core_sapling_spruce.png diff --git a/textures/mcl_core_slime.png b/textures/mcl_core_slime.png new file mode 100644 index 000000000..b43f9c20a Binary files /dev/null and b/textures/mcl_core_slime.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_carved.png b/textures/mcl_core_stonebrick_carved.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_carved.png rename to textures/mcl_core_stonebrick_carved.png diff --git a/textures/mcl_core_stonebrick_cracked.png b/textures/mcl_core_stonebrick_cracked.png new file mode 100644 index 000000000..b340de08f Binary files /dev/null and b/textures/mcl_core_stonebrick_cracked.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_mossy.png b/textures/mcl_core_stonebrick_mossy.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_stonebrick_mossy.png rename to textures/mcl_core_stonebrick_mossy.png diff --git a/textures/mcl_core_stripped_acacia_side.png b/textures/mcl_core_stripped_acacia_side.png new file mode 100644 index 000000000..2ba79863d Binary files /dev/null and b/textures/mcl_core_stripped_acacia_side.png differ diff --git a/textures/mcl_core_stripped_acacia_top.png b/textures/mcl_core_stripped_acacia_top.png new file mode 100644 index 000000000..9dd1f2c97 Binary files /dev/null and b/textures/mcl_core_stripped_acacia_top.png differ diff --git a/textures/mcl_core_stripped_birch_side.png b/textures/mcl_core_stripped_birch_side.png new file mode 100644 index 000000000..7b8288bb2 Binary files /dev/null and b/textures/mcl_core_stripped_birch_side.png differ diff --git a/textures/mcl_core_stripped_birch_top.png b/textures/mcl_core_stripped_birch_top.png new file mode 100644 index 000000000..af3e0b639 Binary files /dev/null and b/textures/mcl_core_stripped_birch_top.png differ diff --git a/textures/mcl_core_stripped_dark_oak_side.png b/textures/mcl_core_stripped_dark_oak_side.png new file mode 100644 index 000000000..cd22ee99e Binary files /dev/null and b/textures/mcl_core_stripped_dark_oak_side.png differ diff --git a/textures/mcl_core_stripped_dark_oak_top.png b/textures/mcl_core_stripped_dark_oak_top.png new file mode 100644 index 000000000..0ade88253 Binary files /dev/null and b/textures/mcl_core_stripped_dark_oak_top.png differ diff --git a/textures/mcl_core_stripped_jungle_side.png b/textures/mcl_core_stripped_jungle_side.png new file mode 100644 index 000000000..7d9f58915 Binary files /dev/null and b/textures/mcl_core_stripped_jungle_side.png differ diff --git a/textures/mcl_core_stripped_jungle_top.png b/textures/mcl_core_stripped_jungle_top.png new file mode 100644 index 000000000..21aa8dfee Binary files /dev/null and b/textures/mcl_core_stripped_jungle_top.png differ diff --git a/textures/mcl_core_stripped_oak_side.png b/textures/mcl_core_stripped_oak_side.png new file mode 100644 index 000000000..88666bafd Binary files /dev/null and b/textures/mcl_core_stripped_oak_side.png differ diff --git a/textures/mcl_core_stripped_oak_top.png b/textures/mcl_core_stripped_oak_top.png new file mode 100644 index 000000000..56ffdb3b2 Binary files /dev/null and b/textures/mcl_core_stripped_oak_top.png differ diff --git a/textures/mcl_core_stripped_spruce_side.png b/textures/mcl_core_stripped_spruce_side.png new file mode 100644 index 000000000..c9acefdf4 Binary files /dev/null and b/textures/mcl_core_stripped_spruce_side.png differ diff --git a/textures/mcl_core_stripped_spruce_top.png b/textures/mcl_core_stripped_spruce_top.png new file mode 100644 index 000000000..db552235a Binary files /dev/null and b/textures/mcl_core_stripped_spruce_top.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_sugar.png b/textures/mcl_core_sugar.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_sugar.png rename to textures/mcl_core_sugar.png diff --git a/textures/mcl_core_vine.png b/textures/mcl_core_vine.png new file mode 100644 index 000000000..47cb195d0 Binary files /dev/null and b/textures/mcl_core_vine.png differ diff --git a/mods/ITEMS/mcl_core/textures/mcl_core_void.png b/textures/mcl_core_void.png similarity index 100% rename from mods/ITEMS/mcl_core/textures/mcl_core_void.png rename to textures/mcl_core_void.png diff --git a/textures/mcl_core_web.png b/textures/mcl_core_web.png new file mode 100644 index 000000000..fc5dd369e Binary files /dev/null and b/textures/mcl_core_web.png differ diff --git a/textures/mcl_cracked_deepslate_bricks.png b/textures/mcl_cracked_deepslate_bricks.png new file mode 100644 index 000000000..f5baf8cff Binary files /dev/null and b/textures/mcl_cracked_deepslate_bricks.png differ diff --git a/textures/mcl_cracked_deepslate_tiles.png b/textures/mcl_cracked_deepslate_tiles.png new file mode 100644 index 000000000..dbe8719cf Binary files /dev/null and b/textures/mcl_cracked_deepslate_tiles.png differ diff --git a/mods/HELP/mcl_craftguide/textures/mcl_craftguide_fuel.png b/textures/mcl_craftguide_fuel.png similarity index 100% rename from mods/HELP/mcl_craftguide/textures/mcl_craftguide_fuel.png rename to textures/mcl_craftguide_fuel.png diff --git a/textures/mcl_crimson_crimson_door.png b/textures/mcl_crimson_crimson_door.png new file mode 100644 index 000000000..52a123d4c Binary files /dev/null and b/textures/mcl_crimson_crimson_door.png differ diff --git a/textures/mcl_crimson_crimson_door_bottom.png b/textures/mcl_crimson_crimson_door_bottom.png new file mode 100644 index 000000000..77da720ff Binary files /dev/null and b/textures/mcl_crimson_crimson_door_bottom.png differ diff --git a/textures/mcl_crimson_crimson_door_bottom_bottompart.png b/textures/mcl_crimson_crimson_door_bottom_bottompart.png new file mode 100644 index 000000000..31a1afe29 Binary files /dev/null and b/textures/mcl_crimson_crimson_door_bottom_bottompart.png differ diff --git a/textures/mcl_crimson_crimson_door_bottom_side.png b/textures/mcl_crimson_crimson_door_bottom_side.png new file mode 100644 index 000000000..934abe3c1 Binary files /dev/null and b/textures/mcl_crimson_crimson_door_bottom_side.png differ diff --git a/textures/mcl_crimson_crimson_door_top.png b/textures/mcl_crimson_crimson_door_top.png new file mode 100644 index 000000000..f6bc75687 Binary files /dev/null and b/textures/mcl_crimson_crimson_door_top.png differ diff --git a/textures/mcl_crimson_crimson_door_top_side.png b/textures/mcl_crimson_crimson_door_top_side.png new file mode 100644 index 000000000..e941e8844 Binary files /dev/null and b/textures/mcl_crimson_crimson_door_top_side.png differ diff --git a/textures/mcl_crimson_crimson_door_top_toppart.png b/textures/mcl_crimson_crimson_door_top_toppart.png new file mode 100644 index 000000000..ac3e1dff4 Binary files /dev/null and b/textures/mcl_crimson_crimson_door_top_toppart.png differ diff --git a/textures/mcl_crimson_crimson_fence.png b/textures/mcl_crimson_crimson_fence.png new file mode 100644 index 000000000..df71d56a9 Binary files /dev/null and b/textures/mcl_crimson_crimson_fence.png differ diff --git a/textures/mcl_crimson_crimson_fence_side.png b/textures/mcl_crimson_crimson_fence_side.png new file mode 100644 index 000000000..4941ce6d4 Binary files /dev/null and b/textures/mcl_crimson_crimson_fence_side.png differ diff --git a/textures/mcl_crimson_crimson_fence_top.png b/textures/mcl_crimson_crimson_fence_top.png new file mode 100644 index 000000000..485633b75 Binary files /dev/null and b/textures/mcl_crimson_crimson_fence_top.png differ diff --git a/textures/mcl_crimson_crimson_fungus.png b/textures/mcl_crimson_crimson_fungus.png new file mode 100644 index 000000000..9c4a48901 Binary files /dev/null and b/textures/mcl_crimson_crimson_fungus.png differ diff --git a/textures/mcl_crimson_crimson_hyphae.png b/textures/mcl_crimson_crimson_hyphae.png new file mode 100644 index 000000000..5df05e3ae Binary files /dev/null and b/textures/mcl_crimson_crimson_hyphae.png differ diff --git a/textures/mcl_crimson_crimson_hyphae_side.png b/textures/mcl_crimson_crimson_hyphae_side.png new file mode 100644 index 000000000..8a6b66f9d Binary files /dev/null and b/textures/mcl_crimson_crimson_hyphae_side.png differ diff --git a/textures/mcl_crimson_crimson_hyphae_wood.png b/textures/mcl_crimson_crimson_hyphae_wood.png new file mode 100644 index 000000000..b2e131031 Binary files /dev/null and b/textures/mcl_crimson_crimson_hyphae_wood.png differ diff --git a/textures/mcl_crimson_crimson_nylium.png b/textures/mcl_crimson_crimson_nylium.png new file mode 100644 index 000000000..faa3ba973 Binary files /dev/null and b/textures/mcl_crimson_crimson_nylium.png differ diff --git a/textures/mcl_crimson_crimson_nylium_side.png b/textures/mcl_crimson_crimson_nylium_side.png new file mode 100644 index 000000000..e4a2ecaa1 Binary files /dev/null and b/textures/mcl_crimson_crimson_nylium_side.png differ diff --git a/textures/mcl_crimson_crimson_roots.png b/textures/mcl_crimson_crimson_roots.png new file mode 100644 index 000000000..19d648058 Binary files /dev/null and b/textures/mcl_crimson_crimson_roots.png differ diff --git a/textures/mcl_crimson_crimson_stem_stripped_side.png b/textures/mcl_crimson_crimson_stem_stripped_side.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/textures/mcl_crimson_crimson_stem_stripped_side.png differ diff --git a/textures/mcl_crimson_crimson_stem_stripped_top.png b/textures/mcl_crimson_crimson_stem_stripped_top.png new file mode 100644 index 000000000..03d9c17b9 Binary files /dev/null and b/textures/mcl_crimson_crimson_stem_stripped_top.png differ diff --git a/textures/mcl_crimson_crimson_trapdoor.png b/textures/mcl_crimson_crimson_trapdoor.png new file mode 100644 index 000000000..615b6b4b6 Binary files /dev/null and b/textures/mcl_crimson_crimson_trapdoor.png differ diff --git a/textures/mcl_crimson_nether_sprouts.png b/textures/mcl_crimson_nether_sprouts.png new file mode 100644 index 000000000..7f91d8af6 Binary files /dev/null and b/textures/mcl_crimson_nether_sprouts.png differ diff --git a/textures/mcl_crimson_shroomlight.png b/textures/mcl_crimson_shroomlight.png new file mode 100644 index 000000000..51056110f Binary files /dev/null and b/textures/mcl_crimson_shroomlight.png differ diff --git a/textures/mcl_crimson_stripped_crimson_stem.png b/textures/mcl_crimson_stripped_crimson_stem.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/textures/mcl_crimson_stripped_crimson_stem.png differ diff --git a/textures/mcl_crimson_stripped_crimson_stem_side.png b/textures/mcl_crimson_stripped_crimson_stem_side.png new file mode 100644 index 000000000..1f9ca2dda Binary files /dev/null and b/textures/mcl_crimson_stripped_crimson_stem_side.png differ diff --git a/textures/mcl_crimson_stripped_crimson_stem_top.png b/textures/mcl_crimson_stripped_crimson_stem_top.png new file mode 100644 index 000000000..71c6f501d Binary files /dev/null and b/textures/mcl_crimson_stripped_crimson_stem_top.png differ diff --git a/textures/mcl_crimson_stripped_warped_stem.png b/textures/mcl_crimson_stripped_warped_stem.png new file mode 100644 index 000000000..c5cd37b46 Binary files /dev/null and b/textures/mcl_crimson_stripped_warped_stem.png differ diff --git a/textures/mcl_crimson_stripped_warped_stem_side.png b/textures/mcl_crimson_stripped_warped_stem_side.png new file mode 100644 index 000000000..17e98fa6c Binary files /dev/null and b/textures/mcl_crimson_stripped_warped_stem_side.png differ diff --git a/textures/mcl_crimson_stripped_warped_stem_top.png b/textures/mcl_crimson_stripped_warped_stem_top.png new file mode 100644 index 000000000..868b0d8a8 Binary files /dev/null and b/textures/mcl_crimson_stripped_warped_stem_top.png differ diff --git a/textures/mcl_crimson_twisting_vines.png b/textures/mcl_crimson_twisting_vines.png new file mode 100644 index 000000000..528b62580 Binary files /dev/null and b/textures/mcl_crimson_twisting_vines.png differ diff --git a/textures/mcl_crimson_twisting_vines_plant.png b/textures/mcl_crimson_twisting_vines_plant.png new file mode 100644 index 000000000..7c2afda4e Binary files /dev/null and b/textures/mcl_crimson_twisting_vines_plant.png differ diff --git a/textures/mcl_crimson_warped_door.png b/textures/mcl_crimson_warped_door.png new file mode 100644 index 000000000..2359fc69c Binary files /dev/null and b/textures/mcl_crimson_warped_door.png differ diff --git a/textures/mcl_crimson_warped_door_bottom.png b/textures/mcl_crimson_warped_door_bottom.png new file mode 100644 index 000000000..c8715f548 Binary files /dev/null and b/textures/mcl_crimson_warped_door_bottom.png differ diff --git a/textures/mcl_crimson_warped_door_bottom_bottompart.png b/textures/mcl_crimson_warped_door_bottom_bottompart.png new file mode 100644 index 000000000..867cd39e5 Binary files /dev/null and b/textures/mcl_crimson_warped_door_bottom_bottompart.png differ diff --git a/textures/mcl_crimson_warped_door_bottom_side.png b/textures/mcl_crimson_warped_door_bottom_side.png new file mode 100644 index 000000000..30bc9859d Binary files /dev/null and b/textures/mcl_crimson_warped_door_bottom_side.png differ diff --git a/textures/mcl_crimson_warped_door_top.png b/textures/mcl_crimson_warped_door_top.png new file mode 100644 index 000000000..8066ab6b5 Binary files /dev/null and b/textures/mcl_crimson_warped_door_top.png differ diff --git a/textures/mcl_crimson_warped_door_top_side.png b/textures/mcl_crimson_warped_door_top_side.png new file mode 100644 index 000000000..732afaf8b Binary files /dev/null and b/textures/mcl_crimson_warped_door_top_side.png differ diff --git a/textures/mcl_crimson_warped_door_top_toppart.png b/textures/mcl_crimson_warped_door_top_toppart.png new file mode 100644 index 000000000..35a48ab9a Binary files /dev/null and b/textures/mcl_crimson_warped_door_top_toppart.png differ diff --git a/textures/mcl_crimson_warped_fence.png b/textures/mcl_crimson_warped_fence.png new file mode 100644 index 000000000..7e25c14c0 Binary files /dev/null and b/textures/mcl_crimson_warped_fence.png differ diff --git a/textures/mcl_crimson_warped_fence_side.png b/textures/mcl_crimson_warped_fence_side.png new file mode 100644 index 000000000..61eda6d7c Binary files /dev/null and b/textures/mcl_crimson_warped_fence_side.png differ diff --git a/textures/mcl_crimson_warped_fence_top.png b/textures/mcl_crimson_warped_fence_top.png new file mode 100644 index 000000000..d5ce4b2b3 Binary files /dev/null and b/textures/mcl_crimson_warped_fence_top.png differ diff --git a/textures/mcl_crimson_warped_fungus.png b/textures/mcl_crimson_warped_fungus.png new file mode 100644 index 000000000..8a75dee07 Binary files /dev/null and b/textures/mcl_crimson_warped_fungus.png differ diff --git a/textures/mcl_crimson_warped_hyphae.png b/textures/mcl_crimson_warped_hyphae.png new file mode 100644 index 000000000..163d7dcf0 Binary files /dev/null and b/textures/mcl_crimson_warped_hyphae.png differ diff --git a/textures/mcl_crimson_warped_hyphae_side.png b/textures/mcl_crimson_warped_hyphae_side.png new file mode 100644 index 000000000..c0dc21ed6 Binary files /dev/null and b/textures/mcl_crimson_warped_hyphae_side.png differ diff --git a/textures/mcl_crimson_warped_hyphae_wood.png b/textures/mcl_crimson_warped_hyphae_wood.png new file mode 100644 index 000000000..6764e2e83 Binary files /dev/null and b/textures/mcl_crimson_warped_hyphae_wood.png differ diff --git a/textures/mcl_crimson_warped_hyphae_wood_2nd.png b/textures/mcl_crimson_warped_hyphae_wood_2nd.png new file mode 100644 index 000000000..6764e2e83 Binary files /dev/null and b/textures/mcl_crimson_warped_hyphae_wood_2nd.png differ diff --git a/textures/mcl_crimson_warped_nylium.png b/textures/mcl_crimson_warped_nylium.png new file mode 100644 index 000000000..d2195d88c Binary files /dev/null and b/textures/mcl_crimson_warped_nylium.png differ diff --git a/textures/mcl_crimson_warped_nylium_side.png b/textures/mcl_crimson_warped_nylium_side.png new file mode 100644 index 000000000..9ab765b39 Binary files /dev/null and b/textures/mcl_crimson_warped_nylium_side.png differ diff --git a/textures/mcl_crimson_warped_roots.png b/textures/mcl_crimson_warped_roots.png new file mode 100644 index 000000000..96838e6b7 Binary files /dev/null and b/textures/mcl_crimson_warped_roots.png differ diff --git a/textures/mcl_crimson_warped_stem_stripped_side.png b/textures/mcl_crimson_warped_stem_stripped_side.png new file mode 100644 index 000000000..17e98fa6c Binary files /dev/null and b/textures/mcl_crimson_warped_stem_stripped_side.png differ diff --git a/textures/mcl_crimson_warped_stem_stripped_top.png b/textures/mcl_crimson_warped_stem_stripped_top.png new file mode 100644 index 000000000..fc722556b Binary files /dev/null and b/textures/mcl_crimson_warped_stem_stripped_top.png differ diff --git a/textures/mcl_crimson_warped_trapdoor.png b/textures/mcl_crimson_warped_trapdoor.png new file mode 100644 index 000000000..05e3f44d6 Binary files /dev/null and b/textures/mcl_crimson_warped_trapdoor.png differ diff --git a/textures/mcl_crimson_warped_wart_block.png b/textures/mcl_crimson_warped_wart_block.png new file mode 100644 index 000000000..236f26ea6 Binary files /dev/null and b/textures/mcl_crimson_warped_wart_block.png differ diff --git a/textures/mcl_crimson_weeping_vines.png b/textures/mcl_crimson_weeping_vines.png new file mode 100644 index 000000000..701688073 Binary files /dev/null and b/textures/mcl_crimson_weeping_vines.png differ diff --git a/textures/mcl_deepslate.png b/textures/mcl_deepslate.png new file mode 100644 index 000000000..bf149765b Binary files /dev/null and b/textures/mcl_deepslate.png differ diff --git a/textures/mcl_deepslate_bricks.png b/textures/mcl_deepslate_bricks.png new file mode 100644 index 000000000..41d254909 Binary files /dev/null and b/textures/mcl_deepslate_bricks.png differ diff --git a/textures/mcl_deepslate_coal_ore.png b/textures/mcl_deepslate_coal_ore.png new file mode 100644 index 000000000..1bafca96d Binary files /dev/null and b/textures/mcl_deepslate_coal_ore.png differ diff --git a/textures/mcl_deepslate_copper_ore.png b/textures/mcl_deepslate_copper_ore.png new file mode 100644 index 000000000..49278476a Binary files /dev/null and b/textures/mcl_deepslate_copper_ore.png differ diff --git a/textures/mcl_deepslate_diamond_ore.png b/textures/mcl_deepslate_diamond_ore.png new file mode 100644 index 000000000..a0c116145 Binary files /dev/null and b/textures/mcl_deepslate_diamond_ore.png differ diff --git a/textures/mcl_deepslate_emerald_ore.png b/textures/mcl_deepslate_emerald_ore.png new file mode 100644 index 000000000..21d151607 Binary files /dev/null and b/textures/mcl_deepslate_emerald_ore.png differ diff --git a/textures/mcl_deepslate_gold_ore.png b/textures/mcl_deepslate_gold_ore.png new file mode 100644 index 000000000..b601afb44 Binary files /dev/null and b/textures/mcl_deepslate_gold_ore.png differ diff --git a/textures/mcl_deepslate_iron_ore.png b/textures/mcl_deepslate_iron_ore.png new file mode 100644 index 000000000..536de8fdf Binary files /dev/null and b/textures/mcl_deepslate_iron_ore.png differ diff --git a/textures/mcl_deepslate_lapis_ore.png b/textures/mcl_deepslate_lapis_ore.png new file mode 100644 index 000000000..0df342755 Binary files /dev/null and b/textures/mcl_deepslate_lapis_ore.png differ diff --git a/textures/mcl_deepslate_redstone_ore.png b/textures/mcl_deepslate_redstone_ore.png new file mode 100644 index 000000000..5ce00fed5 Binary files /dev/null and b/textures/mcl_deepslate_redstone_ore.png differ diff --git a/textures/mcl_deepslate_tiles.png b/textures/mcl_deepslate_tiles.png new file mode 100644 index 000000000..4da18d410 Binary files /dev/null and b/textures/mcl_deepslate_tiles.png differ diff --git a/textures/mcl_deepslate_top.png b/textures/mcl_deepslate_top.png new file mode 100644 index 000000000..d89feea86 Binary files /dev/null and b/textures/mcl_deepslate_top.png differ diff --git a/textures/mcl_deepslate_tuff.png b/textures/mcl_deepslate_tuff.png new file mode 100644 index 000000000..40c0fc9d9 Binary files /dev/null and b/textures/mcl_deepslate_tuff.png differ diff --git a/textures/mcl_dirt_grass_shadow.png b/textures/mcl_dirt_grass_shadow.png new file mode 100644 index 000000000..f0fd97c24 Binary files /dev/null and b/textures/mcl_dirt_grass_shadow.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/textures/mcl_dispensers_dispenser_front_horizontal.png b/textures/mcl_dispensers_dispenser_front_horizontal.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_dispensers/textures/mcl_dispensers_dispenser_front_horizontal.png rename to textures/mcl_dispensers_dispenser_front_horizontal.png diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/textures/mcl_dispensers_dispenser_front_vertical.png b/textures/mcl_dispensers_dispenser_front_vertical.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_dispensers/textures/mcl_dispensers_dispenser_front_vertical.png rename to textures/mcl_dispensers_dispenser_front_vertical.png diff --git a/textures/mcl_doors_door_acacia.png b/textures/mcl_doors_door_acacia.png new file mode 100644 index 000000000..f671d9baa Binary files /dev/null and b/textures/mcl_doors_door_acacia.png differ diff --git a/textures/mcl_doors_door_acacia_lower.png b/textures/mcl_doors_door_acacia_lower.png new file mode 100644 index 000000000..3bf3bc676 Binary files /dev/null and b/textures/mcl_doors_door_acacia_lower.png differ diff --git a/textures/mcl_doors_door_acacia_lower_bottompart.png b/textures/mcl_doors_door_acacia_lower_bottompart.png new file mode 100644 index 000000000..63820d54c Binary files /dev/null and b/textures/mcl_doors_door_acacia_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_acacia_lower_side.png b/textures/mcl_doors_door_acacia_lower_side.png new file mode 100644 index 000000000..65db1e658 Binary files /dev/null and b/textures/mcl_doors_door_acacia_lower_side.png differ diff --git a/textures/mcl_doors_door_acacia_upper.png b/textures/mcl_doors_door_acacia_upper.png new file mode 100644 index 000000000..f982c611e Binary files /dev/null and b/textures/mcl_doors_door_acacia_upper.png differ diff --git a/textures/mcl_doors_door_acacia_upper_side.png b/textures/mcl_doors_door_acacia_upper_side.png new file mode 100644 index 000000000..25edc1f1d Binary files /dev/null and b/textures/mcl_doors_door_acacia_upper_side.png differ diff --git a/textures/mcl_doors_door_acacia_upper_toppart.png b/textures/mcl_doors_door_acacia_upper_toppart.png new file mode 100644 index 000000000..ab01973ad Binary files /dev/null and b/textures/mcl_doors_door_acacia_upper_toppart.png differ diff --git a/textures/mcl_doors_door_birch.png b/textures/mcl_doors_door_birch.png new file mode 100644 index 000000000..bcc111422 Binary files /dev/null and b/textures/mcl_doors_door_birch.png differ diff --git a/textures/mcl_doors_door_birch_lower.png b/textures/mcl_doors_door_birch_lower.png new file mode 100644 index 000000000..4b189095c Binary files /dev/null and b/textures/mcl_doors_door_birch_lower.png differ diff --git a/textures/mcl_doors_door_birch_lower_bottompart.png b/textures/mcl_doors_door_birch_lower_bottompart.png new file mode 100644 index 000000000..b83344bdf Binary files /dev/null and b/textures/mcl_doors_door_birch_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_birch_lower_side.png b/textures/mcl_doors_door_birch_lower_side.png new file mode 100644 index 000000000..e30be5b0b Binary files /dev/null and b/textures/mcl_doors_door_birch_lower_side.png differ diff --git a/textures/mcl_doors_door_birch_upper.png b/textures/mcl_doors_door_birch_upper.png new file mode 100644 index 000000000..b04b0336e Binary files /dev/null and b/textures/mcl_doors_door_birch_upper.png differ diff --git a/textures/mcl_doors_door_birch_upper_side.png b/textures/mcl_doors_door_birch_upper_side.png new file mode 100644 index 000000000..fd46bdf3f Binary files /dev/null and b/textures/mcl_doors_door_birch_upper_side.png differ diff --git a/textures/mcl_doors_door_birch_upper_toppart.png b/textures/mcl_doors_door_birch_upper_toppart.png new file mode 100644 index 000000000..1555938e6 Binary files /dev/null and b/textures/mcl_doors_door_birch_upper_toppart.png differ diff --git a/textures/mcl_doors_door_dark_oak.png b/textures/mcl_doors_door_dark_oak.png new file mode 100644 index 000000000..9fccbd44d Binary files /dev/null and b/textures/mcl_doors_door_dark_oak.png differ diff --git a/textures/mcl_doors_door_dark_oak_lower.png b/textures/mcl_doors_door_dark_oak_lower.png new file mode 100644 index 000000000..56c5c936c Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_lower.png differ diff --git a/textures/mcl_doors_door_dark_oak_lower_bottompart.png b/textures/mcl_doors_door_dark_oak_lower_bottompart.png new file mode 100644 index 000000000..3d28d876f Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_dark_oak_lower_side.png b/textures/mcl_doors_door_dark_oak_lower_side.png new file mode 100644 index 000000000..74e7dccff Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_lower_side.png differ diff --git a/textures/mcl_doors_door_dark_oak_upper.png b/textures/mcl_doors_door_dark_oak_upper.png new file mode 100644 index 000000000..e826eabdd Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_upper.png differ diff --git a/textures/mcl_doors_door_dark_oak_upper_side.png b/textures/mcl_doors_door_dark_oak_upper_side.png new file mode 100644 index 000000000..4dab51cf5 Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_upper_side.png differ diff --git a/textures/mcl_doors_door_dark_oak_upper_toppart.png b/textures/mcl_doors_door_dark_oak_upper_toppart.png new file mode 100644 index 000000000..b06778288 Binary files /dev/null and b/textures/mcl_doors_door_dark_oak_upper_toppart.png differ diff --git a/textures/mcl_doors_door_iron_lower.png b/textures/mcl_doors_door_iron_lower.png new file mode 100644 index 000000000..5eb6e2e07 Binary files /dev/null and b/textures/mcl_doors_door_iron_lower.png differ diff --git a/textures/mcl_doors_door_iron_lower_bottompart.png b/textures/mcl_doors_door_iron_lower_bottompart.png new file mode 100644 index 000000000..f029e14fe Binary files /dev/null and b/textures/mcl_doors_door_iron_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_iron_lower_side.png b/textures/mcl_doors_door_iron_lower_side.png new file mode 100644 index 000000000..e005c24b2 Binary files /dev/null and b/textures/mcl_doors_door_iron_lower_side.png differ diff --git a/textures/mcl_doors_door_iron_upper.png b/textures/mcl_doors_door_iron_upper.png new file mode 100644 index 000000000..867839641 Binary files /dev/null and b/textures/mcl_doors_door_iron_upper.png differ diff --git a/textures/mcl_doors_door_iron_upper_side.png b/textures/mcl_doors_door_iron_upper_side.png new file mode 100644 index 000000000..ee43be6ca Binary files /dev/null and b/textures/mcl_doors_door_iron_upper_side.png differ diff --git a/textures/mcl_doors_door_iron_upper_toppart.png b/textures/mcl_doors_door_iron_upper_toppart.png new file mode 100644 index 000000000..045f8c1a1 Binary files /dev/null and b/textures/mcl_doors_door_iron_upper_toppart.png differ diff --git a/textures/mcl_doors_door_jungle.png b/textures/mcl_doors_door_jungle.png new file mode 100644 index 000000000..b5672cb1b Binary files /dev/null and b/textures/mcl_doors_door_jungle.png differ diff --git a/textures/mcl_doors_door_jungle_lower.png b/textures/mcl_doors_door_jungle_lower.png new file mode 100644 index 000000000..c44e6f8f8 Binary files /dev/null and b/textures/mcl_doors_door_jungle_lower.png differ diff --git a/textures/mcl_doors_door_jungle_lower_bottompart.png b/textures/mcl_doors_door_jungle_lower_bottompart.png new file mode 100644 index 000000000..9aadfb31a Binary files /dev/null and b/textures/mcl_doors_door_jungle_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_jungle_lower_side.png b/textures/mcl_doors_door_jungle_lower_side.png new file mode 100644 index 000000000..fdf996ad6 Binary files /dev/null and b/textures/mcl_doors_door_jungle_lower_side.png differ diff --git a/textures/mcl_doors_door_jungle_upper.png b/textures/mcl_doors_door_jungle_upper.png new file mode 100644 index 000000000..401ae3f58 Binary files /dev/null and b/textures/mcl_doors_door_jungle_upper.png differ diff --git a/textures/mcl_doors_door_jungle_upper_side.png b/textures/mcl_doors_door_jungle_upper_side.png new file mode 100644 index 000000000..af479d3a4 Binary files /dev/null and b/textures/mcl_doors_door_jungle_upper_side.png differ diff --git a/textures/mcl_doors_door_jungle_upper_toppart.png b/textures/mcl_doors_door_jungle_upper_toppart.png new file mode 100644 index 000000000..d0ab14854 Binary files /dev/null and b/textures/mcl_doors_door_jungle_upper_toppart.png differ diff --git a/textures/mcl_doors_door_spruce.png b/textures/mcl_doors_door_spruce.png new file mode 100644 index 000000000..1b005b9b8 Binary files /dev/null and b/textures/mcl_doors_door_spruce.png differ diff --git a/textures/mcl_doors_door_spruce_lower.png b/textures/mcl_doors_door_spruce_lower.png new file mode 100644 index 000000000..fdbca4167 Binary files /dev/null and b/textures/mcl_doors_door_spruce_lower.png differ diff --git a/textures/mcl_doors_door_spruce_lower_bottompart.png b/textures/mcl_doors_door_spruce_lower_bottompart.png new file mode 100644 index 000000000..a28a2d69f Binary files /dev/null and b/textures/mcl_doors_door_spruce_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_spruce_lower_side.png b/textures/mcl_doors_door_spruce_lower_side.png new file mode 100644 index 000000000..b65e82b1c Binary files /dev/null and b/textures/mcl_doors_door_spruce_lower_side.png differ diff --git a/textures/mcl_doors_door_spruce_upper.png b/textures/mcl_doors_door_spruce_upper.png new file mode 100644 index 000000000..3ef5c4c81 Binary files /dev/null and b/textures/mcl_doors_door_spruce_upper.png differ diff --git a/textures/mcl_doors_door_spruce_upper_side.png b/textures/mcl_doors_door_spruce_upper_side.png new file mode 100644 index 000000000..f52beb437 Binary files /dev/null and b/textures/mcl_doors_door_spruce_upper_side.png differ diff --git a/textures/mcl_doors_door_spruce_upper_toppart.png b/textures/mcl_doors_door_spruce_upper_toppart.png new file mode 100644 index 000000000..f1a8bd73e Binary files /dev/null and b/textures/mcl_doors_door_spruce_upper_toppart.png differ diff --git a/textures/mcl_doors_door_wood_lower.png b/textures/mcl_doors_door_wood_lower.png new file mode 100644 index 000000000..81cc12056 Binary files /dev/null and b/textures/mcl_doors_door_wood_lower.png differ diff --git a/textures/mcl_doors_door_wood_lower_bottompart.png b/textures/mcl_doors_door_wood_lower_bottompart.png new file mode 100644 index 000000000..22274cabd Binary files /dev/null and b/textures/mcl_doors_door_wood_lower_bottompart.png differ diff --git a/textures/mcl_doors_door_wood_lower_side.png b/textures/mcl_doors_door_wood_lower_side.png new file mode 100644 index 000000000..f73f7a3e1 Binary files /dev/null and b/textures/mcl_doors_door_wood_lower_side.png differ diff --git a/textures/mcl_doors_door_wood_upper.png b/textures/mcl_doors_door_wood_upper.png new file mode 100644 index 000000000..8265e48ee Binary files /dev/null and b/textures/mcl_doors_door_wood_upper.png differ diff --git a/textures/mcl_doors_door_wood_upper_side.png b/textures/mcl_doors_door_wood_upper_side.png new file mode 100644 index 000000000..efecb1bb4 Binary files /dev/null and b/textures/mcl_doors_door_wood_upper_side.png differ diff --git a/textures/mcl_doors_door_wood_upper_toppart.png b/textures/mcl_doors_door_wood_upper_toppart.png new file mode 100644 index 000000000..7ae6fc712 Binary files /dev/null and b/textures/mcl_doors_door_wood_upper_toppart.png differ diff --git a/textures/mcl_doors_trapdoor_acacia.png b/textures/mcl_doors_trapdoor_acacia.png new file mode 100644 index 000000000..bf1534c06 Binary files /dev/null and b/textures/mcl_doors_trapdoor_acacia.png differ diff --git a/textures/mcl_doors_trapdoor_acacia_side.png b/textures/mcl_doors_trapdoor_acacia_side.png new file mode 100644 index 000000000..af48599c2 Binary files /dev/null and b/textures/mcl_doors_trapdoor_acacia_side.png differ diff --git a/textures/mcl_doors_trapdoor_birch.png b/textures/mcl_doors_trapdoor_birch.png new file mode 100644 index 000000000..f832fe9d0 Binary files /dev/null and b/textures/mcl_doors_trapdoor_birch.png differ diff --git a/textures/mcl_doors_trapdoor_birch_side.png b/textures/mcl_doors_trapdoor_birch_side.png new file mode 100644 index 000000000..ea0bc93ef Binary files /dev/null and b/textures/mcl_doors_trapdoor_birch_side.png differ diff --git a/mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_dark_oak.png b/textures/mcl_doors_trapdoor_dark_oak.png similarity index 100% rename from mods/ITEMS/mcl_doors/textures/mcl_doors_trapdoor_dark_oak.png rename to textures/mcl_doors_trapdoor_dark_oak.png diff --git a/textures/mcl_doors_trapdoor_dark_oak_side.png b/textures/mcl_doors_trapdoor_dark_oak_side.png new file mode 100644 index 000000000..5dbbb4d1b Binary files /dev/null and b/textures/mcl_doors_trapdoor_dark_oak_side.png differ diff --git a/textures/mcl_doors_trapdoor_jungle.png b/textures/mcl_doors_trapdoor_jungle.png new file mode 100644 index 000000000..9ed9ba81c Binary files /dev/null and b/textures/mcl_doors_trapdoor_jungle.png differ diff --git a/textures/mcl_doors_trapdoor_jungle_side.png b/textures/mcl_doors_trapdoor_jungle_side.png new file mode 100644 index 000000000..e62d5b3fd Binary files /dev/null and b/textures/mcl_doors_trapdoor_jungle_side.png differ diff --git a/textures/mcl_doors_trapdoor_spruce.png b/textures/mcl_doors_trapdoor_spruce.png new file mode 100644 index 000000000..c934d8cf3 Binary files /dev/null and b/textures/mcl_doors_trapdoor_spruce.png differ diff --git a/textures/mcl_doors_trapdoor_spruce_side.png b/textures/mcl_doors_trapdoor_spruce_side.png new file mode 100644 index 000000000..ae4b947c4 Binary files /dev/null and b/textures/mcl_doors_trapdoor_spruce_side.png differ diff --git a/textures/mcl_droppers_dropper_front_horizontal.png b/textures/mcl_droppers_dropper_front_horizontal.png new file mode 100644 index 000000000..74dc007e5 Binary files /dev/null and b/textures/mcl_droppers_dropper_front_horizontal.png differ diff --git a/textures/mcl_droppers_dropper_front_vertical.png b/textures/mcl_droppers_dropper_front_vertical.png new file mode 100644 index 000000000..a101434f6 Binary files /dev/null and b/textures/mcl_droppers_dropper_front_vertical.png differ diff --git a/textures/mcl_dye_black.png b/textures/mcl_dye_black.png new file mode 100644 index 000000000..79670d4e2 Binary files /dev/null and b/textures/mcl_dye_black.png differ diff --git a/textures/mcl_dye_blue.png b/textures/mcl_dye_blue.png new file mode 100644 index 000000000..25eaacb4f Binary files /dev/null and b/textures/mcl_dye_blue.png differ diff --git a/textures/mcl_dye_brown.png b/textures/mcl_dye_brown.png new file mode 100644 index 000000000..b24c84b1f Binary files /dev/null and b/textures/mcl_dye_brown.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_cyan.png b/textures/mcl_dye_cyan.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_cyan.png rename to textures/mcl_dye_cyan.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_dark_green.png b/textures/mcl_dye_dark_green.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_dark_green.png rename to textures/mcl_dye_dark_green.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_dark_grey.png b/textures/mcl_dye_dark_grey.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_dark_grey.png rename to textures/mcl_dye_dark_grey.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_lime.png b/textures/mcl_dye_green.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_lime.png rename to textures/mcl_dye_green.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_grey.png b/textures/mcl_dye_grey.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_grey.png rename to textures/mcl_dye_grey.png diff --git a/mods/ITEMS/mcl_dye/textures/mcl_dye_light_blue.png b/textures/mcl_dye_lightblue.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/mcl_dye_light_blue.png rename to textures/mcl_dye_lightblue.png diff --git a/textures/mcl_dye_lime.png b/textures/mcl_dye_lime.png new file mode 100644 index 000000000..7b4d08b34 Binary files /dev/null and b/textures/mcl_dye_lime.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_magenta.png b/textures/mcl_dye_magenta.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_magenta.png rename to textures/mcl_dye_magenta.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_orange.png b/textures/mcl_dye_orange.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_orange.png rename to textures/mcl_dye_orange.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_pink.png b/textures/mcl_dye_pink.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_pink.png rename to textures/mcl_dye_pink.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_red.png b/textures/mcl_dye_red.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_red.png rename to textures/mcl_dye_red.png diff --git a/mods/ITEMS/mcl_dye/textures/dye_violet.png b/textures/mcl_dye_violet.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_violet.png rename to textures/mcl_dye_violet.png diff --git a/textures/mcl_dye_white.png b/textures/mcl_dye_white.png new file mode 100644 index 000000000..96c2c8646 Binary files /dev/null and b/textures/mcl_dye_white.png differ diff --git a/mods/ITEMS/mcl_dye/textures/dye_yellow.png b/textures/mcl_dye_yellow.png similarity index 100% rename from mods/ITEMS/mcl_dye/textures/dye_yellow.png rename to textures/mcl_dye_yellow.png diff --git a/textures/mcl_enchanting_book_closed.png b/textures/mcl_enchanting_book_closed.png new file mode 100644 index 000000000..6ff832d3c Binary files /dev/null and b/textures/mcl_enchanting_book_closed.png differ diff --git a/textures/mcl_enchanting_book_enchanted.png b/textures/mcl_enchanting_book_enchanted.png new file mode 100644 index 000000000..7339e7091 Binary files /dev/null and b/textures/mcl_enchanting_book_enchanted.png differ diff --git a/textures/mcl_enchanting_book_entity.png b/textures/mcl_enchanting_book_entity.png new file mode 100644 index 000000000..9c5ce0277 Binary files /dev/null and b/textures/mcl_enchanting_book_entity.png differ diff --git a/textures/mcl_enchanting_book_open.png b/textures/mcl_enchanting_book_open.png new file mode 100644 index 000000000..6b4d5a379 Binary files /dev/null and b/textures/mcl_enchanting_book_open.png differ diff --git a/textures/mcl_enchanting_button.png b/textures/mcl_enchanting_button.png new file mode 100644 index 000000000..c6765f7ce Binary files /dev/null and b/textures/mcl_enchanting_button.png differ diff --git a/textures/mcl_enchanting_button_background.png b/textures/mcl_enchanting_button_background.png new file mode 100644 index 000000000..cd05418d4 Binary files /dev/null and b/textures/mcl_enchanting_button_background.png differ diff --git a/textures/mcl_enchanting_button_hovered.png b/textures/mcl_enchanting_button_hovered.png new file mode 100644 index 000000000..c6765f7ce Binary files /dev/null and b/textures/mcl_enchanting_button_hovered.png differ diff --git a/textures/mcl_enchanting_button_off.png b/textures/mcl_enchanting_button_off.png new file mode 100644 index 000000000..c6765f7ce Binary files /dev/null and b/textures/mcl_enchanting_button_off.png differ diff --git a/textures/mcl_enchanting_glyph_1.png b/textures/mcl_enchanting_glyph_1.png new file mode 100644 index 000000000..c449eae08 Binary files /dev/null and b/textures/mcl_enchanting_glyph_1.png differ diff --git a/textures/mcl_enchanting_glyph_10.png b/textures/mcl_enchanting_glyph_10.png new file mode 100644 index 000000000..9feb2a5a2 Binary files /dev/null and b/textures/mcl_enchanting_glyph_10.png differ diff --git a/textures/mcl_enchanting_glyph_11.png b/textures/mcl_enchanting_glyph_11.png new file mode 100644 index 000000000..adda78dec Binary files /dev/null and b/textures/mcl_enchanting_glyph_11.png differ diff --git a/textures/mcl_enchanting_glyph_12.png b/textures/mcl_enchanting_glyph_12.png new file mode 100644 index 000000000..5d4c1ee6f Binary files /dev/null and b/textures/mcl_enchanting_glyph_12.png differ diff --git a/textures/mcl_enchanting_glyph_13.png b/textures/mcl_enchanting_glyph_13.png new file mode 100644 index 000000000..b57fbb71e Binary files /dev/null and b/textures/mcl_enchanting_glyph_13.png differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_14.png b/textures/mcl_enchanting_glyph_14.png similarity index 100% rename from mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_14.png rename to textures/mcl_enchanting_glyph_14.png diff --git a/textures/mcl_enchanting_glyph_15.png b/textures/mcl_enchanting_glyph_15.png new file mode 100644 index 000000000..cef995fcf Binary files /dev/null and b/textures/mcl_enchanting_glyph_15.png differ diff --git a/textures/mcl_enchanting_glyph_16.png b/textures/mcl_enchanting_glyph_16.png new file mode 100644 index 000000000..27e180728 Binary files /dev/null and b/textures/mcl_enchanting_glyph_16.png differ diff --git a/textures/mcl_enchanting_glyph_17.png b/textures/mcl_enchanting_glyph_17.png new file mode 100644 index 000000000..1dc41a021 Binary files /dev/null and b/textures/mcl_enchanting_glyph_17.png differ diff --git a/textures/mcl_enchanting_glyph_18.png b/textures/mcl_enchanting_glyph_18.png new file mode 100644 index 000000000..631973dbb Binary files /dev/null and b/textures/mcl_enchanting_glyph_18.png differ diff --git a/textures/mcl_enchanting_glyph_2.png b/textures/mcl_enchanting_glyph_2.png new file mode 100644 index 000000000..674fdeaa5 Binary files /dev/null and b/textures/mcl_enchanting_glyph_2.png differ diff --git a/textures/mcl_enchanting_glyph_3.png b/textures/mcl_enchanting_glyph_3.png new file mode 100644 index 000000000..6f1660580 Binary files /dev/null and b/textures/mcl_enchanting_glyph_3.png differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_4.png b/textures/mcl_enchanting_glyph_4.png similarity index 100% rename from mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_4.png rename to textures/mcl_enchanting_glyph_4.png diff --git a/textures/mcl_enchanting_glyph_5.png b/textures/mcl_enchanting_glyph_5.png new file mode 100644 index 000000000..1473ea41d Binary files /dev/null and b/textures/mcl_enchanting_glyph_5.png differ diff --git a/textures/mcl_enchanting_glyph_6.png b/textures/mcl_enchanting_glyph_6.png new file mode 100644 index 000000000..89de2cf8f Binary files /dev/null and b/textures/mcl_enchanting_glyph_6.png differ diff --git a/textures/mcl_enchanting_glyph_7.png b/textures/mcl_enchanting_glyph_7.png new file mode 100644 index 000000000..bf632f7f6 Binary files /dev/null and b/textures/mcl_enchanting_glyph_7.png differ diff --git a/textures/mcl_enchanting_glyph_8.png b/textures/mcl_enchanting_glyph_8.png new file mode 100644 index 000000000..acecebc44 Binary files /dev/null and b/textures/mcl_enchanting_glyph_8.png differ diff --git a/mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_9.png b/textures/mcl_enchanting_glyph_9.png similarity index 100% rename from mods/ITEMS/mcl_enchanting/textures/mcl_enchanting_glyph_9.png rename to textures/mcl_enchanting_glyph_9.png diff --git a/textures/mcl_enchanting_lapis_background.png b/textures/mcl_enchanting_lapis_background.png new file mode 100644 index 000000000..f056899d0 Binary files /dev/null and b/textures/mcl_enchanting_lapis_background.png differ diff --git a/textures/mcl_enchanting_number_1.png b/textures/mcl_enchanting_number_1.png new file mode 100644 index 000000000..8e5fc6485 Binary files /dev/null and b/textures/mcl_enchanting_number_1.png differ diff --git a/textures/mcl_enchanting_number_1_off.png b/textures/mcl_enchanting_number_1_off.png new file mode 100644 index 000000000..c22f319c3 Binary files /dev/null and b/textures/mcl_enchanting_number_1_off.png differ diff --git a/textures/mcl_enchanting_number_2.png b/textures/mcl_enchanting_number_2.png new file mode 100644 index 000000000..0a89a9dc6 Binary files /dev/null and b/textures/mcl_enchanting_number_2.png differ diff --git a/textures/mcl_enchanting_number_2_off.png b/textures/mcl_enchanting_number_2_off.png new file mode 100644 index 000000000..c22f319c3 Binary files /dev/null and b/textures/mcl_enchanting_number_2_off.png differ diff --git a/textures/mcl_enchanting_number_3.png b/textures/mcl_enchanting_number_3.png new file mode 100644 index 000000000..eee8032a1 Binary files /dev/null and b/textures/mcl_enchanting_number_3.png differ diff --git a/textures/mcl_enchanting_number_3_off.png b/textures/mcl_enchanting_number_3_off.png new file mode 100644 index 000000000..c22f319c3 Binary files /dev/null and b/textures/mcl_enchanting_number_3_off.png differ diff --git a/textures/mcl_enchanting_table_bottom.png b/textures/mcl_enchanting_table_bottom.png new file mode 100644 index 000000000..871d96cca Binary files /dev/null and b/textures/mcl_enchanting_table_bottom.png differ diff --git a/textures/mcl_enchanting_table_side.png b/textures/mcl_enchanting_table_side.png new file mode 100644 index 000000000..29eabb902 Binary files /dev/null and b/textures/mcl_enchanting_table_side.png differ diff --git a/textures/mcl_enchanting_table_top.png b/textures/mcl_enchanting_table_top.png new file mode 100644 index 000000000..d9428503a Binary files /dev/null and b/textures/mcl_enchanting_table_top.png differ diff --git a/textures/mcl_end_chorus_flower.png b/textures/mcl_end_chorus_flower.png new file mode 100644 index 000000000..23f0e06b2 Binary files /dev/null and b/textures/mcl_end_chorus_flower.png differ diff --git a/textures/mcl_end_chorus_flower_dead.png b/textures/mcl_end_chorus_flower_dead.png new file mode 100644 index 000000000..6d4e2d3d5 Binary files /dev/null and b/textures/mcl_end_chorus_flower_dead.png differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_fruit.png b/textures/mcl_end_chorus_fruit.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_chorus_fruit.png rename to textures/mcl_end_chorus_fruit.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_chorus_fruit_popped.png b/textures/mcl_end_chorus_fruit_popped.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_chorus_fruit_popped.png rename to textures/mcl_end_chorus_fruit_popped.png diff --git a/textures/mcl_end_chorus_plant.png b/textures/mcl_end_chorus_plant.png new file mode 100644 index 000000000..920d82ec2 Binary files /dev/null and b/textures/mcl_end_chorus_plant.png differ diff --git a/textures/mcl_end_crystal.png b/textures/mcl_end_crystal.png new file mode 100644 index 000000000..35c3c4b0c Binary files /dev/null and b/textures/mcl_end_crystal.png differ diff --git a/textures/mcl_end_crystal_beam.png b/textures/mcl_end_crystal_beam.png new file mode 100644 index 000000000..0c8abbc83 Binary files /dev/null and b/textures/mcl_end_crystal_beam.png differ diff --git a/textures/mcl_end_crystal_item.png b/textures/mcl_end_crystal_item.png new file mode 100644 index 000000000..54f99b4c2 Binary files /dev/null and b/textures/mcl_end_crystal_item.png differ diff --git a/textures/mcl_end_dragon_egg.png b/textures/mcl_end_dragon_egg.png new file mode 100644 index 000000000..1533c3b17 Binary files /dev/null and b/textures/mcl_end_dragon_egg.png differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_end_bricks.png b/textures/mcl_end_end_bricks.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_end_bricks.png rename to textures/mcl_end_end_bricks.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_end_rod_bottom.png b/textures/mcl_end_end_rod_bottom.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_end_rod_bottom.png rename to textures/mcl_end_end_rod_bottom.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_end_rod_side.png b/textures/mcl_end_end_rod_side.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_end_rod_side.png rename to textures/mcl_end_end_rod_side.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_end_rod_top.png b/textures/mcl_end_end_rod_top.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_end_rod_top.png rename to textures/mcl_end_end_rod_top.png diff --git a/textures/mcl_end_end_stone.png b/textures/mcl_end_end_stone.png new file mode 100644 index 000000000..ea48cea9f Binary files /dev/null and b/textures/mcl_end_end_stone.png differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_ender_eye.png b/textures/mcl_end_ender_eye.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_ender_eye.png rename to textures/mcl_end_ender_eye.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_endframe_eye.png b/textures/mcl_end_endframe_eye.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_endframe_eye.png rename to textures/mcl_end_endframe_eye.png diff --git a/textures/mcl_end_endframe_side.png b/textures/mcl_end_endframe_side.png new file mode 100644 index 000000000..6922795ed Binary files /dev/null and b/textures/mcl_end_endframe_side.png differ diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_endframe_top.png b/textures/mcl_end_endframe_top.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_endframe_top.png rename to textures/mcl_end_endframe_top.png diff --git a/mods/ITEMS/mcl_end/textures/mcl_end_purpur_block.png b/textures/mcl_end_purpur_block.png similarity index 100% rename from mods/ITEMS/mcl_end/textures/mcl_end_purpur_block.png rename to textures/mcl_end_purpur_block.png diff --git a/textures/mcl_end_purpur_pillar.png b/textures/mcl_end_purpur_pillar.png new file mode 100644 index 000000000..2f2522e25 Binary files /dev/null and b/textures/mcl_end_purpur_pillar.png differ diff --git a/textures/mcl_end_purpur_pillar_top.png b/textures/mcl_end_purpur_pillar_top.png new file mode 100644 index 000000000..712247d82 Binary files /dev/null and b/textures/mcl_end_purpur_pillar_top.png differ diff --git a/textures/mcl_experience_bar.png b/textures/mcl_experience_bar.png new file mode 100644 index 000000000..ef6e2f4bb Binary files /dev/null and b/textures/mcl_experience_bar.png differ diff --git a/textures/mcl_experience_bar_background.png b/textures/mcl_experience_bar_background.png new file mode 100644 index 000000000..afbb9188d Binary files /dev/null and b/textures/mcl_experience_bar_background.png differ diff --git a/textures/mcl_experience_bottle.png b/textures/mcl_experience_bottle.png new file mode 100644 index 000000000..4aa540802 Binary files /dev/null and b/textures/mcl_experience_bottle.png differ diff --git a/textures/mcl_experience_orb.png b/textures/mcl_experience_orb.png new file mode 100644 index 000000000..dd99a519c Binary files /dev/null and b/textures/mcl_experience_orb.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot.png b/textures/mcl_farming_beetroot.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot.png rename to textures/mcl_farming_beetroot.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_0.png b/textures/mcl_farming_beetroot_0.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_0.png rename to textures/mcl_farming_beetroot_0.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_1.png b/textures/mcl_farming_beetroot_1.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_1.png rename to textures/mcl_farming_beetroot_1.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_2.png b/textures/mcl_farming_beetroot_2.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_2.png rename to textures/mcl_farming_beetroot_2.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_3.png b/textures/mcl_farming_beetroot_3.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_3.png rename to textures/mcl_farming_beetroot_3.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_seeds.png b/textures/mcl_farming_beetroot_seeds.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_seeds.png rename to textures/mcl_farming_beetroot_seeds.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_soup.png b/textures/mcl_farming_beetroot_soup.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_beetroot_soup.png rename to textures/mcl_farming_beetroot_soup.png diff --git a/textures/mcl_farming_farmland_dry.png b/textures/mcl_farming_farmland_dry.png new file mode 100644 index 000000000..44c956b6f Binary files /dev/null and b/textures/mcl_farming_farmland_dry.png differ diff --git a/textures/mcl_farming_farmland_wet.png b/textures/mcl_farming_farmland_wet.png new file mode 100644 index 000000000..f5ebf2de3 Binary files /dev/null and b/textures/mcl_farming_farmland_wet.png differ diff --git a/textures/mcl_farming_hayblock_side.png b/textures/mcl_farming_hayblock_side.png new file mode 100644 index 000000000..4d994067b Binary files /dev/null and b/textures/mcl_farming_hayblock_side.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_hayblock_top.png b/textures/mcl_farming_hayblock_top.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_hayblock_top.png rename to textures/mcl_farming_hayblock_top.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_melon_seeds.png b/textures/mcl_farming_melon_seeds.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_melon_seeds.png rename to textures/mcl_farming_melon_seeds.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_melon_stem_connected.png b/textures/mcl_farming_melon_stem_connected.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_melon_stem_connected.png rename to textures/mcl_farming_melon_stem_connected.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_melon_stem_disconnected.png b/textures/mcl_farming_melon_stem_disconnected.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_melon_stem_disconnected.png rename to textures/mcl_farming_melon_stem_disconnected.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_0.png b/textures/mcl_farming_potatoes_stage_0.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_0.png rename to textures/mcl_farming_potatoes_stage_0.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_1.png b/textures/mcl_farming_potatoes_stage_1.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_1.png rename to textures/mcl_farming_potatoes_stage_1.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_2.png b/textures/mcl_farming_potatoes_stage_2.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_2.png rename to textures/mcl_farming_potatoes_stage_2.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_3.png b/textures/mcl_farming_potatoes_stage_3.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_potatoes_stage_3.png rename to textures/mcl_farming_potatoes_stage_3.png diff --git a/textures/mcl_farming_pumpkin_face.png b/textures/mcl_farming_pumpkin_face.png new file mode 100644 index 000000000..095b90cc6 Binary files /dev/null and b/textures/mcl_farming_pumpkin_face.png differ diff --git a/textures/mcl_farming_pumpkin_hud.png b/textures/mcl_farming_pumpkin_hud.png new file mode 100644 index 000000000..e2a03671b Binary files /dev/null and b/textures/mcl_farming_pumpkin_hud.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_pie.png b/textures/mcl_farming_pumpkin_pie.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_pie.png rename to textures/mcl_farming_pumpkin_pie.png diff --git a/textures/mcl_farming_pumpkin_seeds.png b/textures/mcl_farming_pumpkin_seeds.png new file mode 100644 index 000000000..24e2c80c1 Binary files /dev/null and b/textures/mcl_farming_pumpkin_seeds.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_stem_connected.png b/textures/mcl_farming_pumpkin_stem_connected.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_stem_connected.png rename to textures/mcl_farming_pumpkin_stem_connected.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_stem_disconnected.png b/textures/mcl_farming_pumpkin_stem_disconnected.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_pumpkin_stem_disconnected.png rename to textures/mcl_farming_pumpkin_stem_disconnected.png diff --git a/textures/mcl_farming_sweet_berry.png b/textures/mcl_farming_sweet_berry.png new file mode 100644 index 000000000..f6a4c1db6 Binary files /dev/null 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 new file mode 100644 index 000000000..2d9a7eed8 Binary files /dev/null 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 new file mode 100644 index 000000000..ecbd5f4cf Binary files /dev/null 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 new file mode 100644 index 000000000..e452fe42b Binary files /dev/null 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 new file mode 100644 index 000000000..0748e09c8 Binary files /dev/null and b/textures/mcl_farming_sweet_berry_bush_3.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_seeds.png b/textures/mcl_farming_wheat_seeds.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_seeds.png rename to textures/mcl_farming_wheat_seeds.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_0.png b/textures/mcl_farming_wheat_stage_0.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_0.png rename to textures/mcl_farming_wheat_stage_0.png diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_1.png b/textures/mcl_farming_wheat_stage_1.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_1.png rename to textures/mcl_farming_wheat_stage_1.png diff --git a/textures/mcl_farming_wheat_stage_2.png b/textures/mcl_farming_wheat_stage_2.png new file mode 100644 index 000000000..323cc830e Binary files /dev/null and b/textures/mcl_farming_wheat_stage_2.png differ diff --git a/textures/mcl_farming_wheat_stage_3.png b/textures/mcl_farming_wheat_stage_3.png new file mode 100644 index 000000000..247c9e051 Binary files /dev/null and b/textures/mcl_farming_wheat_stage_3.png differ diff --git a/textures/mcl_farming_wheat_stage_4.png b/textures/mcl_farming_wheat_stage_4.png new file mode 100644 index 000000000..7410aa01c Binary files /dev/null and b/textures/mcl_farming_wheat_stage_4.png differ diff --git a/mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_5.png b/textures/mcl_farming_wheat_stage_5.png similarity index 100% rename from mods/ITEMS/mcl_farming/textures/mcl_farming_wheat_stage_5.png rename to textures/mcl_farming_wheat_stage_5.png diff --git a/textures/mcl_farming_wheat_stage_6.png b/textures/mcl_farming_wheat_stage_6.png new file mode 100644 index 000000000..04221b430 Binary files /dev/null and b/textures/mcl_farming_wheat_stage_6.png differ diff --git a/textures/mcl_farming_wheat_stage_7.png b/textures/mcl_farming_wheat_stage_7.png new file mode 100644 index 000000000..bff840d3e Binary files /dev/null and b/textures/mcl_farming_wheat_stage_7.png differ diff --git a/textures/mcl_fences_fence_acacia.png b/textures/mcl_fences_fence_acacia.png new file mode 100644 index 000000000..b62dd747f Binary files /dev/null and b/textures/mcl_fences_fence_acacia.png differ diff --git a/textures/mcl_fences_fence_big_oak.png b/textures/mcl_fences_fence_big_oak.png new file mode 100644 index 000000000..5068a71ac Binary files /dev/null and b/textures/mcl_fences_fence_big_oak.png differ diff --git a/textures/mcl_fences_fence_birch.png b/textures/mcl_fences_fence_birch.png new file mode 100644 index 000000000..b52db65d2 Binary files /dev/null and b/textures/mcl_fences_fence_birch.png differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_acacia.png b/textures/mcl_fences_fence_gate_acacia.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_acacia.png rename to textures/mcl_fences_fence_gate_acacia.png diff --git a/textures/mcl_fences_fence_gate_big_oak.png b/textures/mcl_fences_fence_gate_big_oak.png new file mode 100644 index 000000000..68a4323f6 Binary files /dev/null and b/textures/mcl_fences_fence_gate_big_oak.png differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_birch.png b/textures/mcl_fences_fence_gate_birch.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_birch.png rename to textures/mcl_fences_fence_gate_birch.png diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_jungle.png b/textures/mcl_fences_fence_gate_jungle.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_jungle.png rename to textures/mcl_fences_fence_gate_jungle.png diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_mask.png b/textures/mcl_fences_fence_gate_mask.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_mask.png rename to textures/mcl_fences_fence_gate_mask.png diff --git a/mods/ITEMS/mclx_fences/textures/mcl_fences_fence_gate_nether_brick.png b/textures/mcl_fences_fence_gate_nether_brick.png similarity index 100% rename from mods/ITEMS/mclx_fences/textures/mcl_fences_fence_gate_nether_brick.png rename to textures/mcl_fences_fence_gate_nether_brick.png diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_oak.png b/textures/mcl_fences_fence_gate_oak.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_oak.png rename to textures/mcl_fences_fence_gate_oak.png diff --git a/textures/mcl_fences_fence_gate_red_nether_brick.png b/textures/mcl_fences_fence_gate_red_nether_brick.png new file mode 100644 index 000000000..599cf1bf4 Binary files /dev/null and b/textures/mcl_fences_fence_gate_red_nether_brick.png differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_spruce.png b/textures/mcl_fences_fence_gate_spruce.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_gate_spruce.png rename to textures/mcl_fences_fence_gate_spruce.png diff --git a/textures/mcl_fences_fence_jungle.png b/textures/mcl_fences_fence_jungle.png new file mode 100644 index 000000000..4324b3ef7 Binary files /dev/null and b/textures/mcl_fences_fence_jungle.png differ diff --git a/textures/mcl_fences_fence_mask.png b/textures/mcl_fences_fence_mask.png new file mode 100644 index 000000000..35d162915 Binary files /dev/null and b/textures/mcl_fences_fence_mask.png differ diff --git a/textures/mcl_fences_fence_nether_brick.png b/textures/mcl_fences_fence_nether_brick.png new file mode 100644 index 000000000..7f7c461bc Binary files /dev/null and b/textures/mcl_fences_fence_nether_brick.png differ diff --git a/textures/mcl_fences_fence_oak.png b/textures/mcl_fences_fence_oak.png new file mode 100644 index 000000000..90c36edf4 Binary files /dev/null and b/textures/mcl_fences_fence_oak.png differ diff --git a/textures/mcl_fences_fence_red_nether_brick.png b/textures/mcl_fences_fence_red_nether_brick.png new file mode 100644 index 000000000..24e08e0f0 Binary files /dev/null and b/textures/mcl_fences_fence_red_nether_brick.png differ diff --git a/mods/ITEMS/mcl_fences/textures/mcl_fences_fence_spruce.png b/textures/mcl_fences_fence_spruce.png similarity index 100% rename from mods/ITEMS/mcl_fences/textures/mcl_fences_fence_spruce.png rename to textures/mcl_fences_fence_spruce.png diff --git a/mods/ITEMS/mcl_fire/textures/mcl_fire_fire_charge.png b/textures/mcl_fire_fire_charge.png similarity index 100% rename from mods/ITEMS/mcl_fire/textures/mcl_fire_fire_charge.png rename to textures/mcl_fire_fire_charge.png diff --git a/mods/ITEMS/mcl_fire/textures/mcl_fire_flint_and_steel.png b/textures/mcl_fire_flint_and_steel.png similarity index 100% rename from mods/ITEMS/mcl_fire/textures/mcl_fire_flint_and_steel.png rename to textures/mcl_fire_flint_and_steel.png diff --git a/textures/mcl_fireworks_rocket.png b/textures/mcl_fireworks_rocket.png new file mode 100644 index 000000000..1c6a580aa Binary files /dev/null and b/textures/mcl_fireworks_rocket.png differ diff --git a/textures/mcl_fishing_bobber.png b/textures/mcl_fishing_bobber.png new file mode 100644 index 000000000..f7e6a3ac6 Binary files /dev/null and b/textures/mcl_fishing_bobber.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_clownfish_raw.png b/textures/mcl_fishing_clownfish_raw.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_clownfish_raw.png rename to textures/mcl_fishing_clownfish_raw.png diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fish_cooked.png b/textures/mcl_fishing_fish_cooked.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_fish_cooked.png rename to textures/mcl_fishing_fish_cooked.png diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_fish_raw.png b/textures/mcl_fishing_fish_raw.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_fish_raw.png rename to textures/mcl_fishing_fish_raw.png diff --git a/textures/mcl_fishing_fishing_rod.png b/textures/mcl_fishing_fishing_rod.png new file mode 100644 index 000000000..9ff7479ec Binary files /dev/null and b/textures/mcl_fishing_fishing_rod.png differ diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_pufferfish_raw.png b/textures/mcl_fishing_pufferfish_raw.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_pufferfish_raw.png rename to textures/mcl_fishing_pufferfish_raw.png diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_salmon_cooked.png b/textures/mcl_fishing_salmon_cooked.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_salmon_cooked.png rename to textures/mcl_fishing_salmon_cooked.png diff --git a/mods/ITEMS/mcl_fishing/textures/mcl_fishing_salmon_raw.png b/textures/mcl_fishing_salmon_raw.png similarity index 100% rename from mods/ITEMS/mcl_fishing/textures/mcl_fishing_salmon_raw.png rename to textures/mcl_fishing_salmon_raw.png diff --git a/mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_cactus.png b/textures/mcl_flowerpots_cactus.png similarity index 100% rename from mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_cactus.png rename to textures/mcl_flowerpots_cactus.png diff --git a/mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_flowerpot.png b/textures/mcl_flowerpots_flowerpot.png similarity index 100% rename from mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_flowerpot.png rename to textures/mcl_flowerpots_flowerpot.png diff --git a/mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_flowerpot_inventory.png b/textures/mcl_flowerpots_flowerpot_inventory.png similarity index 100% rename from mods/ITEMS/mcl_flowerpots/textures/mcl_flowerpots_flowerpot_inventory.png rename to textures/mcl_flowerpots_flowerpot_inventory.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_allium.png b/textures/mcl_flowers_allium.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_allium.png rename to textures/mcl_flowers_allium.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_azure_bluet.png b/textures/mcl_flowers_azure_bluet.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_azure_bluet.png rename to textures/mcl_flowers_azure_bluet.png diff --git a/textures/mcl_flowers_blue_orchid.png b/textures/mcl_flowers_blue_orchid.png new file mode 100644 index 000000000..60f9df1a0 Binary files /dev/null and b/textures/mcl_flowers_blue_orchid.png differ diff --git a/textures/mcl_flowers_cornflower.png b/textures/mcl_flowers_cornflower.png new file mode 100644 index 000000000..d8058c535 Binary files /dev/null and b/textures/mcl_flowers_cornflower.png differ diff --git a/textures/mcl_flowers_double_plant_fern_bottom.png b/textures/mcl_flowers_double_plant_fern_bottom.png new file mode 100644 index 000000000..d4acb4dda Binary files /dev/null and b/textures/mcl_flowers_double_plant_fern_bottom.png differ diff --git a/textures/mcl_flowers_double_plant_fern_inv.png b/textures/mcl_flowers_double_plant_fern_inv.png new file mode 100644 index 000000000..2a88a3a17 Binary files /dev/null and b/textures/mcl_flowers_double_plant_fern_inv.png differ diff --git a/textures/mcl_flowers_double_plant_fern_top.png b/textures/mcl_flowers_double_plant_fern_top.png new file mode 100644 index 000000000..9a4d4589b Binary files /dev/null and b/textures/mcl_flowers_double_plant_fern_top.png differ diff --git a/textures/mcl_flowers_double_plant_grass_bottom.png b/textures/mcl_flowers_double_plant_grass_bottom.png new file mode 100644 index 000000000..f7ae3a83c Binary files /dev/null and b/textures/mcl_flowers_double_plant_grass_bottom.png differ diff --git a/textures/mcl_flowers_double_plant_grass_inv.png b/textures/mcl_flowers_double_plant_grass_inv.png new file mode 100644 index 000000000..251532a27 Binary files /dev/null and b/textures/mcl_flowers_double_plant_grass_inv.png differ diff --git a/textures/mcl_flowers_double_plant_grass_top.png b/textures/mcl_flowers_double_plant_grass_top.png new file mode 100644 index 000000000..f6b19d558 Binary files /dev/null and b/textures/mcl_flowers_double_plant_grass_top.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_paeonia_bottom.png b/textures/mcl_flowers_double_plant_paeonia_bottom.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_paeonia_bottom.png rename to textures/mcl_flowers_double_plant_paeonia_bottom.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_paeonia_top.png b/textures/mcl_flowers_double_plant_paeonia_top.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_paeonia_top.png rename to textures/mcl_flowers_double_plant_paeonia_top.png diff --git a/textures/mcl_flowers_double_plant_rose_bottom.png b/textures/mcl_flowers_double_plant_rose_bottom.png new file mode 100644 index 000000000..a8f5df226 Binary files /dev/null and b/textures/mcl_flowers_double_plant_rose_bottom.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_rose_top.png b/textures/mcl_flowers_double_plant_rose_top.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_rose_top.png rename to textures/mcl_flowers_double_plant_rose_top.png diff --git a/textures/mcl_flowers_double_plant_sunflower_back.png b/textures/mcl_flowers_double_plant_sunflower_back.png new file mode 100644 index 000000000..c1222611d Binary files /dev/null and b/textures/mcl_flowers_double_plant_sunflower_back.png differ diff --git a/textures/mcl_flowers_double_plant_sunflower_bottom.png b/textures/mcl_flowers_double_plant_sunflower_bottom.png new file mode 100644 index 000000000..e84fc2418 Binary files /dev/null and b/textures/mcl_flowers_double_plant_sunflower_bottom.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_front.png b/textures/mcl_flowers_double_plant_sunflower_front.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_front.png rename to textures/mcl_flowers_double_plant_sunflower_front.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_top.png b/textures/mcl_flowers_double_plant_sunflower_top.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_sunflower_top.png rename to textures/mcl_flowers_double_plant_sunflower_top.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_syringa_bottom.png b/textures/mcl_flowers_double_plant_syringa_bottom.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_double_plant_syringa_bottom.png rename to textures/mcl_flowers_double_plant_syringa_bottom.png diff --git a/textures/mcl_flowers_double_plant_syringa_top.png b/textures/mcl_flowers_double_plant_syringa_top.png new file mode 100644 index 000000000..aaf728114 Binary files /dev/null and b/textures/mcl_flowers_double_plant_syringa_top.png differ diff --git a/textures/mcl_flowers_fern.png b/textures/mcl_flowers_fern.png new file mode 100644 index 000000000..ae54a33fd Binary files /dev/null and b/textures/mcl_flowers_fern.png differ diff --git a/textures/mcl_flowers_fern_inv.png b/textures/mcl_flowers_fern_inv.png new file mode 100644 index 000000000..901332156 Binary files /dev/null and b/textures/mcl_flowers_fern_inv.png differ diff --git a/textures/mcl_flowers_lily_of_the_valley.png b/textures/mcl_flowers_lily_of_the_valley.png new file mode 100644 index 000000000..b4bd537bf Binary files /dev/null and b/textures/mcl_flowers_lily_of_the_valley.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_oxeye_daisy.png b/textures/mcl_flowers_oxeye_daisy.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_oxeye_daisy.png rename to textures/mcl_flowers_oxeye_daisy.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_poppy.png b/textures/mcl_flowers_poppy.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_poppy.png rename to textures/mcl_flowers_poppy.png diff --git a/textures/mcl_flowers_tallgrass.png b/textures/mcl_flowers_tallgrass.png new file mode 100644 index 000000000..ca5579d24 Binary files /dev/null and b/textures/mcl_flowers_tallgrass.png differ diff --git a/textures/mcl_flowers_tallgrass_inv.png b/textures/mcl_flowers_tallgrass_inv.png new file mode 100644 index 000000000..444988810 Binary files /dev/null and b/textures/mcl_flowers_tallgrass_inv.png differ diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_pink.png b/textures/mcl_flowers_tulip_pink.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_pink.png rename to textures/mcl_flowers_tulip_pink.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_red.png b/textures/mcl_flowers_tulip_red.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_red.png rename to textures/mcl_flowers_tulip_red.png diff --git a/mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_white.png b/textures/mcl_flowers_tulip_white.png similarity index 100% rename from mods/ITEMS/mcl_flowers/textures/mcl_flowers_tulip_white.png rename to textures/mcl_flowers_tulip_white.png diff --git a/textures/mcl_flowers_wither_rose.png b/textures/mcl_flowers_wither_rose.png new file mode 100644 index 000000000..d69030ec7 Binary files /dev/null and b/textures/mcl_flowers_wither_rose.png differ diff --git a/textures/mcl_formspec_itemslot.png b/textures/mcl_formspec_itemslot.png new file mode 100644 index 000000000..d35e3f163 Binary files /dev/null and b/textures/mcl_formspec_itemslot.png differ diff --git a/textures/mcl_hamburger.png b/textures/mcl_hamburger.png new file mode 100644 index 000000000..a4bcc904b Binary files /dev/null and b/textures/mcl_hamburger.png differ diff --git a/textures/mcl_hamburger_alt.png b/textures/mcl_hamburger_alt.png new file mode 100644 index 000000000..0c48f42c9 Binary files /dev/null and b/textures/mcl_hamburger_alt.png differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_creeper.png b/textures/mcl_heads_creeper.png similarity index 100% rename from mods/ITEMS/mcl_heads/textures/mcl_heads_creeper.png rename to textures/mcl_heads_creeper.png diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton.png b/textures/mcl_heads_skeleton.png similarity index 100% rename from mods/ITEMS/mcl_heads/textures/mcl_heads_skeleton.png rename to textures/mcl_heads_skeleton.png diff --git a/textures/mcl_heads_steve.png b/textures/mcl_heads_steve.png new file mode 100644 index 000000000..471a8b3c8 Binary files /dev/null and b/textures/mcl_heads_steve.png differ diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton.png b/textures/mcl_heads_wither_skeleton.png similarity index 100% rename from mods/ITEMS/mcl_heads/textures/mcl_heads_wither_skeleton.png rename to textures/mcl_heads_wither_skeleton.png diff --git a/mods/ITEMS/mcl_heads/textures/mcl_heads_zombie.png b/textures/mcl_heads_zombie.png similarity index 100% rename from mods/ITEMS/mcl_heads/textures/mcl_heads_zombie.png rename to textures/mcl_heads_zombie.png diff --git a/textures/mcl_honey_block_bottom.png b/textures/mcl_honey_block_bottom.png new file mode 100644 index 000000000..78de3bcbd Binary files /dev/null and b/textures/mcl_honey_block_bottom.png differ diff --git a/textures/mcl_honey_block_side.png b/textures/mcl_honey_block_side.png new file mode 100644 index 000000000..8ac2c1290 Binary files /dev/null and b/textures/mcl_honey_block_side.png differ diff --git a/textures/mcl_honey_block_top.png b/textures/mcl_honey_block_top.png new file mode 100644 index 000000000..9e37c9b16 Binary files /dev/null and b/textures/mcl_honey_block_top.png differ diff --git a/textures/mcl_honey_honey_bottle.png b/textures/mcl_honey_honey_bottle.png new file mode 100644 index 000000000..d368cd354 Binary files /dev/null and b/textures/mcl_honey_honey_bottle.png differ diff --git a/textures/mcl_honey_honeycomb.png b/textures/mcl_honey_honeycomb.png new file mode 100644 index 000000000..bf0d17c9a Binary files /dev/null and b/textures/mcl_honey_honeycomb.png differ diff --git a/textures/mcl_honey_honeycomb_block.png b/textures/mcl_honey_honeycomb_block.png new file mode 100644 index 000000000..c770c8f5f Binary files /dev/null and b/textures/mcl_honey_honeycomb_block.png differ diff --git a/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_inside.png b/textures/mcl_hoppers_hopper_inside.png similarity index 100% rename from mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_inside.png rename to textures/mcl_hoppers_hopper_inside.png diff --git a/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_outside.png b/textures/mcl_hoppers_hopper_outside.png similarity index 100% rename from mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_hopper_outside.png rename to textures/mcl_hoppers_hopper_outside.png diff --git a/textures/mcl_hoppers_hopper_top.png b/textures/mcl_hoppers_hopper_top.png new file mode 100644 index 000000000..dbef0750b Binary files /dev/null and b/textures/mcl_hoppers_hopper_top.png differ diff --git a/mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_item.png b/textures/mcl_hoppers_item.png similarity index 100% rename from mods/ITEMS/mcl_hoppers/textures/mcl_hoppers_item.png rename to textures/mcl_hoppers_item.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_exhaustion.png b/textures/mcl_hunger_bar_exhaustion.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_exhaustion.png rename to textures/mcl_hunger_bar_exhaustion.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_foodpoison.png b/textures/mcl_hunger_bar_foodpoison.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_foodpoison.png rename to textures/mcl_hunger_bar_foodpoison.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_saturation.png b/textures/mcl_hunger_bar_saturation.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_bar_saturation.png rename to textures/mcl_hunger_bar_saturation.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_bgicon_exhaustion.png b/textures/mcl_hunger_bgicon_exhaustion.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_bgicon_exhaustion.png rename to textures/mcl_hunger_bgicon_exhaustion.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_bgicon_saturation.png b/textures/mcl_hunger_bgicon_saturation.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_bgicon_saturation.png rename to textures/mcl_hunger_bgicon_saturation.png diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_exhaustion.png b/textures/mcl_hunger_icon_exhaustion.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_exhaustion.png rename to textures/mcl_hunger_icon_exhaustion.png diff --git a/textures/mcl_hunger_icon_foodpoison.png b/textures/mcl_hunger_icon_foodpoison.png new file mode 100644 index 000000000..6d2408497 Binary files /dev/null and b/textures/mcl_hunger_icon_foodpoison.png differ diff --git a/mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_saturation.png b/textures/mcl_hunger_icon_saturation.png similarity index 100% rename from mods/PLAYER/mcl_hunger/textures/mcl_hunger_icon_saturation.png rename to textures/mcl_hunger_icon_saturation.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_button9.png b/textures/mcl_inventory_button9.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_button9.png rename to textures/mcl_inventory_button9.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_button9_pressed.png b/textures/mcl_inventory_button9_pressed.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_button9_pressed.png rename to textures/mcl_inventory_button9_pressed.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_boots.png b/textures/mcl_inventory_empty_armor_slot_boots.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_boots.png rename to textures/mcl_inventory_empty_armor_slot_boots.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_chestplate.png b/textures/mcl_inventory_empty_armor_slot_chestplate.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_chestplate.png rename to textures/mcl_inventory_empty_armor_slot_chestplate.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_helmet.png b/textures/mcl_inventory_empty_armor_slot_helmet.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_helmet.png rename to textures/mcl_inventory_empty_armor_slot_helmet.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_leggings.png b/textures/mcl_inventory_empty_armor_slot_leggings.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_leggings.png rename to textures/mcl_inventory_empty_armor_slot_leggings.png diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_shield.png b/textures/mcl_inventory_empty_armor_slot_shield.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_empty_armor_slot_shield.png rename to textures/mcl_inventory_empty_armor_slot_shield.png diff --git a/textures/mcl_inventory_hotbar.png b/textures/mcl_inventory_hotbar.png new file mode 100644 index 000000000..058f5da31 Binary files /dev/null and b/textures/mcl_inventory_hotbar.png differ diff --git a/mods/HUD/mcl_inventory/textures/mcl_inventory_hotbar_selected.png b/textures/mcl_inventory_hotbar_selected.png similarity index 100% rename from mods/HUD/mcl_inventory/textures/mcl_inventory_hotbar_selected.png rename to textures/mcl_inventory_hotbar_selected.png diff --git a/textures/mcl_itemframes_glow_item_frame.png b/textures/mcl_itemframes_glow_item_frame.png new file mode 100644 index 000000000..d87767dea Binary files /dev/null and b/textures/mcl_itemframes_glow_item_frame.png differ diff --git a/textures/mcl_itemframes_glow_item_frame_border.png b/textures/mcl_itemframes_glow_item_frame_border.png new file mode 100644 index 000000000..d87767dea Binary files /dev/null and b/textures/mcl_itemframes_glow_item_frame_border.png differ diff --git a/textures/mcl_itemframes_item_frame.png b/textures/mcl_itemframes_item_frame.png new file mode 100644 index 000000000..fad93a643 Binary files /dev/null and b/textures/mcl_itemframes_item_frame.png differ diff --git a/textures/mcl_itemframes_itemframe_background.png b/textures/mcl_itemframes_itemframe_background.png new file mode 100644 index 000000000..236f3630e Binary files /dev/null and b/textures/mcl_itemframes_itemframe_background.png differ diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_11.png b/textures/mcl_jukebox_record_11.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_11.png rename to textures/mcl_jukebox_record_11.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_13.png b/textures/mcl_jukebox_record_13.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_13.png rename to textures/mcl_jukebox_record_13.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_blocks.png b/textures/mcl_jukebox_record_blocks.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_blocks.png rename to textures/mcl_jukebox_record_blocks.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_cat.png b/textures/mcl_jukebox_record_cat.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_cat.png rename to textures/mcl_jukebox_record_cat.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_chirp.png b/textures/mcl_jukebox_record_chirp.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_chirp.png rename to textures/mcl_jukebox_record_chirp.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_far.png b/textures/mcl_jukebox_record_far.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_far.png rename to textures/mcl_jukebox_record_far.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_mall.png b/textures/mcl_jukebox_record_mall.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_mall.png rename to textures/mcl_jukebox_record_mall.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_mellohi.png b/textures/mcl_jukebox_record_mellohi.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_mellohi.png rename to textures/mcl_jukebox_record_mellohi.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_stal.png b/textures/mcl_jukebox_record_stal.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_stal.png rename to textures/mcl_jukebox_record_stal.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_strad.png b/textures/mcl_jukebox_record_strad.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_strad.png rename to textures/mcl_jukebox_record_strad.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_wait.png b/textures/mcl_jukebox_record_wait.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_wait.png rename to textures/mcl_jukebox_record_wait.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_ward.png b/textures/mcl_jukebox_record_ward.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_record_ward.png rename to textures/mcl_jukebox_record_ward.png diff --git a/mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_side.png b/textures/mcl_jukebox_side.png similarity index 100% rename from mods/ITEMS/mcl_jukebox/textures/mcl_jukebox_side.png rename to textures/mcl_jukebox_side.png diff --git a/textures/mcl_jukebox_top.png b/textures/mcl_jukebox_top.png new file mode 100644 index 000000000..2294972de Binary files /dev/null and b/textures/mcl_jukebox_top.png differ diff --git a/textures/mcl_lanterns_chain.png b/textures/mcl_lanterns_chain.png new file mode 100644 index 000000000..6d535148a Binary files /dev/null and b/textures/mcl_lanterns_chain.png differ diff --git a/textures/mcl_lanterns_chain_inv.png b/textures/mcl_lanterns_chain_inv.png new file mode 100644 index 000000000..bed58736e Binary files /dev/null and b/textures/mcl_lanterns_chain_inv.png differ diff --git a/textures/mcl_lanterns_lantern.png b/textures/mcl_lanterns_lantern.png new file mode 100644 index 000000000..172add092 Binary files /dev/null and b/textures/mcl_lanterns_lantern.png differ diff --git a/textures/mcl_lanterns_lantern_inv.png b/textures/mcl_lanterns_lantern_inv.png new file mode 100644 index 000000000..ac4c41db5 Binary files /dev/null and b/textures/mcl_lanterns_lantern_inv.png differ diff --git a/textures/mcl_lanterns_soul_lantern.png b/textures/mcl_lanterns_soul_lantern.png new file mode 100644 index 000000000..0085d7b28 Binary files /dev/null and b/textures/mcl_lanterns_soul_lantern.png differ diff --git a/textures/mcl_lanterns_soul_lantern_inv.png b/textures/mcl_lanterns_soul_lantern_inv.png new file mode 100644 index 000000000..a7bb7b901 Binary files /dev/null and b/textures/mcl_lanterns_soul_lantern_inv.png differ diff --git a/textures/mcl_lectern_lectern.png b/textures/mcl_lectern_lectern.png new file mode 100644 index 000000000..236c414f8 Binary files /dev/null and b/textures/mcl_lectern_lectern.png differ diff --git a/textures/mcl_lightning_rods_rod.png b/textures/mcl_lightning_rods_rod.png new file mode 100644 index 000000000..355b2bd01 Binary files /dev/null and b/textures/mcl_lightning_rods_rod.png differ diff --git a/textures/mcl_mangrove_door_bottom.png b/textures/mcl_mangrove_door_bottom.png new file mode 100644 index 000000000..a6b9182d7 Binary files /dev/null and b/textures/mcl_mangrove_door_bottom.png differ diff --git a/textures/mcl_mangrove_door_bottom_bottompart.png b/textures/mcl_mangrove_door_bottom_bottompart.png new file mode 100644 index 000000000..508be22a8 Binary files /dev/null and b/textures/mcl_mangrove_door_bottom_bottompart.png differ diff --git a/textures/mcl_mangrove_door_bottom_side.png b/textures/mcl_mangrove_door_bottom_side.png new file mode 100644 index 000000000..d5de6fbd1 Binary files /dev/null and b/textures/mcl_mangrove_door_bottom_side.png differ diff --git a/textures/mcl_mangrove_door_top.png b/textures/mcl_mangrove_door_top.png new file mode 100644 index 000000000..d7068ba18 Binary files /dev/null and b/textures/mcl_mangrove_door_top.png differ diff --git a/textures/mcl_mangrove_door_top_side.png b/textures/mcl_mangrove_door_top_side.png new file mode 100644 index 000000000..df586adf6 Binary files /dev/null and b/textures/mcl_mangrove_door_top_side.png differ diff --git a/textures/mcl_mangrove_door_top_toppart.png b/textures/mcl_mangrove_door_top_toppart.png new file mode 100644 index 000000000..95a9d1f0c Binary files /dev/null and b/textures/mcl_mangrove_door_top_toppart.png differ diff --git a/textures/mcl_mangrove_doors.png b/textures/mcl_mangrove_doors.png new file mode 100644 index 000000000..d23a74ab1 Binary files /dev/null and b/textures/mcl_mangrove_doors.png differ diff --git a/textures/mcl_mangrove_fence.png b/textures/mcl_mangrove_fence.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/textures/mcl_mangrove_fence.png differ diff --git a/textures/mcl_mangrove_fence_gate.png b/textures/mcl_mangrove_fence_gate.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/textures/mcl_mangrove_fence_gate.png differ diff --git a/textures/mcl_mangrove_leaves.png b/textures/mcl_mangrove_leaves.png new file mode 100644 index 000000000..9cb09f9a2 Binary files /dev/null and b/textures/mcl_mangrove_leaves.png differ diff --git a/textures/mcl_mangrove_log.png b/textures/mcl_mangrove_log.png new file mode 100644 index 000000000..fdbc0e949 Binary files /dev/null and b/textures/mcl_mangrove_log.png differ diff --git a/textures/mcl_mangrove_log_top.png b/textures/mcl_mangrove_log_top.png new file mode 100644 index 000000000..aa8906485 Binary files /dev/null and b/textures/mcl_mangrove_log_top.png differ diff --git a/textures/mcl_mangrove_planks.png b/textures/mcl_mangrove_planks.png new file mode 100644 index 000000000..47943496f Binary files /dev/null and b/textures/mcl_mangrove_planks.png differ diff --git a/textures/mcl_mangrove_propagule.png b/textures/mcl_mangrove_propagule.png new file mode 100644 index 000000000..f2f67dbdc Binary files /dev/null and b/textures/mcl_mangrove_propagule.png differ diff --git a/textures/mcl_mangrove_propagule_hanging.png b/textures/mcl_mangrove_propagule_hanging.png new file mode 100644 index 000000000..25c603021 Binary files /dev/null and b/textures/mcl_mangrove_propagule_hanging.png differ diff --git a/textures/mcl_mangrove_propagule_item.png b/textures/mcl_mangrove_propagule_item.png new file mode 100644 index 000000000..a6bb0233c Binary files /dev/null and b/textures/mcl_mangrove_propagule_item.png differ diff --git a/textures/mcl_mangrove_roots_side.png b/textures/mcl_mangrove_roots_side.png new file mode 100644 index 000000000..3115e6c29 Binary files /dev/null and b/textures/mcl_mangrove_roots_side.png differ diff --git a/textures/mcl_mangrove_roots_top.png b/textures/mcl_mangrove_roots_top.png new file mode 100644 index 000000000..8ed132253 Binary files /dev/null and b/textures/mcl_mangrove_roots_top.png differ diff --git a/textures/mcl_mangrove_trapdoor.png b/textures/mcl_mangrove_trapdoor.png new file mode 100644 index 000000000..ea50c5a5f Binary files /dev/null and b/textures/mcl_mangrove_trapdoor.png differ diff --git a/textures/mcl_maps_map_background.png b/textures/mcl_maps_map_background.png new file mode 100644 index 000000000..85f97240e Binary files /dev/null and b/textures/mcl_maps_map_background.png differ diff --git a/mods/ITEMS/mcl_maps/textures/mcl_maps_map_empty.png b/textures/mcl_maps_map_empty.png similarity index 100% rename from mods/ITEMS/mcl_maps/textures/mcl_maps_map_empty.png rename to textures/mcl_maps_map_empty.png diff --git a/mods/ITEMS/mcl_maps/textures/mcl_maps_map_filled.png b/textures/mcl_maps_map_filled.png similarity index 100% rename from mods/ITEMS/mcl_maps/textures/mcl_maps_map_filled.png rename to textures/mcl_maps_map_filled.png diff --git a/mods/ITEMS/mcl_maps/textures/mcl_maps_map_filled_markings.png b/textures/mcl_maps_map_filled_markings.png similarity index 100% rename from mods/ITEMS/mcl_maps/textures/mcl_maps_map_filled_markings.png rename to textures/mcl_maps_map_filled_markings.png diff --git a/textures/mcl_maps_player_arrow.png b/textures/mcl_maps_player_arrow.png new file mode 100644 index 000000000..e13a45b1a Binary files /dev/null and b/textures/mcl_maps_player_arrow.png differ diff --git a/textures/mcl_maps_player_dot.png b/textures/mcl_maps_player_dot.png new file mode 100644 index 000000000..7901d87e4 Binary files /dev/null and b/textures/mcl_maps_player_dot.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart.png b/textures/mcl_minecarts_minecart.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart.png rename to textures/mcl_minecarts_minecart.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_chest.png b/textures/mcl_minecarts_minecart_chest.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_chest.png rename to textures/mcl_minecarts_minecart_chest.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_command_block.png b/textures/mcl_minecarts_minecart_command_block.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_command_block.png rename to textures/mcl_minecarts_minecart_command_block.png diff --git a/textures/mcl_minecarts_minecart_furnace.png b/textures/mcl_minecarts_minecart_furnace.png new file mode 100644 index 000000000..71aec1c7c Binary files /dev/null and b/textures/mcl_minecarts_minecart_furnace.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_hopper.png b/textures/mcl_minecarts_minecart_hopper.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_hopper.png rename to textures/mcl_minecarts_minecart_hopper.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_normal.png b/textures/mcl_minecarts_minecart_normal.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_normal.png rename to textures/mcl_minecarts_minecart_normal.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_tnt.png b/textures/mcl_minecarts_minecart_tnt.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_minecart_tnt.png rename to textures/mcl_minecarts_minecart_tnt.png diff --git a/textures/mcl_minecarts_rail_activator.png b/textures/mcl_minecarts_rail_activator.png new file mode 100644 index 000000000..c318e757b Binary files /dev/null and b/textures/mcl_minecarts_rail_activator.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_crossing.png b/textures/mcl_minecarts_rail_activator_crossing.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_crossing.png rename to textures/mcl_minecarts_rail_activator_crossing.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_crossing_powered.png b/textures/mcl_minecarts_rail_activator_crossing_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_crossing_powered.png rename to textures/mcl_minecarts_rail_activator_crossing_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_curved.png b/textures/mcl_minecarts_rail_activator_curved.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_curved.png rename to textures/mcl_minecarts_rail_activator_curved.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_curved_powered.png b/textures/mcl_minecarts_rail_activator_curved_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_curved_powered.png rename to textures/mcl_minecarts_rail_activator_curved_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_powered.png b/textures/mcl_minecarts_rail_activator_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_powered.png rename to textures/mcl_minecarts_rail_activator_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_t_junction.png b/textures/mcl_minecarts_rail_activator_t_junction.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_t_junction.png rename to textures/mcl_minecarts_rail_activator_t_junction.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_t_junction_powered.png b/textures/mcl_minecarts_rail_activator_t_junction_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_activator_t_junction_powered.png rename to textures/mcl_minecarts_rail_activator_t_junction_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector.png b/textures/mcl_minecarts_rail_detector.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector.png rename to textures/mcl_minecarts_rail_detector.png diff --git a/textures/mcl_minecarts_rail_detector_crossing.png b/textures/mcl_minecarts_rail_detector_crossing.png new file mode 100644 index 000000000..57c729259 Binary files /dev/null and b/textures/mcl_minecarts_rail_detector_crossing.png differ diff --git a/textures/mcl_minecarts_rail_detector_crossing_powered.png b/textures/mcl_minecarts_rail_detector_crossing_powered.png new file mode 100644 index 000000000..c0b8490e8 Binary files /dev/null and b/textures/mcl_minecarts_rail_detector_crossing_powered.png differ diff --git a/textures/mcl_minecarts_rail_detector_curved.png b/textures/mcl_minecarts_rail_detector_curved.png new file mode 100644 index 000000000..cb7c10575 Binary files /dev/null and b/textures/mcl_minecarts_rail_detector_curved.png differ diff --git a/textures/mcl_minecarts_rail_detector_curved_powered.png b/textures/mcl_minecarts_rail_detector_curved_powered.png new file mode 100644 index 000000000..8ee6ce3b3 Binary files /dev/null and b/textures/mcl_minecarts_rail_detector_curved_powered.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_powered.png b/textures/mcl_minecarts_rail_detector_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_powered.png rename to textures/mcl_minecarts_rail_detector_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_t_junction.png b/textures/mcl_minecarts_rail_detector_t_junction.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_t_junction.png rename to textures/mcl_minecarts_rail_detector_t_junction.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_t_junction_powered.png b/textures/mcl_minecarts_rail_detector_t_junction_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_detector_t_junction_powered.png rename to textures/mcl_minecarts_rail_detector_t_junction_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden.png b/textures/mcl_minecarts_rail_golden.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden.png rename to textures/mcl_minecarts_rail_golden.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_crossing.png b/textures/mcl_minecarts_rail_golden_crossing.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_crossing.png rename to textures/mcl_minecarts_rail_golden_crossing.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_crossing_powered.png b/textures/mcl_minecarts_rail_golden_crossing_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_crossing_powered.png rename to textures/mcl_minecarts_rail_golden_crossing_powered.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_curved.png b/textures/mcl_minecarts_rail_golden_curved.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_curved.png rename to textures/mcl_minecarts_rail_golden_curved.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_curved_powered.png b/textures/mcl_minecarts_rail_golden_curved_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_curved_powered.png rename to textures/mcl_minecarts_rail_golden_curved_powered.png diff --git a/textures/mcl_minecarts_rail_golden_powered.png b/textures/mcl_minecarts_rail_golden_powered.png new file mode 100644 index 000000000..5277e24ec Binary files /dev/null and b/textures/mcl_minecarts_rail_golden_powered.png differ diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_t_junction.png b/textures/mcl_minecarts_rail_golden_t_junction.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_t_junction.png rename to textures/mcl_minecarts_rail_golden_t_junction.png diff --git a/mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_t_junction_powered.png b/textures/mcl_minecarts_rail_golden_t_junction_powered.png similarity index 100% rename from mods/ENTITIES/mcl_minecarts/textures/mcl_minecarts_rail_golden_t_junction_powered.png rename to textures/mcl_minecarts_rail_golden_t_junction_powered.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_beef_cooked.png b/textures/mcl_mobitems_beef_cooked.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_beef_cooked.png rename to textures/mcl_mobitems_beef_cooked.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_beef_raw.png b/textures/mcl_mobitems_beef_raw.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_beef_raw.png rename to textures/mcl_mobitems_beef_raw.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_blaze_powder.png b/textures/mcl_mobitems_blaze_powder.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_blaze_powder.png rename to textures/mcl_mobitems_blaze_powder.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_blaze_rod.png b/textures/mcl_mobitems_blaze_rod.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_blaze_rod.png rename to textures/mcl_mobitems_blaze_rod.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_bone.png b/textures/mcl_mobitems_bone.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_bone.png rename to textures/mcl_mobitems_bone.png diff --git a/textures/mcl_mobitems_bucket_milk.png b/textures/mcl_mobitems_bucket_milk.png new file mode 100644 index 000000000..249fc1a9e Binary files /dev/null and b/textures/mcl_mobitems_bucket_milk.png differ diff --git a/textures/mcl_mobitems_carrot_on_a_stick.png b/textures/mcl_mobitems_carrot_on_a_stick.png new file mode 100644 index 000000000..8fa01c753 Binary files /dev/null and b/textures/mcl_mobitems_carrot_on_a_stick.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_chicken_cooked.png b/textures/mcl_mobitems_chicken_cooked.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_chicken_cooked.png rename to textures/mcl_mobitems_chicken_cooked.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_chicken_raw.png b/textures/mcl_mobitems_chicken_raw.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_chicken_raw.png rename to textures/mcl_mobitems_chicken_raw.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_diamond_horse_armor.png b/textures/mcl_mobitems_diamond_horse_armor.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_diamond_horse_armor.png rename to textures/mcl_mobitems_diamond_horse_armor.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_feather.png b/textures/mcl_mobitems_feather.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_feather.png rename to textures/mcl_mobitems_feather.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_ghast_tear.png b/textures/mcl_mobitems_ghast_tear.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_ghast_tear.png rename to textures/mcl_mobitems_ghast_tear.png diff --git a/textures/mcl_mobitems_glow_ink_sac.png b/textures/mcl_mobitems_glow_ink_sac.png new file mode 100644 index 000000000..410984179 Binary files /dev/null and b/textures/mcl_mobitems_glow_ink_sac.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_gold_horse_armor.png b/textures/mcl_mobitems_gold_horse_armor.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_gold_horse_armor.png rename to textures/mcl_mobitems_gold_horse_armor.png diff --git a/textures/mcl_mobitems_heart_of_the_sea.png b/textures/mcl_mobitems_heart_of_the_sea.png new file mode 100644 index 000000000..b550c84ae Binary files /dev/null and b/textures/mcl_mobitems_heart_of_the_sea.png differ diff --git a/textures/mcl_mobitems_heart_of_the_sea_split.png b/textures/mcl_mobitems_heart_of_the_sea_split.png new file mode 100644 index 000000000..b76bd6a6d Binary files /dev/null and b/textures/mcl_mobitems_heart_of_the_sea_split.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_diamond.png b/textures/mcl_mobitems_horse_armor_diamond.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_diamond.png rename to textures/mcl_mobitems_horse_armor_diamond.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_gold.png b/textures/mcl_mobitems_horse_armor_gold.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_gold.png rename to textures/mcl_mobitems_horse_armor_gold.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_iron.png b/textures/mcl_mobitems_horse_armor_iron.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_armor_iron.png rename to textures/mcl_mobitems_horse_armor_iron.png diff --git a/textures/mcl_mobitems_ink_sac.png b/textures/mcl_mobitems_ink_sac.png new file mode 100644 index 000000000..e9aebf595 Binary files /dev/null and b/textures/mcl_mobitems_ink_sac.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_iron_horse_armor.png b/textures/mcl_mobitems_iron_horse_armor.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_iron_horse_armor.png rename to textures/mcl_mobitems_iron_horse_armor.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_leather.png b/textures/mcl_mobitems_leather.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_leather.png rename to textures/mcl_mobitems_leather.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_magma_cream.png b/textures/mcl_mobitems_magma_cream.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_magma_cream.png rename to textures/mcl_mobitems_magma_cream.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_mutton_cooked.png b/textures/mcl_mobitems_mutton_cooked.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_mutton_cooked.png rename to textures/mcl_mobitems_mutton_cooked.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_mutton_raw.png b/textures/mcl_mobitems_mutton_raw.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_mutton_raw.png rename to textures/mcl_mobitems_mutton_raw.png diff --git a/textures/mcl_mobitems_nautilus_shell.png b/textures/mcl_mobitems_nautilus_shell.png new file mode 100644 index 000000000..1185fab2e Binary files /dev/null and b/textures/mcl_mobitems_nautilus_shell.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_nether_star.png b/textures/mcl_mobitems_nether_star.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_nether_star.png rename to textures/mcl_mobitems_nether_star.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_porkchop_cooked.png b/textures/mcl_mobitems_porkchop_cooked.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_porkchop_cooked.png rename to textures/mcl_mobitems_porkchop_cooked.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_porkchop_raw.png b/textures/mcl_mobitems_porkchop_raw.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_porkchop_raw.png rename to textures/mcl_mobitems_porkchop_raw.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_cooked.png b/textures/mcl_mobitems_rabbit_cooked.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_cooked.png rename to textures/mcl_mobitems_rabbit_cooked.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_foot.png b/textures/mcl_mobitems_rabbit_foot.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_foot.png rename to textures/mcl_mobitems_rabbit_foot.png diff --git a/textures/mcl_mobitems_rabbit_hide.png b/textures/mcl_mobitems_rabbit_hide.png new file mode 100644 index 000000000..e36cad4d8 Binary files /dev/null and b/textures/mcl_mobitems_rabbit_hide.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_raw.png b/textures/mcl_mobitems_rabbit_raw.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_raw.png rename to textures/mcl_mobitems_rabbit_raw.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_stew.png b/textures/mcl_mobitems_rabbit_stew.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rabbit_stew.png rename to textures/mcl_mobitems_rabbit_stew.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rotten_flesh.png b/textures/mcl_mobitems_rotten_flesh.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_rotten_flesh.png rename to textures/mcl_mobitems_rotten_flesh.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_saddle.png b/textures/mcl_mobitems_saddle.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_saddle.png rename to textures/mcl_mobitems_saddle.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_shulker_shell.png b/textures/mcl_mobitems_shulker_shell.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_shulker_shell.png rename to textures/mcl_mobitems_shulker_shell.png diff --git a/textures/mcl_mobitems_slimeball.png b/textures/mcl_mobitems_slimeball.png new file mode 100644 index 000000000..1dd8a6cb6 Binary files /dev/null and b/textures/mcl_mobitems_slimeball.png differ diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_spider_eye.png b/textures/mcl_mobitems_spider_eye.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_spider_eye.png rename to textures/mcl_mobitems_spider_eye.png diff --git a/mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_string.png b/textures/mcl_mobitems_string.png similarity index 100% rename from mods/ITEMS/mcl_mobitems/textures/mcl_mobitems_string.png rename to textures/mcl_mobitems_string.png diff --git a/textures/mcl_mobitems_warped_fungus_on_a_stick.png b/textures/mcl_mobitems_warped_fungus_on_a_stick.png new file mode 100644 index 000000000..ddfa97091 Binary files /dev/null and b/textures/mcl_mobitems_warped_fungus_on_a_stick.png differ diff --git a/mods/ENVIRONMENT/mcl_moon/textures/mcl_moon_moon_phases.png b/textures/mcl_moon_moon_phases.png similarity index 100% rename from mods/ENVIRONMENT/mcl_moon/textures/mcl_moon_moon_phases.png rename to textures/mcl_moon_moon_phases.png diff --git a/textures/mcl_mud.png b/textures/mcl_mud.png new file mode 100644 index 000000000..827258b38 Binary files /dev/null and b/textures/mcl_mud.png differ diff --git a/textures/mcl_mud_bricks.png b/textures/mcl_mud_bricks.png new file mode 100644 index 000000000..38e483852 Binary files /dev/null and b/textures/mcl_mud_bricks.png differ diff --git a/textures/mcl_mud_packed_mud.png b/textures/mcl_mud_packed_mud.png new file mode 100644 index 000000000..864d6e663 Binary files /dev/null and b/textures/mcl_mud_packed_mud.png differ diff --git a/textures/mcl_mushrooms_mushroom_block_inside.png b/textures/mcl_mushrooms_mushroom_block_inside.png new file mode 100644 index 000000000..ccbad3d15 Binary files /dev/null and b/textures/mcl_mushrooms_mushroom_block_inside.png differ diff --git a/textures/mcl_mushrooms_mushroom_block_skin_brown.png b/textures/mcl_mushrooms_mushroom_block_skin_brown.png new file mode 100644 index 000000000..9ce7af38d Binary files /dev/null and b/textures/mcl_mushrooms_mushroom_block_skin_brown.png differ diff --git a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_red.png b/textures/mcl_mushrooms_mushroom_block_skin_red.png similarity index 100% rename from mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_red.png rename to textures/mcl_mushrooms_mushroom_block_skin_red.png diff --git a/mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_stem.png b/textures/mcl_mushrooms_mushroom_block_skin_stem.png similarity index 100% rename from mods/ITEMS/mcl_mushrooms/textures/mcl_mushrooms_mushroom_block_skin_stem.png rename to textures/mcl_mushrooms_mushroom_block_skin_stem.png diff --git a/textures/mcl_nether_ancient_debris_side.png b/textures/mcl_nether_ancient_debris_side.png new file mode 100644 index 000000000..fbe84c4de Binary files /dev/null and b/textures/mcl_nether_ancient_debris_side.png differ diff --git a/textures/mcl_nether_ancient_debris_top.png b/textures/mcl_nether_ancient_debris_top.png new file mode 100644 index 000000000..fbe84c4de Binary files /dev/null and b/textures/mcl_nether_ancient_debris_top.png differ diff --git a/textures/mcl_nether_glowstone.png b/textures/mcl_nether_glowstone.png new file mode 100644 index 000000000..43b1979ed Binary files /dev/null and b/textures/mcl_nether_glowstone.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_glowstone_dust.png b/textures/mcl_nether_glowstone_dust.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_glowstone_dust.png rename to textures/mcl_nether_glowstone_dust.png diff --git a/textures/mcl_nether_gold_ore.png b/textures/mcl_nether_gold_ore.png new file mode 100644 index 000000000..105be900d Binary files /dev/null and b/textures/mcl_nether_gold_ore.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_magma.png b/textures/mcl_nether_magma.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_magma.png rename to textures/mcl_nether_magma.png diff --git a/textures/mcl_nether_nether_brick.png b/textures/mcl_nether_nether_brick.png new file mode 100644 index 000000000..665183237 Binary files /dev/null and b/textures/mcl_nether_nether_brick.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart.png b/textures/mcl_nether_nether_wart.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart.png rename to textures/mcl_nether_nether_wart.png diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_block.png b/textures/mcl_nether_nether_wart_block.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_block.png rename to textures/mcl_nether_nether_wart_block.png diff --git a/textures/mcl_nether_nether_wart_block_blue.png b/textures/mcl_nether_nether_wart_block_blue.png new file mode 100644 index 000000000..5974d2c42 Binary files /dev/null and b/textures/mcl_nether_nether_wart_block_blue.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_0.png b/textures/mcl_nether_nether_wart_stage_0.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_0.png rename to textures/mcl_nether_nether_wart_stage_0.png diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_1.png b/textures/mcl_nether_nether_wart_stage_1.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_nether_wart_stage_1.png rename to textures/mcl_nether_nether_wart_stage_1.png diff --git a/textures/mcl_nether_nether_wart_stage_2.png b/textures/mcl_nether_nether_wart_stage_2.png new file mode 100644 index 000000000..75747835d Binary files /dev/null and b/textures/mcl_nether_nether_wart_stage_2.png differ diff --git a/textures/mcl_nether_netherbrick.png b/textures/mcl_nether_netherbrick.png new file mode 100644 index 000000000..ce2960924 Binary files /dev/null and b/textures/mcl_nether_netherbrick.png differ diff --git a/textures/mcl_nether_netherite_ingot.png b/textures/mcl_nether_netherite_ingot.png new file mode 100644 index 000000000..f576b16ca Binary files /dev/null and b/textures/mcl_nether_netherite_ingot.png differ diff --git a/textures/mcl_nether_netherite_scrap.png b/textures/mcl_nether_netherite_scrap.png new file mode 100644 index 000000000..16da8b048 Binary files /dev/null and b/textures/mcl_nether_netherite_scrap.png differ diff --git a/textures/mcl_nether_netheriteblock.png b/textures/mcl_nether_netheriteblock.png new file mode 100644 index 000000000..8f59390fb Binary files /dev/null and b/textures/mcl_nether_netheriteblock.png differ diff --git a/textures/mcl_nether_netherrack.png b/textures/mcl_nether_netherrack.png new file mode 100644 index 000000000..ead9c8c8c Binary files /dev/null and b/textures/mcl_nether_netherrack.png differ diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz.png b/textures/mcl_nether_quartz.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_quartz.png rename to textures/mcl_nether_quartz.png diff --git a/mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_bottom.png b/textures/mcl_nether_quartz_block_bottom.png similarity index 100% rename from mods/ITEMS/mcl_nether/textures/mcl_nether_quartz_block_bottom.png rename to textures/mcl_nether_quartz_block_bottom.png diff --git a/textures/mcl_nether_quartz_block_side.png b/textures/mcl_nether_quartz_block_side.png new file mode 100644 index 000000000..0d960c567 Binary files /dev/null and b/textures/mcl_nether_quartz_block_side.png differ diff --git a/textures/mcl_nether_quartz_block_top.png b/textures/mcl_nether_quartz_block_top.png new file mode 100644 index 000000000..0d960c567 Binary files /dev/null and b/textures/mcl_nether_quartz_block_top.png differ diff --git a/textures/mcl_nether_quartz_chiseled_side.png b/textures/mcl_nether_quartz_chiseled_side.png new file mode 100644 index 000000000..85c29266e Binary files /dev/null and b/textures/mcl_nether_quartz_chiseled_side.png differ diff --git a/textures/mcl_nether_quartz_chiseled_top.png b/textures/mcl_nether_quartz_chiseled_top.png new file mode 100644 index 000000000..086a2a66f Binary files /dev/null and b/textures/mcl_nether_quartz_chiseled_top.png differ diff --git a/textures/mcl_nether_quartz_ore.png b/textures/mcl_nether_quartz_ore.png new file mode 100644 index 000000000..487316e25 Binary files /dev/null and b/textures/mcl_nether_quartz_ore.png differ diff --git a/textures/mcl_nether_quartz_pillar_side.png b/textures/mcl_nether_quartz_pillar_side.png new file mode 100644 index 000000000..73478f1fb Binary files /dev/null and b/textures/mcl_nether_quartz_pillar_side.png differ diff --git a/textures/mcl_nether_quartz_pillar_top.png b/textures/mcl_nether_quartz_pillar_top.png new file mode 100644 index 000000000..e85c01228 Binary files /dev/null and b/textures/mcl_nether_quartz_pillar_top.png differ diff --git a/textures/mcl_nether_red_nether_brick.png b/textures/mcl_nether_red_nether_brick.png new file mode 100644 index 000000000..7248b2100 Binary files /dev/null and b/textures/mcl_nether_red_nether_brick.png differ diff --git a/textures/mcl_nether_soul_sand.png b/textures/mcl_nether_soul_sand.png new file mode 100644 index 000000000..1aab30695 Binary files /dev/null and b/textures/mcl_nether_soul_sand.png differ diff --git a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_back.png b/textures/mcl_observers_observer_back.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_back.png rename to textures/mcl_observers_observer_back.png diff --git a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_back_lit.png b/textures/mcl_observers_observer_back_lit.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_back_lit.png rename to textures/mcl_observers_observer_back_lit.png diff --git a/mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_front.png b/textures/mcl_observers_observer_front.png similarity index 100% rename from mods/ITEMS/REDSTONE/mcl_observers/textures/mcl_observers_observer_front.png rename to textures/mcl_observers_observer_front.png diff --git a/textures/mcl_observers_observer_side.png b/textures/mcl_observers_observer_side.png new file mode 100644 index 000000000..46b7b007b Binary files /dev/null and b/textures/mcl_observers_observer_side.png differ diff --git a/textures/mcl_observers_observer_top.png b/textures/mcl_observers_observer_top.png new file mode 100644 index 000000000..a5dda380a Binary files /dev/null and b/textures/mcl_observers_observer_top.png differ diff --git a/textures/mcl_ocean_brain_coral.png b/textures/mcl_ocean_brain_coral.png new file mode 100644 index 000000000..4c1363bb4 Binary files /dev/null and b/textures/mcl_ocean_brain_coral.png differ diff --git a/textures/mcl_ocean_brain_coral_block.png b/textures/mcl_ocean_brain_coral_block.png new file mode 100644 index 000000000..80b5c5381 Binary files /dev/null and b/textures/mcl_ocean_brain_coral_block.png differ diff --git a/textures/mcl_ocean_brain_coral_fan.png b/textures/mcl_ocean_brain_coral_fan.png new file mode 100644 index 000000000..eaf5388b5 Binary files /dev/null and b/textures/mcl_ocean_brain_coral_fan.png differ diff --git a/textures/mcl_ocean_bubble_coral.png b/textures/mcl_ocean_bubble_coral.png new file mode 100644 index 000000000..4de2e1d73 Binary files /dev/null and b/textures/mcl_ocean_bubble_coral.png differ diff --git a/textures/mcl_ocean_bubble_coral_block.png b/textures/mcl_ocean_bubble_coral_block.png new file mode 100644 index 000000000..7ed97df4b Binary files /dev/null and b/textures/mcl_ocean_bubble_coral_block.png differ diff --git a/textures/mcl_ocean_bubble_coral_fan.png b/textures/mcl_ocean_bubble_coral_fan.png new file mode 100644 index 000000000..f5284375f Binary files /dev/null and b/textures/mcl_ocean_bubble_coral_fan.png differ diff --git a/textures/mcl_ocean_dead_brain_coral.png b/textures/mcl_ocean_dead_brain_coral.png new file mode 100644 index 000000000..91003b825 Binary files /dev/null and b/textures/mcl_ocean_dead_brain_coral.png differ diff --git a/textures/mcl_ocean_dead_brain_coral_block.png b/textures/mcl_ocean_dead_brain_coral_block.png new file mode 100644 index 000000000..5f9ef162c Binary files /dev/null and b/textures/mcl_ocean_dead_brain_coral_block.png differ diff --git a/textures/mcl_ocean_dead_brain_coral_fan.png b/textures/mcl_ocean_dead_brain_coral_fan.png new file mode 100644 index 000000000..26958f8ad Binary files /dev/null and b/textures/mcl_ocean_dead_brain_coral_fan.png differ diff --git a/textures/mcl_ocean_dead_bubble_coral.png b/textures/mcl_ocean_dead_bubble_coral.png new file mode 100644 index 000000000..2418b3ac1 Binary files /dev/null and b/textures/mcl_ocean_dead_bubble_coral.png differ diff --git a/textures/mcl_ocean_dead_bubble_coral_block.png b/textures/mcl_ocean_dead_bubble_coral_block.png new file mode 100644 index 000000000..853bf1f76 Binary files /dev/null and b/textures/mcl_ocean_dead_bubble_coral_block.png differ diff --git a/textures/mcl_ocean_dead_bubble_coral_fan.png b/textures/mcl_ocean_dead_bubble_coral_fan.png new file mode 100644 index 000000000..78626fd3a Binary files /dev/null and b/textures/mcl_ocean_dead_bubble_coral_fan.png differ diff --git a/textures/mcl_ocean_dead_fire_coral.png b/textures/mcl_ocean_dead_fire_coral.png new file mode 100644 index 000000000..b5e0dcf14 Binary files /dev/null and b/textures/mcl_ocean_dead_fire_coral.png differ diff --git a/textures/mcl_ocean_dead_fire_coral_block.png b/textures/mcl_ocean_dead_fire_coral_block.png new file mode 100644 index 000000000..5d0d0b092 Binary files /dev/null and b/textures/mcl_ocean_dead_fire_coral_block.png differ diff --git a/textures/mcl_ocean_dead_fire_coral_fan.png b/textures/mcl_ocean_dead_fire_coral_fan.png new file mode 100644 index 000000000..edbf7a741 Binary files /dev/null and b/textures/mcl_ocean_dead_fire_coral_fan.png differ diff --git a/textures/mcl_ocean_dead_horn_coral.png b/textures/mcl_ocean_dead_horn_coral.png new file mode 100644 index 000000000..14270ea25 Binary files /dev/null and b/textures/mcl_ocean_dead_horn_coral.png differ diff --git a/textures/mcl_ocean_dead_horn_coral_block.png b/textures/mcl_ocean_dead_horn_coral_block.png new file mode 100644 index 000000000..dc897330d Binary files /dev/null and b/textures/mcl_ocean_dead_horn_coral_block.png differ diff --git a/textures/mcl_ocean_dead_horn_coral_fan.png b/textures/mcl_ocean_dead_horn_coral_fan.png new file mode 100644 index 000000000..2bb59125b Binary files /dev/null and b/textures/mcl_ocean_dead_horn_coral_fan.png differ diff --git a/textures/mcl_ocean_dead_tube_coral.png b/textures/mcl_ocean_dead_tube_coral.png new file mode 100644 index 000000000..b99ea16a7 Binary files /dev/null and b/textures/mcl_ocean_dead_tube_coral.png differ diff --git a/textures/mcl_ocean_dead_tube_coral_block.png b/textures/mcl_ocean_dead_tube_coral_block.png new file mode 100644 index 000000000..0a919313c Binary files /dev/null and b/textures/mcl_ocean_dead_tube_coral_block.png differ diff --git a/textures/mcl_ocean_dead_tube_coral_fan.png b/textures/mcl_ocean_dead_tube_coral_fan.png new file mode 100644 index 000000000..d16c44ed0 Binary files /dev/null and b/textures/mcl_ocean_dead_tube_coral_fan.png differ diff --git a/textures/mcl_ocean_dried_kelp.png b/textures/mcl_ocean_dried_kelp.png new file mode 100644 index 000000000..683e903f5 Binary files /dev/null and b/textures/mcl_ocean_dried_kelp.png differ diff --git a/textures/mcl_ocean_dried_kelp_bottom.png b/textures/mcl_ocean_dried_kelp_bottom.png new file mode 100644 index 000000000..aa645462a Binary files /dev/null and b/textures/mcl_ocean_dried_kelp_bottom.png differ diff --git a/textures/mcl_ocean_dried_kelp_side.png b/textures/mcl_ocean_dried_kelp_side.png new file mode 100644 index 000000000..6d369bada Binary files /dev/null and b/textures/mcl_ocean_dried_kelp_side.png differ diff --git a/textures/mcl_ocean_dried_kelp_top.png b/textures/mcl_ocean_dried_kelp_top.png new file mode 100644 index 000000000..aa645462a Binary files /dev/null and b/textures/mcl_ocean_dried_kelp_top.png differ diff --git a/textures/mcl_ocean_fire_coral.png b/textures/mcl_ocean_fire_coral.png new file mode 100644 index 000000000..bfb0c7ded Binary files /dev/null and b/textures/mcl_ocean_fire_coral.png differ diff --git a/textures/mcl_ocean_fire_coral_block.png b/textures/mcl_ocean_fire_coral_block.png new file mode 100644 index 000000000..512261c78 Binary files /dev/null and b/textures/mcl_ocean_fire_coral_block.png differ diff --git a/textures/mcl_ocean_fire_coral_fan.png b/textures/mcl_ocean_fire_coral_fan.png new file mode 100644 index 000000000..e644dab7d Binary files /dev/null and b/textures/mcl_ocean_fire_coral_fan.png differ diff --git a/textures/mcl_ocean_horn_coral.png b/textures/mcl_ocean_horn_coral.png new file mode 100644 index 000000000..81b26b639 Binary files /dev/null and b/textures/mcl_ocean_horn_coral.png differ diff --git a/textures/mcl_ocean_horn_coral_block.png b/textures/mcl_ocean_horn_coral_block.png new file mode 100644 index 000000000..127145223 Binary files /dev/null and b/textures/mcl_ocean_horn_coral_block.png differ diff --git a/textures/mcl_ocean_horn_coral_fan.png b/textures/mcl_ocean_horn_coral_fan.png new file mode 100644 index 000000000..761f590cd Binary files /dev/null and b/textures/mcl_ocean_horn_coral_fan.png differ diff --git a/textures/mcl_ocean_kelp_item.png b/textures/mcl_ocean_kelp_item.png new file mode 100644 index 000000000..f6c942c3b Binary files /dev/null and b/textures/mcl_ocean_kelp_item.png differ diff --git a/textures/mcl_ocean_kelp_plant.png b/textures/mcl_ocean_kelp_plant.png new file mode 100644 index 000000000..2f810e080 Binary files /dev/null and b/textures/mcl_ocean_kelp_plant.png differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_anim.png b/textures/mcl_ocean_prismarine_anim.png similarity index 100% rename from mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_anim.png rename to textures/mcl_ocean_prismarine_anim.png diff --git a/textures/mcl_ocean_prismarine_bricks.png b/textures/mcl_ocean_prismarine_bricks.png new file mode 100644 index 000000000..26ba85c7b Binary files /dev/null and b/textures/mcl_ocean_prismarine_bricks.png differ diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_crystals.png b/textures/mcl_ocean_prismarine_crystals.png similarity index 100% rename from mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_crystals.png rename to textures/mcl_ocean_prismarine_crystals.png diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_dark.png b/textures/mcl_ocean_prismarine_dark.png similarity index 100% rename from mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_dark.png rename to textures/mcl_ocean_prismarine_dark.png diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_shard.png b/textures/mcl_ocean_prismarine_shard.png similarity index 100% rename from mods/ITEMS/mcl_ocean/textures/mcl_ocean_prismarine_shard.png rename to textures/mcl_ocean_prismarine_shard.png diff --git a/mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_lantern.png b/textures/mcl_ocean_sea_lantern.png similarity index 100% rename from mods/ITEMS/mcl_ocean/textures/mcl_ocean_sea_lantern.png rename to textures/mcl_ocean_sea_lantern.png diff --git a/textures/mcl_ocean_sea_pickle_1_anim.png b/textures/mcl_ocean_sea_pickle_1_anim.png new file mode 100644 index 000000000..715640baf Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_1_anim.png differ diff --git a/textures/mcl_ocean_sea_pickle_1_off.png b/textures/mcl_ocean_sea_pickle_1_off.png new file mode 100644 index 000000000..8dc110b8a Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_1_off.png differ diff --git a/textures/mcl_ocean_sea_pickle_2_anim.png b/textures/mcl_ocean_sea_pickle_2_anim.png new file mode 100644 index 000000000..32916257b Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_2_anim.png differ diff --git a/textures/mcl_ocean_sea_pickle_2_off.png b/textures/mcl_ocean_sea_pickle_2_off.png new file mode 100644 index 000000000..97a292874 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_2_off.png differ diff --git a/textures/mcl_ocean_sea_pickle_3_anim.png b/textures/mcl_ocean_sea_pickle_3_anim.png new file mode 100644 index 000000000..31fcdb4f5 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_3_anim.png differ diff --git a/textures/mcl_ocean_sea_pickle_3_off.png b/textures/mcl_ocean_sea_pickle_3_off.png new file mode 100644 index 000000000..0fa6d6587 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_3_off.png differ diff --git a/textures/mcl_ocean_sea_pickle_4_anim.png b/textures/mcl_ocean_sea_pickle_4_anim.png new file mode 100644 index 000000000..6e36864b0 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_4_anim.png differ diff --git a/textures/mcl_ocean_sea_pickle_4_off.png b/textures/mcl_ocean_sea_pickle_4_off.png new file mode 100644 index 000000000..3c7746881 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_4_off.png differ diff --git a/textures/mcl_ocean_sea_pickle_item.png b/textures/mcl_ocean_sea_pickle_item.png new file mode 100644 index 000000000..d9ce86739 Binary files /dev/null and b/textures/mcl_ocean_sea_pickle_item.png differ diff --git a/textures/mcl_ocean_seagrass.png b/textures/mcl_ocean_seagrass.png new file mode 100644 index 000000000..da9c30664 Binary files /dev/null and b/textures/mcl_ocean_seagrass.png differ diff --git a/textures/mcl_ocean_seagrass_item.png b/textures/mcl_ocean_seagrass_item.png new file mode 100644 index 000000000..462bf9cbd Binary files /dev/null and b/textures/mcl_ocean_seagrass_item.png differ diff --git a/textures/mcl_ocean_tube_coral.png b/textures/mcl_ocean_tube_coral.png new file mode 100644 index 000000000..eb63d85b6 Binary files /dev/null and b/textures/mcl_ocean_tube_coral.png differ diff --git a/textures/mcl_ocean_tube_coral_block.png b/textures/mcl_ocean_tube_coral_block.png new file mode 100644 index 000000000..dd152b242 Binary files /dev/null and b/textures/mcl_ocean_tube_coral_block.png differ diff --git a/textures/mcl_ocean_tube_coral_fan.png b/textures/mcl_ocean_tube_coral_fan.png new file mode 100644 index 000000000..b10f365d3 Binary files /dev/null and b/textures/mcl_ocean_tube_coral_fan.png differ diff --git a/textures/mcl_offhand_slot.png b/textures/mcl_offhand_slot.png new file mode 100644 index 000000000..310d2ad58 Binary files /dev/null and b/textures/mcl_offhand_slot.png differ diff --git a/textures/mcl_paintings_painting.png b/textures/mcl_paintings_painting.png new file mode 100644 index 000000000..5a29f4efb Binary files /dev/null and b/textures/mcl_paintings_painting.png differ diff --git a/mods/ENTITIES/mcl_paintings/textures/mcl_paintings_paintings.png b/textures/mcl_paintings_paintings.png similarity index 100% rename from mods/ENTITIES/mcl_paintings/textures/mcl_paintings_paintings.png rename to textures/mcl_paintings_paintings.png diff --git a/textures/mcl_particles_bonemeal.png b/textures/mcl_particles_bonemeal.png new file mode 100644 index 000000000..4f8a966fc Binary files /dev/null and b/textures/mcl_particles_bonemeal.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_bubble.png b/textures/mcl_particles_bubble.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_bubble.png rename to textures/mcl_particles_bubble.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_crit.png b/textures/mcl_particles_crit.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_crit.png rename to textures/mcl_particles_crit.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_droplet_bottle.png b/textures/mcl_particles_droplet_bottle.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_droplet_bottle.png rename to textures/mcl_particles_droplet_bottle.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_effect.png b/textures/mcl_particles_effect.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_effect.png rename to textures/mcl_particles_effect.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_flame.png b/textures/mcl_particles_flame.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_flame.png rename to textures/mcl_particles_flame.png diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_instant_effect.png b/textures/mcl_particles_instant_effect.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_instant_effect.png rename to textures/mcl_particles_instant_effect.png diff --git a/textures/mcl_particles_lava.png b/textures/mcl_particles_lava.png new file mode 100644 index 000000000..a0fb99a13 Binary files /dev/null and b/textures/mcl_particles_lava.png differ diff --git a/textures/mcl_particles_mob_death.png b/textures/mcl_particles_mob_death.png new file mode 100644 index 000000000..eaca237e2 Binary files /dev/null and b/textures/mcl_particles_mob_death.png differ diff --git a/mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust1.png b/textures/mcl_particles_nether_dust1.png similarity index 100% rename from mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust1.png rename to textures/mcl_particles_nether_dust1.png diff --git a/mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust2.png b/textures/mcl_particles_nether_dust2.png similarity index 100% rename from mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust2.png rename to textures/mcl_particles_nether_dust2.png diff --git a/mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust3.png b/textures/mcl_particles_nether_dust3.png similarity index 100% rename from mods/ENVIRONMENT/mcl_weather/textures/mcl_particles_nether_dust3.png rename to textures/mcl_particles_nether_dust3.png diff --git a/mods/ITEMS/mcl_portals/textures/mcl_particles_nether_portal.png b/textures/mcl_particles_nether_portal.png similarity index 100% rename from mods/ITEMS/mcl_portals/textures/mcl_particles_nether_portal.png rename to textures/mcl_particles_nether_portal.png diff --git a/mods/ITEMS/mcl_portals/textures/mcl_particles_nether_portal_t.png b/textures/mcl_particles_nether_portal_t.png similarity index 100% rename from mods/ITEMS/mcl_portals/textures/mcl_particles_nether_portal_t.png rename to textures/mcl_particles_nether_portal_t.png diff --git a/textures/mcl_particles_note.png b/textures/mcl_particles_note.png new file mode 100644 index 000000000..4e2931768 Binary files /dev/null and b/textures/mcl_particles_note.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_smoke.png b/textures/mcl_particles_smoke.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_smoke.png rename to textures/mcl_particles_smoke.png diff --git a/textures/mcl_particles_smoke_anim.png b/textures/mcl_particles_smoke_anim.png new file mode 100644 index 000000000..76e116a2e Binary files /dev/null and b/textures/mcl_particles_smoke_anim.png differ diff --git a/textures/mcl_particles_soul_fire_flame.png b/textures/mcl_particles_soul_fire_flame.png new file mode 100644 index 000000000..94022a6c3 Binary files /dev/null and b/textures/mcl_particles_soul_fire_flame.png differ diff --git a/textures/mcl_particles_sponge1.png b/textures/mcl_particles_sponge1.png new file mode 100644 index 000000000..d8d6e55c4 Binary files /dev/null and b/textures/mcl_particles_sponge1.png differ diff --git a/textures/mcl_particles_sponge2.png b/textures/mcl_particles_sponge2.png new file mode 100644 index 000000000..95531a5af Binary files /dev/null and b/textures/mcl_particles_sponge2.png differ diff --git a/textures/mcl_particles_sponge3.png b/textures/mcl_particles_sponge3.png new file mode 100644 index 000000000..37f168b71 Binary files /dev/null and b/textures/mcl_particles_sponge3.png differ diff --git a/textures/mcl_particles_sponge4.png b/textures/mcl_particles_sponge4.png new file mode 100644 index 000000000..38c4b71a7 Binary files /dev/null and b/textures/mcl_particles_sponge4.png differ diff --git a/textures/mcl_particles_sponge5.png b/textures/mcl_particles_sponge5.png new file mode 100644 index 000000000..ad4784b3c Binary files /dev/null and b/textures/mcl_particles_sponge5.png differ diff --git a/mods/CORE/mcl_particles/textures/mcl_particles_teleport.png b/textures/mcl_particles_teleport.png similarity index 100% rename from mods/CORE/mcl_particles/textures/mcl_particles_teleport.png rename to textures/mcl_particles_teleport.png diff --git a/textures/mcl_particles_totem1.png b/textures/mcl_particles_totem1.png new file mode 100644 index 000000000..b1486ec47 Binary files /dev/null and b/textures/mcl_particles_totem1.png differ diff --git a/textures/mcl_particles_totem2.png b/textures/mcl_particles_totem2.png new file mode 100644 index 000000000..998f89d4d Binary files /dev/null and b/textures/mcl_particles_totem2.png differ diff --git a/textures/mcl_particles_totem3.png b/textures/mcl_particles_totem3.png new file mode 100644 index 000000000..7e9133817 Binary files /dev/null and b/textures/mcl_particles_totem3.png differ diff --git a/textures/mcl_particles_totem4.png b/textures/mcl_particles_totem4.png new file mode 100644 index 000000000..81ae7e5ac Binary files /dev/null and b/textures/mcl_particles_totem4.png differ diff --git a/mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_end_sky.png b/textures/mcl_playerplus_end_sky.png similarity index 100% rename from mods/PLAYER/mcl_playerplus/textures/mcl_playerplus_end_sky.png rename to textures/mcl_playerplus_end_sky.png diff --git a/textures/mcl_playerplus_water.png b/textures/mcl_playerplus_water.png new file mode 100644 index 000000000..577e24e87 Binary files /dev/null and b/textures/mcl_playerplus_water.png differ diff --git a/textures/mcl_polished_deepslate.png b/textures/mcl_polished_deepslate.png new file mode 100644 index 000000000..507b8195e Binary files /dev/null and b/textures/mcl_polished_deepslate.png differ diff --git a/textures/mcl_portals_end_portal.png b/textures/mcl_portals_end_portal.png new file mode 100644 index 000000000..1003beb31 Binary files /dev/null and b/textures/mcl_portals_end_portal.png differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_bottom.png b/textures/mcl_portals_endframe_bottom.png similarity index 100% rename from mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_bottom.png rename to textures/mcl_portals_endframe_bottom.png diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_eye.png b/textures/mcl_portals_endframe_eye.png similarity index 100% rename from mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_eye.png rename to textures/mcl_portals_endframe_eye.png diff --git a/textures/mcl_portals_endframe_side.png b/textures/mcl_portals_endframe_side.png new file mode 100644 index 000000000..6922795ed Binary files /dev/null and b/textures/mcl_portals_endframe_side.png differ diff --git a/mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_top.png b/textures/mcl_portals_endframe_top.png similarity index 100% rename from mods/ITEMS/mcl_portals/textures/mcl_portals_endframe_top.png rename to textures/mcl_portals_endframe_top.png diff --git a/textures/mcl_portals_particle1.png b/textures/mcl_portals_particle1.png new file mode 100644 index 000000000..e3b7b55c6 Binary files /dev/null and b/textures/mcl_portals_particle1.png differ diff --git a/textures/mcl_portals_particle2.png b/textures/mcl_portals_particle2.png new file mode 100644 index 000000000..52ee3b3c7 Binary files /dev/null and b/textures/mcl_portals_particle2.png differ diff --git a/textures/mcl_portals_particle3.png b/textures/mcl_portals_particle3.png new file mode 100644 index 000000000..e07d2492b Binary files /dev/null and b/textures/mcl_portals_particle3.png differ diff --git a/textures/mcl_portals_particle4.png b/textures/mcl_portals_particle4.png new file mode 100644 index 000000000..5a44d9ee1 Binary files /dev/null and b/textures/mcl_portals_particle4.png differ diff --git a/textures/mcl_portals_particle5.png b/textures/mcl_portals_particle5.png new file mode 100644 index 000000000..e2b4da97c Binary files /dev/null and b/textures/mcl_portals_particle5.png differ diff --git a/textures/mcl_portals_portal.png b/textures/mcl_portals_portal.png new file mode 100644 index 000000000..ca5a182df Binary files /dev/null and b/textures/mcl_portals_portal.png differ diff --git a/textures/mcl_potions_arrow_inv.png b/textures/mcl_potions_arrow_inv.png new file mode 100644 index 000000000..1f60971ca Binary files /dev/null and b/textures/mcl_potions_arrow_inv.png differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_dragon_breath.png b/textures/mcl_potions_dragon_breath.png similarity index 100% rename from mods/ITEMS/mcl_potions/textures/mcl_potions_dragon_breath.png rename to textures/mcl_potions_dragon_breath.png diff --git a/textures/mcl_potions_effect_bad_omen.png b/textures/mcl_potions_effect_bad_omen.png new file mode 100644 index 000000000..4293aed22 Binary files /dev/null and b/textures/mcl_potions_effect_bad_omen.png differ diff --git a/textures/mcl_potions_effect_fire_proof.png b/textures/mcl_potions_effect_fire_proof.png new file mode 100644 index 000000000..effbefaa4 Binary files /dev/null and b/textures/mcl_potions_effect_fire_proof.png differ diff --git a/textures/mcl_potions_effect_food_poisoning.png b/textures/mcl_potions_effect_food_poisoning.png new file mode 100644 index 000000000..f29be56a5 Binary files /dev/null and b/textures/mcl_potions_effect_food_poisoning.png differ diff --git a/textures/mcl_potions_effect_invisible.png b/textures/mcl_potions_effect_invisible.png new file mode 100644 index 000000000..db0afb575 Binary files /dev/null and b/textures/mcl_potions_effect_invisible.png differ diff --git a/textures/mcl_potions_effect_leaping.png b/textures/mcl_potions_effect_leaping.png new file mode 100644 index 000000000..8fbf25ae8 Binary files /dev/null and b/textures/mcl_potions_effect_leaping.png differ diff --git a/textures/mcl_potions_effect_night_vision.png b/textures/mcl_potions_effect_night_vision.png new file mode 100644 index 000000000..f4263968a Binary files /dev/null and b/textures/mcl_potions_effect_night_vision.png differ diff --git a/textures/mcl_potions_effect_poisoned.png b/textures/mcl_potions_effect_poisoned.png new file mode 100644 index 000000000..9d8cd5815 Binary files /dev/null and b/textures/mcl_potions_effect_poisoned.png differ diff --git a/textures/mcl_potions_effect_regenerating.png b/textures/mcl_potions_effect_regenerating.png new file mode 100644 index 000000000..dfb82bba9 Binary files /dev/null and b/textures/mcl_potions_effect_regenerating.png differ diff --git a/textures/mcl_potions_effect_slow.png b/textures/mcl_potions_effect_slow.png new file mode 100644 index 000000000..464d270a9 Binary files /dev/null and b/textures/mcl_potions_effect_slow.png differ diff --git a/textures/mcl_potions_effect_strong.png b/textures/mcl_potions_effect_strong.png new file mode 100644 index 000000000..515b5777a Binary files /dev/null and b/textures/mcl_potions_effect_strong.png differ diff --git a/textures/mcl_potions_effect_swift.png b/textures/mcl_potions_effect_swift.png new file mode 100644 index 000000000..cf9e4b95c Binary files /dev/null and b/textures/mcl_potions_effect_swift.png differ diff --git a/textures/mcl_potions_effect_water_breathing.png b/textures/mcl_potions_effect_water_breathing.png new file mode 100644 index 000000000..3ced75eba Binary files /dev/null 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 new file mode 100644 index 000000000..398c161ab Binary files /dev/null and b/textures/mcl_potions_effect_weak.png differ diff --git a/textures/mcl_potions_lingering_bottle.png b/textures/mcl_potions_lingering_bottle.png new file mode 100644 index 000000000..cd5e76564 Binary files /dev/null and b/textures/mcl_potions_lingering_bottle.png differ diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_melon_speckled.png b/textures/mcl_potions_melon_speckled.png similarity index 100% rename from mods/ITEMS/mcl_potions/textures/mcl_potions_melon_speckled.png rename to textures/mcl_potions_melon_speckled.png diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_potion_bottle.png b/textures/mcl_potions_potion_bottle.png similarity index 100% rename from mods/ITEMS/mcl_potions/textures/mcl_potions_potion_bottle.png rename to textures/mcl_potions_potion_bottle.png diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_potion_overlay.png b/textures/mcl_potions_potion_overlay.png similarity index 100% rename from mods/ITEMS/mcl_potions/textures/mcl_potions_potion_overlay.png rename to textures/mcl_potions_potion_overlay.png diff --git a/mods/ITEMS/mcl_potions/textures/mcl_potions_spider_eye_fermented.png b/textures/mcl_potions_spider_eye_fermented.png similarity index 100% rename from mods/ITEMS/mcl_potions/textures/mcl_potions_spider_eye_fermented.png rename to textures/mcl_potions_spider_eye_fermented.png diff --git a/textures/mcl_potions_splash_bottle.png b/textures/mcl_potions_splash_bottle.png new file mode 100644 index 000000000..5af0dc373 Binary files /dev/null and b/textures/mcl_potions_splash_bottle.png differ diff --git a/textures/mcl_potions_splash_overlay.png b/textures/mcl_potions_splash_overlay.png new file mode 100644 index 000000000..c3b5f317e Binary files /dev/null and b/textures/mcl_potions_splash_overlay.png differ diff --git a/textures/mcl_raids_hero_of_the_village_icon.png b/textures/mcl_raids_hero_of_the_village_icon.png new file mode 100644 index 000000000..d42dfb230 Binary files /dev/null and b/textures/mcl_raids_hero_of_the_village_icon.png differ diff --git a/textures/mcl_raw_ores_raw_gold.png b/textures/mcl_raw_ores_raw_gold.png new file mode 100644 index 000000000..d49405831 Binary files /dev/null and b/textures/mcl_raw_ores_raw_gold.png differ diff --git a/textures/mcl_raw_ores_raw_gold_block.png b/textures/mcl_raw_ores_raw_gold_block.png new file mode 100644 index 000000000..503e3f16e Binary files /dev/null and b/textures/mcl_raw_ores_raw_gold_block.png differ diff --git a/textures/mcl_raw_ores_raw_iron.png b/textures/mcl_raw_ores_raw_iron.png new file mode 100644 index 000000000..36641148b Binary files /dev/null and b/textures/mcl_raw_ores_raw_iron.png differ diff --git a/textures/mcl_raw_ores_raw_iron_block.png b/textures/mcl_raw_ores_raw_iron_block.png new file mode 100644 index 000000000..35b29a018 Binary files /dev/null and b/textures/mcl_raw_ores_raw_iron_block.png differ diff --git a/textures/mcl_sculk_catalyst_bottom.png b/textures/mcl_sculk_catalyst_bottom.png new file mode 100644 index 000000000..94981fcb9 Binary files /dev/null and b/textures/mcl_sculk_catalyst_bottom.png differ diff --git a/textures/mcl_sculk_catalyst_side.png b/textures/mcl_sculk_catalyst_side.png new file mode 100644 index 000000000..0828267e5 Binary files /dev/null and b/textures/mcl_sculk_catalyst_side.png differ diff --git a/textures/mcl_sculk_catalyst_top.png b/textures/mcl_sculk_catalyst_top.png new file mode 100644 index 000000000..eeebcac5d Binary files /dev/null and b/textures/mcl_sculk_catalyst_top.png differ diff --git a/textures/mcl_sculk_sculk.png b/textures/mcl_sculk_sculk.png new file mode 100644 index 000000000..593c63c7e Binary files /dev/null and b/textures/mcl_sculk_sculk.png differ diff --git a/textures/mcl_sculk_sensor_bottom.png b/textures/mcl_sculk_sensor_bottom.png new file mode 100644 index 000000000..eeebcac5d Binary files /dev/null and b/textures/mcl_sculk_sensor_bottom.png differ diff --git a/textures/mcl_sculk_sensor_side.png b/textures/mcl_sculk_sensor_side.png new file mode 100644 index 000000000..ef22f9af5 Binary files /dev/null and b/textures/mcl_sculk_sensor_side.png differ diff --git a/textures/mcl_sculk_sensor_top.png b/textures/mcl_sculk_sensor_top.png new file mode 100644 index 000000000..4da71770d Binary files /dev/null and b/textures/mcl_sculk_sensor_top.png differ diff --git a/textures/mcl_sculk_shrieker_bottom.png b/textures/mcl_sculk_shrieker_bottom.png new file mode 100644 index 000000000..eeebcac5d Binary files /dev/null and b/textures/mcl_sculk_shrieker_bottom.png differ diff --git a/textures/mcl_sculk_shrieker_side.png b/textures/mcl_sculk_shrieker_side.png new file mode 100644 index 000000000..83e60da5c Binary files /dev/null and b/textures/mcl_sculk_shrieker_side.png differ diff --git a/textures/mcl_sculk_shrieker_top.png b/textures/mcl_sculk_shrieker_top.png new file mode 100644 index 000000000..7c0125663 Binary files /dev/null and b/textures/mcl_sculk_shrieker_top.png differ diff --git a/textures/mcl_sculk_vein.png b/textures/mcl_sculk_vein.png new file mode 100644 index 000000000..ebfa49cc8 Binary files /dev/null and b/textures/mcl_sculk_vein.png differ diff --git a/textures/mcl_shield.png b/textures/mcl_shield.png new file mode 100644 index 000000000..2fd057d5a Binary files /dev/null and b/textures/mcl_shield.png differ diff --git a/textures/mcl_shield_base_nopattern.png b/textures/mcl_shield_base_nopattern.png new file mode 100644 index 000000000..febfb4b5a Binary files /dev/null and b/textures/mcl_shield_base_nopattern.png differ diff --git a/textures/mcl_shield_hud.png b/textures/mcl_shield_hud.png new file mode 100644 index 000000000..f3ec407d0 Binary files /dev/null and b/textures/mcl_shield_hud.png differ diff --git a/textures/mcl_shield_item_overlay.png b/textures/mcl_shield_item_overlay.png new file mode 100644 index 000000000..a83f574fd Binary files /dev/null and b/textures/mcl_shield_item_overlay.png differ diff --git a/textures/mcl_shield_pattern_base.png b/textures/mcl_shield_pattern_base.png new file mode 100644 index 000000000..d3cfab8c0 Binary files /dev/null and b/textures/mcl_shield_pattern_base.png differ diff --git a/textures/mcl_shield_pattern_border.png b/textures/mcl_shield_pattern_border.png new file mode 100644 index 000000000..ae382bcdb Binary files /dev/null and b/textures/mcl_shield_pattern_border.png differ diff --git a/textures/mcl_shield_pattern_bricks.png b/textures/mcl_shield_pattern_bricks.png new file mode 100644 index 000000000..3acba57ab Binary files /dev/null and b/textures/mcl_shield_pattern_bricks.png differ diff --git a/textures/mcl_shield_pattern_circle.png b/textures/mcl_shield_pattern_circle.png new file mode 100644 index 000000000..07a483ae7 Binary files /dev/null and b/textures/mcl_shield_pattern_circle.png differ diff --git a/textures/mcl_shield_pattern_creeper.png b/textures/mcl_shield_pattern_creeper.png new file mode 100644 index 000000000..7fb573b61 Binary files /dev/null and b/textures/mcl_shield_pattern_creeper.png differ diff --git a/textures/mcl_shield_pattern_cross.png b/textures/mcl_shield_pattern_cross.png new file mode 100644 index 000000000..0aca4dacf Binary files /dev/null and b/textures/mcl_shield_pattern_cross.png differ diff --git a/textures/mcl_shield_pattern_curly_border.png b/textures/mcl_shield_pattern_curly_border.png new file mode 100644 index 000000000..4cd9b778b Binary files /dev/null and b/textures/mcl_shield_pattern_curly_border.png differ diff --git a/textures/mcl_shield_pattern_diagonal_left.png b/textures/mcl_shield_pattern_diagonal_left.png new file mode 100644 index 000000000..f41cfe1bf Binary files /dev/null and b/textures/mcl_shield_pattern_diagonal_left.png differ diff --git a/textures/mcl_shield_pattern_diagonal_right.png b/textures/mcl_shield_pattern_diagonal_right.png new file mode 100644 index 000000000..d906a82fe Binary files /dev/null and b/textures/mcl_shield_pattern_diagonal_right.png differ diff --git a/textures/mcl_shield_pattern_diagonal_up_left.png b/textures/mcl_shield_pattern_diagonal_up_left.png new file mode 100644 index 000000000..0b4830838 Binary files /dev/null and b/textures/mcl_shield_pattern_diagonal_up_left.png differ diff --git a/textures/mcl_shield_pattern_diagonal_up_right.png b/textures/mcl_shield_pattern_diagonal_up_right.png new file mode 100644 index 000000000..7883d821c Binary files /dev/null and b/textures/mcl_shield_pattern_diagonal_up_right.png differ diff --git a/textures/mcl_shield_pattern_flower.png b/textures/mcl_shield_pattern_flower.png new file mode 100644 index 000000000..dc6e5db31 Binary files /dev/null and b/textures/mcl_shield_pattern_flower.png differ diff --git a/textures/mcl_shield_pattern_gradient.png b/textures/mcl_shield_pattern_gradient.png new file mode 100644 index 000000000..bf8094ce4 Binary files /dev/null and b/textures/mcl_shield_pattern_gradient.png differ diff --git a/textures/mcl_shield_pattern_gradient_up.png b/textures/mcl_shield_pattern_gradient_up.png new file mode 100644 index 000000000..c974ad7a1 Binary files /dev/null and b/textures/mcl_shield_pattern_gradient_up.png differ diff --git a/textures/mcl_shield_pattern_half_horizontal.png b/textures/mcl_shield_pattern_half_horizontal.png new file mode 100644 index 000000000..adacc8f28 Binary files /dev/null and b/textures/mcl_shield_pattern_half_horizontal.png differ diff --git a/textures/mcl_shield_pattern_half_horizontal_bottom.png b/textures/mcl_shield_pattern_half_horizontal_bottom.png new file mode 100644 index 000000000..292b401b1 Binary files /dev/null and b/textures/mcl_shield_pattern_half_horizontal_bottom.png differ diff --git a/textures/mcl_shield_pattern_half_vertical.png b/textures/mcl_shield_pattern_half_vertical.png new file mode 100644 index 000000000..f6092d450 Binary files /dev/null and b/textures/mcl_shield_pattern_half_vertical.png differ diff --git a/textures/mcl_shield_pattern_half_vertical_right.png b/textures/mcl_shield_pattern_half_vertical_right.png new file mode 100644 index 000000000..111e0a300 Binary files /dev/null and b/textures/mcl_shield_pattern_half_vertical_right.png differ diff --git a/textures/mcl_shield_pattern_rhombus.png b/textures/mcl_shield_pattern_rhombus.png new file mode 100644 index 000000000..732eb6ecd Binary files /dev/null and b/textures/mcl_shield_pattern_rhombus.png differ diff --git a/textures/mcl_shield_pattern_skull.png b/textures/mcl_shield_pattern_skull.png new file mode 100644 index 000000000..f7f6362e9 Binary files /dev/null and b/textures/mcl_shield_pattern_skull.png differ diff --git a/textures/mcl_shield_pattern_small_stripes.png b/textures/mcl_shield_pattern_small_stripes.png new file mode 100644 index 000000000..c7a2a8ab1 Binary files /dev/null and b/textures/mcl_shield_pattern_small_stripes.png differ diff --git a/textures/mcl_shield_pattern_square_bottom_left.png b/textures/mcl_shield_pattern_square_bottom_left.png new file mode 100644 index 000000000..644c991c9 Binary files /dev/null and b/textures/mcl_shield_pattern_square_bottom_left.png differ diff --git a/textures/mcl_shield_pattern_square_bottom_right.png b/textures/mcl_shield_pattern_square_bottom_right.png new file mode 100644 index 000000000..cad96247e Binary files /dev/null and b/textures/mcl_shield_pattern_square_bottom_right.png differ diff --git a/textures/mcl_shield_pattern_square_top_left.png b/textures/mcl_shield_pattern_square_top_left.png new file mode 100644 index 000000000..dcfcbcc21 Binary files /dev/null and b/textures/mcl_shield_pattern_square_top_left.png differ diff --git a/textures/mcl_shield_pattern_square_top_right.png b/textures/mcl_shield_pattern_square_top_right.png new file mode 100644 index 000000000..7cfd3470f Binary files /dev/null and b/textures/mcl_shield_pattern_square_top_right.png differ diff --git a/textures/mcl_shield_pattern_straight_cross.png b/textures/mcl_shield_pattern_straight_cross.png new file mode 100644 index 000000000..8cb195c0f Binary files /dev/null and b/textures/mcl_shield_pattern_straight_cross.png differ diff --git a/textures/mcl_shield_pattern_stripe_bottom.png b/textures/mcl_shield_pattern_stripe_bottom.png new file mode 100644 index 000000000..c9dd28d0d Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_bottom.png differ diff --git a/textures/mcl_shield_pattern_stripe_center.png b/textures/mcl_shield_pattern_stripe_center.png new file mode 100644 index 000000000..f716f3532 Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_center.png differ diff --git a/textures/mcl_shield_pattern_stripe_downleft.png b/textures/mcl_shield_pattern_stripe_downleft.png new file mode 100644 index 000000000..31095bfed Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_downleft.png differ diff --git a/textures/mcl_shield_pattern_stripe_downright.png b/textures/mcl_shield_pattern_stripe_downright.png new file mode 100644 index 000000000..cb35cf8c5 Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_downright.png differ diff --git a/textures/mcl_shield_pattern_stripe_left.png b/textures/mcl_shield_pattern_stripe_left.png new file mode 100644 index 000000000..7f183effb Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_left.png differ diff --git a/textures/mcl_shield_pattern_stripe_middle.png b/textures/mcl_shield_pattern_stripe_middle.png new file mode 100644 index 000000000..3da72340a Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_middle.png differ diff --git a/textures/mcl_shield_pattern_stripe_right.png b/textures/mcl_shield_pattern_stripe_right.png new file mode 100644 index 000000000..19f8c6ea3 Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_right.png differ diff --git a/textures/mcl_shield_pattern_stripe_top.png b/textures/mcl_shield_pattern_stripe_top.png new file mode 100644 index 000000000..2bef3467f Binary files /dev/null and b/textures/mcl_shield_pattern_stripe_top.png differ diff --git a/textures/mcl_shield_pattern_thing.png b/textures/mcl_shield_pattern_thing.png new file mode 100644 index 000000000..5eb26a74d Binary files /dev/null and b/textures/mcl_shield_pattern_thing.png differ diff --git a/textures/mcl_shield_pattern_triangle_bottom.png b/textures/mcl_shield_pattern_triangle_bottom.png new file mode 100644 index 000000000..b78139fd1 Binary files /dev/null and b/textures/mcl_shield_pattern_triangle_bottom.png differ diff --git a/textures/mcl_shield_pattern_triangle_top.png b/textures/mcl_shield_pattern_triangle_top.png new file mode 100644 index 000000000..f6e1cb2ec Binary files /dev/null and b/textures/mcl_shield_pattern_triangle_top.png differ diff --git a/textures/mcl_shield_pattern_triangles_bottom.png b/textures/mcl_shield_pattern_triangles_bottom.png new file mode 100644 index 000000000..12c432057 Binary files /dev/null and b/textures/mcl_shield_pattern_triangles_bottom.png differ diff --git a/textures/mcl_shield_pattern_triangles_top.png b/textures/mcl_shield_pattern_triangles_top.png new file mode 100644 index 000000000..4d210007e Binary files /dev/null and b/textures/mcl_shield_pattern_triangles_top.png differ diff --git a/textures/mcl_signs_default_sign.png b/textures/mcl_signs_default_sign.png new file mode 100644 index 000000000..5acd7d10b Binary files /dev/null and b/textures/mcl_signs_default_sign.png differ diff --git a/textures/mcl_signs_default_sign_dark.png b/textures/mcl_signs_default_sign_dark.png new file mode 100644 index 000000000..b0726f839 Binary files /dev/null and b/textures/mcl_signs_default_sign_dark.png differ diff --git a/textures/mcl_signs_default_sign_greyscale.png b/textures/mcl_signs_default_sign_greyscale.png new file mode 100644 index 000000000..e76d6378c Binary files /dev/null and b/textures/mcl_signs_default_sign_greyscale.png differ diff --git a/mods/ITEMS/mcl_signs/textures/mcl_signs_sign.png b/textures/mcl_signs_sign.png similarity index 100% rename from mods/ITEMS/mcl_signs/textures/mcl_signs_sign.png rename to textures/mcl_signs_sign.png diff --git a/textures/mcl_signs_sign_dark.png b/textures/mcl_signs_sign_dark.png new file mode 100644 index 000000000..5f835390c Binary files /dev/null and b/textures/mcl_signs_sign_dark.png differ diff --git a/textures/mcl_signs_sign_greyscale.png b/textures/mcl_signs_sign_greyscale.png new file mode 100644 index 000000000..2c902dad6 Binary files /dev/null and b/textures/mcl_signs_sign_greyscale.png differ diff --git a/textures/mcl_skins_arrow.png b/textures/mcl_skins_arrow.png new file mode 100644 index 000000000..ea839ed4e Binary files /dev/null and b/textures/mcl_skins_arrow.png differ diff --git a/textures/mcl_skins_base_1.png b/textures/mcl_skins_base_1.png new file mode 100644 index 000000000..4cbc682f2 Binary files /dev/null and b/textures/mcl_skins_base_1.png differ diff --git a/textures/mcl_skins_base_1_mask.png b/textures/mcl_skins_base_1_mask.png new file mode 100644 index 000000000..21b0e8ce0 Binary files /dev/null and b/textures/mcl_skins_base_1_mask.png differ diff --git a/textures/mcl_skins_bottom_1.png b/textures/mcl_skins_bottom_1.png new file mode 100644 index 000000000..ebe25c356 Binary files /dev/null and b/textures/mcl_skins_bottom_1.png differ diff --git a/textures/mcl_skins_bottom_1_mask.png b/textures/mcl_skins_bottom_1_mask.png new file mode 100644 index 000000000..b26699db9 Binary files /dev/null and b/textures/mcl_skins_bottom_1_mask.png differ diff --git a/textures/mcl_skins_bottom_2.png b/textures/mcl_skins_bottom_2.png new file mode 100644 index 000000000..b9cd79874 Binary files /dev/null and b/textures/mcl_skins_bottom_2.png differ diff --git a/textures/mcl_skins_bottom_2_mask.png b/textures/mcl_skins_bottom_2_mask.png new file mode 100644 index 000000000..351e2dd85 Binary files /dev/null and b/textures/mcl_skins_bottom_2_mask.png differ diff --git a/textures/mcl_skins_bottom_3.png b/textures/mcl_skins_bottom_3.png new file mode 100644 index 000000000..01e7c0714 Binary files /dev/null and b/textures/mcl_skins_bottom_3.png differ diff --git a/textures/mcl_skins_bottom_3_mask.png b/textures/mcl_skins_bottom_3_mask.png new file mode 100644 index 000000000..fa5214ef9 Binary files /dev/null and b/textures/mcl_skins_bottom_3_mask.png differ diff --git a/textures/mcl_skins_bottom_4.png b/textures/mcl_skins_bottom_4.png new file mode 100644 index 000000000..ded9f4991 Binary files /dev/null and b/textures/mcl_skins_bottom_4.png differ diff --git a/textures/mcl_skins_bottom_4_mask.png b/textures/mcl_skins_bottom_4_mask.png new file mode 100644 index 000000000..b26699db9 Binary files /dev/null and b/textures/mcl_skins_bottom_4_mask.png differ diff --git a/textures/mcl_skins_bottom_5.png b/textures/mcl_skins_bottom_5.png new file mode 100644 index 000000000..0cb44293f Binary files /dev/null and b/textures/mcl_skins_bottom_5.png differ diff --git a/textures/mcl_skins_bottom_5_mask.png b/textures/mcl_skins_bottom_5_mask.png new file mode 100644 index 000000000..284cdba2c Binary files /dev/null and b/textures/mcl_skins_bottom_5_mask.png differ diff --git a/textures/mcl_skins_button.png b/textures/mcl_skins_button.png new file mode 100644 index 000000000..d46cf9f38 Binary files /dev/null and b/textures/mcl_skins_button.png differ diff --git a/textures/mcl_skins_character_1.png b/textures/mcl_skins_character_1.png new file mode 100644 index 000000000..4c3d334f4 Binary files /dev/null and b/textures/mcl_skins_character_1.png differ diff --git a/textures/mcl_skins_eye_1.png b/textures/mcl_skins_eye_1.png new file mode 100644 index 000000000..49caef689 Binary files /dev/null and b/textures/mcl_skins_eye_1.png differ diff --git a/textures/mcl_skins_eye_2.png b/textures/mcl_skins_eye_2.png new file mode 100644 index 000000000..6928ae533 Binary files /dev/null and b/textures/mcl_skins_eye_2.png differ diff --git a/textures/mcl_skins_eye_3.png b/textures/mcl_skins_eye_3.png new file mode 100644 index 000000000..efde92ad4 Binary files /dev/null and b/textures/mcl_skins_eye_3.png differ diff --git a/textures/mcl_skins_eye_4.png b/textures/mcl_skins_eye_4.png new file mode 100644 index 000000000..42f3f201a Binary files /dev/null and b/textures/mcl_skins_eye_4.png differ diff --git a/textures/mcl_skins_eye_5.png b/textures/mcl_skins_eye_5.png new file mode 100644 index 000000000..dfb7d45e1 Binary files /dev/null and b/textures/mcl_skins_eye_5.png differ diff --git a/textures/mcl_skins_eye_6.png b/textures/mcl_skins_eye_6.png new file mode 100644 index 000000000..318f30772 Binary files /dev/null and b/textures/mcl_skins_eye_6.png differ diff --git a/textures/mcl_skins_eye_7.png b/textures/mcl_skins_eye_7.png new file mode 100644 index 000000000..d92f57fd5 Binary files /dev/null and b/textures/mcl_skins_eye_7.png differ diff --git a/textures/mcl_skins_footwear_1.png b/textures/mcl_skins_footwear_1.png new file mode 100644 index 000000000..ffe92a423 Binary files /dev/null and b/textures/mcl_skins_footwear_1.png differ diff --git a/textures/mcl_skins_footwear_2.png b/textures/mcl_skins_footwear_2.png new file mode 100644 index 000000000..2b3a00a56 Binary files /dev/null and b/textures/mcl_skins_footwear_2.png differ diff --git a/textures/mcl_skins_footwear_3.png b/textures/mcl_skins_footwear_3.png new file mode 100644 index 000000000..69b48fcaf Binary files /dev/null and b/textures/mcl_skins_footwear_3.png differ diff --git a/textures/mcl_skins_hair_1.png b/textures/mcl_skins_hair_1.png new file mode 100644 index 000000000..f3a18c8d6 Binary files /dev/null and b/textures/mcl_skins_hair_1.png differ diff --git a/textures/mcl_skins_hair_10.png b/textures/mcl_skins_hair_10.png new file mode 100644 index 000000000..6d8ea14cc Binary files /dev/null and b/textures/mcl_skins_hair_10.png differ diff --git a/textures/mcl_skins_hair_10_mask.png b/textures/mcl_skins_hair_10_mask.png new file mode 100644 index 000000000..4bfda1913 Binary files /dev/null and b/textures/mcl_skins_hair_10_mask.png differ diff --git a/textures/mcl_skins_hair_11.png b/textures/mcl_skins_hair_11.png new file mode 100644 index 000000000..5d38bd62e Binary files /dev/null and b/textures/mcl_skins_hair_11.png differ diff --git a/textures/mcl_skins_hair_11_mask.png b/textures/mcl_skins_hair_11_mask.png new file mode 100644 index 000000000..4cf0e1f11 Binary files /dev/null and b/textures/mcl_skins_hair_11_mask.png differ diff --git a/textures/mcl_skins_hair_1_mask.png b/textures/mcl_skins_hair_1_mask.png new file mode 100644 index 000000000..2d87b36fa Binary files /dev/null and b/textures/mcl_skins_hair_1_mask.png differ diff --git a/textures/mcl_skins_hair_2.png b/textures/mcl_skins_hair_2.png new file mode 100644 index 000000000..226fad553 Binary files /dev/null and b/textures/mcl_skins_hair_2.png differ diff --git a/textures/mcl_skins_hair_2_mask.png b/textures/mcl_skins_hair_2_mask.png new file mode 100644 index 000000000..407524b17 Binary files /dev/null and b/textures/mcl_skins_hair_2_mask.png differ diff --git a/textures/mcl_skins_hair_3.png b/textures/mcl_skins_hair_3.png new file mode 100644 index 000000000..67dffa9de Binary files /dev/null and b/textures/mcl_skins_hair_3.png differ diff --git a/textures/mcl_skins_hair_3_mask.png b/textures/mcl_skins_hair_3_mask.png new file mode 100644 index 000000000..3c379b3fb Binary files /dev/null and b/textures/mcl_skins_hair_3_mask.png differ diff --git a/textures/mcl_skins_hair_4.png b/textures/mcl_skins_hair_4.png new file mode 100644 index 000000000..b268e1a96 Binary files /dev/null and b/textures/mcl_skins_hair_4.png differ diff --git a/textures/mcl_skins_hair_4_mask.png b/textures/mcl_skins_hair_4_mask.png new file mode 100644 index 000000000..39b50ad25 Binary files /dev/null and b/textures/mcl_skins_hair_4_mask.png differ diff --git a/textures/mcl_skins_hair_5.png b/textures/mcl_skins_hair_5.png new file mode 100644 index 000000000..fdee2689e Binary files /dev/null and b/textures/mcl_skins_hair_5.png differ diff --git a/textures/mcl_skins_hair_5_mask.png b/textures/mcl_skins_hair_5_mask.png new file mode 100644 index 000000000..f85bed492 Binary files /dev/null and b/textures/mcl_skins_hair_5_mask.png differ diff --git a/textures/mcl_skins_hair_6.png b/textures/mcl_skins_hair_6.png new file mode 100644 index 000000000..7e2382dbc Binary files /dev/null and b/textures/mcl_skins_hair_6.png differ diff --git a/textures/mcl_skins_hair_6_mask.png b/textures/mcl_skins_hair_6_mask.png new file mode 100644 index 000000000..cb8bcb735 Binary files /dev/null and b/textures/mcl_skins_hair_6_mask.png differ diff --git a/textures/mcl_skins_hair_7.png b/textures/mcl_skins_hair_7.png new file mode 100644 index 000000000..fefaaa3ee Binary files /dev/null and b/textures/mcl_skins_hair_7.png differ diff --git a/textures/mcl_skins_hair_7_mask.png b/textures/mcl_skins_hair_7_mask.png new file mode 100644 index 000000000..df7c8e8b2 Binary files /dev/null and b/textures/mcl_skins_hair_7_mask.png differ diff --git a/textures/mcl_skins_hair_8.png b/textures/mcl_skins_hair_8.png new file mode 100644 index 000000000..498621a36 Binary files /dev/null and b/textures/mcl_skins_hair_8.png differ diff --git a/textures/mcl_skins_hair_8_mask.png b/textures/mcl_skins_hair_8_mask.png new file mode 100644 index 000000000..5b9c0b8a6 Binary files /dev/null and b/textures/mcl_skins_hair_8_mask.png differ diff --git a/textures/mcl_skins_hair_9.png b/textures/mcl_skins_hair_9.png new file mode 100644 index 000000000..83083bd61 Binary files /dev/null and b/textures/mcl_skins_hair_9.png differ diff --git a/textures/mcl_skins_hair_9_mask.png b/textures/mcl_skins_hair_9_mask.png new file mode 100644 index 000000000..52f43b1c8 Binary files /dev/null and b/textures/mcl_skins_hair_9_mask.png differ diff --git a/textures/mcl_skins_headwear_1.png b/textures/mcl_skins_headwear_1.png new file mode 100644 index 000000000..7323a6ce6 Binary files /dev/null and b/textures/mcl_skins_headwear_1.png differ diff --git a/textures/mcl_skins_headwear_2.png b/textures/mcl_skins_headwear_2.png new file mode 100644 index 000000000..060a3ad3f Binary files /dev/null and b/textures/mcl_skins_headwear_2.png differ diff --git a/textures/mcl_skins_headwear_3.png b/textures/mcl_skins_headwear_3.png new file mode 100644 index 000000000..010d8229e Binary files /dev/null and b/textures/mcl_skins_headwear_3.png differ diff --git a/textures/mcl_skins_headwear_4.png b/textures/mcl_skins_headwear_4.png new file mode 100644 index 000000000..a5c89bee2 Binary files /dev/null and b/textures/mcl_skins_headwear_4.png differ diff --git a/textures/mcl_skins_headwear_5.png b/textures/mcl_skins_headwear_5.png new file mode 100644 index 000000000..87bd7e861 Binary files /dev/null and b/textures/mcl_skins_headwear_5.png differ diff --git a/textures/mcl_skins_headwear_6.png b/textures/mcl_skins_headwear_6.png new file mode 100644 index 000000000..47c11abf7 Binary files /dev/null and b/textures/mcl_skins_headwear_6.png differ diff --git a/textures/mcl_skins_headwear_7.png b/textures/mcl_skins_headwear_7.png new file mode 100644 index 000000000..97cdd7360 Binary files /dev/null and b/textures/mcl_skins_headwear_7.png differ diff --git a/textures/mcl_skins_icons.png b/textures/mcl_skins_icons.png new file mode 100644 index 000000000..f0e7e93d8 Binary files /dev/null and b/textures/mcl_skins_icons.png differ diff --git a/textures/mcl_skins_mouth_1.png b/textures/mcl_skins_mouth_1.png new file mode 100644 index 000000000..963955c81 Binary files /dev/null and b/textures/mcl_skins_mouth_1.png differ diff --git a/textures/mcl_skins_mouth_2.png b/textures/mcl_skins_mouth_2.png new file mode 100644 index 000000000..8c6583759 Binary files /dev/null and b/textures/mcl_skins_mouth_2.png differ diff --git a/textures/mcl_skins_mouth_3.png b/textures/mcl_skins_mouth_3.png new file mode 100644 index 000000000..98b18c7ec Binary files /dev/null and b/textures/mcl_skins_mouth_3.png differ diff --git a/textures/mcl_skins_mouth_4.png b/textures/mcl_skins_mouth_4.png new file mode 100644 index 000000000..7c29832d6 Binary files /dev/null and b/textures/mcl_skins_mouth_4.png differ diff --git a/textures/mcl_skins_mouth_5.png b/textures/mcl_skins_mouth_5.png new file mode 100644 index 000000000..9c08cdb6b Binary files /dev/null and b/textures/mcl_skins_mouth_5.png differ diff --git a/textures/mcl_skins_mouth_6.png b/textures/mcl_skins_mouth_6.png new file mode 100644 index 000000000..9b36d2b96 Binary files /dev/null and b/textures/mcl_skins_mouth_6.png differ diff --git a/textures/mcl_skins_mouth_7.png b/textures/mcl_skins_mouth_7.png new file mode 100644 index 000000000..1c6b5f7e8 Binary files /dev/null and b/textures/mcl_skins_mouth_7.png differ diff --git a/textures/mcl_skins_select_overlay.png b/textures/mcl_skins_select_overlay.png new file mode 100644 index 000000000..3fb6549c1 Binary files /dev/null and b/textures/mcl_skins_select_overlay.png differ diff --git a/textures/mcl_skins_slim_arms.png b/textures/mcl_skins_slim_arms.png new file mode 100644 index 000000000..415de4f34 Binary files /dev/null and b/textures/mcl_skins_slim_arms.png differ diff --git a/textures/mcl_skins_thick_arms.png b/textures/mcl_skins_thick_arms.png new file mode 100644 index 000000000..b839b3a1f Binary files /dev/null and b/textures/mcl_skins_thick_arms.png differ diff --git a/textures/mcl_skins_top_1.png b/textures/mcl_skins_top_1.png new file mode 100644 index 000000000..55e670b77 Binary files /dev/null and b/textures/mcl_skins_top_1.png differ diff --git a/textures/mcl_skins_top_10.png b/textures/mcl_skins_top_10.png new file mode 100644 index 000000000..59d21fcfb Binary files /dev/null and b/textures/mcl_skins_top_10.png differ diff --git a/textures/mcl_skins_top_10_mask.png b/textures/mcl_skins_top_10_mask.png new file mode 100644 index 000000000..624069481 Binary files /dev/null and b/textures/mcl_skins_top_10_mask.png differ diff --git a/textures/mcl_skins_top_1_mask.png b/textures/mcl_skins_top_1_mask.png new file mode 100644 index 000000000..22466f5e8 Binary files /dev/null and b/textures/mcl_skins_top_1_mask.png differ diff --git a/textures/mcl_skins_top_2.png b/textures/mcl_skins_top_2.png new file mode 100644 index 000000000..d8bf697da Binary files /dev/null and b/textures/mcl_skins_top_2.png differ diff --git a/textures/mcl_skins_top_2_mask.png b/textures/mcl_skins_top_2_mask.png new file mode 100644 index 000000000..d74053624 Binary files /dev/null and b/textures/mcl_skins_top_2_mask.png differ diff --git a/textures/mcl_skins_top_3.png b/textures/mcl_skins_top_3.png new file mode 100644 index 000000000..f9eb1d576 Binary files /dev/null and b/textures/mcl_skins_top_3.png differ diff --git a/textures/mcl_skins_top_3_mask.png b/textures/mcl_skins_top_3_mask.png new file mode 100644 index 000000000..461172271 Binary files /dev/null and b/textures/mcl_skins_top_3_mask.png differ diff --git a/textures/mcl_skins_top_4.png b/textures/mcl_skins_top_4.png new file mode 100644 index 000000000..042e63bcd Binary files /dev/null and b/textures/mcl_skins_top_4.png differ diff --git a/textures/mcl_skins_top_4_mask.png b/textures/mcl_skins_top_4_mask.png new file mode 100644 index 000000000..d669763dd Binary files /dev/null and b/textures/mcl_skins_top_4_mask.png differ diff --git a/textures/mcl_skins_top_5.png b/textures/mcl_skins_top_5.png new file mode 100644 index 000000000..179b2ea2f Binary files /dev/null and b/textures/mcl_skins_top_5.png differ diff --git a/textures/mcl_skins_top_5_mask.png b/textures/mcl_skins_top_5_mask.png new file mode 100644 index 000000000..6bf55d061 Binary files /dev/null and b/textures/mcl_skins_top_5_mask.png differ diff --git a/textures/mcl_skins_top_6.png b/textures/mcl_skins_top_6.png new file mode 100644 index 000000000..90f2cb9bc Binary files /dev/null and b/textures/mcl_skins_top_6.png differ diff --git a/textures/mcl_skins_top_6_mask.png b/textures/mcl_skins_top_6_mask.png new file mode 100644 index 000000000..3b712205e Binary files /dev/null and b/textures/mcl_skins_top_6_mask.png differ diff --git a/textures/mcl_skins_top_7.png b/textures/mcl_skins_top_7.png new file mode 100644 index 000000000..b3f12eacc Binary files /dev/null and b/textures/mcl_skins_top_7.png differ diff --git a/textures/mcl_skins_top_7_mask.png b/textures/mcl_skins_top_7_mask.png new file mode 100644 index 000000000..d341f00c5 Binary files /dev/null and b/textures/mcl_skins_top_7_mask.png differ diff --git a/textures/mcl_skins_top_8.png b/textures/mcl_skins_top_8.png new file mode 100644 index 000000000..3ea545e7e Binary files /dev/null and b/textures/mcl_skins_top_8.png differ diff --git a/textures/mcl_skins_top_8_mask.png b/textures/mcl_skins_top_8_mask.png new file mode 100644 index 000000000..93a90ea2f Binary files /dev/null and b/textures/mcl_skins_top_8_mask.png differ diff --git a/textures/mcl_skins_top_9.png b/textures/mcl_skins_top_9.png new file mode 100644 index 000000000..50c4dbd59 Binary files /dev/null and b/textures/mcl_skins_top_9.png differ diff --git a/textures/mcl_skins_top_9_mask.png b/textures/mcl_skins_top_9_mask.png new file mode 100644 index 000000000..6657dc067 Binary files /dev/null and b/textures/mcl_skins_top_9_mask.png differ diff --git a/textures/mcl_smithing_table_bottom.png b/textures/mcl_smithing_table_bottom.png new file mode 100644 index 000000000..d44c0773e Binary files /dev/null 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 new file mode 100644 index 000000000..bdf52e354 Binary files /dev/null and b/textures/mcl_smithing_table_front.png differ diff --git a/textures/mcl_smithing_table_inventory.png b/textures/mcl_smithing_table_inventory.png new file mode 100644 index 000000000..49421b3db Binary files /dev/null and b/textures/mcl_smithing_table_inventory.png differ diff --git a/textures/mcl_smithing_table_side.png b/textures/mcl_smithing_table_side.png new file mode 100644 index 000000000..fbc1a9a23 Binary files /dev/null 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 new file mode 100644 index 000000000..63c6aea35 Binary files /dev/null and b/textures/mcl_smithing_table_top.png differ diff --git a/textures/mcl_sponges_sponge.png b/textures/mcl_sponges_sponge.png new file mode 100644 index 000000000..dd7f3b71c Binary files /dev/null and b/textures/mcl_sponges_sponge.png differ diff --git a/textures/mcl_sponges_sponge_wet.png b/textures/mcl_sponges_sponge_wet.png new file mode 100644 index 000000000..e9d152199 Binary files /dev/null and b/textures/mcl_sponges_sponge_wet.png differ diff --git a/textures/mcl_sponges_sponge_wet_river_water.png b/textures/mcl_sponges_sponge_wet_river_water.png new file mode 100644 index 000000000..bbbf86fa4 Binary files /dev/null and b/textures/mcl_sponges_sponge_wet_river_water.png differ diff --git a/textures/mcl_spyglass.png b/textures/mcl_spyglass.png new file mode 100644 index 000000000..cdbee2de8 Binary files /dev/null and b/textures/mcl_spyglass.png differ diff --git a/textures/mcl_spyglass_scope.png b/textures/mcl_spyglass_scope.png new file mode 100644 index 000000000..bf03bcedd Binary files /dev/null and b/textures/mcl_spyglass_scope.png differ diff --git a/textures/mcl_stairs_andesite_smooth_slab.png b/textures/mcl_stairs_andesite_smooth_slab.png new file mode 100644 index 000000000..b2ccfa1d5 Binary files /dev/null and b/textures/mcl_stairs_andesite_smooth_slab.png differ diff --git a/textures/mcl_stairs_diorite_smooth_slab.png b/textures/mcl_stairs_diorite_smooth_slab.png new file mode 100644 index 000000000..2fd10111b Binary files /dev/null and b/textures/mcl_stairs_diorite_smooth_slab.png differ diff --git a/textures/mcl_stairs_gold_block_slab.png b/textures/mcl_stairs_gold_block_slab.png new file mode 100644 index 000000000..b8da4edeb Binary files /dev/null and b/textures/mcl_stairs_gold_block_slab.png differ diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_granite_smooth_slab.png b/textures/mcl_stairs_granite_smooth_slab.png similarity index 100% rename from mods/ITEMS/mclx_stairs/textures/mcl_stairs_granite_smooth_slab.png rename to textures/mcl_stairs_granite_smooth_slab.png diff --git a/textures/mcl_stairs_iron_block_slab.png b/textures/mcl_stairs_iron_block_slab.png new file mode 100644 index 000000000..9f027e4b4 Binary files /dev/null and b/textures/mcl_stairs_iron_block_slab.png differ diff --git a/mods/ITEMS/mclx_stairs/textures/mcl_stairs_lapis_block_slab.png b/textures/mcl_stairs_lapis_block_slab.png similarity index 100% rename from mods/ITEMS/mclx_stairs/textures/mcl_stairs_lapis_block_slab.png rename to textures/mcl_stairs_lapis_block_slab.png diff --git a/mods/ITEMS/mcl_stairs/textures/mcl_stairs_stone_slab_side.png b/textures/mcl_stairs_stone_slab_side.png similarity index 100% rename from mods/ITEMS/mcl_stairs/textures/mcl_stairs_stone_slab_side.png rename to textures/mcl_stairs_stone_slab_side.png diff --git a/textures/mcl_stairs_stone_slab_top.png b/textures/mcl_stairs_stone_slab_top.png new file mode 100644 index 000000000..8570ff38a Binary files /dev/null and b/textures/mcl_stairs_stone_slab_top.png differ diff --git a/mods/ITEMS/mcl_stairs/textures/mcl_stairs_turntexture.png b/textures/mcl_stairs_turntexture.png similarity index 100% rename from mods/ITEMS/mcl_stairs/textures/mcl_stairs_turntexture.png rename to textures/mcl_stairs_turntexture.png diff --git a/textures/mcl_stonecutter_bottom.png b/textures/mcl_stonecutter_bottom.png new file mode 100644 index 000000000..5b15fe3f5 Binary files /dev/null and b/textures/mcl_stonecutter_bottom.png differ diff --git a/textures/mcl_stonecutter_saw.png b/textures/mcl_stonecutter_saw.png new file mode 100644 index 000000000..7d9aa48fd Binary files /dev/null and b/textures/mcl_stonecutter_saw.png differ diff --git a/textures/mcl_stonecutter_side.png b/textures/mcl_stonecutter_side.png new file mode 100644 index 000000000..02261e763 Binary files /dev/null and b/textures/mcl_stonecutter_side.png differ diff --git a/textures/mcl_stonecutter_top.png b/textures/mcl_stonecutter_top.png new file mode 100644 index 000000000..1cb7ee6e1 Binary files /dev/null and b/textures/mcl_stonecutter_top.png differ diff --git a/textures/mcl_stripped_mangrove_log_side.png b/textures/mcl_stripped_mangrove_log_side.png new file mode 100644 index 000000000..cb9ac10ac Binary files /dev/null and b/textures/mcl_stripped_mangrove_log_side.png differ diff --git a/textures/mcl_stripped_mangrove_log_top.png b/textures/mcl_stripped_mangrove_log_top.png new file mode 100644 index 000000000..da228d4be Binary files /dev/null and b/textures/mcl_stripped_mangrove_log_top.png differ diff --git a/textures/mcl_target_target_side.png b/textures/mcl_target_target_side.png new file mode 100644 index 000000000..5a8c0f09a Binary files /dev/null and b/textures/mcl_target_target_side.png differ diff --git a/textures/mcl_target_target_top.png b/textures/mcl_target_target_top.png new file mode 100644 index 000000000..5a8c0f09a Binary files /dev/null and b/textures/mcl_target_target_top.png differ diff --git a/mods/ITEMS/mcl_throwing/textures/mcl_throwing_egg.png b/textures/mcl_throwing_egg.png similarity index 100% rename from mods/ITEMS/mcl_throwing/textures/mcl_throwing_egg.png rename to textures/mcl_throwing_egg.png diff --git a/textures/mcl_throwing_ender_pearl.png b/textures/mcl_throwing_ender_pearl.png new file mode 100644 index 000000000..a73be6941 Binary files /dev/null and b/textures/mcl_throwing_ender_pearl.png differ diff --git a/textures/mcl_throwing_snowball.png b/textures/mcl_throwing_snowball.png new file mode 100644 index 000000000..d1216839e Binary files /dev/null and b/textures/mcl_throwing_snowball.png differ diff --git a/textures/mcl_tnt_blink.png b/textures/mcl_tnt_blink.png new file mode 100644 index 000000000..faf0ec13d Binary files /dev/null and b/textures/mcl_tnt_blink.png differ diff --git a/textures/mcl_totems_totem.png b/textures/mcl_totems_totem.png new file mode 100644 index 000000000..56f56cbe0 Binary files /dev/null and b/textures/mcl_totems_totem.png differ diff --git a/textures/mcl_walls_cobble_mossy_wall_side.png b/textures/mcl_walls_cobble_mossy_wall_side.png new file mode 100644 index 000000000..472d508c6 Binary files /dev/null and b/textures/mcl_walls_cobble_mossy_wall_side.png differ diff --git a/textures/mcl_walls_cobble_mossy_wall_top.png b/textures/mcl_walls_cobble_mossy_wall_top.png new file mode 100644 index 000000000..ef54287c8 Binary files /dev/null and b/textures/mcl_walls_cobble_mossy_wall_top.png differ diff --git a/textures/mcl_walls_cobble_wall_side.png b/textures/mcl_walls_cobble_wall_side.png new file mode 100644 index 000000000..0614efbc0 Binary files /dev/null and b/textures/mcl_walls_cobble_wall_side.png differ diff --git a/textures/mcl_walls_cobble_wall_top.png b/textures/mcl_walls_cobble_wall_top.png new file mode 100644 index 000000000..5e88b5761 Binary files /dev/null and b/textures/mcl_walls_cobble_wall_top.png differ diff --git a/textures/mcl_wear_bar.png b/textures/mcl_wear_bar.png new file mode 100644 index 000000000..2d8d70f28 Binary files /dev/null and b/textures/mcl_wear_bar.png differ diff --git a/textures/mcl_wool_light_blue.png b/textures/mcl_wool_light_blue.png new file mode 100644 index 000000000..010b8a8c2 Binary files /dev/null and b/textures/mcl_wool_light_blue.png differ diff --git a/textures/mcl_wool_lime.png b/textures/mcl_wool_lime.png new file mode 100644 index 000000000..e9de9a362 Binary files /dev/null and b/textures/mcl_wool_lime.png differ diff --git a/textures/mesecons_button_wield_mask.png b/textures/mesecons_button_wield_mask.png new file mode 100644 index 000000000..ae866e986 Binary files /dev/null and b/textures/mesecons_button_wield_mask.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_end_locked_off.png b/textures/mesecons_delayer_end_locked_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_end_locked_off.png rename to textures/mesecons_delayer_end_locked_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_end_locked_on.png b/textures/mesecons_delayer_end_locked_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_end_locked_on.png rename to textures/mesecons_delayer_end_locked_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_ends_off.png b/textures/mesecons_delayer_ends_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_ends_off.png rename to textures/mesecons_delayer_ends_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_ends_on.png b/textures/mesecons_delayer_ends_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_ends_on.png rename to textures/mesecons_delayer_ends_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_front_locked_off.png b/textures/mesecons_delayer_front_locked_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_front_locked_off.png rename to textures/mesecons_delayer_front_locked_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_front_locked_on.png b/textures/mesecons_delayer_front_locked_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_front_locked_on.png rename to textures/mesecons_delayer_front_locked_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_item.png b/textures/mesecons_delayer_item.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_item.png rename to textures/mesecons_delayer_item.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_locked_off.png b/textures/mesecons_delayer_locked_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_locked_off.png rename to textures/mesecons_delayer_locked_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_locked_on.png b/textures/mesecons_delayer_locked_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_locked_on.png rename to textures/mesecons_delayer_locked_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_off.png b/textures/mesecons_delayer_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_off.png rename to textures/mesecons_delayer_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_on.png b/textures/mesecons_delayer_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_on.png rename to textures/mesecons_delayer_on.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_locked_off.png b/textures/mesecons_delayer_sides_locked_off.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_locked_off.png rename to textures/mesecons_delayer_sides_locked_off.png diff --git a/mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_locked_on.png b/textures/mesecons_delayer_sides_locked_on.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_delayer/textures/mesecons_delayer_sides_locked_on.png rename to textures/mesecons_delayer_sides_locked_on.png diff --git a/textures/mesecons_delayer_sides_off.png b/textures/mesecons_delayer_sides_off.png new file mode 100644 index 000000000..e69dc2f2a Binary files /dev/null and b/textures/mesecons_delayer_sides_off.png differ diff --git a/textures/mesecons_delayer_sides_on.png b/textures/mesecons_delayer_sides_on.png new file mode 100644 index 000000000..96a2c2602 Binary files /dev/null and b/textures/mesecons_delayer_sides_on.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_noteblock/textures/mesecons_noteblock.png b/textures/mesecons_noteblock.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_noteblock/textures/mesecons_noteblock.png rename to textures/mesecons_noteblock.png diff --git a/textures/mesecons_piston_back.png b/textures/mesecons_piston_back.png new file mode 100644 index 000000000..fba234eb9 Binary files /dev/null and b/textures/mesecons_piston_back.png differ diff --git a/textures/mesecons_piston_bottom.png b/textures/mesecons_piston_bottom.png new file mode 100644 index 000000000..ebcdeb637 Binary files /dev/null and b/textures/mesecons_piston_bottom.png differ diff --git a/textures/mesecons_piston_on_front.png b/textures/mesecons_piston_on_front.png new file mode 100644 index 000000000..424d64571 Binary files /dev/null and b/textures/mesecons_piston_on_front.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_back.png b/textures/mesecons_piston_pusher_back.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_back.png rename to textures/mesecons_piston_pusher_back.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_bottom.png b/textures/mesecons_piston_pusher_bottom.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_bottom.png rename to textures/mesecons_piston_pusher_bottom.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_front.png b/textures/mesecons_piston_pusher_front.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_front.png rename to textures/mesecons_piston_pusher_front.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_front_sticky.png b/textures/mesecons_piston_pusher_front_sticky.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_front_sticky.png rename to textures/mesecons_piston_pusher_front_sticky.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_left.png b/textures/mesecons_piston_pusher_left.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_left.png rename to textures/mesecons_piston_pusher_left.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_right.png b/textures/mesecons_piston_pusher_right.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_right.png rename to textures/mesecons_piston_pusher_right.png diff --git a/mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_top.png b/textures/mesecons_piston_pusher_top.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_pistons/textures/mesecons_piston_pusher_top.png rename to textures/mesecons_piston_pusher_top.png diff --git a/textures/mineclone2_icon.png b/textures/mineclone2_icon.png new file mode 100644 index 000000000..d2a1554a6 Binary files /dev/null and b/textures/mineclone2_icon.png differ diff --git a/textures/mineclone2_logo.png b/textures/mineclone2_logo.png new file mode 100644 index 000000000..d3e01733d Binary files /dev/null and b/textures/mineclone2_logo.png differ diff --git a/textures/mob_spawner.png b/textures/mob_spawner.png new file mode 100644 index 000000000..069a015e9 Binary files /dev/null and b/textures/mob_spawner.png differ diff --git a/textures/mobs_blood.png b/textures/mobs_blood.png new file mode 100644 index 000000000..ebda3703f Binary files /dev/null and b/textures/mobs_blood.png differ diff --git a/textures/mobs_chicken_egg.png b/textures/mobs_chicken_egg.png new file mode 100644 index 000000000..346dac7ab Binary files /dev/null and b/textures/mobs_chicken_egg.png differ diff --git a/textures/mobs_mc_TEMP_wither_projectile.png b/textures/mobs_mc_TEMP_wither_projectile.png new file mode 100644 index 000000000..d9ddd9bba Binary files /dev/null and b/textures/mobs_mc_TEMP_wither_projectile.png differ diff --git a/textures/mobs_mc_arrow_particle.png b/textures/mobs_mc_arrow_particle.png new file mode 100644 index 000000000..b7105877c Binary files /dev/null and b/textures/mobs_mc_arrow_particle.png differ diff --git a/textures/mobs_mc_axolotl_black.png b/textures/mobs_mc_axolotl_black.png new file mode 100644 index 000000000..ea508c9f1 Binary files /dev/null and b/textures/mobs_mc_axolotl_black.png differ diff --git a/textures/mobs_mc_axolotl_brown.png b/textures/mobs_mc_axolotl_brown.png new file mode 100644 index 000000000..5698c1d36 Binary files /dev/null and b/textures/mobs_mc_axolotl_brown.png differ diff --git a/textures/mobs_mc_axolotl_green.png b/textures/mobs_mc_axolotl_green.png new file mode 100644 index 000000000..aa854807c Binary files /dev/null and b/textures/mobs_mc_axolotl_green.png differ diff --git a/textures/mobs_mc_axolotl_pink.png b/textures/mobs_mc_axolotl_pink.png new file mode 100644 index 000000000..b2fd714b7 Binary files /dev/null and b/textures/mobs_mc_axolotl_pink.png differ diff --git a/textures/mobs_mc_axolotl_purple.png b/textures/mobs_mc_axolotl_purple.png new file mode 100644 index 000000000..4042b3891 Binary files /dev/null and b/textures/mobs_mc_axolotl_purple.png differ diff --git a/textures/mobs_mc_axolotl_white.png b/textures/mobs_mc_axolotl_white.png new file mode 100644 index 000000000..918f038fb Binary files /dev/null and b/textures/mobs_mc_axolotl_white.png differ diff --git a/textures/mobs_mc_axolotl_yellow.png b/textures/mobs_mc_axolotl_yellow.png new file mode 100644 index 000000000..a21c6e122 Binary files /dev/null and b/textures/mobs_mc_axolotl_yellow.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_bat.png b/textures/mobs_mc_bat.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_bat.png rename to textures/mobs_mc_bat.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_blaze.png b/textures/mobs_mc_blaze.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_blaze.png rename to textures/mobs_mc_blaze.png diff --git a/textures/mobs_mc_cat_black.png b/textures/mobs_mc_cat_black.png new file mode 100644 index 000000000..02e84f3db Binary files /dev/null and b/textures/mobs_mc_cat_black.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_ocelot.png b/textures/mobs_mc_cat_ocelot.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_ocelot.png rename to textures/mobs_mc_cat_ocelot.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_red.png b/textures/mobs_mc_cat_red.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_red.png rename to textures/mobs_mc_cat_red.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_siamese.png b/textures/mobs_mc_cat_siamese.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_cat_siamese.png rename to textures/mobs_mc_cat_siamese.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cave_spider.png b/textures/mobs_mc_cave_spider.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_cave_spider.png rename to textures/mobs_mc_cave_spider.png diff --git a/textures/mobs_mc_chicken.png b/textures/mobs_mc_chicken.png new file mode 100644 index 000000000..a2664e720 Binary files /dev/null and b/textures/mobs_mc_chicken.png differ diff --git a/textures/mobs_mc_cod.png b/textures/mobs_mc_cod.png new file mode 100644 index 000000000..0da300c6e Binary files /dev/null and b/textures/mobs_mc_cod.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_cow.png b/textures/mobs_mc_cow.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_cow.png rename to textures/mobs_mc_cow.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper.png b/textures/mobs_mc_creeper.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_creeper.png rename to textures/mobs_mc_creeper.png diff --git a/textures/mobs_mc_creeper_charge.png b/textures/mobs_mc_creeper_charge.png new file mode 100644 index 000000000..f80392bc0 Binary files /dev/null and b/textures/mobs_mc_creeper_charge.png differ diff --git a/textures/mobs_mc_diamond.png b/textures/mobs_mc_diamond.png new file mode 100644 index 000000000..f224eb463 Binary files /dev/null and b/textures/mobs_mc_diamond.png differ diff --git a/textures/mobs_mc_diamond_horse_armor.png b/textures/mobs_mc_diamond_horse_armor.png new file mode 100644 index 000000000..121be08de Binary files /dev/null and b/textures/mobs_mc_diamond_horse_armor.png differ diff --git a/textures/mobs_mc_donkey.png b/textures/mobs_mc_donkey.png new file mode 100644 index 000000000..c26e22004 Binary files /dev/null and b/textures/mobs_mc_donkey.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon.png b/textures/mobs_mc_dragon.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_dragon.png rename to textures/mobs_mc_dragon.png diff --git a/textures/mobs_mc_dragon_fireball.png b/textures/mobs_mc_dragon_fireball.png new file mode 100644 index 000000000..77a282727 Binary files /dev/null and b/textures/mobs_mc_dragon_fireball.png differ diff --git a/textures/mobs_mc_emerald.png b/textures/mobs_mc_emerald.png new file mode 100644 index 000000000..023101a17 Binary files /dev/null and b/textures/mobs_mc_emerald.png differ diff --git a/textures/mobs_mc_empty.png b/textures/mobs_mc_empty.png new file mode 100644 index 000000000..4c3d3ea87 Binary files /dev/null and b/textures/mobs_mc_empty.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_endergolem.png b/textures/mobs_mc_endergolem.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_endergolem.png rename to textures/mobs_mc_endergolem.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman.png b/textures/mobs_mc_enderman.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman.png rename to textures/mobs_mc_enderman.png diff --git a/textures/mobs_mc_enderman_cactus_background.png b/textures/mobs_mc_enderman_cactus_background.png new file mode 100644 index 000000000..34d98fad7 Binary files /dev/null and b/textures/mobs_mc_enderman_cactus_background.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_eyes.png b/textures/mobs_mc_enderman_eyes.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_enderman_eyes.png rename to textures/mobs_mc_enderman_eyes.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_endermite.png b/textures/mobs_mc_endermite.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_endermite.png rename to textures/mobs_mc_endermite.png diff --git a/textures/mobs_mc_evoker.png b/textures/mobs_mc_evoker.png new file mode 100644 index 000000000..af793b59b Binary files /dev/null and b/textures/mobs_mc_evoker.png differ diff --git a/textures/mobs_mc_ghast.png b/textures/mobs_mc_ghast.png new file mode 100644 index 000000000..2bd9322a1 Binary files /dev/null and b/textures/mobs_mc_ghast.png differ diff --git a/textures/mobs_mc_ghast_firing.png b/textures/mobs_mc_ghast_firing.png new file mode 100644 index 000000000..9516fa0ed Binary files /dev/null and b/textures/mobs_mc_ghast_firing.png differ diff --git a/textures/mobs_mc_glow_squid.png b/textures/mobs_mc_glow_squid.png new file mode 100644 index 000000000..342153b19 Binary files /dev/null and b/textures/mobs_mc_glow_squid.png differ diff --git a/textures/mobs_mc_glow_squid_glint1.png b/textures/mobs_mc_glow_squid_glint1.png new file mode 100644 index 000000000..9fb56ce6e Binary files /dev/null and b/textures/mobs_mc_glow_squid_glint1.png differ diff --git a/textures/mobs_mc_glow_squid_glint2.png b/textures/mobs_mc_glow_squid_glint2.png new file mode 100644 index 000000000..b09e640d9 Binary files /dev/null and b/textures/mobs_mc_glow_squid_glint2.png differ diff --git a/textures/mobs_mc_glow_squid_glint3.png b/textures/mobs_mc_glow_squid_glint3.png new file mode 100644 index 000000000..986373084 Binary files /dev/null and b/textures/mobs_mc_glow_squid_glint3.png differ diff --git a/textures/mobs_mc_glow_squid_glint4.png b/textures/mobs_mc_glow_squid_glint4.png new file mode 100644 index 000000000..e3b0c8984 Binary files /dev/null and b/textures/mobs_mc_glow_squid_glint4.png differ diff --git a/textures/mobs_mc_gold.png b/textures/mobs_mc_gold.png new file mode 100644 index 000000000..a0022f0ef Binary files /dev/null and b/textures/mobs_mc_gold.png differ diff --git a/textures/mobs_mc_gold_horse_armor.png b/textures/mobs_mc_gold_horse_armor.png new file mode 100644 index 000000000..f6b4fdfb9 Binary files /dev/null and b/textures/mobs_mc_gold_horse_armor.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_guardian.png b/textures/mobs_mc_guardian.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_guardian.png rename to textures/mobs_mc_guardian.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_guardian_elder.png b/textures/mobs_mc_guardian_elder.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_guardian_elder.png rename to textures/mobs_mc_guardian_elder.png diff --git a/textures/mobs_mc_horse_black.png b/textures/mobs_mc_horse_black.png new file mode 100644 index 000000000..79386694c Binary files /dev/null and b/textures/mobs_mc_horse_black.png differ diff --git a/textures/mobs_mc_horse_brown.png b/textures/mobs_mc_horse_brown.png new file mode 100644 index 000000000..fef1b6bac Binary files /dev/null and b/textures/mobs_mc_horse_brown.png differ diff --git a/textures/mobs_mc_horse_chestnut.png b/textures/mobs_mc_horse_chestnut.png new file mode 100644 index 000000000..89dfb8472 Binary files /dev/null and b/textures/mobs_mc_horse_chestnut.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_creamy.png b/textures/mobs_mc_horse_creamy.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_creamy.png rename to textures/mobs_mc_horse_creamy.png diff --git a/textures/mobs_mc_horse_darkbrown.png b/textures/mobs_mc_horse_darkbrown.png new file mode 100644 index 000000000..fed93e0e1 Binary files /dev/null and b/textures/mobs_mc_horse_darkbrown.png differ diff --git a/textures/mobs_mc_horse_gray.png b/textures/mobs_mc_horse_gray.png new file mode 100644 index 000000000..e2ff0b7da Binary files /dev/null and b/textures/mobs_mc_horse_gray.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_blackdots.png b/textures/mobs_mc_horse_markings_blackdots.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_blackdots.png rename to textures/mobs_mc_horse_markings_blackdots.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_white.png b/textures/mobs_mc_horse_markings_white.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_white.png rename to textures/mobs_mc_horse_markings_white.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_whitedots.png b/textures/mobs_mc_horse_markings_whitedots.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_whitedots.png rename to textures/mobs_mc_horse_markings_whitedots.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_whitefield.png b/textures/mobs_mc_horse_markings_whitefield.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_horse_markings_whitefield.png rename to textures/mobs_mc_horse_markings_whitefield.png diff --git a/textures/mobs_mc_horse_skeleton.png b/textures/mobs_mc_horse_skeleton.png new file mode 100644 index 000000000..c96f94d05 Binary files /dev/null and b/textures/mobs_mc_horse_skeleton.png differ diff --git a/textures/mobs_mc_horse_white.png b/textures/mobs_mc_horse_white.png new file mode 100644 index 000000000..fcf3eee04 Binary files /dev/null and b/textures/mobs_mc_horse_white.png differ diff --git a/textures/mobs_mc_horse_zombie.png b/textures/mobs_mc_horse_zombie.png new file mode 100644 index 000000000..b64ac8109 Binary files /dev/null and b/textures/mobs_mc_horse_zombie.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_husk.png b/textures/mobs_mc_husk.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_husk.png rename to textures/mobs_mc_husk.png diff --git a/textures/mobs_mc_illusionist.png b/textures/mobs_mc_illusionist.png new file mode 100644 index 000000000..a03a920b5 Binary files /dev/null and b/textures/mobs_mc_illusionist.png differ diff --git a/textures/mobs_mc_iron.png b/textures/mobs_mc_iron.png new file mode 100644 index 000000000..6f6e0c7f8 Binary files /dev/null and b/textures/mobs_mc_iron.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_iron_golem.png b/textures/mobs_mc_iron_golem.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_iron_golem.png rename to textures/mobs_mc_iron_golem.png diff --git a/textures/mobs_mc_iron_horse_armor.png b/textures/mobs_mc_iron_horse_armor.png new file mode 100644 index 000000000..4f078a92b Binary files /dev/null and b/textures/mobs_mc_iron_horse_armor.png differ diff --git a/textures/mobs_mc_llama.png b/textures/mobs_mc_llama.png new file mode 100644 index 000000000..2fba8db66 Binary files /dev/null and b/textures/mobs_mc_llama.png differ diff --git a/textures/mobs_mc_llama_brown.png b/textures/mobs_mc_llama_brown.png new file mode 100644 index 000000000..b0e830f94 Binary files /dev/null and b/textures/mobs_mc_llama_brown.png differ diff --git a/textures/mobs_mc_llama_creamy.png b/textures/mobs_mc_llama_creamy.png new file mode 100644 index 000000000..b8079da7c Binary files /dev/null and b/textures/mobs_mc_llama_creamy.png differ diff --git a/textures/mobs_mc_llama_decor_black.png b/textures/mobs_mc_llama_decor_black.png new file mode 100644 index 000000000..1fdc3746c Binary files /dev/null and b/textures/mobs_mc_llama_decor_black.png differ diff --git a/textures/mobs_mc_llama_decor_blue.png b/textures/mobs_mc_llama_decor_blue.png new file mode 100644 index 000000000..658a0c56e Binary files /dev/null and b/textures/mobs_mc_llama_decor_blue.png differ diff --git a/textures/mobs_mc_llama_decor_brown.png b/textures/mobs_mc_llama_decor_brown.png new file mode 100644 index 000000000..94442c553 Binary files /dev/null and b/textures/mobs_mc_llama_decor_brown.png differ diff --git a/textures/mobs_mc_llama_decor_cyan.png b/textures/mobs_mc_llama_decor_cyan.png new file mode 100644 index 000000000..57dccc3c6 Binary files /dev/null and b/textures/mobs_mc_llama_decor_cyan.png differ diff --git a/textures/mobs_mc_llama_decor_gray.png b/textures/mobs_mc_llama_decor_gray.png new file mode 100644 index 000000000..aef4d5799 Binary files /dev/null and b/textures/mobs_mc_llama_decor_gray.png differ diff --git a/textures/mobs_mc_llama_decor_green.png b/textures/mobs_mc_llama_decor_green.png new file mode 100644 index 000000000..39bc777b2 Binary files /dev/null and b/textures/mobs_mc_llama_decor_green.png differ diff --git a/textures/mobs_mc_llama_decor_light_blue.png b/textures/mobs_mc_llama_decor_light_blue.png new file mode 100644 index 000000000..6246a8e4e Binary files /dev/null and b/textures/mobs_mc_llama_decor_light_blue.png differ diff --git a/textures/mobs_mc_llama_decor_light_gray.png b/textures/mobs_mc_llama_decor_light_gray.png new file mode 100644 index 000000000..bffda2021 Binary files /dev/null and b/textures/mobs_mc_llama_decor_light_gray.png differ diff --git a/textures/mobs_mc_llama_decor_lime.png b/textures/mobs_mc_llama_decor_lime.png new file mode 100644 index 000000000..5b267298c Binary files /dev/null and b/textures/mobs_mc_llama_decor_lime.png differ diff --git a/textures/mobs_mc_llama_decor_magenta.png b/textures/mobs_mc_llama_decor_magenta.png new file mode 100644 index 000000000..3edc12f0d Binary files /dev/null and b/textures/mobs_mc_llama_decor_magenta.png differ diff --git a/textures/mobs_mc_llama_decor_orange.png b/textures/mobs_mc_llama_decor_orange.png new file mode 100644 index 000000000..6fdeebe38 Binary files /dev/null and b/textures/mobs_mc_llama_decor_orange.png differ diff --git a/textures/mobs_mc_llama_decor_pink.png b/textures/mobs_mc_llama_decor_pink.png new file mode 100644 index 000000000..cd93362d2 Binary files /dev/null and b/textures/mobs_mc_llama_decor_pink.png differ diff --git a/textures/mobs_mc_llama_decor_purple.png b/textures/mobs_mc_llama_decor_purple.png new file mode 100644 index 000000000..a30423a0c Binary files /dev/null and b/textures/mobs_mc_llama_decor_purple.png differ diff --git a/textures/mobs_mc_llama_decor_red.png b/textures/mobs_mc_llama_decor_red.png new file mode 100644 index 000000000..0158a398c Binary files /dev/null and b/textures/mobs_mc_llama_decor_red.png differ diff --git a/textures/mobs_mc_llama_decor_white.png b/textures/mobs_mc_llama_decor_white.png new file mode 100644 index 000000000..161a2c875 Binary files /dev/null and b/textures/mobs_mc_llama_decor_white.png differ diff --git a/textures/mobs_mc_llama_decor_yellow.png b/textures/mobs_mc_llama_decor_yellow.png new file mode 100644 index 000000000..ed3810e2b Binary files /dev/null and b/textures/mobs_mc_llama_decor_yellow.png differ diff --git a/textures/mobs_mc_llama_gray.png b/textures/mobs_mc_llama_gray.png new file mode 100644 index 000000000..a4d2a7685 Binary files /dev/null and b/textures/mobs_mc_llama_gray.png differ diff --git a/textures/mobs_mc_llama_spit.png b/textures/mobs_mc_llama_spit.png new file mode 100644 index 000000000..788919cf3 Binary files /dev/null and b/textures/mobs_mc_llama_spit.png differ diff --git a/textures/mobs_mc_llama_white.png b/textures/mobs_mc_llama_white.png new file mode 100644 index 000000000..6eae4b41d Binary files /dev/null and b/textures/mobs_mc_llama_white.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_magmacube.png b/textures/mobs_mc_magmacube.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_magmacube.png rename to textures/mobs_mc_magmacube.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom.png b/textures/mobs_mc_mooshroom.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_mooshroom.png rename to textures/mobs_mc_mooshroom.png diff --git a/textures/mobs_mc_mooshroom_brown.png b/textures/mobs_mc_mooshroom_brown.png new file mode 100644 index 000000000..c274c2fa6 Binary files /dev/null and b/textures/mobs_mc_mooshroom_brown.png differ diff --git a/textures/mobs_mc_mule.png b/textures/mobs_mc_mule.png new file mode 100644 index 000000000..e80c13163 Binary files /dev/null and b/textures/mobs_mc_mule.png differ diff --git a/textures/mobs_mc_mushroom_brown.png b/textures/mobs_mc_mushroom_brown.png new file mode 100644 index 000000000..84e8c89b5 Binary files /dev/null and b/textures/mobs_mc_mushroom_brown.png differ diff --git a/textures/mobs_mc_mushroom_red.png b/textures/mobs_mc_mushroom_red.png new file mode 100644 index 000000000..391392f20 Binary files /dev/null and b/textures/mobs_mc_mushroom_red.png differ diff --git a/textures/mobs_mc_parrot_blue.png b/textures/mobs_mc_parrot_blue.png new file mode 100644 index 000000000..e8b44a9ef Binary files /dev/null and b/textures/mobs_mc_parrot_blue.png differ diff --git a/textures/mobs_mc_parrot_green.png b/textures/mobs_mc_parrot_green.png new file mode 100644 index 000000000..63cdc02af Binary files /dev/null and b/textures/mobs_mc_parrot_green.png differ diff --git a/textures/mobs_mc_parrot_grey.png b/textures/mobs_mc_parrot_grey.png new file mode 100644 index 000000000..d621282cc Binary files /dev/null and b/textures/mobs_mc_parrot_grey.png differ diff --git a/textures/mobs_mc_parrot_red_blue.png b/textures/mobs_mc_parrot_red_blue.png new file mode 100644 index 000000000..2d61a8371 Binary files /dev/null and b/textures/mobs_mc_parrot_red_blue.png differ diff --git a/textures/mobs_mc_parrot_yellow_blue.png b/textures/mobs_mc_parrot_yellow_blue.png new file mode 100644 index 000000000..bc6ab8525 Binary files /dev/null and b/textures/mobs_mc_parrot_yellow_blue.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_pig.png b/textures/mobs_mc_pig.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_pig.png rename to textures/mobs_mc_pig.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_pig_saddle.png b/textures/mobs_mc_pig_saddle.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_pig_saddle.png rename to textures/mobs_mc_pig_saddle.png diff --git a/textures/mobs_mc_pillager.png b/textures/mobs_mc_pillager.png new file mode 100644 index 000000000..398442141 Binary files /dev/null and b/textures/mobs_mc_pillager.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_polarbear.png b/textures/mobs_mc_polarbear.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_polarbear.png rename to textures/mobs_mc_polarbear.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_black.png b/textures/mobs_mc_rabbit_black.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_black.png rename to textures/mobs_mc_rabbit_black.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_brown.png b/textures/mobs_mc_rabbit_brown.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_brown.png rename to textures/mobs_mc_rabbit_brown.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_caerbannog.png b/textures/mobs_mc_rabbit_caerbannog.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_caerbannog.png rename to textures/mobs_mc_rabbit_caerbannog.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_gold.png b/textures/mobs_mc_rabbit_gold.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_gold.png rename to textures/mobs_mc_rabbit_gold.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_salt.png b/textures/mobs_mc_rabbit_salt.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_salt.png rename to textures/mobs_mc_rabbit_salt.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_toast.png b/textures/mobs_mc_rabbit_toast.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_toast.png rename to textures/mobs_mc_rabbit_toast.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_white.png b/textures/mobs_mc_rabbit_white.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_white.png rename to textures/mobs_mc_rabbit_white.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_white_splotched.png b/textures/mobs_mc_rabbit_white_splotched.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_rabbit_white_splotched.png rename to textures/mobs_mc_rabbit_white_splotched.png diff --git a/textures/mobs_mc_salmon.png b/textures/mobs_mc_salmon.png new file mode 100644 index 000000000..5ce4d6cc3 Binary files /dev/null and b/textures/mobs_mc_salmon.png differ diff --git a/textures/mobs_mc_sheep.png b/textures/mobs_mc_sheep.png new file mode 100644 index 000000000..426e3ae76 Binary files /dev/null and b/textures/mobs_mc_sheep.png differ diff --git a/textures/mobs_mc_sheep_fur.png b/textures/mobs_mc_sheep_fur.png new file mode 100644 index 000000000..e125c4d47 Binary files /dev/null and b/textures/mobs_mc_sheep_fur.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_black.png b/textures/mobs_mc_shulker_black.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_black.png rename to textures/mobs_mc_shulker_black.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_blue.png b/textures/mobs_mc_shulker_blue.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_blue.png rename to textures/mobs_mc_shulker_blue.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_brown.png b/textures/mobs_mc_shulker_brown.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_brown.png rename to textures/mobs_mc_shulker_brown.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_cyan.png b/textures/mobs_mc_shulker_cyan.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_cyan.png rename to textures/mobs_mc_shulker_cyan.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_gray.png b/textures/mobs_mc_shulker_gray.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_gray.png rename to textures/mobs_mc_shulker_gray.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_green.png b/textures/mobs_mc_shulker_green.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_green.png rename to textures/mobs_mc_shulker_green.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_light_blue.png b/textures/mobs_mc_shulker_light_blue.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_light_blue.png rename to textures/mobs_mc_shulker_light_blue.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_lime.png b/textures/mobs_mc_shulker_lime.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_lime.png rename to textures/mobs_mc_shulker_lime.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_magenta.png b/textures/mobs_mc_shulker_magenta.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_magenta.png rename to textures/mobs_mc_shulker_magenta.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_orange.png b/textures/mobs_mc_shulker_orange.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_orange.png rename to textures/mobs_mc_shulker_orange.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_pink.png b/textures/mobs_mc_shulker_pink.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_pink.png rename to textures/mobs_mc_shulker_pink.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_purple.png b/textures/mobs_mc_shulker_purple.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_purple.png rename to textures/mobs_mc_shulker_purple.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_red.png b/textures/mobs_mc_shulker_red.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_red.png rename to textures/mobs_mc_shulker_red.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_silver.png b/textures/mobs_mc_shulker_silver.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_silver.png rename to textures/mobs_mc_shulker_silver.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_white.png b/textures/mobs_mc_shulker_white.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_white.png rename to textures/mobs_mc_shulker_white.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_yellow.png b/textures/mobs_mc_shulker_yellow.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulker_yellow.png rename to textures/mobs_mc_shulker_yellow.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_shulkerbullet.png b/textures/mobs_mc_shulkerbullet.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_shulkerbullet.png rename to textures/mobs_mc_shulkerbullet.png diff --git a/textures/mobs_mc_silverfish.png b/textures/mobs_mc_silverfish.png new file mode 100644 index 000000000..d1af41064 Binary files /dev/null and b/textures/mobs_mc_silverfish.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_skeleton.png b/textures/mobs_mc_skeleton.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_skeleton.png rename to textures/mobs_mc_skeleton.png diff --git a/textures/mobs_mc_slime.png b/textures/mobs_mc_slime.png new file mode 100644 index 000000000..2290d16e5 Binary files /dev/null and b/textures/mobs_mc_slime.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_snowman.png b/textures/mobs_mc_snowman.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_snowman.png rename to textures/mobs_mc_snowman.png diff --git a/textures/mobs_mc_spawn_icon_bat.png b/textures/mobs_mc_spawn_icon_bat.png new file mode 100644 index 000000000..820b58dac Binary files /dev/null and b/textures/mobs_mc_spawn_icon_bat.png differ diff --git a/textures/mobs_mc_spawn_icon_blaze.png b/textures/mobs_mc_spawn_icon_blaze.png new file mode 100644 index 000000000..94a5014fb Binary files /dev/null and b/textures/mobs_mc_spawn_icon_blaze.png differ diff --git a/textures/mobs_mc_spawn_icon_cat.png b/textures/mobs_mc_spawn_icon_cat.png new file mode 100644 index 000000000..1b904e5ff Binary files /dev/null and b/textures/mobs_mc_spawn_icon_cat.png differ diff --git a/textures/mobs_mc_spawn_icon_cave_spider.png b/textures/mobs_mc_spawn_icon_cave_spider.png new file mode 100644 index 000000000..2d5e06f5c Binary files /dev/null and b/textures/mobs_mc_spawn_icon_cave_spider.png differ diff --git a/textures/mobs_mc_spawn_icon_chicken.png b/textures/mobs_mc_spawn_icon_chicken.png new file mode 100644 index 000000000..70717aed3 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_chicken.png differ diff --git a/textures/mobs_mc_spawn_icon_cod.png b/textures/mobs_mc_spawn_icon_cod.png new file mode 100644 index 000000000..e82b889d2 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_cod.png differ diff --git a/textures/mobs_mc_spawn_icon_cow.png b/textures/mobs_mc_spawn_icon_cow.png new file mode 100644 index 000000000..619547a4b Binary files /dev/null and b/textures/mobs_mc_spawn_icon_cow.png differ diff --git a/textures/mobs_mc_spawn_icon_creeper.png b/textures/mobs_mc_spawn_icon_creeper.png new file mode 100644 index 000000000..51477b201 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_creeper.png differ diff --git a/textures/mobs_mc_spawn_icon_donkey.png b/textures/mobs_mc_spawn_icon_donkey.png new file mode 100644 index 000000000..a3ed2c9b1 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_donkey.png differ diff --git a/textures/mobs_mc_spawn_icon_dragon.png b/textures/mobs_mc_spawn_icon_dragon.png new file mode 100644 index 000000000..228461b8a Binary files /dev/null and b/textures/mobs_mc_spawn_icon_dragon.png differ diff --git a/textures/mobs_mc_spawn_icon_enderman.png b/textures/mobs_mc_spawn_icon_enderman.png new file mode 100644 index 000000000..9ee03b2ab Binary files /dev/null and b/textures/mobs_mc_spawn_icon_enderman.png differ diff --git a/textures/mobs_mc_spawn_icon_endermite.png b/textures/mobs_mc_spawn_icon_endermite.png new file mode 100644 index 000000000..9e553db7d Binary files /dev/null and b/textures/mobs_mc_spawn_icon_endermite.png differ diff --git a/textures/mobs_mc_spawn_icon_evoker.png b/textures/mobs_mc_spawn_icon_evoker.png new file mode 100644 index 000000000..f3b3100d9 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_evoker.png differ diff --git a/textures/mobs_mc_spawn_icon_ghast.png b/textures/mobs_mc_spawn_icon_ghast.png new file mode 100644 index 000000000..b4d0cb4b3 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_ghast.png differ diff --git a/textures/mobs_mc_spawn_icon_guardian.png b/textures/mobs_mc_spawn_icon_guardian.png new file mode 100644 index 000000000..019a9dee8 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_guardian.png differ diff --git a/textures/mobs_mc_spawn_icon_guardian_elder.png b/textures/mobs_mc_spawn_icon_guardian_elder.png new file mode 100644 index 000000000..0b9ce9d76 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_guardian_elder.png differ diff --git a/textures/mobs_mc_spawn_icon_horse.png b/textures/mobs_mc_spawn_icon_horse.png new file mode 100644 index 000000000..17b2460f7 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_horse.png differ diff --git a/textures/mobs_mc_spawn_icon_horse_skeleton.png b/textures/mobs_mc_spawn_icon_horse_skeleton.png new file mode 100644 index 000000000..02176a62b Binary files /dev/null and b/textures/mobs_mc_spawn_icon_horse_skeleton.png differ diff --git a/textures/mobs_mc_spawn_icon_horse_zombie.png b/textures/mobs_mc_spawn_icon_horse_zombie.png new file mode 100644 index 000000000..de6fe28fc Binary files /dev/null and b/textures/mobs_mc_spawn_icon_horse_zombie.png differ diff --git a/textures/mobs_mc_spawn_icon_husk.png b/textures/mobs_mc_spawn_icon_husk.png new file mode 100644 index 000000000..7d1b75769 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_husk.png differ diff --git a/textures/mobs_mc_spawn_icon_illusioner.png b/textures/mobs_mc_spawn_icon_illusioner.png new file mode 100644 index 000000000..f219cc28b Binary files /dev/null and b/textures/mobs_mc_spawn_icon_illusioner.png differ diff --git a/textures/mobs_mc_spawn_icon_iron_golem.png b/textures/mobs_mc_spawn_icon_iron_golem.png new file mode 100644 index 000000000..f0b1cf745 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_iron_golem.png differ diff --git a/textures/mobs_mc_spawn_icon_killer_bunny.png b/textures/mobs_mc_spawn_icon_killer_bunny.png new file mode 100644 index 000000000..1a3539349 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_killer_bunny.png differ diff --git a/textures/mobs_mc_spawn_icon_llama.png b/textures/mobs_mc_spawn_icon_llama.png new file mode 100644 index 000000000..752c9a570 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_llama.png differ diff --git a/textures/mobs_mc_spawn_icon_magmacube.png b/textures/mobs_mc_spawn_icon_magmacube.png new file mode 100644 index 000000000..b7c929566 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_magmacube.png differ diff --git a/textures/mobs_mc_spawn_icon_mooshroom.png b/textures/mobs_mc_spawn_icon_mooshroom.png new file mode 100644 index 000000000..2fc8300f6 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_mooshroom.png differ diff --git a/textures/mobs_mc_spawn_icon_mule.png b/textures/mobs_mc_spawn_icon_mule.png new file mode 100644 index 000000000..4086a361d Binary files /dev/null and b/textures/mobs_mc_spawn_icon_mule.png differ diff --git a/textures/mobs_mc_spawn_icon_parrot.png b/textures/mobs_mc_spawn_icon_parrot.png new file mode 100644 index 000000000..4962f1917 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_parrot.png differ diff --git a/textures/mobs_mc_spawn_icon_pig.png b/textures/mobs_mc_spawn_icon_pig.png new file mode 100644 index 000000000..c431de73b Binary files /dev/null and b/textures/mobs_mc_spawn_icon_pig.png differ diff --git a/textures/mobs_mc_spawn_icon_polarbear.png b/textures/mobs_mc_spawn_icon_polarbear.png new file mode 100644 index 000000000..b287317d3 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_polarbear.png differ diff --git a/textures/mobs_mc_spawn_icon_rabbit.png b/textures/mobs_mc_spawn_icon_rabbit.png new file mode 100644 index 000000000..9382accbf Binary files /dev/null and b/textures/mobs_mc_spawn_icon_rabbit.png differ diff --git a/textures/mobs_mc_spawn_icon_salmon.png b/textures/mobs_mc_spawn_icon_salmon.png new file mode 100644 index 000000000..d7d94c8fe Binary files /dev/null and b/textures/mobs_mc_spawn_icon_salmon.png differ diff --git a/textures/mobs_mc_spawn_icon_sheep.png b/textures/mobs_mc_spawn_icon_sheep.png new file mode 100644 index 000000000..26c8c81f6 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_sheep.png differ diff --git a/textures/mobs_mc_spawn_icon_shulker.png b/textures/mobs_mc_spawn_icon_shulker.png new file mode 100644 index 000000000..be6a00de9 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_shulker.png differ diff --git a/textures/mobs_mc_spawn_icon_silverfish.png b/textures/mobs_mc_spawn_icon_silverfish.png new file mode 100644 index 000000000..5561016fc Binary files /dev/null and b/textures/mobs_mc_spawn_icon_silverfish.png differ diff --git a/textures/mobs_mc_spawn_icon_skeleton.png b/textures/mobs_mc_spawn_icon_skeleton.png new file mode 100644 index 000000000..4ca867c2f Binary files /dev/null and b/textures/mobs_mc_spawn_icon_skeleton.png differ diff --git a/textures/mobs_mc_spawn_icon_slime.png b/textures/mobs_mc_spawn_icon_slime.png new file mode 100644 index 000000000..c50a330d4 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_slime.png differ diff --git a/textures/mobs_mc_spawn_icon_snowman.png b/textures/mobs_mc_spawn_icon_snowman.png new file mode 100644 index 000000000..d14af8fa1 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_snowman.png differ diff --git a/textures/mobs_mc_spawn_icon_spider.png b/textures/mobs_mc_spawn_icon_spider.png new file mode 100644 index 000000000..a4ba7a8f5 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_spider.png differ diff --git a/textures/mobs_mc_spawn_icon_squid.png b/textures/mobs_mc_spawn_icon_squid.png new file mode 100644 index 000000000..04e8c965d Binary files /dev/null and b/textures/mobs_mc_spawn_icon_squid.png differ diff --git a/textures/mobs_mc_spawn_icon_stray.png b/textures/mobs_mc_spawn_icon_stray.png new file mode 100644 index 000000000..9b8dafa93 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_stray.png differ diff --git a/textures/mobs_mc_spawn_icon_vex.png b/textures/mobs_mc_spawn_icon_vex.png new file mode 100644 index 000000000..3b131389f Binary files /dev/null and b/textures/mobs_mc_spawn_icon_vex.png differ diff --git a/textures/mobs_mc_spawn_icon_villager.png b/textures/mobs_mc_spawn_icon_villager.png new file mode 100644 index 000000000..04e1cfd93 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_villager.png differ diff --git a/textures/mobs_mc_spawn_icon_vindicator.png b/textures/mobs_mc_spawn_icon_vindicator.png new file mode 100644 index 000000000..9080b48f8 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_vindicator.png differ diff --git a/textures/mobs_mc_spawn_icon_witch.png b/textures/mobs_mc_spawn_icon_witch.png new file mode 100644 index 000000000..2b3cf8d87 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_witch.png differ diff --git a/textures/mobs_mc_spawn_icon_wither.png b/textures/mobs_mc_spawn_icon_wither.png new file mode 100644 index 000000000..c1f01c3de Binary files /dev/null and b/textures/mobs_mc_spawn_icon_wither.png differ diff --git a/textures/mobs_mc_spawn_icon_witherskeleton.png b/textures/mobs_mc_spawn_icon_witherskeleton.png new file mode 100644 index 000000000..75694303d Binary files /dev/null and b/textures/mobs_mc_spawn_icon_witherskeleton.png differ diff --git a/textures/mobs_mc_spawn_icon_wolf.png b/textures/mobs_mc_spawn_icon_wolf.png new file mode 100644 index 000000000..a42bd0925 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_wolf.png differ diff --git a/textures/mobs_mc_spawn_icon_zombie.png b/textures/mobs_mc_spawn_icon_zombie.png new file mode 100644 index 000000000..26ee1291f Binary files /dev/null and b/textures/mobs_mc_spawn_icon_zombie.png differ diff --git a/textures/mobs_mc_spawn_icon_zombie_pigman.png b/textures/mobs_mc_spawn_icon_zombie_pigman.png new file mode 100644 index 000000000..461ffcfa7 Binary files /dev/null and b/textures/mobs_mc_spawn_icon_zombie_pigman.png differ diff --git a/textures/mobs_mc_spawn_icon_zombie_villager.png b/textures/mobs_mc_spawn_icon_zombie_villager.png new file mode 100644 index 000000000..f092e6f5f Binary files /dev/null and b/textures/mobs_mc_spawn_icon_zombie_villager.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spider.png b/textures/mobs_mc_spider.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_spider.png rename to textures/mobs_mc_spider.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_spider_eyes.png b/textures/mobs_mc_spider_eyes.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_spider_eyes.png rename to textures/mobs_mc_spider_eyes.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_squid.png b/textures/mobs_mc_squid.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_squid.png rename to textures/mobs_mc_squid.png diff --git a/textures/mobs_mc_stone.png b/textures/mobs_mc_stone.png new file mode 100644 index 000000000..f55c786d2 Binary files /dev/null and b/textures/mobs_mc_stone.png differ diff --git a/textures/mobs_mc_stray.png b/textures/mobs_mc_stray.png new file mode 100644 index 000000000..49cf71bea Binary files /dev/null and b/textures/mobs_mc_stray.png differ diff --git a/textures/mobs_mc_stray_overlay.png b/textures/mobs_mc_stray_overlay.png new file mode 100644 index 000000000..7605eaa8d Binary files /dev/null and b/textures/mobs_mc_stray_overlay.png differ diff --git a/textures/mobs_mc_trading_formspec_bg.png b/textures/mobs_mc_trading_formspec_bg.png new file mode 100644 index 000000000..05b8f5741 Binary files /dev/null and b/textures/mobs_mc_trading_formspec_bg.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_disabled.png b/textures/mobs_mc_trading_formspec_disabled.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_trading_formspec_disabled.png rename to textures/mobs_mc_trading_formspec_disabled.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vex.png b/textures/mobs_mc_vex.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_vex.png rename to textures/mobs_mc_vex.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_vex_charging.png b/textures/mobs_mc_vex_charging.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_vex_charging.png rename to textures/mobs_mc_vex_charging.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager.png b/textures/mobs_mc_villager.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_villager.png rename to textures/mobs_mc_villager.png diff --git a/textures/mobs_mc_villager_armorer.png b/textures/mobs_mc_villager_armorer.png new file mode 100644 index 000000000..6d0eb39b1 Binary files /dev/null and b/textures/mobs_mc_villager_armorer.png differ diff --git a/textures/mobs_mc_villager_butcher.png b/textures/mobs_mc_villager_butcher.png new file mode 100644 index 000000000..025600ff2 Binary files /dev/null and b/textures/mobs_mc_villager_butcher.png differ diff --git a/textures/mobs_mc_villager_cartographer.png b/textures/mobs_mc_villager_cartographer.png new file mode 100644 index 000000000..7ab66072e Binary files /dev/null and b/textures/mobs_mc_villager_cartographer.png differ diff --git a/textures/mobs_mc_villager_farmer.png b/textures/mobs_mc_villager_farmer.png new file mode 100644 index 000000000..851f3a59d Binary files /dev/null and b/textures/mobs_mc_villager_farmer.png differ diff --git a/textures/mobs_mc_villager_fisherman.png b/textures/mobs_mc_villager_fisherman.png new file mode 100644 index 000000000..c394f2e6e Binary files /dev/null and b/textures/mobs_mc_villager_fisherman.png differ diff --git a/textures/mobs_mc_villager_fletcher.png b/textures/mobs_mc_villager_fletcher.png new file mode 100644 index 000000000..d9875ec10 Binary files /dev/null and b/textures/mobs_mc_villager_fletcher.png differ diff --git a/textures/mobs_mc_villager_leatherworker.png b/textures/mobs_mc_villager_leatherworker.png new file mode 100644 index 000000000..ea491713e Binary files /dev/null and b/textures/mobs_mc_villager_leatherworker.png differ diff --git a/textures/mobs_mc_villager_librarian.png b/textures/mobs_mc_villager_librarian.png new file mode 100644 index 000000000..f4a90d6fb Binary files /dev/null and b/textures/mobs_mc_villager_librarian.png differ diff --git a/textures/mobs_mc_villager_mason.png b/textures/mobs_mc_villager_mason.png new file mode 100644 index 000000000..9f9f86d4c Binary files /dev/null and b/textures/mobs_mc_villager_mason.png differ diff --git a/textures/mobs_mc_villager_nitwit.png b/textures/mobs_mc_villager_nitwit.png new file mode 100644 index 000000000..8009f0326 Binary files /dev/null and b/textures/mobs_mc_villager_nitwit.png differ diff --git a/textures/mobs_mc_villager_priest.png b/textures/mobs_mc_villager_priest.png new file mode 100644 index 000000000..38318d4a9 Binary files /dev/null and b/textures/mobs_mc_villager_priest.png differ diff --git a/textures/mobs_mc_villager_sheperd.png b/textures/mobs_mc_villager_sheperd.png new file mode 100644 index 000000000..db3226969 Binary files /dev/null and b/textures/mobs_mc_villager_sheperd.png differ diff --git a/textures/mobs_mc_villager_smith.png b/textures/mobs_mc_villager_smith.png new file mode 100644 index 000000000..8afdc6b29 Binary files /dev/null and b/textures/mobs_mc_villager_smith.png differ diff --git a/textures/mobs_mc_villager_toolsmith.png b/textures/mobs_mc_villager_toolsmith.png new file mode 100644 index 000000000..538a64b99 Binary files /dev/null and b/textures/mobs_mc_villager_toolsmith.png differ diff --git a/textures/mobs_mc_villager_weaponsmith.png b/textures/mobs_mc_villager_weaponsmith.png new file mode 100644 index 000000000..07157a553 Binary files /dev/null and b/textures/mobs_mc_villager_weaponsmith.png differ diff --git a/textures/mobs_mc_vindicator.png b/textures/mobs_mc_vindicator.png new file mode 100644 index 000000000..c47a157a5 Binary files /dev/null and b/textures/mobs_mc_vindicator.png differ diff --git a/textures/mobs_mc_witch.png b/textures/mobs_mc_witch.png new file mode 100644 index 000000000..3227db140 Binary files /dev/null and b/textures/mobs_mc_witch.png differ diff --git a/textures/mobs_mc_wither.png b/textures/mobs_mc_wither.png new file mode 100644 index 000000000..2d4a46e51 Binary files /dev/null and b/textures/mobs_mc_wither.png differ diff --git a/textures/mobs_mc_wither_half_health.png b/textures/mobs_mc_wither_half_health.png new file mode 100644 index 000000000..ff2baa989 Binary files /dev/null and b/textures/mobs_mc_wither_half_health.png differ diff --git a/textures/mobs_mc_wither_skeleton.png b/textures/mobs_mc_wither_skeleton.png new file mode 100644 index 000000000..bb3829af4 Binary files /dev/null and b/textures/mobs_mc_wither_skeleton.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf.png b/textures/mobs_mc_wolf.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf.png rename to textures/mobs_mc_wolf.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_angry.png b/textures/mobs_mc_wolf_angry.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_angry.png rename to textures/mobs_mc_wolf_angry.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_collar.png b/textures/mobs_mc_wolf_collar.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_collar.png rename to textures/mobs_mc_wolf_collar.png diff --git a/textures/mobs_mc_wolf_icon_roam.png b/textures/mobs_mc_wolf_icon_roam.png new file mode 100644 index 000000000..bbd858353 Binary files /dev/null and b/textures/mobs_mc_wolf_icon_roam.png differ diff --git a/textures/mobs_mc_wolf_icon_sit.png b/textures/mobs_mc_wolf_icon_sit.png new file mode 100644 index 000000000..53e18cca9 Binary files /dev/null and b/textures/mobs_mc_wolf_icon_sit.png differ diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_tame.png b/textures/mobs_mc_wolf_tame.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_wolf_tame.png rename to textures/mobs_mc_wolf_tame.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie.png b/textures/mobs_mc_zombie.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie.png rename to textures/mobs_mc_zombie.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_butcher.png b/textures/mobs_mc_zombie_butcher.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_butcher.png rename to textures/mobs_mc_zombie_butcher.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_farmer.png b/textures/mobs_mc_zombie_farmer.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_farmer.png rename to textures/mobs_mc_zombie_farmer.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_librarian.png b/textures/mobs_mc_zombie_librarian.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_librarian.png rename to textures/mobs_mc_zombie_librarian.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_pigman.png b/textures/mobs_mc_zombie_pigman.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_pigman.png rename to textures/mobs_mc_zombie_pigman.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_priest.png b/textures/mobs_mc_zombie_priest.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_priest.png rename to textures/mobs_mc_zombie_priest.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_smith.png b/textures/mobs_mc_zombie_smith.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_smith.png rename to textures/mobs_mc_zombie_smith.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_villager.png b/textures/mobs_mc_zombie_villager.png similarity index 100% rename from mods/ENTITIES/mobs_mc/textures/mobs_mc_zombie_villager.png rename to textures/mobs_mc_zombie_villager.png diff --git a/mods/ENTITIES/mcl_mobs/textures/mobs_nametag.png b/textures/mobs_nametag.png similarity index 100% rename from mods/ENTITIES/mcl_mobs/textures/mobs_nametag.png rename to textures/mobs_nametag.png diff --git a/textures/nether_wart_block.png b/textures/nether_wart_block.png new file mode 100644 index 000000000..b9c4e447e Binary files /dev/null and b/textures/nether_wart_block.png differ diff --git a/textures/object_crosshair.png b/textures/object_crosshair.png new file mode 100644 index 000000000..da9938670 Binary files /dev/null and b/textures/object_crosshair.png differ diff --git a/textures/player.png b/textures/player.png new file mode 100644 index 000000000..c738752ee Binary files /dev/null and b/textures/player.png differ diff --git a/textures/player_back.png b/textures/player_back.png new file mode 100644 index 000000000..39e143c3b Binary files /dev/null and b/textures/player_back.png differ diff --git a/mods/ITEMS/REDSTONE/mesecons_torch/textures/redstone_redstone_block.png b/textures/redstone_redstone_block.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_torch/textures/redstone_redstone_block.png rename to textures/redstone_redstone_block.png diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust.png b/textures/redstone_redstone_dust.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust.png rename to textures/redstone_redstone_dust.png diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_dot.png b/textures/redstone_redstone_dust_dot.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_dot.png rename to textures/redstone_redstone_dust_dot.png diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_line0.png b/textures/redstone_redstone_dust_line0.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_line0.png rename to textures/redstone_redstone_dust_line0.png diff --git a/mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_line1.png b/textures/redstone_redstone_dust_line1.png similarity index 100% rename from mods/ITEMS/REDSTONE/mesecons_wires/textures/redstone_redstone_dust_line1.png rename to textures/redstone_redstone_dust_line1.png diff --git a/textures/respawn_anchor_bottom.png b/textures/respawn_anchor_bottom.png new file mode 100644 index 000000000..b4f1caf73 Binary files /dev/null and b/textures/respawn_anchor_bottom.png differ diff --git a/textures/respawn_anchor_side0.png b/textures/respawn_anchor_side0.png new file mode 100644 index 000000000..21070e311 Binary files /dev/null and b/textures/respawn_anchor_side0.png differ diff --git a/textures/respawn_anchor_side1.png b/textures/respawn_anchor_side1.png new file mode 100644 index 000000000..967b6f11b Binary files /dev/null and b/textures/respawn_anchor_side1.png differ diff --git a/textures/respawn_anchor_side2.png b/textures/respawn_anchor_side2.png new file mode 100644 index 000000000..555bd4e29 Binary files /dev/null and b/textures/respawn_anchor_side2.png differ diff --git a/textures/respawn_anchor_side3.png b/textures/respawn_anchor_side3.png new file mode 100644 index 000000000..775d54847 Binary files /dev/null and b/textures/respawn_anchor_side3.png differ diff --git a/textures/respawn_anchor_side4.png b/textures/respawn_anchor_side4.png new file mode 100644 index 000000000..649ec399a Binary files /dev/null and b/textures/respawn_anchor_side4.png differ diff --git a/textures/respawn_anchor_top_off.png b/textures/respawn_anchor_top_off.png new file mode 100644 index 000000000..31937ff7b Binary files /dev/null and b/textures/respawn_anchor_top_off.png differ diff --git a/textures/respawn_anchor_top_on.png b/textures/respawn_anchor_top_on.png new file mode 100644 index 000000000..1db663a6e Binary files /dev/null and b/textures/respawn_anchor_top_on.png differ diff --git a/textures/screwdriver.png b/textures/screwdriver.png new file mode 100644 index 000000000..8e3409752 Binary files /dev/null and b/textures/screwdriver.png differ diff --git a/mods/HUD/mcl_base_textures/textures/smoke_puff.png b/textures/smoke_puff.png similarity index 100% rename from mods/HUD/mcl_base_textures/textures/smoke_puff.png rename to textures/smoke_puff.png diff --git a/textures/smoker_bottom.png b/textures/smoker_bottom.png new file mode 100644 index 000000000..a0598b34d Binary files /dev/null and b/textures/smoker_bottom.png differ diff --git a/textures/smoker_front.png b/textures/smoker_front.png new file mode 100644 index 000000000..8871bf9b1 Binary files /dev/null and b/textures/smoker_front.png differ diff --git a/textures/smoker_front_on.png b/textures/smoker_front_on.png new file mode 100644 index 000000000..d4ebda2b4 Binary files /dev/null and b/textures/smoker_front_on.png differ diff --git a/textures/smoker_side.png b/textures/smoker_side.png new file mode 100644 index 000000000..567b895b8 Binary files /dev/null and b/textures/smoker_side.png differ diff --git a/textures/smoker_top.png b/textures/smoker_top.png new file mode 100644 index 000000000..fc39d5fe5 Binary files /dev/null and b/textures/smoker_top.png differ diff --git a/textures/soul_fire_basic_flame.png b/textures/soul_fire_basic_flame.png new file mode 100644 index 000000000..e1309a952 Binary files /dev/null and b/textures/soul_fire_basic_flame.png differ diff --git a/textures/soul_fire_basic_flame_animated.png b/textures/soul_fire_basic_flame_animated.png new file mode 100644 index 000000000..be6ba773e Binary files /dev/null and b/textures/soul_fire_basic_flame_animated.png differ diff --git a/textures/soul_mcl_burning_entity_flame_animated.png b/textures/soul_mcl_burning_entity_flame_animated.png new file mode 100644 index 000000000..be6ba773e Binary files /dev/null and b/textures/soul_mcl_burning_entity_flame_animated.png differ diff --git a/textures/soul_mcl_burning_hud_flame_animated.png b/textures/soul_mcl_burning_hud_flame_animated.png new file mode 100644 index 000000000..be6ba773e Binary files /dev/null and b/textures/soul_mcl_burning_hud_flame_animated.png differ diff --git a/textures/soul_torch_on_floor.png b/textures/soul_torch_on_floor.png new file mode 100644 index 000000000..4e186d76c Binary files /dev/null and b/textures/soul_torch_on_floor.png differ diff --git a/textures/soul_torch_on_floor_animated.png b/textures/soul_torch_on_floor_animated.png new file mode 100644 index 000000000..d1b5ce2ea Binary files /dev/null and b/textures/soul_torch_on_floor_animated.png differ diff --git a/textures/spawn_egg.png b/textures/spawn_egg.png new file mode 100644 index 000000000..67a6fda4b Binary files /dev/null and b/textures/spawn_egg.png differ diff --git a/textures/spawn_egg_overlay.png b/textures/spawn_egg_overlay.png new file mode 100644 index 000000000..fd0aa48a1 Binary files /dev/null and b/textures/spawn_egg_overlay.png differ diff --git a/textures/sunrisebg.png b/textures/sunrisebg.png new file mode 100644 index 000000000..8f22cc6fe Binary files /dev/null and b/textures/sunrisebg.png differ diff --git a/textures/sus_stew.png b/textures/sus_stew.png new file mode 100644 index 000000000..5a4910ef0 Binary files /dev/null and b/textures/sus_stew.png differ diff --git a/textures/weather_pack_rain_raindrop_1.png b/textures/weather_pack_rain_raindrop_1.png new file mode 100644 index 000000000..be92679f4 Binary files /dev/null and b/textures/weather_pack_rain_raindrop_1.png differ diff --git a/textures/weather_pack_rain_raindrop_2.png b/textures/weather_pack_rain_raindrop_2.png new file mode 100644 index 000000000..eb0cac5f0 Binary files /dev/null and b/textures/weather_pack_rain_raindrop_2.png differ diff --git a/textures/weather_pack_rain_raindrop_3.png b/textures/weather_pack_rain_raindrop_3.png new file mode 100644 index 000000000..79020dcd1 Binary files /dev/null and b/textures/weather_pack_rain_raindrop_3.png differ diff --git a/textures/weather_pack_snow_snowflake1.png b/textures/weather_pack_snow_snowflake1.png new file mode 100644 index 000000000..1c609810f Binary files /dev/null and b/textures/weather_pack_snow_snowflake1.png differ diff --git a/textures/weather_pack_snow_snowflake2.png b/textures/weather_pack_snow_snowflake2.png new file mode 100644 index 000000000..949e27662 Binary files /dev/null and b/textures/weather_pack_snow_snowflake2.png differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_black.png b/textures/wool_black.png similarity index 100% rename from mods/ITEMS/mcl_wool/textures/wool_black.png rename to textures/wool_black.png diff --git a/mods/ITEMS/mcl_wool/textures/wool_blue.png b/textures/wool_blue.png similarity index 100% rename from mods/ITEMS/mcl_wool/textures/wool_blue.png rename to textures/wool_blue.png diff --git a/textures/wool_brown.png b/textures/wool_brown.png new file mode 100644 index 000000000..fac3ceffd Binary files /dev/null and b/textures/wool_brown.png differ diff --git a/textures/wool_cyan.png b/textures/wool_cyan.png new file mode 100644 index 000000000..25d3e2f07 Binary files /dev/null and b/textures/wool_cyan.png differ diff --git a/textures/wool_dark_green.png b/textures/wool_dark_green.png new file mode 100644 index 000000000..9d17bfdc3 Binary files /dev/null and b/textures/wool_dark_green.png differ diff --git a/textures/wool_dark_grey.png b/textures/wool_dark_grey.png new file mode 100644 index 000000000..aa0be74be Binary files /dev/null and b/textures/wool_dark_grey.png differ diff --git a/textures/wool_grey.png b/textures/wool_grey.png new file mode 100644 index 000000000..e604a9146 Binary files /dev/null and b/textures/wool_grey.png differ diff --git a/textures/wool_magenta.png b/textures/wool_magenta.png new file mode 100644 index 000000000..f6889b447 Binary files /dev/null and b/textures/wool_magenta.png differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_orange.png b/textures/wool_orange.png similarity index 100% rename from mods/ITEMS/mcl_wool/textures/wool_orange.png rename to textures/wool_orange.png diff --git a/mods/ITEMS/mcl_wool/textures/wool_pink.png b/textures/wool_pink.png similarity index 100% rename from mods/ITEMS/mcl_wool/textures/wool_pink.png rename to textures/wool_pink.png diff --git a/textures/wool_red.png b/textures/wool_red.png new file mode 100644 index 000000000..1602f0ea2 Binary files /dev/null and b/textures/wool_red.png differ diff --git a/textures/wool_violet.png b/textures/wool_violet.png new file mode 100644 index 000000000..92a20df29 Binary files /dev/null and b/textures/wool_violet.png differ diff --git a/textures/wool_white.png b/textures/wool_white.png new file mode 100644 index 000000000..c3695550f Binary files /dev/null and b/textures/wool_white.png differ diff --git a/mods/ITEMS/mcl_wool/textures/wool_yellow.png b/textures/wool_yellow.png similarity index 100% rename from mods/ITEMS/mcl_wool/textures/wool_yellow.png rename to textures/wool_yellow.png diff --git a/textures/xpanes_pane_iron.png b/textures/xpanes_pane_iron.png new file mode 100644 index 000000000..8424b4626 Binary files /dev/null and b/textures/xpanes_pane_iron.png differ diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_black.png b/textures/xpanes_top_glass_black.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_black.png rename to textures/xpanes_top_glass_black.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_blue.png b/textures/xpanes_top_glass_blue.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_blue.png rename to textures/xpanes_top_glass_blue.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_brown.png b/textures/xpanes_top_glass_brown.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_brown.png rename to textures/xpanes_top_glass_brown.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_cyan.png b/textures/xpanes_top_glass_cyan.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_cyan.png rename to textures/xpanes_top_glass_cyan.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_gray.png b/textures/xpanes_top_glass_gray.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_gray.png rename to textures/xpanes_top_glass_gray.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_green.png b/textures/xpanes_top_glass_green.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_green.png rename to textures/xpanes_top_glass_green.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_light_blue.png b/textures/xpanes_top_glass_light_blue.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_light_blue.png rename to textures/xpanes_top_glass_light_blue.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_lime.png b/textures/xpanes_top_glass_lime.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_lime.png rename to textures/xpanes_top_glass_lime.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_magenta.png b/textures/xpanes_top_glass_magenta.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_magenta.png rename to textures/xpanes_top_glass_magenta.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_natural.png b/textures/xpanes_top_glass_natural.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_natural.png rename to textures/xpanes_top_glass_natural.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_orange.png b/textures/xpanes_top_glass_orange.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_orange.png rename to textures/xpanes_top_glass_orange.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_pink.png b/textures/xpanes_top_glass_pink.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_pink.png rename to textures/xpanes_top_glass_pink.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_purple.png b/textures/xpanes_top_glass_purple.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_purple.png rename to textures/xpanes_top_glass_purple.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_red.png b/textures/xpanes_top_glass_red.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_red.png rename to textures/xpanes_top_glass_red.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_silver.png b/textures/xpanes_top_glass_silver.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_silver.png rename to textures/xpanes_top_glass_silver.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_white.png b/textures/xpanes_top_glass_white.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_white.png rename to textures/xpanes_top_glass_white.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_glass_yellow.png b/textures/xpanes_top_glass_yellow.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_glass_yellow.png rename to textures/xpanes_top_glass_yellow.png diff --git a/mods/ITEMS/xpanes/textures/xpanes_top_iron.png b/textures/xpanes_top_iron.png similarity index 100% rename from mods/ITEMS/xpanes/textures/xpanes_top_iron.png rename to textures/xpanes_top_iron.png diff --git a/tools/Conversion_Table.csv b/tools/Conversion_Table.csv index 426712f5b..9dc50dc7a 100644 --- a/tools/Conversion_Table.csv +++ b/tools/Conversion_Table.csv @@ -10,7 +10,7 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? /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,bucket_lava.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,,,,,,, @@ -176,7 +176,7 @@ Source path,Source file,Target path,Target file,xs,ys,xl,yl,xt,yt,Blacklisted? /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,default_papyrus.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,,,,,,, diff --git a/tools/README.md b/tools/README.md index abcc73ae3..4dc378bc1 100644 --- a/tools/README.md +++ b/tools/README.md @@ -27,3 +27,17 @@ Usage: - Convert the textures - Put the new texture directory in the Minetest texture pack directory, just like any other Minetest texture pack + +## Luacheck Globals Generators +This is a Python script which list every single global tables in mineclone2 source code. +It outputs a list to be used in luacheck conf files. + +Modes of operation: +- List global tables + +Requirements: +- Know how to use the console +- Python 3 + +Usage: +- In the console, run `python3 ./tools/create_luacheck.py` in the MineClone2 directory diff --git a/tools/Texture_Converter.py b/tools/Texture_Converter.py index c23bc9fce..67800ccfc 100755 --- a/tools/Texture_Converter.py +++ b/tools/Texture_Converter.py @@ -118,17 +118,6 @@ 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) -# This function is unused atm. -# TODO: Implemnt colormap extraction -def extract_colormap(colormap, colormap_pixel, positions): - os.system("convert -size 16x16 canvas:black "+tempfile1.name) - x=0 - y=0 - for p in positions: - os.system("convert "+colormap+" -crop 1x1+"+colormap_pixel+" -depth 8 "+tempfile2.name) - os.system("composite -geometry 16x16+"+x+"+"+y+" "+tempfile2.name) - x = x+1 - def target_dir(directory): if make_texture_pack: return output_dir + "/" + output_dir_name @@ -196,13 +185,19 @@ def convert_textures(): 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/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 @@ -392,20 +387,60 @@ def convert_textures(): 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 = "49+172" # Plains grass color + 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") - # TODO: Convert grass palette - - offset = [ - [ pcol, "", "grass" ], # Default grass: Plains + # 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) ] - for o in offset: - colorize(GRASS, tex_dir+"/blocks/grass_top.png", o[0], str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_"+o[2]+".png") - colorize_alpha(GRASS, tex_dir+"/blocks/grass_side_overlay.png", o[0], str(PXSIZE), target_dir("/mods/ITEMS/mcl_core/textures")+"/default_"+o[2]+"_side.png") + + 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: diff --git a/tools/analyze-packet-spam b/tools/analyze-packet-spam new file mode 100755 index 000000000..310616fd9 --- /dev/null +++ b/tools/analyze-packet-spam @@ -0,0 +1,60 @@ +#!/bin/sh -eu +# analyze-packet-spam – show minetest client packet count per second +# Copyright © 2021 Nils Dagsson Moskopp (erlehmann) + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# Dieses Programm hat das Ziel, die Medienkompetenz der Leser zu +# steigern. Gelegentlich packe ich sogar einen handfesten Buffer +# Overflow oder eine Format String Vulnerability zwischen die anderen +# Codezeilen und schreibe das auch nicht dran. + +# This script takes a minetest log with at least INFO log level and +# outputs the MINETEST network protocol packet count per second. + +# To collect such a log file of minetest running for 10 minutes, run: +# timeout 600 minetest --info >log.txt 2>&1 >/dev/null + +# To get packet counts from that file, run: +# ./analyze-packet-spam "${TEMPFILE}" + +TIMESTAMP_START=$( <"${TEMPFILE}" head -n1 |cut -d' ' -f1 ) +TIMESTAMP_END=$( <"${TEMPFILE}" tail -n1 |cut -d' ' -f1 ) +DURATION=$(( 30 + ${TIMESTAMP_END} - ${TIMESTAMP_START} )) + +PACKET_NAME_SEEN='' +<"${TEMPFILE}" tac \ + |while read _ PACKET_NAME PACKET_COUNT; do + case "${PACKET_NAME_SEEN}" in + *"${PACKET_NAME}"*) + ;; + *) + PACKET_COUNT_PER_SECOND=$( + printf '1k %s %s /p' "${PACKET_COUNT}" "${DURATION}" \ + |dc + ) + printf '%s\t%s\n' "${PACKET_COUNT_PER_SECOND}" "${PACKET_NAME}" + PACKET_NAME_SEEN="${PACKET_NAME_SEEN} ${PACKET_NAME}" + ;; + esac + done + +unlink "${TEMPFILE}" diff --git a/tools/check_translate_files.py b/tools/check_translate_files.py index 445dc9151..ec3c3944a 100644 --- a/tools/check_translate_files.py +++ b/tools/check_translate_files.py @@ -1,8 +1,9 @@ # Output indicator # !< Indicates a text line without '=' in template.txt -# << Indicates an untranslated line in template.txt +# << Indicates an untranslated line in template.txt or an extra line in translate file (.tr) # !> Indicates a text line without '=' in translate file (.tr) # >> Indicates an unknown translated line in translate file (.tr) +# >= Indicate an untrannslated entry in translate file (.tr) # >> Missing file: Indicates a missing translate file (.tr) import os @@ -15,7 +16,7 @@ args = parser.parse_args() path = "../mods/" code_lang = args.language -def LoadTranslateFile(filename, direction): +def LoadTranslateFile(filename, direction, ref=None): result = set() file = open(filename, 'r', encoding="utf-8") for line in file: @@ -23,15 +24,18 @@ def LoadTranslateFile(filename, direction): if line.startswith('#') or line == '': continue if '=' in line: - result.add(line.split('=')[0]) + parts = line.split('=') + result.add(parts[0]) + if ref is not None and parts[1] == '' and parts[1] not in ref : + print ('>= ' + parts[0]) else: print (direction + line) return result def CompareFiles(f1, f2): - r1 = LoadTranslateFile(f1, "!> ") - r2 = LoadTranslateFile(f2, "!< ") + r1 = LoadTranslateFile(f1, "!< ") + r2 = LoadTranslateFile(f2, "!> ", r1) for key in r1.difference(r2): print (">> " + key ) @@ -57,5 +61,5 @@ for root, directories, files in os.walk(path): print("Compare files %s with %s" % (template, language)) CompareFiles(template, language) else: - LoadTranslateFile(filename, "!> ") + LoadTranslateFile(template, "!< ") print(">> Missing file = " + language) diff --git a/tools/colors.txt b/tools/colors.txt new file mode 100644 index 000000000..de20aa49a --- /dev/null +++ b/tools/colors.txt @@ -0,0 +1,2240 @@ +## Mcl2 colors.txt file for minetestmapper +## by Ranko Saotome using the tools provided by minetestmapper + +# mcl_amethyst +mcl_amethyst:amethyst_block 143 94 174 +mcl_amethyst:amethyst_cluster 165 121 193 +mcl_amethyst:budding_amethyst_block 138 88 170 +mcl_amethyst:calcite 189 193 207 +mcl_amethyst:large_amethyst_bud 177 136 203 +mcl_amethyst:medium_amethyst_bud 187 148 212 +mcl_amethyst:small_amethyst_bud 181 140 206 +mcl_amethyst:tinted_glass 126 74 160 + +# mcl_anvils +mcl_anvils:anvil 53 53 53 +mcl_anvils:anvil_damage_1 52 52 52 +mcl_anvils:anvil_damage_2 50 50 50 + +# mcl_armor_stand +mcl_armor_stand:armor_stand 115 89 68 + +# mcl_banners +mcl_banners:hanging_banner 102 88 74 +mcl_banners:standing_banner 102 88 74 + +# mcl_barrels +mcl_barrels:barrel_closed 81 63 49 +mcl_barrels:barrel_open 60 46 36 + +# mcl_beacons +mcl_beacons:beacon 116 168 197 + +# mcl_beds +mcl_beds:bed_black_bottom 109 90 78 +mcl_beds:bed_black_top 109 90 78 +mcl_beds:bed_blue_bottom 108 98 107 +mcl_beds:bed_blue_top 108 98 107 +mcl_beds:bed_brown_bottom 121 94 79 +mcl_beds:bed_brown_top 121 94 79 +mcl_beds:bed_cyan_bottom 109 106 102 +mcl_beds:bed_cyan_top 109 106 102 +mcl_beds:bed_green_bottom 109 103 79 +mcl_beds:bed_green_top 109 103 79 +mcl_beds:bed_grey_bottom 119 100 89 +mcl_beds:bed_grey_top 119 100 89 +mcl_beds:bed_light_blue_bottom 118 118 134 +mcl_beds:bed_light_blue_top 118 118 134 +mcl_beds:bed_lime_bottom 122 123 87 +mcl_beds:bed_lime_top 122 123 87 +mcl_beds:bed_magenta_bottom 136 101 112 +mcl_beds:bed_magenta_top 136 101 112 +mcl_beds:bed_orange_bottom 152 107 81 +mcl_beds:bed_orange_top 152 107 81 +mcl_beds:bed_pink_bottom 152 111 106 +mcl_beds:bed_pink_top 152 111 106 +mcl_beds:bed_purple_bottom 119 94 102 +mcl_beds:bed_purple_top 119 94 102 +mcl_beds:bed_red_bottom 136 90 79 +mcl_beds:bed_red_top 136 90 79 +mcl_beds:bed_silver_bottom 137 118 109 +mcl_beds:bed_silver_top 137 118 109 +mcl_beds:bed_white_bottom 170 152 135 +mcl_beds:bed_white_top 170 152 135 +mcl_beds:bed_yellow_bottom 161 134 86 +mcl_beds:bed_yellow_top 161 134 86 +mcl_beds:respawn_anchor 93 75 91 +mcl_beds:respawn_anchor_charged_1 105 75 136 +mcl_beds:respawn_anchor_charged_2 105 75 136 +mcl_beds:respawn_anchor_charged_3 105 75 136 +mcl_beds:respawn_anchor_charged_4 105 75 136 + +# mcl_bells +mcl_bells:bell 207 203 82 + +# mcl_blackstone +mcl_blackstone:basalt 71 71 71 +mcl_blackstone:basalt_polished 80 79 79 +mcl_blackstone:basalt_smooth 88 87 88 +mcl_blackstone:blackstone 33 31 35 +mcl_blackstone:blackstone_brick_polished 42 39 44 +mcl_blackstone:blackstone_chiseled_polished 42 39 44 +mcl_blackstone:blackstone_gilded 33 31 35 +mcl_blackstone:blackstone_polished 44 42 47 +mcl_blackstone:nether_gold 133 52 40 +mcl_blackstone:quartz_brick 190 185 182 +mcl_blackstone:soul_fire 89 169 169 +mcl_blackstone:soul_soil 94 72 54 +mcl_blackstone:soul_torch 98 108 100 +mcl_blackstone:soul_torch_wall 98 108 100 +mcl_blackstone:wall 33 31 35 +mcl_blackstone:wall_0 33 31 35 +mcl_blackstone:wall_1 33 31 35 +mcl_blackstone:wall_10 33 31 35 +mcl_blackstone:wall_11 33 31 35 +mcl_blackstone:wall_12 33 31 35 +mcl_blackstone:wall_13 33 31 35 +mcl_blackstone:wall_14 33 31 35 +mcl_blackstone:wall_15 33 31 35 +mcl_blackstone:wall_16 33 31 35 +mcl_blackstone:wall_2 33 31 35 +mcl_blackstone:wall_21 33 31 35 +mcl_blackstone:wall_3 33 31 35 +mcl_blackstone:wall_4 33 31 35 +mcl_blackstone:wall_5 33 31 35 +mcl_blackstone:wall_6 33 31 35 +mcl_blackstone:wall_7 33 31 35 +mcl_blackstone:wall_8 33 31 35 +mcl_blackstone:wall_9 33 31 35 + +# mcl_blast_furnace +mcl_blast_furnace:blast_furnace 130 120 115 +mcl_blast_furnace:blast_furnace_active 130 120 115 + +# mcl_books +mcl_books:bookshelf 111 86 66 + +# mcl_brewing +mcl_brewing:stand_000 141 134 134 +mcl_brewing:stand_001 141 134 134 +mcl_brewing:stand_010 141 134 134 +mcl_brewing:stand_011 141 134 134 +mcl_brewing:stand_100 141 134 134 +mcl_brewing:stand_101 141 134 134 +mcl_brewing:stand_110 141 134 134 +mcl_brewing:stand_111 141 134 134 + +# mcl_cake +mcl_cake:cake 241 233 231 +mcl_cake:cake_1 241 233 231 +mcl_cake:cake_2 241 233 231 +mcl_cake:cake_3 241 233 231 +mcl_cake:cake_4 241 233 231 +mcl_cake:cake_5 241 233 231 +mcl_cake:cake_6 241 233 231 + +# mcl_campfires +mcl_campfires:campfire 83 69 65 +mcl_campfires:campfire_lit 210 114 39 +mcl_campfires:soul_campfire 83 69 65 +mcl_campfires:soul_campfire_lit 39 189 195 + +# mcl_cartography_table +mcl_cartography_table:cartography_table 127 110 96 + +# mcl_cauldrons +mcl_cauldrons:cauldron 25 25 25 +mcl_cauldrons:cauldron_1 38 98 129 +mcl_cauldrons:cauldron_1_lava 183 54 21 +mcl_cauldrons:cauldron_1r 32 121 138 +mcl_cauldrons:cauldron_2 38 98 129 +mcl_cauldrons:cauldron_2_lava 183 54 21 +mcl_cauldrons:cauldron_2r 32 121 138 +mcl_cauldrons:cauldron_3 38 98 129 +mcl_cauldrons:cauldron_3_lava 183 54 21 +mcl_cauldrons:cauldron_3r 32 121 138 + +# mcl_chests +mcl_chests:black_shulker_box 101 92 87 +mcl_chests:blue_shulker_box 107 109 128 +mcl_chests:brown_shulker_box 110 95 82 +mcl_chests:chest 100 79 62 +mcl_chests:cyan_shulker_box 107 121 130 +mcl_chests:dark_green_shulker_box 107 128 92 +mcl_chests:dark_grey_shulker_box 119 112 113 +mcl_chests:dark_grey_shulker_box_small 0 0 0 +mcl_chests:ender_chest 75 68 62 +mcl_chests:green_shulker_box 120 136 95 +mcl_chests:grey_shulker_box 147 142 145 +mcl_chests:lightblue_shulker_box 124 143 159 +mcl_chests:magenta_shulker_box 148 106 132 +mcl_chests:orange_shulker_box 160 102 80 +mcl_chests:pink_shulker_box 176 131 161 +mcl_chests:red_shulker_box 151 92 83 +mcl_chests:trapped_chest 100 79 62 +mcl_chests:trapped_chest_on 100 79 62 +mcl_chests:violet_shulker_box 142 99 104 +mcl_chests:white_shulker_box 186 183 187 +mcl_chests:yellow_shulker_box 178 132 81 + +# mcl_cocoas +mcl_cocoas:cocoa_3 140 74 54 + +# mcl_colorblocks +mcl_colorblocks:concrete_black 8 10 15 +mcl_colorblocks:concrete_blue 46 48 147 +mcl_colorblocks:concrete_brown 98 60 32 +mcl_colorblocks:concrete_cyan 21 123 140 +mcl_colorblocks:concrete_green 75 94 37 +mcl_colorblocks:concrete_grey 56 59 64 +mcl_colorblocks:concrete_light_blue 37 140 200 +mcl_colorblocks:concrete_lime 96 171 25 +mcl_colorblocks:concrete_magenta 171 49 162 +mcl_colorblocks:concrete_orange 226 101 1 +mcl_colorblocks:concrete_pink 213 103 144 +mcl_colorblocks:concrete_powder_black 23 26 30 +mcl_colorblocks:concrete_powder_blue 72 76 169 +mcl_colorblocks:concrete_powder_brown 128 87 54 +mcl_colorblocks:concrete_powder_cyan 38 150 160 +mcl_colorblocks:concrete_powder_green 104 127 45 +mcl_colorblocks:concrete_powder_grey 91 98 103 +mcl_colorblocks:concrete_powder_light_blue 76 181 212 +mcl_colorblocks:concrete_powder_lime 126 186 42 +mcl_colorblocks:concrete_powder_magenta 196 94 189 +mcl_colorblocks:concrete_powder_orange 227 141 38 +mcl_colorblocks:concrete_powder_pink 224 149 176 +mcl_colorblocks:concrete_powder_purple 138 58 180 +mcl_colorblocks:concrete_powder_red 172 57 52 +mcl_colorblocks:concrete_powder_silver 160 160 155 +mcl_colorblocks:concrete_powder_white 224 225 225 +mcl_colorblocks:concrete_powder_yellow 230 198 54 +mcl_colorblocks:concrete_purple 103 32 159 +mcl_colorblocks:concrete_red 146 34 34 +mcl_colorblocks:concrete_silver 128 129 118 +mcl_colorblocks:concrete_white 208 214 215 +mcl_colorblocks:concrete_yellow 241 177 21 +mcl_colorblocks:glazed_terracotta_black 61 28 28 +mcl_colorblocks:glazed_terracotta_blue 35 83 135 +mcl_colorblocks:glazed_terracotta_brown 116 93 73 +mcl_colorblocks:glazed_terracotta_cyan 117 144 148 +mcl_colorblocks:glazed_terracotta_green 122 141 83 +mcl_colorblocks:glazed_terracotta_grey 96 96 96 +mcl_colorblocks:glazed_terracotta_light_blue 123 174 208 +mcl_colorblocks:glazed_terracotta_lime 160 213 86 +mcl_colorblocks:glazed_terracotta_magenta 210 112 216 +mcl_colorblocks:glazed_terracotta_orange 196 150 102 +mcl_colorblocks:glazed_terracotta_pink 251 145 173 +mcl_colorblocks:glazed_terracotta_purple 118 55 159 +mcl_colorblocks:glazed_terracotta_red 189 72 63 +mcl_colorblocks:glazed_terracotta_silver 150 160 160 +mcl_colorblocks:glazed_terracotta_white 205 217 219 +mcl_colorblocks:glazed_terracotta_yellow 236 205 111 +mcl_colorblocks:hardened_clay 143 104 88 +mcl_colorblocks:hardened_clay_black 70 53 46 +mcl_colorblocks:hardened_clay_blue 68 91 143 +mcl_colorblocks:hardened_clay_brown 96 69 61 +mcl_colorblocks:hardened_clay_cyan 71 108 124 +mcl_colorblocks:hardened_clay_green 75 102 63 +mcl_colorblocks:hardened_clay_grey 110 92 85 +mcl_colorblocks:hardened_clay_light_blue 91 128 171 +mcl_colorblocks:hardened_clay_lime 106 135 73 +mcl_colorblocks:hardened_clay_magenta 150 80 85 +mcl_colorblocks:hardened_clay_orange 157 95 70 +mcl_colorblocks:hardened_clay_pink 164 80 76 +mcl_colorblocks:hardened_clay_purple 82 71 124 +mcl_colorblocks:hardened_clay_red 159 82 67 +mcl_colorblocks:hardened_clay_silver 149 129 117 +mcl_colorblocks:hardened_clay_white 213 197 184 +mcl_colorblocks:hardened_clay_yellow 177 128 51 + +# mcl_comparators +mcl_comparators:comparator_off_comp 116 106 102 +mcl_comparators:comparator_off_sub 116 106 102 +mcl_comparators:comparator_on_comp 118 106 102 +mcl_comparators:comparator_on_sub 118 106 102 + +# mcl_compass +mcl_compass:lodestone 86 76 72 + +# mcl_composters +mcl_composters:composter 143 112 88 +mcl_composters:composter_1 76 76 41 +mcl_composters:composter_2 76 76 41 +mcl_composters:composter_3 76 76 41 +mcl_composters:composter_4 76 76 41 +mcl_composters:composter_5 76 76 41 +mcl_composters:composter_6 76 76 41 +mcl_composters:composter_7 76 76 41 +mcl_composters:composter_ready 124 120 95 + +# mcl_copper +mcl_copper:block 150 78 57 +mcl_copper:block_cut 150 78 58 +mcl_copper:block_exposed 130 94 84 +mcl_copper:block_exposed_cut 132 94 84 +mcl_copper:block_oxidized 90 110 111 +mcl_copper:block_oxidized_cut 91 112 112 +mcl_copper:block_raw 171 91 69 +mcl_copper:block_weathered 104 104 102 +mcl_copper:block_weathered_cut 109 105 102 +mcl_copper:stone_with_copper 131 123 118 + +# mcl_core +mcl_core:acacialeaves 110 88 44 +mcl_core:acaciasapling 111 94 65 +mcl_core:acaciatree 137 89 58 +mcl_core:acaciatree_bark 107 94 77 +mcl_core:acaciawood 153 103 71 +mcl_core:andesite 105 111 107 +mcl_core:andesite_smooth 107 114 110 +mcl_core:bedrock 92 79 68 +mcl_core:birchleaves 27 56 27 +mcl_core:birchsapling 93 114 84 +mcl_core:birchtree 160 137 119 +mcl_core:birchtree_bark 199 190 180 +mcl_core:birchwood 147 116 90 +mcl_core:bone_block 222 203 171 +mcl_core:brick_block 140 92 81 +mcl_core:cactus 90 106 66 +mcl_core:clay 124 124 124 +mcl_core:coalblock 54 51 54 +mcl_core:coarse_dirt 119 94 78 +mcl_core:cobble 114 108 105 +mcl_core:cobweb 203 190 168 +mcl_core:crying_obsidian 26 19 41 +mcl_core:darkleaves 20 69 28 +mcl_core:darksapling 70 98 85 +mcl_core:darktree 87 74 66 +mcl_core:darktree_bark 77 65 58 +mcl_core:darkwood 89 76 63 +mcl_core:deadbush 121 91 70 +mcl_core:diamondblock 98 164 203 +mcl_core:diorite 154 150 148 +mcl_core:diorite_smooth 158 155 153 +mcl_core:dirt 109 84 70 +mcl_core:dirt_with_grass 64 111 26 +mcl_core:dirt_with_grass_snow 221 229 234 +mcl_core:emeraldblock 56 146 49 +mcl_core:frosted_ice_0 141 194 224 +mcl_core:frosted_ice_1 149 199 227 +mcl_core:frosted_ice_2 155 203 229 +mcl_core:frosted_ice_3 168 210 233 +mcl_core:glass 215 224 235 +mcl_core:glass_black 25 25 25 +mcl_core:glass_blue 51 76 178 +mcl_core:glass_brown 102 76 51 +mcl_core:glass_cyan 76 127 153 +mcl_core:glass_gray 76 76 76 +mcl_core:glass_green 102 127 51 +mcl_core:glass_light_blue 102 153 216 +mcl_core:glass_lime 127 204 25 +mcl_core:glass_magenta 178 76 216 +mcl_core:glass_orange 216 127 51 +mcl_core:glass_pink 242 127 165 +mcl_core:glass_purple 127 63 178 +mcl_core:glass_red 153 51 51 +mcl_core:glass_silver 153 153 153 +mcl_core:glass_white 255 255 255 +mcl_core:glass_yellow 229 229 51 +mcl_core:goldblock 196 153 69 +mcl_core:granite 155 122 111 +mcl_core:granite_smooth 151 122 111 +mcl_core:grass_path 148 122 65 +mcl_core:gravel 137 142 140 +mcl_core:ice 146 198 227 +mcl_core:ironblock 164 157 157 +mcl_core:jungleleaves 29 84 30 +mcl_core:junglesapling 66 91 40 +mcl_core:jungletree 132 92 70 +mcl_core:jungletree_bark 90 62 46 +mcl_core:junglewood 114 80 60 +mcl_core:ladder 85 66 51 +mcl_core:lapisblock 58 97 165 +mcl_core:lava_source 255 100 0 +mcl_core:lava_flowing 255 100 0 +mcl_core:leaves 40 80 39 +mcl_core:mossycobble 105 106 97 +mcl_core:mycelium 109 89 118 +mcl_core:mycelium_snow 221 229 234 +mcl_core:obsidian 26 19 41 +mcl_core:packed_ice 166 212 231 +mcl_core:podzol 86 64 43 +mcl_core:podzol_snow 221 229 234 +mcl_core:redsand 225 137 111 +mcl_core:redsandstone 212 126 108 +mcl_core:redsandstonecarved 212 126 108 +mcl_core:redsandstonesmooth 212 126 108 +mcl_core:redsandstonesmooth2 212 126 108 +mcl_core:reeds 107 107 107 +mcl_core:sand 221 171 127 +mcl_core:sandstone 202 155 121 +mcl_core:sandstonecarved 202 155 121 +mcl_core:sandstonesmooth 202 155 121 +mcl_core:sandstonesmooth2 202 155 121 +mcl_core:sapling 66 93 47 +mcl_core:slimeblock 93 157 87 +mcl_core:snow 221 229 234 +mcl_core:snow_2 221 229 234 +mcl_core:snow_3 221 229 234 +mcl_core:snow_4 221 229 234 +mcl_core:snow_5 221 229 234 +mcl_core:snow_6 221 229 234 +mcl_core:snow_7 221 229 234 +mcl_core:snow_8 221 229 234 +mcl_core:snowblock 221 229 234 +mcl_core:spruceleaves 38 75 47 +mcl_core:sprucesapling 59 76 56 +mcl_core:sprucetree 104 75 59 +mcl_core:sprucetree_bark 69 53 45 +mcl_core:sprucewood 82 66 54 +mcl_core:stone 131 123 118 +mcl_core:stone_smooth 128 119 115 +mcl_core:stone_with_coal 114 106 103 +mcl_core:stone_with_diamond 124 128 133 +mcl_core:stone_with_emerald 120 124 108 +mcl_core:stone_with_gold 136 121 107 +mcl_core:stone_with_iron 137 125 119 +mcl_core:stone_with_lapis 116 115 128 +mcl_core:stone_with_redstone 131 101 98 +mcl_core:stone_with_redstone_lit 131 101 98 +mcl_core:stonebrick 122 122 122 +mcl_core:stonebrickcarved 100 92 88 +mcl_core:stonebrickcracked 96 89 85 +mcl_core:stonebrickmossy 86 104 79 +mcl_core:stripped_acacia 157 99 63 +mcl_core:stripped_acacia_bark 151 90 57 +mcl_core:stripped_birch 170 136 108 +mcl_core:stripped_birch_bark 179 144 115 +mcl_core:stripped_dark_oak 92 79 70 +mcl_core:stripped_dark_oak_bark 91 79 70 +mcl_core:stripped_jungle 170 114 84 +mcl_core:stripped_jungle_bark 176 117 86 +mcl_core:stripped_oak 155 117 81 +mcl_core:stripped_oak_bark 162 122 84 +mcl_core:stripped_spruce 109 80 65 +mcl_core:stripped_spruce_bark 109 82 67 +mcl_core:tree 142 108 77 +mcl_core:tree_bark 99 78 59 +mcl_core:vine 21 62 22 +mcl_core:water_source 0 94 184 224 +mcl_core:wood 115 89 68 + +# mcl_crafting_table +mcl_crafting_table:crafting_table 154 123 95 + +# mcl_crimson +mcl_crimson:crimson_door_t_1 119 46 40 +mcl_crimson:crimson_door_t_2 119 46 40 +mcl_crimson:crimson_fence 107 40 48 +mcl_crimson:crimson_fence_gate 107 40 48 +mcl_crimson:crimson_fence_gate_open 107 40 48 +mcl_crimson:crimson_fungus 153 60 41 +mcl_crimson:crimson_hyphae 176 81 69 +mcl_crimson:crimson_hyphae_bark 100 74 62 +mcl_crimson:crimson_hyphae_wood 119 46 40 +mcl_crimson:crimson_nylium 133 31 35 +mcl_crimson:crimson_roots 129 39 39 +mcl_crimson:crimson_trapdoor 91 40 47 +mcl_crimson:crimson_trapdoor_open 119 46 40 +mcl_crimson:nether_sprouts 115 90 156 +mcl_crimson:shroomlight 253 187 125 +mcl_crimson:stripped_crimson_hyphae 177 74 67 +mcl_crimson:stripped_crimson_hyphae_bark 117 40 48 +mcl_crimson:stripped_warped_hyphae 20 94 82 +mcl_crimson:stripped_warped_hyphae_bark 117 40 48 +mcl_crimson:twisting_vines 101 82 133 +mcl_crimson:warped_fungus 128 139 114 +mcl_crimson:warped_hyphae 90 71 121 +mcl_crimson:warped_hyphae_bark 51 44 61 +mcl_crimson:warped_hyphae_wood 78 64 108 +mcl_crimson:warped_nylium 86 72 116 +mcl_crimson:warped_roots 97 79 128 +mcl_crimson:warped_trapdoor 37 60 54 +mcl_crimson:warped_trapdoor_open 78 64 108 +mcl_crimson:warped_wart_block 70 56 97 +mcl_crimson:weeping_vines 145 47 38 + +# mcl_deepslate +mcl_deepslate:deepslate 75 73 73 +mcl_deepslate:deepslate_bricks 64 62 62 +mcl_deepslate:deepslate_bricks_cracked 62 60 60 +mcl_deepslate:deepslate_chiseled 46 45 45 +mcl_deepslate:deepslate_cobbled 80 78 76 +mcl_deepslate:deepslate_polished 69 68 67 +mcl_deepslate:deepslate_tiles 51 50 49 +mcl_deepslate:deepslate_tiles_cracked 49 48 48 +mcl_deepslate:deepslate_with_coal 65 62 61 +mcl_deepslate:deepslate_with_copper 88 72 68 +mcl_deepslate:deepslate_with_diamond 76 105 118 +mcl_deepslate:deepslate_with_emerald 66 88 73 +mcl_deepslate:deepslate_with_gold 98 84 66 +mcl_deepslate:deepslate_with_iron 98 91 86 +mcl_deepslate:deepslate_with_lapis 67 77 100 +mcl_deepslate:deepslate_with_redstone 97 63 62 +mcl_deepslate:deepslate_with_redstone_lit 97 63 62 +mcl_deepslate:deepslatebrickswall 64 62 62 +mcl_deepslate:deepslatebrickswall_0 64 62 62 +mcl_deepslate:deepslatebrickswall_1 64 62 62 +mcl_deepslate:deepslatebrickswall_10 64 62 62 +mcl_deepslate:deepslatebrickswall_11 64 62 62 +mcl_deepslate:deepslatebrickswall_12 64 62 62 +mcl_deepslate:deepslatebrickswall_13 64 62 62 +mcl_deepslate:deepslatebrickswall_14 64 62 62 +mcl_deepslate:deepslatebrickswall_15 64 62 62 +mcl_deepslate:deepslatebrickswall_16 64 62 62 +mcl_deepslate:deepslatebrickswall_2 64 62 62 +mcl_deepslate:deepslatebrickswall_21 64 62 62 +mcl_deepslate:deepslatebrickswall_3 64 62 62 +mcl_deepslate:deepslatebrickswall_4 64 62 62 +mcl_deepslate:deepslatebrickswall_5 64 62 62 +mcl_deepslate:deepslatebrickswall_6 64 62 62 +mcl_deepslate:deepslatebrickswall_7 64 62 62 +mcl_deepslate:deepslatebrickswall_8 64 62 62 +mcl_deepslate:deepslatebrickswall_9 64 62 62 +mcl_deepslate:deepslatecobbledwall 80 78 76 +mcl_deepslate:deepslatecobbledwall_0 80 78 76 +mcl_deepslate:deepslatecobbledwall_1 80 78 76 +mcl_deepslate:deepslatecobbledwall_10 80 78 76 +mcl_deepslate:deepslatecobbledwall_11 80 78 76 +mcl_deepslate:deepslatecobbledwall_12 80 78 76 +mcl_deepslate:deepslatecobbledwall_13 80 78 76 +mcl_deepslate:deepslatecobbledwall_14 80 78 76 +mcl_deepslate:deepslatecobbledwall_15 80 78 76 +mcl_deepslate:deepslatecobbledwall_16 80 78 76 +mcl_deepslate:deepslatecobbledwall_2 80 78 76 +mcl_deepslate:deepslatecobbledwall_21 80 78 76 +mcl_deepslate:deepslatecobbledwall_3 80 78 76 +mcl_deepslate:deepslatecobbledwall_4 80 78 76 +mcl_deepslate:deepslatecobbledwall_5 80 78 76 +mcl_deepslate:deepslatecobbledwall_6 80 78 76 +mcl_deepslate:deepslatecobbledwall_7 80 78 76 +mcl_deepslate:deepslatecobbledwall_8 80 78 76 +mcl_deepslate:deepslatecobbledwall_9 80 78 76 +mcl_deepslate:deepslatepolishedwall 69 68 67 +mcl_deepslate:deepslatepolishedwall_0 69 68 67 +mcl_deepslate:deepslatepolishedwall_1 69 68 67 +mcl_deepslate:deepslatepolishedwall_10 69 68 67 +mcl_deepslate:deepslatepolishedwall_11 69 68 67 +mcl_deepslate:deepslatepolishedwall_12 69 68 67 +mcl_deepslate:deepslatepolishedwall_13 69 68 67 +mcl_deepslate:deepslatepolishedwall_14 69 68 67 +mcl_deepslate:deepslatepolishedwall_15 69 68 67 +mcl_deepslate:deepslatepolishedwall_16 69 68 67 +mcl_deepslate:deepslatepolishedwall_2 69 68 67 +mcl_deepslate:deepslatepolishedwall_21 69 68 67 +mcl_deepslate:deepslatepolishedwall_3 69 68 67 +mcl_deepslate:deepslatepolishedwall_4 69 68 67 +mcl_deepslate:deepslatepolishedwall_5 69 68 67 +mcl_deepslate:deepslatepolishedwall_6 69 68 67 +mcl_deepslate:deepslatepolishedwall_7 69 68 67 +mcl_deepslate:deepslatepolishedwall_8 69 68 67 +mcl_deepslate:deepslatepolishedwall_9 69 68 67 +mcl_deepslate:deepslatetileswall 51 50 49 +mcl_deepslate:deepslatetileswall_0 51 50 49 +mcl_deepslate:deepslatetileswall_1 51 50 49 +mcl_deepslate:deepslatetileswall_10 51 50 49 +mcl_deepslate:deepslatetileswall_11 51 50 49 +mcl_deepslate:deepslatetileswall_12 51 50 49 +mcl_deepslate:deepslatetileswall_13 51 50 49 +mcl_deepslate:deepslatetileswall_14 51 50 49 +mcl_deepslate:deepslatetileswall_15 51 50 49 +mcl_deepslate:deepslatetileswall_16 51 50 49 +mcl_deepslate:deepslatetileswall_2 51 50 49 +mcl_deepslate:deepslatetileswall_21 51 50 49 +mcl_deepslate:deepslatetileswall_3 51 50 49 +mcl_deepslate:deepslatetileswall_4 51 50 49 +mcl_deepslate:deepslatetileswall_5 51 50 49 +mcl_deepslate:deepslatetileswall_6 51 50 49 +mcl_deepslate:deepslatetileswall_7 51 50 49 +mcl_deepslate:deepslatetileswall_8 51 50 49 +mcl_deepslate:deepslatetileswall_9 51 50 49 +mcl_deepslate:infested_deepslate 75 73 73 +mcl_deepslate:tuff 99 82 70 + +# mcl_dispensers +mcl_dispensers:dispenser 149 139 133 +mcl_dispensers:dispenser_down 149 139 133 +mcl_dispensers:dispenser_up 123 113 108 + +# mcl_doors +mcl_doors:acacia_door_t_1 134 81 53 +mcl_doors:acacia_door_t_2 134 81 53 +mcl_doors:acacia_trapdoor 150 100 69 +mcl_doors:acacia_trapdoor_open 156 105 73 +mcl_doors:birch_door_t_1 154 121 94 +mcl_doors:birch_door_t_2 154 121 94 +mcl_doors:birch_trapdoor 180 163 146 +mcl_doors:birch_trapdoor_open 147 116 90 +mcl_doors:dark_oak_door_t_1 103 90 76 +mcl_doors:dark_oak_door_t_2 103 90 76 +mcl_doors:dark_oak_trapdoor 82 70 58 +mcl_doors:dark_oak_trapdoor_open 86 73 61 +mcl_doors:iron_door_t_1 157 151 150 +mcl_doors:iron_door_t_2 157 151 150 +mcl_doors:iron_trapdoor 151 143 143 +mcl_doors:iron_trapdoor_open 151 142 142 +mcl_doors:jungle_door_t_1 110 76 57 +mcl_doors:jungle_door_t_2 110 76 57 +mcl_doors:jungle_trapdoor 106 73 53 +mcl_doors:jungle_trapdoor_open 122 88 63 +mcl_doors:spruce_door_t_1 93 80 69 +mcl_doors:spruce_door_t_2 93 80 69 +mcl_doors:spruce_trapdoor 73 59 48 +mcl_doors:spruce_trapdoor_open 76 60 49 +mcl_doors:trapdoor 100 76 60 +mcl_doors:trapdoor_open 114 86 67 +mcl_doors:wooden_door_t_1 85 65 52 +mcl_doors:wooden_door_t_2 85 65 52 + +# mcl_droppers +mcl_droppers:dropper 149 139 133 +mcl_droppers:dropper_down 149 139 133 +mcl_droppers:dropper_up 126 115 111 + +# mcl_enchanting +mcl_enchanting:table 97 97 96 + +# mcl_end +mcl_end:chorus_flower 96 100 127 +mcl_end:chorus_flower_dead 83 82 119 +mcl_end:chorus_plant 79 74 115 +mcl_end:dragon_egg 56 36 34 +mcl_end:end_bricks 195 189 123 +mcl_end:end_rod 124 77 97 +mcl_end:end_stone 221 214 131 +mcl_end:purpur_block 161 112 175 +mcl_end:purpur_pillar 160 111 173 + +# mcl_farming +mcl_farming:beetroot 84 109 72 +mcl_farming:beetroot_0 56 122 76 +mcl_farming:beetroot_1 55 119 73 +mcl_farming:beetroot_2 56 120 74 +mcl_farming:carrot 105 106 59 +mcl_farming:carrot_1 76 113 62 +mcl_farming:carrot_2 76 113 62 +mcl_farming:carrot_3 74 109 59 +mcl_farming:carrot_4 74 109 59 +mcl_farming:carrot_5 72 108 58 +mcl_farming:carrot_6 72 108 58 +mcl_farming:carrot_7 72 108 58 +mcl_farming:hay_block 156 119 83 +mcl_farming:melon 59 82 34 +mcl_farming:melontige_unconnect 100 100 100 +mcl_farming:potato 86 111 59 +mcl_farming:potato_1 75 120 65 +mcl_farming:potato_2 75 120 65 +mcl_farming:potato_3 71 115 62 +mcl_farming:potato_4 71 115 62 +mcl_farming:potato_5 74 119 64 +mcl_farming:potato_6 74 119 64 +mcl_farming:potato_7 74 119 64 +mcl_farming:pumpkin 174 90 40 +mcl_farming:pumpkin_face 174 90 40 +mcl_farming:pumpkin_face_light 174 90 40 +mcl_farming:pumpkintige_unconnect 100 100 100 +mcl_farming:soil 103 81 69 +mcl_farming:soil_wet 70 56 47 +mcl_farming:sweet_berry_bush_0 0 111 29 +mcl_farming:sweet_berry_bush_1 0 101 25 +mcl_farming:sweet_berry_bush_2 76 95 24 +mcl_farming:sweet_berry_bush_3 107 87 39 +mcl_farming:wheat 167 120 78 +mcl_farming:wheat_1 55 103 48 +mcl_farming:wheat_2 51 99 46 +mcl_farming:wheat_3 51 98 46 +mcl_farming:wheat_4 67 115 53 +mcl_farming:wheat_5 87 130 66 +mcl_farming:wheat_6 104 144 68 +mcl_farming:wheat_7 148 147 71 + +# mcl_fences +mcl_fences:acacia_fence 153 101 70 +mcl_fences:acacia_fence_gate 153 101 70 +mcl_fences:acacia_fence_gate_open 153 101 70 +mcl_fences:birch_fence 152 120 93 +mcl_fences:birch_fence_gate 152 120 93 +mcl_fences:birch_fence_gate_open 152 120 93 +mcl_fences:dark_oak_fence 85 73 60 +mcl_fences:dark_oak_fence_gate 85 73 60 +mcl_fences:dark_oak_fence_gate_open 85 73 60 +mcl_fences:fence 110 84 65 +mcl_fences:fence_gate 110 84 65 +mcl_fences:fence_gate_open 110 84 65 +mcl_fences:jungle_fence 116 82 61 +mcl_fences:jungle_fence_gate 116 82 61 +mcl_fences:jungle_fence_gate_open 116 82 61 +mcl_fences:nether_brick_fence 50 25 26 +mcl_fences:spruce_fence 85 68 55 +mcl_fences:spruce_fence_gate 85 68 55 +mcl_fences:spruce_fence_gate_open 85 68 55 + +# mcl_fire +mcl_fire:eternal_fire 209 112 39 +mcl_fire:fire 209 112 39 + +# mcl_fletching_table +mcl_fletching_table:fletching_table 174 116 83 + +# mcl_flowerpots +mcl_flowerpots:flower_pot 121 57 48 +mcl_flowerpots:flower_pot_cactus 114 92 57 + +# mcl_flowers +mcl_flowers:allium 130 121 159 +mcl_flowers:azure_bluet 118 124 125 +mcl_flowers:blue_orchid 0 118 191 +mcl_flowers:dandelion 136 120 59 +mcl_flowers:double_fern 142 132 114 +mcl_flowers:double_fern_top 150 139 120 +mcl_flowers:double_grass 0 255 0 +mcl_flowers:double_grass_top 0 255 0 +mcl_flowers:fern 144 134 116 +mcl_flowers:lilac 198 161 207 +mcl_flowers:lilac_top 198 161 207 +mcl_flowers:oxeye_daisy 162 158 139 +mcl_flowers:peony 242 172 185 +mcl_flowers:peony_top 242 172 185 +mcl_flowers:poppy 161 0 14 +mcl_flowers:rose_bush 161 0 14 +mcl_flowers:rose_bush_top 161 0 14 +mcl_flowers:sunflower 247 247 73 +mcl_flowers:sunflower_top 247 247 73 +mcl_flowers:tulip_orange 132 87 55 +mcl_flowers:tulip_pink 242 172 185 +mcl_flowers:tulip_red 161 0 14 +mcl_flowers:tulip_white 255 255 255 +mcl_flowers:waterlily 29 83 29 +mcl_flowers:tallgrass 21 71 52 + +# mcl_furnaces +mcl_furnaces:furnace 149 139 133 +mcl_furnaces:furnace_active 149 139 133 + +# mcl_grindstone +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:skeleton22_5 126 126 126 +mcl_heads:skeleton45 126 126 126 +mcl_heads:skeleton67_5 126 126 126 +mcl_heads:steve22_5 123 87 69 +mcl_heads:steve45 123 87 69 +mcl_heads:steve67_5 123 87 69 +mcl_heads:wither_skeleton22_5 50 50 50 +mcl_heads:wither_skeleton45 50 50 50 +mcl_heads:wither_skeleton67_5 50 50 50 +mcl_heads:zombie22_5 67 105 70 +mcl_heads:zombie45 67 105 70 +mcl_heads:zombie67_5 67 105 70 + +# mcl_hoppers +mcl_hoppers:hopper 50 50 50 +mcl_hoppers:hopper_disabled 50 50 50 +mcl_hoppers:hopper_side 50 50 50 +mcl_hoppers:hopper_side_disabled 50 50 50 + +# mcl_itemframes +mcl_itemframes:glow_item_frame 182 132 79 +mcl_itemframes:item_frame 127 94 66 + +# mcl_jukebox +mcl_jukebox:jukebox 77 60 46 + +# mcl_lanterns +mcl_lanterns:chain 41 41 41 +mcl_lanterns:lantern_ceiling 102 73 51 +mcl_lanterns:lantern_floor 102 73 51 +mcl_lanterns:soul_lantern_ceiling 62 91 92 +mcl_lanterns:soul_lantern_floor 62 91 92 + +# mcl_lightning_rods + +# mcl_loom +mcl_loom:loom 130 121 119 + +# mcl_mangrove +mcl_mangrove:hanging_propagule_1 80 100 48 +mcl_mangrove:mangrove_door_t_1 125 61 55 +mcl_mangrove:mangrove_door_t_2 125 61 55 +mcl_mangrove:mangrove_mud_roots 66 61 58 +mcl_mangrove:mangrove_roots 97 75 49 +mcl_mangrove:mangrove_stripped_bark 141 68 57 +mcl_mangrove:mangrove_stripped_trunk 127 62 56 +mcl_mangrove:mangrove_trapdoor 123 60 55 +mcl_mangrove:mangrove_trapdoor_open 125 61 55 +mcl_mangrove:mangrove_tree 125 66 54 +mcl_mangrove:mangrove_tree_bark 88 68 46 +mcl_mangrove:mangrove_wood 125 61 55 +mcl_mangrove:mangrove_wood_fence 125 61 55 +mcl_mangrove:mangrove_wood_fence_gate 125 61 55 +mcl_mangrove:mangrove_wood_fence_gate_open 125 61 55 +mcl_mangrove:mangroveleaves 34 50 14 +mcl_mangrove:propagule 71 114 46 +mcl_mangrove:propagule_clay 124 124 124 +mcl_mangrove:propagule_coarse_dirt 119 94 78 +mcl_mangrove:propagule_dirt 109 84 70 +mcl_mangrove:propagule_mud 66 61 58 +mcl_mangrove:river_water_logged_roots 32 121 138 +mcl_mangrove:water_logged_roots 38 98 129 + +# mcl_maps +mcl_maps:filled_map_character_male 123 77 64 +mcl_maps:filled_map_mcl_skins_base_18D471DFF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_18D471DFF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1B47A57FF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1B47A57FF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1EEB592FF_female 0 0 0 +mcl_maps:filled_map_mcl_skins_base_1EEB592FF_male 0 0 0 +mcl_maps:filled_map_mcl_skins_character_1_female 106 100 86 + +# mcl_meshhand +mcl_meshhand:character_male 123 77 64 +mcl_meshhand:mcl_skins_base_18D471DFF_female 0 0 0 +mcl_meshhand:mcl_skins_base_18D471DFF_male 0 0 0 +mcl_meshhand:mcl_skins_base_1B47A57FF_female 0 0 0 +mcl_meshhand:mcl_skins_base_1B47A57FF_male 0 0 0 +mcl_meshhand:mcl_skins_base_1EEB592FF_female 0 0 0 +mcl_meshhand:mcl_skins_base_1EEB592FF_male 0 0 0 +mcl_meshhand:mcl_skins_character_1_female 106 100 86 + +# mcl_minecarts +mcl_minecarts:activator_rail 87 70 59 +mcl_minecarts:activator_rail_on 95 69 59 +mcl_minecarts:detector_rail 94 81 73 +mcl_minecarts:detector_rail_on 96 81 73 +mcl_minecarts:golden_rail 107 88 63 +mcl_minecarts:golden_rail_on 110 88 63 +mcl_minecarts:rail 92 75 63 + +# mcl_mobspawners +mcl_mobspawners:spawner 42 42 42 + +# mcl_monster_eggs +mcl_monster_eggs:monster_egg_cobble 114 108 105 +mcl_monster_eggs:monster_egg_stone 131 123 118 +mcl_monster_eggs:monster_egg_stonebrick 99 91 88 +mcl_monster_eggs:monster_egg_stonebrickcarved 100 92 88 +mcl_monster_eggs:monster_egg_stonebrickcracked 96 89 85 +mcl_monster_eggs:monster_egg_stonebrickmossy 86 104 79 + +# mcl_mud +mcl_mud:mud 66 61 58 +mcl_mud:mud_bricks 109 96 87 +mcl_mud:packed_mud 102 90 83 + +# mcl_mushrooms +mcl_mushrooms:brown_mushroom_block_cap_000000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_000111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_001111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_010111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011000 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011001 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011010 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011011 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011100 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011101 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011110 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_011111 218 176 137 +mcl_mushrooms:brown_mushroom_block_cap_100000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_100111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_101111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_110111 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111000 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111001 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111010 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111011 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111100 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111101 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111110 132 87 69 +mcl_mushrooms:brown_mushroom_block_cap_111111 132 87 69 +mcl_mushrooms:brown_mushroom_block_stem 218 176 137 +mcl_mushrooms:brown_mushroom_block_stem_full 205 184 151 +mcl_mushrooms:mushroom_brown 123 84 61 +mcl_mushrooms:mushroom_red 173 71 66 +mcl_mushrooms:red_mushroom_block_cap_000000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_000111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_001111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_010111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011000 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011001 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011010 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011011 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011100 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011101 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011110 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_011111 218 176 137 +mcl_mushrooms:red_mushroom_block_cap_100000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_100111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_101111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_110111 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111000 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111001 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111010 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111011 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111100 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111101 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111110 138 40 26 +mcl_mushrooms:red_mushroom_block_cap_111111 138 40 26 +mcl_mushrooms:red_mushroom_block_stem 218 176 137 +mcl_mushrooms:red_mushroom_block_stem_full 205 184 151 + +# mcl_nether +mcl_nether:ancient_debris 63 57 50 +mcl_nether:glowstone 206 160 102 +mcl_nether:magma 99 35 28 +mcl_nether:nether_brick 49 25 26 +mcl_nether:nether_lava_flowing 180 50 19 +mcl_nether:nether_lava_source 183 54 21 +mcl_nether:nether_wart 129 61 57 +mcl_nether:nether_wart_0 59 42 39 +mcl_nether:nether_wart_1 103 59 56 +mcl_nether:nether_wart_2 103 59 56 +mcl_nether:nether_wart_block 179 79 74 +mcl_nether:netheriteblock 36 34 33 +mcl_nether:netherrack 133 52 40 +mcl_nether:quartz_block 198 191 187 +mcl_nether:quartz_chiseled 198 190 187 +mcl_nether:quartz_ore 137 75 67 +mcl_nether:quartz_pillar 196 188 186 +mcl_nether:quartz_smooth 198 191 187 +mcl_nether:red_nether_brick 72 17 6 +mcl_nether:soul_sand 92 71 52 + +# mcl_observers +mcl_observers:observer_down_off 89 82 79 +mcl_observers:observer_down_on 92 82 79 +mcl_observers:observer_off 142 131 126 +mcl_observers:observer_on 142 131 126 +mcl_observers:observer_up_off 111 91 91 +mcl_observers:observer_up_on 111 91 91 + +# mcl_ocean +mcl_ocean:brain_coral 202 85 149 +mcl_ocean:brain_coral_block 202 85 149 +mcl_ocean:brain_coral_fan 202 85 149 +mcl_ocean:bubble_coral 145 76 196 +mcl_ocean:bubble_coral_block 145 76 196 +mcl_ocean:bubble_coral_fan 145 76 196 +mcl_ocean:dead_brain_coral 131 114 124 +mcl_ocean:dead_brain_coral_block 131 114 124 +mcl_ocean:dead_brain_coral_fan 131 114 124 +mcl_ocean:dead_bubble_coral 115 106 123 +mcl_ocean:dead_bubble_coral_block 115 106 123 +mcl_ocean:dead_bubble_coral_fan 115 106 123 +mcl_ocean:dead_fire_coral 129 103 101 +mcl_ocean:dead_fire_coral_block 129 103 101 +mcl_ocean:dead_fire_coral_fan 129 103 101 +mcl_ocean:dead_horn_coral 154 147 127 +mcl_ocean:dead_horn_coral_block 154 147 127 +mcl_ocean:dead_horn_coral_fan 154 147 127 +mcl_ocean:dead_tube_coral 100 106 129 +mcl_ocean:dead_tube_coral_block 100 106 129 +mcl_ocean:dead_tube_coral_fan 100 106 129 +mcl_ocean:dried_kelp_block 56 71 57 +mcl_ocean:fire_coral 201 75 62 +mcl_ocean:fire_coral_block 201 75 62 +mcl_ocean:fire_coral_fan 201 75 62 +mcl_ocean:horn_coral 232 195 70 +mcl_ocean:horn_coral_block 232 195 70 +mcl_ocean:horn_coral_fan 232 195 70 +mcl_ocean:kelp_dirt 109 84 70 +mcl_ocean:kelp_gravel 115 109 103 +mcl_ocean:kelp_redsand 225 137 111 +mcl_ocean:kelp_sand 221 171 127 +mcl_ocean:prismarine 106 127 123 +mcl_ocean:prismarine_brick 107 116 117 +mcl_ocean:prismarine_dark 77 90 97 +mcl_ocean:sea_lantern 141 152 152 +mcl_ocean:sea_pickle_1_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_1_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_2_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_2_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_3_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_3_off_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_4_dead_brain_coral_block 131 114 124 +mcl_ocean:sea_pickle_4_off_dead_brain_coral_block 131 114 124 +mcl_ocean:seagrass_dirt 109 84 70 +mcl_ocean:seagrass_gravel 115 109 103 +mcl_ocean:seagrass_redsand 225 137 111 +mcl_ocean:seagrass_sand 221 171 127 +mcl_ocean:tube_coral 58 91 211 +mcl_ocean:tube_coral_block 58 91 211 +mcl_ocean:tube_coral_fan 58 91 211 + +# mcl_portals +mcl_portals:end_portal_frame 101 92 80 +mcl_portals:end_portal_frame_eye 101 92 80 +mcl_portals:portal_end 15 15 15 +mcl_portals:portal_gateway 15 15 15 + +# mcl_potions +mcl_potions:fire_resistance_arrow_box 148 132 127 +mcl_potions:fire_resistance_plus_arrow_box 148 132 127 +mcl_potions:harming_2_arrow_box 148 132 127 +mcl_potions:harming_arrow_box 148 132 127 +mcl_potions:healing_2_arrow_box 148 132 127 +mcl_potions:healing_arrow_box 148 132 127 +mcl_potions:invisibility_arrow_box 148 132 127 +mcl_potions:invisibility_plus_arrow_box 148 132 127 +mcl_potions:leaping_2_arrow_box 148 132 127 +mcl_potions:leaping_arrow_box 148 132 127 +mcl_potions:leaping_plus_arrow_box 148 132 127 +mcl_potions:night_vision_arrow_box 148 132 127 +mcl_potions:night_vision_plus_arrow_box 148 132 127 +mcl_potions:poison_2_arrow_box 148 132 127 +mcl_potions:poison_arrow_box 148 132 127 +mcl_potions:poison_plus_arrow_box 148 132 127 +mcl_potions:regeneration_2_arrow_box 148 132 127 +mcl_potions:regeneration_arrow_box 148 132 127 +mcl_potions:regeneration_plus_arrow_box 148 132 127 +mcl_potions:slowness_2_arrow_box 148 132 127 +mcl_potions:slowness_arrow_box 148 132 127 +mcl_potions:slowness_plus_arrow_box 148 132 127 +mcl_potions:swiftness_2_arrow_box 148 132 127 +mcl_potions:swiftness_arrow_box 148 132 127 +mcl_potions:swiftness_plus_arrow_box 148 132 127 +mcl_potions:water_breathing_arrow_box 148 132 127 +mcl_potions:water_breathing_plus_arrow_box 148 132 127 + +# mcl_raw_ores +mcl_raw_ores:raw_gold_block 210 169 85 +mcl_raw_ores:raw_iron_block 195 175 159 + +# mcl_sculk +mcl_sculk:catalyst 5 19 24 +mcl_sculk:sculk 5 19 24 +mcl_sculk:vein 6 17 24 + +# mcl_signs +mcl_signs:standing_sign 119 93 72 +mcl_signs:standing_sign22_5 119 93 72 +mcl_signs:standing_sign22_5_acaciawood 234 116 121 +mcl_signs:standing_sign22_5_birchwood 255 219 167 +mcl_signs:standing_sign22_5_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign22_5_darkwood 133 100 67 +mcl_signs:standing_sign22_5_junglewood 134 98 73 +mcl_signs:standing_sign22_5_mangrove_wood 184 105 61 +mcl_signs:standing_sign22_5_sprucewood 85 62 36 +mcl_signs:standing_sign22_5_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign45 119 93 72 +mcl_signs:standing_sign45_acaciawood 234 116 121 +mcl_signs:standing_sign45_birchwood 255 219 167 +mcl_signs:standing_sign45_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign45_darkwood 133 100 67 +mcl_signs:standing_sign45_junglewood 134 98 73 +mcl_signs:standing_sign45_mangrove_wood 134 105 61 +mcl_signs:standing_sign45_sprucewood 85 62 36 +mcl_signs:standing_sign45_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign67_5 119 93 72 +mcl_signs:standing_sign67_5_acaciawood 234 116 121 +mcl_signs:standing_sign67_5_birchwood 255 219 167 +mcl_signs:standing_sign67_5_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign67_5_darkwood 133 100 67 +mcl_signs:standing_sign67_5_junglewood 134 98 73 +mcl_signs:standing_sign67_5_mangrove_wood 184 105 61 +mcl_signs:standing_sign67_5_sprucewood 85 62 36 +mcl_signs:standing_sign67_5_warped_hyphae_wood 159 125 207 +mcl_signs:standing_sign_acaciawood 234 116 121 +mcl_signs:standing_sign_birchwood 255 219 167 +mcl_signs:standing_sign_crimson_hyphae_wood 195 95 81 +mcl_signs:standing_sign_darkwood 133 100 67 +mcl_signs:standing_sign_junglewood 134 98 73 +mcl_signs:standing_sign_mangrove_wood 119 93 72 +mcl_signs:standing_sign_sprucewood 85 62 36 +mcl_signs:standing_sign_warped_hyphae_wood 159 125 207 +mcl_signs:wall_sign 119 93 72 +mcl_signs:wall_sign_acaciawood 234 116 121 +mcl_signs:wall_sign_birchwood 255 219 255 +mcl_signs:wall_sign_crimson_hyphae_wood 195 95 81 +mcl_signs:wall_sign_darkwood 133 100 67 +mcl_signs:wall_sign_junglewood 134 98 73 +mcl_signs:wall_sign_mangrove_wood 184 105 61 +mcl_signs:wall_sign_sprucewood 85 62 36 +mcl_signs:wall_sign_warped_hyphae_wood 159 125 207 + +# mcl_smithing_table +mcl_smithing_table:table 51 48 45 + +# mcl_smoker +mcl_smoker:smoker 121 110 106 +mcl_smoker:smoker_active 121 110 106 + +# mcl_sponges +mcl_sponges:sponge 211 179 120 +mcl_sponges:sponge_wet 157 136 94 +mcl_sponges:sponge_wet_river_water 158 142 105 + +# mcl_stairs +mcl_stairs:slab_acaciatree_bark 107 94 77 +mcl_stairs:slab_acaciatree_bark_double 107 94 77 +mcl_stairs:slab_acaciatree_bark_top 107 94 77 +mcl_stairs:slab_acaciawood 153 103 71 +mcl_stairs:slab_acaciawood_double 153 103 71 +mcl_stairs:slab_acaciawood_top 153 103 71 +mcl_stairs:slab_andesite 105 111 107 +mcl_stairs:slab_andesite_double 105 111 107 +mcl_stairs:slab_andesite_smooth 107 114 110 +mcl_stairs:slab_andesite_smooth_double 107 114 110 +mcl_stairs:slab_andesite_smooth_top 107 114 110 +mcl_stairs:slab_andesite_top 105 111 107 +mcl_stairs:slab_birchtree_bark 199 190 180 +mcl_stairs:slab_birchtree_bark_double 199 190 180 +mcl_stairs:slab_birchtree_bark_top 199 190 180 +mcl_stairs:slab_birchwood 147 116 90 +mcl_stairs:slab_birchwood_double 147 116 90 +mcl_stairs:slab_birchwood_top 147 116 90 +mcl_stairs:slab_blackstone 33 31 35 +mcl_stairs:slab_blackstone_brick_polished 42 39 44 +mcl_stairs:slab_blackstone_brick_polished_double 42 39 44 +mcl_stairs:slab_blackstone_brick_polished_top 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished_double 42 39 44 +mcl_stairs:slab_blackstone_chiseled_polished_top 42 39 44 +mcl_stairs:slab_blackstone_double 33 31 35 +mcl_stairs:slab_blackstone_polished 44 42 47 +mcl_stairs:slab_blackstone_polished_double 44 42 47 +mcl_stairs:slab_blackstone_polished_top 44 42 47 +mcl_stairs:slab_blackstone_top 33 31 35 +mcl_stairs:slab_brick_block 140 92 81 +mcl_stairs:slab_brick_block_double 140 92 81 +mcl_stairs:slab_brick_block_top 140 92 81 +mcl_stairs:slab_cobble 114 108 105 +mcl_stairs:slab_cobble_double 114 108 105 +mcl_stairs:slab_cobble_top 114 108 105 +mcl_stairs:slab_concrete_black 8 10 15 +mcl_stairs:slab_concrete_black_double 8 10 15 +mcl_stairs:slab_concrete_black_top 8 10 15 +mcl_stairs:slab_concrete_blue 46 48 147 +mcl_stairs:slab_concrete_blue_double 46 48 147 +mcl_stairs:slab_concrete_blue_top 46 48 147 +mcl_stairs:slab_concrete_brown 98 60 32 +mcl_stairs:slab_concrete_brown_double 98 60 32 +mcl_stairs:slab_concrete_brown_top 98 60 32 +mcl_stairs:slab_concrete_cyan 21 123 140 +mcl_stairs:slab_concrete_cyan_double 21 123 140 +mcl_stairs:slab_concrete_cyan_top 21 123 140 +mcl_stairs:slab_concrete_green 75 94 37 +mcl_stairs:slab_concrete_green_double 75 94 37 +mcl_stairs:slab_concrete_green_top 75 94 37 +mcl_stairs:slab_concrete_grey 56 59 64 +mcl_stairs:slab_concrete_grey_double 56 59 64 +mcl_stairs:slab_concrete_grey_top 56 59 64 +mcl_stairs:slab_concrete_light_blue 37 140 200 +mcl_stairs:slab_concrete_light_blue_double 37 140 200 +mcl_stairs:slab_concrete_light_blue_top 37 140 200 +mcl_stairs:slab_concrete_lime 96 171 25 +mcl_stairs:slab_concrete_lime_double 96 171 25 +mcl_stairs:slab_concrete_lime_top 96 171 25 +mcl_stairs:slab_concrete_magenta 171 49 162 +mcl_stairs:slab_concrete_magenta_double 171 49 162 +mcl_stairs:slab_concrete_magenta_top 171 49 162 +mcl_stairs:slab_concrete_orange 226 101 1 +mcl_stairs:slab_concrete_orange_double 226 101 1 +mcl_stairs:slab_concrete_orange_top 226 101 1 +mcl_stairs:slab_concrete_pink 213 103 144 +mcl_stairs:slab_concrete_pink_double 213 103 144 +mcl_stairs:slab_concrete_pink_top 213 103 144 +mcl_stairs:slab_concrete_purple 103 32 159 +mcl_stairs:slab_concrete_purple_double 103 32 159 +mcl_stairs:slab_concrete_purple_top 103 32 159 +mcl_stairs:slab_concrete_red 146 34 34 +mcl_stairs:slab_concrete_red_double 146 34 34 +mcl_stairs:slab_concrete_red_top 146 34 34 +mcl_stairs:slab_concrete_silver 128 129 118 +mcl_stairs:slab_concrete_silver_double 128 129 118 +mcl_stairs:slab_concrete_silver_top 128 129 118 +mcl_stairs:slab_concrete_white 208 214 215 +mcl_stairs:slab_concrete_white_double 208 214 215 +mcl_stairs:slab_concrete_white_top 208 214 215 +mcl_stairs:slab_concrete_yellow 241 177 21 +mcl_stairs:slab_concrete_yellow_double 241 177 21 +mcl_stairs:slab_concrete_yellow_top 241 177 21 +mcl_stairs:slab_copper_cut 150 78 58 +mcl_stairs:slab_copper_cut_double 150 78 58 +mcl_stairs:slab_copper_cut_top 150 78 58 +mcl_stairs:slab_copper_exposed_cut 132 94 84 +mcl_stairs:slab_copper_exposed_cut_double 132 94 84 +mcl_stairs:slab_copper_exposed_cut_top 132 94 84 +mcl_stairs:slab_copper_oxidized_cut 91 112 112 +mcl_stairs:slab_copper_oxidized_cut_double 91 112 112 +mcl_stairs:slab_copper_oxidized_cut_top 91 112 112 +mcl_stairs:slab_copper_weathered_cut 109 105 102 +mcl_stairs:slab_copper_weathered_cut_double 109 105 102 +mcl_stairs:slab_copper_weathered_cut_top 109 105 102 +mcl_stairs:slab_crimson_hyphae_wood 119 46 40 +mcl_stairs:slab_crimson_hyphae_wood_double 119 46 40 +mcl_stairs:slab_crimson_hyphae_wood_top 119 46 40 +mcl_stairs:slab_darktree_bark 77 65 58 +mcl_stairs:slab_darktree_bark_double 77 65 58 +mcl_stairs:slab_darktree_bark_top 77 65 58 +mcl_stairs:slab_darkwood 89 76 63 +mcl_stairs:slab_darkwood_double 89 76 63 +mcl_stairs:slab_darkwood_top 89 76 63 +mcl_stairs:slab_deepslate_bricks 64 62 62 +mcl_stairs:slab_deepslate_bricks_double 64 62 62 +mcl_stairs:slab_deepslate_bricks_top 64 62 62 +mcl_stairs:slab_deepslate_cobbled 80 78 76 +mcl_stairs:slab_deepslate_cobbled_double 80 78 76 +mcl_stairs:slab_deepslate_cobbled_top 80 78 76 +mcl_stairs:slab_deepslate_polished 69 68 67 +mcl_stairs:slab_deepslate_polished_double 69 68 67 +mcl_stairs:slab_deepslate_polished_top 69 68 67 +mcl_stairs:slab_deepslate_tiles 51 50 49 +mcl_stairs:slab_deepslate_tiles_double 51 50 49 +mcl_stairs:slab_deepslate_tiles_top 51 50 49 +mcl_stairs:slab_diorite 154 150 148 +mcl_stairs:slab_diorite_double 154 150 148 +mcl_stairs:slab_diorite_smooth 158 155 153 +mcl_stairs:slab_diorite_smooth_double 158 155 153 +mcl_stairs:slab_diorite_smooth_top 158 155 153 +mcl_stairs:slab_diorite_top 154 150 148 +mcl_stairs:slab_end_bricks 195 189 123 +mcl_stairs:slab_end_bricks_double 195 189 123 +mcl_stairs:slab_end_bricks_top 195 189 123 +mcl_stairs:slab_goldblock 196 153 69 +mcl_stairs:slab_goldblock_double 196 153 69 +mcl_stairs:slab_goldblock_top 196 153 69 +mcl_stairs:slab_granite 155 122 111 +mcl_stairs:slab_granite_double 155 122 111 +mcl_stairs:slab_granite_smooth 151 122 111 +mcl_stairs:slab_granite_smooth_double 151 122 111 +mcl_stairs:slab_granite_smooth_top 151 122 111 +mcl_stairs:slab_granite_top 155 122 111 +mcl_stairs:slab_ironblock 164 157 157 +mcl_stairs:slab_ironblock_double 164 157 157 +mcl_stairs:slab_ironblock_top 164 157 157 +mcl_stairs:slab_jungletree_bark 90 62 46 +mcl_stairs:slab_jungletree_bark_double 90 62 46 +mcl_stairs:slab_jungletree_bark_top 90 62 46 +mcl_stairs:slab_junglewood 114 80 60 +mcl_stairs:slab_junglewood_double 114 80 60 +mcl_stairs:slab_junglewood_top 114 80 60 +mcl_stairs:slab_lapisblock 58 97 165 +mcl_stairs:slab_lapisblock_double 58 97 165 +mcl_stairs:slab_lapisblock_top 58 97 165 +mcl_stairs:slab_mangrove_wood 125 61 55 +mcl_stairs:slab_mangrove_wood_double 125 61 55 +mcl_stairs:slab_mangrove_wood_top 125 61 55 +mcl_stairs:slab_mossycobble 105 106 97 +mcl_stairs:slab_mossycobble_double 105 106 97 +mcl_stairs:slab_mossycobble_top 105 106 97 +mcl_stairs:slab_mud_brick 109 96 87 +mcl_stairs:slab_mud_brick_double 109 96 87 +mcl_stairs:slab_mud_brick_top 109 96 87 +mcl_stairs:slab_nether_brick 49 25 26 +mcl_stairs:slab_nether_brick_double 49 25 26 +mcl_stairs:slab_nether_brick_top 49 25 26 +mcl_stairs:slab_prismarine 106 127 123 +mcl_stairs:slab_prismarine_brick 107 116 117 +mcl_stairs:slab_prismarine_brick_double 107 116 117 +mcl_stairs:slab_prismarine_brick_top 107 116 117 +mcl_stairs:slab_prismarine_dark 77 90 97 +mcl_stairs:slab_prismarine_dark_double 77 90 97 +mcl_stairs:slab_prismarine_dark_top 77 90 97 +mcl_stairs:slab_prismarine_double 106 127 123 +mcl_stairs:slab_prismarine_top 106 127 123 +mcl_stairs:slab_purpur_block 161 112 175 +mcl_stairs:slab_purpur_block_double 161 112 175 +mcl_stairs:slab_purpur_block_top 161 112 175 +mcl_stairs:slab_quartz_smooth 198 191 187 +mcl_stairs:slab_quartz_smooth_double 198 191 187 +mcl_stairs:slab_quartz_smooth_top 198 191 187 +mcl_stairs:slab_quartzblock 198 191 187 +mcl_stairs:slab_quartzblock_double 198 191 187 +mcl_stairs:slab_quartzblock_top 198 191 187 +mcl_stairs:slab_red_nether_brick 72 17 6 +mcl_stairs:slab_red_nether_brick_double 72 17 6 +mcl_stairs:slab_red_nether_brick_top 72 17 6 +mcl_stairs:slab_redsandstone 212 126 108 +mcl_stairs:slab_redsandstone_double 212 126 108 +mcl_stairs:slab_redsandstone_top 212 126 108 +mcl_stairs:slab_redsandstonesmooth2 212 126 108 +mcl_stairs:slab_redsandstonesmooth2_double 212 126 108 +mcl_stairs:slab_redsandstonesmooth2_top 212 126 108 +mcl_stairs:slab_sandstone 202 155 121 +mcl_stairs:slab_sandstone_double 202 155 121 +mcl_stairs:slab_sandstone_top 202 155 121 +mcl_stairs:slab_sandstonesmooth2 202 155 121 +mcl_stairs:slab_sandstonesmooth2_double 202 155 121 +mcl_stairs:slab_sandstonesmooth2_top 202 155 121 +mcl_stairs:slab_sprucetree_bark 69 53 45 +mcl_stairs:slab_sprucetree_bark_double 69 53 45 +mcl_stairs:slab_sprucetree_bark_top 69 53 45 +mcl_stairs:slab_sprucewood 82 66 54 +mcl_stairs:slab_sprucewood_double 82 66 54 +mcl_stairs:slab_sprucewood_top 82 66 54 +mcl_stairs:slab_stone 128 119 115 +mcl_stairs:slab_stone_double 128 119 115 +mcl_stairs:slab_stone_rough 131 123 118 +mcl_stairs:slab_stone_rough_double 131 123 118 +mcl_stairs:slab_stone_rough_top 131 123 118 +mcl_stairs:slab_stone_top 128 119 115 +mcl_stairs:slab_stonebrick 99 91 88 +mcl_stairs:slab_stonebrick_double 99 91 88 +mcl_stairs:slab_stonebrick_top 99 91 88 +mcl_stairs:slab_stonebrickcracked 96 89 85 +mcl_stairs:slab_stonebrickcracked_double 96 89 85 +mcl_stairs:slab_stonebrickcracked_top 96 89 85 +mcl_stairs:slab_stonebrickmossy 86 104 79 +mcl_stairs:slab_stonebrickmossy_double 86 104 79 +mcl_stairs:slab_stonebrickmossy_top 86 104 79 +mcl_stairs:slab_tree_bark 99 78 59 +mcl_stairs:slab_tree_bark_double 99 78 59 +mcl_stairs:slab_tree_bark_top 99 78 59 +mcl_stairs:slab_warped_hyphae_wood 78 64 108 +mcl_stairs:slab_warped_hyphae_wood_double 78 64 108 +mcl_stairs:slab_warped_hyphae_wood_top 78 64 108 +mcl_stairs:slab_wood 115 89 68 +mcl_stairs:slab_wood_double 115 89 68 +mcl_stairs:slab_wood_top 115 89 68 +mcl_stairs:stair_acaciatree_bark 107 94 77 +mcl_stairs:stair_acaciatree_bark_inner 107 94 77 +mcl_stairs:stair_acaciatree_bark_outer 107 94 77 +mcl_stairs:stair_acaciawood 153 103 71 +mcl_stairs:stair_acaciawood_inner 153 103 71 +mcl_stairs:stair_acaciawood_outer 153 103 71 +mcl_stairs:stair_andesite 105 111 107 +mcl_stairs:stair_andesite_inner 105 111 107 +mcl_stairs:stair_andesite_outer 105 111 107 +mcl_stairs:stair_andesite_smooth 107 114 109 +mcl_stairs:stair_andesite_smooth_inner 107 114 109 +mcl_stairs:stair_andesite_smooth_outer 107 114 109 +mcl_stairs:stair_birchtree_bark 199 190 180 +mcl_stairs:stair_birchtree_bark_inner 199 190 180 +mcl_stairs:stair_birchtree_bark_outer 199 190 180 +mcl_stairs:stair_birchwood 147 116 90 +mcl_stairs:stair_birchwood_inner 147 116 90 +mcl_stairs:stair_birchwood_outer 147 116 90 +mcl_stairs:stair_blackstone 33 31 35 +mcl_stairs:stair_blackstone_brick_polished 42 39 44 +mcl_stairs:stair_blackstone_brick_polished_inner 42 39 44 +mcl_stairs:stair_blackstone_brick_polished_outer 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished_inner 42 39 44 +mcl_stairs:stair_blackstone_chiseled_polished_outer 42 39 44 +mcl_stairs:stair_blackstone_inner 33 31 35 +mcl_stairs:stair_blackstone_outer 33 31 35 +mcl_stairs:stair_blackstone_polished 44 42 47 +mcl_stairs:stair_blackstone_polished_inner 44 42 47 +mcl_stairs:stair_blackstone_polished_outer 44 42 47 +mcl_stairs:stair_brick_block 140 92 81 +mcl_stairs:stair_brick_block_inner 140 92 81 +mcl_stairs:stair_brick_block_outer 140 92 81 +mcl_stairs:stair_cobble 114 108 105 +mcl_stairs:stair_cobble_inner 114 108 105 +mcl_stairs:stair_cobble_outer 114 108 105 +mcl_stairs:stair_concrete_black 8 10 15 +mcl_stairs:stair_concrete_black_inner 8 10 15 +mcl_stairs:stair_concrete_black_outer 8 10 15 +mcl_stairs:stair_concrete_blue 46 48 147 +mcl_stairs:stair_concrete_blue_inner 46 48 147 +mcl_stairs:stair_concrete_blue_outer 46 48 147 +mcl_stairs:stair_concrete_brown 98 60 32 +mcl_stairs:stair_concrete_brown_inner 98 60 32 +mcl_stairs:stair_concrete_brown_outer 98 60 32 +mcl_stairs:stair_concrete_cyan 21 123 140 +mcl_stairs:stair_concrete_cyan_inner 21 123 140 +mcl_stairs:stair_concrete_cyan_outer 21 123 140 +mcl_stairs:stair_concrete_green 75 94 37 +mcl_stairs:stair_concrete_green_inner 75 94 37 +mcl_stairs:stair_concrete_green_outer 75 94 37 +mcl_stairs:stair_concrete_grey 56 59 64 +mcl_stairs:stair_concrete_grey_inner 56 59 64 +mcl_stairs:stair_concrete_grey_outer 56 59 64 +mcl_stairs:stair_concrete_light_blue 37 140 200 +mcl_stairs:stair_concrete_light_blue_inner 37 140 200 +mcl_stairs:stair_concrete_light_blue_outer 37 140 200 +mcl_stairs:stair_concrete_lime 96 171 25 +mcl_stairs:stair_concrete_lime_inner 96 171 25 +mcl_stairs:stair_concrete_lime_outer 96 171 25 +mcl_stairs:stair_concrete_magenta 171 49 162 +mcl_stairs:stair_concrete_magenta_inner 171 49 162 +mcl_stairs:stair_concrete_magenta_outer 171 49 162 +mcl_stairs:stair_concrete_orange 226 101 1 +mcl_stairs:stair_concrete_orange_inner 226 101 1 +mcl_stairs:stair_concrete_orange_outer 226 101 1 +mcl_stairs:stair_concrete_pink 213 103 144 +mcl_stairs:stair_concrete_pink_inner 213 103 144 +mcl_stairs:stair_concrete_pink_outer 213 103 144 +mcl_stairs:stair_concrete_purple 103 32 159 +mcl_stairs:stair_concrete_purple_inner 103 32 159 +mcl_stairs:stair_concrete_purple_outer 103 32 159 +mcl_stairs:stair_concrete_red 146 34 34 +mcl_stairs:stair_concrete_red_inner 146 34 34 +mcl_stairs:stair_concrete_red_outer 146 34 34 +mcl_stairs:stair_concrete_silver 128 129 118 +mcl_stairs:stair_concrete_silver_inner 128 129 118 +mcl_stairs:stair_concrete_silver_outer 128 129 118 +mcl_stairs:stair_concrete_white 208 214 215 +mcl_stairs:stair_concrete_white_inner 208 214 215 +mcl_stairs:stair_concrete_white_outer 208 214 215 +mcl_stairs:stair_concrete_yellow 241 177 21 +mcl_stairs:stair_concrete_yellow_inner 241 177 21 +mcl_stairs:stair_concrete_yellow_outer 241 177 21 +mcl_stairs:stair_copper_cut 150 78 58 +mcl_stairs:stair_copper_cut_inner 150 78 58 +mcl_stairs:stair_copper_cut_outer 150 78 58 +mcl_stairs:stair_copper_exposed_cut 132 94 84 +mcl_stairs:stair_copper_exposed_cut_inner 132 94 84 +mcl_stairs:stair_copper_exposed_cut_outer 132 94 84 +mcl_stairs:stair_copper_oxidized_cut 91 112 112 +mcl_stairs:stair_copper_oxidized_cut_inner 91 112 112 +mcl_stairs:stair_copper_oxidized_cut_outer 91 112 112 +mcl_stairs:stair_copper_weathered_cut 109 105 102 +mcl_stairs:stair_copper_weathered_cut_inner 109 105 102 +mcl_stairs:stair_copper_weathered_cut_outer 109 105 102 +mcl_stairs:stair_crimson_hyphae_wood 119 46 40 +mcl_stairs:stair_crimson_hyphae_wood_inner 119 46 40 +mcl_stairs:stair_crimson_hyphae_wood_outer 119 46 40 +mcl_stairs:stair_darktree_bark 77 65 58 +mcl_stairs:stair_darktree_bark_inner 77 65 58 +mcl_stairs:stair_darktree_bark_outer 77 65 58 +mcl_stairs:stair_darkwood 89 76 63 +mcl_stairs:stair_darkwood_inner 89 76 63 +mcl_stairs:stair_darkwood_outer 89 76 63 +mcl_stairs:stair_deepslate_bricks 64 62 62 +mcl_stairs:stair_deepslate_bricks_inner 64 62 62 +mcl_stairs:stair_deepslate_bricks_outer 64 62 62 +mcl_stairs:stair_deepslate_cobbled 80 78 76 +mcl_stairs:stair_deepslate_cobbled_inner 80 78 76 +mcl_stairs:stair_deepslate_cobbled_outer 80 78 76 +mcl_stairs:stair_deepslate_polished 69 68 67 +mcl_stairs:stair_deepslate_polished_inner 69 68 67 +mcl_stairs:stair_deepslate_polished_outer 69 68 67 +mcl_stairs:stair_deepslate_tiles 51 50 49 +mcl_stairs:stair_deepslate_tiles_inner 51 50 49 +mcl_stairs:stair_deepslate_tiles_outer 51 50 49 +mcl_stairs:stair_diorite 154 150 148 +mcl_stairs:stair_diorite_inner 154 150 148 +mcl_stairs:stair_diorite_outer 154 150 148 +mcl_stairs:stair_diorite_smooth 158 155 152 +mcl_stairs:stair_diorite_smooth_inner 158 155 152 +mcl_stairs:stair_diorite_smooth_outer 158 155 152 +mcl_stairs:stair_end_bricks 195 189 123 +mcl_stairs:stair_end_bricks_inner 195 189 123 +mcl_stairs:stair_end_bricks_outer 195 189 123 +mcl_stairs:stair_goldblock 195 152 65 +mcl_stairs:stair_goldblock_inner 195 152 65 +mcl_stairs:stair_goldblock_outer 195 152 65 +mcl_stairs:stair_granite 155 122 111 +mcl_stairs:stair_granite_inner 155 122 111 +mcl_stairs:stair_granite_outer 155 122 111 +mcl_stairs:stair_granite_smooth 152 122 110 +mcl_stairs:stair_granite_smooth_inner 152 122 110 +mcl_stairs:stair_granite_smooth_outer 152 122 110 +mcl_stairs:stair_ironblock 173 167 167 +mcl_stairs:stair_ironblock_inner 173 167 167 +mcl_stairs:stair_ironblock_outer 173 167 167 +mcl_stairs:stair_jungletree_bark 90 62 46 +mcl_stairs:stair_jungletree_bark_inner 90 62 46 +mcl_stairs:stair_jungletree_bark_outer 90 62 46 +mcl_stairs:stair_junglewood 114 80 60 +mcl_stairs:stair_junglewood_inner 114 80 60 +mcl_stairs:stair_junglewood_outer 114 80 60 +mcl_stairs:stair_lapisblock 57 95 161 +mcl_stairs:stair_lapisblock_inner 57 95 161 +mcl_stairs:stair_lapisblock_outer 57 95 161 +mcl_stairs:stair_mangrove_wood 125 61 55 +mcl_stairs:stair_mangrove_wood_inner 125 61 55 +mcl_stairs:stair_mangrove_wood_outer 125 61 55 +mcl_stairs:stair_mossycobble 105 106 97 +mcl_stairs:stair_mossycobble_inner 105 106 97 +mcl_stairs:stair_mossycobble_outer 105 106 97 +mcl_stairs:stair_mud_brick 109 96 87 +mcl_stairs:stair_mud_brick_inner 109 96 87 +mcl_stairs:stair_mud_brick_outer 109 96 87 +mcl_stairs:stair_nether_brick 49 25 26 +mcl_stairs:stair_nether_brick_inner 49 25 26 +mcl_stairs:stair_nether_brick_outer 49 25 26 +mcl_stairs:stair_prismarine 106 127 123 +mcl_stairs:stair_prismarine_brick 107 116 117 +mcl_stairs:stair_prismarine_brick_inner 107 116 117 +mcl_stairs:stair_prismarine_brick_outer 107 116 117 +mcl_stairs:stair_prismarine_dark 77 90 97 +mcl_stairs:stair_prismarine_dark_inner 77 90 97 +mcl_stairs:stair_prismarine_dark_outer 77 90 97 +mcl_stairs:stair_prismarine_inner 106 127 123 +mcl_stairs:stair_prismarine_outer 106 127 123 +mcl_stairs:stair_purpur_block 161 112 175 +mcl_stairs:stair_purpur_block_inner 161 112 175 +mcl_stairs:stair_purpur_block_outer 161 112 175 +mcl_stairs:stair_quartz_smooth 198 191 187 +mcl_stairs:stair_quartz_smooth_inner 198 191 187 +mcl_stairs:stair_quartz_smooth_outer 198 191 187 +mcl_stairs:stair_quartzblock 198 191 187 +mcl_stairs:stair_quartzblock_inner 198 191 187 +mcl_stairs:stair_quartzblock_outer 198 191 187 +mcl_stairs:stair_red_nether_brick 72 17 6 +mcl_stairs:stair_red_nether_brick_inner 72 17 6 +mcl_stairs:stair_red_nether_brick_outer 72 17 6 +mcl_stairs:stair_redsandstone 212 126 108 +mcl_stairs:stair_redsandstone_inner 212 126 108 +mcl_stairs:stair_redsandstone_outer 212 126 108 +mcl_stairs:stair_redsandstonesmooth2 212 126 108 +mcl_stairs:stair_redsandstonesmooth2_inner 212 126 108 +mcl_stairs:stair_redsandstonesmooth2_outer 212 126 108 +mcl_stairs:stair_sandstone 202 155 121 +mcl_stairs:stair_sandstone_inner 202 155 121 +mcl_stairs:stair_sandstone_outer 202 155 121 +mcl_stairs:stair_sandstonesmooth2 202 155 121 +mcl_stairs:stair_sandstonesmooth2_inner 202 155 121 +mcl_stairs:stair_sandstonesmooth2_outer 202 155 121 +mcl_stairs:stair_sprucetree_bark 69 53 45 +mcl_stairs:stair_sprucetree_bark_inner 69 53 45 +mcl_stairs:stair_sprucetree_bark_outer 69 53 45 +mcl_stairs:stair_sprucewood 82 66 54 +mcl_stairs:stair_sprucewood_inner 82 66 54 +mcl_stairs:stair_sprucewood_outer 82 66 54 +mcl_stairs:stair_stone_rough 131 123 118 +mcl_stairs:stair_stone_rough_inner 131 123 118 +mcl_stairs:stair_stone_rough_outer 131 123 118 +mcl_stairs:stair_stonebrick 99 91 88 +mcl_stairs:stair_stonebrick_inner 99 91 88 +mcl_stairs:stair_stonebrick_outer 99 91 88 +mcl_stairs:stair_stonebrickcracked 96 89 85 +mcl_stairs:stair_stonebrickcracked_inner 96 89 85 +mcl_stairs:stair_stonebrickcracked_outer 96 89 85 +mcl_stairs:stair_stonebrickmossy 86 104 79 +mcl_stairs:stair_stonebrickmossy_inner 86 104 79 +mcl_stairs:stair_stonebrickmossy_outer 86 104 79 +mcl_stairs:stair_tree_bark 99 78 59 +mcl_stairs:stair_tree_bark_inner 99 78 59 +mcl_stairs:stair_tree_bark_outer 99 78 59 +mcl_stairs:stair_warped_hyphae_wood 78 64 108 +mcl_stairs:stair_warped_hyphae_wood_inner 78 64 108 +mcl_stairs:stair_warped_hyphae_wood_outer 78 64 108 +mcl_stairs:stair_wood 115 89 68 +mcl_stairs:stair_wood_inner 115 89 68 +mcl_stairs:stair_wood_outer 115 89 68 + +# mcl_stonecutter +mcl_stonecutter:stonecutter 88 82 80 + +# mcl_structures + +# mcl_target +mcl_target:target_off 182 137 112 +mcl_target:target_on 182 137 112 + +# mcl_tnt +mcl_tnt:tnt 134 55 57 + +# mcl_torches +mcl_torches:torch 94 72 58 +mcl_torches:torch_wall 94 72 58 + +# mcl_villages +mcl_villages:stonebrickcarved 100 92 88 + +# mcl_walls +mcl_walls:andesite 105 111 107 +mcl_walls:andesite_0 105 111 107 +mcl_walls:andesite_1 105 111 107 +mcl_walls:andesite_10 105 111 107 +mcl_walls:andesite_11 105 111 107 +mcl_walls:andesite_12 105 111 107 +mcl_walls:andesite_13 105 111 107 +mcl_walls:andesite_14 105 111 107 +mcl_walls:andesite_15 105 111 107 +mcl_walls:andesite_16 105 111 107 +mcl_walls:andesite_2 105 111 107 +mcl_walls:andesite_21 105 111 107 +mcl_walls:andesite_3 105 111 107 +mcl_walls:andesite_4 105 111 107 +mcl_walls:andesite_5 105 111 107 +mcl_walls:andesite_6 105 111 107 +mcl_walls:andesite_7 105 111 107 +mcl_walls:andesite_8 105 111 107 +mcl_walls:andesite_9 105 111 107 +mcl_walls:brick 140 92 81 +mcl_walls:brick_0 140 92 81 +mcl_walls:brick_1 140 92 81 +mcl_walls:brick_10 140 92 81 +mcl_walls:brick_11 140 92 81 +mcl_walls:brick_12 140 92 81 +mcl_walls:brick_13 140 92 81 +mcl_walls:brick_14 140 92 81 +mcl_walls:brick_15 140 92 81 +mcl_walls:brick_16 140 92 81 +mcl_walls:brick_2 140 92 81 +mcl_walls:brick_21 140 92 81 +mcl_walls:brick_3 140 92 81 +mcl_walls:brick_4 140 92 81 +mcl_walls:brick_5 140 92 81 +mcl_walls:brick_6 140 92 81 +mcl_walls:brick_7 140 92 81 +mcl_walls:brick_8 140 92 81 +mcl_walls:brick_9 140 92 81 +mcl_walls:cobble 122 116 113 +mcl_walls:cobble_0 122 116 113 +mcl_walls:cobble_1 122 116 113 +mcl_walls:cobble_10 122 116 113 +mcl_walls:cobble_11 122 116 113 +mcl_walls:cobble_12 122 116 113 +mcl_walls:cobble_13 122 116 113 +mcl_walls:cobble_14 122 116 113 +mcl_walls:cobble_15 122 116 113 +mcl_walls:cobble_16 122 116 113 +mcl_walls:cobble_2 122 116 113 +mcl_walls:cobble_21 122 116 113 +mcl_walls:cobble_3 122 116 113 +mcl_walls:cobble_4 122 116 113 +mcl_walls:cobble_5 122 116 113 +mcl_walls:cobble_6 122 116 113 +mcl_walls:cobble_7 122 116 113 +mcl_walls:cobble_8 122 116 113 +mcl_walls:cobble_9 122 116 113 +mcl_walls:diorite 154 150 148 +mcl_walls:diorite_0 154 150 148 +mcl_walls:diorite_1 154 150 148 +mcl_walls:diorite_10 154 150 148 +mcl_walls:diorite_11 154 150 148 +mcl_walls:diorite_12 154 150 148 +mcl_walls:diorite_13 154 150 148 +mcl_walls:diorite_14 154 150 148 +mcl_walls:diorite_15 154 150 148 +mcl_walls:diorite_16 154 150 148 +mcl_walls:diorite_2 154 150 148 +mcl_walls:diorite_21 154 150 148 +mcl_walls:diorite_3 154 150 148 +mcl_walls:diorite_4 154 150 148 +mcl_walls:diorite_5 154 150 148 +mcl_walls:diorite_6 154 150 148 +mcl_walls:diorite_7 154 150 148 +mcl_walls:diorite_8 154 150 148 +mcl_walls:diorite_9 154 150 148 +mcl_walls:endbricks 195 189 123 +mcl_walls:endbricks_0 195 189 123 +mcl_walls:endbricks_1 195 189 123 +mcl_walls:endbricks_10 195 189 123 +mcl_walls:endbricks_11 195 189 123 +mcl_walls:endbricks_12 195 189 123 +mcl_walls:endbricks_13 195 189 123 +mcl_walls:endbricks_14 195 189 123 +mcl_walls:endbricks_15 195 189 123 +mcl_walls:endbricks_16 195 189 123 +mcl_walls:endbricks_2 195 189 123 +mcl_walls:endbricks_21 195 189 123 +mcl_walls:endbricks_3 195 189 123 +mcl_walls:endbricks_4 195 189 123 +mcl_walls:endbricks_5 195 189 123 +mcl_walls:endbricks_6 195 189 123 +mcl_walls:endbricks_7 195 189 123 +mcl_walls:endbricks_8 195 189 123 +mcl_walls:endbricks_9 195 189 123 +mcl_walls:granite 155 122 111 +mcl_walls:granite_0 155 122 111 +mcl_walls:granite_1 155 122 111 +mcl_walls:granite_10 155 122 111 +mcl_walls:granite_11 155 122 111 +mcl_walls:granite_12 155 122 111 +mcl_walls:granite_13 155 122 111 +mcl_walls:granite_14 155 122 111 +mcl_walls:granite_15 155 122 111 +mcl_walls:granite_16 155 122 111 +mcl_walls:granite_2 155 122 111 +mcl_walls:granite_21 155 122 111 +mcl_walls:granite_3 155 122 111 +mcl_walls:granite_4 155 122 111 +mcl_walls:granite_5 155 122 111 +mcl_walls:granite_6 155 122 111 +mcl_walls:granite_7 155 122 111 +mcl_walls:granite_8 155 122 111 +mcl_walls:granite_9 155 122 111 +mcl_walls:mossycobble 59 98 63 +mcl_walls:mossycobble_0 59 98 63 +mcl_walls:mossycobble_1 59 98 63 +mcl_walls:mossycobble_10 59 98 63 +mcl_walls:mossycobble_11 59 98 63 +mcl_walls:mossycobble_12 59 98 63 +mcl_walls:mossycobble_13 59 98 63 +mcl_walls:mossycobble_14 59 98 63 +mcl_walls:mossycobble_15 59 98 63 +mcl_walls:mossycobble_16 59 98 63 +mcl_walls:mossycobble_2 59 98 63 +mcl_walls:mossycobble_21 59 98 63 +mcl_walls:mossycobble_3 59 98 63 +mcl_walls:mossycobble_4 59 98 63 +mcl_walls:mossycobble_5 59 98 63 +mcl_walls:mossycobble_6 59 98 63 +mcl_walls:mossycobble_7 59 98 63 +mcl_walls:mossycobble_8 59 98 63 +mcl_walls:mossycobble_9 59 98 63 +mcl_walls:mudbrick 109 96 87 +mcl_walls:mudbrick_0 109 96 87 +mcl_walls:mudbrick_1 109 96 87 +mcl_walls:mudbrick_10 109 96 87 +mcl_walls:mudbrick_11 109 96 87 +mcl_walls:mudbrick_12 109 96 87 +mcl_walls:mudbrick_13 109 96 87 +mcl_walls:mudbrick_14 109 96 87 +mcl_walls:mudbrick_15 109 96 87 +mcl_walls:mudbrick_16 109 96 87 +mcl_walls:mudbrick_2 109 96 87 +mcl_walls:mudbrick_21 109 96 87 +mcl_walls:mudbrick_3 109 96 87 +mcl_walls:mudbrick_4 109 96 87 +mcl_walls:mudbrick_5 109 96 87 +mcl_walls:mudbrick_6 109 96 87 +mcl_walls:mudbrick_7 109 96 87 +mcl_walls:mudbrick_8 109 96 87 +mcl_walls:mudbrick_9 109 96 87 +mcl_walls:netherbrick 49 25 26 +mcl_walls:netherbrick_0 49 25 26 +mcl_walls:netherbrick_1 49 25 26 +mcl_walls:netherbrick_10 49 25 26 +mcl_walls:netherbrick_11 49 25 26 +mcl_walls:netherbrick_12 49 25 26 +mcl_walls:netherbrick_13 49 25 26 +mcl_walls:netherbrick_14 49 25 26 +mcl_walls:netherbrick_15 49 25 26 +mcl_walls:netherbrick_16 49 25 26 +mcl_walls:netherbrick_2 49 25 26 +mcl_walls:netherbrick_21 49 25 26 +mcl_walls:netherbrick_3 49 25 26 +mcl_walls:netherbrick_4 49 25 26 +mcl_walls:netherbrick_5 49 25 26 +mcl_walls:netherbrick_6 49 25 26 +mcl_walls:netherbrick_7 49 25 26 +mcl_walls:netherbrick_8 49 25 26 +mcl_walls:netherbrick_9 49 25 26 +mcl_walls:prismarine 106 127 123 +mcl_walls:prismarine_0 106 127 123 +mcl_walls:prismarine_1 106 127 123 +mcl_walls:prismarine_10 106 127 123 +mcl_walls:prismarine_11 106 127 123 +mcl_walls:prismarine_12 106 127 123 +mcl_walls:prismarine_13 106 127 123 +mcl_walls:prismarine_14 106 127 123 +mcl_walls:prismarine_15 106 127 123 +mcl_walls:prismarine_16 106 127 123 +mcl_walls:prismarine_2 106 127 123 +mcl_walls:prismarine_21 106 127 123 +mcl_walls:prismarine_3 106 127 123 +mcl_walls:prismarine_4 106 127 123 +mcl_walls:prismarine_5 106 127 123 +mcl_walls:prismarine_6 106 127 123 +mcl_walls:prismarine_7 106 127 123 +mcl_walls:prismarine_8 106 127 123 +mcl_walls:prismarine_9 106 127 123 +mcl_walls:rednetherbrick 72 17 6 +mcl_walls:rednetherbrick_0 72 17 6 +mcl_walls:rednetherbrick_1 72 17 6 +mcl_walls:rednetherbrick_10 72 17 6 +mcl_walls:rednetherbrick_11 72 17 6 +mcl_walls:rednetherbrick_12 72 17 6 +mcl_walls:rednetherbrick_13 72 17 6 +mcl_walls:rednetherbrick_14 72 17 6 +mcl_walls:rednetherbrick_15 72 17 6 +mcl_walls:rednetherbrick_16 72 17 6 +mcl_walls:rednetherbrick_2 72 17 6 +mcl_walls:rednetherbrick_21 72 17 6 +mcl_walls:rednetherbrick_3 72 17 6 +mcl_walls:rednetherbrick_4 72 17 6 +mcl_walls:rednetherbrick_5 72 17 6 +mcl_walls:rednetherbrick_6 72 17 6 +mcl_walls:rednetherbrick_7 72 17 6 +mcl_walls:rednetherbrick_8 72 17 6 +mcl_walls:rednetherbrick_9 72 17 6 +mcl_walls:redsandstone 212 126 108 +mcl_walls:redsandstone_0 212 126 108 +mcl_walls:redsandstone_1 212 126 108 +mcl_walls:redsandstone_10 212 126 108 +mcl_walls:redsandstone_11 212 126 108 +mcl_walls:redsandstone_12 212 126 108 +mcl_walls:redsandstone_13 212 126 108 +mcl_walls:redsandstone_14 212 126 108 +mcl_walls:redsandstone_15 212 126 108 +mcl_walls:redsandstone_16 212 126 108 +mcl_walls:redsandstone_2 212 126 108 +mcl_walls:redsandstone_21 212 126 108 +mcl_walls:redsandstone_3 212 126 108 +mcl_walls:redsandstone_4 212 126 108 +mcl_walls:redsandstone_5 212 126 108 +mcl_walls:redsandstone_6 212 126 108 +mcl_walls:redsandstone_7 212 126 108 +mcl_walls:redsandstone_8 212 126 108 +mcl_walls:redsandstone_9 212 126 108 +mcl_walls:sandstone 202 155 121 +mcl_walls:sandstone_0 202 155 121 +mcl_walls:sandstone_1 202 155 121 +mcl_walls:sandstone_10 202 155 121 +mcl_walls:sandstone_11 202 155 121 +mcl_walls:sandstone_12 202 155 121 +mcl_walls:sandstone_13 202 155 121 +mcl_walls:sandstone_14 202 155 121 +mcl_walls:sandstone_15 202 155 121 +mcl_walls:sandstone_16 202 155 121 +mcl_walls:sandstone_2 202 155 121 +mcl_walls:sandstone_21 202 155 121 +mcl_walls:sandstone_3 202 155 121 +mcl_walls:sandstone_4 202 155 121 +mcl_walls:sandstone_5 202 155 121 +mcl_walls:sandstone_6 202 155 121 +mcl_walls:sandstone_7 202 155 121 +mcl_walls:sandstone_8 202 155 121 +mcl_walls:sandstone_9 202 155 121 +mcl_walls:stonebrick 99 91 88 +mcl_walls:stonebrick_0 99 91 88 +mcl_walls:stonebrick_1 99 91 88 +mcl_walls:stonebrick_10 99 91 88 +mcl_walls:stonebrick_11 99 91 88 +mcl_walls:stonebrick_12 99 91 88 +mcl_walls:stonebrick_13 99 91 88 +mcl_walls:stonebrick_14 99 91 88 +mcl_walls:stonebrick_15 99 91 88 +mcl_walls:stonebrick_16 99 91 88 +mcl_walls:stonebrick_2 99 91 88 +mcl_walls:stonebrick_21 99 91 88 +mcl_walls:stonebrick_3 99 91 88 +mcl_walls:stonebrick_4 99 91 88 +mcl_walls:stonebrick_5 99 91 88 +mcl_walls:stonebrick_6 99 91 88 +mcl_walls:stonebrick_7 99 91 88 +mcl_walls:stonebrick_8 99 91 88 +mcl_walls:stonebrick_9 99 91 88 +mcl_walls:stonebrickmossy 86 104 79 +mcl_walls:stonebrickmossy_0 86 104 79 +mcl_walls:stonebrickmossy_1 86 104 79 +mcl_walls:stonebrickmossy_10 86 104 79 +mcl_walls:stonebrickmossy_11 86 104 79 +mcl_walls:stonebrickmossy_12 86 104 79 +mcl_walls:stonebrickmossy_13 86 104 79 +mcl_walls:stonebrickmossy_14 86 104 79 +mcl_walls:stonebrickmossy_15 86 104 79 +mcl_walls:stonebrickmossy_16 86 104 79 +mcl_walls:stonebrickmossy_2 86 104 79 +mcl_walls:stonebrickmossy_21 86 104 79 +mcl_walls:stonebrickmossy_3 86 104 79 +mcl_walls:stonebrickmossy_4 86 104 79 +mcl_walls:stonebrickmossy_5 86 104 79 +mcl_walls:stonebrickmossy_6 86 104 79 +mcl_walls:stonebrickmossy_7 86 104 79 +mcl_walls:stonebrickmossy_8 86 104 79 +mcl_walls:stonebrickmossy_9 86 104 79 + +# mcl_wool +mcl_wool:black 46 43 43 +mcl_wool:black_carpet 46 43 43 +mcl_wool:blue 43 75 126 +mcl_wool:blue_carpet 43 75 126 +mcl_wool:brown 87 57 43 +mcl_wool:brown_carpet 87 57 43 +mcl_wool:cyan 30 95 113 +mcl_wool:cyan_carpet 30 95 113 +mcl_wool:green 54 92 51 +mcl_wool:green_carpet 54 92 51 +mcl_wool:grey 97 88 88 +mcl_wool:grey_carpet 97 88 88 +mcl_wool:light_blue 92 132 180 +mcl_wool:light_blue_carpet 92 132 180 +mcl_wool:lime 110 152 77 +mcl_wool:lime_carpet 110 152 77 +mcl_wool:magenta 142 86 126 +mcl_wool:magenta_carpet 142 86 126 +mcl_wool:orange 188 107 46 +mcl_wool:orange_carpet 188 107 46 +mcl_wool:pink 171 92 108 +mcl_wool:pink_carpet 171 92 108 +mcl_wool:purple 79 57 103 +mcl_wool:purple_carpet 79 57 103 +mcl_wool:red 133 42 45 +mcl_wool:red_carpet 133 42 45 +mcl_wool:silver 143 135 135 +mcl_wool:silver_carpet 143 135 135 +mcl_wool:white 212 199 183 +mcl_wool:white_carpet 212 199 183 +mcl_wool:yellow 201 164 70 +mcl_wool:yellow_carpet 201 164 70 + +# mclx_core +mclx_core:river_water_flowing 0 122 139 +mclx_core:river_water_source 32 121 138 + +# mclx_fences +mclx_fences:nether_brick_fence_gate 51 27 27 +mclx_fences:nether_brick_fence_gate_open 51 27 27 +mclx_fences:red_nether_brick_fence 72 18 0 +mclx_fences:red_nether_brick_fence_gate 68 16 0 +mclx_fences:red_nether_brick_fence_gate_open 68 16 0 + +# mesecons +mesecons:wire_00000000_off 171 171 171 +mesecons:wire_00000000_on 171 171 171 +mesecons:wire_00010000_off 171 171 171 +mesecons:wire_00010000_on 171 171 171 +mesecons:wire_00010001_off 171 171 171 +mesecons:wire_00010001_on 171 171 171 +mesecons:wire_00100000_off 171 171 171 +mesecons:wire_00100000_on 171 171 171 +mesecons:wire_00100010_off 171 171 171 +mesecons:wire_00100010_on 171 171 171 +mesecons:wire_00110000_off 171 171 171 +mesecons:wire_00110000_on 171 171 171 +mesecons:wire_00110001_off 171 171 171 +mesecons:wire_00110001_on 171 171 171 +mesecons:wire_00110010_off 171 171 171 +mesecons:wire_00110010_on 171 171 171 +mesecons:wire_00110011_off 171 171 171 +mesecons:wire_00110011_on 171 171 171 +mesecons:wire_01000000_off 171 171 171 +mesecons:wire_01000000_on 171 171 171 +mesecons:wire_01000100_off 171 171 171 +mesecons:wire_01000100_on 171 171 171 +mesecons:wire_01010000_off 171 171 171 +mesecons:wire_01010000_on 171 171 171 +mesecons:wire_01010001_off 171 171 171 +mesecons:wire_01010001_on 171 171 171 +mesecons:wire_01010100_off 171 171 171 +mesecons:wire_01010100_on 171 171 171 +mesecons:wire_01010101_off 171 171 171 +mesecons:wire_01010101_on 171 171 171 +mesecons:wire_01100000_off 171 171 171 +mesecons:wire_01100000_on 171 171 171 +mesecons:wire_01100010_off 171 171 171 +mesecons:wire_01100010_on 171 171 171 +mesecons:wire_01100100_off 171 171 171 +mesecons:wire_01100100_on 171 171 171 +mesecons:wire_01100110_off 171 171 171 +mesecons:wire_01100110_on 171 171 171 +mesecons:wire_01110000_off 171 171 171 +mesecons:wire_01110000_on 171 171 171 +mesecons:wire_01110001_off 171 171 171 +mesecons:wire_01110001_on 171 171 171 +mesecons:wire_01110010_off 171 171 171 +mesecons:wire_01110010_on 171 171 171 +mesecons:wire_01110011_off 171 171 171 +mesecons:wire_01110011_on 171 171 171 +mesecons:wire_01110100_off 171 171 171 +mesecons:wire_01110100_on 171 171 171 +mesecons:wire_01110101_off 171 171 171 +mesecons:wire_01110101_on 171 171 171 +mesecons:wire_01110110_off 171 171 171 +mesecons:wire_01110110_on 171 171 171 +mesecons:wire_01110111_off 171 171 171 +mesecons:wire_01110111_on 171 171 171 +mesecons:wire_10000000_off 171 171 171 +mesecons:wire_10000000_on 171 171 171 +mesecons:wire_10001000_off 171 171 171 +mesecons:wire_10001000_on 171 171 171 +mesecons:wire_10010000_off 171 171 171 +mesecons:wire_10010000_on 171 171 171 +mesecons:wire_10010001_off 171 171 171 +mesecons:wire_10010001_on 171 171 171 +mesecons:wire_10011000_off 171 171 171 +mesecons:wire_10011000_on 171 171 171 +mesecons:wire_10011001_off 171 171 171 +mesecons:wire_10011001_on 171 171 171 +mesecons:wire_10100000_off 171 171 171 +mesecons:wire_10100000_on 171 171 171 +mesecons:wire_10100010_off 171 171 171 +mesecons:wire_10100010_on 171 171 171 +mesecons:wire_10101000_off 171 171 171 +mesecons:wire_10101000_on 171 171 171 +mesecons:wire_10101010_off 171 171 171 +mesecons:wire_10101010_on 171 171 171 +mesecons:wire_10110000_off 171 171 171 +mesecons:wire_10110000_on 171 171 171 +mesecons:wire_10110001_off 171 171 171 +mesecons:wire_10110001_on 171 171 171 +mesecons:wire_10110010_off 171 171 171 +mesecons:wire_10110010_on 171 171 171 +mesecons:wire_10110011_off 171 171 171 +mesecons:wire_10110011_on 171 171 171 +mesecons:wire_10111000_off 171 171 171 +mesecons:wire_10111000_on 171 171 171 +mesecons:wire_10111001_off 171 171 171 +mesecons:wire_10111001_on 171 171 171 +mesecons:wire_10111010_off 171 171 171 +mesecons:wire_10111010_on 171 171 171 +mesecons:wire_10111011_off 171 171 171 +mesecons:wire_10111011_on 171 171 171 +mesecons:wire_11000000_off 171 171 171 +mesecons:wire_11000000_on 171 171 171 +mesecons:wire_11000100_off 171 171 171 +mesecons:wire_11000100_on 171 171 171 +mesecons:wire_11001000_off 171 171 171 +mesecons:wire_11001000_on 171 171 171 +mesecons:wire_11001100_off 171 171 171 +mesecons:wire_11001100_on 171 171 171 +mesecons:wire_11010000_off 171 171 171 +mesecons:wire_11010000_on 171 171 171 +mesecons:wire_11010001_off 171 171 171 +mesecons:wire_11010001_on 171 171 171 +mesecons:wire_11010100_off 171 171 171 +mesecons:wire_11010100_on 171 171 171 +mesecons:wire_11010101_off 171 171 171 +mesecons:wire_11010101_on 171 171 171 +mesecons:wire_11011000_off 171 171 171 +mesecons:wire_11011000_on 171 171 171 +mesecons:wire_11011001_off 171 171 171 +mesecons:wire_11011001_on 171 171 171 +mesecons:wire_11011100_off 171 171 171 +mesecons:wire_11011100_on 171 171 171 +mesecons:wire_11011101_off 171 171 171 +mesecons:wire_11011101_on 171 171 171 +mesecons:wire_11100000_off 171 171 171 +mesecons:wire_11100000_on 171 171 171 +mesecons:wire_11100010_off 171 171 171 +mesecons:wire_11100010_on 171 171 171 +mesecons:wire_11100100_off 171 171 171 +mesecons:wire_11100100_on 171 171 171 +mesecons:wire_11100110_off 171 171 171 +mesecons:wire_11100110_on 171 171 171 +mesecons:wire_11101000_off 171 171 171 +mesecons:wire_11101000_on 171 171 171 +mesecons:wire_11101010_off 171 171 171 +mesecons:wire_11101010_on 171 171 171 +mesecons:wire_11101100_off 171 171 171 +mesecons:wire_11101100_on 171 171 171 +mesecons:wire_11101110_off 171 171 171 +mesecons:wire_11101110_on 171 171 171 +mesecons:wire_11110000_off 171 171 171 +mesecons:wire_11110000_on 171 171 171 +mesecons:wire_11110001_off 171 171 171 +mesecons:wire_11110001_on 171 171 171 +mesecons:wire_11110010_off 171 171 171 +mesecons:wire_11110010_on 171 171 171 +mesecons:wire_11110011_off 171 171 171 +mesecons:wire_11110011_on 171 171 171 +mesecons:wire_11110100_off 171 171 171 +mesecons:wire_11110100_on 171 171 171 +mesecons:wire_11110101_off 171 171 171 +mesecons:wire_11110101_on 171 171 171 +mesecons:wire_11110110_off 171 171 171 +mesecons:wire_11110110_on 171 171 171 +mesecons:wire_11110111_off 171 171 171 +mesecons:wire_11110111_on 171 171 171 +mesecons:wire_11111000_off 171 171 171 +mesecons:wire_11111000_on 171 171 171 +mesecons:wire_11111001_off 171 171 171 +mesecons:wire_11111001_on 171 171 171 +mesecons:wire_11111010_off 171 171 171 +mesecons:wire_11111010_on 171 171 171 +mesecons:wire_11111011_off 171 171 171 +mesecons:wire_11111011_on 171 171 171 +mesecons:wire_11111100_off 171 171 171 +mesecons:wire_11111100_on 171 171 171 +mesecons:wire_11111101_off 171 171 171 +mesecons:wire_11111101_on 171 171 171 +mesecons:wire_11111110_off 171 171 171 +mesecons:wire_11111110_on 171 171 171 +mesecons:wire_11111111_off 171 171 171 +mesecons:wire_11111111_on 171 171 171 + +# mesecons_button +mesecons_button:button_acaciawood_off 153 103 71 +mesecons_button:button_acaciawood_on 153 103 71 +mesecons_button:button_birchwood_off 147 116 90 +mesecons_button:button_birchwood_on 147 116 90 +mesecons_button:button_darkwood_off 89 76 63 +mesecons_button:button_darkwood_on 89 76 63 +mesecons_button:button_junglewood_off 114 80 60 +mesecons_button:button_junglewood_on 114 80 60 +mesecons_button:button_sprucewood_off 82 66 54 +mesecons_button:button_sprucewood_on 82 66 54 +mesecons_button:button_stone_off 131 123 118 +mesecons_button:button_stone_on 131 123 118 +mesecons_button:button_wood_off 115 89 68 +mesecons_button:button_wood_on 115 89 68 + +# mesecons_commandblock +mesecons_commandblock:commandblock_off 128 113 105 +mesecons_commandblock:commandblock_on 128 113 105 + +# mesecons_delayer +mesecons_delayer:delayer_off_1 115 105 101 +mesecons_delayer:delayer_off_2 115 105 101 +mesecons_delayer:delayer_off_3 115 105 101 +mesecons_delayer:delayer_off_4 115 105 101 +mesecons_delayer:delayer_off_locked 113 104 99 +mesecons_delayer:delayer_on_1 118 105 101 +mesecons_delayer:delayer_on_2 118 105 101 +mesecons_delayer:delayer_on_3 118 105 101 +mesecons_delayer:delayer_on_4 118 105 101 +mesecons_delayer:delayer_on_locked 116 104 99 + +# mesecons_lightstone +mesecons_lightstone:lightstone_off 73 52 44 +mesecons_lightstone:lightstone_on 122 65 41 + +# mesecons_noteblock +mesecons_noteblock:noteblock 114 89 69 + +# mesecons_pistons +mesecons_pistons:piston_down_normal_off 117 108 104 +mesecons_pistons:piston_down_normal_on 117 108 104 +mesecons_pistons:piston_down_pusher_normal 110 85 67 +mesecons_pistons:piston_down_pusher_sticky 110 85 67 +mesecons_pistons:piston_down_sticky_off 117 108 104 +mesecons_pistons:piston_down_sticky_on 117 108 104 +mesecons_pistons:piston_normal_off 123 111 103 +mesecons_pistons:piston_normal_on 123 111 103 +mesecons_pistons:piston_pusher_normal 110 85 67 +mesecons_pistons:piston_pusher_sticky 110 85 67 +mesecons_pistons:piston_sticky_off 123 111 103 +mesecons_pistons:piston_sticky_on 123 111 103 +mesecons_pistons:piston_up_normal_off 110 85 67 +mesecons_pistons:piston_up_normal_on 116 107 104 +mesecons_pistons:piston_up_pusher_normal 110 85 67 +mesecons_pistons:piston_up_pusher_sticky 103 84 65 +mesecons_pistons:piston_up_sticky_off 103 84 65 +mesecons_pistons:piston_up_sticky_on 116 107 104 + +# mesecons_pressureplates +mesecons_pressureplates:pressure_plate_acaciawood_off 153 103 71 +mesecons_pressureplates:pressure_plate_acaciawood_on 153 103 71 +mesecons_pressureplates:pressure_plate_birchwood_off 147 116 90 +mesecons_pressureplates:pressure_plate_birchwood_on 147 116 90 +mesecons_pressureplates:pressure_plate_darkwood_off 89 76 63 +mesecons_pressureplates:pressure_plate_darkwood_on 89 76 63 +mesecons_pressureplates:pressure_plate_junglewood_off 114 80 60 +mesecons_pressureplates:pressure_plate_junglewood_on 114 80 60 +mesecons_pressureplates:pressure_plate_sprucewood_off 82 66 54 +mesecons_pressureplates:pressure_plate_sprucewood_on 82 66 54 +mesecons_pressureplates:pressure_plate_stone_off 131 123 118 +mesecons_pressureplates:pressure_plate_stone_on 131 123 118 +mesecons_pressureplates:pressure_plate_wood_off 115 89 68 +mesecons_pressureplates:pressure_plate_wood_on 115 89 68 + +# mesecons_solarpanel +mesecons_solarpanel:solar_panel_inverted_off 118 132 149 +mesecons_solarpanel:solar_panel_inverted_on 118 132 149 +mesecons_solarpanel:solar_panel_off 150 141 130 +mesecons_solarpanel:solar_panel_on 150 141 130 + +# mesecons_torch +mesecons_torch:mesecon_torch_off 93 71 57 +mesecons_torch:mesecon_torch_off_wall 93 71 57 +mesecons_torch:mesecon_torch_on 104 72 58 +mesecons_torch:mesecon_torch_on_wall 104 72 58 +mesecons_torch:mesecon_torch_overheated 93 71 57 +mesecons_torch:mesecon_torch_overheated_wall 93 71 57 +mesecons_torch:redstoneblock 131 12 14 + +# mesecons_walllever +mesecons_walllever:wall_lever_off 110 100 95 +mesecons_walllever:wall_lever_on 110 100 95 + +# xpanes +xpanes:bar 157 148 148 64 16 +xpanes:bar_flat 157 148 148 64 16 +xpanes:pane_black 25 25 25 64 16 +xpanes:pane_black_flat 25 25 25 64 16 +xpanes:pane_blue 51 76 178 64 16 +xpanes:pane_blue_flat 51 76 178 64 16 +xpanes:pane_brown 102 76 51 64 16 +xpanes:pane_brown_flat 102 76 51 64 16 +xpanes:pane_cyan 76 127 153 64 16 +xpanes:pane_cyan_flat 76 127 153 64 16 +xpanes:pane_gray 76 76 76 64 16 +xpanes:pane_gray_flat 76 76 76 64 16 +xpanes:pane_green 102 127 51 64 16 +xpanes:pane_green_flat 102 127 51 64 16 +xpanes:pane_light_blue 102 153 216 64 16 +xpanes:pane_light_blue_flat 102 153 216 64 16 +xpanes:pane_lime 127 204 25 64 16 +xpanes:pane_lime_flat 127 204 25 64 16 +xpanes:pane_magenta 0 0 0 64 16 +xpanes:pane_magenta_flat 0 0 0 64 16 +xpanes:pane_natural 222 222 239 64 16 +xpanes:pane_natural_flat 222 222 239 64 16 +xpanes:pane_orange 216 127 51 64 16 +xpanes:pane_orange_flat 216 127 51 64 16 +xpanes:pane_pink 0 0 0 64 16 +xpanes:pane_pink_flat 0 0 0 64 16 +xpanes:pane_purple 127 63 178 64 16 +xpanes:pane_purple_flat 127 63 178 64 16 +xpanes:pane_red 153 51 51 64 16 +xpanes:pane_red_flat 153 51 51 64 16 +xpanes:pane_silver 153 153 153 64 16 +xpanes:pane_silver_flat 153 153 153 64 16 +xpanes:pane_white 255 255 255 64 16 +xpanes:pane_white_flat 255 255 255 64 16 +xpanes:pane_yellow 229 229 51 64 16 +xpanes:pane_yellow_flat 229 229 51 64 16 + diff --git a/tools/create_luacheck.py b/tools/create_luacheck.py new file mode 100755 index 000000000..d3ee5d038 --- /dev/null +++ b/tools/create_luacheck.py @@ -0,0 +1,44 @@ +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 + +path = "./mods/" + +pattern = re.compile(r'^(?P[A-Za-z_0-9]+)[ ]*=[ ]*\{') +pattern_local = re.compile(r'local (?P[A-Za-z_0-9]+)') + +global_vars = [] + + +print("---Copy/Paste output in your luacheck conf file---\n") + + +pathlist = Path(path).rglob('*.lua') +for path in pathlist: + path_in_str = str(path) + # print(path_in_str) + found = False + with open(path_in_str) as f: + local_vars = [] + for i, line in enumerate(f.readlines()): + m = pattern.match(line) + if m: + global_name = m.group('global_var') + if global_name not in local_vars: + #print(path_in_str, ":", i+1, ":", m.group('global_var').strip()) + global_vars.append(m.group('global_var').strip()) + found = True + break + + else: + n = pattern_local.match(line) + if n: + local_vars.append(n.group('local_var')) + + if not found: + nb_varloc = len(local_vars) + #print(path_in_str, ": -", "({} variables locales)".format(nb_varloc) if nb_varloc > 0 else '') + +print(', '.join(['"{}"'.format(v) for v in global_vars])) diff --git a/tools/create_map_color_file.py b/tools/create_map_color_file.py new file mode 100644 index 000000000..b6486b8e3 --- /dev/null +++ b/tools/create_map_color_file.py @@ -0,0 +1,59 @@ +import json, os +from PIL import Image + +colors = {} +palettes = {} + +for root, directories, files in os.walk(".."): + if root.endswith("/textures"): + for name in files: + try: + img = Image.open(os.path.join(root, name)).convert("RGBA") + pixels = img.load() + + if "palette" in name: + palette = [] + + for y in range(0, img.size[1]): + for x in range(0, img.size[0]): + r, g, b, a = pixels[x, y] + palette.append((r, g, b)) + + palettes[name] = palette + else: + r_total = 0 + g_total = 0 + b_total = 0 + + count = 0 + + for x in range(0, img.size[0]): + for y in range(0, img.size[1]): + r, g, b, a = pixels[x, y] + if a > 0: + r_total += r / 255 * a + g_total += g / 255 * a + b_total += b / 255 * a + count += a / 255 + + average_color = None + + if count > 0: + average_color = (int(r_total / count), int(g_total / count), int(b_total / count)) + else: + average_color = (255, 255, 255) + + colors[name] = average_color + + img.close() + except IOError: + pass + +path = "../mods/ITEMS/mcl_maps/" + +with open(path + "colors.json", "w") as colorfile: + colorfile.write(json.dumps(colors)) + +with open(path + "palettes.json", "w") as palettefile: + palettefile.write(json.dumps(palettes)) + diff --git a/tools/dicts/polish.dic b/tools/dicts/polish.dic new file mode 100644 index 000000000..952ae57eb --- /dev/null +++ b/tools/dicts/polish.dic @@ -0,0 +1,176 @@ +1s +1f +Badlandach +biomeinfo +creeper +Creeper +creepera +czerwienit +czerwienitem +czerwienitowych +czerwienitu +czerwienitowa +czerwienitowe +czerwienitowej +czerwienitowego +czerwienitową +czerwienitowy +czerwienitowym +czerwienitowymi +enchant +Enderman +Endermit +endermitom +forceenchant +Ghast +ghasta +Ghasta +kresomysz +kresomyszę +przywoływacza +endermana +pigmana +szlama +enable +disable +awards +Dozuj +wskazywalne +zderzalne +Zderzalne +zderzalnego +Minetest +doc_basics +doc_identifier +help_reveal +doc_items +doc_encyclopedia +F1 +shout +Minetesta +voxelach +InfiniMinera +F10 +F9 +celeron55 +F2 +Ahola +debug +Perttu +F8 +F3 +F7 +F5 +F12 +noclip +F6 +https +viewforum +php +minetest +Houstonia +houstonią +wskazywalna +MineClone +voxeli +niewskazywalne +wskazywalnych +github +Wuzzy2 +MineClone2 +Minetestem +freenode +irc +Bugs +viewtopic +forums +iskrzyłuda +Spawnowanie +Griefowanie +PvP +enable_pvp +creative_mode +msg +enable_damage +boats +privs +give +tekst3 +tekst1 +tekst2 +słowo1 +słowo2 +słowo3 +slesz +slesza +mcl_core +giveme +spawnentity +spawnowaniem +grantme +interact +spawnuje +revoke +spawnują +jasnogłazu +Netherowego +Netherowych +Netherowy +jasnogłazy +Iskrzyłuda +iskrzyłudzie +jasnogłazie +Jasnogłaz +Kolcze +Kolczy +Łuczarz +maphack +międzywymiarowego +międzywymiarowych +moba +Muuuchomor +Nether +netherowej +Netherowa +Netherowe +Netheru +Netherze +półbloku +Prastrażnik +pryzmaryn +pryzmarynowe +pryzmarynowa +Pryzmaryn +Pryzmarynowa +Pryzmarynowe +Przywoływacz +setblock +Shulker +shulkera +shulkerów +shulkerowa +Shulkerowa +shulkerową +Shulkerowe +shulkerowej +shulkerowych +shulkerowymi +spawner +spawnowania +spawnery +spawnerze +spawnstruct +szkieleta +v6 +Wielostrzał +Wither +witherowego +withera +Witherowy +zakłuta +refrenusu +refrenusowych +thunder +clear +snow +rain diff --git a/tools/generate_ingame_credits.lua b/tools/generate_ingame_credits.lua new file mode 100755 index 000000000..a484322c0 --- /dev/null +++ b/tools/generate_ingame_credits.lua @@ -0,0 +1,51 @@ +#! /usr/bin/env lua +-- Script to automatically generate mods/HUD/mcl_credits/people.lua from CREDITS.md +-- Run from MCL2 root folder + +local colors = { + ["Creator of MineClone"] = "0x0A9400", + ["Creator of MineClone2"] = "0xFBF837", + ["Maintainers"] = "0xFF51D5", + ["Developers"] = "0xF84355", + ["Past Developers"] = "0xF84355", + ["Contributors"] = "0x52FF00", + ["Music"] = "0xA60014", + ["Original Mod Authors"] = "0x343434", + ["3D Models"] = "0x0019FF", + ["Textures"] = "0xFF9705", + ["Translations"] = "0x00FF60", + ["Funders"] = "0xF7FF00", + ["Special thanks"] = "0x00E9FF", +} + +local from = io.open("CREDITS.md", "r") +local to = io.open("mods/HUD/mcl_credits/people.lua", "w") + +to:write([[ +local modname = minetest.get_current_modname() +local S = minetest.get_translator(modname) + +]]) + +to:write("return {\n") + +local started_block = false + +for line in from:lines() do + if line:find("## ") == 1 then + if started_block then + to:write("\t}},\n") + end + local title = line:sub(4, #line) + to:write("\t{S(\"" .. title .. "\"), " .. (colors[title] or "0xFFFFFF") .. ", {\n") + started_block = true + elseif line:find("*") == 1 then + to:write("\t\t\"" .. line:sub(3, #line) .. "\",\n") + end +end + +if started_block then + to:write("\t}},\n") +end + +to:write("}\n") diff --git a/tools/spell_check_translate_files.py b/tools/spell_check_translate_files.py new file mode 100644 index 000000000..6b3cc85b0 --- /dev/null +++ b/tools/spell_check_translate_files.py @@ -0,0 +1,60 @@ +# Output indicator +# >> Spell checking error +# !> Indicates a text line with too many '=' in translate file (.tr) + +import os +import argparse +import hunspell +import re + +parser = argparse.ArgumentParser(description='Check translation file using pyhunspell for a given language.') +parser.add_argument("language", help='language code') +parser.add_argument("dic_file", help='path to .dic file') +parser.add_argument("aff_file", help='path to .aff file') +parser.add_argument('-a', "--add", help='path to file with additional words', default=None) +parser.add_argument('-s', "--suggestions", action="store_true", help='display spelling suggestions for incorrectly spelled words') +args = parser.parse_args() + +PATH = "../mods/" +code_lang = args.language +hs = hunspell.HunSpell(args.dic_file, args.aff_file) +if args.add is not None: + with open(args.add, 'r') as file: + for word in file: + hs.add(word.strip()) + +def get_errors(file): + result = set() + for line in file: + line = line.strip() + if line.startswith('#') or line == '': + continue + if '=' in line: + try: + _, translated = re.split(r'[^@]=', line) + except: + print("!> Too many '='s in line:", line) + continue + for word in re.split(r'\@.|[\W ]',translated): + if not hs.spell(word): + result.add(word) + + return result + +def spell_check(filename): + with open(filename, 'r', encoding="utf-8") as file: + errors = get_errors(file) + if len(errors) > 0: + print("Spell checking errors in '", filename[len(PATH):], "':", sep='') + for word in errors: + print('>>', word) + if args.suggestions: + print(">> Did you mean:", ", ".join(hs.suggest(word)), "?") + + +for root, _, _ in os.walk(PATH): + if root.endswith('locale'): + translated_file = os.path.join(root, os.path.basename(os.path.dirname(root))) + "." + code_lang + ".tr" + + if os.path.exists(translated_file) and os.path.isfile(translated_file): + spell_check(translated_file) diff --git a/tools/strip_trailing_whitespace.sh b/tools/strip_trailing_whitespace.sh new file mode 100755 index 000000000..57e51d311 --- /dev/null +++ b/tools/strip_trailing_whitespace.sh @@ -0,0 +1,2 @@ +#!/bin/bash +sed --in-place 's/[[:space:]]\+$//' $(find -name "*.lua")